From ddc25bdd2b7f34667111714fafc9c04f6ad97fee Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Wed, 7 Jan 2015 13:15:22 +0100 Subject: [PATCH 00001/11651] iio: dht11: Fix out-of-bounds read As we access i-1 we must not start with i=0. Signed-off-by: Richard Weinberger Acked-by: Hartmut Knaack Acked-by: Harald Geyer Reviewed-by: Sanjeev Sharma Signed-off-by: Jonathan Cameron --- drivers/iio/humidity/dht11.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/humidity/dht11.c b/drivers/iio/humidity/dht11.c index 623c145d8a97..f546ecae90f1 100644 --- a/drivers/iio/humidity/dht11.c +++ b/drivers/iio/humidity/dht11.c @@ -88,7 +88,7 @@ static int dht11_decode(struct dht11 *dht11, int offset) unsigned char temp_int, temp_dec, hum_int, hum_dec, checksum; /* Calculate timestamp resolution */ - for (i = 0; i < dht11->num_edges; ++i) { + for (i = 1; i < dht11->num_edges; ++i) { t = dht11->edges[i].ts - dht11->edges[i-1].ts; if (t > 0 && t < timeres) timeres = t; -- GitLab From 004bc530341a40536494431cf665504f8ee70266 Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Wed, 7 Jan 2015 13:18:23 +0100 Subject: [PATCH 00002/11651] iio: dht11: Add locking Make sure that the read function is not interrupted... Signed-off-by: Richard Weinberger Acked-by: Harald Geyer Reviewed-by: Sanjeev Sharma Signed-off-by: Jonathan Cameron --- drivers/iio/humidity/dht11.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/iio/humidity/dht11.c b/drivers/iio/humidity/dht11.c index f546ecae90f1..7717f5c3395b 100644 --- a/drivers/iio/humidity/dht11.c +++ b/drivers/iio/humidity/dht11.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -57,6 +58,7 @@ struct dht11 { int irq; struct completion completion; + struct mutex lock; s64 timestamp; int temperature; @@ -145,6 +147,7 @@ static int dht11_read_raw(struct iio_dev *iio_dev, struct dht11 *dht11 = iio_priv(iio_dev); int ret; + mutex_lock(&dht11->lock); if (dht11->timestamp + DHT11_DATA_VALID_TIME < iio_get_time_ns()) { reinit_completion(&dht11->completion); @@ -185,6 +188,7 @@ static int dht11_read_raw(struct iio_dev *iio_dev, ret = -EINVAL; err: dht11->num_edges = -1; + mutex_unlock(&dht11->lock); return ret; } @@ -268,6 +272,7 @@ static int dht11_probe(struct platform_device *pdev) platform_set_drvdata(pdev, iio); init_completion(&dht11->completion); + mutex_init(&dht11->lock); iio->name = pdev->name; iio->dev.parent = &pdev->dev; iio->info = &dht11_iio_info; -- GitLab From 94e65519abde01cbffb9c538a4598f6a50bc86d1 Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Wed, 7 Jan 2015 13:22:49 +0100 Subject: [PATCH 00003/11651] iio: dht11: IRQ fixes Since setting irq-enabled GPIOs into output state is not supported by all GPIO controllers, we need to disable the irq while requesting sensor data. As side effect we lose a tiny bit of functionality: Some wiring problems can't be concluded from log messages anymore. Signed-off-by: Richard Weinberger Signed-off-by: Harald Geyer Signed-off-by: Jonathan Cameron --- drivers/iio/humidity/dht11.c | 62 ++++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 27 deletions(-) diff --git a/drivers/iio/humidity/dht11.c b/drivers/iio/humidity/dht11.c index 7717f5c3395b..7d79a1ac5f5f 100644 --- a/drivers/iio/humidity/dht11.c +++ b/drivers/iio/humidity/dht11.c @@ -40,8 +40,12 @@ #define DHT11_DATA_VALID_TIME 2000000000 /* 2s in ns */ -#define DHT11_EDGES_PREAMBLE 4 +#define DHT11_EDGES_PREAMBLE 2 #define DHT11_BITS_PER_READ 40 +/* + * Note that when reading the sensor actually 84 edges are detected, but + * since the last edge is not significant, we only store 83: + */ #define DHT11_EDGES_PER_READ (2*DHT11_BITS_PER_READ + DHT11_EDGES_PREAMBLE + 1) /* Data transmission timing (nano seconds) */ @@ -140,6 +144,27 @@ static int dht11_decode(struct dht11 *dht11, int offset) return 0; } +/* + * IRQ handler called on GPIO edges + */ +static irqreturn_t dht11_handle_irq(int irq, void *data) +{ + struct iio_dev *iio = data; + struct dht11 *dht11 = iio_priv(iio); + + /* TODO: Consider making the handler safe for IRQ sharing */ + if (dht11->num_edges < DHT11_EDGES_PER_READ && dht11->num_edges >= 0) { + dht11->edges[dht11->num_edges].ts = iio_get_time_ns(); + dht11->edges[dht11->num_edges++].value = + gpio_get_value(dht11->gpio); + + if (dht11->num_edges >= DHT11_EDGES_PER_READ) + complete(&dht11->completion); + } + + return IRQ_HANDLED; +} + static int dht11_read_raw(struct iio_dev *iio_dev, const struct iio_chan_spec *chan, int *val, int *val2, long m) @@ -160,8 +185,17 @@ static int dht11_read_raw(struct iio_dev *iio_dev, if (ret) goto err; + ret = request_irq(dht11->irq, dht11_handle_irq, + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, + iio_dev->name, iio_dev); + if (ret) + goto err; + ret = wait_for_completion_killable_timeout(&dht11->completion, HZ); + + free_irq(dht11->irq, iio_dev); + if (ret == 0 && dht11->num_edges < DHT11_EDGES_PER_READ - 1) { dev_err(&iio_dev->dev, "Only %d signal edges detected\n", @@ -197,27 +231,6 @@ static const struct iio_info dht11_iio_info = { .read_raw = dht11_read_raw, }; -/* - * IRQ handler called on GPIO edges -*/ -static irqreturn_t dht11_handle_irq(int irq, void *data) -{ - struct iio_dev *iio = data; - struct dht11 *dht11 = iio_priv(iio); - - /* TODO: Consider making the handler safe for IRQ sharing */ - if (dht11->num_edges < DHT11_EDGES_PER_READ && dht11->num_edges >= 0) { - dht11->edges[dht11->num_edges].ts = iio_get_time_ns(); - dht11->edges[dht11->num_edges++].value = - gpio_get_value(dht11->gpio); - - if (dht11->num_edges >= DHT11_EDGES_PER_READ) - complete(&dht11->completion); - } - - return IRQ_HANDLED; -} - static const struct iio_chan_spec dht11_chan_spec[] = { { .type = IIO_TEMP, .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), }, @@ -260,11 +273,6 @@ static int dht11_probe(struct platform_device *pdev) dev_err(dev, "GPIO %d has no interrupt\n", dht11->gpio); return -EINVAL; } - ret = devm_request_irq(dev, dht11->irq, dht11_handle_irq, - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, - pdev->name, iio); - if (ret) - return ret; dht11->timestamp = iio_get_time_ns() - DHT11_DATA_VALID_TIME - 1; dht11->num_edges = -1; -- GitLab From f2229ab8611e6e79992b6357db3fb4faf70e74a9 Mon Sep 17 00:00:00 2001 From: Nicholas Mc Guire Date: Wed, 31 Dec 2014 03:59:46 -0500 Subject: [PATCH 00004/11651] iio: iadc: wait_for_completion_timeout time in jiffies The timeout value to wait_for_completion_timeout is in jiffies but the value being passed seems like it was intended to by microseconds Note that the timeout was extremely long thus it might be too short now. In any case it probably should be passed through usecs_to_jiffies() or msecs_to_jiffies() patch is against linux-next 3.19.0-rc1 -next-20141226 patch was only compile-tested x86_64_defcofnig + CONFIG_SPMI=m CONFIG_IIO=m, CONFIG_QCOM_SPMI_IADC=m Signed-off-by: Nicholas Mc Guire Acked-by: Ivan T. Ivanov Signed-off-by: Jonathan Cameron --- drivers/iio/adc/qcom-spmi-iadc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/iio/adc/qcom-spmi-iadc.c b/drivers/iio/adc/qcom-spmi-iadc.c index b9666f2f5e51..fabd24edc2a1 100644 --- a/drivers/iio/adc/qcom-spmi-iadc.c +++ b/drivers/iio/adc/qcom-spmi-iadc.c @@ -296,7 +296,8 @@ static int iadc_do_conversion(struct iadc_chip *iadc, int chan, u16 *data) if (iadc->poll_eoc) { ret = iadc_poll_wait_eoc(iadc, wait); } else { - ret = wait_for_completion_timeout(&iadc->complete, wait); + ret = wait_for_completion_timeout(&iadc->complete, + usecs_to_jiffies(wait)); if (!ret) ret = -ETIMEDOUT; else -- GitLab From 4f33fbae555000bf73aaacbc4f5b24668afc8c7a Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Fri, 9 Jan 2015 15:13:37 -0800 Subject: [PATCH 00005/11651] iio: imu: inv_mpu6050: Prevent dereferencing NULL When id is null, with ACPI enumeration, don't dereference it. Signed-off-by: Srinivas Pandruvada Signed-off-by: Jonathan Cameron --- drivers/iio/imu/inv_mpu6050/inv_mpu_core.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c index b75519deac1a..eedd3e07d27c 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c @@ -690,7 +690,11 @@ static int inv_mpu_probe(struct i2c_client *client, i2c_set_clientdata(client, indio_dev); indio_dev->dev.parent = &client->dev; - indio_dev->name = id->name; + /* id will be NULL when enumerated via ACPI */ + if (id) + indio_dev->name = (char *)id->name; + else + indio_dev->name = (char *)dev_name(&client->dev); indio_dev->channels = inv_mpu_channels; indio_dev->num_channels = ARRAY_SIZE(inv_mpu_channels); -- GitLab From 5dbcf319b283276468a52feafefeb5802d87cb8a Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 15 Jun 2014 11:11:10 +0100 Subject: [PATCH 00006/11651] drm/i2c: tda998x: add OF support for finding attached CRTCs Add support to find the attached CRTCs via OF using the newly introduced helper. Signed-off-by: Russell King --- drivers/gpu/drm/i2c/tda998x_drv.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index d4762799351d..4dcf47417aee 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__) @@ -1515,6 +1516,7 @@ static int tda998x_bind(struct device *dev, struct device *master, void *data) struct i2c_client *client = to_i2c_client(dev); struct drm_device *drm = data; struct tda998x_priv2 *priv; + uint32_t crtcs = 0; int ret; priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); @@ -1523,9 +1525,18 @@ static int tda998x_bind(struct device *dev, struct device *master, void *data) dev_set_drvdata(dev, priv); + if (dev->of_node) + crtcs = drm_of_find_possible_crtcs(drm, dev->of_node); + + /* If no CRTCs were found, fall back to our old behaviour */ + if (crtcs == 0) { + dev_warn(dev, "Falling back to first CRTC\n"); + crtcs = 1 << 0; + } + priv->base.encoder = &priv->encoder; priv->connector.interlace_allowed = 1; - priv->encoder.possible_crtcs = 1 << 0; + priv->encoder.possible_crtcs = crtcs; ret = tda998x_create(client, &priv->base); if (ret) -- GitLab From 288ffc73f6e9be6334ca491994cc01110bebfc96 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 7 Dec 2014 20:20:59 +0100 Subject: [PATCH 00007/11651] drm/i2c: tda998x: fix misspelling of current function in string Replace a misspelled function name by %s and then __func__. This was done using Coccinelle, including the use of Levenshtein distance, as proposed by Rasmus Villemoes. Signed-off-by: Julia Lawall Signed-off-by: Russell King --- drivers/gpu/drm/i2c/tda998x_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index 4dcf47417aee..d853ab5ba472 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c @@ -386,7 +386,7 @@ set_page(struct tda998x_priv *priv, uint16_t reg) }; int ret = i2c_master_send(client, buf, sizeof(buf)); if (ret < 0) { - dev_err(&client->dev, "setpage %04x err %d\n", + dev_err(&client->dev, "%s %04x err %d\n", __func__, reg, ret); return ret; } -- GitLab From 07259f8b9fbd30fcef595e872deeea5ffab934ed Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 16 Jan 2015 18:37:43 +0200 Subject: [PATCH 00008/11651] drm/i2c: tda998x: use drm_do_get_edid() Replace the internal EDID read implementation by a call to the new EDID read core function. Signed-off-by: Laurent Pinchart Reviewed-by: Rob Clark Tested-by: Jean-Francois Moine Signed-off-by: Russell King --- drivers/gpu/drm/i2c/tda998x_drv.c | 86 +++++++------------------------ 1 file changed, 18 insertions(+), 68 deletions(-) diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index d853ab5ba472..43d5d91fe880 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c @@ -1012,8 +1012,9 @@ tda998x_encoder_detect(struct tda998x_priv *priv) connector_status_disconnected; } -static int read_edid_block(struct tda998x_priv *priv, uint8_t *buf, int blk) +static int read_edid_block(void *data, u8 *buf, unsigned int blk, size_t length) { + struct tda998x_priv *priv = data; uint8_t offset, segptr; int ret, i; @@ -1057,8 +1058,8 @@ static int read_edid_block(struct tda998x_priv *priv, uint8_t *buf, int blk) return -ETIMEDOUT; } - ret = reg_read_range(priv, REG_EDID_DATA_0, buf, EDID_LENGTH); - if (ret != EDID_LENGTH) { + ret = reg_read_range(priv, REG_EDID_DATA_0, buf, length); + if (ret != length) { dev_err(&priv->hdmi->dev, "failed to read edid block %d: %d\n", blk, ret); return ret; @@ -1067,82 +1068,31 @@ static int read_edid_block(struct tda998x_priv *priv, uint8_t *buf, int blk) return 0; } -static uint8_t *do_get_edid(struct tda998x_priv *priv) +static int +tda998x_encoder_get_modes(struct tda998x_priv *priv, + struct drm_connector *connector) { - int j, valid_extensions = 0; - uint8_t *block, *new; - bool print_bad_edid = drm_debug & DRM_UT_KMS; - - if ((block = kmalloc(EDID_LENGTH, GFP_KERNEL)) == NULL) - return NULL; + struct edid *edid; + int n; if (priv->rev == TDA19988) reg_clear(priv, REG_TX4, TX4_PD_RAM); - /* base block fetch */ - if (read_edid_block(priv, block, 0)) - goto fail; - - if (!drm_edid_block_valid(block, 0, print_bad_edid)) - goto fail; - - /* if there's no extensions, we're done */ - if (block[0x7e] == 0) - goto done; - - new = krealloc(block, (block[0x7e] + 1) * EDID_LENGTH, GFP_KERNEL); - if (!new) - goto fail; - block = new; - - for (j = 1; j <= block[0x7e]; j++) { - uint8_t *ext_block = block + (valid_extensions + 1) * EDID_LENGTH; - if (read_edid_block(priv, ext_block, j)) - goto fail; - - if (!drm_edid_block_valid(ext_block, j, print_bad_edid)) - goto fail; + edid = drm_do_get_edid(connector, read_edid_block, priv); - valid_extensions++; - } - - if (valid_extensions != block[0x7e]) { - block[EDID_LENGTH-1] += block[0x7e] - valid_extensions; - block[0x7e] = valid_extensions; - new = krealloc(block, (valid_extensions + 1) * EDID_LENGTH, GFP_KERNEL); - if (!new) - goto fail; - block = new; - } - -done: if (priv->rev == TDA19988) reg_set(priv, REG_TX4, TX4_PD_RAM); - return block; - -fail: - if (priv->rev == TDA19988) - reg_set(priv, REG_TX4, TX4_PD_RAM); - dev_warn(&priv->hdmi->dev, "failed to read EDID\n"); - kfree(block); - return NULL; -} - -static int -tda998x_encoder_get_modes(struct tda998x_priv *priv, - struct drm_connector *connector) -{ - struct edid *edid = (struct edid *)do_get_edid(priv); - int n = 0; - - if (edid) { - drm_mode_connector_update_edid_property(connector, edid); - n = drm_add_edid_modes(connector, edid); - priv->is_hdmi_sink = drm_detect_hdmi_monitor(edid); - kfree(edid); + if (!edid) { + dev_warn(&priv->hdmi->dev, "failed to read EDID\n"); + return 0; } + drm_mode_connector_update_edid_property(connector, edid); + n = drm_add_edid_modes(connector, edid); + priv->is_hdmi_sink = drm_detect_hdmi_monitor(edid); + kfree(edid); + return n; } -- GitLab From fb8b7d2b9d80e1e71f379e57355936bd2b024be9 Mon Sep 17 00:00:00 2001 From: Jammy Zhou Date: Wed, 21 Jan 2015 18:35:47 +0800 Subject: [PATCH 00009/11651] reservation: wait only with non-zero timeout specified (v3) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the timeout value passed to reservation_object_wait_timeout_rcu is zero, no wait should be done if the fences are not signaled. Return '1' for idle and '0' for busy if the specified timeout is '0' to keep consistent with the case of non-zero timeout. v2: call fence_put if not signaled in the case of timeout==0 v3: switch to reservation_object_test_signaled_rcu Signed-off-by: Jammy Zhou Reviewed-by: Christian König Reviewed-by: Alex Deucher Reviewed-By: Maarten Lankhorst Signed-off-by: Sumit Semwal --- drivers/dma-buf/reservation.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/dma-buf/reservation.c b/drivers/dma-buf/reservation.c index 3c97c8fa8d02..807ef1555255 100644 --- a/drivers/dma-buf/reservation.c +++ b/drivers/dma-buf/reservation.c @@ -327,6 +327,9 @@ long reservation_object_wait_timeout_rcu(struct reservation_object *obj, unsigned seq, shared_count, i = 0; long ret = timeout; + if (!timeout) + return reservation_object_test_signaled_rcu(obj, wait_all); + retry: fence = NULL; shared_count = 0; -- GitLab From 847b19a39e4c9b5e74c40f0842c48b41664cb43c Mon Sep 17 00:00:00 2001 From: Jammy Zhou Date: Wed, 21 Jan 2015 18:35:48 +0800 Subject: [PATCH 00010/11651] dma-buf/fence: don't wait when specified timeout is zero MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When specified timeout is zero for fence_wait_timeout, just check if the fence is signaled or not without wait. Signed-off-by: Jammy Zhou Reviewed-by: Christian König Reviewed-By: Maarten Lankhorst Signed-off-by: Sumit Semwal --- drivers/dma-buf/fence.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/dma-buf/fence.c b/drivers/dma-buf/fence.c index e5541117b3e9..50ef8bd8708b 100644 --- a/drivers/dma-buf/fence.c +++ b/drivers/dma-buf/fence.c @@ -159,6 +159,9 @@ fence_wait_timeout(struct fence *fence, bool intr, signed long timeout) if (WARN_ON(timeout < 0)) return -EINVAL; + if (timeout == 0) + return fence_is_signaled(fence); + trace_fence_wait_start(fence); ret = fence->ops->wait(fence, intr, timeout); trace_fence_wait_end(fence); -- GitLab From 4eb2440ed60fb5793f7aa6da89b3d517cc59de43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 22 Jan 2015 16:00:17 +0900 Subject: [PATCH 00011/11651] reservation: Remove shadowing local variable 'ret' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It was causing the return value of fence_is_signaled to be ignored, making reservation objects signal too early. Cc: stable@vger.kernel.org Reviewed-by: Maarten Lankhorst Reviewed-by: Alex Deucher Signed-off-by: Michel Dänzer Signed-off-by: Sumit Semwal --- drivers/dma-buf/reservation.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/dma-buf/reservation.c b/drivers/dma-buf/reservation.c index 807ef1555255..39920d77f288 100644 --- a/drivers/dma-buf/reservation.c +++ b/drivers/dma-buf/reservation.c @@ -405,8 +405,6 @@ reservation_object_test_signaled_single(struct fence *passed_fence) int ret = 1; if (!test_bit(FENCE_FLAG_SIGNALED_BIT, &lfence->flags)) { - int ret; - fence = fence_get_rcu(lfence); if (!fence) return -1; -- GitLab From 163f9eb95a10371ead59b62087e0d4e7ce53112e Mon Sep 17 00:00:00 2001 From: David Howells Date: Wed, 21 Jan 2015 20:03:40 +0000 Subject: [PATCH 00012/11651] debugfs: Provide a file creation function that also takes an initial size Provide a file creation function that also takes an initial size so that the caller doesn't have to set i_size, thus meaning that we don't have to call deal with ->d_inode in the callers. Signed-off-by: David Howells --- drivers/infiniband/hw/cxgb4/device.c | 35 +++++----------- .../ethernet/chelsio/cxgb4/cxgb4_debugfs.c | 9 ++--- drivers/scsi/csiostor/csio_init.c | 9 ++--- drivers/usb/gadget/udc/atmel_usba_udc.c | 15 ++++--- fs/debugfs/inode.c | 40 +++++++++++++++++++ include/linux/debugfs.h | 13 ++++++ 6 files changed, 79 insertions(+), 42 deletions(-) diff --git a/drivers/infiniband/hw/cxgb4/device.c b/drivers/infiniband/hw/cxgb4/device.c index eb5df4e62703..391309a55360 100644 --- a/drivers/infiniband/hw/cxgb4/device.c +++ b/drivers/infiniband/hw/cxgb4/device.c @@ -700,37 +700,24 @@ static const struct file_operations ep_debugfs_fops = { static int setup_debugfs(struct c4iw_dev *devp) { - struct dentry *de; - if (!devp->debugfs_root) return -1; - de = debugfs_create_file("qps", S_IWUSR, devp->debugfs_root, - (void *)devp, &qp_debugfs_fops); - if (de && de->d_inode) - de->d_inode->i_size = 4096; + debugfs_create_file_size("qps", S_IWUSR, devp->debugfs_root, + (void *)devp, &qp_debugfs_fops, 4096); - de = debugfs_create_file("stags", S_IWUSR, devp->debugfs_root, - (void *)devp, &stag_debugfs_fops); - if (de && de->d_inode) - de->d_inode->i_size = 4096; + debugfs_create_file_size("stags", S_IWUSR, devp->debugfs_root, + (void *)devp, &stag_debugfs_fops, 4096); - de = debugfs_create_file("stats", S_IWUSR, devp->debugfs_root, - (void *)devp, &stats_debugfs_fops); - if (de && de->d_inode) - de->d_inode->i_size = 4096; + debugfs_create_file_size("stats", S_IWUSR, devp->debugfs_root, + (void *)devp, &stats_debugfs_fops, 4096); - de = debugfs_create_file("eps", S_IWUSR, devp->debugfs_root, - (void *)devp, &ep_debugfs_fops); - if (de && de->d_inode) - de->d_inode->i_size = 4096; + debugfs_create_file_size("eps", S_IWUSR, devp->debugfs_root, + (void *)devp, &ep_debugfs_fops, 4096); - if (c4iw_wr_log) { - de = debugfs_create_file("wr_log", S_IWUSR, devp->debugfs_root, - (void *)devp, &wr_log_debugfs_fops); - if (de && de->d_inode) - de->d_inode->i_size = 4096; - } + if (c4iw_wr_log) + debugfs_create_file_size("wr_log", S_IWUSR, devp->debugfs_root, + (void *)devp, &wr_log_debugfs_fops, 4096); return 0; } diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c index c98a350d857e..4c7fe447e407 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c @@ -91,12 +91,9 @@ static const struct file_operations mem_debugfs_fops = { static void add_debugfs_mem(struct adapter *adap, const char *name, unsigned int idx, unsigned int size_mb) { - struct dentry *de; - - de = debugfs_create_file(name, S_IRUSR, adap->debugfs_root, - (void *)adap + idx, &mem_debugfs_fops); - if (de && de->d_inode) - de->d_inode->i_size = size_mb << 20; + debugfs_create_file_size(name, S_IRUSR, adap->debugfs_root, + (void *)adap + idx, &mem_debugfs_fops, + size_mb << 20); } /* Add an array of Debug FS files. diff --git a/drivers/scsi/csiostor/csio_init.c b/drivers/scsi/csiostor/csio_init.c index 34d20cc3e110..2617f15eaeeb 100644 --- a/drivers/scsi/csiostor/csio_init.c +++ b/drivers/scsi/csiostor/csio_init.c @@ -113,12 +113,9 @@ static const struct file_operations csio_mem_debugfs_fops = { void csio_add_debugfs_mem(struct csio_hw *hw, const char *name, unsigned int idx, unsigned int size_mb) { - struct dentry *de; - - de = debugfs_create_file(name, S_IRUSR, hw->debugfs_root, - (void *)hw + idx, &csio_mem_debugfs_fops); - if (de && de->d_inode) - de->d_inode->i_size = size_mb << 20; + debugfs_create_file_size(name, S_IRUSR, hw->debugfs_root, + (void *)hw + idx, &csio_mem_debugfs_fops, + size_mb << 20); } static int csio_setup_debugfs(struct csio_hw *hw) diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.c b/drivers/usb/gadget/udc/atmel_usba_udc.c index 9f93bed42052..b2239a2d4941 100644 --- a/drivers/usb/gadget/udc/atmel_usba_udc.c +++ b/drivers/usb/gadget/udc/atmel_usba_udc.c @@ -264,14 +264,17 @@ static void usba_init_debugfs(struct usba_udc *udc) goto err_root; udc->debugfs_root = root; - regs = debugfs_create_file("regs", 0400, root, udc, ®s_dbg_fops); - if (!regs) - goto err_regs; - regs_resource = platform_get_resource(udc->pdev, IORESOURCE_MEM, CTRL_IOMEM_ID); - regs->d_inode->i_size = resource_size(regs_resource); - udc->debugfs_regs = regs; + + if (regs_resource) { + regs = debugfs_create_file_size("regs", 0400, root, udc, + ®s_dbg_fops, + resource_size(regs_resource)); + if (!regs) + goto err_regs; + udc->debugfs_regs = regs; + } usba_ep_init_debugfs(udc, to_usba_ep(udc->gadget.ep0)); diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index 957c40ce09f6..45b18a5e225c 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c @@ -337,6 +337,46 @@ struct dentry *debugfs_create_file(const char *name, umode_t mode, } EXPORT_SYMBOL_GPL(debugfs_create_file); +/** + * debugfs_create_file_size - create a file in the debugfs filesystem + * @name: a pointer to a string containing the name of the file to create. + * @mode: the permission that the file should have. + * @parent: a pointer to the parent dentry for this file. This should be a + * directory dentry if set. If this parameter is NULL, then the + * file will be created in the root of the debugfs filesystem. + * @data: a pointer to something that the caller will want to get to later + * on. The inode.i_private pointer will point to this value on + * the open() call. + * @fops: a pointer to a struct file_operations that should be used for + * this file. + * @file_size: initial file size + * + * This is the basic "create a file" function for debugfs. It allows for a + * wide range of flexibility in creating a file, or a directory (if you want + * to create a directory, the debugfs_create_dir() function is + * recommended to be used instead.) + * + * This function will return a pointer to a dentry if it succeeds. This + * pointer must be passed to the debugfs_remove() function when the file is + * to be removed (no automatic cleanup happens if your module is unloaded, + * you are responsible here.) If an error occurs, %NULL will be returned. + * + * If debugfs is not enabled in the kernel, the value -%ENODEV will be + * returned. + */ +struct dentry *debugfs_create_file_size(const char *name, umode_t mode, + struct dentry *parent, void *data, + const struct file_operations *fops, + loff_t file_size) +{ + struct dentry *de = debugfs_create_file(name, mode, parent, data, fops); + + if (de) + de->d_inode->i_size = file_size; + return de; +} +EXPORT_SYMBOL_GPL(debugfs_create_file_size); + /** * debugfs_create_dir - create a directory in the debugfs filesystem * @name: a pointer to a string containing the name of the directory to diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h index ea149a24a1f2..cb25af461054 100644 --- a/include/linux/debugfs.h +++ b/include/linux/debugfs.h @@ -51,6 +51,11 @@ struct dentry *debugfs_create_file(const char *name, umode_t mode, struct dentry *parent, void *data, const struct file_operations *fops); +struct dentry *debugfs_create_file_size(const char *name, umode_t mode, + struct dentry *parent, void *data, + const struct file_operations *fops, + loff_t file_size); + struct dentry *debugfs_create_dir(const char *name, struct dentry *parent); struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent, @@ -129,6 +134,14 @@ static inline struct dentry *debugfs_create_file(const char *name, umode_t mode, return ERR_PTR(-ENODEV); } +static inline struct dentry *debugfs_create_file_size(const char *name, umode_t mode, + struct dentry *parent, void *data, + const struct file_operations *fops, + loff_t file_size) +{ + return ERR_PTR(-ENODEV); +} + static inline struct dentry *debugfs_create_dir(const char *name, struct dentry *parent) { -- GitLab From f81197b8a31b8fb287ae57f597b5b6841e1ece92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristina=20Mart=C5=A1enko?= Date: Sun, 25 Jan 2015 18:28:19 +0200 Subject: [PATCH 00013/11651] iio: mxs-lradc: separate touchscreen and buffer virtual channels MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The touchscreen was initially designed [1] to map all of its physical channels to one virtual channel, leaving buffered capture to use the remaining 7 virtual channels. When the touchscreen was reimplemented [2], it was made to use four virtual channels, which overlap and conflict with the channels the buffer uses. As a result, when the buffer is enabled, the touchscreen's virtual channels are remapped to whichever physical channels the buffer was configured with, causing the touchscreen to read those instead of the touch measurement channels. Effectively the touchscreen stops working. So here we separate the channels again, giving the touchscreen 2 virtual channels and the buffer 6. We can't give the touchscreen just 1 channel as before, as the current pressure calculation requires 2 channels to be read at the same time. This makes the touchscreen continue to work during buffered capture. It has been tested on i.MX28, but not on i.MX23. [1] 06ddd353f5c8 ("iio: mxs: Implement support for touchscreen") [2] dee05308f602 ("Staging/iio/adc/touchscreen/MXS: add interrupt driven touch detection") Signed-off-by: Kristina Martšenko Reviewed-by: Marek Vasut Cc: Stable@vger.kernel.org Signed-off-by: Jonathan Cameron --- drivers/staging/iio/adc/mxs-lradc.c | 166 +++++++++++++--------------- 1 file changed, 75 insertions(+), 91 deletions(-) diff --git a/drivers/staging/iio/adc/mxs-lradc.c b/drivers/staging/iio/adc/mxs-lradc.c index f053535385bf..4e574b76ead0 100644 --- a/drivers/staging/iio/adc/mxs-lradc.c +++ b/drivers/staging/iio/adc/mxs-lradc.c @@ -214,11 +214,14 @@ struct mxs_lradc { unsigned long is_divided; /* - * Touchscreen LRADC channels receives a private slot in the CTRL4 - * register, the slot #7. Therefore only 7 slots instead of 8 in the - * CTRL4 register can be mapped to LRADC channels when using the - * touchscreen. - * + * When the touchscreen is enabled, we give it two private virtual + * channels: #6 and #7. This means that only 6 virtual channels (instead + * of 8) will be available for buffered capture. + */ +#define TOUCHSCREEN_VCHANNEL1 7 +#define TOUCHSCREEN_VCHANNEL2 6 + + /* * Furthermore, certain LRADC channels are shared between touchscreen * and/or touch-buttons and generic LRADC block. Therefore when using * either of these, these channels are not available for the regular @@ -342,6 +345,9 @@ struct mxs_lradc { #define LRADC_CTRL4 0x140 #define LRADC_CTRL4_LRADCSELECT_MASK(n) (0xf << ((n) * 4)) #define LRADC_CTRL4_LRADCSELECT_OFFSET(n) ((n) * 4) +#define LRADC_CTRL4_LRADCSELECT(n, x) \ + (((x) << LRADC_CTRL4_LRADCSELECT_OFFSET(n)) & \ + LRADC_CTRL4_LRADCSELECT_MASK(n)) #define LRADC_RESOLUTION 12 #define LRADC_SINGLE_SAMPLE_MASK ((1 << LRADC_RESOLUTION) - 1) @@ -416,6 +422,14 @@ static bool mxs_lradc_check_touch_event(struct mxs_lradc *lradc) LRADC_STATUS_TOUCH_DETECT_RAW); } +static void mxs_lradc_map_channel(struct mxs_lradc *lradc, unsigned vch, + unsigned ch) +{ + mxs_lradc_reg_clear(lradc, LRADC_CTRL4_LRADCSELECT_MASK(vch), + LRADC_CTRL4); + mxs_lradc_reg_set(lradc, LRADC_CTRL4_LRADCSELECT(vch, ch), LRADC_CTRL4); +} + static void mxs_lradc_setup_ts_channel(struct mxs_lradc *lradc, unsigned ch) { /* @@ -443,12 +457,8 @@ static void mxs_lradc_setup_ts_channel(struct mxs_lradc *lradc, unsigned ch) LRADC_DELAY_DELAY(lradc->over_sample_delay - 1), LRADC_DELAY(3)); - mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ(2) | - LRADC_CTRL1_LRADC_IRQ(3) | LRADC_CTRL1_LRADC_IRQ(4) | - LRADC_CTRL1_LRADC_IRQ(5), LRADC_CTRL1); + mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ(ch), LRADC_CTRL1); - /* wake us again, when the complete conversion is done */ - mxs_lradc_reg_set(lradc, LRADC_CTRL1_LRADC_IRQ_EN(ch), LRADC_CTRL1); /* * after changing the touchscreen plates setting * the signals need some initial time to settle. Start the @@ -502,12 +512,8 @@ static void mxs_lradc_setup_ts_pressure(struct mxs_lradc *lradc, unsigned ch1, LRADC_DELAY_DELAY(lradc->over_sample_delay - 1), LRADC_DELAY(3)); - mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ(2) | - LRADC_CTRL1_LRADC_IRQ(3) | LRADC_CTRL1_LRADC_IRQ(4) | - LRADC_CTRL1_LRADC_IRQ(5), LRADC_CTRL1); + mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ(ch2), LRADC_CTRL1); - /* wake us again, when the conversions are done */ - mxs_lradc_reg_set(lradc, LRADC_CTRL1_LRADC_IRQ_EN(ch2), LRADC_CTRL1); /* * after changing the touchscreen plates setting * the signals need some initial time to settle. Start the @@ -573,36 +579,6 @@ static unsigned mxs_lradc_read_ts_pressure(struct mxs_lradc *lradc, #define TS_CH_XM 4 #define TS_CH_YM 5 -static int mxs_lradc_read_ts_channel(struct mxs_lradc *lradc) -{ - u32 reg; - int val; - - reg = readl(lradc->base + LRADC_CTRL1); - - /* only channels 3 to 5 are of interest here */ - if (reg & LRADC_CTRL1_LRADC_IRQ(TS_CH_YP)) { - mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ_EN(TS_CH_YP) | - LRADC_CTRL1_LRADC_IRQ(TS_CH_YP), LRADC_CTRL1); - val = mxs_lradc_read_raw_channel(lradc, TS_CH_YP); - } else if (reg & LRADC_CTRL1_LRADC_IRQ(TS_CH_XM)) { - mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ_EN(TS_CH_XM) | - LRADC_CTRL1_LRADC_IRQ(TS_CH_XM), LRADC_CTRL1); - val = mxs_lradc_read_raw_channel(lradc, TS_CH_XM); - } else if (reg & LRADC_CTRL1_LRADC_IRQ(TS_CH_YM)) { - mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ_EN(TS_CH_YM) | - LRADC_CTRL1_LRADC_IRQ(TS_CH_YM), LRADC_CTRL1); - val = mxs_lradc_read_raw_channel(lradc, TS_CH_YM); - } else { - return -EIO; - } - - mxs_lradc_reg_wrt(lradc, 0, LRADC_DELAY(2)); - mxs_lradc_reg_wrt(lradc, 0, LRADC_DELAY(3)); - - return val; -} - /* * YP(open)--+-------------+ * | |--+ @@ -646,7 +622,8 @@ static void mxs_lradc_prepare_x_pos(struct mxs_lradc *lradc) mxs_lradc_reg_set(lradc, mxs_lradc_drive_x_plate(lradc), LRADC_CTRL0); lradc->cur_plate = LRADC_SAMPLE_X; - mxs_lradc_setup_ts_channel(lradc, TS_CH_YP); + mxs_lradc_map_channel(lradc, TOUCHSCREEN_VCHANNEL1, TS_CH_YP); + mxs_lradc_setup_ts_channel(lradc, TOUCHSCREEN_VCHANNEL1); } /* @@ -667,7 +644,8 @@ static void mxs_lradc_prepare_y_pos(struct mxs_lradc *lradc) mxs_lradc_reg_set(lradc, mxs_lradc_drive_y_plate(lradc), LRADC_CTRL0); lradc->cur_plate = LRADC_SAMPLE_Y; - mxs_lradc_setup_ts_channel(lradc, TS_CH_XM); + mxs_lradc_map_channel(lradc, TOUCHSCREEN_VCHANNEL1, TS_CH_XM); + mxs_lradc_setup_ts_channel(lradc, TOUCHSCREEN_VCHANNEL1); } /* @@ -688,7 +666,10 @@ static void mxs_lradc_prepare_pressure(struct mxs_lradc *lradc) mxs_lradc_reg_set(lradc, mxs_lradc_drive_pressure(lradc), LRADC_CTRL0); lradc->cur_plate = LRADC_SAMPLE_PRESSURE; - mxs_lradc_setup_ts_pressure(lradc, TS_CH_XP, TS_CH_YM); + mxs_lradc_map_channel(lradc, TOUCHSCREEN_VCHANNEL1, TS_CH_YM); + mxs_lradc_map_channel(lradc, TOUCHSCREEN_VCHANNEL2, TS_CH_XP); + mxs_lradc_setup_ts_pressure(lradc, TOUCHSCREEN_VCHANNEL2, + TOUCHSCREEN_VCHANNEL1); } static void mxs_lradc_enable_touch_detection(struct mxs_lradc *lradc) @@ -701,6 +682,19 @@ static void mxs_lradc_enable_touch_detection(struct mxs_lradc *lradc) mxs_lradc_reg_set(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ_EN, LRADC_CTRL1); } +static void mxs_lradc_start_touch_event(struct mxs_lradc *lradc) +{ + mxs_lradc_reg_clear(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ_EN, + LRADC_CTRL1); + mxs_lradc_reg_set(lradc, + LRADC_CTRL1_LRADC_IRQ_EN(TOUCHSCREEN_VCHANNEL1), LRADC_CTRL1); + /* + * start with the Y-pos, because it uses nearly the same plate + * settings like the touch detection + */ + mxs_lradc_prepare_y_pos(lradc); +} + static void mxs_lradc_report_ts_event(struct mxs_lradc *lradc) { input_report_abs(lradc->ts_input, ABS_X, lradc->ts_x_pos); @@ -718,10 +712,12 @@ static void mxs_lradc_complete_touch_event(struct mxs_lradc *lradc) * start a dummy conversion to burn time to settle the signals * note: we are not interested in the conversion's value */ - mxs_lradc_reg_wrt(lradc, 0, LRADC_CH(5)); - mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ(5), LRADC_CTRL1); - mxs_lradc_reg_set(lradc, LRADC_CTRL1_LRADC_IRQ_EN(5), LRADC_CTRL1); - mxs_lradc_reg_wrt(lradc, LRADC_DELAY_TRIGGER(1 << 5) | + mxs_lradc_reg_wrt(lradc, 0, LRADC_CH(TOUCHSCREEN_VCHANNEL1)); + mxs_lradc_reg_clear(lradc, + LRADC_CTRL1_LRADC_IRQ(TOUCHSCREEN_VCHANNEL1) | + LRADC_CTRL1_LRADC_IRQ(TOUCHSCREEN_VCHANNEL2), LRADC_CTRL1); + mxs_lradc_reg_wrt(lradc, + LRADC_DELAY_TRIGGER(1 << TOUCHSCREEN_VCHANNEL1) | LRADC_DELAY_KICK | LRADC_DELAY_DELAY(10), /* waste 5 ms */ LRADC_DELAY(2)); } @@ -753,59 +749,45 @@ static void mxs_lradc_finish_touch_event(struct mxs_lradc *lradc, bool valid) /* if it is released, wait for the next touch via IRQ */ lradc->cur_plate = LRADC_TOUCH; - mxs_lradc_reg_clear(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ, LRADC_CTRL1); + mxs_lradc_reg_wrt(lradc, 0, LRADC_DELAY(2)); + mxs_lradc_reg_wrt(lradc, 0, LRADC_DELAY(3)); + mxs_lradc_reg_clear(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ | + LRADC_CTRL1_LRADC_IRQ_EN(TOUCHSCREEN_VCHANNEL1) | + LRADC_CTRL1_LRADC_IRQ(TOUCHSCREEN_VCHANNEL1), LRADC_CTRL1); mxs_lradc_reg_set(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ_EN, LRADC_CTRL1); } /* touchscreen's state machine */ static void mxs_lradc_handle_touch(struct mxs_lradc *lradc) { - int val; - switch (lradc->cur_plate) { case LRADC_TOUCH: - /* - * start with the Y-pos, because it uses nearly the same plate - * settings like the touch detection - */ - if (mxs_lradc_check_touch_event(lradc)) { - mxs_lradc_reg_clear(lradc, - LRADC_CTRL1_TOUCH_DETECT_IRQ_EN, - LRADC_CTRL1); - mxs_lradc_prepare_y_pos(lradc); - } + if (mxs_lradc_check_touch_event(lradc)) + mxs_lradc_start_touch_event(lradc); mxs_lradc_reg_clear(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ, LRADC_CTRL1); return; case LRADC_SAMPLE_Y: - val = mxs_lradc_read_ts_channel(lradc); - if (val < 0) { - mxs_lradc_enable_touch_detection(lradc); /* re-start */ - return; - } - lradc->ts_y_pos = val; + lradc->ts_y_pos = mxs_lradc_read_raw_channel(lradc, + TOUCHSCREEN_VCHANNEL1); mxs_lradc_prepare_x_pos(lradc); return; case LRADC_SAMPLE_X: - val = mxs_lradc_read_ts_channel(lradc); - if (val < 0) { - mxs_lradc_enable_touch_detection(lradc); /* re-start */ - return; - } - lradc->ts_x_pos = val; + lradc->ts_x_pos = mxs_lradc_read_raw_channel(lradc, + TOUCHSCREEN_VCHANNEL1); mxs_lradc_prepare_pressure(lradc); return; case LRADC_SAMPLE_PRESSURE: - lradc->ts_pressure = - mxs_lradc_read_ts_pressure(lradc, TS_CH_XP, TS_CH_YM); + lradc->ts_pressure = mxs_lradc_read_ts_pressure(lradc, + TOUCHSCREEN_VCHANNEL2, + TOUCHSCREEN_VCHANNEL1); mxs_lradc_complete_touch_event(lradc); return; case LRADC_SAMPLE_VALID: - val = mxs_lradc_read_ts_channel(lradc); /* ignore the value */ mxs_lradc_finish_touch_event(lradc, 1); break; } @@ -1083,9 +1065,8 @@ static void mxs_lradc_disable_ts(struct mxs_lradc *lradc) { /* stop all interrupts from firing */ mxs_lradc_reg_clear(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ_EN | - LRADC_CTRL1_LRADC_IRQ_EN(2) | LRADC_CTRL1_LRADC_IRQ_EN(3) | - LRADC_CTRL1_LRADC_IRQ_EN(4) | LRADC_CTRL1_LRADC_IRQ_EN(5), - LRADC_CTRL1); + LRADC_CTRL1_LRADC_IRQ_EN(TOUCHSCREEN_VCHANNEL1) | + LRADC_CTRL1_LRADC_IRQ_EN(TOUCHSCREEN_VCHANNEL2), LRADC_CTRL1); /* Power-down touchscreen touch-detect circuitry. */ mxs_lradc_reg_clear(lradc, mxs_lradc_plate_mask(lradc), LRADC_CTRL0); @@ -1151,26 +1132,29 @@ static irqreturn_t mxs_lradc_handle_irq(int irq, void *data) struct iio_dev *iio = data; struct mxs_lradc *lradc = iio_priv(iio); unsigned long reg = readl(lradc->base + LRADC_CTRL1); + uint32_t clr_irq = mxs_lradc_irq_mask(lradc); const uint32_t ts_irq_mask = LRADC_CTRL1_TOUCH_DETECT_IRQ | - LRADC_CTRL1_LRADC_IRQ(2) | - LRADC_CTRL1_LRADC_IRQ(3) | - LRADC_CTRL1_LRADC_IRQ(4) | - LRADC_CTRL1_LRADC_IRQ(5); + LRADC_CTRL1_LRADC_IRQ(TOUCHSCREEN_VCHANNEL1) | + LRADC_CTRL1_LRADC_IRQ(TOUCHSCREEN_VCHANNEL2); if (!(reg & mxs_lradc_irq_mask(lradc))) return IRQ_NONE; - if (lradc->use_touchscreen && (reg & ts_irq_mask)) + if (lradc->use_touchscreen && (reg & ts_irq_mask)) { mxs_lradc_handle_touch(lradc); + /* Make sure we don't clear the next conversion's interrupt. */ + clr_irq &= ~(LRADC_CTRL1_LRADC_IRQ(TOUCHSCREEN_VCHANNEL1) | + LRADC_CTRL1_LRADC_IRQ(TOUCHSCREEN_VCHANNEL2)); + } + if (iio_buffer_enabled(iio)) iio_trigger_poll(iio->trig); else if (reg & LRADC_CTRL1_LRADC_IRQ(0)) complete(&lradc->completion); - mxs_lradc_reg_clear(lradc, reg & mxs_lradc_irq_mask(lradc), - LRADC_CTRL1); + mxs_lradc_reg_clear(lradc, reg & clr_irq, LRADC_CTRL1); return IRQ_HANDLED; } @@ -1346,7 +1330,7 @@ static bool mxs_lradc_validate_scan_mask(struct iio_dev *iio, if (lradc->use_touchbutton) rsvd_chans++; if (lradc->use_touchscreen) - rsvd_chans++; + rsvd_chans += 2; /* Test for attempts to map channels with special mode of operation. */ if (bitmap_intersects(mask, &rsvd_mask, LRADC_MAX_TOTAL_CHANS)) -- GitLab From 86bf7f3ef7e961e91e16dceb31ae0f583483b204 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristina=20Mart=C5=A1enko?= Date: Sun, 25 Jan 2015 18:28:20 +0200 Subject: [PATCH 00014/11651] iio: mxs-lradc: make ADC reads not disable touchscreen interrupts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reading a channel through sysfs, or starting a buffered capture, will currently turn off the touchscreen. This is because the read_raw() and buffer preenable()/postdisable() callbacks disable interrupts for all LRADC channels, including those the touchscreen uses. So make the callbacks only disable interrupts for the channels they use. This means channel 0 for read_raw() and channels 0-5 for the buffer (if the touchscreen is enabled). Since the touchscreen uses different channels (6 and 7), it no longer gets turned off. Note that only i.MX28 is affected by this issue, i.MX23 should be fine. Signed-off-by: Kristina Martšenko Reviewed-by: Marek Vasut Cc: Stable@vger.kernel.org Signed-off-by: Jonathan Cameron --- drivers/staging/iio/adc/mxs-lradc.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/drivers/staging/iio/adc/mxs-lradc.c b/drivers/staging/iio/adc/mxs-lradc.c index 4e574b76ead0..653af03bc69d 100644 --- a/drivers/staging/iio/adc/mxs-lradc.c +++ b/drivers/staging/iio/adc/mxs-lradc.c @@ -220,6 +220,9 @@ struct mxs_lradc { */ #define TOUCHSCREEN_VCHANNEL1 7 #define TOUCHSCREEN_VCHANNEL2 6 +#define BUFFER_VCHANS_LIMITED 0x3f +#define BUFFER_VCHANS_ALL 0xff + u8 buffer_vchans; /* * Furthermore, certain LRADC channels are shared between touchscreen @@ -819,7 +822,7 @@ static int mxs_lradc_read_single(struct iio_dev *iio_dev, int chan, int *val) * used if doing raw sampling. */ if (lradc->soc == IMX28_LRADC) - mxs_lradc_reg_clear(lradc, LRADC_CTRL1_MX28_LRADC_IRQ_EN_MASK, + mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ_EN(0), LRADC_CTRL1); mxs_lradc_reg_clear(lradc, 0xff, LRADC_CTRL0); @@ -1266,8 +1269,9 @@ static int mxs_lradc_buffer_preenable(struct iio_dev *iio) } if (lradc->soc == IMX28_LRADC) - mxs_lradc_reg_clear(lradc, LRADC_CTRL1_MX28_LRADC_IRQ_EN_MASK, - LRADC_CTRL1); + mxs_lradc_reg_clear(lradc, + lradc->buffer_vchans << LRADC_CTRL1_LRADC_IRQ_EN_OFFSET, + LRADC_CTRL1); mxs_lradc_reg_clear(lradc, 0xff, LRADC_CTRL0); for_each_set_bit(chan, iio->active_scan_mask, LRADC_MAX_TOTAL_CHANS) { @@ -1303,8 +1307,9 @@ static int mxs_lradc_buffer_postdisable(struct iio_dev *iio) mxs_lradc_reg_clear(lradc, 0xff, LRADC_CTRL0); if (lradc->soc == IMX28_LRADC) - mxs_lradc_reg_clear(lradc, LRADC_CTRL1_MX28_LRADC_IRQ_EN_MASK, - LRADC_CTRL1); + mxs_lradc_reg_clear(lradc, + lradc->buffer_vchans << LRADC_CTRL1_LRADC_IRQ_EN_OFFSET, + LRADC_CTRL1); kfree(lradc->buffer); mutex_unlock(&lradc->lock); @@ -1542,6 +1547,11 @@ static int mxs_lradc_probe(struct platform_device *pdev) touch_ret = mxs_lradc_probe_touchscreen(lradc, node); + if (touch_ret == 0) + lradc->buffer_vchans = BUFFER_VCHANS_LIMITED; + else + lradc->buffer_vchans = BUFFER_VCHANS_ALL; + /* Grab all IRQ sources */ for (i = 0; i < of_cfg->irq_count; i++) { lradc->irq[i] = platform_get_irq(pdev, i); -- GitLab From 6abe0300a1d5242f4ff89257197f284679af1a06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristina=20Mart=C5=A1enko?= Date: Sun, 25 Jan 2015 18:28:21 +0200 Subject: [PATCH 00015/11651] iio: mxs-lradc: make ADC reads not unschedule touchscreen conversions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reading a channel through sysfs, or starting a buffered capture, can occasionally turn off the touchscreen. This is because the read_raw() and buffer preenable()/postdisable() callbacks unschedule current conversions on all channels. If a delay channel happens to schedule a touchscreen conversion at the same time, the conversion gets cancelled and the touchscreen sequence stops. This is probably related to this note from the reference manual: "If a delay group schedules channels to be sampled and a manual write to the schedule field in CTRL0 occurs while the block is discarding samples, the LRADC will switch to the new schedule and will not sample the channels that were previously scheduled. The time window for this to happen is very small and lasts only while the LRADC is discarding samples." So make the callbacks only unschedule conversions for the channels they use. This means channel 0 for read_raw() and channels 0-5 for the buffer (if the touchscreen is enabled). Since the touchscreen uses different channels (6 and 7), it no longer gets turned off. This is tested and fixes the issue on i.MX28, but hasn't been tested on i.MX23. Signed-off-by: Kristina Martšenko Reviewed-by: Marek Vasut Cc: Stable@vger.kernel.org Signed-off-by: Jonathan Cameron --- drivers/staging/iio/adc/mxs-lradc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/iio/adc/mxs-lradc.c b/drivers/staging/iio/adc/mxs-lradc.c index 653af03bc69d..d2e0c275bf4d 100644 --- a/drivers/staging/iio/adc/mxs-lradc.c +++ b/drivers/staging/iio/adc/mxs-lradc.c @@ -824,7 +824,7 @@ static int mxs_lradc_read_single(struct iio_dev *iio_dev, int chan, int *val) if (lradc->soc == IMX28_LRADC) mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ_EN(0), LRADC_CTRL1); - mxs_lradc_reg_clear(lradc, 0xff, LRADC_CTRL0); + mxs_lradc_reg_clear(lradc, 0x1, LRADC_CTRL0); /* Enable / disable the divider per requirement */ if (test_bit(chan, &lradc->is_divided)) @@ -1272,7 +1272,7 @@ static int mxs_lradc_buffer_preenable(struct iio_dev *iio) mxs_lradc_reg_clear(lradc, lradc->buffer_vchans << LRADC_CTRL1_LRADC_IRQ_EN_OFFSET, LRADC_CTRL1); - mxs_lradc_reg_clear(lradc, 0xff, LRADC_CTRL0); + mxs_lradc_reg_clear(lradc, lradc->buffer_vchans, LRADC_CTRL0); for_each_set_bit(chan, iio->active_scan_mask, LRADC_MAX_TOTAL_CHANS) { ctrl4_set |= chan << LRADC_CTRL4_LRADCSELECT_OFFSET(ofs); @@ -1305,7 +1305,7 @@ static int mxs_lradc_buffer_postdisable(struct iio_dev *iio) mxs_lradc_reg_clear(lradc, LRADC_DELAY_TRIGGER_LRADCS_MASK | LRADC_DELAY_KICK, LRADC_DELAY(0)); - mxs_lradc_reg_clear(lradc, 0xff, LRADC_CTRL0); + mxs_lradc_reg_clear(lradc, lradc->buffer_vchans, LRADC_CTRL0); if (lradc->soc == IMX28_LRADC) mxs_lradc_reg_clear(lradc, lradc->buffer_vchans << LRADC_CTRL1_LRADC_IRQ_EN_OFFSET, -- GitLab From 89bb35e200bee745c539a96666e0792301ca40f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristina=20Mart=C5=A1enko?= Date: Sun, 25 Jan 2015 18:28:22 +0200 Subject: [PATCH 00016/11651] iio: mxs-lradc: only update the buffer when its conversions have finished MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Using the touchscreen while running buffered capture results in the buffer reporting lots of wrong values, often just zeros. This is because we push readings to the buffer every time a touchscreen interrupt arrives, including when the buffer's own conversions have not yet finished. So let's only push to the buffer when its conversions are ready. Signed-off-by: Kristina Martšenko Reviewed-by: Marek Vasut Cc: Stable@vger.kernel.org Signed-off-by: Jonathan Cameron --- drivers/staging/iio/adc/mxs-lradc.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/staging/iio/adc/mxs-lradc.c b/drivers/staging/iio/adc/mxs-lradc.c index d2e0c275bf4d..ebcbd12d48b9 100644 --- a/drivers/staging/iio/adc/mxs-lradc.c +++ b/drivers/staging/iio/adc/mxs-lradc.c @@ -1152,10 +1152,12 @@ static irqreturn_t mxs_lradc_handle_irq(int irq, void *data) LRADC_CTRL1_LRADC_IRQ(TOUCHSCREEN_VCHANNEL2)); } - if (iio_buffer_enabled(iio)) - iio_trigger_poll(iio->trig); - else if (reg & LRADC_CTRL1_LRADC_IRQ(0)) + if (iio_buffer_enabled(iio)) { + if (reg & lradc->buffer_vchans) + iio_trigger_poll(iio->trig); + } else if (reg & LRADC_CTRL1_LRADC_IRQ(0)) { complete(&lradc->completion); + } mxs_lradc_reg_clear(lradc, reg & clr_irq, LRADC_CTRL1); -- GitLab From f7067a5ad717d4dbb4faa3ec56744152f6ba97ad Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Fri, 23 Jan 2015 00:09:56 +0100 Subject: [PATCH 00017/11651] staging: iio: ad2s1200: Fix sign extension The line above makes vel a 12-bit quantity (st->rx[] is u8). The intention is to sign-extend vel using bit 11 as the sign bit. But because of C's promotion rules "vel = (vel << 4) >> 4;" is actually a no-op, since vel is promoted to int before the inner shift. sign_extend32 works equally well for 8 and 16 bits types, so use that. Signed-off-by: Rasmus Villemoes Acked-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/staging/iio/resolver/ad2s1200.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/iio/resolver/ad2s1200.c b/drivers/staging/iio/resolver/ad2s1200.c index 017d2f8379b7..c17893b4918c 100644 --- a/drivers/staging/iio/resolver/ad2s1200.c +++ b/drivers/staging/iio/resolver/ad2s1200.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -68,7 +69,7 @@ static int ad2s1200_read_raw(struct iio_dev *indio_dev, break; case IIO_ANGL_VEL: vel = (((s16)(st->rx[0])) << 4) | ((st->rx[1] & 0xF0) >> 4); - vel = (vel << 4) >> 4; + vel = sign_extend32(vel, 11); *val = vel; break; default: -- GitLab From 19e353f2b344ad86cea6ebbc0002e5f903480a90 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Fri, 23 Jan 2015 00:34:02 +0100 Subject: [PATCH 00018/11651] iio: imu: adis16400: Fix sign extension The intention is obviously to sign-extend a 12 bit quantity. But because of C's promotion rules, the assignment is equivalent to "val16 &= 0xfff;". Use the proper API for this. Signed-off-by: Rasmus Villemoes Acked-by: Lars-Peter Clausen Cc: Stable@vger.kernel.org Signed-off-by: Jonathan Cameron --- drivers/iio/imu/adis16400_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/iio/imu/adis16400_core.c b/drivers/iio/imu/adis16400_core.c index b70873de04ea..fa795dcd5f75 100644 --- a/drivers/iio/imu/adis16400_core.c +++ b/drivers/iio/imu/adis16400_core.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -414,7 +415,7 @@ static int adis16400_read_raw(struct iio_dev *indio_dev, mutex_unlock(&indio_dev->mlock); if (ret) return ret; - val16 = ((val16 & 0xFFF) << 4) >> 4; + val16 = sign_extend32(val16, 11); *val = val16; return IIO_VAL_INT; case IIO_CHAN_INFO_OFFSET: -- GitLab From 03305e535cd5cdc1079b32909bf4b2dd67d46f7f Mon Sep 17 00:00:00 2001 From: Stefan Wahren Date: Sat, 3 Jan 2015 20:34:12 +0000 Subject: [PATCH 00019/11651] iio: mxs-lradc: fix iio channel map regression Since commit c8231a9af8147f8a ("iio: mxs-lradc: compute temperature from channel 8 and 9") with the removal of adc channel 9 there is no 1-1 mapping in the channel spec. All hwmon channel values above 9 are accessible via there index minus one. So add a hidden iio channel 9 to fix this issue. Signed-off-by: Stefan Wahren Acked-by: Alexandre Belloni Reviewed-by: Marek Vasut Cc: Stable@vger.kernel.org Signed-off-by: Jonathan Cameron --- drivers/staging/iio/adc/mxs-lradc.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/staging/iio/adc/mxs-lradc.c b/drivers/staging/iio/adc/mxs-lradc.c index ebcbd12d48b9..351339ccaad6 100644 --- a/drivers/staging/iio/adc/mxs-lradc.c +++ b/drivers/staging/iio/adc/mxs-lradc.c @@ -1397,6 +1397,13 @@ static const struct iio_chan_spec mxs_lradc_chan_spec[] = { .channel = 8, .scan_type = {.sign = 'u', .realbits = 18, .storagebits = 32,}, }, + /* Hidden channel to keep indexes */ + { + .type = IIO_TEMP, + .indexed = 1, + .scan_index = -1, + .channel = 9, + }, MXS_ADC_CHAN(10, IIO_VOLTAGE), /* VDDIO */ MXS_ADC_CHAN(11, IIO_VOLTAGE), /* VTH */ MXS_ADC_CHAN(12, IIO_VOLTAGE), /* VDDA */ -- GitLab From 0f67f04ffcb592d065a20862a82d4539e0f8e909 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Tue, 3 Feb 2015 11:56:20 -0500 Subject: [PATCH 00020/11651] tracing: Only create tracer options files if directory exists Do not bother creating tracer options if no tracing directory exists. If a tracer is enabled via the command line, and is started before the tracing directory is created, then it wont have its tracer specific options created. Signed-off-by: Steven Rostedt --- kernel/trace/trace.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 38c613ede10d..d4627f15407a 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -4172,8 +4172,11 @@ static int tracing_set_tracer(struct trace_array *tr, const char *buf) free_snapshot(tr); } #endif - /* Currently, only the top instance has options */ - if (tr->flags & TRACE_ARRAY_FL_GLOBAL) { + /* + * Only enable if the directory has been created already. + * Currently, only the top instance has options + */ + if (tr->dir && tr->flags & TRACE_ARRAY_FL_GLOBAL) { destroy_trace_option_files(topts); topts = create_trace_option_files(tr, t); } -- GitLab From 09d23a1d8a82e814bd56a4f121b80ea8214ac49d Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Tue, 3 Feb 2015 12:45:53 -0500 Subject: [PATCH 00021/11651] tracing: Create cmdline tracer options on tracing fs init The options for cmdline tracers are not created if the debugfs system is not ready yet. If tracing has started before debugfs is up, then the option files for the tracer are not created. Create them when creating the tracing directory if the current tracer requires option files. Signed-off-by: Steven Rostedt --- kernel/trace/trace.c | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index d4627f15407a..05e0e50539fc 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -4105,9 +4105,24 @@ static void tracing_set_nop(struct trace_array *tr) tr->current_trace = &nop_trace; } -static int tracing_set_tracer(struct trace_array *tr, const char *buf) +static void update_tracer_options(struct trace_array *tr, struct tracer *t) { static struct trace_option_dentry *topts; + + /* Only enable if the directory has been created already. */ + if (!tr->dir) + return; + + /* Currently, only the top instance has options */ + if (!(tr->flags & TRACE_ARRAY_FL_GLOBAL)) + return; + + destroy_trace_option_files(topts); + topts = create_trace_option_files(tr, t); +} + +static int tracing_set_tracer(struct trace_array *tr, const char *buf) +{ struct tracer *t; #ifdef CONFIG_TRACER_MAX_TRACE bool had_max_tr; @@ -4172,14 +4187,7 @@ static int tracing_set_tracer(struct trace_array *tr, const char *buf) free_snapshot(tr); } #endif - /* - * Only enable if the directory has been created already. - * Currently, only the top instance has options - */ - if (tr->dir && tr->flags & TRACE_ARRAY_FL_GLOBAL) { - destroy_trace_option_files(topts); - topts = create_trace_option_files(tr, t); - } + update_tracer_options(tr, t); #ifdef CONFIG_TRACER_MAX_TRACE if (t->use_max_tr && !had_max_tr) { @@ -6578,6 +6586,10 @@ static __init int tracer_init_debugfs(void) create_trace_options_dir(&global_trace); + /* If the tracer was started via cmdline, create options for it here */ + if (global_trace.current_trace != &nop_trace) + update_tracer_options(&global_trace, global_trace.current_trace); + return 0; } -- GitLab From 4282d60689d4f21b40692029080440cc58e8a17d Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Tue, 20 Jan 2015 11:36:55 -0500 Subject: [PATCH 00022/11651] tracefs: Add new tracefs file system Add a separate file system to handle the tracing directory. Currently it is part of debugfs, but that is starting to show its limits. One thing is that in order to access the tracing infrastructure, you need to mount debugfs. As that includes debugging from all sorts of sub systems in the kernel, it is not considered advisable to mount such an all encompassing debugging system. Having the tracing system in its own file systems gives access to the tracing sub system without needing to include all other systems. Another problem with tracing using the debugfs system is that the instances use mkdir to create sub buffers. debugfs does not support mkdir from userspace so to implement it, special hacks were used. By controlling the file system that the tracing infrastructure uses, this can be properly done without hacks. Signed-off-by: Steven Rostedt --- fs/Makefile | 1 + fs/tracefs/Makefile | 4 + fs/tracefs/inode.c | 522 +++++++++++++++++++++++++++++++++++++ include/linux/tracefs.h | 41 +++ include/uapi/linux/magic.h | 2 + 5 files changed, 570 insertions(+) create mode 100644 fs/tracefs/Makefile create mode 100644 fs/tracefs/inode.c create mode 100644 include/linux/tracefs.h diff --git a/fs/Makefile b/fs/Makefile index bedff48e8fdc..d244b8d973ac 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -118,6 +118,7 @@ obj-$(CONFIG_HOSTFS) += hostfs/ obj-$(CONFIG_HPPFS) += hppfs/ obj-$(CONFIG_CACHEFILES) += cachefiles/ obj-$(CONFIG_DEBUG_FS) += debugfs/ +obj-$(CONFIG_TRACING) += tracefs/ obj-$(CONFIG_OCFS2_FS) += ocfs2/ obj-$(CONFIG_BTRFS_FS) += btrfs/ obj-$(CONFIG_GFS2_FS) += gfs2/ diff --git a/fs/tracefs/Makefile b/fs/tracefs/Makefile new file mode 100644 index 000000000000..82fa35b656c4 --- /dev/null +++ b/fs/tracefs/Makefile @@ -0,0 +1,4 @@ +tracefs-objs := inode.o + +obj-$(CONFIG_TRACING) += tracefs.o + diff --git a/fs/tracefs/inode.c b/fs/tracefs/inode.c new file mode 100644 index 000000000000..5b1547a452d8 --- /dev/null +++ b/fs/tracefs/inode.c @@ -0,0 +1,522 @@ +/* + * inode.c - part of tracefs, a pseudo file system for activating tracing + * + * Based on debugfs by: Greg Kroah-Hartman + * + * Copyright (C) 2014 Red Hat Inc, author: Steven Rostedt + * + * 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. + * + * tracefs is the file system that is used by the tracing infrastructure. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TRACEFS_DEFAULT_MODE 0700 + +static struct vfsmount *tracefs_mount; +static int tracefs_mount_count; +static bool tracefs_registered; + +static ssize_t default_read_file(struct file *file, char __user *buf, + size_t count, loff_t *ppos) +{ + return 0; +} + +static ssize_t default_write_file(struct file *file, const char __user *buf, + size_t count, loff_t *ppos) +{ + return count; +} + +static const struct file_operations tracefs_file_operations = { + .read = default_read_file, + .write = default_write_file, + .open = simple_open, + .llseek = noop_llseek, +}; + +static struct inode *tracefs_get_inode(struct super_block *sb) +{ + struct inode *inode = new_inode(sb); + if (inode) { + inode->i_ino = get_next_ino(); + inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; + } + return inode; +} + +struct tracefs_mount_opts { + kuid_t uid; + kgid_t gid; + umode_t mode; +}; + +enum { + Opt_uid, + Opt_gid, + Opt_mode, + Opt_err +}; + +static const match_table_t tokens = { + {Opt_uid, "uid=%u"}, + {Opt_gid, "gid=%u"}, + {Opt_mode, "mode=%o"}, + {Opt_err, NULL} +}; + +struct tracefs_fs_info { + struct tracefs_mount_opts mount_opts; +}; + +static int tracefs_parse_options(char *data, struct tracefs_mount_opts *opts) +{ + substring_t args[MAX_OPT_ARGS]; + int option; + int token; + kuid_t uid; + kgid_t gid; + char *p; + + opts->mode = TRACEFS_DEFAULT_MODE; + + while ((p = strsep(&data, ",")) != NULL) { + if (!*p) + continue; + + token = match_token(p, tokens, args); + switch (token) { + case Opt_uid: + if (match_int(&args[0], &option)) + return -EINVAL; + uid = make_kuid(current_user_ns(), option); + if (!uid_valid(uid)) + return -EINVAL; + opts->uid = uid; + break; + case Opt_gid: + if (match_int(&args[0], &option)) + return -EINVAL; + gid = make_kgid(current_user_ns(), option); + if (!gid_valid(gid)) + return -EINVAL; + opts->gid = gid; + break; + case Opt_mode: + if (match_octal(&args[0], &option)) + return -EINVAL; + opts->mode = option & S_IALLUGO; + break; + /* + * We might like to report bad mount options here; + * but traditionally tracefs has ignored all mount options + */ + } + } + + return 0; +} + +static int tracefs_apply_options(struct super_block *sb) +{ + struct tracefs_fs_info *fsi = sb->s_fs_info; + struct inode *inode = sb->s_root->d_inode; + struct tracefs_mount_opts *opts = &fsi->mount_opts; + + inode->i_mode &= ~S_IALLUGO; + inode->i_mode |= opts->mode; + + inode->i_uid = opts->uid; + inode->i_gid = opts->gid; + + return 0; +} + +static int tracefs_remount(struct super_block *sb, int *flags, char *data) +{ + int err; + struct tracefs_fs_info *fsi = sb->s_fs_info; + + sync_filesystem(sb); + err = tracefs_parse_options(data, &fsi->mount_opts); + if (err) + goto fail; + + tracefs_apply_options(sb); + +fail: + return err; +} + +static int tracefs_show_options(struct seq_file *m, struct dentry *root) +{ + struct tracefs_fs_info *fsi = root->d_sb->s_fs_info; + struct tracefs_mount_opts *opts = &fsi->mount_opts; + + if (!uid_eq(opts->uid, GLOBAL_ROOT_UID)) + seq_printf(m, ",uid=%u", + from_kuid_munged(&init_user_ns, opts->uid)); + if (!gid_eq(opts->gid, GLOBAL_ROOT_GID)) + seq_printf(m, ",gid=%u", + from_kgid_munged(&init_user_ns, opts->gid)); + if (opts->mode != TRACEFS_DEFAULT_MODE) + seq_printf(m, ",mode=%o", opts->mode); + + return 0; +} + +static const struct super_operations tracefs_super_operations = { + .statfs = simple_statfs, + .remount_fs = tracefs_remount, + .show_options = tracefs_show_options, +}; + +static int trace_fill_super(struct super_block *sb, void *data, int silent) +{ + static struct tree_descr trace_files[] = {{""}}; + struct tracefs_fs_info *fsi; + int err; + + save_mount_options(sb, data); + + fsi = kzalloc(sizeof(struct tracefs_fs_info), GFP_KERNEL); + sb->s_fs_info = fsi; + if (!fsi) { + err = -ENOMEM; + goto fail; + } + + err = tracefs_parse_options(data, &fsi->mount_opts); + if (err) + goto fail; + + err = simple_fill_super(sb, TRACEFS_MAGIC, trace_files); + if (err) + goto fail; + + sb->s_op = &tracefs_super_operations; + + tracefs_apply_options(sb); + + return 0; + +fail: + kfree(fsi); + sb->s_fs_info = NULL; + return err; +} + +static struct dentry *trace_mount(struct file_system_type *fs_type, + int flags, const char *dev_name, + void *data) +{ + return mount_single(fs_type, flags, data, trace_fill_super); +} + +static struct file_system_type trace_fs_type = { + .owner = THIS_MODULE, + .name = "tracefs", + .mount = trace_mount, + .kill_sb = kill_litter_super, +}; +MODULE_ALIAS_FS("tracefs"); + +static struct dentry *start_creating(const char *name, struct dentry *parent) +{ + struct dentry *dentry; + int error; + + pr_debug("tracefs: creating file '%s'\n",name); + + error = simple_pin_fs(&trace_fs_type, &tracefs_mount, + &tracefs_mount_count); + if (error) + return ERR_PTR(error); + + /* If the parent is not specified, we create it in the root. + * We need the root dentry to do this, which is in the super + * block. A pointer to that is in the struct vfsmount that we + * have around. + */ + if (!parent) + parent = tracefs_mount->mnt_root; + + mutex_lock(&parent->d_inode->i_mutex); + dentry = lookup_one_len(name, parent, strlen(name)); + if (!IS_ERR(dentry) && dentry->d_inode) { + dput(dentry); + dentry = ERR_PTR(-EEXIST); + } + if (IS_ERR(dentry)) + mutex_unlock(&parent->d_inode->i_mutex); + return dentry; +} + +static struct dentry *failed_creating(struct dentry *dentry) +{ + mutex_unlock(&dentry->d_parent->d_inode->i_mutex); + dput(dentry); + simple_release_fs(&tracefs_mount, &tracefs_mount_count); + return NULL; +} + +static struct dentry *end_creating(struct dentry *dentry) +{ + mutex_unlock(&dentry->d_parent->d_inode->i_mutex); + return dentry; +} + +/** + * tracefs_create_file - create a file in the tracefs filesystem + * @name: a pointer to a string containing the name of the file to create. + * @mode: the permission that the file should have. + * @parent: a pointer to the parent dentry for this file. This should be a + * directory dentry if set. If this parameter is NULL, then the + * file will be created in the root of the tracefs filesystem. + * @data: a pointer to something that the caller will want to get to later + * on. The inode.i_private pointer will point to this value on + * the open() call. + * @fops: a pointer to a struct file_operations that should be used for + * this file. + * + * This is the basic "create a file" function for tracefs. It allows for a + * wide range of flexibility in creating a file, or a directory (if you want + * to create a directory, the tracefs_create_dir() function is + * recommended to be used instead.) + * + * This function will return a pointer to a dentry if it succeeds. This + * pointer must be passed to the tracefs_remove() function when the file is + * to be removed (no automatic cleanup happens if your module is unloaded, + * you are responsible here.) If an error occurs, %NULL will be returned. + * + * If tracefs is not enabled in the kernel, the value -%ENODEV will be + * returned. + */ +struct dentry *tracefs_create_file(const char *name, umode_t mode, + struct dentry *parent, void *data, + const struct file_operations *fops) +{ + struct dentry *dentry; + struct inode *inode; + + if (!(mode & S_IFMT)) + mode |= S_IFREG; + BUG_ON(!S_ISREG(mode)); + dentry = start_creating(name, parent); + + if (IS_ERR(dentry)) + return NULL; + + inode = tracefs_get_inode(dentry->d_sb); + if (unlikely(!inode)) + return failed_creating(dentry); + + inode->i_mode = mode; + inode->i_fop = fops ? fops : &tracefs_file_operations; + inode->i_private = data; + d_instantiate(dentry, inode); + fsnotify_create(dentry->d_parent->d_inode, dentry); + return end_creating(dentry); +} + +/** + * tracefs_create_dir - create a directory in the tracefs filesystem + * @name: a pointer to a string containing the name of the directory to + * create. + * @parent: a pointer to the parent dentry for this file. This should be a + * directory dentry if set. If this parameter is NULL, then the + * directory will be created in the root of the tracefs filesystem. + * + * This function creates a directory in tracefs with the given name. + * + * This function will return a pointer to a dentry if it succeeds. This + * pointer must be passed to the tracefs_remove() function when the file is + * to be removed. If an error occurs, %NULL will be returned. + * + * If tracing is not enabled in the kernel, the value -%ENODEV will be + * returned. + */ +struct dentry *tracefs_create_dir(const char *name, struct dentry *parent) +{ + struct dentry *dentry = start_creating(name, parent); + struct inode *inode; + + if (IS_ERR(dentry)) + return NULL; + + inode = tracefs_get_inode(dentry->d_sb); + if (unlikely(!inode)) + return failed_creating(dentry); + + inode->i_mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO; + inode->i_op = &simple_dir_inode_operations; + inode->i_fop = &simple_dir_operations; + + /* directory inodes start off with i_nlink == 2 (for "." entry) */ + inc_nlink(inode); + d_instantiate(dentry, inode); + inc_nlink(dentry->d_parent->d_inode); + fsnotify_mkdir(dentry->d_parent->d_inode, dentry); + return end_creating(dentry); +} + +static inline int tracefs_positive(struct dentry *dentry) +{ + return dentry->d_inode && !d_unhashed(dentry); +} + +static int __tracefs_remove(struct dentry *dentry, struct dentry *parent) +{ + int ret = 0; + + if (tracefs_positive(dentry)) { + if (dentry->d_inode) { + dget(dentry); + switch (dentry->d_inode->i_mode & S_IFMT) { + case S_IFDIR: + ret = simple_rmdir(parent->d_inode, dentry); + break; + default: + simple_unlink(parent->d_inode, dentry); + break; + } + if (!ret) + d_delete(dentry); + dput(dentry); + } + } + return ret; +} + +/** + * tracefs_remove - removes a file or directory from the tracefs filesystem + * @dentry: a pointer to a the dentry of the file or directory to be + * removed. + * + * This function removes a file or directory in tracefs that was previously + * created with a call to another tracefs function (like + * tracefs_create_file() or variants thereof.) + */ +void tracefs_remove(struct dentry *dentry) +{ + struct dentry *parent; + int ret; + + if (IS_ERR_OR_NULL(dentry)) + return; + + parent = dentry->d_parent; + if (!parent || !parent->d_inode) + return; + + mutex_lock(&parent->d_inode->i_mutex); + ret = __tracefs_remove(dentry, parent); + mutex_unlock(&parent->d_inode->i_mutex); + if (!ret) + simple_release_fs(&tracefs_mount, &tracefs_mount_count); +} + +/** + * tracefs_remove_recursive - recursively removes a directory + * @dentry: a pointer to a the dentry of the directory to be removed. + * + * This function recursively removes a directory tree in tracefs that + * was previously created with a call to another tracefs function + * (like tracefs_create_file() or variants thereof.) + */ +void tracefs_remove_recursive(struct dentry *dentry) +{ + struct dentry *child, *parent; + + if (IS_ERR_OR_NULL(dentry)) + return; + + parent = dentry->d_parent; + if (!parent || !parent->d_inode) + return; + + parent = dentry; + down: + mutex_lock(&parent->d_inode->i_mutex); + loop: + /* + * The parent->d_subdirs is protected by the d_lock. Outside that + * lock, the child can be unlinked and set to be freed which can + * use the d_u.d_child as the rcu head and corrupt this list. + */ + spin_lock(&parent->d_lock); + list_for_each_entry(child, &parent->d_subdirs, d_child) { + if (!tracefs_positive(child)) + continue; + + /* perhaps simple_empty(child) makes more sense */ + if (!list_empty(&child->d_subdirs)) { + spin_unlock(&parent->d_lock); + mutex_unlock(&parent->d_inode->i_mutex); + parent = child; + goto down; + } + + spin_unlock(&parent->d_lock); + + if (!__tracefs_remove(child, parent)) + simple_release_fs(&tracefs_mount, &tracefs_mount_count); + + /* + * The parent->d_lock protects agaist child from unlinking + * from d_subdirs. When releasing the parent->d_lock we can + * no longer trust that the next pointer is valid. + * Restart the loop. We'll skip this one with the + * tracefs_positive() check. + */ + goto loop; + } + spin_unlock(&parent->d_lock); + + mutex_unlock(&parent->d_inode->i_mutex); + child = parent; + parent = parent->d_parent; + mutex_lock(&parent->d_inode->i_mutex); + + if (child != dentry) + /* go up */ + goto loop; + + if (!__tracefs_remove(child, parent)) + simple_release_fs(&tracefs_mount, &tracefs_mount_count); + mutex_unlock(&parent->d_inode->i_mutex); +} + +/** + * tracefs_initialized - Tells whether tracefs has been registered + */ +bool tracefs_initialized(void) +{ + return tracefs_registered; +} + +static int __init tracefs_init(void) +{ + int retval; + + retval = register_filesystem(&trace_fs_type); + if (!retval) + tracefs_registered = true; + + return retval; +} +core_initcall(tracefs_init); diff --git a/include/linux/tracefs.h b/include/linux/tracefs.h new file mode 100644 index 000000000000..23e04ce21749 --- /dev/null +++ b/include/linux/tracefs.h @@ -0,0 +1,41 @@ +/* + * tracefs.h - a pseudo file system for activating tracing + * + * Based on debugfs by: 2004 Greg Kroah-Hartman + * + * Copyright (C) 2014 Red Hat Inc, author: Steven Rostedt + * + * 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. + * + * tracefs is the file system that is used by the tracing infrastructure. + * + */ + +#ifndef _TRACEFS_H_ +#define _TRACEFS_H_ + +#include +#include + +#include + +struct file_operations; + +#ifdef CONFIG_TRACING + +struct dentry *tracefs_create_file(const char *name, umode_t mode, + struct dentry *parent, void *data, + const struct file_operations *fops); + +struct dentry *tracefs_create_dir(const char *name, struct dentry *parent); + +void tracefs_remove(struct dentry *dentry); +void tracefs_remove_recursive(struct dentry *dentry); + +bool tracefs_initialized(void); + +#endif /* CONFIG_TRACING */ + +#endif diff --git a/include/uapi/linux/magic.h b/include/uapi/linux/magic.h index 7d664ea85ebd..7b1425a6b370 100644 --- a/include/uapi/linux/magic.h +++ b/include/uapi/linux/magic.h @@ -58,6 +58,8 @@ #define STACK_END_MAGIC 0x57AC6E9D +#define TRACEFS_MAGIC 0x74726163 + #define V9FS_MAGIC 0x01021997 #define BDEVFS_MAGIC 0x62646576 -- GitLab From 8434dc9340cd2e117fc944cf7526263bf490a52a Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Tue, 20 Jan 2015 12:13:40 -0500 Subject: [PATCH 00023/11651] tracing: Convert the tracing facility over to use tracefs debugfs was fine for the tracing facility as a quick way to get an interface. Now that tracing has matured, it should separate itself from debugfs such that it can be mounted separately without needing to mount all of debugfs with it. That is, users resist using tracing because it requires mounting debugfs. Having tracing have its own file system lets users get the features of tracing without needing to bring in the rest of the kernel's debug infrastructure. Another reason for tracefs is that debubfs does not support mkdir. Currently, to create instances, one does a mkdir in the tracing/instance directory. This is implemented via a hack that forces debugfs to do something it is not intended on doing. By converting over to tracefs, this hack can be removed and mkdir can be properly implemented. This patch does not address this yet, but it lays the ground work for that to be done. Signed-off-by: Steven Rostedt --- kernel/trace/ftrace.c | 22 +++++------ kernel/trace/trace.c | 55 ++++++++++++++++------------ kernel/trace/trace.h | 2 +- kernel/trace/trace_events.c | 32 ++++++++-------- kernel/trace/trace_functions_graph.c | 7 ++-- kernel/trace/trace_kprobe.c | 10 ++--- kernel/trace/trace_probe.h | 2 +- kernel/trace/trace_stat.c | 10 ++--- 8 files changed, 74 insertions(+), 66 deletions(-) diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 45e5cb143d17..fcc0e7052a79 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include #include @@ -1008,7 +1008,7 @@ static struct tracer_stat function_stats __initdata = { .stat_show = function_stat_show }; -static __init void ftrace_profile_debugfs(struct dentry *d_tracer) +static __init void ftrace_profile_tracefs(struct dentry *d_tracer) { struct ftrace_profile_stat *stat; struct dentry *entry; @@ -1044,15 +1044,15 @@ static __init void ftrace_profile_debugfs(struct dentry *d_tracer) } } - entry = debugfs_create_file("function_profile_enabled", 0644, + entry = tracefs_create_file("function_profile_enabled", 0644, d_tracer, NULL, &ftrace_profile_fops); if (!entry) - pr_warning("Could not create debugfs " + pr_warning("Could not create tracefs " "'function_profile_enabled' entry\n"); } #else /* CONFIG_FUNCTION_PROFILER */ -static __init void ftrace_profile_debugfs(struct dentry *d_tracer) +static __init void ftrace_profile_tracefs(struct dentry *d_tracer) { } #endif /* CONFIG_FUNCTION_PROFILER */ @@ -4690,7 +4690,7 @@ void ftrace_destroy_filter_files(struct ftrace_ops *ops) mutex_unlock(&ftrace_lock); } -static __init int ftrace_init_dyn_debugfs(struct dentry *d_tracer) +static __init int ftrace_init_dyn_tracefs(struct dentry *d_tracer) { trace_create_file("available_filter_functions", 0444, @@ -4998,7 +4998,7 @@ static int __init ftrace_nodyn_init(void) } core_initcall(ftrace_nodyn_init); -static inline int ftrace_init_dyn_debugfs(struct dentry *d_tracer) { return 0; } +static inline int ftrace_init_dyn_tracefs(struct dentry *d_tracer) { return 0; } static inline void ftrace_startup_enable(int command) { } static inline void ftrace_startup_all(int command) { } /* Keep as macros so we do not need to define the commands */ @@ -5451,7 +5451,7 @@ static const struct file_operations ftrace_pid_fops = { .release = ftrace_pid_release, }; -static __init int ftrace_init_debugfs(void) +static __init int ftrace_init_tracefs(void) { struct dentry *d_tracer; @@ -5459,16 +5459,16 @@ static __init int ftrace_init_debugfs(void) if (IS_ERR(d_tracer)) return 0; - ftrace_init_dyn_debugfs(d_tracer); + ftrace_init_dyn_tracefs(d_tracer); trace_create_file("set_ftrace_pid", 0644, d_tracer, NULL, &ftrace_pid_fops); - ftrace_profile_debugfs(d_tracer); + ftrace_profile_tracefs(d_tracer); return 0; } -fs_initcall(ftrace_init_debugfs); +fs_initcall(ftrace_init_tracefs); /** * ftrace_kill - kill ftrace diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 05e0e50539fc..6c4739bee4bb 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -5828,6 +5829,14 @@ static inline __init int register_snapshot_cmd(void) { return 0; } static struct dentry *tracing_get_dentry(struct trace_array *tr) { + if (WARN_ON(!tr->dir)) + return ERR_PTR(-ENODEV); + + /* Top directory uses NULL as the parent */ + if (tr->flags & TRACE_ARRAY_FL_GLOBAL) + return NULL; + + /* All sub buffers have a descriptor */ return tr->dir; } @@ -5842,10 +5851,10 @@ static struct dentry *tracing_dentry_percpu(struct trace_array *tr, int cpu) if (IS_ERR(d_tracer)) return NULL; - tr->percpu_dir = debugfs_create_dir("per_cpu", d_tracer); + tr->percpu_dir = tracefs_create_dir("per_cpu", d_tracer); WARN_ONCE(!tr->percpu_dir, - "Could not create debugfs directory 'per_cpu/%d'\n", cpu); + "Could not create tracefs directory 'per_cpu/%d'\n", cpu); return tr->percpu_dir; } @@ -5862,7 +5871,7 @@ trace_create_cpu_file(const char *name, umode_t mode, struct dentry *parent, } static void -tracing_init_debugfs_percpu(struct trace_array *tr, long cpu) +tracing_init_tracefs_percpu(struct trace_array *tr, long cpu) { struct dentry *d_percpu = tracing_dentry_percpu(tr, cpu); struct dentry *d_cpu; @@ -5872,9 +5881,9 @@ tracing_init_debugfs_percpu(struct trace_array *tr, long cpu) return; snprintf(cpu_dir, 30, "cpu%ld", cpu); - d_cpu = debugfs_create_dir(cpu_dir, d_percpu); + d_cpu = tracefs_create_dir(cpu_dir, d_percpu); if (!d_cpu) { - pr_warning("Could not create debugfs '%s' entry\n", cpu_dir); + pr_warning("Could not create tracefs '%s' entry\n", cpu_dir); return; } @@ -6026,9 +6035,9 @@ struct dentry *trace_create_file(const char *name, { struct dentry *ret; - ret = debugfs_create_file(name, mode, parent, data, fops); + ret = tracefs_create_file(name, mode, parent, data, fops); if (!ret) - pr_warning("Could not create debugfs '%s' entry\n", name); + pr_warning("Could not create tracefs '%s' entry\n", name); return ret; } @@ -6045,9 +6054,9 @@ static struct dentry *trace_options_init_dentry(struct trace_array *tr) if (IS_ERR(d_tracer)) return NULL; - tr->options = debugfs_create_dir("options", d_tracer); + tr->options = tracefs_create_dir("options", d_tracer); if (!tr->options) { - pr_warning("Could not create debugfs directory 'options'\n"); + pr_warning("Could not create tracefs directory 'options'\n"); return NULL; } @@ -6116,7 +6125,7 @@ destroy_trace_option_files(struct trace_option_dentry *topts) return; for (cnt = 0; topts[cnt].opt; cnt++) - debugfs_remove(topts[cnt].entry); + tracefs_remove(topts[cnt].entry); kfree(topts); } @@ -6205,7 +6214,7 @@ static const struct file_operations rb_simple_fops = { struct dentry *trace_instance_dir; static void -init_tracer_debugfs(struct trace_array *tr, struct dentry *d_tracer); +init_tracer_tracefs(struct trace_array *tr, struct dentry *d_tracer); static int allocate_trace_buffer(struct trace_array *tr, struct trace_buffer *buf, int size) @@ -6321,17 +6330,17 @@ static int new_instance_create(const char *name) if (allocate_trace_buffers(tr, trace_buf_size) < 0) goto out_free_tr; - tr->dir = debugfs_create_dir(name, trace_instance_dir); + tr->dir = tracefs_create_dir(name, trace_instance_dir); if (!tr->dir) goto out_free_tr; ret = event_trace_add_tracer(tr->dir, tr); if (ret) { - debugfs_remove_recursive(tr->dir); + tracefs_remove_recursive(tr->dir); goto out_free_tr; } - init_tracer_debugfs(tr, tr->dir); + init_tracer_tracefs(tr, tr->dir); list_add(&tr->list, &ftrace_trace_arrays); @@ -6404,7 +6413,7 @@ static int instance_mkdir (struct inode *inode, struct dentry *dentry, umode_t m return -ENOENT; /* - * The inode mutex is locked, but debugfs_create_dir() will also + * The inode mutex is locked, but tracefs_create_dir() will also * take the mutex. As the instances directory can not be destroyed * or changed in any other way, it is safe to unlock it, and * let the dentry try. If two users try to make the same dir at @@ -6434,7 +6443,7 @@ static int instance_rmdir(struct inode *inode, struct dentry *dentry) mutex_unlock(&dentry->d_inode->i_mutex); /* - * The inode mutex is locked, but debugfs_create_dir() will also + * The inode mutex is locked, but tracefs_create_dir() will also * take the mutex. As the instances directory can not be destroyed * or changed in any other way, it is safe to unlock it, and * let the dentry try. If two users try to make the same dir at @@ -6459,7 +6468,7 @@ static const struct inode_operations instance_dir_inode_operations = { static __init void create_trace_instances(struct dentry *d_tracer) { - trace_instance_dir = debugfs_create_dir("instances", d_tracer); + trace_instance_dir = tracefs_create_dir("instances", d_tracer); if (WARN_ON(!trace_instance_dir)) return; @@ -6468,7 +6477,7 @@ static __init void create_trace_instances(struct dentry *d_tracer) } static void -init_tracer_debugfs(struct trace_array *tr, struct dentry *d_tracer) +init_tracer_tracefs(struct trace_array *tr, struct dentry *d_tracer) { int cpu; @@ -6522,7 +6531,7 @@ init_tracer_debugfs(struct trace_array *tr, struct dentry *d_tracer) #endif for_each_tracing_cpu(cpu) - tracing_init_debugfs_percpu(tr, cpu); + tracing_init_tracefs_percpu(tr, cpu); } @@ -6550,10 +6559,10 @@ struct dentry *tracing_init_dentry(void) return ERR_PTR(-ENOMEM); } - return tr->dir; + return NULL; } -static __init int tracer_init_debugfs(void) +static __init int tracer_init_tracefs(void) { struct dentry *d_tracer; @@ -6563,7 +6572,7 @@ static __init int tracer_init_debugfs(void) if (IS_ERR(d_tracer)) return 0; - init_tracer_debugfs(&global_trace, d_tracer); + init_tracer_tracefs(&global_trace, d_tracer); trace_create_file("tracing_thresh", 0644, d_tracer, &global_trace, &tracing_thresh_fops); @@ -6925,5 +6934,5 @@ __init static int clear_boot_tracer(void) return 0; } -fs_initcall(tracer_init_debugfs); +fs_initcall(tracer_init_tracefs); late_initcall(clear_boot_tracer); diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index dd8205a35760..d951deddec89 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -334,7 +334,7 @@ struct tracer_flags { /** - * struct tracer - a specific tracer and its callbacks to interact with debugfs + * struct tracer - a specific tracer and its callbacks to interact with tracefs * @name: the name chosen to select it on the available_tracers file * @init: called when one switches to this tracer (echo name > current_tracer) * @reset: called when one switches to another tracer diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index db54dda10ccc..0d2e47370ee7 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include #include @@ -480,7 +480,7 @@ static void remove_subsystem(struct ftrace_subsystem_dir *dir) return; if (!--dir->nr_events) { - debugfs_remove_recursive(dir->entry); + tracefs_remove_recursive(dir->entry); list_del(&dir->list); __put_system_dir(dir); } @@ -499,7 +499,7 @@ static void remove_event_file_dir(struct ftrace_event_file *file) } spin_unlock(&dir->d_lock); - debugfs_remove_recursive(dir); + tracefs_remove_recursive(dir); } list_del(&file->list); @@ -1526,7 +1526,7 @@ event_subsystem_dir(struct trace_array *tr, const char *name, } else __get_system(system); - dir->entry = debugfs_create_dir(name, parent); + dir->entry = tracefs_create_dir(name, parent); if (!dir->entry) { pr_warn("Failed to create system directory %s\n", name); __put_system(system); @@ -1539,12 +1539,12 @@ event_subsystem_dir(struct trace_array *tr, const char *name, dir->subsystem = system; file->system = dir; - entry = debugfs_create_file("filter", 0644, dir->entry, dir, + entry = tracefs_create_file("filter", 0644, dir->entry, dir, &ftrace_subsystem_filter_fops); if (!entry) { kfree(system->filter); system->filter = NULL; - pr_warn("Could not create debugfs '%s/filter' entry\n", name); + pr_warn("Could not create tracefs '%s/filter' entry\n", name); } trace_create_file("enable", 0644, dir->entry, dir, @@ -1585,9 +1585,9 @@ event_create_dir(struct dentry *parent, struct ftrace_event_file *file) d_events = parent; name = ftrace_event_name(call); - file->dir = debugfs_create_dir(name, d_events); + file->dir = tracefs_create_dir(name, d_events); if (!file->dir) { - pr_warn("Could not create debugfs '%s' directory\n", name); + pr_warn("Could not create tracefs '%s' directory\n", name); return -1; } @@ -2228,7 +2228,7 @@ static inline int register_event_cmds(void) { return 0; } /* * The top level array has already had its ftrace_event_file * descriptors created in order to allow for early events to - * be recorded. This function is called after the debugfs has been + * be recorded. This function is called after the tracefs has been * initialized, and we now have to create the files associated * to the events. */ @@ -2311,16 +2311,16 @@ create_event_toplevel_files(struct dentry *parent, struct trace_array *tr) struct dentry *d_events; struct dentry *entry; - entry = debugfs_create_file("set_event", 0644, parent, + entry = tracefs_create_file("set_event", 0644, parent, tr, &ftrace_set_event_fops); if (!entry) { - pr_warn("Could not create debugfs 'set_event' entry\n"); + pr_warn("Could not create tracefs 'set_event' entry\n"); return -ENOMEM; } - d_events = debugfs_create_dir("events", parent); + d_events = tracefs_create_dir("events", parent); if (!d_events) { - pr_warn("Could not create debugfs 'events' directory\n"); + pr_warn("Could not create tracefs 'events' directory\n"); return -ENOMEM; } @@ -2412,7 +2412,7 @@ int event_trace_del_tracer(struct trace_array *tr) down_write(&trace_event_sem); __trace_remove_event_dirs(tr); - debugfs_remove_recursive(tr->event_dir); + tracefs_remove_recursive(tr->event_dir); up_write(&trace_event_sem); tr->event_dir = NULL; @@ -2534,10 +2534,10 @@ static __init int event_trace_init(void) if (IS_ERR(d_tracer)) return 0; - entry = debugfs_create_file("available_events", 0444, d_tracer, + entry = tracefs_create_file("available_events", 0444, d_tracer, tr, &ftrace_avail_fops); if (!entry) - pr_warn("Could not create debugfs 'available_events' entry\n"); + pr_warn("Could not create tracefs 'available_events' entry\n"); if (trace_define_common_fields()) pr_warn("tracing: Failed to allocate common fields"); diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c index 2d25ad1526bb..9cfea4c6d314 100644 --- a/kernel/trace/trace_functions_graph.c +++ b/kernel/trace/trace_functions_graph.c @@ -6,7 +6,6 @@ * is Copyright (c) Steven Rostedt * */ -#include #include #include #include @@ -151,7 +150,7 @@ ftrace_push_return_trace(unsigned long ret, unsigned long func, int *depth, * The curr_ret_stack is initialized to -1 and get increased * in this function. So it can be less than -1 only if it was * filtered out via ftrace_graph_notrace_addr() which can be - * set from set_graph_notrace file in debugfs by user. + * set from set_graph_notrace file in tracefs by user. */ if (current->curr_ret_stack < -1) return -EBUSY; @@ -1432,7 +1431,7 @@ static const struct file_operations graph_depth_fops = { .llseek = generic_file_llseek, }; -static __init int init_graph_debugfs(void) +static __init int init_graph_tracefs(void) { struct dentry *d_tracer; @@ -1445,7 +1444,7 @@ static __init int init_graph_debugfs(void) return 0; } -fs_initcall(init_graph_debugfs); +fs_initcall(init_graph_tracefs); static __init int init_graph_trace(void) { diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index b4a00def88f5..c1c6655847c8 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -1310,7 +1310,7 @@ static int unregister_kprobe_event(struct trace_kprobe *tk) return ret; } -/* Make a debugfs interface for controlling probe points */ +/* Make a tracefs interface for controlling probe points */ static __init int init_kprobe_trace(void) { struct dentry *d_tracer; @@ -1323,20 +1323,20 @@ static __init int init_kprobe_trace(void) if (IS_ERR(d_tracer)) return 0; - entry = debugfs_create_file("kprobe_events", 0644, d_tracer, + entry = tracefs_create_file("kprobe_events", 0644, d_tracer, NULL, &kprobe_events_ops); /* Event list interface */ if (!entry) - pr_warning("Could not create debugfs " + pr_warning("Could not create tracefs " "'kprobe_events' entry\n"); /* Profile interface */ - entry = debugfs_create_file("kprobe_profile", 0444, d_tracer, + entry = tracefs_create_file("kprobe_profile", 0444, d_tracer, NULL, &kprobe_profile_ops); if (!entry) - pr_warning("Could not create debugfs " + pr_warning("Could not create tracefs " "'kprobe_profile' entry\n"); return 0; } diff --git a/kernel/trace/trace_probe.h b/kernel/trace/trace_probe.h index 4f815fbce16d..19aff635841a 100644 --- a/kernel/trace/trace_probe.h +++ b/kernel/trace/trace_probe.h @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/kernel/trace/trace_stat.c b/kernel/trace/trace_stat.c index 75e19e86c954..6cf935316769 100644 --- a/kernel/trace/trace_stat.c +++ b/kernel/trace/trace_stat.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include "trace_stat.h" #include "trace.h" @@ -65,7 +65,7 @@ static void reset_stat_session(struct stat_session *session) static void destroy_session(struct stat_session *session) { - debugfs_remove(session->file); + tracefs_remove(session->file); __reset_stat_session(session); mutex_destroy(&session->stat_mutex); kfree(session); @@ -279,9 +279,9 @@ static int tracing_stat_init(void) if (IS_ERR(d_tracing)) return 0; - stat_dir = debugfs_create_dir("trace_stat", d_tracing); + stat_dir = tracefs_create_dir("trace_stat", d_tracing); if (!stat_dir) - pr_warning("Could not create debugfs " + pr_warning("Could not create tracefs " "'trace_stat' entry\n"); return 0; } @@ -291,7 +291,7 @@ static int init_stat_file(struct stat_session *session) if (!stat_dir && tracing_stat_init()) return -ENODEV; - session->file = debugfs_create_file(session->ts->name, 0644, + session->file = tracefs_create_file(session->ts->name, 0644, stat_dir, session, &tracing_stat_fops); if (!session->file) -- GitLab From f76180bc07abc399977bfbe8c43bf58c4570e893 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Tue, 20 Jan 2015 15:48:46 -0500 Subject: [PATCH 00024/11651] tracing: Automatically mount tracefs on debugfs/tracing As tools currently rely on the tracing directory in debugfs, we can not just created a tracefs infrastructure and expect sysadmins to mount the new tracefs to have their old tools work. Instead, the debugfs tracing directory is still created and the tracefs file system is mounted there when the debugfs filesystem is mounted. No longer does the tracing infrastructure update the debugfs file system, but instead interacts with the tracefs file system. But now, it still appears to the user like nothing changed, except you also have the feature of mounting just the tracing system without needing all of debugfs! Cc: Al Viro Signed-off-by: Steven Rostedt --- kernel/trace/trace.c | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 6c4739bee4bb..b4aa936509d2 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -6535,6 +6536,28 @@ init_tracer_tracefs(struct trace_array *tr, struct dentry *d_tracer) } +static struct vfsmount *trace_automount(void *ingore) +{ + struct vfsmount *mnt; + struct file_system_type *type; + + /* + * To maintain backward compatibility for tools that mount + * debugfs to get to the tracing facility, tracefs is automatically + * mounted to the debugfs/tracing directory. + */ + type = get_fs_type("tracefs"); + if (!type) + return NULL; + mnt = vfs_kern_mount(type, 0, "tracefs", NULL); + put_filesystem(type); + if (IS_ERR(mnt)) + return NULL; + mntget(mnt); + + return mnt; +} + /** * tracing_init_dentry - initialize top level trace array * @@ -6546,14 +6569,21 @@ struct dentry *tracing_init_dentry(void) { struct trace_array *tr = &global_trace; + /* The top level trace array uses NULL as parent */ if (tr->dir) - return tr->dir; + return NULL; if (WARN_ON(!debugfs_initialized())) return ERR_PTR(-ENODEV); - tr->dir = debugfs_create_dir("tracing", NULL); - + /* + * As there may still be users that expect the tracing + * files to exist in debugfs/tracing, we must automount + * the tracefs file system there, so older tools still + * work with the newer kerenl. + */ + tr->dir = debugfs_create_automount("tracing", NULL, + trace_automount, NULL); if (!tr->dir) { pr_warn_once("Could not create debugfs directory 'tracing'\n"); return ERR_PTR(-ENOMEM); -- GitLab From cc31004a4aa784d89054ec07b87eae05cecf7121 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Wed, 21 Jan 2015 11:28:23 -0500 Subject: [PATCH 00025/11651] tracefs: Add directory /sys/kernel/tracing When tracefs is configured, have the directory /sys/kernel/tracing appear just like /sys/kernel/debug appears when debugfs is configured. This will give a consistent place for system admins to mount tracefs. Acked-by: Greg Kroah-Hartman Signed-off-by: Steven Rostedt --- fs/tracefs/inode.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/fs/tracefs/inode.c b/fs/tracefs/inode.c index 5b1547a452d8..0b9cf5cf24c9 100644 --- a/fs/tracefs/inode.c +++ b/fs/tracefs/inode.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -509,10 +510,16 @@ bool tracefs_initialized(void) return tracefs_registered; } +static struct kobject *trace_kobj; + static int __init tracefs_init(void) { int retval; + trace_kobj = kobject_create_and_add("tracing", kernel_kobj); + if (!trace_kobj) + return -EINVAL; + retval = register_filesystem(&trace_fs_type); if (!retval) tracefs_registered = true; -- GitLab From eae473581cf93dad94ca833aa961c033c6a43924 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Wed, 21 Jan 2015 10:01:39 -0500 Subject: [PATCH 00026/11651] tracing: Have mkdir and rmdir be part of tracefs The tracing "instances" directory can create sub tracing buffers with mkdir, and remove them with rmdir. As a mkdir will also create all the files and directories that control the sub buffer the inode mutexes need to be released before this is done, to avoid deadlocks. It is better to let the tracing system unlock the inode mutexes before calling the functions that create the files within the new directory (or deletes the files from the one being destroyed). Now that tracing has been converted over to tracefs, the tracefs file system can be modified to accommodate this feature. It still releases the locks, but the filesystem itself can take care of the ugly business and let the user just do what it needs. The tracing system now attaches a descriptor to the directory dentry that can have userspace create or remove sub directories. If this descriptor does not exist for a dentry, then that dentry can not be used to create other directories. This descriptor holds a mkdir and rmdir method that only takes a character string as an argument. The tracefs file system will first make a copy of the dentry name before releasing the locks. Then it will pass the copied name to the methods. It is up to the tracing system that supplied the methods to handle races with duplicate names and such as all the inode mutexes would be released when the functions are called. Cc: Al Viro Signed-off-by: Steven Rostedt --- fs/tracefs/inode.c | 151 ++++++++++++++++++++++++++++++++++++---- include/linux/tracefs.h | 4 ++ kernel/trace/trace.c | 75 ++------------------ 3 files changed, 145 insertions(+), 85 deletions(-) diff --git a/fs/tracefs/inode.c b/fs/tracefs/inode.c index 0b9cf5cf24c9..d92bdf3b079a 100644 --- a/fs/tracefs/inode.c +++ b/fs/tracefs/inode.c @@ -50,6 +50,84 @@ static const struct file_operations tracefs_file_operations = { .llseek = noop_llseek, }; +static struct tracefs_dir_ops { + int (*mkdir)(const char *name); + int (*rmdir)(const char *name); +} tracefs_ops; + +static char *get_dname(struct dentry *dentry) +{ + const char *dname; + char *name; + int len = dentry->d_name.len; + + dname = dentry->d_name.name; + name = kmalloc(len + 1, GFP_KERNEL); + if (!name) + return NULL; + memcpy(name, dname, len); + name[len] = 0; + return name; +} + +static int tracefs_syscall_mkdir(struct inode *inode, struct dentry *dentry, umode_t mode) +{ + char *name; + int ret; + + name = get_dname(dentry); + if (!name) + return -ENOMEM; + + /* + * The mkdir call can call the generic functions that create + * the files within the tracefs system. It is up to the individual + * mkdir routine to handle races. + */ + mutex_unlock(&inode->i_mutex); + ret = tracefs_ops.mkdir(name); + mutex_lock(&inode->i_mutex); + + kfree(name); + + return ret; +} + +static int tracefs_syscall_rmdir(struct inode *inode, struct dentry *dentry) +{ + char *name; + int ret; + + name = get_dname(dentry); + if (!name) + return -ENOMEM; + + /* + * The rmdir call can call the generic functions that create + * the files within the tracefs system. It is up to the individual + * rmdir routine to handle races. + * This time we need to unlock not only the parent (inode) but + * also the directory that is being deleted. + */ + mutex_unlock(&inode->i_mutex); + mutex_unlock(&dentry->d_inode->i_mutex); + + ret = tracefs_ops.rmdir(name); + + mutex_lock_nested(&inode->i_mutex, I_MUTEX_PARENT); + mutex_lock(&dentry->d_inode->i_mutex); + + kfree(name); + + return ret; +} + +static const struct inode_operations tracefs_dir_inode_operations = { + .lookup = simple_lookup, + .mkdir = tracefs_syscall_mkdir, + .rmdir = tracefs_syscall_rmdir, +}; + static struct inode *tracefs_get_inode(struct super_block *sb) { struct inode *inode = new_inode(sb); @@ -334,6 +412,31 @@ struct dentry *tracefs_create_file(const char *name, umode_t mode, return end_creating(dentry); } +static struct dentry *__create_dir(const char *name, struct dentry *parent, + const struct inode_operations *ops) +{ + struct dentry *dentry = start_creating(name, parent); + struct inode *inode; + + if (IS_ERR(dentry)) + return NULL; + + inode = tracefs_get_inode(dentry->d_sb); + if (unlikely(!inode)) + return failed_creating(dentry); + + inode->i_mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO; + inode->i_op = ops; + inode->i_fop = &simple_dir_operations; + + /* directory inodes start off with i_nlink == 2 (for "." entry) */ + inc_nlink(inode); + d_instantiate(dentry, inode); + inc_nlink(dentry->d_parent->d_inode); + fsnotify_mkdir(dentry->d_parent->d_inode, dentry); + return end_creating(dentry); +} + /** * tracefs_create_dir - create a directory in the tracefs filesystem * @name: a pointer to a string containing the name of the directory to @@ -353,26 +456,44 @@ struct dentry *tracefs_create_file(const char *name, umode_t mode, */ struct dentry *tracefs_create_dir(const char *name, struct dentry *parent) { - struct dentry *dentry = start_creating(name, parent); - struct inode *inode; + return __create_dir(name, parent, &simple_dir_inode_operations); +} - if (IS_ERR(dentry)) +/** + * tracefs_create_instance_dir - create the tracing instances directory + * @name: The name of the instances directory to create + * @parent: The parent directory that the instances directory will exist + * @mkdir: The function to call when a mkdir is performed. + * @rmdir: The function to call when a rmdir is performed. + * + * Only one instances directory is allowed. + * + * The instances directory is special as it allows for mkdir and rmdir to + * to be done by userspace. When a mkdir or rmdir is performed, the inode + * locks are released and the methhods passed in (@mkdir and @rmdir) are + * called without locks and with the name of the directory being created + * within the instances directory. + * + * Returns the dentry of the instances directory. + */ +struct dentry *tracefs_create_instance_dir(const char *name, struct dentry *parent, + int (*mkdir)(const char *name), + int (*rmdir)(const char *name)) +{ + struct dentry *dentry; + + /* Only allow one instance of the instances directory. */ + if (WARN_ON(tracefs_ops.mkdir || tracefs_ops.rmdir)) return NULL; - inode = tracefs_get_inode(dentry->d_sb); - if (unlikely(!inode)) - return failed_creating(dentry); + dentry = __create_dir(name, parent, &tracefs_dir_inode_operations); + if (!dentry) + return NULL; - inode->i_mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO; - inode->i_op = &simple_dir_inode_operations; - inode->i_fop = &simple_dir_operations; + tracefs_ops.mkdir = mkdir; + tracefs_ops.rmdir = rmdir; - /* directory inodes start off with i_nlink == 2 (for "." entry) */ - inc_nlink(inode); - d_instantiate(dentry, inode); - inc_nlink(dentry->d_parent->d_inode); - fsnotify_mkdir(dentry->d_parent->d_inode, dentry); - return end_creating(dentry); + return dentry; } static inline int tracefs_positive(struct dentry *dentry) diff --git a/include/linux/tracefs.h b/include/linux/tracefs.h index 23e04ce21749..5b727a17beee 100644 --- a/include/linux/tracefs.h +++ b/include/linux/tracefs.h @@ -34,6 +34,10 @@ struct dentry *tracefs_create_dir(const char *name, struct dentry *parent); void tracefs_remove(struct dentry *dentry); void tracefs_remove_recursive(struct dentry *dentry); +struct dentry *tracefs_create_instance_dir(const char *name, struct dentry *parent, + int (*mkdir)(const char *name), + int (*rmdir)(const char *name)); + bool tracefs_initialized(void); #endif /* CONFIG_TRACING */ diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index b4aa936509d2..3c8913bac204 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -6292,7 +6292,7 @@ static void free_trace_buffers(struct trace_array *tr) #endif } -static int new_instance_create(const char *name) +static int instance_mkdir(const char *name) { struct trace_array *tr; int ret; @@ -6362,7 +6362,7 @@ static int new_instance_create(const char *name) } -static int instance_delete(const char *name) +static int instance_rmdir(const char *name) { struct trace_array *tr; int found = 0; @@ -6403,78 +6403,13 @@ static int instance_delete(const char *name) return ret; } -static int instance_mkdir (struct inode *inode, struct dentry *dentry, umode_t mode) -{ - struct dentry *parent; - int ret; - - /* Paranoid: Make sure the parent is the "instances" directory */ - parent = hlist_entry(inode->i_dentry.first, struct dentry, d_u.d_alias); - if (WARN_ON_ONCE(parent != trace_instance_dir)) - return -ENOENT; - - /* - * The inode mutex is locked, but tracefs_create_dir() will also - * take the mutex. As the instances directory can not be destroyed - * or changed in any other way, it is safe to unlock it, and - * let the dentry try. If two users try to make the same dir at - * the same time, then the new_instance_create() will determine the - * winner. - */ - mutex_unlock(&inode->i_mutex); - - ret = new_instance_create(dentry->d_iname); - - mutex_lock(&inode->i_mutex); - - return ret; -} - -static int instance_rmdir(struct inode *inode, struct dentry *dentry) -{ - struct dentry *parent; - int ret; - - /* Paranoid: Make sure the parent is the "instances" directory */ - parent = hlist_entry(inode->i_dentry.first, struct dentry, d_u.d_alias); - if (WARN_ON_ONCE(parent != trace_instance_dir)) - return -ENOENT; - - /* The caller did a dget() on dentry */ - mutex_unlock(&dentry->d_inode->i_mutex); - - /* - * The inode mutex is locked, but tracefs_create_dir() will also - * take the mutex. As the instances directory can not be destroyed - * or changed in any other way, it is safe to unlock it, and - * let the dentry try. If two users try to make the same dir at - * the same time, then the instance_delete() will determine the - * winner. - */ - mutex_unlock(&inode->i_mutex); - - ret = instance_delete(dentry->d_iname); - - mutex_lock_nested(&inode->i_mutex, I_MUTEX_PARENT); - mutex_lock(&dentry->d_inode->i_mutex); - - return ret; -} - -static const struct inode_operations instance_dir_inode_operations = { - .lookup = simple_lookup, - .mkdir = instance_mkdir, - .rmdir = instance_rmdir, -}; - static __init void create_trace_instances(struct dentry *d_tracer) { - trace_instance_dir = tracefs_create_dir("instances", d_tracer); + trace_instance_dir = tracefs_create_instance_dir("instances", d_tracer, + instance_mkdir, + instance_rmdir); if (WARN_ON(!trace_instance_dir)) return; - - /* Hijack the dir inode operations, to allow mkdir */ - trace_instance_dir->d_inode->i_op = &instance_dir_inode_operations; } static void -- GitLab From abe4e26bb7edb7b36ef99e2e78e86de79b18f922 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Fri, 2 Jan 2015 04:02:54 -0500 Subject: [PATCH 00027/11651] iio: meter: ade7754: add error handling in _reset and _stop_device MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds the error handling for the value returned from ade7754_spi_read_reg_8. With this patch, the following randconfig warnings get fixed automatically. drivers/staging/iio/meter/ade7754.c:222:6: warning: ‘val’ may be used uninitialized in this function [-Wmaybe-uninitialized] drivers/staging/iio/meter/ade7754.c:368:6: warning: ‘val’ may be used uninitialized in this function [-Wmaybe-uninitialized] Signed-off-by: Devendra Naga Signed-off-by: Jonathan Cameron --- drivers/staging/iio/meter/ade7754.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/staging/iio/meter/ade7754.c b/drivers/staging/iio/meter/ade7754.c index 81f67318974a..746b18894ebf 100644 --- a/drivers/staging/iio/meter/ade7754.c +++ b/drivers/staging/iio/meter/ade7754.c @@ -216,9 +216,13 @@ error_ret: static int ade7754_reset(struct device *dev) { + int ret; u8 val; - ade7754_spi_read_reg_8(dev, ADE7754_OPMODE, &val); + ret = ade7754_spi_read_reg_8(dev, ADE7754_OPMODE, &val); + if (ret < 0) + return ret; + val |= 1 << 6; /* Software Chip Reset */ return ade7754_spi_write_reg_8(dev, ADE7754_OPMODE, val); } @@ -362,9 +366,16 @@ error_ret: /* Power down the device */ static int ade7754_stop_device(struct device *dev) { + int ret; u8 val; - ade7754_spi_read_reg_8(dev, ADE7754_OPMODE, &val); + ret = ade7754_spi_read_reg_8(dev, ADE7754_OPMODE, &val); + if (ret < 0) { + dev_err(dev, "unable to power down the device, error: %d", + ret); + return ret; + } + val |= 7 << 3; /* ADE7754 powered down */ return ade7754_spi_write_reg_8(dev, ADE7754_OPMODE, val); } -- GitLab From 1e716a15ce5e5840cac0fb4cd6ca79d70d3568a9 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Fri, 2 Jan 2015 04:02:55 -0500 Subject: [PATCH 00028/11651] iio: meter: ade7759: add error handling in _reset and _stop_device MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds the error handling for the value returned from ade7759_spi_read_reg_16. With this patch, the following randconfig warnings get fixed automatically. drivers/staging/iio/meter/ade7759.c:224:6: warning: ‘val’ may be used uninitialized in this function [-Wmaybe-uninitialized] drivers/staging/iio/meter/ade7759.c:309:6: warning: ‘val’ may be used uninitialized in this function [-Wmaybe-uninitialized] Signed-off-by: Devendra Naga Signed-off-by: Jonathan Cameron --- drivers/staging/iio/meter/ade7759.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/staging/iio/meter/ade7759.c b/drivers/staging/iio/meter/ade7759.c index b0c7dbc8a428..9afdb1e1a222 100644 --- a/drivers/staging/iio/meter/ade7759.c +++ b/drivers/staging/iio/meter/ade7759.c @@ -218,9 +218,12 @@ static int ade7759_reset(struct device *dev) int ret; u16 val; - ade7759_spi_read_reg_16(dev, + ret = ade7759_spi_read_reg_16(dev, ADE7759_MODE, &val); + if (ret < 0) + return ret; + val |= 1 << 6; /* Software Chip Reset */ ret = ade7759_spi_write_reg_16(dev, ADE7759_MODE, @@ -301,11 +304,18 @@ error_ret: /* Power down the device */ static int ade7759_stop_device(struct device *dev) { + int ret; u16 val; - ade7759_spi_read_reg_16(dev, + ret = ade7759_spi_read_reg_16(dev, ADE7759_MODE, &val); + if (ret < 0) { + dev_err(dev, "unable to power down the device, error: %d\n", + ret); + return ret; + } + val |= 1 << 4; /* AD converters can be turned off */ return ade7759_spi_write_reg_16(dev, ADE7759_MODE, val); -- GitLab From a36385a2613c0755164ec53e8b7a42d4d11f65b9 Mon Sep 17 00:00:00 2001 From: Daniel Baluta Date: Mon, 5 Jan 2015 11:21:42 +0200 Subject: [PATCH 00029/11651] iio: imu: kmx61: Drop odr_bits from kmx61_samp_freq_table odr_bits values are between 0 and 11, so we can use the index in kmx61_samp_freq_table instead of odr_bits structure member. Signed-off-by: Daniel Baluta Reviewed-by: Hartmut Knaack Signed-off-by: Jonathan Cameron --- drivers/iio/imu/kmx61.c | 64 +++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 38 deletions(-) diff --git a/drivers/iio/imu/kmx61.c b/drivers/iio/imu/kmx61.c index 5cc3692acf37..32e5f96a6477 100644 --- a/drivers/iio/imu/kmx61.c +++ b/drivers/iio/imu/kmx61.c @@ -169,19 +169,18 @@ static const u16 kmx61_uscale_table[] = {9582, 19163, 38326}; static const struct { int val; int val2; - u8 odr_bits; -} kmx61_samp_freq_table[] = { {12, 500000, 0x00}, - {25, 0, 0x01}, - {50, 0, 0x02}, - {100, 0, 0x03}, - {200, 0, 0x04}, - {400, 0, 0x05}, - {800, 0, 0x06}, - {1600, 0, 0x07}, - {0, 781000, 0x08}, - {1, 563000, 0x09}, - {3, 125000, 0x0A}, - {6, 250000, 0x0B} }; +} kmx61_samp_freq_table[] = { {12, 500000}, + {25, 0}, + {50, 0}, + {100, 0}, + {200, 0}, + {400, 0}, + {800, 0}, + {1600, 0}, + {0, 781000}, + {1, 563000}, + {3, 125000}, + {6, 250000} }; static const struct { int val; @@ -302,24 +301,10 @@ static int kmx61_convert_freq_to_bit(int val, int val2) for (i = 0; i < ARRAY_SIZE(kmx61_samp_freq_table); i++) if (val == kmx61_samp_freq_table[i].val && val2 == kmx61_samp_freq_table[i].val2) - return kmx61_samp_freq_table[i].odr_bits; - return -EINVAL; -} - -static int kmx61_convert_bit_to_freq(u8 odr_bits, int *val, int *val2) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(kmx61_samp_freq_table); i++) - if (odr_bits == kmx61_samp_freq_table[i].odr_bits) { - *val = kmx61_samp_freq_table[i].val; - *val2 = kmx61_samp_freq_table[i].val2; - return 0; - } + return i; return -EINVAL; } - static int kmx61_convert_wake_up_odr_to_bit(int val, int val2) { int i; @@ -478,7 +463,7 @@ static int kmx61_set_odr(struct kmx61_data *data, int val, int val2, u8 device) static int kmx61_get_odr(struct kmx61_data *data, int *val, int *val2, u8 device) -{ int i; +{ u8 lodr_bits; if (device & KMX61_ACC) @@ -490,13 +475,13 @@ static int kmx61_get_odr(struct kmx61_data *data, int *val, int *val2, else return -EINVAL; - for (i = 0; i < ARRAY_SIZE(kmx61_samp_freq_table); i++) - if (lodr_bits == kmx61_samp_freq_table[i].odr_bits) { - *val = kmx61_samp_freq_table[i].val; - *val2 = kmx61_samp_freq_table[i].val2; - return 0; - } - return -EINVAL; + if (lodr_bits >= ARRAY_SIZE(kmx61_samp_freq_table)) + return -EINVAL; + + *val = kmx61_samp_freq_table[lodr_bits].val; + *val2 = kmx61_samp_freq_table[lodr_bits].val2; + + return 0; } static int kmx61_set_range(struct kmx61_data *data, u8 range) @@ -580,8 +565,11 @@ static int kmx61_chip_init(struct kmx61_data *data) } data->odr_bits = ret; - /* set output data rate for wake up (motion detection) function */ - ret = kmx61_convert_bit_to_freq(data->odr_bits, &val, &val2); + /* + * set output data rate for wake up (motion detection) function + * to match data rate for accelerometer sampling + */ + ret = kmx61_get_odr(data, &val, &val2, KMX61_ACC); if (ret < 0) return ret; -- GitLab From 1a21dfed63515faeb2cda334fbf00787b92d7771 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Tue, 3 Feb 2015 08:47:11 +0900 Subject: [PATCH 00030/11651] clk: samsung: exynos5433: Add binding document for Exynos5433 clock domains This patch adds devicetree binding document for Exynos5433 SoC system clock controller. Signed-off-by: Chanwoo Choi Acked-by: Inki Dae Signed-off-by: Sylwester Nawrocki --- .../bindings/clock/exynos5433-clock.txt | 305 ++++++++++++++++++ 1 file changed, 305 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/exynos5433-clock.txt diff --git a/Documentation/devicetree/bindings/clock/exynos5433-clock.txt b/Documentation/devicetree/bindings/clock/exynos5433-clock.txt new file mode 100644 index 000000000000..9e7ed2d43a15 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/exynos5433-clock.txt @@ -0,0 +1,305 @@ +* Samsung Exynos5433 CMU (Clock Management Units) + +The Exynos5433 clock controller generates and supplies clock to various +controllers within the Exynos5433 SoC. + +Required Properties: + +- compatible: should be one of the following. + - "samsung,exynos5433-cmu-top" - clock controller compatible for CMU_TOP + which generates clocks for IMEM/FSYS/G3D/GSCL/HEVC/MSCL/G2D/MFC/PERIC/PERIS + domains and bus clocks. + - "samsung,exynos5433-cmu-cpif" - clock controller compatible for CMU_CPIF + which generates clocks for LLI (Low Latency Interface) IP. + - "samsung,exynos5433-cmu-mif" - clock controller compatible for CMU_MIF + which generates clocks for DRAM Memory Controller domain. + - "samsung,exynos5433-cmu-peric" - clock controller compatible for CMU_PERIC + which generates clocks for UART/I2C/SPI/I2S/PCM/SPDIF/PWM/SLIMBUS IPs. + - "samsung,exynos5433-cmu-peris" - clock controller compatible for CMU_PERIS + which generates clocks for PMU/TMU/MCT/WDT/RTC/SECKEY/TZPC IPs. + - "samsung,exynos5433-cmu-fsys" - clock controller compatible for CMU_FSYS + which generates clocks for USB/UFS/SDMMC/TSI/PDMA IPs. + - "samsung,exynos5433-cmu-g2d" - clock controller compatible for CMU_G2D + which generates clocks for G2D/MDMA IPs. + - "samsung,exynos5433-cmu-disp" - clock controller compatible for CMU_DISP + which generates clocks for Display (DECON/HDMI/DSIM/MIXER) IPs. + - "samsung,exynos5433-cmu-aud" - clock controller compatible for CMU_AUD + which generates clocks for Cortex-A5/BUS/AUDIO clocks. + - "samsung,exynos5433-cmu-bus0", "samsung,exynos5433-cmu-bus1" + and "samsung,exynos5433-cmu-bus2" - clock controller compatible for CMU_BUS + which generates global data buses clock and global peripheral buses clock. + - "samsung,exynos5433-cmu-g3d" - clock controller compatible for CMU_G3D + which generates clocks for 3D Graphics Engine IP. + - "samsung,exynos5433-cmu-gscl" - clock controller compatible for CMU_GSCL + which generates clocks for GSCALER IPs. + +- reg: physical base address of the controller and length of memory mapped + region. + +- #clock-cells: should be 1. + +- clocks: list of the clock controller input clock identifiers, + from common clock bindings. Please refer the next section + to find the input clocks for a given controller. + +- clock-names: list of the clock controller input clock names, + as described in clock-bindings.txt. + + Input clocks for top clock controller: + - oscclk + - sclk_mphy_pll + - sclk_mfc_pll + - sclk_bus_pll + + Input clocks for cpif clock controller: + - oscclk + + Input clocks for mif clock controller: + - oscclk + - sclk_mphy_pll + + Input clocks for fsys clock controller: + - oscclk + - sclk_ufs_mphy + - div_aclk_fsys_200 + - sclk_pcie_100_fsys + - sclk_ufsunipro_fsys + - sclk_mmc2_fsys + - sclk_mmc1_fsys + - sclk_mmc0_fsys + - sclk_usbhost30_fsys + - sclk_usbdrd30_fsys + + Input clocks for g2d clock controller: + - oscclk + - aclk_g2d_266 + - aclk_g2d_400 + + Input clocks for disp clock controller: + - oscclk + - sclk_dsim1_disp + - sclk_dsim0_disp + - sclk_dsd_disp + - sclk_decon_tv_eclk_disp + - sclk_decon_vclk_disp + - sclk_decon_eclk_disp + - sclk_decon_tv_vclk_disp + - aclk_disp_333 + + Input clocks for bus0 clock controller: + - aclk_bus0_400 + + Input clocks for bus1 clock controller: + - aclk_bus1_400 + + Input clocks for bus2 clock controller: + - oscclk + - aclk_bus2_400 + + Input clocks for g3d clock controller: + - oscclk + - aclk_g3d_400 + + Input clocks for gscl clock controller: + - oscclk + - aclk_gscl_111 + - aclk_gscl_333 + +Each clock is assigned an identifier and client nodes can use this identifier +to specify the clock which they consume. + +All available clocks are defined as preprocessor macros in +dt-bindings/clock/exynos5433.h header and can be used in device +tree sources. + +Example 1: Examples of 'oscclk' source clock node are listed below. + + xxti: xxti { + compatible = "fixed-clock"; + clock-output-names = "oscclk"; + #clock-cells = <0>; + }; + +Example 2: Examples of clock controller nodes are listed below. + + cmu_top: clock-controller@10030000 { + compatible = "samsung,exynos5433-cmu-top"; + reg = <0x10030000 0x0c04>; + #clock-cells = <1>; + + clock-names = "oscclk", + "sclk_mphy_pll", + "sclk_mfc_pll", + "sclk_bus_pll"; + clocks = <&xxti>, + <&cmu_cpif CLK_SCLK_MPHY_PLL>, + <&cmu_mif CLK_SCLK_MFC_PLL>, + <&cmu_mif CLK_SCLK_BUS_PLL>; + }; + + cmu_cpif: clock-controller@10fc0000 { + compatible = "samsung,exynos5433-cmu-cpif"; + reg = <0x10fc0000 0x0c04>; + #clock-cells = <1>; + + clock-names = "oscclk"; + clocks = <&xxti>; + }; + + cmu_mif: clock-controller@105b0000 { + compatible = "samsung,exynos5433-cmu-mif"; + reg = <0x105b0000 0x100c>; + #clock-cells = <1>; + + clock-names = "oscclk", + "sclk_mphy_pll"; + clocks = <&xxti>, + <&cmu_cpif CLK_SCLK_MPHY_PLL>; + }; + + cmu_peric: clock-controller@14c80000 { + compatible = "samsung,exynos5433-cmu-peric"; + reg = <0x14c80000 0x0b08>; + #clock-cells = <1>; + }; + + cmu_peris: clock-controller@10040000 { + compatible = "samsung,exynos5433-cmu-peris"; + reg = <0x10040000 0x0b20>; + #clock-cells = <1>; + }; + + cmu_fsys: clock-controller@156e0000 { + compatible = "samsung,exynos5433-cmu-fsys"; + reg = <0x156e0000 0x0b04>; + #clock-cells = <1>; + + clock-names = "oscclk", + "sclk_ufs_mphy", + "div_aclk_fsys_200", + "sclk_pcie_100_fsys", + "sclk_ufsunipro_fsys", + "sclk_mmc2_fsys", + "sclk_mmc1_fsys", + "sclk_mmc0_fsys", + "sclk_usbhost30_fsys", + "sclk_usbdrd30_fsys"; + clocks = <&xxti>, + <&cmu_cpif CLK_SCLK_UFS_MPHY>, + <&cmu_top CLK_DIV_ACLK_FSYS_200>, + <&cmu_top CLK_SCLK_PCIE_100_FSYS>, + <&cmu_top CLK_SCLK_UFSUNIPRO_FSYS>, + <&cmu_top CLK_SCLK_MMC2_FSYS>, + <&cmu_top CLK_SCLK_MMC1_FSYS>, + <&cmu_top CLK_SCLK_MMC0_FSYS>, + <&cmu_top CLK_SCLK_USBHOST30_FSYS>, + <&cmu_top CLK_SCLK_USBDRD30_FSYS>; + }; + + cmu_g2d: clock-controller@12460000 { + compatible = "samsung,exynos5433-cmu-g2d"; + reg = <0x12460000 0x0b08>; + #clock-cells = <1>; + + clock-names = "oscclk", + "aclk_g2d_266", + "aclk_g2d_400"; + clocks = <&xxti>, + <&cmu_top CLK_ACLK_G2D_266>, + <&cmu_top CLK_ACLK_G2D_400>; + }; + + cmu_disp: clock-controller@13b90000 { + compatible = "samsung,exynos5433-cmu-disp"; + reg = <0x13b90000 0x0c04>; + #clock-cells = <1>; + + clock-names = "oscclk", + "sclk_dsim1_disp", + "sclk_dsim0_disp", + "sclk_dsd_disp", + "sclk_decon_tv_eclk_disp", + "sclk_decon_vclk_disp", + "sclk_decon_eclk_disp", + "sclk_decon_tv_vclk_disp", + "aclk_disp_333"; + clocks = <&xxti>, + <&cmu_mif CLK_SCLK_DSIM1_DISP>, + <&cmu_mif CLK_SCLK_DSIM0_DISP>, + <&cmu_mif CLK_SCLK_DSD_DISP>, + <&cmu_mif CLK_SCLK_DECON_TV_ECLK_DISP>, + <&cmu_mif CLK_SCLK_DECON_VCLK_DISP>, + <&cmu_mif CLK_SCLK_DECON_ECLK_DISP>, + <&cmu_mif CLK_SCLK_DECON_TV_VCLK_DISP>, + <&cmu_mif CLK_ACLK_DISP_333>; + }; + + cmu_aud: clock-controller@114c0000 { + compatible = "samsung,exynos5433-cmu-aud"; + reg = <0x114c0000 0x0b04>; + #clock-cells = <1>; + }; + + cmu_bus0: clock-controller@13600000 { + compatible = "samsung,exynos5433-cmu-bus0"; + reg = <0x13600000 0x0b04>; + #clock-cells = <1>; + + clock-names = "aclk_bus0_400"; + clocks = <&cmu_top CLK_ACLK_BUS0_400>; + }; + + cmu_bus1: clock-controller@14800000 { + compatible = "samsung,exynos5433-cmu-bus1"; + reg = <0x14800000 0x0b04>; + #clock-cells = <1>; + + clock-names = "aclk_bus1_400"; + clocks = <&cmu_top CLK_ACLK_BUS1_400>; + }; + + cmu_bus2: clock-controller@13400000 { + compatible = "samsung,exynos5433-cmu-bus2"; + reg = <0x13400000 0x0b04>; + #clock-cells = <1>; + + clock-names = "oscclk", "aclk_bus2_400"; + clocks = <&xxti>, <&cmu_mif CLK_ACLK_BUS2_400>; + }; + + cmu_g3d: clock-controller@14aa0000 { + compatible = "samsung,exynos5433-cmu-g3d"; + reg = <0x14aa0000 0x1000>; + #clock-cells = <1>; + + clock-names = "oscclk", "aclk_g3d_400"; + clocks = <&xxti>, <&cmu_top CLK_ACLK_G3D_400>; + }; + + cmu_gscl: clock-controller@13cf0000 { + compatible = "samsung,exynos5433-cmu-gscl"; + reg = <0x13cf0000 0x0b10>; + #clock-cells = <1>; + + clock-names = "oscclk", + "aclk_gscl_111", + "aclk_gscl_333"; + clocks = <&xxti>, + <&cmu_top CLK_ACLK_GSCL_111>, + <&cmu_top CLK_ACLK_GSCL_333>; + }; + +Example 3: UART controller node that consumes the clock generated by the clock + controller. + + serial_0: serial@14C10000 { + compatible = "samsung,exynos5433-uart"; + reg = <0x14C10000 0x100>; + interrupts = <0 421 0>; + clocks = <&cmu_peric CLK_PCLK_UART0>, + <&cmu_peric CLK_SCLK_UART0>; + clock-names = "uart", "clk_uart_baud0"; + pinctrl-names = "default"; + pinctrl-0 = <&uart0_bus>; + status = "disabled"; + }; -- GitLab From 9e128ced3851d2802b6db870f6b2e93f449ce013 Mon Sep 17 00:00:00 2001 From: Angelo Compagnucci Date: Wed, 4 Feb 2015 15:14:26 +0100 Subject: [PATCH 00031/11651] iio:adc:mcp3422 Fix incorrect scales table This patch fixes uncorrect order of mcp3422_scales table, the values was erroneously transposed. It removes also an unused array and a wrong comment. Signed-off-by: Angelo Compagnucci Cc: Stable@vger.kernel.org Signed-off-by: Jonathan Cameron --- drivers/iio/adc/mcp3422.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/drivers/iio/adc/mcp3422.c b/drivers/iio/adc/mcp3422.c index 51672256072b..b96c636470ef 100644 --- a/drivers/iio/adc/mcp3422.c +++ b/drivers/iio/adc/mcp3422.c @@ -58,20 +58,11 @@ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ } -/* LSB is in nV to eliminate floating point */ -static const u32 rates_to_lsb[] = {1000000, 250000, 62500, 15625}; - -/* - * scales calculated as: - * rates_to_lsb[sample_rate] / (1 << pga); - * pga is 1 for 0, 2 - */ - static const int mcp3422_scales[4][4] = { - { 1000000, 250000, 62500, 15625 }, - { 500000 , 125000, 31250, 7812 }, - { 250000 , 62500 , 15625, 3906 }, - { 125000 , 31250 , 7812 , 1953 } }; + { 1000000, 500000, 250000, 125000 }, + { 250000 , 125000, 62500 , 31250 }, + { 62500 , 31250 , 15625 , 7812 }, + { 15625 , 7812 , 3906 , 1953 } }; /* Constant msleep times for data acquisitions */ static const int mcp3422_read_times[4] = { -- GitLab From da019f59cb16570e78feaf10380ac65a3a06861e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Urs=20F=C3=A4ssler?= Date: Mon, 2 Feb 2015 17:12:23 +0100 Subject: [PATCH 00032/11651] iio: ad5686: fix optional reference voltage declaration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When not using the "_optional" function, a dummy regulator is returned and the driver fails to initialize. Signed-off-by: Urs Fässler Acked-by: Lars-Peter Clausen Cc: stable@vger.kernel.org Signed-off-by: Jonathan Cameron --- drivers/iio/dac/ad5686.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/dac/ad5686.c b/drivers/iio/dac/ad5686.c index f57562aa396f..15c73e20272d 100644 --- a/drivers/iio/dac/ad5686.c +++ b/drivers/iio/dac/ad5686.c @@ -322,7 +322,7 @@ static int ad5686_probe(struct spi_device *spi) st = iio_priv(indio_dev); spi_set_drvdata(spi, indio_dev); - st->reg = devm_regulator_get(&spi->dev, "vcc"); + st->reg = devm_regulator_get_optional(&spi->dev, "vcc"); if (!IS_ERR(st->reg)) { ret = regulator_enable(st->reg); if (ret) -- GitLab From ee3ac290e8aaa8396e697a11470703e616ab335f Mon Sep 17 00:00:00 2001 From: Nicholas Mc Guire Date: Mon, 2 Feb 2015 03:35:20 -0500 Subject: [PATCH 00033/11651] iio: vf610_adc: cleanup wait_for_completion return handling return type of wait_for_completion_timeout is unsigned long not int, this patch only fixes up the return handling. Signed-off-by: Nicholas Mc Guire Signed-off-by: Jonathan Cameron --- drivers/iio/adc/vf610_adc.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/iio/adc/vf610_adc.c b/drivers/iio/adc/vf610_adc.c index 8ec353c01d98..5b72d170fd36 100644 --- a/drivers/iio/adc/vf610_adc.c +++ b/drivers/iio/adc/vf610_adc.c @@ -259,7 +259,6 @@ static void vf610_adc_cfg_post_set(struct vf610_adc *info) static void vf610_adc_calibration(struct vf610_adc *info) { int adc_gc, hc_cfg; - int timeout; if (!info->adc_feature.calibration) return; @@ -271,9 +270,7 @@ static void vf610_adc_calibration(struct vf610_adc *info) adc_gc = readl(info->regs + VF610_REG_ADC_GC); writel(adc_gc | VF610_ADC_CAL, info->regs + VF610_REG_ADC_GC); - timeout = wait_for_completion_timeout - (&info->completion, VF610_ADC_TIMEOUT); - if (timeout == 0) + if (!wait_for_completion_timeout(&info->completion, VF610_ADC_TIMEOUT)) dev_err(info->dev, "Timeout for adc calibration\n"); adc_gc = readl(info->regs + VF610_REG_ADC_GS); -- GitLab From 96bd6224f07b8bf73e0359f15a3d7678118494e6 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Mon, 2 Feb 2015 23:23:56 +0900 Subject: [PATCH 00034/11651] clk: samsung: exynos5433: Add clocks using common clock framework This patch adds support for the CMU (Clock Management Units) of Exynos5433 which is an Octa-core 64bit SoC. This patch supports necessary clocks (PLL/MMC/UART/MCT/I2C/SPI) for kernel boot and includes binding documentation for Exynos5433 clock controller. Signed-off-by: Chanwoo Choi Acked-by: Inki Dae [s.nawrocki@samsung.com: whitespace cleanup in dt-bindings/clock/exynos5433.h] [ added U suffix to first arguments of PLL_35XX_RATE()] Signed-off-by: Sylwester Nawrocki --- drivers/clk/samsung/Makefile | 1 + drivers/clk/samsung/clk-exynos5433.c | 963 +++++++++++++++++++++++++ include/dt-bindings/clock/exynos5433.h | 199 +++++ 3 files changed, 1163 insertions(+) create mode 100644 drivers/clk/samsung/clk-exynos5433.c create mode 100644 include/dt-bindings/clock/exynos5433.h diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile index 006c6f294310..17e9af7fe81f 100644 --- a/drivers/clk/samsung/Makefile +++ b/drivers/clk/samsung/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_SOC_EXYNOS5250) += clk-exynos5250.o obj-$(CONFIG_SOC_EXYNOS5260) += clk-exynos5260.o obj-$(CONFIG_SOC_EXYNOS5410) += clk-exynos5410.o obj-$(CONFIG_SOC_EXYNOS5420) += clk-exynos5420.o +obj-$(CONFIG_ARCH_EXYNOS5433) += clk-exynos5433.o obj-$(CONFIG_SOC_EXYNOS5440) += clk-exynos5440.o obj-$(CONFIG_ARCH_EXYNOS) += clk-exynos-audss.o obj-$(CONFIG_ARCH_EXYNOS) += clk-exynos-clkout.o diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c new file mode 100644 index 000000000000..a4047390bfc2 --- /dev/null +++ b/drivers/clk/samsung/clk-exynos5433.c @@ -0,0 +1,963 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * Author: Chanwoo Choi + * + * 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. + * + * Common Clock Framework support for Exynos5443 SoC. + */ + +#include +#include +#include +#include + +#include + +#include "clk.h" +#include "clk-pll.h" + +/* + * Register offset definitions for CMU_TOP + */ +#define ISP_PLL_LOCK 0x0000 +#define AUD_PLL_LOCK 0x0004 +#define ISP_PLL_CON0 0x0100 +#define ISP_PLL_CON1 0x0104 +#define ISP_PLL_FREQ_DET 0x0108 +#define AUD_PLL_CON0 0x0110 +#define AUD_PLL_CON1 0x0114 +#define AUD_PLL_CON2 0x0118 +#define AUD_PLL_FREQ_DET 0x011c +#define MUX_SEL_TOP0 0x0200 +#define MUX_SEL_TOP1 0x0204 +#define MUX_SEL_TOP2 0x0208 +#define MUX_SEL_TOP3 0x020c +#define MUX_SEL_TOP4 0x0210 +#define MUX_SEL_TOP_MSCL 0x0220 +#define MUX_SEL_TOP_CAM1 0x0224 +#define MUX_SEL_TOP_DISP 0x0228 +#define MUX_SEL_TOP_FSYS0 0x0230 +#define MUX_SEL_TOP_FSYS1 0x0234 +#define MUX_SEL_TOP_PERIC0 0x0238 +#define MUX_SEL_TOP_PERIC1 0x023c +#define MUX_ENABLE_TOP0 0x0300 +#define MUX_ENABLE_TOP1 0x0304 +#define MUX_ENABLE_TOP2 0x0308 +#define MUX_ENABLE_TOP3 0x030c +#define MUX_ENABLE_TOP4 0x0310 +#define MUX_ENABLE_TOP_MSCL 0x0320 +#define MUX_ENABLE_TOP_CAM1 0x0324 +#define MUX_ENABLE_TOP_DISP 0x0328 +#define MUX_ENABLE_TOP_FSYS0 0x0330 +#define MUX_ENABLE_TOP_FSYS1 0x0334 +#define MUX_ENABLE_TOP_PERIC0 0x0338 +#define MUX_ENABLE_TOP_PERIC1 0x033c +#define MUX_STAT_TOP0 0x0400 +#define MUX_STAT_TOP1 0x0404 +#define MUX_STAT_TOP2 0x0408 +#define MUX_STAT_TOP3 0x040c +#define MUX_STAT_TOP4 0x0410 +#define MUX_STAT_TOP_MSCL 0x0420 +#define MUX_STAT_TOP_CAM1 0x0424 +#define MUX_STAT_TOP_FSYS0 0x0430 +#define MUX_STAT_TOP_FSYS1 0x0434 +#define MUX_STAT_TOP_PERIC0 0x0438 +#define MUX_STAT_TOP_PERIC1 0x043c +#define DIV_TOP0 0x0600 +#define DIV_TOP1 0x0604 +#define DIV_TOP2 0x0608 +#define DIV_TOP3 0x060c +#define DIV_TOP4 0x0610 +#define DIV_TOP_MSCL 0x0618 +#define DIV_TOP_CAM10 0x061c +#define DIV_TOP_CAM11 0x0620 +#define DIV_TOP_FSYS0 0x062c +#define DIV_TOP_FSYS1 0x0630 +#define DIV_TOP_FSYS2 0x0634 +#define DIV_TOP_PERIC0 0x0638 +#define DIV_TOP_PERIC1 0x063c +#define DIV_TOP_PERIC2 0x0640 +#define DIV_TOP_PERIC3 0x0644 +#define DIV_TOP_PERIC4 0x0648 +#define DIV_TOP_PLL_FREQ_DET 0x064c +#define DIV_STAT_TOP0 0x0700 +#define DIV_STAT_TOP1 0x0704 +#define DIV_STAT_TOP2 0x0708 +#define DIV_STAT_TOP3 0x070c +#define DIV_STAT_TOP4 0x0710 +#define DIV_STAT_TOP_MSCL 0x0718 +#define DIV_STAT_TOP_CAM10 0x071c +#define DIV_STAT_TOP_CAM11 0x0720 +#define DIV_STAT_TOP_FSYS0 0x072c +#define DIV_STAT_TOP_FSYS1 0x0730 +#define DIV_STAT_TOP_FSYS2 0x0734 +#define DIV_STAT_TOP_PERIC0 0x0738 +#define DIV_STAT_TOP_PERIC1 0x073c +#define DIV_STAT_TOP_PERIC2 0x0740 +#define DIV_STAT_TOP_PERIC3 0x0744 +#define DIV_STAT_TOP_PLL_FREQ_DET 0x074c +#define ENABLE_ACLK_TOP 0x0800 +#define ENABLE_SCLK_TOP 0x0a00 +#define ENABLE_SCLK_TOP_MSCL 0x0a04 +#define ENABLE_SCLK_TOP_CAM1 0x0a08 +#define ENABLE_SCLK_TOP_DISP 0x0a0c +#define ENABLE_SCLK_TOP_FSYS 0x0a10 +#define ENABLE_SCLK_TOP_PERIC 0x0a14 +#define ENABLE_IP_TOP 0x0b00 +#define ENABLE_CMU_TOP 0x0c00 +#define ENABLE_CMU_TOP_DIV_STAT 0x0c04 + +static unsigned long top_clk_regs[] __initdata = { + ISP_PLL_LOCK, + AUD_PLL_LOCK, + ISP_PLL_CON0, + ISP_PLL_CON1, + ISP_PLL_FREQ_DET, + AUD_PLL_CON0, + AUD_PLL_CON1, + AUD_PLL_CON2, + AUD_PLL_FREQ_DET, + MUX_SEL_TOP0, + MUX_SEL_TOP1, + MUX_SEL_TOP2, + MUX_SEL_TOP3, + MUX_SEL_TOP4, + MUX_SEL_TOP_MSCL, + MUX_SEL_TOP_CAM1, + MUX_SEL_TOP_DISP, + MUX_SEL_TOP_FSYS0, + MUX_SEL_TOP_FSYS1, + MUX_SEL_TOP_PERIC0, + MUX_SEL_TOP_PERIC1, + MUX_ENABLE_TOP0, + MUX_ENABLE_TOP1, + MUX_ENABLE_TOP2, + MUX_ENABLE_TOP3, + MUX_ENABLE_TOP4, + MUX_ENABLE_TOP_MSCL, + MUX_ENABLE_TOP_CAM1, + MUX_ENABLE_TOP_DISP, + MUX_ENABLE_TOP_FSYS0, + MUX_ENABLE_TOP_FSYS1, + MUX_ENABLE_TOP_PERIC0, + MUX_ENABLE_TOP_PERIC1, + MUX_STAT_TOP0, + MUX_STAT_TOP1, + MUX_STAT_TOP2, + MUX_STAT_TOP3, + MUX_STAT_TOP4, + MUX_STAT_TOP_MSCL, + MUX_STAT_TOP_CAM1, + MUX_STAT_TOP_FSYS0, + MUX_STAT_TOP_FSYS1, + MUX_STAT_TOP_PERIC0, + MUX_STAT_TOP_PERIC1, + DIV_TOP0, + DIV_TOP1, + DIV_TOP2, + DIV_TOP3, + DIV_TOP4, + DIV_TOP_MSCL, + DIV_TOP_CAM10, + DIV_TOP_CAM11, + DIV_TOP_FSYS0, + DIV_TOP_FSYS1, + DIV_TOP_FSYS2, + DIV_TOP_PERIC0, + DIV_TOP_PERIC1, + DIV_TOP_PERIC2, + DIV_TOP_PERIC3, + DIV_TOP_PERIC4, + DIV_TOP_PLL_FREQ_DET, + DIV_STAT_TOP0, + DIV_STAT_TOP1, + DIV_STAT_TOP2, + DIV_STAT_TOP3, + DIV_STAT_TOP4, + DIV_STAT_TOP_MSCL, + DIV_STAT_TOP_CAM10, + DIV_STAT_TOP_CAM11, + DIV_STAT_TOP_FSYS0, + DIV_STAT_TOP_FSYS1, + DIV_STAT_TOP_FSYS2, + DIV_STAT_TOP_PERIC0, + DIV_STAT_TOP_PERIC1, + DIV_STAT_TOP_PERIC2, + DIV_STAT_TOP_PERIC3, + DIV_STAT_TOP_PLL_FREQ_DET, + ENABLE_ACLK_TOP, + ENABLE_SCLK_TOP, + ENABLE_SCLK_TOP_MSCL, + ENABLE_SCLK_TOP_CAM1, + ENABLE_SCLK_TOP_DISP, + ENABLE_SCLK_TOP_FSYS, + ENABLE_SCLK_TOP_PERIC, + ENABLE_IP_TOP, + ENABLE_CMU_TOP, + ENABLE_CMU_TOP_DIV_STAT, +}; + +/* list of all parent clock list */ +PNAME(mout_aud_pll_p) = { "oscclk", "fout_aud_pll", }; +PNAME(mout_isp_pll_p) = { "oscclk", "fout_isp_pll", }; +PNAME(mout_aud_pll_user_p) = { "oscclk", "mout_aud_pll", }; +PNAME(mout_mphy_pll_user_p) = { "oscclk", "sclk_mphy_pll", }; +PNAME(mout_mfc_pll_user_p) = { "oscclk", "sclk_mfc_pll", }; +PNAME(mout_bus_pll_user_p) = { "oscclk", "sclk_bus_pll", }; +PNAME(mout_bus_pll_user_t_p) = { "oscclk", "mout_bus_pll_user", }; + +PNAME(mout_bus_mfc_pll_user_p) = { "mout_bus_pll_user", "mout_mfc_pll_user",}; +PNAME(mout_mfc_bus_pll_user_p) = { "mout_mfc_pll_user", "mout_bus_pll_user",}; +PNAME(mout_aclk_cam1_552_b_p) = { "mout_aclk_cam1_552_a", + "mout_mfc_pll_user", }; +PNAME(mout_aclk_cam1_552_a_p) = { "mout_isp_pll", "mout_bus_pll_user", }; + +PNAME(mout_bus_mphy_pll_user_p) = { "mout_bus_pll_user", + "mout_mphy_pll_user", }; +PNAME(mout_aclk_mscl_b_p) = { "mout_aclk_mscl_400_a", + "mout_mphy_pll_user", }; +PNAME(mout_aclk_g2d_400_b_p) = { "mout_aclk_g2d_400_a", + "mout_mphy_pll_user", }; + +PNAME(mout_sclk_jpeg_c_p) = { "mout_sclk_jpeg_b", "mout_mphy_pll_user",}; +PNAME(mout_sclk_jpeg_b_p) = { "mout_sclk_jpeg_a", "mout_mfc_pll_user", }; + +PNAME(mout_sclk_mmc2_b_p) = { "mout_sclk_mmc2_a", "mout_mfc_pll_user",}; +PNAME(mout_sclk_mmc1_b_p) = { "mout_sclk_mmc1_a", "mout_mfc_pll_user",}; +PNAME(mout_sclk_mmc0_d_p) = { "mout_sclk_mmc0_c", "mout_isp_pll", }; +PNAME(mout_sclk_mmc0_c_p) = { "mout_sclk_mmc0_b", "mout_mphy_pll_user",}; +PNAME(mout_sclk_mmc0_b_p) = { "mout_sclk_mmc0_a", "mout_mfc_pll_user", }; + +static struct samsung_mux_clock top_mux_clks[] __initdata = { + /* MUX_SEL_TOP0 */ + MUX(CLK_MOUT_AUD_PLL, "mout_aud_pll", mout_aud_pll_p, MUX_SEL_TOP0, + 4, 1), + MUX(CLK_MOUT_ISP_PLL, "mout_isp_pll", mout_isp_pll_p, MUX_SEL_TOP0, + 0, 1), + + /* MUX_SEL_TOP1 */ + MUX(CLK_MOUT_AUD_PLL_USER_T, "mout_aud_pll_user_t", + mout_aud_pll_user_p, MUX_SEL_TOP1, 12, 1), + MUX(CLK_MOUT_MPHY_PLL_USER, "mout_mphy_pll_user", mout_mphy_pll_user_p, + MUX_SEL_TOP1, 8, 1), + MUX(CLK_MOUT_MFC_PLL_USER, "mout_mfc_pll_user", mout_mfc_pll_user_p, + MUX_SEL_TOP1, 4, 1), + MUX(CLK_MOUT_BUS_PLL_USER, "mout_bus_pll_user", mout_bus_pll_user_p, + MUX_SEL_TOP1, 0, 1), + + /* MUX_SEL_TOP2 */ + MUX(CLK_MOUT_ACLK_HEVC_400, "mout_aclk_hevc_400", + mout_bus_mfc_pll_user_p, MUX_SEL_TOP2, 28, 1), + MUX(CLK_MOUT_ACLK_CAM1_333, "mout_aclk_cam1_333", + mout_mfc_bus_pll_user_p, MUX_SEL_TOP2, 16, 1), + MUX(CLK_MOUT_ACLK_CAM1_552_B, "mout_aclk_cam1_552_b", + mout_aclk_cam1_552_b_p, MUX_SEL_TOP2, 12, 1), + MUX(CLK_MOUT_ACLK_CAM1_552_A, "mout_aclk_cam1_552_a", + mout_aclk_cam1_552_a_p, MUX_SEL_TOP2, 8, 1), + MUX(CLK_MOUT_ACLK_ISP_DIS_400, "mout_aclk_isp_dis_400", + mout_bus_mfc_pll_user_p, MUX_SEL_TOP2, 4, 1), + MUX(CLK_MOUT_ACLK_ISP_400, "mout_aclk_isp_400", + mout_bus_mfc_pll_user_p, MUX_SEL_TOP2, 0, 1), + + /* MUX_SEL_TOP3 */ + MUX(CLK_MOUT_ACLK_BUS0_400, "mout_aclk_bus0_400", + mout_bus_mphy_pll_user_p, MUX_SEL_TOP3, 20, 1), + MUX(CLK_MOUT_ACLK_MSCL_400_B, "mout_aclk_mscl_400_b", + mout_aclk_mscl_b_p, MUX_SEL_TOP3, 16, 1), + MUX(CLK_MOUT_ACLK_MSCL_400_A, "mout_aclk_mscl_400_a", + mout_bus_mfc_pll_user_p, MUX_SEL_TOP3, 12, 1), + MUX(CLK_MOUT_ACLK_GSCL_333, "mout_aclk_gscl_333", + mout_mfc_bus_pll_user_p, MUX_SEL_TOP3, 8, 1), + MUX(CLK_MOUT_ACLK_G2D_400_B, "mout_aclk_g2d_400_b", + mout_aclk_g2d_400_b_p, MUX_SEL_TOP3, 4, 1), + MUX(CLK_MOUT_ACLK_G2D_400_A, "mout_aclk_g2d_400_a", + mout_bus_mfc_pll_user_p, MUX_SEL_TOP3, 0, 1), + + /* MUX_SEL_TOP_MSCL */ + MUX(CLK_MOUT_SCLK_JPEG_C, "mout_sclk_jpeg_c", mout_sclk_jpeg_c_p, + MUX_SEL_TOP_MSCL, 8, 1), + MUX(CLK_MOUT_SCLK_JPEG_B, "mout_sclk_jpeg_b", mout_sclk_jpeg_b_p, + MUX_SEL_TOP_MSCL, 4, 1), + MUX(CLK_MOUT_SCLK_JPEG_A, "mout_sclk_jpeg_a", mout_bus_pll_user_t_p, + MUX_SEL_TOP_MSCL, 0, 1), + + /* MUX_SEL_TOP_FSYS0 */ + MUX(CLK_MOUT_SCLK_MMC2_B, "mout_sclk_mmc2_b", mout_sclk_mmc2_b_p, + MUX_SEL_TOP_FSYS0, 28, 1), + MUX(CLK_MOUT_SCLK_MMC2_A, "mout_sclk_mmc2_a", mout_bus_pll_user_t_p, + MUX_SEL_TOP_FSYS0, 24, 1), + MUX(CLK_MOUT_SCLK_MMC1_B, "mout_sclk_mmc1_b", mout_sclk_mmc1_b_p, + MUX_SEL_TOP_FSYS0, 20, 1), + MUX(CLK_MOUT_SCLK_MMC1_A, "mout_sclk_mmc1_a", mout_bus_pll_user_t_p, + MUX_SEL_TOP_FSYS0, 16, 1), + MUX(CLK_MOUT_SCLK_MMC0_D, "mout_sclk_mmc0_d", mout_sclk_mmc0_d_p, + MUX_SEL_TOP_FSYS0, 12, 1), + MUX(CLK_MOUT_SCLK_MMC0_C, "mout_sclk_mmc0_c", mout_sclk_mmc0_c_p, + MUX_SEL_TOP_FSYS0, 8, 1), + MUX(CLK_MOUT_SCLK_MMC0_B, "mout_sclk_mmc0_b", mout_sclk_mmc0_b_p, + MUX_SEL_TOP_FSYS0, 4, 1), + MUX(CLK_MOUT_SCLK_MMC0_A, "mout_sclk_mmc0_a", mout_bus_pll_user_t_p, + MUX_SEL_TOP_FSYS0, 0, 1), + + /* MUX_SEL_TOP_PERIC0 */ + MUX(CLK_MOUT_SCLK_SPI4, "mout_sclk_spi4", mout_bus_pll_user_t_p, + MUX_SEL_TOP_PERIC0, 28, 1), + MUX(CLK_MOUT_SCLK_SPI3, "mout_sclk_spi3", mout_bus_pll_user_t_p, + MUX_SEL_TOP_PERIC0, 24, 1), + MUX(CLK_MOUT_SCLK_UART2, "mout_sclk_uart2", mout_bus_pll_user_t_p, + MUX_SEL_TOP_PERIC0, 20, 1), + MUX(CLK_MOUT_SCLK_UART1, "mout_sclk_uart1", mout_bus_pll_user_t_p, + MUX_SEL_TOP_PERIC0, 16, 1), + MUX(CLK_MOUT_SCLK_UART0, "mout_sclk_uart0", mout_bus_pll_user_t_p, + MUX_SEL_TOP_PERIC0, 12, 1), + MUX(CLK_MOUT_SCLK_SPI2, "mout_sclk_spi2", mout_bus_pll_user_t_p, + MUX_SEL_TOP_PERIC0, 8, 1), + MUX(CLK_MOUT_SCLK_SPI1, "mout_sclk_spi1", mout_bus_pll_user_t_p, + MUX_SEL_TOP_PERIC0, 4, 1), + MUX(CLK_MOUT_SCLK_SPI0, "mout_sclk_spi0", mout_bus_pll_user_t_p, + MUX_SEL_TOP_PERIC0, 0, 1), +}; + +static struct samsung_div_clock top_div_clks[] __initdata = { + /* DIV_TOP2 */ + DIV(CLK_DIV_ACLK_FSYS_200, "div_aclk_fsys_200", "mout_bus_pll_user", + DIV_TOP2, 0, 3), + + /* DIV_TOP3 */ + DIV(CLK_DIV_ACLK_IMEM_SSSX_266, "div_aclk_imem_sssx_266", + "mout_bus_pll_user", DIV_TOP3, 24, 3), + DIV(CLK_DIV_ACLK_IMEM_200, "div_aclk_imem_200", + "mout_bus_pll_user", DIV_TOP3, 20, 3), + DIV(CLK_DIV_ACLK_IMEM_266, "div_aclk_imem_266", + "mout_bus_pll_user", DIV_TOP3, 16, 3), + DIV(CLK_DIV_ACLK_PERIC_66_B, "div_aclk_peric_66_b", + "div_aclk_peric_66_a", DIV_TOP3, 12, 3), + DIV(CLK_DIV_ACLK_PERIC_66_A, "div_aclk_peric_66_a", + "mout_bus_pll_user", DIV_TOP3, 8, 3), + DIV(CLK_DIV_ACLK_PERIS_66_B, "div_aclk_peris_66_b", + "div_aclk_peris_66_a", DIV_TOP3, 4, 3), + DIV(CLK_DIV_ACLK_PERIS_66_A, "div_aclk_peris_66_a", + "mout_bus_pll_user", DIV_TOP3, 0, 3), + + /* DIV_TOP_FSYS0 */ + DIV(CLK_DIV_SCLK_MMC1_B, "div_sclk_mmc1_b", "div_sclk_mmc1_a", + DIV_TOP_FSYS0, 16, 8), + DIV(CLK_DIV_SCLK_MMC1_A, "div_sclk_mmc1_a", "mout_sclk_mmc1_b", + DIV_TOP_FSYS0, 12, 4), + DIV_F(CLK_DIV_SCLK_MMC0_B, "div_sclk_mmc0_b", "div_sclk_mmc0_a", + DIV_TOP_FSYS0, 4, 8, CLK_SET_RATE_PARENT, 0), + DIV_F(CLK_DIV_SCLK_MMC0_A, "div_sclk_mmc0_a", "mout_sclk_mmc0_d", + DIV_TOP_FSYS0, 0, 4, CLK_SET_RATE_PARENT, 0), + + /* DIV_TOP_FSYS1 */ + DIV(CLK_DIV_SCLK_MMC2_B, "div_sclk_mmc2_b", "div_sclk_mmc2_a", + DIV_TOP_FSYS1, 4, 8), + DIV(CLK_DIV_SCLK_MMC2_A, "div_sclk_mmc2_a", "mout_sclk_mmc2_b", + DIV_TOP_FSYS1, 0, 4), + + /* DIV_TOP_PERIC0 */ + DIV(CLK_DIV_SCLK_SPI1_B, "div_sclk_spi1_b", "div_sclk_spi1_a", + DIV_TOP_PERIC0, 16, 8), + DIV(CLK_DIV_SCLK_SPI1_A, "div_sclk_spi1_a", "mout_sclk_spi1", + DIV_TOP_PERIC0, 12, 4), + DIV(CLK_DIV_SCLK_SPI0_B, "div_sclk_spi0_b", "div_sclk_spi0_a", + DIV_TOP_PERIC0, 4, 8), + DIV(CLK_DIV_SCLK_SPI0_A, "div_sclk_spi0_a", "mout_sclk_spi0", + DIV_TOP_PERIC0, 0, 4), + + /* DIV_TOP_PERIC1 */ + DIV(CLK_DIV_SCLK_SPI2_B, "div_sclk_spi2_b", "div_sclk_spi2_a", + DIV_TOP_PERIC1, 4, 8), + DIV(CLK_DIV_SCLK_SPI2_A, "div_sclk_spi2_a", "mout_sclk_spi2", + DIV_TOP_PERIC1, 0, 4), + + /* DIV_TOP_PERIC2 */ + DIV(CLK_DIV_SCLK_UART2, "div_sclk_uart2", "mout_sclk_uart2", + DIV_TOP_PERIC2, 8, 4), + DIV(CLK_DIV_SCLK_UART1, "div_sclk_uart1", "mout_sclk_uart0", + DIV_TOP_PERIC2, 4, 4), + DIV(CLK_DIV_SCLK_UART0, "div_sclk_uart0", "mout_sclk_uart1", + DIV_TOP_PERIC2, 0, 4), + + /* DIV_TOP_PERIC4 */ + DIV(CLK_DIV_SCLK_SPI4_B, "div_sclk_spi4_b", "div_sclk_spi4_a", + DIV_TOP_PERIC4, 16, 8), + DIV(CLK_DIV_SCLK_SPI4_A, "div_sclk_spi4_a", "mout_sclk_spi4", + DIV_TOP_PERIC4, 12, 4), + DIV(CLK_DIV_SCLK_SPI3_B, "div_sclk_spi3_b", "div_sclk_spi3_a", + DIV_TOP_PERIC4, 4, 8), + DIV(CLK_DIV_SCLK_SPI3_A, "div_sclk_spi3_a", "mout_sclk_spi3", + DIV_TOP_PERIC4, 0, 4), +}; + +static struct samsung_gate_clock top_gate_clks[] __initdata = { + /* ENABLE_ACLK_TOP */ + GATE(CLK_ACLK_PERIC_66, "aclk_peric_66", "div_aclk_peric_66_b", + ENABLE_ACLK_TOP, 22, + CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_PERIS_66, "aclk_peris_66", "div_aclk_peris_66_b", + ENABLE_ACLK_TOP, 21, + CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_FSYS_200, "aclk_fsys_200", "div_aclk_fsys_200", + ENABLE_ACLK_TOP, 18, + CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0), + + /* ENABLE_SCLK_TOP_FSYS */ + GATE(CLK_SCLK_MMC2_FSYS, "sclk_mmc2_fsys", "div_sclk_mmc2_b", + ENABLE_SCLK_TOP_FSYS, 6, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_MMC1_FSYS, "sclk_mmc1_fsys", "div_sclk_mmc1_b", + ENABLE_SCLK_TOP_FSYS, 5, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_MMC0_FSYS, "sclk_mmc0_fsys", "div_sclk_mmc0_b", + ENABLE_SCLK_TOP_FSYS, 4, CLK_SET_RATE_PARENT, 0), + + /* ENABLE_SCLK_TOP_PERIC */ + GATE(CLK_SCLK_SPI4_PERIC, "sclk_spi4_peric", "div_sclk_spi4_b", + ENABLE_SCLK_TOP_PERIC, 12, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_SPI3_PERIC, "sclk_spi3_peric", "div_sclk_spi3_b", + ENABLE_SCLK_TOP_PERIC, 11, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_UART2_PERIC, "sclk_uart2_peric", "div_sclk_uart2", + ENABLE_SCLK_TOP_PERIC, 5, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_UART1_PERIC, "sclk_uart1_peric", "div_sclk_uart1", + ENABLE_SCLK_TOP_PERIC, 4, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_UART0_PERIC, "sclk_uart0_peric", "div_sclk_uart0", + ENABLE_SCLK_TOP_PERIC, 3, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_SPI2_PERIC, "sclk_spi2_peric", "div_sclk_spi2_b", + ENABLE_SCLK_TOP_PERIC, 2, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_SPI1_PERIC, "sclk_spi1_peric", "div_sclk_spi1_b", + ENABLE_SCLK_TOP_PERIC, 1, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_SPI0_PERIC, "sclk_spi0_peric", "div_sclk_spi0_b", + ENABLE_SCLK_TOP_PERIC, 0, CLK_SET_RATE_PARENT, 0), +}; + +/* + * ATLAS_PLL & APOLLO_PLL & MEM0_PLL & MEM1_PLL & BUS_PLL & MFC_PLL + * & MPHY_PLL & G3D_PLL & DISP_PLL & ISP_PLL + */ +static struct samsung_pll_rate_table exynos5443_pll_rates[] = { + PLL_35XX_RATE(2500000000U, 625, 6, 0), + PLL_35XX_RATE(2400000000U, 500, 5, 0), + PLL_35XX_RATE(2300000000U, 575, 6, 0), + PLL_35XX_RATE(2200000000U, 550, 6, 0), + PLL_35XX_RATE(2100000000U, 350, 4, 0), + PLL_35XX_RATE(2000000000U, 500, 6, 0), + PLL_35XX_RATE(1900000000U, 475, 6, 0), + PLL_35XX_RATE(1800000000U, 375, 5, 0), + PLL_35XX_RATE(1700000000U, 425, 6, 0), + PLL_35XX_RATE(1600000000U, 400, 6, 0), + PLL_35XX_RATE(1500000000U, 250, 4, 0), + PLL_35XX_RATE(1400000000U, 350, 6, 0), + PLL_35XX_RATE(1332000000U, 222, 4, 0), + PLL_35XX_RATE(1300000000U, 325, 6, 0), + PLL_35XX_RATE(1200000000U, 500, 5, 1), + PLL_35XX_RATE(1100000000U, 550, 6, 1), + PLL_35XX_RATE(1086000000U, 362, 4, 1), + PLL_35XX_RATE(1066000000U, 533, 6, 1), + PLL_35XX_RATE(1000000000U, 500, 6, 1), + PLL_35XX_RATE(933000000U, 311, 4, 1), + PLL_35XX_RATE(921000000U, 307, 4, 1), + PLL_35XX_RATE(900000000U, 375, 5, 1), + PLL_35XX_RATE(825000000U, 275, 4, 1), + PLL_35XX_RATE(800000000U, 400, 6, 1), + PLL_35XX_RATE(733000000U, 733, 12, 1), + PLL_35XX_RATE(700000000U, 360, 6, 1), + PLL_35XX_RATE(667000000U, 222, 4, 1), + PLL_35XX_RATE(633000000U, 211, 4, 1), + PLL_35XX_RATE(600000000U, 500, 5, 2), + PLL_35XX_RATE(552000000U, 460, 5, 2), + PLL_35XX_RATE(550000000U, 550, 6, 2), + PLL_35XX_RATE(543000000U, 362, 4, 2), + PLL_35XX_RATE(533000000U, 533, 6, 2), + PLL_35XX_RATE(500000000U, 500, 6, 2), + PLL_35XX_RATE(444000000U, 370, 5, 2), + PLL_35XX_RATE(420000000U, 350, 5, 2), + PLL_35XX_RATE(400000000U, 400, 6, 2), + PLL_35XX_RATE(350000000U, 360, 6, 2), + PLL_35XX_RATE(333000000U, 222, 4, 2), + PLL_35XX_RATE(300000000U, 500, 5, 3), + PLL_35XX_RATE(266000000U, 532, 6, 3), + PLL_35XX_RATE(200000000U, 400, 6, 3), + PLL_35XX_RATE(166000000U, 332, 6, 3), + PLL_35XX_RATE(160000000U, 320, 6, 3), + PLL_35XX_RATE(133000000U, 552, 6, 4), + PLL_35XX_RATE(100000000U, 400, 6, 4), + { /* sentinel */ } +}; + +/* AUD_PLL */ +static struct samsung_pll_rate_table exynos5443_aud_pll_rates[] = { + PLL_36XX_RATE(400000000U, 200, 3, 2, 0), + PLL_36XX_RATE(393216000U, 197, 3, 2, -25690), + PLL_36XX_RATE(384000000U, 128, 2, 2, 0), + PLL_36XX_RATE(368640000U, 246, 4, 2, -15729), + PLL_36XX_RATE(361507200U, 181, 3, 2, -16148), + PLL_36XX_RATE(338688000U, 113, 2, 2, -6816), + PLL_36XX_RATE(294912000U, 98, 1, 3, 19923), + PLL_36XX_RATE(288000000U, 96, 1, 3, 0), + PLL_36XX_RATE(252000000U, 84, 1, 3, 0), + { /* sentinel */ } +}; + +static struct samsung_pll_clock top_pll_clks[] __initdata = { + PLL(pll_35xx, CLK_FOUT_ISP_PLL, "fout_isp_pll", "oscclk", + ISP_PLL_LOCK, ISP_PLL_CON0, exynos5443_pll_rates), + PLL(pll_36xx, CLK_FOUT_AUD_PLL, "fout_aud_pll", "oscclk", + AUD_PLL_LOCK, AUD_PLL_CON0, exynos5443_aud_pll_rates), +}; + +static struct samsung_cmu_info top_cmu_info __initdata = { + .pll_clks = top_pll_clks, + .nr_pll_clks = ARRAY_SIZE(top_pll_clks), + .mux_clks = top_mux_clks, + .nr_mux_clks = ARRAY_SIZE(top_mux_clks), + .div_clks = top_div_clks, + .nr_div_clks = ARRAY_SIZE(top_div_clks), + .gate_clks = top_gate_clks, + .nr_gate_clks = ARRAY_SIZE(top_gate_clks), + .nr_clk_ids = TOP_NR_CLK, + .clk_regs = top_clk_regs, + .nr_clk_regs = ARRAY_SIZE(top_clk_regs), +}; + +static void __init exynos5433_cmu_top_init(struct device_node *np) +{ + samsung_cmu_register_one(np, &top_cmu_info); +} +CLK_OF_DECLARE(exynos5433_cmu_top, "samsung,exynos5433-cmu-top", + exynos5433_cmu_top_init); + +/* + * Register offset definitions for CMU_CPIF + */ +#define MPHY_PLL_LOCK 0x0000 +#define MPHY_PLL_CON0 0x0100 +#define MPHY_PLL_CON1 0x0104 +#define MPHY_PLL_FREQ_DET 0x010c +#define MUX_SEL_CPIF0 0x0200 +#define DIV_CPIF 0x0600 +#define ENABLE_SCLK_CPIF 0x0a00 + +static unsigned long cpif_clk_regs[] __initdata = { + MPHY_PLL_LOCK, + MPHY_PLL_CON0, + MPHY_PLL_CON1, + MPHY_PLL_FREQ_DET, + MUX_SEL_CPIF0, + ENABLE_SCLK_CPIF, +}; + +/* list of all parent clock list */ +PNAME(mout_mphy_pll_p) = { "oscclk", "fout_mphy_pll", }; + +static struct samsung_pll_clock cpif_pll_clks[] __initdata = { + PLL(pll_35xx, CLK_FOUT_MPHY_PLL, "fout_mphy_pll", "oscclk", + MPHY_PLL_LOCK, MPHY_PLL_CON0, exynos5443_pll_rates), +}; + +static struct samsung_mux_clock cpif_mux_clks[] __initdata = { + /* MUX_SEL_CPIF0 */ + MUX(CLK_MOUT_MPHY_PLL, "mout_mphy_pll", mout_mphy_pll_p, MUX_SEL_CPIF0, + 0, 1), +}; + +static struct samsung_div_clock cpif_div_clks[] __initdata = { + /* DIV_CPIF */ + DIV(CLK_DIV_SCLK_MPHY, "div_sclk_mphy", "mout_mphy_pll", DIV_CPIF, + 0, 6), +}; + +static struct samsung_gate_clock cpif_gate_clks[] __initdata = { + /* ENABLE_SCLK_CPIF */ + GATE(CLK_SCLK_MPHY_PLL, "sclk_mphy_pll", "mout_mphy_pll", + ENABLE_SCLK_CPIF, 9, 0, 0), + GATE(CLK_SCLK_UFS_MPHY, "sclk_ufs_mphy", "div_sclk_mphy", + ENABLE_SCLK_CPIF, 4, 0, 0), +}; + +static struct samsung_cmu_info cpif_cmu_info __initdata = { + .pll_clks = cpif_pll_clks, + .nr_pll_clks = ARRAY_SIZE(cpif_pll_clks), + .mux_clks = cpif_mux_clks, + .nr_mux_clks = ARRAY_SIZE(cpif_mux_clks), + .div_clks = cpif_div_clks, + .nr_div_clks = ARRAY_SIZE(cpif_div_clks), + .gate_clks = cpif_gate_clks, + .nr_gate_clks = ARRAY_SIZE(cpif_gate_clks), + .nr_clk_ids = CPIF_NR_CLK, + .clk_regs = cpif_clk_regs, + .nr_clk_regs = ARRAY_SIZE(cpif_clk_regs), +}; + +static void __init exynos5433_cmu_cpif_init(struct device_node *np) +{ + samsung_cmu_register_one(np, &cpif_cmu_info); +} +CLK_OF_DECLARE(exynos5433_cmu_cpif, "samsung,exynos5433-cmu-cpif", + exynos5433_cmu_cpif_init); + +/* + * Register offset definitions for CMU_MIF + */ +#define MEM0_PLL_LOCK 0x0000 +#define MEM1_PLL_LOCK 0x0004 +#define BUS_PLL_LOCK 0x0008 +#define MFC_PLL_LOCK 0x000c +#define MEM0_PLL_CON0 0x0100 +#define MEM0_PLL_CON1 0x0104 +#define MEM0_PLL_FREQ_DET 0x010c +#define MEM1_PLL_CON0 0x0110 +#define MEM1_PLL_CON1 0x0114 +#define MEM1_PLL_FREQ_DET 0x011c +#define BUS_PLL_CON0 0x0120 +#define BUS_PLL_CON1 0x0124 +#define BUS_PLL_FREQ_DET 0x012c +#define MFC_PLL_CON0 0x0130 +#define MFC_PLL_CON1 0x0134 +#define MFC_PLL_FREQ_DET 0x013c + +static unsigned long mif_clk_regs[] __initdata = { + MEM0_PLL_LOCK, + MEM1_PLL_LOCK, + BUS_PLL_LOCK, + MFC_PLL_LOCK, + MEM0_PLL_CON0, + MEM0_PLL_CON1, + MEM0_PLL_FREQ_DET, + MEM1_PLL_CON0, + MEM1_PLL_CON1, + MEM1_PLL_FREQ_DET, + BUS_PLL_CON0, + BUS_PLL_CON1, + BUS_PLL_FREQ_DET, + MFC_PLL_CON0, + MFC_PLL_CON1, + MFC_PLL_FREQ_DET, +}; + +static struct samsung_pll_clock mif_pll_clks[] __initdata = { + PLL(pll_35xx, CLK_FOUT_MEM0_PLL, "fout_mem0_pll", "oscclk", + MEM0_PLL_LOCK, MEM0_PLL_CON0, exynos5443_pll_rates), + PLL(pll_35xx, CLK_FOUT_MEM1_PLL, "fout_mem1_pll", "oscclk", + MEM1_PLL_LOCK, MEM1_PLL_CON0, exynos5443_pll_rates), + PLL(pll_35xx, CLK_FOUT_BUS_PLL, "fout_bus_pll", "oscclk", + BUS_PLL_LOCK, BUS_PLL_CON0, exynos5443_pll_rates), + PLL(pll_35xx, CLK_FOUT_MFC_PLL, "fout_mfc_pll", "oscclk", + MFC_PLL_LOCK, MFC_PLL_CON0, exynos5443_pll_rates), +}; + +static struct samsung_cmu_info mif_cmu_info __initdata = { + .pll_clks = mif_pll_clks, + .nr_pll_clks = ARRAY_SIZE(mif_pll_clks), + .nr_clk_ids = MIF_NR_CLK, + .clk_regs = mif_clk_regs, + .nr_clk_regs = ARRAY_SIZE(mif_clk_regs), +}; + +static void __init exynos5433_cmu_mif_init(struct device_node *np) +{ + samsung_cmu_register_one(np, &mif_cmu_info); +} +CLK_OF_DECLARE(exynos5433_cmu_mif, "samsung,exynos5433-cmu-mif", + exynos5433_cmu_mif_init); + +/* + * Register offset definitions for CMU_PERIC + */ +#define DIV_PERIC 0x0600 +#define ENABLE_ACLK_PERIC 0x0800 +#define ENABLE_PCLK_PERIC0 0x0900 +#define ENABLE_PCLK_PERIC1 0x0904 +#define ENABLE_SCLK_PERIC 0x0A00 +#define ENABLE_IP_PERIC0 0x0B00 +#define ENABLE_IP_PERIC1 0x0B04 +#define ENABLE_IP_PERIC2 0x0B08 + +static unsigned long peric_clk_regs[] __initdata = { + DIV_PERIC, + ENABLE_ACLK_PERIC, + ENABLE_PCLK_PERIC0, + ENABLE_PCLK_PERIC1, + ENABLE_SCLK_PERIC, + ENABLE_IP_PERIC0, + ENABLE_IP_PERIC1, + ENABLE_IP_PERIC2, +}; + +static struct samsung_gate_clock peric_gate_clks[] __initdata = { + /* ENABLE_PCLK_PERIC0 */ + GATE(CLK_PCLK_SPI2, "pclk_spi2", "aclk_peric_66", ENABLE_PCLK_PERIC0, + 23, CLK_SET_RATE_PARENT, 0), + GATE(CLK_PCLK_SPI1, "pclk_spi1", "aclk_peric_66", ENABLE_PCLK_PERIC0, + 22, CLK_SET_RATE_PARENT, 0), + GATE(CLK_PCLK_SPI0, "pclk_spi0", "aclk_peric_66", ENABLE_PCLK_PERIC0, + 21, CLK_SET_RATE_PARENT, 0), + GATE(CLK_PCLK_UART2, "pclk_uart2", "aclk_peric_66", ENABLE_PCLK_PERIC0, + 14, CLK_SET_RATE_PARENT, 0), + GATE(CLK_PCLK_UART1, "pclk_uart1", "aclk_peric_66", ENABLE_PCLK_PERIC0, + 13, CLK_SET_RATE_PARENT, 0), + GATE(CLK_PCLK_UART0, "pclk_uart0", "aclk_peric_66", ENABLE_PCLK_PERIC0, + 12, CLK_SET_RATE_PARENT, 0), + GATE(CLK_PCLK_HSI2C3, "pclk_hsi2c3", "aclk_peric_66", + ENABLE_PCLK_PERIC0, 11, CLK_SET_RATE_PARENT, 0), + GATE(CLK_PCLK_HSI2C2, "pclk_hsi2c2", "aclk_peric_66", + ENABLE_PCLK_PERIC0, 10, CLK_SET_RATE_PARENT, 0), + GATE(CLK_PCLK_HSI2C1, "pclk_hsi2c1", "aclk_peric_66", + ENABLE_PCLK_PERIC0, 9, CLK_SET_RATE_PARENT, 0), + GATE(CLK_PCLK_HSI2C0, "pclk_hsi2c0", "aclk_peric_66", + ENABLE_PCLK_PERIC0, 8, CLK_SET_RATE_PARENT, 0), + GATE(CLK_PCLK_I2C7, "pclk_i2c7", "aclk_peric_66", ENABLE_PCLK_PERIC0, + 7, CLK_SET_RATE_PARENT, 0), + GATE(CLK_PCLK_I2C6, "pclk_i2c6", "aclk_peric_66", ENABLE_PCLK_PERIC0, + 6, CLK_SET_RATE_PARENT, 0), + GATE(CLK_PCLK_I2C5, "pclk_i2c5", "aclk_peric_66", ENABLE_PCLK_PERIC0, + 5, CLK_SET_RATE_PARENT, 0), + GATE(CLK_PCLK_I2C4, "pclk_i2c4", "aclk_peric_66", ENABLE_PCLK_PERIC0, + 4, CLK_SET_RATE_PARENT, 0), + GATE(CLK_PCLK_I2C3, "pclk_i2c3", "aclk_peric_66", ENABLE_PCLK_PERIC0, + 3, CLK_SET_RATE_PARENT, 0), + GATE(CLK_PCLK_I2C2, "pclk_i2c2", "aclk_peric_66", ENABLE_PCLK_PERIC0, + 2, CLK_SET_RATE_PARENT, 0), + GATE(CLK_PCLK_I2C1, "pclk_i2c1", "aclk_peric_66", ENABLE_PCLK_PERIC0, + 1, CLK_SET_RATE_PARENT, 0), + GATE(CLK_PCLK_I2C0, "pclk_i2c0", "aclk_peric_66", ENABLE_PCLK_PERIC0, + 0, CLK_SET_RATE_PARENT, 0), + + /* ENABLE_PCLK_PERIC1 */ + GATE(CLK_PCLK_SPI4, "pclk_spi4", "aclk_peric_66", ENABLE_PCLK_PERIC1, + 9, CLK_SET_RATE_PARENT, 0), + GATE(CLK_PCLK_SPI3, "pclk_spi3", "aclk_peric_66", ENABLE_PCLK_PERIC1, + 8, CLK_SET_RATE_PARENT, 0), + GATE(CLK_PCLK_HSI2C11, "pclk_hsi2c11", "aclk_peric_66", + ENABLE_PCLK_PERIC1, 7, CLK_SET_RATE_PARENT, 0), + GATE(CLK_PCLK_HSI2C10, "pclk_hsi2c10", "aclk_peric_66", + ENABLE_PCLK_PERIC1, 6, CLK_SET_RATE_PARENT, 0), + GATE(CLK_PCLK_HSI2C9, "pclk_hsi2c9", "aclk_peric_66", + ENABLE_PCLK_PERIC1, 5, CLK_SET_RATE_PARENT, 0), + GATE(CLK_PCLK_HSI2C8, "pclk_hsi2c8", "aclk_peric_66", + ENABLE_PCLK_PERIC1, 4, CLK_SET_RATE_PARENT, 0), + GATE(CLK_PCLK_HSI2C7, "pclk_hsi2c7", "aclk_peric_66", + ENABLE_PCLK_PERIC1, 3, CLK_SET_RATE_PARENT, 0), + GATE(CLK_PCLK_HSI2C6, "pclk_hsi2c6", "aclk_peric_66", + ENABLE_PCLK_PERIC1, 2, CLK_SET_RATE_PARENT, 0), + GATE(CLK_PCLK_HSI2C5, "pclk_hsi2c5", "aclk_peric_66", + ENABLE_PCLK_PERIC1, 1, CLK_SET_RATE_PARENT, 0), + GATE(CLK_PCLK_HSI2C4, "pclk_hsi2c4", "aclk_peric_66", + ENABLE_PCLK_PERIC1, 0, CLK_SET_RATE_PARENT, 0), + + /* ENABLE_SCLK_PERIC */ + GATE(CLK_SCLK_SPI4, "sclk_spi4", "sclk_spi4_peric", ENABLE_SCLK_PERIC, + 19, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_SPI3, "sclk_spi3", "sclk_spi3_peric", ENABLE_SCLK_PERIC, + 18, CLK_SET_RATE_PARENT, 0), + + GATE(CLK_SCLK_SPI2, "sclk_spi2", "sclk_spi2_peric", ENABLE_SCLK_PERIC, + 5, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_SPI1, "sclk_spi1", "sclk_spi1_peric", ENABLE_SCLK_PERIC, + 4, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_SPI0, "sclk_spi0", "sclk_spi0_peric", ENABLE_SCLK_PERIC, + 3, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_UART2, "sclk_uart2", "sclk_uart2_peric", + ENABLE_SCLK_PERIC, 2, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_UART1, "sclk_uart1", "sclk_uart1_peric", + ENABLE_SCLK_PERIC, 1, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_UART0, "sclk_uart0", "sclk_uart0_peric", + ENABLE_SCLK_PERIC, 0, CLK_SET_RATE_PARENT, 0), +}; + +static struct samsung_cmu_info peric_cmu_info __initdata = { + .gate_clks = peric_gate_clks, + .nr_gate_clks = ARRAY_SIZE(peric_gate_clks), + .nr_clk_ids = PERIC_NR_CLK, + .clk_regs = peric_clk_regs, + .nr_clk_regs = ARRAY_SIZE(peric_clk_regs), +}; + +static void __init exynos5433_cmu_peric_init(struct device_node *np) +{ + samsung_cmu_register_one(np, &peric_cmu_info); +} + +CLK_OF_DECLARE(exynos5433_cmu_peric, "samsung,exynos5433-cmu-peric", + exynos5433_cmu_peric_init); + +/* + * Register offset definitions for CMU_PERIS + */ +#define ENABLE_ACLK_PERIS 0x0800 +#define ENABLE_PCLK_PERIS 0x0900 + +static unsigned long peris_clk_regs[] __initdata = { + ENABLE_ACLK_PERIS, + ENABLE_PCLK_PERIS, +}; + +static struct samsung_gate_clock peris_gate_clks[] __initdata = { + /* ENABLE_PCLK_PERIS */ + GATE(CLK_PCLK_HPM_APBIF, "pclk_hpm_apbif", "aclk_peris_66", + ENABLE_PCLK_PERIS, 30, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_TMU1_APBIF, "pclk_tmu1_apbif", "aclk_peris_66", + ENABLE_PCLK_PERIS, 24, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_TMU0_APBIF, "pclk_tmu0_apbif", "aclk_peris_66", + ENABLE_PCLK_PERIS, 23, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_PMU_PERIS, "pclk_pmu_peris", "aclk_peris_66", + ENABLE_PCLK_PERIS, 22, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_SYSREG_PERIS, "pclk_sysreg_peris", "aclk_peris_66", + ENABLE_PCLK_PERIS, 21, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_CMU_TOP_APBIF, "pclk_cmu_top_apbif", "aclk_peris_66", + ENABLE_PCLK_PERIS, 20, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_WDT_APOLLO, "pclk_wdt_apollo", "aclk_peris_66", + ENABLE_PCLK_PERIS, 17, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_WDT_ATLAS, "pclk_wdt_atlas", "aclk_peris_66", + ENABLE_PCLK_PERIS, 16, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_MCT, "pclk_mct", "aclk_peris_66", + ENABLE_PCLK_PERIS, 15, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_HDMI_CEC, "pclk_hdmi_cec", "aclk_peris_66", + ENABLE_PCLK_PERIS, 14, CLK_IGNORE_UNUSED, 0), +}; + +static struct samsung_cmu_info peris_cmu_info __initdata = { + .gate_clks = peris_gate_clks, + .nr_gate_clks = ARRAY_SIZE(peris_gate_clks), + .nr_clk_ids = PERIS_NR_CLK, + .clk_regs = peris_clk_regs, + .nr_clk_regs = ARRAY_SIZE(peris_clk_regs), +}; + +static void __init exynos5433_cmu_peris_init(struct device_node *np) +{ + samsung_cmu_register_one(np, &peris_cmu_info); +} + +CLK_OF_DECLARE(exynos5433_cmu_peris, "samsung,exynos5433-cmu-peris", + exynos5433_cmu_peris_init); + +/* + * Register offset definitions for CMU_FSYS + */ +#define MUX_SEL_FSYS0 0x0200 +#define MUX_SEL_FSYS1 0x0204 +#define MUX_SEL_FSYS2 0x0208 +#define MUX_SEL_FSYS3 0x020c +#define MUX_SEL_FSYS4 0x0210 +#define MUX_ENABLE_FSYS0 0x0300 +#define MUX_ENABLE_FSYS1 0x0304 +#define MUX_ENABLE_FSYS2 0x0308 +#define MUX_ENABLE_FSYS3 0x030c +#define MUX_ENABLE_FSYS4 0x0310 +#define MUX_STAT_FSYS0 0x0400 +#define MUX_STAT_FSYS1 0x0404 +#define MUX_STAT_FSYS2 0x0408 +#define MUX_STAT_FSYS3 0x040c +#define MUX_STAT_FSYS4 0x0410 +#define MUX_IGNORE_FSYS2 0x0508 +#define MUX_IGNORE_FSYS3 0x050c +#define ENABLE_ACLK_FSYS0 0x0800 +#define ENABLE_ACLK_FSYS1 0x0804 +#define ENABLE_PCLK_FSYS 0x0900 +#define ENABLE_SCLK_FSYS 0x0a00 +#define ENABLE_IP_FSYS0 0x0b00 +#define ENABLE_IP_FSYS1 0x0b04 + +/* list of all parent clock list */ +PNAME(mout_aclk_fsys_200_user_p) = { "oscclk", "div_aclk_fsys_200", }; +PNAME(mout_sclk_mmc2_user_p) = { "oscclk", "sclk_mmc2_fsys", }; +PNAME(mout_sclk_mmc1_user_p) = { "oscclk", "sclk_mmc1_fsys", }; +PNAME(mout_sclk_mmc0_user_p) = { "oscclk", "sclk_mmc0_fsys", }; + +static unsigned long fsys_clk_regs[] __initdata = { + MUX_SEL_FSYS0, + MUX_SEL_FSYS1, + MUX_SEL_FSYS2, + MUX_SEL_FSYS3, + MUX_SEL_FSYS4, + MUX_ENABLE_FSYS0, + MUX_ENABLE_FSYS1, + MUX_ENABLE_FSYS2, + MUX_ENABLE_FSYS3, + MUX_ENABLE_FSYS4, + MUX_STAT_FSYS0, + MUX_STAT_FSYS1, + MUX_STAT_FSYS2, + MUX_STAT_FSYS3, + MUX_STAT_FSYS4, + MUX_IGNORE_FSYS2, + MUX_IGNORE_FSYS3, + ENABLE_ACLK_FSYS0, + ENABLE_ACLK_FSYS1, + ENABLE_PCLK_FSYS, + ENABLE_SCLK_FSYS, + ENABLE_IP_FSYS0, + ENABLE_IP_FSYS1, +}; + +static struct samsung_mux_clock fsys_mux_clks[] __initdata = { + /* MUX_SEL_FSYS0 */ + MUX(CLK_MOUT_ACLK_FSYS_200_USER, "mout_aclk_fsys_200_user", + mout_aclk_fsys_200_user_p, MUX_SEL_FSYS0, 0, 1), + + /* MUX_SEL_FSYS1 */ + MUX(CLK_MOUT_SCLK_MMC2_USER, "mout_sclk_mmc2_user", + mout_sclk_mmc2_user_p, MUX_SEL_FSYS1, 20, 1), + MUX(CLK_MOUT_SCLK_MMC1_USER, "mout_sclk_mmc1_user", + mout_sclk_mmc1_user_p, MUX_SEL_FSYS1, 16, 1), + MUX(CLK_MOUT_SCLK_MMC0_USER, "mout_sclk_mmc0_user", + mout_sclk_mmc0_user_p, MUX_SEL_FSYS1, 12, 1), +}; + +static struct samsung_gate_clock fsys_gate_clks[] __initdata = { + /* ENABLE_ACLK_FSYS0 */ + GATE(CLK_ACLK_PCIE, "aclk_pcie", "mout_aclk_fsys_200_user", + ENABLE_ACLK_FSYS0, 13, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_PDMA1, "aclk_pdma1", "mout_aclk_fsys_200_user", + ENABLE_ACLK_FSYS0, 11, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_TSI, "aclk_tsi", "mout_aclk_fsys_200_user", + ENABLE_ACLK_FSYS0, 10, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_MMC2, "aclk_mmc2", "mout_aclk_fsys_200_user", + ENABLE_ACLK_FSYS0, 8, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_MMC1, "aclk_mmc1", "mout_aclk_fsys_200_user", + ENABLE_ACLK_FSYS0, 7, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_MMC0, "aclk_mmc0", "mout_aclk_fsys_200_user", + ENABLE_ACLK_FSYS0, 6, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_UFS, "aclk_ufs", "mout_aclk_fsys_200_user", + ENABLE_ACLK_FSYS0, 5, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_USBHOST20, "aclk_usbhost20", "mout_aclk_fsys_200_user", + ENABLE_ACLK_FSYS0, 3, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_USBHOST30, "aclk_usbhost30", "mout_aclk_fsys_200_user", + ENABLE_ACLK_FSYS0, 2, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_USBDRD30, "aclk_usbdrd30", "mout_aclk_fsys_200_user", + ENABLE_ACLK_FSYS0, 1, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_PDMA0, "aclk_pdma0", "mout_aclk_fsys_200_user", + ENABLE_ACLK_FSYS0, 0, CLK_IGNORE_UNUSED, 0), + + /* ENABLE_SCLK_FSYS */ + GATE(CLK_SCLK_MMC2, "sclk_mmc2", "mout_sclk_mmc2_user", + ENABLE_SCLK_FSYS, 4, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_MMC1, "sclk_mmc1", "mout_sclk_mmc1_user", + ENABLE_SCLK_FSYS, 3, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_MMC0, "sclk_mmc0", "mout_sclk_mmc0_user", + ENABLE_SCLK_FSYS, 2, CLK_SET_RATE_PARENT, 0), + + /* ENABLE_IP_FSYS0 */ + GATE(CLK_PDMA1, "pdma1", "aclk_pdma1", ENABLE_IP_FSYS0, 15, 0, 0), + GATE(CLK_PDMA0, "pdma0", "aclk_pdma0", ENABLE_IP_FSYS0, 0, 0, 0), +}; + +static struct samsung_cmu_info fsys_cmu_info __initdata = { + .mux_clks = fsys_mux_clks, + .nr_mux_clks = ARRAY_SIZE(fsys_mux_clks), + .gate_clks = fsys_gate_clks, + .nr_gate_clks = ARRAY_SIZE(fsys_gate_clks), + .nr_clk_ids = FSYS_NR_CLK, + .clk_regs = fsys_clk_regs, + .nr_clk_regs = ARRAY_SIZE(fsys_clk_regs), +}; + +static void __init exynos5433_cmu_fsys_init(struct device_node *np) +{ + samsung_cmu_register_one(np, &fsys_cmu_info); +} + +CLK_OF_DECLARE(exynos5433_cmu_fsys, "samsung,exynos5433-cmu-fsys", + exynos5433_cmu_fsys_init); diff --git a/include/dt-bindings/clock/exynos5433.h b/include/dt-bindings/clock/exynos5433.h new file mode 100644 index 000000000000..5c4e2e39ce49 --- /dev/null +++ b/include/dt-bindings/clock/exynos5433.h @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * Author: Chanwoo Choi + * + * 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. + */ + +#ifndef _DT_BINDINGS_CLOCK_EXYNOS5433_H +#define _DT_BINDINGS_CLOCK_EXYNOS5433_H + +/* CMU_TOP */ +#define CLK_FOUT_ISP_PLL 1 +#define CLK_FOUT_AUD_PLL 2 + +#define CLK_MOUT_AUD_PLL 10 +#define CLK_MOUT_ISP_PLL 11 +#define CLK_MOUT_AUD_PLL_USER_T 12 +#define CLK_MOUT_MPHY_PLL_USER 13 +#define CLK_MOUT_MFC_PLL_USER 14 +#define CLK_MOUT_BUS_PLL_USER 15 +#define CLK_MOUT_ACLK_HEVC_400 16 +#define CLK_MOUT_ACLK_CAM1_333 17 +#define CLK_MOUT_ACLK_CAM1_552_B 18 +#define CLK_MOUT_ACLK_CAM1_552_A 19 +#define CLK_MOUT_ACLK_ISP_DIS_400 20 +#define CLK_MOUT_ACLK_ISP_400 21 +#define CLK_MOUT_ACLK_BUS0_400 22 +#define CLK_MOUT_ACLK_MSCL_400_B 23 +#define CLK_MOUT_ACLK_MSCL_400_A 24 +#define CLK_MOUT_ACLK_GSCL_333 25 +#define CLK_MOUT_ACLK_G2D_400_B 26 +#define CLK_MOUT_ACLK_G2D_400_A 27 +#define CLK_MOUT_SCLK_JPEG_C 28 +#define CLK_MOUT_SCLK_JPEG_B 29 +#define CLK_MOUT_SCLK_JPEG_A 30 +#define CLK_MOUT_SCLK_MMC2_B 31 +#define CLK_MOUT_SCLK_MMC2_A 32 +#define CLK_MOUT_SCLK_MMC1_B 33 +#define CLK_MOUT_SCLK_MMC1_A 34 +#define CLK_MOUT_SCLK_MMC0_D 35 +#define CLK_MOUT_SCLK_MMC0_C 36 +#define CLK_MOUT_SCLK_MMC0_B 37 +#define CLK_MOUT_SCLK_MMC0_A 38 +#define CLK_MOUT_SCLK_SPI4 39 +#define CLK_MOUT_SCLK_SPI3 40 +#define CLK_MOUT_SCLK_UART2 41 +#define CLK_MOUT_SCLK_UART1 42 +#define CLK_MOUT_SCLK_UART0 43 +#define CLK_MOUT_SCLK_SPI2 44 +#define CLK_MOUT_SCLK_SPI1 45 +#define CLK_MOUT_SCLK_SPI0 46 + +#define CLK_DIV_ACLK_FSYS_200 100 +#define CLK_DIV_ACLK_IMEM_SSSX_266 101 +#define CLK_DIV_ACLK_IMEM_200 102 +#define CLK_DIV_ACLK_IMEM_266 103 +#define CLK_DIV_ACLK_PERIC_66_B 104 +#define CLK_DIV_ACLK_PERIC_66_A 105 +#define CLK_DIV_ACLK_PERIS_66_B 106 +#define CLK_DIV_ACLK_PERIS_66_A 107 +#define CLK_DIV_SCLK_MMC1_B 108 +#define CLK_DIV_SCLK_MMC1_A 109 +#define CLK_DIV_SCLK_MMC0_B 110 +#define CLK_DIV_SCLK_MMC0_A 111 +#define CLK_DIV_SCLK_MMC2_B 112 +#define CLK_DIV_SCLK_MMC2_A 113 +#define CLK_DIV_SCLK_SPI1_B 114 +#define CLK_DIV_SCLK_SPI1_A 115 +#define CLK_DIV_SCLK_SPI0_B 116 +#define CLK_DIV_SCLK_SPI0_A 117 +#define CLK_DIV_SCLK_SPI2_B 118 +#define CLK_DIV_SCLK_SPI2_A 119 +#define CLK_DIV_SCLK_UART2 120 +#define CLK_DIV_SCLK_UART1 121 +#define CLK_DIV_SCLK_UART0 122 +#define CLK_DIV_SCLK_SPI4_B 123 +#define CLK_DIV_SCLK_SPI4_A 124 +#define CLK_DIV_SCLK_SPI3_B 125 +#define CLK_DIV_SCLK_SPI3_A 126 + +#define CLK_ACLK_PERIC_66 200 +#define CLK_ACLK_PERIS_66 201 +#define CLK_ACLK_FSYS_200 202 +#define CLK_SCLK_MMC2_FSYS 203 +#define CLK_SCLK_MMC1_FSYS 204 +#define CLK_SCLK_MMC0_FSYS 205 +#define CLK_SCLK_SPI4_PERIC 206 +#define CLK_SCLK_SPI3_PERIC 207 +#define CLK_SCLK_UART2_PERIC 208 +#define CLK_SCLK_UART1_PERIC 209 +#define CLK_SCLK_UART0_PERIC 210 +#define CLK_SCLK_SPI2_PERIC 211 +#define CLK_SCLK_SPI1_PERIC 212 +#define CLK_SCLK_SPI0_PERIC 213 + +#define TOP_NR_CLK 214 + +/* CMU_CPIF */ +#define CLK_FOUT_MPHY_PLL 1 + +#define CLK_MOUT_MPHY_PLL 2 + +#define CLK_DIV_SCLK_MPHY 10 + +#define CLK_SCLK_MPHY_PLL 11 +#define CLK_SCLK_UFS_MPHY 11 + +#define CPIF_NR_CLK 12 + +/* CMU_MIF */ +#define CLK_FOUT_MEM0_PLL 1 +#define CLK_FOUT_MEM1_PLL 2 +#define CLK_FOUT_BUS_PLL 3 +#define CLK_FOUT_MFC_PLL 4 + +#define MIF_NR_CLK 5 + +/* CMU_PERIC */ +#define CLK_PCLK_SPI2 1 +#define CLK_PCLK_SPI1 2 +#define CLK_PCLK_SPI0 3 +#define CLK_PCLK_UART2 4 +#define CLK_PCLK_UART1 5 +#define CLK_PCLK_UART0 6 +#define CLK_PCLK_HSI2C3 7 +#define CLK_PCLK_HSI2C2 8 +#define CLK_PCLK_HSI2C1 9 +#define CLK_PCLK_HSI2C0 10 +#define CLK_PCLK_I2C7 11 +#define CLK_PCLK_I2C6 12 +#define CLK_PCLK_I2C5 13 +#define CLK_PCLK_I2C4 14 +#define CLK_PCLK_I2C3 15 +#define CLK_PCLK_I2C2 16 +#define CLK_PCLK_I2C1 17 +#define CLK_PCLK_I2C0 18 +#define CLK_PCLK_SPI4 19 +#define CLK_PCLK_SPI3 20 +#define CLK_PCLK_HSI2C11 21 +#define CLK_PCLK_HSI2C10 22 +#define CLK_PCLK_HSI2C9 23 +#define CLK_PCLK_HSI2C8 24 +#define CLK_PCLK_HSI2C7 25 +#define CLK_PCLK_HSI2C6 26 +#define CLK_PCLK_HSI2C5 27 +#define CLK_PCLK_HSI2C4 28 +#define CLK_SCLK_SPI4 29 +#define CLK_SCLK_SPI3 30 +#define CLK_SCLK_SPI2 31 +#define CLK_SCLK_SPI1 32 +#define CLK_SCLK_SPI0 33 +#define CLK_SCLK_UART2 34 +#define CLK_SCLK_UART1 35 +#define CLK_SCLK_UART0 36 + +#define PERIC_NR_CLK 37 + +/* CMU_PERIS */ +#define CLK_PCLK_HPM_APBIF 1 +#define CLK_PCLK_TMU1_APBIF 2 +#define CLK_PCLK_TMU0_APBIF 3 +#define CLK_PCLK_PMU_PERIS 4 +#define CLK_PCLK_SYSREG_PERIS 5 +#define CLK_PCLK_CMU_TOP_APBIF 6 +#define CLK_PCLK_WDT_APOLLO 7 +#define CLK_PCLK_WDT_ATLAS 8 +#define CLK_PCLK_MCT 9 +#define CLK_PCLK_HDMI_CEC 10 + +#define PERIS_NR_CLK 11 + +/* CMU_FSYS */ +#define CLK_MOUT_ACLK_FSYS_200_USER 1 +#define CLK_MOUT_SCLK_MMC2_USER 2 +#define CLK_MOUT_SCLK_MMC1_USER 3 +#define CLK_MOUT_SCLK_MMC0_USER 4 + +#define CLK_ACLK_PCIE 50 +#define CLK_ACLK_PDMA1 51 +#define CLK_ACLK_TSI 52 +#define CLK_ACLK_MMC2 53 +#define CLK_ACLK_MMC1 54 +#define CLK_ACLK_MMC0 55 +#define CLK_ACLK_UFS 56 +#define CLK_ACLK_USBHOST20 57 +#define CLK_ACLK_USBHOST30 58 +#define CLK_ACLK_USBDRD30 59 +#define CLK_ACLK_PDMA0 60 +#define CLK_SCLK_MMC2 61 +#define CLK_SCLK_MMC1 62 +#define CLK_SCLK_MMC0 63 +#define CLK_PDMA1 64 +#define CLK_PDMA0 65 + +#define FSYS_NR_CLK 66 + +#endif /* _DT_BINDINGS_CLOCK_EXYNOS5433_H */ -- GitLab From 232364969d8a8a17c52fd9b754d15924abf98d6a Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Mon, 2 Feb 2015 23:23:57 +0900 Subject: [PATCH 00035/11651] clk: samsung: exynos5433: Add MUX clocks of CMU_TOP domain This patch adds the MUX (multiplexer) clocks for CMU_TOP domain of Exynos5433. CMU_TOP domain provides source clocks to other CMU domains. Signed-off-by: Chanwoo Choi Acked-by: Inki Dae Reviewed-by: Pankaj Dubey Signed-off-by: Sylwester Nawrocki --- drivers/clk/samsung/clk-exynos5433.c | 90 ++++++++++++++++++++++++++ include/dt-bindings/clock/exynos5433.h | 31 ++++++++- 2 files changed, 119 insertions(+), 2 deletions(-) diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c index a4047390bfc2..5585dce04a38 100644 --- a/drivers/clk/samsung/clk-exynos5433.c +++ b/drivers/clk/samsung/clk-exynos5433.c @@ -208,6 +208,7 @@ PNAME(mout_mphy_pll_user_p) = { "oscclk", "sclk_mphy_pll", }; PNAME(mout_mfc_pll_user_p) = { "oscclk", "sclk_mfc_pll", }; PNAME(mout_bus_pll_user_p) = { "oscclk", "sclk_bus_pll", }; PNAME(mout_bus_pll_user_t_p) = { "oscclk", "mout_bus_pll_user", }; +PNAME(mout_mphy_pll_user_t_p) = { "oscclk", "mout_mphy_pll_user", }; PNAME(mout_bus_mfc_pll_user_p) = { "mout_bus_pll_user", "mout_mfc_pll_user",}; PNAME(mout_mfc_bus_pll_user_p) = { "mout_mfc_pll_user", "mout_bus_pll_user",}; @@ -215,6 +216,12 @@ PNAME(mout_aclk_cam1_552_b_p) = { "mout_aclk_cam1_552_a", "mout_mfc_pll_user", }; PNAME(mout_aclk_cam1_552_a_p) = { "mout_isp_pll", "mout_bus_pll_user", }; +PNAME(mout_aclk_mfc_400_c_p) = { "mout_aclk_mfc_400_b", + "mout_mphy_pll_user", }; +PNAME(mout_aclk_mfc_400_b_p) = { "mout_aclk_mfc_400_a", + "mout_bus_pll_user", }; +PNAME(mout_aclk_mfc_400_a_p) = { "mout_mfc_pll_user", "mout_isp_pll", }; + PNAME(mout_bus_mphy_pll_user_p) = { "mout_bus_pll_user", "mout_mphy_pll_user", }; PNAME(mout_aclk_mscl_b_p) = { "mout_aclk_mscl_400_a", @@ -231,6 +238,21 @@ PNAME(mout_sclk_mmc0_d_p) = { "mout_sclk_mmc0_c", "mout_isp_pll", }; PNAME(mout_sclk_mmc0_c_p) = { "mout_sclk_mmc0_b", "mout_mphy_pll_user",}; PNAME(mout_sclk_mmc0_b_p) = { "mout_sclk_mmc0_a", "mout_mfc_pll_user", }; +PNAME(mout_sclk_spdif_p) = { "sclk_audio0", "sclk_audio1", + "oscclk", "ioclk_spdif_extclk", }; +PNAME(mout_sclk_audio1_p) = { "ioclk_audiocdclk1", "oscclk", + "mout_aud_pll_user_t",}; +PNAME(mout_sclk_audio0_p) = { "ioclk_audiocdclk0", "oscclk", + "mout_aud_pll_user_t",}; + +static struct samsung_fixed_rate_clock top_fixed_clks[] __initdata = { + /* Xi2s{0|1}CDCLK input clock for I2S/PCM */ + FRATE(0, "ioclk_audiocdclk1", NULL, CLK_IS_ROOT, 100000000), + FRATE(0, "ioclk_audiocdclk0", NULL, CLK_IS_ROOT, 100000000), + /* Xi2s1SDI input clock for SPDIF */ + FRATE(0, "ioclk_spdif_extclk", NULL, CLK_IS_ROOT, 100000000), +}; + static struct samsung_mux_clock top_mux_clks[] __initdata = { /* MUX_SEL_TOP0 */ MUX(CLK_MOUT_AUD_PLL, "mout_aud_pll", mout_aud_pll_p, MUX_SEL_TOP0, @@ -276,6 +298,14 @@ static struct samsung_mux_clock top_mux_clks[] __initdata = { MUX(CLK_MOUT_ACLK_G2D_400_A, "mout_aclk_g2d_400_a", mout_bus_mfc_pll_user_p, MUX_SEL_TOP3, 0, 1), + /* MUX_SEL_TOP4 */ + MUX(CLK_MOUT_ACLK_MFC_400_C, "mout_aclk_mfc_400_c", + mout_aclk_mfc_400_c_p, MUX_SEL_TOP4, 8, 1), + MUX(CLK_MOUT_ACLK_MFC_400_B, "mout_aclk_mfc_400_b", + mout_aclk_mfc_400_b_p, MUX_SEL_TOP4, 4, 1), + MUX(CLK_MOUT_ACLK_MFC_400_A, "mout_aclk_mfc_400_a", + mout_aclk_mfc_400_a_p, MUX_SEL_TOP4, 0, 1), + /* MUX_SEL_TOP_MSCL */ MUX(CLK_MOUT_SCLK_JPEG_C, "mout_sclk_jpeg_c", mout_sclk_jpeg_c_p, MUX_SEL_TOP_MSCL, 8, 1), @@ -284,6 +314,20 @@ static struct samsung_mux_clock top_mux_clks[] __initdata = { MUX(CLK_MOUT_SCLK_JPEG_A, "mout_sclk_jpeg_a", mout_bus_pll_user_t_p, MUX_SEL_TOP_MSCL, 0, 1), + /* MUX_SEL_TOP_CAM1 */ + MUX(CLK_MOUT_SCLK_ISP_SENSOR2, "mout_sclk_isp_sensor2", + mout_bus_pll_user_t_p, MUX_SEL_TOP_CAM1, 24, 1), + MUX(CLK_MOUT_SCLK_ISP_SENSOR1, "mout_sclk_isp_sensor1", + mout_bus_pll_user_t_p, MUX_SEL_TOP_CAM1, 20, 1), + MUX(CLK_MOUT_SCLK_ISP_SENSOR0, "mout_sclk_isp_sensor0", + mout_bus_pll_user_t_p, MUX_SEL_TOP_CAM1, 16, 1), + MUX(CLK_MOUT_SCLK_ISP_UART, "mout_sclk_isp_uart", + mout_bus_pll_user_t_p, MUX_SEL_TOP_CAM1, 8, 1), + MUX(CLK_MOUT_SCLK_ISP_SPI1, "mout_sclk_isp_spi1", + mout_bus_pll_user_t_p, MUX_SEL_TOP_CAM1, 4, 1), + MUX(CLK_MOUT_SCLK_ISP_SPI0, "mout_sclk_isp_spi0", + mout_bus_pll_user_t_p, MUX_SEL_TOP_CAM1, 0, 1), + /* MUX_SEL_TOP_FSYS0 */ MUX(CLK_MOUT_SCLK_MMC2_B, "mout_sclk_mmc2_b", mout_sclk_mmc2_b_p, MUX_SEL_TOP_FSYS0, 28, 1), @@ -302,6 +346,16 @@ static struct samsung_mux_clock top_mux_clks[] __initdata = { MUX(CLK_MOUT_SCLK_MMC0_A, "mout_sclk_mmc0_a", mout_bus_pll_user_t_p, MUX_SEL_TOP_FSYS0, 0, 1), + /* MUX_SEL_TOP_FSYS1 */ + MUX(CLK_MOUT_SCLK_PCIE_100, "mout_sclk_pcie_100", mout_bus_pll_user_t_p, + MUX_SEL_TOP_FSYS1, 12, 1), + MUX(CLK_MOUT_SCLK_UFSUNIPRO, "mout_sclk_ufsunipro", + mout_mphy_pll_user_t_p, MUX_SEL_TOP_FSYS1, 8, 1), + MUX(CLK_MOUT_SCLK_USBHOST30, "mout_sclk_usbhost30", + mout_bus_pll_user_t_p, MUX_SEL_TOP_FSYS1, 4, 1), + MUX(CLK_MOUT_SCLK_USBDRD30, "mout_sclk_usbdrd30", + mout_bus_pll_user_t_p, MUX_SEL_TOP_FSYS1, 0, 1), + /* MUX_SEL_TOP_PERIC0 */ MUX(CLK_MOUT_SCLK_SPI4, "mout_sclk_spi4", mout_bus_pll_user_t_p, MUX_SEL_TOP_PERIC0, 28, 1), @@ -319,6 +373,16 @@ static struct samsung_mux_clock top_mux_clks[] __initdata = { MUX_SEL_TOP_PERIC0, 4, 1), MUX(CLK_MOUT_SCLK_SPI0, "mout_sclk_spi0", mout_bus_pll_user_t_p, MUX_SEL_TOP_PERIC0, 0, 1), + + /* MUX_SEL_TOP_PERIC1 */ + MUX(CLK_MOUT_SCLK_SLIMBUS, "mout_sclk_slimbus", mout_aud_pll_user_p, + MUX_SEL_TOP_PERIC1, 16, 1), + MUX(CLK_MOUT_SCLK_SPDIF, "mout_sclk_spdif", mout_sclk_spdif_p, + MUX_SEL_TOP_PERIC1, 12, 2), + MUX(CLK_MOUT_SCLK_AUDIO1, "mout_sclk_audio1", mout_sclk_audio1_p, + MUX_SEL_TOP_PERIC1, 4, 2), + MUX(CLK_MOUT_SCLK_AUDIO0, "mout_sclk_audio0", mout_sclk_audio0_p, + MUX_SEL_TOP_PERIC1, 0, 2), }; static struct samsung_div_clock top_div_clks[] __initdata = { @@ -382,6 +446,16 @@ static struct samsung_div_clock top_div_clks[] __initdata = { DIV(CLK_DIV_SCLK_UART0, "div_sclk_uart0", "mout_sclk_uart1", DIV_TOP_PERIC2, 0, 4), + /* DIV_TOP_PERIC3 */ + DIV(CLK_DIV_SCLK_I2S1, "div_sclk_i2s1", "sclk_audio1", + DIV_TOP_PERIC3, 16, 6), + DIV(CLK_DIV_SCLK_PCM1, "div_sclk_pcm1", "sclk_audio1", + DIV_TOP_PERIC3, 8, 8), + DIV(CLK_DIV_SCLK_AUDIO1, "div_sclk_audio1", "mout_sclk_audio1", + DIV_TOP_PERIC3, 4, 4), + DIV(CLK_DIV_SCLK_AUDIO0, "div_sclk_audio0", "mout_sclk_audio0", + DIV_TOP_PERIC3, 0, 4), + /* DIV_TOP_PERIC4 */ DIV(CLK_DIV_SCLK_SPI4_B, "div_sclk_spi4_b", "div_sclk_spi4_a", DIV_TOP_PERIC4, 16, 8), @@ -418,6 +492,12 @@ static struct samsung_gate_clock top_gate_clks[] __initdata = { ENABLE_SCLK_TOP_PERIC, 12, CLK_SET_RATE_PARENT, 0), GATE(CLK_SCLK_SPI3_PERIC, "sclk_spi3_peric", "div_sclk_spi3_b", ENABLE_SCLK_TOP_PERIC, 11, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_SPDIF_PERIC, "sclk_spdif_peric", "mout_sclk_spdif", + ENABLE_SCLK_TOP_PERIC, 9, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_I2S1_PERIC, "sclk_i2s1_peric", "div_sclk_i2s1", + ENABLE_SCLK_TOP_PERIC, 8, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_PCM1_PERIC, "sclk_pcm1_peric", "div_sclk_pcm1", + ENABLE_SCLK_TOP_PERIC, 7, CLK_SET_RATE_PARENT, 0), GATE(CLK_SCLK_UART2_PERIC, "sclk_uart2_peric", "div_sclk_uart2", ENABLE_SCLK_TOP_PERIC, 5, CLK_SET_RATE_PARENT, 0), GATE(CLK_SCLK_UART1_PERIC, "sclk_uart1_peric", "div_sclk_uart1", @@ -430,6 +510,14 @@ static struct samsung_gate_clock top_gate_clks[] __initdata = { ENABLE_SCLK_TOP_PERIC, 1, CLK_SET_RATE_PARENT, 0), GATE(CLK_SCLK_SPI0_PERIC, "sclk_spi0_peric", "div_sclk_spi0_b", ENABLE_SCLK_TOP_PERIC, 0, CLK_SET_RATE_PARENT, 0), + + /* MUX_ENABLE_TOP_PERIC1 */ + GATE(CLK_SCLK_SLIMBUS, "sclk_slimbus", "mout_sclk_slimbus", + MUX_ENABLE_TOP_PERIC1, 16, 0, 0), + GATE(CLK_SCLK_AUDIO1, "sclk_audio1", "div_sclk_audio1", + MUX_ENABLE_TOP_PERIC1, 4, 0, 0), + GATE(CLK_SCLK_AUDIO0, "sclk_audio0", "div_sclk_audio0", + MUX_ENABLE_TOP_PERIC1, 0, 0, 0), }; /* @@ -516,6 +604,8 @@ static struct samsung_cmu_info top_cmu_info __initdata = { .nr_div_clks = ARRAY_SIZE(top_div_clks), .gate_clks = top_gate_clks, .nr_gate_clks = ARRAY_SIZE(top_gate_clks), + .fixed_clks = top_fixed_clks, + .nr_fixed_clks = ARRAY_SIZE(top_fixed_clks), .nr_clk_ids = TOP_NR_CLK, .clk_regs = top_clk_regs, .nr_clk_regs = ARRAY_SIZE(top_clk_regs), diff --git a/include/dt-bindings/clock/exynos5433.h b/include/dt-bindings/clock/exynos5433.h index 5c4e2e39ce49..8f0ee5a13db4 100644 --- a/include/dt-bindings/clock/exynos5433.h +++ b/include/dt-bindings/clock/exynos5433.h @@ -51,6 +51,23 @@ #define CLK_MOUT_SCLK_SPI2 44 #define CLK_MOUT_SCLK_SPI1 45 #define CLK_MOUT_SCLK_SPI0 46 +#define CLK_MOUT_ACLK_MFC_400_C 47 +#define CLK_MOUT_ACLK_MFC_400_B 48 +#define CLK_MOUT_ACLK_MFC_400_A 49 +#define CLK_MOUT_SCLK_ISP_SENSOR2 50 +#define CLK_MOUT_SCLK_ISP_SENSOR1 51 +#define CLK_MOUT_SCLK_ISP_SENSOR0 52 +#define CLK_MOUT_SCLK_ISP_UART 53 +#define CLK_MOUT_SCLK_ISP_SPI1 54 +#define CLK_MOUT_SCLK_ISP_SPI0 55 +#define CLK_MOUT_SCLK_PCIE_100 56 +#define CLK_MOUT_SCLK_UFSUNIPRO 57 +#define CLK_MOUT_SCLK_USBHOST30 58 +#define CLK_MOUT_SCLK_USBDRD30 59 +#define CLK_MOUT_SCLK_SLIMBUS 60 +#define CLK_MOUT_SCLK_SPDIF 61 +#define CLK_MOUT_SCLK_AUDIO1 62 +#define CLK_MOUT_SCLK_AUDIO0 63 #define CLK_DIV_ACLK_FSYS_200 100 #define CLK_DIV_ACLK_IMEM_SSSX_266 101 @@ -79,6 +96,10 @@ #define CLK_DIV_SCLK_SPI4_A 124 #define CLK_DIV_SCLK_SPI3_B 125 #define CLK_DIV_SCLK_SPI3_A 126 +#define CLK_DIV_SCLK_I2S1 127 +#define CLK_DIV_SCLK_PCM1 128 +#define CLK_DIV_SCLK_AUDIO1 129 +#define CLK_DIV_SCLK_AUDIO0 130 #define CLK_ACLK_PERIC_66 200 #define CLK_ACLK_PERIS_66 201 @@ -94,8 +115,14 @@ #define CLK_SCLK_SPI2_PERIC 211 #define CLK_SCLK_SPI1_PERIC 212 #define CLK_SCLK_SPI0_PERIC 213 - -#define TOP_NR_CLK 214 +#define CLK_SCLK_SPDIF_PERIC 214 +#define CLK_SCLK_I2S1_PERIC 215 +#define CLK_SCLK_PCM1_PERIC 216 +#define CLK_SCLK_SLIMBUS 217 +#define CLK_SCLK_AUDIO1 218 +#define CLK_SCLK_AUDIO0 219 + +#define TOP_NR_CLK 220 /* CMU_CPIF */ #define CLK_FOUT_MPHY_PLL 1 -- GitLab From d0f5de6677de4405c9acdb88db7c7cf7b9cc954e Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Mon, 2 Feb 2015 23:23:58 +0900 Subject: [PATCH 00036/11651] clk: samsung: exynos5433: Add clocks for CMU_PERIC domain This patch adds missing divider/gate clocks of CMU_PERIC domain which includes I2S/PCM/SPDIF/PWM/SLIMBUS IPs. The SPI/I2S may use external input clock which has 'ioclk_*' prefix. Signed-off-by: Chanwoo Choi [ideal.song: Change clk flags of to pclk_gpio_* clk, pclk_gpio_* should be always on] Signed-off-by: Inha Song Acked-by: Inki Dae Signed-off-by: Sylwester Nawrocki --- drivers/clk/samsung/clk-exynos5433.c | 83 +++++++++++++++++++++++++- include/dt-bindings/clock/exynos5433.h | 34 ++++++++++- 2 files changed, 114 insertions(+), 3 deletions(-) diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c index 5585dce04a38..10a9f8313c24 100644 --- a/drivers/clk/samsung/clk-exynos5433.c +++ b/drivers/clk/samsung/clk-exynos5433.c @@ -251,6 +251,14 @@ static struct samsung_fixed_rate_clock top_fixed_clks[] __initdata = { FRATE(0, "ioclk_audiocdclk0", NULL, CLK_IS_ROOT, 100000000), /* Xi2s1SDI input clock for SPDIF */ FRATE(0, "ioclk_spdif_extclk", NULL, CLK_IS_ROOT, 100000000), + /* XspiCLK[4:0] input clock for SPI */ + FRATE(0, "ioclk_spi4_clk_in", NULL, CLK_IS_ROOT, 50000000), + FRATE(0, "ioclk_spi3_clk_in", NULL, CLK_IS_ROOT, 50000000), + FRATE(0, "ioclk_spi2_clk_in", NULL, CLK_IS_ROOT, 50000000), + FRATE(0, "ioclk_spi1_clk_in", NULL, CLK_IS_ROOT, 50000000), + FRATE(0, "ioclk_spi0_clk_in", NULL, CLK_IS_ROOT, 50000000), + /* Xi2s1SCLK input clock for I2S1_BCLK */ + FRATE(0, "ioclk_i2s1_bclk_in", NULL, CLK_IS_ROOT, 12288000), }; static struct samsung_mux_clock top_mux_clks[] __initdata = { @@ -756,6 +764,7 @@ CLK_OF_DECLARE(exynos5433_cmu_mif, "samsung,exynos5433-cmu-mif", * Register offset definitions for CMU_PERIC */ #define DIV_PERIC 0x0600 +#define DIV_STAT_PERIC 0x0700 #define ENABLE_ACLK_PERIC 0x0800 #define ENABLE_PCLK_PERIC0 0x0900 #define ENABLE_PCLK_PERIC1 0x0904 @@ -766,6 +775,7 @@ CLK_OF_DECLARE(exynos5433_cmu_mif, "samsung,exynos5433-cmu-mif", static unsigned long peric_clk_regs[] __initdata = { DIV_PERIC, + DIV_STAT_PERIC, ENABLE_ACLK_PERIC, ENABLE_PCLK_PERIC0, ENABLE_PCLK_PERIC1, @@ -775,14 +785,57 @@ static unsigned long peric_clk_regs[] __initdata = { ENABLE_IP_PERIC2, }; +static struct samsung_div_clock peric_div_clks[] __initdata = { + /* DIV_PERIC */ + DIV(CLK_DIV_SCLK_SCI, "div_sclk_sci", "oscclk", DIV_PERIC, 4, 4), + DIV(CLK_DIV_SCLK_SC_IN, "div_sclk_sc_in", "oscclk", DIV_PERIC, 0, 4), +}; + static struct samsung_gate_clock peric_gate_clks[] __initdata = { + /* ENABLE_ACLK_PERIC */ + GATE(CLK_ACLK_AHB2APB_PERIC2P, "aclk_ahb2apb_peric2p", "aclk_peric_66", + ENABLE_ACLK_PERIC, 3, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_AHB2APB_PERIC1P, "aclk_ahb2apb_peric1p", "aclk_peric_66", + ENABLE_ACLK_PERIC, 2, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_AHB2APB_PERIC0P, "aclk_ahb2apb_peric0p", "aclk_peric_66", + ENABLE_ACLK_PERIC, 1, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_PERICNP_66, "aclk_pericnp_66", "aclk_peric_66", + ENABLE_ACLK_PERIC, 0, CLK_IGNORE_UNUSED, 0), + /* ENABLE_PCLK_PERIC0 */ + GATE(CLK_PCLK_SCI, "pclk_sci", "aclk_peric_66", ENABLE_PCLK_PERIC0, + 31, CLK_SET_RATE_PARENT, 0), + GATE(CLK_PCLK_GPIO_FINGER, "pclk_gpio_finger", "aclk_peric_66", + ENABLE_PCLK_PERIC0, 30, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_GPIO_ESE, "pclk_gpio_ese", "aclk_peric_66", + ENABLE_PCLK_PERIC0, 29, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_PWM, "pclk_pwm", "aclk_peric_66", ENABLE_PCLK_PERIC0, + 28, CLK_SET_RATE_PARENT, 0), + GATE(CLK_PCLK_SPDIF, "pclk_spdif", "aclk_peric_66", ENABLE_PCLK_PERIC0, + 26, CLK_SET_RATE_PARENT, 0), + GATE(CLK_PCLK_PCM1, "pclk_pcm1", "aclk_peric_66", ENABLE_PCLK_PERIC0, + 25, CLK_SET_RATE_PARENT, 0), + GATE(CLK_PCLK_I2S1, "pclk_i2s", "aclk_peric_66", ENABLE_PCLK_PERIC0, + 24, CLK_SET_RATE_PARENT, 0), GATE(CLK_PCLK_SPI2, "pclk_spi2", "aclk_peric_66", ENABLE_PCLK_PERIC0, 23, CLK_SET_RATE_PARENT, 0), GATE(CLK_PCLK_SPI1, "pclk_spi1", "aclk_peric_66", ENABLE_PCLK_PERIC0, 22, CLK_SET_RATE_PARENT, 0), GATE(CLK_PCLK_SPI0, "pclk_spi0", "aclk_peric_66", ENABLE_PCLK_PERIC0, 21, CLK_SET_RATE_PARENT, 0), + GATE(CLK_PCLK_ADCIF, "pclk_adcif", "aclk_peric_66", ENABLE_PCLK_PERIC0, + 20, CLK_SET_RATE_PARENT, 0), + GATE(CLK_PCLK_GPIO_TOUCH, "pclk_gpio_touch", "aclk_peric_66", + ENABLE_PCLK_PERIC0, 19, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_GPIO_NFC, "pclk_gpio_nfc", "aclk_peric_66", + ENABLE_PCLK_PERIC0, 18, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_GPIO_PERIC, "pclk_gpio_peric", "aclk_peric_66", + ENABLE_PCLK_PERIC0, 17, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_PMU_PERIC, "pclk_pmu_peric", "aclk_peric_66", + ENABLE_PCLK_PERIC0, 16, CLK_SET_RATE_PARENT, 0), + GATE(CLK_PCLK_SYSREG_PERIC, "pclk_sysreg_peric", "aclk_peric_66", + ENABLE_PCLK_PERIC0, 15, + CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0), GATE(CLK_PCLK_UART2, "pclk_uart2", "aclk_peric_66", ENABLE_PCLK_PERIC0, 14, CLK_SET_RATE_PARENT, 0), GATE(CLK_PCLK_UART1, "pclk_uart1", "aclk_peric_66", ENABLE_PCLK_PERIC0, @@ -837,15 +890,39 @@ static struct samsung_gate_clock peric_gate_clks[] __initdata = { ENABLE_PCLK_PERIC1, 0, CLK_SET_RATE_PARENT, 0), /* ENABLE_SCLK_PERIC */ + GATE(CLK_SCLK_IOCLK_SPI4, "sclk_ioclk_spi4", "ioclk_spi4_clk_in", + ENABLE_SCLK_PERIC, 21, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_IOCLK_SPI3, "sclk_ioclk_spi3", "ioclk_spi3_clk_in", + ENABLE_SCLK_PERIC, 20, CLK_SET_RATE_PARENT, 0), GATE(CLK_SCLK_SPI4, "sclk_spi4", "sclk_spi4_peric", ENABLE_SCLK_PERIC, 19, CLK_SET_RATE_PARENT, 0), GATE(CLK_SCLK_SPI3, "sclk_spi3", "sclk_spi3_peric", ENABLE_SCLK_PERIC, 18, CLK_SET_RATE_PARENT, 0), - + GATE(CLK_SCLK_SCI, "sclk_sci", "div_sclk_sci", ENABLE_SCLK_PERIC, + 17, 0, 0), + GATE(CLK_SCLK_SC_IN, "sclk_sc_in", "div_sclk_sc_in", ENABLE_SCLK_PERIC, + 16, 0, 0), + GATE(CLK_SCLK_PWM, "sclk_pwm", "oscclk", ENABLE_SCLK_PERIC, 15, 0, 0), + GATE(CLK_SCLK_IOCLK_SPI2, "sclk_ioclk_spi2", "ioclk_spi2_clk_in", + ENABLE_SCLK_PERIC, 13, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_IOCLK_SPI1, "sclk_ioclk_spi1", "ioclk_spi1_clk_in", + ENABLE_SCLK_PERIC, 12, + CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_IOCLK_SPI0, "sclk_ioclk_spi0", "ioclk_spi0_clk_in", + ENABLE_SCLK_PERIC, 11, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_IOCLK_I2S1_BCLK, "sclk_ioclk_i2s1_bclk", + "ioclk_i2s1_bclk_in", ENABLE_SCLK_PERIC, 10, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_SPDIF, "sclk_spdif", "sclk_spdif_peric", + ENABLE_SCLK_PERIC, 8, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_PCM1, "sclk_pcm1", "sclk_pcm1_peric", + ENABLE_SCLK_PERIC, 7, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_I2S1, "sclk_i2s1", "sclk_i2s1_peric", + ENABLE_SCLK_PERIC, 6, CLK_SET_RATE_PARENT, 0), GATE(CLK_SCLK_SPI2, "sclk_spi2", "sclk_spi2_peric", ENABLE_SCLK_PERIC, 5, CLK_SET_RATE_PARENT, 0), GATE(CLK_SCLK_SPI1, "sclk_spi1", "sclk_spi1_peric", ENABLE_SCLK_PERIC, - 4, CLK_SET_RATE_PARENT, 0), + 4, CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0), GATE(CLK_SCLK_SPI0, "sclk_spi0", "sclk_spi0_peric", ENABLE_SCLK_PERIC, 3, CLK_SET_RATE_PARENT, 0), GATE(CLK_SCLK_UART2, "sclk_uart2", "sclk_uart2_peric", @@ -857,6 +934,8 @@ static struct samsung_gate_clock peric_gate_clks[] __initdata = { }; static struct samsung_cmu_info peric_cmu_info __initdata = { + .div_clks = peric_div_clks, + .nr_div_clks = ARRAY_SIZE(peric_div_clks), .gate_clks = peric_gate_clks, .nr_gate_clks = ARRAY_SIZE(peric_gate_clks), .nr_clk_ids = PERIC_NR_CLK, diff --git a/include/dt-bindings/clock/exynos5433.h b/include/dt-bindings/clock/exynos5433.h index 8f0ee5a13db4..b5c66f7b83be 100644 --- a/include/dt-bindings/clock/exynos5433.h +++ b/include/dt-bindings/clock/exynos5433.h @@ -181,8 +181,40 @@ #define CLK_SCLK_UART2 34 #define CLK_SCLK_UART1 35 #define CLK_SCLK_UART0 36 +#define CLK_ACLK_AHB2APB_PERIC2P 37 +#define CLK_ACLK_AHB2APB_PERIC1P 38 +#define CLK_ACLK_AHB2APB_PERIC0P 39 +#define CLK_ACLK_PERICNP_66 40 +#define CLK_PCLK_SCI 41 +#define CLK_PCLK_GPIO_FINGER 42 +#define CLK_PCLK_GPIO_ESE 43 +#define CLK_PCLK_PWM 44 +#define CLK_PCLK_SPDIF 45 +#define CLK_PCLK_PCM1 46 +#define CLK_PCLK_I2S1 47 +#define CLK_PCLK_ADCIF 48 +#define CLK_PCLK_GPIO_TOUCH 49 +#define CLK_PCLK_GPIO_NFC 50 +#define CLK_PCLK_GPIO_PERIC 51 +#define CLK_PCLK_PMU_PERIC 52 +#define CLK_PCLK_SYSREG_PERIC 53 +#define CLK_SCLK_IOCLK_SPI4 54 +#define CLK_SCLK_IOCLK_SPI3 55 +#define CLK_SCLK_SCI 56 +#define CLK_SCLK_SC_IN 57 +#define CLK_SCLK_PWM 58 +#define CLK_SCLK_IOCLK_SPI2 59 +#define CLK_SCLK_IOCLK_SPI1 60 +#define CLK_SCLK_IOCLK_SPI0 61 +#define CLK_SCLK_IOCLK_I2S1_BCLK 62 +#define CLK_SCLK_SPDIF 63 +#define CLK_SCLK_PCM1 64 +#define CLK_SCLK_I2S1 65 -#define PERIC_NR_CLK 37 +#define CLK_DIV_SCLK_SCI 70 +#define CLK_DIV_SCLK_SC_IN 71 + +#define PERIC_NR_CLK 72 /* CMU_PERIS */ #define CLK_PCLK_HPM_APBIF 1 -- GitLab From 56bcf3f3ea39402acff09cba9558a0d3b13fc56f Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Mon, 2 Feb 2015 23:23:59 +0900 Subject: [PATCH 00037/11651] clk: samsung: exynos5433: Add clocks for CMU_PERIS domain This patch adds missing gate clocks of CMU_PERIS domain which includes TMU/TZPC/SECKEY/CHIPID/TOPRTC/EFUSE IPs. The special clocks of CMU_PERIS use oscclk source clock directly. Signed-off-by: Chanwoo Choi Acked-by: Inki Dae Reviewed-by: Pankaj Dubey Signed-off-by: Sylwester Nawrocki --- drivers/clk/samsung/clk-exynos5433.c | 151 ++++++++++++++++++++++++- include/dt-bindings/clock/exynos5433.h | 33 +++++- 2 files changed, 181 insertions(+), 3 deletions(-) diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c index 10a9f8313c24..5ba9311624aa 100644 --- a/drivers/clk/samsung/clk-exynos5433.c +++ b/drivers/clk/samsung/clk-exynos5433.c @@ -245,6 +245,10 @@ PNAME(mout_sclk_audio1_p) = { "ioclk_audiocdclk1", "oscclk", PNAME(mout_sclk_audio0_p) = { "ioclk_audiocdclk0", "oscclk", "mout_aud_pll_user_t",}; +static struct samsung_fixed_factor_clock top_fixed_factor_clks[] __initdata = { + FFACTOR(0, "oscclk_efuse_common", "oscclk", 1, 1, 0), +}; + static struct samsung_fixed_rate_clock top_fixed_clks[] __initdata = { /* Xi2s{0|1}CDCLK input clock for I2S/PCM */ FRATE(0, "ioclk_audiocdclk1", NULL, CLK_IS_ROOT, 100000000), @@ -614,6 +618,8 @@ static struct samsung_cmu_info top_cmu_info __initdata = { .nr_gate_clks = ARRAY_SIZE(top_gate_clks), .fixed_clks = top_fixed_clks, .nr_fixed_clks = ARRAY_SIZE(top_fixed_clks), + .fixed_factor_clks = top_fixed_factor_clks, + .nr_fixed_factor_clks = ARRAY_SIZE(top_fixed_factor_clks), .nr_clk_ids = TOP_NR_CLK, .clk_regs = top_clk_regs, .nr_clk_regs = ARRAY_SIZE(top_clk_regs), @@ -954,15 +960,69 @@ CLK_OF_DECLARE(exynos5433_cmu_peric, "samsung,exynos5433-cmu-peric", /* * Register offset definitions for CMU_PERIS */ -#define ENABLE_ACLK_PERIS 0x0800 -#define ENABLE_PCLK_PERIS 0x0900 +#define ENABLE_ACLK_PERIS 0x0800 +#define ENABLE_PCLK_PERIS 0x0900 +#define ENABLE_PCLK_PERIS_SECURE_TZPC 0x0904 +#define ENABLE_PCLK_PERIS_SECURE_SECKEY_APBIF 0x0908 +#define ENABLE_PCLK_PERIS_SECURE_CHIPID_APBIF 0x090c +#define ENABLE_PCLK_PERIS_SECURE_TOPRTC 0x0910 +#define ENABLE_PCLK_PERIS_SECURE_CUSTOM_EFUSE_APBIF 0x0914 +#define ENABLE_PCLK_PERIS_SECURE_ANTIRBK_CNT_APBIF 0x0918 +#define ENABLE_PCLK_PERIS_SECURE_OTP_CON_APBIF 0x091c +#define ENABLE_SCLK_PERIS 0x0a00 +#define ENABLE_SCLK_PERIS_SECURE_SECKEY 0x0a04 +#define ENABLE_SCLK_PERIS_SECURE_CHIPID 0x0a08 +#define ENABLE_SCLK_PERIS_SECURE_TOPRTC 0x0a0c +#define ENABLE_SCLK_PERIS_SECURE_CUSTOM_EFUSE 0x0a10 +#define ENABLE_SCLK_PERIS_SECURE_ANTIRBK_CNT 0x0a14 +#define ENABLE_SCLK_PERIS_SECURE_OTP_CON 0x0a18 +#define ENABLE_IP_PERIS0 0x0b00 +#define ENABLE_IP_PERIS1 0x0b04 +#define ENABLE_IP_PERIS_SECURE_TZPC 0x0b08 +#define ENABLE_IP_PERIS_SECURE_SECKEY 0x0b0c +#define ENABLE_IP_PERIS_SECURE_CHIPID 0x0b10 +#define ENABLE_IP_PERIS_SECURE_TOPRTC 0x0b14 +#define ENABLE_IP_PERIS_SECURE_CUSTOM_EFUSE 0x0b18 +#define ENABLE_IP_PERIS_SECURE_ANTIBRK_CNT 0x0b1c +#define ENABLE_IP_PERIS_SECURE_OTP_CON 0x0b20 static unsigned long peris_clk_regs[] __initdata = { ENABLE_ACLK_PERIS, ENABLE_PCLK_PERIS, + ENABLE_PCLK_PERIS_SECURE_TZPC, + ENABLE_PCLK_PERIS_SECURE_SECKEY_APBIF, + ENABLE_PCLK_PERIS_SECURE_CHIPID_APBIF, + ENABLE_PCLK_PERIS_SECURE_TOPRTC, + ENABLE_PCLK_PERIS_SECURE_CUSTOM_EFUSE_APBIF, + ENABLE_PCLK_PERIS_SECURE_ANTIRBK_CNT_APBIF, + ENABLE_PCLK_PERIS_SECURE_OTP_CON_APBIF, + ENABLE_SCLK_PERIS, + ENABLE_SCLK_PERIS_SECURE_SECKEY, + ENABLE_SCLK_PERIS_SECURE_CHIPID, + ENABLE_SCLK_PERIS_SECURE_TOPRTC, + ENABLE_SCLK_PERIS_SECURE_CUSTOM_EFUSE, + ENABLE_SCLK_PERIS_SECURE_ANTIRBK_CNT, + ENABLE_SCLK_PERIS_SECURE_OTP_CON, + ENABLE_IP_PERIS0, + ENABLE_IP_PERIS1, + ENABLE_IP_PERIS_SECURE_TZPC, + ENABLE_IP_PERIS_SECURE_SECKEY, + ENABLE_IP_PERIS_SECURE_CHIPID, + ENABLE_IP_PERIS_SECURE_TOPRTC, + ENABLE_IP_PERIS_SECURE_CUSTOM_EFUSE, + ENABLE_IP_PERIS_SECURE_ANTIBRK_CNT, + ENABLE_IP_PERIS_SECURE_OTP_CON, }; static struct samsung_gate_clock peris_gate_clks[] __initdata = { + /* ENABLE_ACLK_PERIS */ + GATE(CLK_ACLK_AHB2APB_PERIS1P, "aclk_ahb2apb_peris1p", "aclk_peris_66", + ENABLE_ACLK_PERIS, 2, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_AHB2APB_PERIS0P, "aclk_ahb2apb_peris0p", "aclk_peris_66", + ENABLE_ACLK_PERIS, 1, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_PERISNP_66, "aclk_perisnp_66", "aclk_peris_66", + ENABLE_ACLK_PERIS, 0, CLK_IGNORE_UNUSED, 0), + /* ENABLE_PCLK_PERIS */ GATE(CLK_PCLK_HPM_APBIF, "pclk_hpm_apbif", "aclk_peris_66", ENABLE_PCLK_PERIS, 30, CLK_IGNORE_UNUSED, 0), @@ -984,6 +1044,93 @@ static struct samsung_gate_clock peris_gate_clks[] __initdata = { ENABLE_PCLK_PERIS, 15, CLK_IGNORE_UNUSED, 0), GATE(CLK_PCLK_HDMI_CEC, "pclk_hdmi_cec", "aclk_peris_66", ENABLE_PCLK_PERIS, 14, CLK_IGNORE_UNUSED, 0), + + /* ENABLE_PCLK_PERIS_SECURE_TZPC */ + GATE(CLK_PCLK_TZPC12, "pclk_tzpc12", "aclk_peris_66", + ENABLE_PCLK_PERIS_SECURE_TZPC, 12, 0, 0), + GATE(CLK_PCLK_TZPC11, "pclk_tzpc11", "aclk_peris_66", + ENABLE_PCLK_PERIS_SECURE_TZPC, 11, 0, 0), + GATE(CLK_PCLK_TZPC10, "pclk_tzpc10", "aclk_peris_66", + ENABLE_PCLK_PERIS_SECURE_TZPC, 10, 0, 0), + GATE(CLK_PCLK_TZPC9, "pclk_tzpc9", "aclk_peris_66", + ENABLE_PCLK_PERIS_SECURE_TZPC, 9, 0, 0), + GATE(CLK_PCLK_TZPC8, "pclk_tzpc8", "aclk_peris_66", + ENABLE_PCLK_PERIS_SECURE_TZPC, 8, 0, 0), + GATE(CLK_PCLK_TZPC7, "pclk_tzpc7", "aclk_peris_66", + ENABLE_PCLK_PERIS_SECURE_TZPC, 7, 0, 0), + GATE(CLK_PCLK_TZPC6, "pclk_tzpc6", "aclk_peris_66", + ENABLE_PCLK_PERIS_SECURE_TZPC, 6, 0, 0), + GATE(CLK_PCLK_TZPC5, "pclk_tzpc5", "aclk_peris_66", + ENABLE_PCLK_PERIS_SECURE_TZPC, 5, 0, 0), + GATE(CLK_PCLK_TZPC4, "pclk_tzpc4", "aclk_peris_66", + ENABLE_PCLK_PERIS_SECURE_TZPC, 4, 0, 0), + GATE(CLK_PCLK_TZPC3, "pclk_tzpc3", "aclk_peris_66", + ENABLE_PCLK_PERIS_SECURE_TZPC, 3, 0, 0), + GATE(CLK_PCLK_TZPC2, "pclk_tzpc2", "aclk_peris_66", + ENABLE_PCLK_PERIS_SECURE_TZPC, 2, 0, 0), + GATE(CLK_PCLK_TZPC1, "pclk_tzpc1", "aclk_peris_66", + ENABLE_PCLK_PERIS_SECURE_TZPC, 1, 0, 0), + GATE(CLK_PCLK_TZPC0, "pclk_tzpc0", "aclk_peris_66", + ENABLE_PCLK_PERIS_SECURE_TZPC, 0, 0, 0), + + /* ENABLE_PCLK_PERIS_SECURE_SECKEY_APBIF */ + GATE(CLK_PCLK_SECKEY_APBIF, "pclk_seckey_apbif", "aclk_peris_66", + ENABLE_PCLK_PERIS_SECURE_SECKEY_APBIF, 0, 0, 0), + + /* ENABLE_PCLK_PERIS_SECURE_CHIPID_APBIF */ + GATE(CLK_PCLK_CHIPID_APBIF, "pclk_chipid_apbif", "aclk_peris_66", + ENABLE_PCLK_PERIS_SECURE_CHIPID_APBIF, 0, 0, 0), + + /* ENABLE_PCLK_PERIS_SECURE_TOPRTC */ + GATE(CLK_PCLK_TOPRTC, "pclk_toprtc", "aclk_peris_66", + ENABLE_PCLK_PERIS_SECURE_TOPRTC, 0, 0, 0), + + /* ENABLE_PCLK_PERIS_SECURE_CUSTOM_EFUSE_APBIF */ + GATE(CLK_PCLK_CUSTOM_EFUSE_APBIF, "pclk_custom_efuse_apbif", + "aclk_peris_66", + ENABLE_PCLK_PERIS_SECURE_CUSTOM_EFUSE_APBIF, 0, 0, 0), + + /* ENABLE_PCLK_PERIS_SECURE_ANTIRBK_CNT_APBIF */ + GATE(CLK_PCLK_ANTIRBK_CNT_APBIF, "pclk_antirbk_cnt_apbif", + "aclk_peris_66", + ENABLE_PCLK_PERIS_SECURE_ANTIRBK_CNT_APBIF, 0, 0, 0), + + /* ENABLE_PCLK_PERIS_SECURE_OTP_CON_APBIF */ + GATE(CLK_PCLK_OTP_CON_APBIF, "pclk_otp_con_apbif", + "aclk_peris_66", + ENABLE_PCLK_PERIS_SECURE_OTP_CON_APBIF, 0, 0, 0), + + /* ENABLE_SCLK_PERIS */ + GATE(CLK_SCLK_ASV_TB, "sclk_asv_tb", "oscclk_efuse_common", + ENABLE_SCLK_PERIS, 10, 0, 0), + GATE(CLK_SCLK_TMU1, "sclk_tmu1", "oscclk_efuse_common", + ENABLE_SCLK_PERIS, 4, 0, 0), + GATE(CLK_SCLK_TMU0, "sclk_tmu0", "oscclk_efuse_common", + ENABLE_SCLK_PERIS, 3, 0, 0), + + /* ENABLE_SCLK_PERIS_SECURE_SECKEY */ + GATE(CLK_SCLK_SECKEY, "sclk_seckey", "oscclk_efuse_common", + ENABLE_SCLK_PERIS_SECURE_SECKEY, 0, 0, 0), + + /* ENABLE_SCLK_PERIS_SECURE_CHIPID */ + GATE(CLK_SCLK_CHIPID, "sclk_chipid", "oscclk_efuse_common", + ENABLE_SCLK_PERIS_SECURE_CHIPID, 0, 0, 0), + + /* ENABLE_SCLK_PERIS_SECURE_TOPRTC */ + GATE(CLK_SCLK_TOPRTC, "sclk_toprtc", "oscclk_efuse_common", + ENABLE_SCLK_PERIS_SECURE_TOPRTC, 0, 0, 0), + + /* ENABLE_SCLK_PERIS_SECURE_CUSTOM_EFUSE */ + GATE(CLK_SCLK_CUSTOM_EFUSE, "sclk_custom_efuse", "oscclk_efuse_common", + ENABLE_SCLK_PERIS_SECURE_CUSTOM_EFUSE, 0, 0, 0), + + /* ENABLE_SCLK_PERIS_SECURE_ANTIRBK_CNT */ + GATE(CLK_SCLK_ANTIRBK_CNT, "sclk_antirbk_cnt", "oscclk_efuse_common", + ENABLE_SCLK_PERIS_SECURE_ANTIRBK_CNT, 0, 0, 0), + + /* ENABLE_SCLK_PERIS_SECURE_OTP_CON */ + GATE(CLK_SCLK_OTP_CON, "sclk_otp_con", "oscclk_efuse_common", + ENABLE_SCLK_PERIS_SECURE_OTP_CON, 0, 0, 0), }; static struct samsung_cmu_info peris_cmu_info __initdata = { diff --git a/include/dt-bindings/clock/exynos5433.h b/include/dt-bindings/clock/exynos5433.h index b5c66f7b83be..5b3397d9843a 100644 --- a/include/dt-bindings/clock/exynos5433.h +++ b/include/dt-bindings/clock/exynos5433.h @@ -227,8 +227,39 @@ #define CLK_PCLK_WDT_ATLAS 8 #define CLK_PCLK_MCT 9 #define CLK_PCLK_HDMI_CEC 10 +#define CLK_ACLK_AHB2APB_PERIS1P 11 +#define CLK_ACLK_AHB2APB_PERIS0P 12 +#define CLK_ACLK_PERISNP_66 13 +#define CLK_PCLK_TZPC12 14 +#define CLK_PCLK_TZPC11 15 +#define CLK_PCLK_TZPC10 16 +#define CLK_PCLK_TZPC9 17 +#define CLK_PCLK_TZPC8 18 +#define CLK_PCLK_TZPC7 19 +#define CLK_PCLK_TZPC6 20 +#define CLK_PCLK_TZPC5 21 +#define CLK_PCLK_TZPC4 22 +#define CLK_PCLK_TZPC3 23 +#define CLK_PCLK_TZPC2 24 +#define CLK_PCLK_TZPC1 25 +#define CLK_PCLK_TZPC0 26 +#define CLK_PCLK_SECKEY_APBIF 27 +#define CLK_PCLK_CHIPID_APBIF 28 +#define CLK_PCLK_TOPRTC 29 +#define CLK_PCLK_CUSTOM_EFUSE_APBIF 30 +#define CLK_PCLK_ANTIRBK_CNT_APBIF 31 +#define CLK_PCLK_OTP_CON_APBIF 32 +#define CLK_SCLK_ASV_TB 33 +#define CLK_SCLK_TMU1 34 +#define CLK_SCLK_TMU0 35 +#define CLK_SCLK_SECKEY 36 +#define CLK_SCLK_CHIPID 37 +#define CLK_SCLK_TOPRTC 38 +#define CLK_SCLK_CUSTOM_EFUSE 39 +#define CLK_SCLK_ANTIRBK_CNT 40 +#define CLK_SCLK_OTP_CON 41 -#define PERIS_NR_CLK 11 +#define PERIS_NR_CLK 42 /* CMU_FSYS */ #define CLK_MOUT_ACLK_FSYS_200_USER 1 -- GitLab From a29308dad5dc4695a344ed9042cae8a1b8e35267 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Mon, 2 Feb 2015 23:24:00 +0900 Subject: [PATCH 00038/11651] clk: samsung: exynos5433: Add clocks for CMU_G2D domain This patch adds ths mux/divider/gate clocks of CMU_G2D domain which includes G2D/MDMA IPs. The CMU_G2D requires its parent defined in the CMU_TOP domain. Hence this patch adds G2D related clocks to the CMU_TOP domain. Signed-off-by: Chanwoo Choi Acked-by: Inki Dae Reviewed-by: Pankaj Dubey Signed-off-by: Sylwester Nawrocki --- drivers/clk/samsung/clk-exynos5433.c | 146 +++++++++++++++++++++++++ include/dt-bindings/clock/exynos5433.h | 42 ++++++- 2 files changed, 187 insertions(+), 1 deletion(-) diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c index 5ba9311624aa..24218dba8218 100644 --- a/drivers/clk/samsung/clk-exynos5433.c +++ b/drivers/clk/samsung/clk-exynos5433.c @@ -398,6 +398,20 @@ static struct samsung_mux_clock top_mux_clks[] __initdata = { }; static struct samsung_div_clock top_div_clks[] __initdata = { + /* DIV_TOP1 */ + DIV(CLK_DIV_ACLK_GSCL_111, "div_aclk_gscl_111", "mout_aclk_gscl_333", + DIV_TOP1, 28, 3), + DIV(CLK_DIV_ACLK_GSCL_333, "div_aclk_gscl_333", "mout_aclk_gscl_333", + DIV_TOP1, 24, 3), + DIV(CLK_DIV_ACLK_HEVC_400, "div_aclk_hevc_400", "mout_aclk_hevc_400", + DIV_TOP1, 20, 3), + DIV(CLK_DIV_ACLK_MFC_400, "div_aclk_mfc_400", "mout_aclk_mfc_400_c", + DIV_TOP1, 12, 3), + DIV(CLK_DIV_ACLK_G2D_266, "div_aclk_g2d_266", "mout_bus_pll_user", + DIV_TOP1, 8, 3), + DIV(CLK_DIV_ACLK_G2D_400, "div_aclk_g2d_400", "mout_aclk_g2d_400_b", + DIV_TOP1, 0, 3), + /* DIV_TOP2 */ DIV(CLK_DIV_ACLK_FSYS_200, "div_aclk_fsys_200", "mout_bus_pll_user", DIV_TOP2, 0, 3), @@ -490,6 +504,12 @@ static struct samsung_gate_clock top_gate_clks[] __initdata = { GATE(CLK_ACLK_FSYS_200, "aclk_fsys_200", "div_aclk_fsys_200", ENABLE_ACLK_TOP, 18, CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_G2D_266, "aclk_g2d_266", "div_aclk_g2d_266", + ENABLE_ACLK_TOP, 2, + CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_G2D_400, "aclk_g2d_400", "div_aclk_g2d_400", + ENABLE_ACLK_TOP, 0, + CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0), /* ENABLE_SCLK_TOP_FSYS */ GATE(CLK_SCLK_MMC2_FSYS, "sclk_mmc2_fsys", "div_sclk_mmc2_b", @@ -1277,3 +1297,129 @@ static void __init exynos5433_cmu_fsys_init(struct device_node *np) CLK_OF_DECLARE(exynos5433_cmu_fsys, "samsung,exynos5433-cmu-fsys", exynos5433_cmu_fsys_init); + +/* + * Register offset definitions for CMU_G2D + */ +#define MUX_SEL_G2D0 0x0200 +#define MUX_SEL_ENABLE_G2D0 0x0300 +#define MUX_SEL_STAT_G2D0 0x0400 +#define DIV_G2D 0x0600 +#define DIV_STAT_G2D 0x0700 +#define DIV_ENABLE_ACLK_G2D 0x0800 +#define DIV_ENABLE_ACLK_G2D_SECURE_SMMU_G2D 0x0804 +#define DIV_ENABLE_PCLK_G2D 0x0900 +#define DIV_ENABLE_PCLK_G2D_SECURE_SMMU_G2D 0x0904 +#define DIV_ENABLE_IP_G2D0 0x0b00 +#define DIV_ENABLE_IP_G2D1 0x0b04 +#define DIV_ENABLE_IP_G2D_SECURE_SMMU_G2D 0x0b08 + +static unsigned long g2d_clk_regs[] __initdata = { + MUX_SEL_G2D0, + MUX_SEL_ENABLE_G2D0, + MUX_SEL_STAT_G2D0, + DIV_G2D, + DIV_STAT_G2D, + DIV_ENABLE_ACLK_G2D, + DIV_ENABLE_ACLK_G2D_SECURE_SMMU_G2D, + DIV_ENABLE_PCLK_G2D, + DIV_ENABLE_PCLK_G2D_SECURE_SMMU_G2D, + DIV_ENABLE_IP_G2D0, + DIV_ENABLE_IP_G2D1, + DIV_ENABLE_IP_G2D_SECURE_SMMU_G2D, +}; + +/* list of all parent clock list */ +PNAME(mout_aclk_g2d_266_user_p) = { "oscclk", "aclk_g2d_266", }; +PNAME(mout_aclk_g2d_400_user_p) = { "oscclk", "aclk_g2d_400", }; + +static struct samsung_mux_clock g2d_mux_clks[] __initdata = { + /* MUX_SEL_G2D0 */ + MUX(CLK_MUX_ACLK_G2D_266_USER, "mout_aclk_g2d_266_user", + mout_aclk_g2d_266_user_p, MUX_SEL_G2D0, 4, 1), + MUX(CLK_MUX_ACLK_G2D_400_USER, "mout_aclk_g2d_400_user", + mout_aclk_g2d_400_user_p, MUX_SEL_G2D0, 0, 1), +}; + +static struct samsung_div_clock g2d_div_clks[] __initdata = { + /* DIV_G2D */ + DIV(CLK_DIV_PCLK_G2D, "div_pclk_g2d", "mout_aclk_g2d_266_user", + DIV_G2D, 0, 2), +}; + +static struct samsung_gate_clock g2d_gate_clks[] __initdata = { + /* DIV_ENABLE_ACLK_G2D */ + GATE(CLK_ACLK_SMMU_MDMA1, "aclk_smmu_mdma1", "mout_aclk_g2d_266_user", + DIV_ENABLE_ACLK_G2D, 12, 0, 0), + GATE(CLK_ACLK_BTS_MDMA1, "aclk_bts_mdam1", "mout_aclk_g2d_266_user", + DIV_ENABLE_ACLK_G2D, 11, 0, 0), + GATE(CLK_ACLK_BTS_G2D, "aclk_bts_g2d", "mout_aclk_g2d_400_user", + DIV_ENABLE_ACLK_G2D, 10, 0, 0), + GATE(CLK_ACLK_ALB_G2D, "aclk_alb_g2d", "mout_aclk_g2d_400_user", + DIV_ENABLE_ACLK_G2D, 9, 0, 0), + GATE(CLK_ACLK_AXIUS_G2DX, "aclk_axius_g2dx", "mout_aclk_g2d_400_user", + DIV_ENABLE_ACLK_G2D, 8, 0, 0), + GATE(CLK_ACLK_ASYNCAXI_SYSX, "aclk_asyncaxi_sysx", + "mout_aclk_g2d_400_user", DIV_ENABLE_ACLK_G2D, + 7, 0, 0), + GATE(CLK_ACLK_AHB2APB_G2D1P, "aclk_ahb2apb_g2d1p", "div_pclk_g2d", + DIV_ENABLE_ACLK_G2D, 6, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_AHB2APB_G2D0P, "aclk_ahb2apb_g2d0p", "div_pclk_g2d", + DIV_ENABLE_ACLK_G2D, 5, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_XIU_G2DX, "aclk_xiu_g2dx", "mout_aclk_g2d_400_user", + DIV_ENABLE_ACLK_G2D, 4, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_G2DNP_133, "aclk_g2dnp_133", "div_pclk_g2d", + DIV_ENABLE_ACLK_G2D, 3, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_G2DND_400, "aclk_g2dnd_400", "mout_aclk_g2d_400_user", + DIV_ENABLE_ACLK_G2D, 2, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_MDMA1, "aclk_mdma1", "mout_aclk_g2d_266_user", + DIV_ENABLE_ACLK_G2D, 1, 0, 0), + GATE(CLK_ACLK_G2D, "aclk_g2d", "mout_aclk_g2d_400_user", + DIV_ENABLE_ACLK_G2D, 0, 0, 0), + + /* DIV_ENABLE_ACLK_G2D_SECURE_SMMU_G2D */ + GATE(CLK_ACLK_SMMU_G2D, "aclk_smmu_g2d", "mout_aclk_g2d_400_user", + DIV_ENABLE_ACLK_G2D_SECURE_SMMU_G2D, 0, 0, 0), + + /* DIV_ENABLE_PCLK_G2D */ + GATE(CLK_PCLK_SMMU_MDMA1, "pclk_smmu_mdma1", "div_pclk_g2d", + DIV_ENABLE_PCLK_G2D, 7, 0, 0), + GATE(CLK_PCLK_BTS_MDMA1, "pclk_bts_mdam1", "div_pclk_g2d", + DIV_ENABLE_PCLK_G2D, 6, 0, 0), + GATE(CLK_PCLK_BTS_G2D, "pclk_bts_g2d", "div_pclk_g2d", + DIV_ENABLE_PCLK_G2D, 5, 0, 0), + GATE(CLK_PCLK_ALB_G2D, "pclk_alb_g2d", "div_pclk_g2d", + DIV_ENABLE_PCLK_G2D, 4, 0, 0), + GATE(CLK_PCLK_ASYNCAXI_SYSX, "pclk_asyncaxi_sysx", "div_pclk_g2d", + DIV_ENABLE_PCLK_G2D, 3, 0, 0), + GATE(CLK_PCLK_PMU_G2D, "pclk_pmu_g2d", "div_pclk_g2d", + DIV_ENABLE_PCLK_G2D, 2, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_SYSREG_G2D, "pclk_sysreg_g2d", "div_pclk_g2d", + DIV_ENABLE_PCLK_G2D, 1, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_G2D, "pclk_g2d", "div_pclk_g2d", DIV_ENABLE_PCLK_G2D, + 0, 0, 0), + + /* DIV_ENABLE_PCLK_G2D_SECURE_SMMU_G2D */ + GATE(CLK_PCLK_SMMU_G2D, "pclk_smmu_g2d", "div_pclk_g2d", + DIV_ENABLE_PCLK_G2D_SECURE_SMMU_G2D, 0, 0, 0), +}; + +static struct samsung_cmu_info g2d_cmu_info __initdata = { + .mux_clks = g2d_mux_clks, + .nr_mux_clks = ARRAY_SIZE(g2d_mux_clks), + .div_clks = g2d_div_clks, + .nr_div_clks = ARRAY_SIZE(g2d_div_clks), + .gate_clks = g2d_gate_clks, + .nr_gate_clks = ARRAY_SIZE(g2d_gate_clks), + .nr_clk_ids = G2D_NR_CLK, + .clk_regs = g2d_clk_regs, + .nr_clk_regs = ARRAY_SIZE(g2d_clk_regs), +}; + +static void __init exynos5433_cmu_g2d_init(struct device_node *np) +{ + samsung_cmu_register_one(np, &g2d_cmu_info); +} + +CLK_OF_DECLARE(exynos5433_cmu_g2d, "samsung,exynos5433-cmu-g2d", + exynos5433_cmu_g2d_init); diff --git a/include/dt-bindings/clock/exynos5433.h b/include/dt-bindings/clock/exynos5433.h index 5b3397d9843a..818d6b6bbdc4 100644 --- a/include/dt-bindings/clock/exynos5433.h +++ b/include/dt-bindings/clock/exynos5433.h @@ -100,6 +100,12 @@ #define CLK_DIV_SCLK_PCM1 128 #define CLK_DIV_SCLK_AUDIO1 129 #define CLK_DIV_SCLK_AUDIO0 130 +#define CLK_DIV_ACLK_GSCL_111 131 +#define CLK_DIV_ACLK_GSCL_333 132 +#define CLK_DIV_ACLK_HEVC_400 133 +#define CLK_DIV_ACLK_MFC_400 134 +#define CLK_DIV_ACLK_G2D_266 135 +#define CLK_DIV_ACLK_G2D_400 136 #define CLK_ACLK_PERIC_66 200 #define CLK_ACLK_PERIS_66 201 @@ -121,8 +127,10 @@ #define CLK_SCLK_SLIMBUS 217 #define CLK_SCLK_AUDIO1 218 #define CLK_SCLK_AUDIO0 219 +#define CLK_ACLK_G2D_266 220 +#define CLK_ACLK_G2D_400 221 -#define TOP_NR_CLK 220 +#define TOP_NR_CLK 222 /* CMU_CPIF */ #define CLK_FOUT_MPHY_PLL 1 @@ -286,4 +294,36 @@ #define FSYS_NR_CLK 66 +/* CMU_G2D */ +#define CLK_MUX_ACLK_G2D_266_USER 1 +#define CLK_MUX_ACLK_G2D_400_USER 2 + +#define CLK_DIV_PCLK_G2D 3 + +#define CLK_ACLK_SMMU_MDMA1 4 +#define CLK_ACLK_BTS_MDMA1 5 +#define CLK_ACLK_BTS_G2D 6 +#define CLK_ACLK_ALB_G2D 7 +#define CLK_ACLK_AXIUS_G2DX 8 +#define CLK_ACLK_ASYNCAXI_SYSX 9 +#define CLK_ACLK_AHB2APB_G2D1P 10 +#define CLK_ACLK_AHB2APB_G2D0P 11 +#define CLK_ACLK_XIU_G2DX 12 +#define CLK_ACLK_G2DNP_133 13 +#define CLK_ACLK_G2DND_400 14 +#define CLK_ACLK_MDMA1 15 +#define CLK_ACLK_G2D 16 +#define CLK_ACLK_SMMU_G2D 17 +#define CLK_PCLK_SMMU_MDMA1 18 +#define CLK_PCLK_BTS_MDMA1 19 +#define CLK_PCLK_BTS_G2D 20 +#define CLK_PCLK_ALB_G2D 21 +#define CLK_PCLK_ASYNCAXI_SYSX 22 +#define CLK_PCLK_PMU_G2D 23 +#define CLK_PCLK_SYSREG_G2D 24 +#define CLK_PCLK_G2D 25 +#define CLK_PCLK_SMMU_G2D 26 + +#define G2D_NR_CLK 27 + #endif /* _DT_BINDINGS_CLOCK_EXYNOS5433_H */ -- GitLab From 06d2f9dfa663367e8cc1690d7e5ce4113e5dbcc1 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Mon, 2 Feb 2015 23:24:01 +0900 Subject: [PATCH 00039/11651] clk: samsung: exynos5433: Add clocks for CMU_MIF domain This patch adds the mux/divider/gate clocks of CMU_MIF domain which includes the clocks for DMC(DRAM memory controller) and CCI(Cache Coherent Interconnect). The CMU_MIF domain provides the source clocks for CMU_DISP/CMU_BUS2. Signed-off-by: Chanwoo Choi Acked-by: Inki Dae Signed-off-by: Sylwester Nawrocki --- drivers/clk/samsung/clk-exynos5433.c | 599 +++++++++++++++++++++++++ include/dt-bindings/clock/exynos5433.h | 190 +++++++- 2 files changed, 788 insertions(+), 1 deletion(-) diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c index 24218dba8218..09ccf11bab64 100644 --- a/drivers/clk/samsung/clk-exynos5433.c +++ b/drivers/clk/samsung/clk-exynos5433.c @@ -740,6 +740,66 @@ CLK_OF_DECLARE(exynos5433_cmu_cpif, "samsung,exynos5433-cmu-cpif", #define MFC_PLL_CON0 0x0130 #define MFC_PLL_CON1 0x0134 #define MFC_PLL_FREQ_DET 0x013c +#define MUX_SEL_MIF0 0x0200 +#define MUX_SEL_MIF1 0x0204 +#define MUX_SEL_MIF2 0x0208 +#define MUX_SEL_MIF3 0x020c +#define MUX_SEL_MIF4 0x0210 +#define MUX_SEL_MIF5 0x0214 +#define MUX_SEL_MIF6 0x0218 +#define MUX_SEL_MIF7 0x021c +#define MUX_ENABLE_MIF0 0x0300 +#define MUX_ENABLE_MIF1 0x0304 +#define MUX_ENABLE_MIF2 0x0308 +#define MUX_ENABLE_MIF3 0x030c +#define MUX_ENABLE_MIF4 0x0310 +#define MUX_ENABLE_MIF5 0x0314 +#define MUX_ENABLE_MIF6 0x0318 +#define MUX_ENABLE_MIF7 0x031c +#define MUX_STAT_MIF0 0x0400 +#define MUX_STAT_MIF1 0x0404 +#define MUX_STAT_MIF2 0x0408 +#define MUX_STAT_MIF3 0x040c +#define MUX_STAT_MIF4 0x0410 +#define MUX_STAT_MIF5 0x0414 +#define MUX_STAT_MIF6 0x0418 +#define MUX_STAT_MIF7 0x041c +#define DIV_MIF1 0x0604 +#define DIV_MIF2 0x0608 +#define DIV_MIF3 0x060c +#define DIV_MIF4 0x0610 +#define DIV_MIF5 0x0614 +#define DIV_MIF_PLL_FREQ_DET 0x0618 +#define DIV_STAT_MIF1 0x0704 +#define DIV_STAT_MIF2 0x0708 +#define DIV_STAT_MIF3 0x070c +#define DIV_STAT_MIF4 0x0710 +#define DIV_STAT_MIF5 0x0714 +#define DIV_STAT_MIF_PLL_FREQ_DET 0x0718 +#define ENABLE_ACLK_MIF0 0x0800 +#define ENABLE_ACLK_MIF1 0x0804 +#define ENABLE_ACLK_MIF2 0x0808 +#define ENABLE_ACLK_MIF3 0x080c +#define ENABLE_PCLK_MIF 0x0900 +#define ENABLE_PCLK_MIF_SECURE_DREX0_TZ 0x0904 +#define ENABLE_PCLK_MIF_SECURE_DREX1_TZ 0x0908 +#define ENABLE_PCLK_MIF_SECURE_MONOTONIC_CNT 0x090c +#define ENABLE_PCLK_MIF_SECURE_RTC 0x0910 +#define ENABLE_SCLK_MIF 0x0a00 +#define ENABLE_IP_MIF0 0x0b00 +#define ENABLE_IP_MIF1 0x0b04 +#define ENABLE_IP_MIF2 0x0b08 +#define ENABLE_IP_MIF3 0x0b0c +#define ENABLE_IP_MIF_SECURE_DREX0_TZ 0x0b10 +#define ENABLE_IP_MIF_SECURE_DREX1_TZ 0x0b14 +#define ENABLE_IP_MIF_SECURE_MONOTONIC_CNT 0x0b18 +#define ENABLE_IP_MIF_SECURE_RTC 0x0b1c +#define CLKOUT_CMU_MIF 0x0c00 +#define CLKOUT_CMU_MIF_DIV_STAT 0x0c04 +#define DREX_FREQ_CTRL0 0x1000 +#define DREX_FREQ_CTRL1 0x1004 +#define PAUSE 0x1008 +#define DDRPHY_LOCK_CTRL 0x100c static unsigned long mif_clk_regs[] __initdata = { MEM0_PLL_LOCK, @@ -758,6 +818,66 @@ static unsigned long mif_clk_regs[] __initdata = { MFC_PLL_CON0, MFC_PLL_CON1, MFC_PLL_FREQ_DET, + MUX_SEL_MIF0, + MUX_SEL_MIF1, + MUX_SEL_MIF2, + MUX_SEL_MIF3, + MUX_SEL_MIF4, + MUX_SEL_MIF5, + MUX_SEL_MIF6, + MUX_SEL_MIF7, + MUX_ENABLE_MIF0, + MUX_ENABLE_MIF1, + MUX_ENABLE_MIF2, + MUX_ENABLE_MIF3, + MUX_ENABLE_MIF4, + MUX_ENABLE_MIF5, + MUX_ENABLE_MIF6, + MUX_ENABLE_MIF7, + MUX_STAT_MIF0, + MUX_STAT_MIF1, + MUX_STAT_MIF2, + MUX_STAT_MIF3, + MUX_STAT_MIF4, + MUX_STAT_MIF5, + MUX_STAT_MIF6, + MUX_STAT_MIF7, + DIV_MIF1, + DIV_MIF2, + DIV_MIF3, + DIV_MIF4, + DIV_MIF5, + DIV_MIF_PLL_FREQ_DET, + DIV_STAT_MIF1, + DIV_STAT_MIF2, + DIV_STAT_MIF3, + DIV_STAT_MIF4, + DIV_STAT_MIF5, + DIV_STAT_MIF_PLL_FREQ_DET, + ENABLE_ACLK_MIF0, + ENABLE_ACLK_MIF1, + ENABLE_ACLK_MIF2, + ENABLE_ACLK_MIF3, + ENABLE_PCLK_MIF, + ENABLE_PCLK_MIF_SECURE_DREX0_TZ, + ENABLE_PCLK_MIF_SECURE_DREX1_TZ, + ENABLE_PCLK_MIF_SECURE_MONOTONIC_CNT, + ENABLE_PCLK_MIF_SECURE_RTC, + ENABLE_SCLK_MIF, + ENABLE_IP_MIF0, + ENABLE_IP_MIF1, + ENABLE_IP_MIF2, + ENABLE_IP_MIF3, + ENABLE_IP_MIF_SECURE_DREX0_TZ, + ENABLE_IP_MIF_SECURE_DREX1_TZ, + ENABLE_IP_MIF_SECURE_MONOTONIC_CNT, + ENABLE_IP_MIF_SECURE_RTC, + CLKOUT_CMU_MIF, + CLKOUT_CMU_MIF_DIV_STAT, + DREX_FREQ_CTRL0, + DREX_FREQ_CTRL1, + PAUSE, + DDRPHY_LOCK_CTRL, }; static struct samsung_pll_clock mif_pll_clks[] __initdata = { @@ -771,9 +891,488 @@ static struct samsung_pll_clock mif_pll_clks[] __initdata = { MFC_PLL_LOCK, MFC_PLL_CON0, exynos5443_pll_rates), }; +/* list of all parent clock list */ +PNAME(mout_mfc_pll_div2_p) = { "mout_mfc_pll", "dout_mfc_pll", }; +PNAME(mout_bus_pll_div2_p) = { "mout_bus_pll", "dout_bus_pll", }; +PNAME(mout_mem1_pll_div2_p) = { "mout_mem1_pll", "dout_mem1_pll", }; +PNAME(mout_mem0_pll_div2_p) = { "mout_mem0_pll", "dout_mem0_pll", }; +PNAME(mout_mfc_pll_p) = { "oscclk", "fout_mfc_pll", }; +PNAME(mout_bus_pll_p) = { "oscclk", "fout_bus_pll", }; +PNAME(mout_mem1_pll_p) = { "oscclk", "fout_mem1_pll", }; +PNAME(mout_mem0_pll_p) = { "oscclk", "fout_mem0_pll", }; + +PNAME(mout_clk2x_phy_c_p) = { "mout_mem0_pll_div2", "mout_clkm_phy_b", }; +PNAME(mout_clk2x_phy_b_p) = { "mout_bus_pll_div2", "mout_clkm_phy_a", }; +PNAME(mout_clk2x_phy_a_p) = { "mout_bus_pll_div2", "mout_mfc_pll_div2", }; +PNAME(mout_clkm_phy_b_p) = { "mout_mem1_pll_div2", "mout_clkm_phy_a", }; + +PNAME(mout_aclk_mifnm_200_p) = { "mout_mem0_pll_div2", "div_mif_pre", }; +PNAME(mout_aclk_mifnm_400_p) = { "mout_mem1_pll_div2", "mout_bus_pll_div2",}; + +PNAME(mout_aclk_disp_333_b_p) = { "mout_aclk_disp_333_a", + "mout_bus_pll_div2", }; +PNAME(mout_aclk_disp_333_a_p) = { "mout_mfc_pll_div2", "sclk_mphy_pll", }; + +PNAME(mout_sclk_decon_vclk_c_p) = { "mout_sclk_decon_vclk_b", + "sclk_mphy_pll", }; +PNAME(mout_sclk_decon_vclk_b_p) = { "mout_sclk_decon_vclk_a", + "mout_mfc_pll_div2", }; +PNAME(mout_sclk_decon_p) = { "oscclk", "mout_bus_pll_div2", }; +PNAME(mout_sclk_decon_eclk_c_p) = { "mout_sclk_decon_eclk_b", + "sclk_mphy_pll", }; +PNAME(mout_sclk_decon_eclk_b_p) = { "mout_sclk_decon_eclk_a", + "mout_mfc_pll_div2", }; + +PNAME(mout_sclk_decon_tv_eclk_c_p) = { "mout_sclk_decon_tv_eclk_b", + "sclk_mphy_pll", }; +PNAME(mout_sclk_decon_tv_eclk_b_p) = { "mout_sclk_decon_tv_eclk_a", + "mout_mfc_pll_div2", }; +PNAME(mout_sclk_dsd_c_p) = { "mout_sclk_dsd_b", "mout_bus_pll_div2", }; +PNAME(mout_sclk_dsd_b_p) = { "mout_sclk_dsd_a", "sclk_mphy_pll", }; +PNAME(mout_sclk_dsd_a_p) = { "oscclk", "mout_mfc_pll_div2", }; + +PNAME(mout_sclk_dsim0_c_p) = { "mout_sclk_dsim0_b", "sclk_mphy_pll", }; +PNAME(mout_sclk_dsim0_b_p) = { "mout_sclk_dsim0_a", "mout_mfc_pll_div2" }; + +PNAME(mout_sclk_decon_tv_vclk_c_p) = { "mout_sclk_decon_tv_vclk_b", + "sclk_mphy_pll", }; +PNAME(mout_sclk_decon_tv_vclk_b_p) = { "mout_sclk_decon_tv_vclk_a", + "mout_mfc_pll_div2", }; +PNAME(mout_sclk_dsim1_c_p) = { "mout_sclk_dsim1_b", "sclk_mphy_pll", }; +PNAME(mout_sclk_dsim1_b_p) = { "mout_sclk_dsim1_a", "mout_mfc_pll_div2",}; + +static struct samsung_fixed_factor_clock mif_fixed_factor_clks[] __initdata = { + /* dout_{mfc|bus|mem1|mem0}_pll is half fixed rate from parent mux */ + FFACTOR(CLK_DOUT_MFC_PLL, "dout_mfc_pll", "mout_mfc_pll", 1, 1, 0), + FFACTOR(CLK_DOUT_BUS_PLL, "dout_bus_pll", "mout_bus_pll", 1, 1, 0), + FFACTOR(CLK_DOUT_MEM1_PLL, "dout_mem1_pll", "mout_mem1_pll", 1, 1, 0), + FFACTOR(CLK_DOUT_MEM0_PLL, "dout_mem0_pll", "mout_mem0_pll", 1, 1, 0), +}; + +static struct samsung_mux_clock mif_mux_clks[] __initdata = { + /* MUX_SEL_MIF0 */ + MUX(CLK_MOUT_MFC_PLL_DIV2, "mout_mfc_pll_div2", mout_mfc_pll_div2_p, + MUX_SEL_MIF0, 28, 1), + MUX(CLK_MOUT_BUS_PLL_DIV2, "mout_bus_pll_div2", mout_bus_pll_div2_p, + MUX_SEL_MIF0, 24, 1), + MUX(CLK_MOUT_MEM1_PLL_DIV2, "mout_mem1_pll_div2", mout_mem1_pll_div2_p, + MUX_SEL_MIF0, 20, 1), + MUX(CLK_MOUT_MEM0_PLL_DIV2, "mout_mem0_pll_div2", mout_mem0_pll_div2_p, + MUX_SEL_MIF0, 16, 1), + MUX(CLK_MOUT_MFC_PLL, "mout_mfc_pll", mout_mfc_pll_p, MUX_SEL_MIF0, + 12, 1), + MUX(CLK_MOUT_BUS_PLL, "mout_bus_pll", mout_bus_pll_p, MUX_SEL_MIF0, + 8, 1), + MUX(CLK_MOUT_MEM1_PLL, "mout_mem1_pll", mout_mem1_pll_p, MUX_SEL_MIF0, + 4, 1), + MUX(CLK_MOUT_MEM0_PLL, "mout_mem0_pll", mout_mem0_pll_p, MUX_SEL_MIF0, + 0, 1), + + /* MUX_SEL_MIF1 */ + MUX(CLK_MOUT_CLK2X_PHY_C, "mout_clk2x_phy_c", mout_clk2x_phy_c_p, + MUX_SEL_MIF1, 24, 1), + MUX(CLK_MOUT_CLK2X_PHY_B, "mout_clk2x_phy_b", mout_clk2x_phy_b_p, + MUX_SEL_MIF1, 20, 1), + MUX(CLK_MOUT_CLK2X_PHY_A, "mout_clk2x_phy_a", mout_clk2x_phy_a_p, + MUX_SEL_MIF1, 16, 1), + MUX(CLK_MOUT_CLKM_PHY_C, "mout_clkm_phy_c", mout_clk2x_phy_c_p, + MUX_SEL_MIF1, 12, 1), + MUX(CLK_MOUT_CLKM_PHY_B, "mout_clkm_phy_b", mout_clkm_phy_b_p, + MUX_SEL_MIF1, 8, 1), + MUX(CLK_MOUT_CLKM_PHY_A, "mout_clkm_phy_a", mout_clk2x_phy_a_p, + MUX_SEL_MIF1, 4, 1), + + /* MUX_SEL_MIF2 */ + MUX(CLK_MOUT_ACLK_MIFNM_200, "mout_aclk_mifnm_200", + mout_aclk_mifnm_200_p, MUX_SEL_MIF2, 8, 1), + MUX(CLK_MOUT_ACLK_MIFNM_400, "mout_aclk_mifnm_400", + mout_aclk_mifnm_400_p, MUX_SEL_MIF2, 0, 1), + + /* MUX_SEL_MIF3 */ + MUX(CLK_MOUT_ACLK_DISP_333_B, "mout_aclk_disp_333_b", + mout_aclk_disp_333_b_p, MUX_SEL_MIF3, 4, 1), + MUX(CLK_MOUT_ACLK_DISP_333_A, "mout_aclk_disp_333_a", + mout_aclk_disp_333_a_p, MUX_SEL_MIF3, 0, 1), + + /* MUX_SEL_MIF4 */ + MUX(CLK_MOUT_SCLK_DECON_VCLK_C, "mout_sclk_decon_vclk_c", + mout_sclk_decon_vclk_c_p, MUX_SEL_MIF4, 24, 1), + MUX(CLK_MOUT_SCLK_DECON_VCLK_B, "mout_sclk_decon_vclk_b", + mout_sclk_decon_vclk_b_p, MUX_SEL_MIF4, 20, 1), + MUX(CLK_MOUT_SCLK_DECON_VCLK_A, "mout_sclk_decon_vclk_a", + mout_sclk_decon_p, MUX_SEL_MIF4, 16, 1), + MUX(CLK_MOUT_SCLK_DECON_ECLK_C, "mout_sclk_decon_eclk_c", + mout_sclk_decon_eclk_c_p, MUX_SEL_MIF4, 8, 1), + MUX(CLK_MOUT_SCLK_DECON_ECLK_B, "mout_sclk_decon_eclk_b", + mout_sclk_decon_eclk_b_p, MUX_SEL_MIF4, 4, 1), + MUX(CLK_MOUT_SCLK_DECON_ECLK_A, "mout_sclk_decon_eclk_a", + mout_sclk_decon_p, MUX_SEL_MIF4, 0, 1), + + /* MUX_SEL_MIF5 */ + MUX(CLK_MOUT_SCLK_DECON_TV_ECLK_C, "mout_sclk_decon_tv_eclk_c", + mout_sclk_decon_tv_eclk_c_p, MUX_SEL_MIF5, 24, 1), + MUX(CLK_MOUT_SCLK_DECON_TV_ECLK_B, "mout_sclk_decon_tv_eclk_b", + mout_sclk_decon_tv_eclk_b_p, MUX_SEL_MIF5, 20, 1), + MUX(CLK_MOUT_SCLK_DECON_TV_ECLK_A, "mout_sclk_decon_tv_eclk_a", + mout_sclk_decon_p, MUX_SEL_MIF5, 16, 1), + MUX(CLK_MOUT_SCLK_DSD_C, "mout_sclk_dsd_c", mout_sclk_dsd_c_p, + MUX_SEL_MIF5, 8, 1), + MUX(CLK_MOUT_SCLK_DSD_B, "mout_sclk_dsd_b", mout_sclk_dsd_b_p, + MUX_SEL_MIF5, 4, 1), + MUX(CLK_MOUT_SCLK_DSD_A, "mout_sclk_dsd_a", mout_sclk_dsd_a_p, + MUX_SEL_MIF5, 0, 1), + + /* MUX_SEL_MIF6 */ + MUX(CLK_MOUT_SCLK_DSIM0_C, "mout_sclk_dsim0_c", mout_sclk_dsim0_c_p, + MUX_SEL_MIF6, 8, 1), + MUX(CLK_MOUT_SCLK_DSIM0_B, "mout_sclk_dsim0_b", mout_sclk_dsim0_b_p, + MUX_SEL_MIF6, 4, 1), + MUX(CLK_MOUT_SCLK_DSIM0_A, "mout_sclk_dsim0_a", mout_sclk_decon_p, + MUX_SEL_MIF6, 0, 1), + + /* MUX_SEL_MIF7 */ + MUX(CLK_MOUT_SCLK_DECON_TV_VCLK_C, "mout_sclk_decon_tv_vclk_c", + mout_sclk_decon_tv_vclk_c_p, MUX_SEL_MIF7, 24, 1), + MUX(CLK_MOUT_SCLK_DECON_TV_VCLK_B, "mout_sclk_decon_tv_vclk_b", + mout_sclk_decon_tv_vclk_b_p, MUX_SEL_MIF7, 20, 1), + MUX(CLK_MOUT_SCLK_DECON_TV_VCLK_A, "mout_sclk_decon_tv_vclk_a", + mout_sclk_decon_p, MUX_SEL_MIF7, 16, 1), + MUX(CLK_MOUT_SCLK_DSIM1_C, "mout_sclk_dsim1_c", mout_sclk_dsim1_c_p, + MUX_SEL_MIF7, 8, 1), + MUX(CLK_MOUT_SCLK_DSIM1_B, "mout_sclk_dsim1_b", mout_sclk_dsim1_b_p, + MUX_SEL_MIF7, 4, 1), + MUX(CLK_MOUT_SCLK_DSIM1_A, "mout_sclk_dsim1_a", mout_sclk_decon_p, + MUX_SEL_MIF7, 0, 1), +}; + +static struct samsung_div_clock mif_div_clks[] __initdata = { + /* DIV_MIF1 */ + DIV(CLK_DIV_SCLK_HPM_MIF, "div_sclk_hpm_mif", "div_clk2x_phy", + DIV_MIF1, 16, 2), + DIV(CLK_DIV_ACLK_DREX1, "div_aclk_drex1", "div_clk2x_phy", DIV_MIF1, + 12, 2), + DIV(CLK_DIV_ACLK_DREX0, "div_aclk_drex0", "div_clk2x_phy", DIV_MIF1, + 8, 2), + DIV(CLK_DIV_CLK2XPHY, "div_clk2x_phy", "mout_clk2x_phy_c", DIV_MIF1, + 4, 4), + + /* DIV_MIF2 */ + DIV(CLK_DIV_ACLK_MIF_266, "div_aclk_mif_266", "mout_bus_pll_div2", + DIV_MIF2, 20, 3), + DIV(CLK_DIV_ACLK_MIFND_133, "div_aclk_mifnd_133", "div_mif_pre", + DIV_MIF2, 16, 4), + DIV(CLK_DIV_ACLK_MIF_133, "div_aclk_mif_133", "div_mif_pre", + DIV_MIF2, 12, 4), + DIV(CLK_DIV_ACLK_MIFNM_200, "div_aclk_mifnm_200", + "mout_aclk_mifnm_200", DIV_MIF2, 8, 3), + DIV(CLK_DIV_ACLK_MIF_200, "div_aclk_mif_200", "div_aclk_mif_400", + DIV_MIF2, 4, 2), + DIV(CLK_DIV_ACLK_MIF_400, "div_aclk_mif_400", "mout_aclk_mifnm_400", + DIV_MIF2, 0, 3), + + /* DIV_MIF3 */ + DIV(CLK_DIV_ACLK_BUS2_400, "div_aclk_bus2_400", "div_mif_pre", + DIV_MIF3, 16, 4), + DIV(CLK_DIV_ACLK_DISP_333, "div_aclk_disp_333", "mout_aclk_disp_333_b", + DIV_MIF3, 4, 3), + DIV(CLK_DIV_ACLK_CPIF_200, "div_aclk_cpif_200", "mout_aclk_mifnm_200", + DIV_MIF3, 0, 3), + + /* DIV_MIF4 */ + DIV(CLK_DIV_SCLK_DSIM1, "div_sclk_dsim1", "mout_sclk_dsim1_c", + DIV_MIF4, 24, 4), + DIV(CLK_DIV_SCLK_DECON_TV_VCLK, "div_sclk_decon_tv_vclk", + "mout_sclk_decon_tv_vclk_c", DIV_MIF4, 20, 4), + DIV(CLK_DIV_SCLK_DSIM0, "div_sclk_dsim0", "mout_sclk_dsim0_c", + DIV_MIF4, 16, 4), + DIV(CLK_DIV_SCLK_DSD, "div_sclk_dsd", "mout_sclk_dsd_c", + DIV_MIF4, 12, 4), + DIV(CLK_DIV_SCLK_DECON_TV_ECLK, "div_sclk_decon_tv_eclk", + "mout_sclk_decon_tv_eclk_c", DIV_MIF4, 8, 4), + DIV(CLK_DIV_SCLK_DECON_VCLK, "div_sclk_decon_vclk", + "mout_sclk_decon_vclk_c", DIV_MIF4, 4, 4), + DIV(CLK_DIV_SCLK_DECON_ECLK, "div_sclk_decon_eclk", + "mout_sclk_decon_eclk_c", DIV_MIF4, 0, 4), + + /* DIV_MIF5 */ + DIV(CLK_DIV_MIF_PRE, "div_mif_pre", "mout_bus_pll_div2", DIV_MIF5, + 0, 3), +}; + +static struct samsung_gate_clock mif_gate_clks[] __initdata = { + /* ENABLE_ACLK_MIF0 */ + GATE(CLK_CLK2X_PHY1, "clk2k_phy1", "div_clk2x_phy", ENABLE_ACLK_MIF0, + 19, CLK_IGNORE_UNUSED, 0), + GATE(CLK_CLK2X_PHY0, "clk2x_phy0", "div_clk2x_phy", ENABLE_ACLK_MIF0, + 18, CLK_IGNORE_UNUSED, 0), + GATE(CLK_CLKM_PHY1, "clkm_phy1", "mout_clkm_phy_c", ENABLE_ACLK_MIF0, + 17, CLK_IGNORE_UNUSED, 0), + GATE(CLK_CLKM_PHY0, "clkm_phy0", "mout_clkm_phy_c", ENABLE_ACLK_MIF0, + 16, CLK_IGNORE_UNUSED, 0), + GATE(CLK_RCLK_DREX1, "rclk_drex1", "oscclk", ENABLE_ACLK_MIF0, + 15, CLK_IGNORE_UNUSED, 0), + GATE(CLK_RCLK_DREX0, "rclk_drex0", "oscclk", ENABLE_ACLK_MIF0, + 14, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_DREX1_TZ, "aclk_drex1_tz", "div_aclk_drex1", + ENABLE_ACLK_MIF0, 13, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_DREX0_TZ, "aclk_drex0_tz", "div_aclk_drex0", + ENABLE_ACLK_MIF0, 12, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_DREX1_PEREV, "aclk_drex1_perev", "div_aclk_drex1", + ENABLE_ACLK_MIF0, 11, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_DREX0_PEREV, "aclk_drex0_perev", "div_aclk_drex0", + ENABLE_ACLK_MIF0, 10, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_DREX1_MEMIF, "aclk_drex1_memif", "div_aclk_drex1", + ENABLE_ACLK_MIF0, 9, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_DREX0_MEMIF, "aclk_drex0_memif", "div_aclk_drex0", + ENABLE_ACLK_MIF0, 8, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_DREX1_SCH, "aclk_drex1_sch", "div_aclk_drex1", + ENABLE_ACLK_MIF0, 7, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_DREX0_SCH, "aclk_drex0_sch", "div_aclk_drex0", + ENABLE_ACLK_MIF0, 6, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_DREX1_BUSIF, "aclk_drex1_busif", "div_aclk_drex1", + ENABLE_ACLK_MIF0, 5, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_DREX0_BUSIF, "aclk_drex0_busif", "div_aclk_drex0", + ENABLE_ACLK_MIF0, 4, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_DREX1_BUSIF_RD, "aclk_drex1_busif_rd", "div_aclk_drex1", + ENABLE_ACLK_MIF0, 3, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_DREX0_BUSIF_RD, "aclk_drex0_busif_rd", "div_aclk_drex0", + ENABLE_ACLK_MIF0, 2, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_DREX1, "aclk_drex1", "div_aclk_drex1", + ENABLE_ACLK_MIF0, 2, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_DREX0, "aclk_drex0", "div_aclk_drex0", + ENABLE_ACLK_MIF0, 1, CLK_IGNORE_UNUSED, 0), + + /* ENABLE_ACLK_MIF1 */ + GATE(CLK_ACLK_ASYNCAXIS_MIF_IMEM, "aclk_asyncaxis_mif_imem", + "div_aclk_mif_200", ENABLE_ACLK_MIF1, 28, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAXIS_NOC_P_CCI, "aclk_asyncaxis_noc_p_cci", + "div_aclk_mif_200", ENABLE_ACLK_MIF1, + 27, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAXIM_NOC_P_CCI, "aclk_asyncaxim_noc_p_cci", + "div_aclk_mif_133", ENABLE_ACLK_MIF1, + 26, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAXIS_CP1, "aclk_asyncaxis_cp1", + "div_aclk_mifnm_200", ENABLE_ACLK_MIF1, + 25, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAXIM_CP1, "aclk_asyncaxim_cp1", + "div_aclk_drex1", ENABLE_ACLK_MIF1, + 24, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAXIS_CP0, "aclk_asyncaxis_cp0", + "div_aclk_mifnm_200", ENABLE_ACLK_MIF1, + 23, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAXIM_CP0, "aclk_asyncaxim_cp0", + "div_aclk_drex0", ENABLE_ACLK_MIF1, + 22, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAXIS_DREX1_3, "aclk_asyncaxis_drex1_3", + "div_aclk_mif_133", ENABLE_ACLK_MIF1, + 21, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAXIM_DREX1_3, "aclk_asyncaxim_drex1_3", + "div_aclk_drex1", ENABLE_ACLK_MIF1, + 20, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAXIS_DREX1_1, "aclk_asyncaxis_drex1_1", + "div_aclk_mif_133", ENABLE_ACLK_MIF1, + 19, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAXIM_DREX1_1, "aclk_asyncaxim_drex1_1", + "div_aclk_drex1", ENABLE_ACLK_MIF1, + 18, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAXIS_DREX1_0, "aclk_asyncaxis_drex1_0", + "div_aclk_mif_133", ENABLE_ACLK_MIF1, + 17, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAXIM_DREX1_0, "aclk_asyncaxim_drex1_0", + "div_aclk_drex1", ENABLE_ACLK_MIF1, + 16, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAXIS_DREX0_3, "aclk_asyncaxis_drex0_3", + "div_aclk_mif_133", ENABLE_ACLK_MIF1, + 15, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAXIM_DREX0_3, "aclk_asyncaxim_drex0_3", + "div_aclk_drex0", ENABLE_ACLK_MIF1, + 14, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAXIS_DREX0_1, "aclk_asyncaxis_drex0_1", + "div_aclk_mif_133", ENABLE_ACLK_MIF1, + 13, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAXIM_DREX0_1, "aclk_asyncaxim_drex0_1", + "div_aclk_drex0", ENABLE_ACLK_MIF1, + 12, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAXIS_DREX0_0, "aclk_asyncaxis_drex0_0", + "div_aclk_mif_133", ENABLE_ACLK_MIF1, + 11, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAXIM_DREX0_0, "aclk_asyncaxim_drex0_0", + "div_aclk_drex0", ENABLE_ACLK_MIF1, + 10, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_AHB2APB_MIF2P, "aclk_ahb2apb_mif2p", "div_aclk_mif_133", + ENABLE_ACLK_MIF1, 9, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_AHB2APB_MIF1P, "aclk_ahb2apb_mif1p", "div_aclk_mif_133", + ENABLE_ACLK_MIF1, 8, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_AHB2APB_MIF0P, "aclk_ahb2apb_mif0p", "div_aclk_mif_133", + ENABLE_ACLK_MIF1, 7, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_IXIU_CCI, "aclk_ixiu_cci", "div_aclk_mif_400", + ENABLE_ACLK_MIF1, 6, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_XIU_MIFSFRX, "aclk_xiu_mifsfrx", "div_aclk_mif_200", + ENABLE_ACLK_MIF1, 5, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_MIFNP_133, "aclk_mifnp_133", "div_aclk_mif_133", + ENABLE_ACLK_MIF1, 4, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_MIFNM_200, "aclk_mifnm_200", "div_aclk_mifnm_200", + ENABLE_ACLK_MIF1, 3, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_MIFND_133, "aclk_mifnd_133", "div_aclk_mifnd_133", + ENABLE_ACLK_MIF1, 2, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_MIFND_400, "aclk_mifnd_400", "div_aclk_mif_400", + ENABLE_ACLK_MIF1, 1, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_CCI, "aclk_cci", "div_aclk_mif_400", ENABLE_ACLK_MIF1, + 0, CLK_IGNORE_UNUSED, 0), + + /* ENABLE_ACLK_MIF2 */ + GATE(CLK_ACLK_MIFND_266, "aclk_mifnd_266", "div_aclk_mif_266", + ENABLE_ACLK_MIF2, 20, 0, 0), + GATE(CLK_ACLK_PPMU_DREX1S3, "aclk_ppmu_drex1s3", "div_aclk_drex1", + ENABLE_ACLK_MIF2, 17, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_PPMU_DREX1S1, "aclk_ppmu_drex1s1", "div_aclk_drex1", + ENABLE_ACLK_MIF2, 16, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_PPMU_DREX1S0, "aclk_ppmu_drex1s0", "div_aclk_drex1", + ENABLE_ACLK_MIF2, 15, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_PPMU_DREX0S3, "aclk_ppmu_drex0s3", "div_aclk_drex0", + ENABLE_ACLK_MIF2, 14, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_PPMU_DREX0S1, "aclk_ppmu_drex0s1", "div_aclk_drex0", + ENABLE_ACLK_MIF2, 13, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_PPMU_DREX0S0, "aclk_ppmu_drex0s0", "div_aclk_drex0", + ENABLE_ACLK_MIF2, 12, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_AXIDS_CCI_MIFSFRX, "aclk_axids_cci_mifsfrx", + "div_aclk_mif_200", ENABLE_ACLK_MIF2, 7, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_AXISYNCDNS_CCI, "aclk_axisyncdns_cci", + "div_aclk_mif_400", ENABLE_ACLK_MIF2, + 5, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_AXISYNCDN_CCI, "aclk_axisyncdn_cci", "div_aclk_mif_400", + ENABLE_ACLK_MIF2, 4, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_AXISYNCDN_NOC_D, "aclk_axisyncdn_noc_d", + "div_aclk_mif_200", ENABLE_ACLK_MIF2, + 3, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAPBS_MIF_CSSYS, "aclk_asyncapbs_mif_cssys", + "div_aclk_mifnd_133", ENABLE_ACLK_MIF2, 0, 0, 0), + + /* ENABLE_ACLK_MIF3 */ + GATE(CLK_ACLK_BUS2_400, "aclk_bus2_400", "div_aclk_bus2_400", + ENABLE_ACLK_MIF3, 4, + CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0), + GATE(CLK_ACLK_DISP_333, "aclk_disp_333", "div_aclk_disp_333", + ENABLE_ACLK_MIF3, 1, + CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0), + GATE(CLK_ACLK_CPIF_200, "aclk_cpif_200", "div_aclk_cpif_200", + ENABLE_ACLK_MIF3, 0, + CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0), + + /* ENABLE_PCLK_MIF */ + GATE(CLK_PCLK_PPMU_DREX1S3, "pclk_ppmu_drex1s3", "div_aclk_drex1", + ENABLE_PCLK_MIF, 29, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_PPMU_DREX1S1, "pclk_ppmu_drex1s1", "div_aclk_drex1", + ENABLE_PCLK_MIF, 28, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_PPMU_DREX1S0, "pclk_ppmu_drex1s0", "div_aclk_drex1", + ENABLE_PCLK_MIF, 27, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_PPMU_DREX0S3, "pclk_ppmu_drex0s3", "div_aclk_drex0", + ENABLE_PCLK_MIF, 26, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_PPMU_DREX0S1, "pclk_ppmu_drex0s1", "div_aclk_drex0", + ENABLE_PCLK_MIF, 25, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_PPMU_DREX0S0, "pclk_ppmu_drex0s0", "div_aclk_drex0", + ENABLE_PCLK_MIF, 24, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_ASYNCAXI_NOC_P_CCI, "pclk_asyncaxi_noc_p_cci", + "div_aclk_mif_133", ENABLE_PCLK_MIF, 21, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_ASYNCAXI_CP1, "pclk_asyncaxi_cp1", "div_aclk_mif_133", + ENABLE_PCLK_MIF, 19, 0, 0), + GATE(CLK_PCLK_ASYNCAXI_CP0, "pclk_asyncaxi_cp0", "div_aclk_mif_133", + ENABLE_PCLK_MIF, 18, 0, 0), + GATE(CLK_PCLK_ASYNCAXI_DREX1_3, "pclk_asyncaxi_drex1_3", + "div_aclk_mif_133", ENABLE_PCLK_MIF, 17, 0, 0), + GATE(CLK_PCLK_ASYNCAXI_DREX1_1, "pclk_asyncaxi_drex1_1", + "div_aclk_mif_133", ENABLE_PCLK_MIF, 16, 0, 0), + GATE(CLK_PCLK_ASYNCAXI_DREX1_0, "pclk_asyncaxi_drex1_0", + "div_aclk_mif_133", ENABLE_PCLK_MIF, 15, 0, 0), + GATE(CLK_PCLK_ASYNCAXI_DREX0_3, "pclk_asyncaxi_drex0_3", + "div_aclk_mif_133", ENABLE_PCLK_MIF, 14, 0, 0), + GATE(CLK_PCLK_ASYNCAXI_DREX0_1, "pclk_asyncaxi_drex0_1", + "div_aclk_mif_133", ENABLE_PCLK_MIF, 13, 0, 0), + GATE(CLK_PCLK_ASYNCAXI_DREX0_0, "pclk_asyncaxi_drex0_0", + "div_aclk_mif_133", ENABLE_PCLK_MIF, 12, 0, 0), + GATE(CLK_PCLK_MIFSRVND_133, "pclk_mifsrvnd_133", "div_aclk_mif_133", + ENABLE_PCLK_MIF, 11, 0, 0), + GATE(CLK_PCLK_PMU_MIF, "pclk_pmu_mif", "div_aclk_mif_133", + ENABLE_PCLK_MIF, 10, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_SYSREG_MIF, "pclk_sysreg_mif", "div_aclk_mif_133", + ENABLE_PCLK_MIF, 9, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_GPIO_ALIVE, "pclk_gpio_alive", "div_aclk_mif_133", + ENABLE_PCLK_MIF, 8, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_ABB, "pclk_abb", "div_aclk_mif_133", + ENABLE_PCLK_MIF, 7, 0, 0), + GATE(CLK_PCLK_PMU_APBIF, "pclk_pmu_apbif", "div_aclk_mif_133", + ENABLE_PCLK_MIF, 6, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_DDR_PHY1, "pclk_ddr_phy1", "div_aclk_mif_133", + ENABLE_PCLK_MIF, 5, 0, 0), + GATE(CLK_PCLK_DREX1, "pclk_drex1", "div_aclk_mif_133", + ENABLE_PCLK_MIF, 3, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_DDR_PHY0, "pclk_ddr_phy0", "div_aclk_mif_133", + ENABLE_PCLK_MIF, 2, 0, 0), + GATE(CLK_PCLK_DREX0, "pclk_drex0", "div_aclk_mif_133", + ENABLE_PCLK_MIF, 0, CLK_IGNORE_UNUSED, 0), + + /* ENABLE_PCLK_MIF_SECURE_DREX0_TZ */ + GATE(CLK_PCLK_DREX0_TZ, "pclk_drex0_tz", "div_aclk_mif_133", + ENABLE_PCLK_MIF_SECURE_DREX0_TZ, 0, 0, 0), + + /* ENABLE_PCLK_MIF_SECURE_DREX1_TZ */ + GATE(CLK_PCLK_DREX1_TZ, "pclk_drex1_tz", "div_aclk_mif_133", + ENABLE_PCLK_MIF_SECURE_DREX1_TZ, 0, 0, 0), + + /* ENABLE_PCLK_MIF_SECURE_MONOTONIC_CNT */ + GATE(CLK_PCLK_MONOTONIC_CNT, "pclk_monotonic_cnt", "div_aclk_mif_133", + ENABLE_PCLK_MIF_SECURE_RTC, 0, 0, 0), + + /* ENABLE_PCLK_MIF_SECURE_RTC */ + GATE(CLK_PCLK_RTC, "pclk_rtc", "div_aclk_mif_133", + ENABLE_PCLK_MIF_SECURE_RTC, 0, 0, 0), + + /* ENABLE_SCLK_MIF */ + GATE(CLK_SCLK_DSIM1_DISP, "sclk_dsim1_disp", "div_sclk_dsim1", + ENABLE_SCLK_MIF, 15, CLK_IGNORE_UNUSED, 0), + GATE(CLK_SCLK_DECON_TV_VCLK_DISP, "sclk_decon_tv_vclk_disp", + "div_sclk_decon_tv_vclk", ENABLE_SCLK_MIF, + 14, CLK_IGNORE_UNUSED, 0), + GATE(CLK_SCLK_DSIM0_DISP, "sclk_dsim0_disp", "div_sclk_dsim0", + ENABLE_SCLK_MIF, 9, CLK_IGNORE_UNUSED, 0), + GATE(CLK_SCLK_DSD_DISP, "sclk_dsd_disp", "div_sclk_dsd", + ENABLE_SCLK_MIF, 8, CLK_IGNORE_UNUSED, 0), + GATE(CLK_SCLK_DECON_TV_ECLK_DISP, "sclk_decon_tv_eclk_disp", + "div_sclk_decon_tv_eclk", ENABLE_SCLK_MIF, + 7, CLK_IGNORE_UNUSED, 0), + GATE(CLK_SCLK_DECON_VCLK_DISP, "sclk_decon_vclk_disp", + "div_sclk_decon_vclk", ENABLE_SCLK_MIF, + 6, CLK_IGNORE_UNUSED, 0), + GATE(CLK_SCLK_DECON_ECLK_DISP, "sclk_decon_eclk_disp", + "div_sclk_decon_eclk", ENABLE_SCLK_MIF, + 5, CLK_IGNORE_UNUSED, 0), + GATE(CLK_SCLK_HPM_MIF, "sclk_hpm_mif", "div_sclk_hpm_mif", + ENABLE_SCLK_MIF, 4, + CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_MFC_PLL, "sclk_mfc_pll", "mout_mfc_pll_div2", + ENABLE_SCLK_MIF, 3, CLK_IGNORE_UNUSED, 0), + GATE(CLK_SCLK_BUS_PLL, "sclk_bus_pll", "mout_bus_pll_div2", + ENABLE_SCLK_MIF, 2, CLK_IGNORE_UNUSED, 0), + GATE(CLK_SCLK_BUS_PLL_APOLLO, "sclk_bus_pll_apollo", "sclk_bus_pll", + ENABLE_SCLK_MIF, 1, CLK_IGNORE_UNUSED, 0), + GATE(CLK_SCLK_BUS_PLL_ATLAS, "sclk_bus_pll_atlas", "sclk_bus_pll", + ENABLE_SCLK_MIF, 0, CLK_IGNORE_UNUSED, 0), +}; + static struct samsung_cmu_info mif_cmu_info __initdata = { .pll_clks = mif_pll_clks, .nr_pll_clks = ARRAY_SIZE(mif_pll_clks), + .mux_clks = mif_mux_clks, + .nr_mux_clks = ARRAY_SIZE(mif_mux_clks), + .div_clks = mif_div_clks, + .nr_div_clks = ARRAY_SIZE(mif_div_clks), + .gate_clks = mif_gate_clks, + .nr_gate_clks = ARRAY_SIZE(mif_gate_clks), + .fixed_factor_clks = mif_fixed_factor_clks, + .nr_fixed_factor_clks = ARRAY_SIZE(mif_fixed_factor_clks), .nr_clk_ids = MIF_NR_CLK, .clk_regs = mif_clk_regs, .nr_clk_regs = ARRAY_SIZE(mif_clk_regs), diff --git a/include/dt-bindings/clock/exynos5433.h b/include/dt-bindings/clock/exynos5433.h index 818d6b6bbdc4..6a3ce113e1e5 100644 --- a/include/dt-bindings/clock/exynos5433.h +++ b/include/dt-bindings/clock/exynos5433.h @@ -149,8 +149,196 @@ #define CLK_FOUT_MEM1_PLL 2 #define CLK_FOUT_BUS_PLL 3 #define CLK_FOUT_MFC_PLL 4 +#define CLK_DOUT_MFC_PLL 5 +#define CLK_DOUT_BUS_PLL 6 +#define CLK_DOUT_MEM1_PLL 7 +#define CLK_DOUT_MEM0_PLL 8 -#define MIF_NR_CLK 5 +#define CLK_MOUT_MFC_PLL_DIV2 10 +#define CLK_MOUT_BUS_PLL_DIV2 11 +#define CLK_MOUT_MEM1_PLL_DIV2 12 +#define CLK_MOUT_MEM0_PLL_DIV2 13 +#define CLK_MOUT_MFC_PLL 14 +#define CLK_MOUT_BUS_PLL 15 +#define CLK_MOUT_MEM1_PLL 16 +#define CLK_MOUT_MEM0_PLL 17 +#define CLK_MOUT_CLK2X_PHY_C 18 +#define CLK_MOUT_CLK2X_PHY_B 19 +#define CLK_MOUT_CLK2X_PHY_A 20 +#define CLK_MOUT_CLKM_PHY_C 21 +#define CLK_MOUT_CLKM_PHY_B 22 +#define CLK_MOUT_CLKM_PHY_A 23 +#define CLK_MOUT_ACLK_MIFNM_200 24 +#define CLK_MOUT_ACLK_MIFNM_400 25 +#define CLK_MOUT_ACLK_DISP_333_B 26 +#define CLK_MOUT_ACLK_DISP_333_A 27 +#define CLK_MOUT_SCLK_DECON_VCLK_C 28 +#define CLK_MOUT_SCLK_DECON_VCLK_B 29 +#define CLK_MOUT_SCLK_DECON_VCLK_A 30 +#define CLK_MOUT_SCLK_DECON_ECLK_C 31 +#define CLK_MOUT_SCLK_DECON_ECLK_B 32 +#define CLK_MOUT_SCLK_DECON_ECLK_A 33 +#define CLK_MOUT_SCLK_DECON_TV_ECLK_C 34 +#define CLK_MOUT_SCLK_DECON_TV_ECLK_B 35 +#define CLK_MOUT_SCLK_DECON_TV_ECLK_A 36 +#define CLK_MOUT_SCLK_DSD_C 37 +#define CLK_MOUT_SCLK_DSD_B 38 +#define CLK_MOUT_SCLK_DSD_A 39 +#define CLK_MOUT_SCLK_DSIM0_C 40 +#define CLK_MOUT_SCLK_DSIM0_B 41 +#define CLK_MOUT_SCLK_DSIM0_A 42 +#define CLK_MOUT_SCLK_DECON_TV_VCLK_C 46 +#define CLK_MOUT_SCLK_DECON_TV_VCLK_B 47 +#define CLK_MOUT_SCLK_DECON_TV_VCLK_A 48 +#define CLK_MOUT_SCLK_DSIM1_C 49 +#define CLK_MOUT_SCLK_DSIM1_B 50 +#define CLK_MOUT_SCLK_DSIM1_A 51 + +#define CLK_DIV_SCLK_HPM_MIF 55 +#define CLK_DIV_ACLK_DREX1 56 +#define CLK_DIV_ACLK_DREX0 57 +#define CLK_DIV_CLK2XPHY 58 +#define CLK_DIV_ACLK_MIF_266 59 +#define CLK_DIV_ACLK_MIFND_133 60 +#define CLK_DIV_ACLK_MIF_133 61 +#define CLK_DIV_ACLK_MIFNM_200 62 +#define CLK_DIV_ACLK_MIF_200 63 +#define CLK_DIV_ACLK_MIF_400 64 +#define CLK_DIV_ACLK_BUS2_400 65 +#define CLK_DIV_ACLK_DISP_333 66 +#define CLK_DIV_ACLK_CPIF_200 67 +#define CLK_DIV_SCLK_DSIM1 68 +#define CLK_DIV_SCLK_DECON_TV_VCLK 69 +#define CLK_DIV_SCLK_DSIM0 70 +#define CLK_DIV_SCLK_DSD 71 +#define CLK_DIV_SCLK_DECON_TV_ECLK 72 +#define CLK_DIV_SCLK_DECON_VCLK 73 +#define CLK_DIV_SCLK_DECON_ECLK 74 +#define CLK_DIV_MIF_PRE 75 + +#define CLK_CLK2X_PHY1 80 +#define CLK_CLK2X_PHY0 81 +#define CLK_CLKM_PHY1 82 +#define CLK_CLKM_PHY0 83 +#define CLK_RCLK_DREX1 84 +#define CLK_RCLK_DREX0 85 +#define CLK_ACLK_DREX1_TZ 86 +#define CLK_ACLK_DREX0_TZ 87 +#define CLK_ACLK_DREX1_PEREV 88 +#define CLK_ACLK_DREX0_PEREV 89 +#define CLK_ACLK_DREX1_MEMIF 90 +#define CLK_ACLK_DREX0_MEMIF 91 +#define CLK_ACLK_DREX1_SCH 92 +#define CLK_ACLK_DREX0_SCH 93 +#define CLK_ACLK_DREX1_BUSIF 94 +#define CLK_ACLK_DREX0_BUSIF 95 +#define CLK_ACLK_DREX1_BUSIF_RD 96 +#define CLK_ACLK_DREX0_BUSIF_RD 97 +#define CLK_ACLK_DREX1 98 +#define CLK_ACLK_DREX0 99 +#define CLK_ACLK_ASYNCAXIM_ATLAS_CCIX 100 +#define CLK_ACLK_ASYNCAXIS_ATLAS_MIF 101 +#define CLK_ACLK_ASYNCAXIM_ATLAS_MIF 102 +#define CLK_ACLK_ASYNCAXIS_MIF_IMEM 103 +#define CLK_ACLK_ASYNCAXIS_NOC_P_CCI 104 +#define CLK_ACLK_ASYNCAXIM_NOC_P_CCI 105 +#define CLK_ACLK_ASYNCAXIS_CP1 106 +#define CLK_ACLK_ASYNCAXIM_CP1 107 +#define CLK_ACLK_ASYNCAXIS_CP0 108 +#define CLK_ACLK_ASYNCAXIM_CP0 109 +#define CLK_ACLK_ASYNCAXIS_DREX1_3 110 +#define CLK_ACLK_ASYNCAXIM_DREX1_3 111 +#define CLK_ACLK_ASYNCAXIS_DREX1_1 112 +#define CLK_ACLK_ASYNCAXIM_DREX1_1 113 +#define CLK_ACLK_ASYNCAXIS_DREX1_0 114 +#define CLK_ACLK_ASYNCAXIM_DREX1_0 115 +#define CLK_ACLK_ASYNCAXIS_DREX0_3 116 +#define CLK_ACLK_ASYNCAXIM_DREX0_3 117 +#define CLK_ACLK_ASYNCAXIS_DREX0_1 118 +#define CLK_ACLK_ASYNCAXIM_DREX0_1 119 +#define CLK_ACLK_ASYNCAXIS_DREX0_0 120 +#define CLK_ACLK_ASYNCAXIM_DREX0_0 121 +#define CLK_ACLK_AHB2APB_MIF2P 122 +#define CLK_ACLK_AHB2APB_MIF1P 123 +#define CLK_ACLK_AHB2APB_MIF0P 124 +#define CLK_ACLK_IXIU_CCI 125 +#define CLK_ACLK_XIU_MIFSFRX 126 +#define CLK_ACLK_MIFNP_133 127 +#define CLK_ACLK_MIFNM_200 128 +#define CLK_ACLK_MIFND_133 129 +#define CLK_ACLK_MIFND_400 130 +#define CLK_ACLK_CCI 131 +#define CLK_ACLK_MIFND_266 132 +#define CLK_ACLK_PPMU_DREX1S3 133 +#define CLK_ACLK_PPMU_DREX1S1 134 +#define CLK_ACLK_PPMU_DREX1S0 135 +#define CLK_ACLK_PPMU_DREX0S3 136 +#define CLK_ACLK_PPMU_DREX0S1 137 +#define CLK_ACLK_PPMU_DREX0S0 138 +#define CLK_ACLK_BTS_APOLLO 139 +#define CLK_ACLK_BTS_ATLAS 140 +#define CLK_ACLK_ACE_SEL_APOLL 141 +#define CLK_ACLK_ACE_SEL_ATLAS 142 +#define CLK_ACLK_AXIDS_CCI_MIFSFRX 143 +#define CLK_ACLK_AXIUS_ATLAS_CCI 144 +#define CLK_ACLK_AXISYNCDNS_CCI 145 +#define CLK_ACLK_AXISYNCDN_CCI 146 +#define CLK_ACLK_AXISYNCDN_NOC_D 147 +#define CLK_ACLK_ASYNCACEM_APOLLO_CCI 148 +#define CLK_ACLK_ASYNCACEM_ATLAS_CCI 149 +#define CLK_ACLK_ASYNCAPBS_MIF_CSSYS 150 +#define CLK_ACLK_BUS2_400 151 +#define CLK_ACLK_DISP_333 152 +#define CLK_ACLK_CPIF_200 153 +#define CLK_PCLK_PPMU_DREX1S3 154 +#define CLK_PCLK_PPMU_DREX1S1 155 +#define CLK_PCLK_PPMU_DREX1S0 156 +#define CLK_PCLK_PPMU_DREX0S3 157 +#define CLK_PCLK_PPMU_DREX0S1 158 +#define CLK_PCLK_PPMU_DREX0S0 159 +#define CLK_PCLK_BTS_APOLLO 160 +#define CLK_PCLK_BTS_ATLAS 161 +#define CLK_PCLK_ASYNCAXI_NOC_P_CCI 162 +#define CLK_PCLK_ASYNCAXI_CP1 163 +#define CLK_PCLK_ASYNCAXI_CP0 164 +#define CLK_PCLK_ASYNCAXI_DREX1_3 165 +#define CLK_PCLK_ASYNCAXI_DREX1_1 166 +#define CLK_PCLK_ASYNCAXI_DREX1_0 167 +#define CLK_PCLK_ASYNCAXI_DREX0_3 168 +#define CLK_PCLK_ASYNCAXI_DREX0_1 169 +#define CLK_PCLK_ASYNCAXI_DREX0_0 170 +#define CLK_PCLK_MIFSRVND_133 171 +#define CLK_PCLK_PMU_MIF 172 +#define CLK_PCLK_SYSREG_MIF 173 +#define CLK_PCLK_GPIO_ALIVE 174 +#define CLK_PCLK_ABB 175 +#define CLK_PCLK_PMU_APBIF 176 +#define CLK_PCLK_DDR_PHY1 177 +#define CLK_PCLK_DREX1 178 +#define CLK_PCLK_DDR_PHY0 179 +#define CLK_PCLK_DREX0 180 +#define CLK_PCLK_DREX0_TZ 181 +#define CLK_PCLK_DREX1_TZ 182 +#define CLK_PCLK_MONOTONIC_CNT 183 +#define CLK_PCLK_RTC 184 +#define CLK_SCLK_DSIM1_DISP 185 +#define CLK_SCLK_DECON_TV_VCLK_DISP 186 +#define CLK_SCLK_FREQ_DET_BUS_PLL 187 +#define CLK_SCLK_FREQ_DET_MFC_PLL 188 +#define CLK_SCLK_FREQ_DET_MEM0_PLL 189 +#define CLK_SCLK_FREQ_DET_MEM1_PLL 190 +#define CLK_SCLK_DSIM0_DISP 191 +#define CLK_SCLK_DSD_DISP 192 +#define CLK_SCLK_DECON_TV_ECLK_DISP 193 +#define CLK_SCLK_DECON_VCLK_DISP 194 +#define CLK_SCLK_DECON_ECLK_DISP 195 +#define CLK_SCLK_HPM_MIF 196 +#define CLK_SCLK_MFC_PLL 197 +#define CLK_SCLK_BUS_PLL 198 +#define CLK_SCLK_BUS_PLL_APOLLO 199 +#define CLK_SCLK_BUS_PLL_ATLAS 200 + +#define MIF_NR_CLK 201 /* CMU_PERIC */ #define CLK_PCLK_SPI2 1 -- GitLab From 2a1808a6c00fb6d75ebfa596add57638b9290926 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Mon, 2 Feb 2015 23:24:02 +0900 Subject: [PATCH 00040/11651] clk: samsung: exynos5433: Add clocks for CMU_DISP domain This patch adds the the mux/divider/gate clocks for CMU_DISP domain which includes clocks of the display IPs (DECON/HDMI/DSIM/MIXER). Also, CMU_DISP requires 'sclk_hdmi_spdif_disp' source clock from CMU_TOP domain. This patch adds the clocks of CMU_TOP related to HDMI. Signed-off-by: Chanwoo Choi Acked-by: Inki Dae Signed-off-by: Sylwester Nawrocki --- drivers/clk/samsung/clk-exynos5433.c | 437 +++++++++++++++++++++++++ include/dt-bindings/clock/exynos5433.h | 114 ++++++- 2 files changed, 550 insertions(+), 1 deletion(-) diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c index 09ccf11bab64..3e6c3d595e96 100644 --- a/drivers/clk/samsung/clk-exynos5433.c +++ b/drivers/clk/samsung/clk-exynos5433.c @@ -245,6 +245,8 @@ PNAME(mout_sclk_audio1_p) = { "ioclk_audiocdclk1", "oscclk", PNAME(mout_sclk_audio0_p) = { "ioclk_audiocdclk0", "oscclk", "mout_aud_pll_user_t",}; +PNAME(mout_sclk_hdmi_spdif_p) = { "sclk_audio1", "ioclk_spdif_extclk", }; + static struct samsung_fixed_factor_clock top_fixed_factor_clks[] __initdata = { FFACTOR(0, "oscclk_efuse_common", "oscclk", 1, 1, 0), }; @@ -395,6 +397,10 @@ static struct samsung_mux_clock top_mux_clks[] __initdata = { MUX_SEL_TOP_PERIC1, 4, 2), MUX(CLK_MOUT_SCLK_AUDIO0, "mout_sclk_audio0", mout_sclk_audio0_p, MUX_SEL_TOP_PERIC1, 0, 2), + + /* MUX_SEL_TOP_DISP */ + MUX(CLK_MOUT_SCLK_HDMI_SPDIF, "mout_sclk_hdmi_spdif", + mout_sclk_hdmi_spdif_p, MUX_SEL_TOP_DISP, 0, 1), }; static struct samsung_div_clock top_div_clks[] __initdata = { @@ -1360,6 +1366,11 @@ static struct samsung_gate_clock mif_gate_clks[] __initdata = { ENABLE_SCLK_MIF, 1, CLK_IGNORE_UNUSED, 0), GATE(CLK_SCLK_BUS_PLL_ATLAS, "sclk_bus_pll_atlas", "sclk_bus_pll", ENABLE_SCLK_MIF, 0, CLK_IGNORE_UNUSED, 0), + + /* ENABLE_SCLK_TOP_DISP */ + GATE(CLK_SCLK_HDMI_SPDIF_DISP, "sclk_hdmi_spdif_disp", + "mout_sclk_hdmi_spdif", ENABLE_SCLK_TOP_DISP, 0, + CLK_IGNORE_UNUSED, 0), }; static struct samsung_cmu_info mif_cmu_info __initdata = { @@ -2022,3 +2033,429 @@ static void __init exynos5433_cmu_g2d_init(struct device_node *np) CLK_OF_DECLARE(exynos5433_cmu_g2d, "samsung,exynos5433-cmu-g2d", exynos5433_cmu_g2d_init); + +/* + * Register offset definitions for CMU_DISP + */ +#define DISP_PLL_LOCK 0x0000 +#define DISP_PLL_CON0 0x0100 +#define DISP_PLL_CON1 0x0104 +#define DISP_PLL_FREQ_DET 0x0108 +#define MUX_SEL_DISP0 0x0200 +#define MUX_SEL_DISP1 0x0204 +#define MUX_SEL_DISP2 0x0208 +#define MUX_SEL_DISP3 0x020c +#define MUX_SEL_DISP4 0x0210 +#define MUX_ENABLE_DISP0 0x0300 +#define MUX_ENABLE_DISP1 0x0304 +#define MUX_ENABLE_DISP2 0x0308 +#define MUX_ENABLE_DISP3 0x030c +#define MUX_ENABLE_DISP4 0x0310 +#define MUX_STAT_DISP0 0x0400 +#define MUX_STAT_DISP1 0x0404 +#define MUX_STAT_DISP2 0x0408 +#define MUX_STAT_DISP3 0x040c +#define MUX_STAT_DISP4 0x0410 +#define MUX_IGNORE_DISP2 0x0508 +#define DIV_DISP 0x0600 +#define DIV_DISP_PLL_FREQ_DET 0x0604 +#define DIV_STAT_DISP 0x0700 +#define DIV_STAT_DISP_PLL_FREQ_DET 0x0704 +#define ENABLE_ACLK_DISP0 0x0800 +#define ENABLE_ACLK_DISP1 0x0804 +#define ENABLE_PCLK_DISP 0x0900 +#define ENABLE_SCLK_DISP 0x0a00 +#define ENABLE_IP_DISP0 0x0b00 +#define ENABLE_IP_DISP1 0x0b04 +#define CLKOUT_CMU_DISP 0x0c00 +#define CLKOUT_CMU_DISP_DIV_STAT 0x0c04 + +static unsigned long disp_clk_regs[] __initdata = { + DISP_PLL_LOCK, + DISP_PLL_CON0, + DISP_PLL_CON1, + DISP_PLL_FREQ_DET, + MUX_SEL_DISP0, + MUX_SEL_DISP1, + MUX_SEL_DISP2, + MUX_SEL_DISP3, + MUX_SEL_DISP4, + MUX_ENABLE_DISP0, + MUX_ENABLE_DISP1, + MUX_ENABLE_DISP2, + MUX_ENABLE_DISP3, + MUX_ENABLE_DISP4, + MUX_STAT_DISP0, + MUX_STAT_DISP1, + MUX_STAT_DISP2, + MUX_STAT_DISP3, + MUX_STAT_DISP4, + MUX_IGNORE_DISP2, + DIV_DISP, + DIV_DISP_PLL_FREQ_DET, + DIV_STAT_DISP, + DIV_STAT_DISP_PLL_FREQ_DET, + ENABLE_ACLK_DISP0, + ENABLE_ACLK_DISP1, + ENABLE_PCLK_DISP, + ENABLE_SCLK_DISP, + ENABLE_IP_DISP0, + ENABLE_IP_DISP1, + CLKOUT_CMU_DISP, + CLKOUT_CMU_DISP_DIV_STAT, +}; + +/* list of all parent clock list */ +PNAME(mout_disp_pll_p) = { "oscclk", "fout_disp_pll", }; +PNAME(mout_sclk_dsim1_user_p) = { "oscclk", "sclk_dsim1_disp", }; +PNAME(mout_sclk_dsim0_user_p) = { "oscclk", "sclk_dsim0_disp", }; +PNAME(mout_sclk_dsd_user_p) = { "oscclk", "sclk_dsd_disp", }; +PNAME(mout_sclk_decon_tv_eclk_user_p) = { "oscclk", + "sclk_decon_tv_eclk_disp", }; +PNAME(mout_sclk_decon_vclk_user_p) = { "oscclk", + "sclk_decon_vclk_disp", }; +PNAME(mout_sclk_decon_eclk_user_p) = { "oscclk", + "sclk_decon_eclk_disp", }; +PNAME(mout_sclk_decon_tv_vlkc_user_p) = { "oscclk", + "sclk_decon_tv_vclk_disp", }; +PNAME(mout_aclk_disp_333_user_p) = { "oscclk", "aclk_disp_333", }; + +PNAME(mout_phyclk_mipidphy1_bitclkdiv8_user_p) = { "oscclk", + "phyclk_mipidphy1_bitclkdiv8_phy", }; +PNAME(mout_phyclk_mipidphy1_rxclkesc0_user_p) = { "oscclk", + "phyclk_mipidphy1_rxclkesc0_phy", }; +PNAME(mout_phyclk_mipidphy0_bitclkdiv8_user_p) = { "oscclk", + "phyclk_mipidphy0_bitclkdiv8_phy", }; +PNAME(mout_phyclk_mipidphy0_rxclkesc0_user_p) = { "oscclk", + "phyclk_mipidphy0_rxclkesc0_phy", }; +PNAME(mout_phyclk_hdmiphy_tmds_clko_user_p) = { "oscclk", + "phyclk_hdmiphy_tmds_clko_phy", }; +PNAME(mout_phyclk_hdmiphy_pixel_clko_user_p) = { "oscclk", + "phyclk_hdmiphy_pixel_clko_phy", }; + +PNAME(mout_sclk_dsim0_p) = { "mout_disp_pll", + "mout_sclk_dsim0_user", }; +PNAME(mout_sclk_decon_tv_eclk_p) = { "mout_disp_pll", + "mout_sclk_decon_tv_eclk_user", }; +PNAME(mout_sclk_decon_vclk_p) = { "mout_disp_pll", + "mout_sclk_decon_vclk_user", }; +PNAME(mout_sclk_decon_eclk_p) = { "mout_disp_pll", + "mout_sclk_decon_eclk_user", }; + +PNAME(mout_sclk_dsim1_b_disp_p) = { "mout_sclk_dsim1_a_disp", + "mout_sclk_dsim1_user", }; +PNAME(mout_sclk_decon_tv_vclk_c_disp_p) = { + "mout_phyclk_hdmiphy_pixel_clko_user", + "mout_sclk_decon_tv_vclk_b_disp", }; +PNAME(mout_sclk_decon_tv_vclk_b_disp_p) = { "mout_sclk_decon_tv_vclk_a_disp", + "mout_sclk_decon_tv_vclk_user", }; + +static struct samsung_pll_clock disp_pll_clks[] __initdata = { + PLL(pll_35xx, CLK_FOUT_DISP_PLL, "fout_disp_pll", "oscclk", + DISP_PLL_LOCK, DISP_PLL_CON0, exynos5443_pll_rates), +}; + +static struct samsung_fixed_factor_clock disp_fixed_factor_clks[] __initdata = { + /* + * sclk_rgb_{vclk|tv_vclk} is half clock of sclk_decon_{vclk|tv_vclk}. + * The divider has fixed value (2) between sclk_rgb_{vclk|tv_vclk} + * and sclk_decon_{vclk|tv_vclk}. + */ + FFACTOR(CLK_SCLK_RGB_VCLK, "sclk_rgb_vclk", "sclk_decon_vclk", + 1, 2, 0), + FFACTOR(CLK_SCLK_RGB_TV_VCLK, "sclk_rgb_tv_vclk", "sclk_decon_tv_vclk", + 1, 2, 0), +}; + +static struct samsung_fixed_rate_clock disp_fixed_clks[] __initdata = { + /* PHY clocks from MIPI_DPHY1 */ + FRATE(0, "phyclk_mipidphy1_bitclkdiv8_phy", NULL, CLK_IS_ROOT, + 188000000), + FRATE(0, "phyclk_mipidphy1_rxclkesc0_phy", NULL, CLK_IS_ROOT, + 100000000), + /* PHY clocks from MIPI_DPHY0 */ + FRATE(0, "phyclk_mipidphy0_bitclkdiv8_phy", NULL, CLK_IS_ROOT, + 188000000), + FRATE(0, "phyclk_mipidphy0_rxclkesc0_phy", NULL, CLK_IS_ROOT, + 100000000), + /* PHY clocks from HDMI_PHY */ + FRATE(0, "phyclk_hdmiphy_tmds_clko_phy", NULL, CLK_IS_ROOT, 300000000), + FRATE(0, "phyclk_hdmiphy_pixel_clko_phy", NULL, CLK_IS_ROOT, 166000000), +}; + +static struct samsung_mux_clock disp_mux_clks[] __initdata = { + /* MUX_SEL_DISP0 */ + MUX(CLK_MOUT_DISP_PLL, "mout_disp_pll", mout_disp_pll_p, MUX_SEL_DISP0, + 0, 1), + + /* MUX_SEL_DISP1 */ + MUX(CLK_MOUT_SCLK_DSIM1_USER, "mout_sclk_dsim1_user", + mout_sclk_dsim1_user_p, MUX_SEL_DISP1, 28, 1), + MUX(CLK_MOUT_SCLK_DSIM0_USER, "mout_sclk_dsim0_user", + mout_sclk_dsim0_user_p, MUX_SEL_DISP1, 24, 1), + MUX(CLK_MOUT_SCLK_DSD_USER, "mout_sclk_dsd_user", mout_sclk_dsd_user_p, + MUX_SEL_DISP1, 20, 1), + MUX(CLK_MOUT_SCLK_DECON_TV_ECLK_USER, "mout_sclk_decon_tv_eclk_user", + mout_sclk_decon_tv_eclk_user_p, MUX_SEL_DISP1, 16, 1), + MUX(CLK_MOUT_SCLK_DECON_VCLK_USER, "mout_sclk_decon_vclk_user", + mout_sclk_decon_vclk_user_p, MUX_SEL_DISP1, 12, 1), + MUX(CLK_MOUT_SCLK_DECON_ECLK_USER, "mout_sclk_decon_eclk_user", + mout_sclk_decon_eclk_user_p, MUX_SEL_DISP1, 8, 1), + MUX(CLK_MOUT_SCLK_DECON_TV_VCLK_USER, "mout_sclk_decon_tv_vclk_user", + mout_sclk_decon_tv_vlkc_user_p, MUX_SEL_DISP1, 4, 1), + MUX(CLK_MOUT_ACLK_DISP_333_USER, "mout_aclk_disp_333_user", + mout_aclk_disp_333_user_p, MUX_SEL_DISP1, 0, 1), + + /* MUX_SEL_DISP2 */ + MUX(CLK_MOUT_PHYCLK_MIPIDPHY1_BITCLKDIV8_USER, + "mout_phyclk_mipidphy1_bitclkdiv8_user", + mout_phyclk_mipidphy1_bitclkdiv8_user_p, MUX_SEL_DISP2, + 20, 1), + MUX(CLK_MOUT_PHYCLK_MIPIDPHY1_RXCLKESC0_USER, + "mout_phyclk_mipidphy1_rxclkesc0_user", + mout_phyclk_mipidphy1_rxclkesc0_user_p, MUX_SEL_DISP2, + 16, 1), + MUX(CLK_MOUT_PHYCLK_MIPIDPHY0_BITCLKDIV8_USER, + "mout_phyclk_mipidphy0_bitclkdiv8_user", + mout_phyclk_mipidphy0_bitclkdiv8_user_p, MUX_SEL_DISP2, + 12, 1), + MUX(CLK_MOUT_PHYCLK_MIPIDPHY0_RXCLKESC0_USER, + "mout_phyclk_mipidphy0_rxclkesc0_user", + mout_phyclk_mipidphy0_rxclkesc0_user_p, MUX_SEL_DISP2, + 8, 1), + MUX(CLK_MOUT_PHYCLK_HDMIPHY_TMDS_CLKO_USER, + "mout_phyclk_hdmiphy_tmds_clko_user", + mout_phyclk_hdmiphy_tmds_clko_user_p, MUX_SEL_DISP2, + 4, 1), + MUX(CLK_MOUT_PHYCLK_HDMIPHY_PIXEL_CLKO_USER, + "mout_phyclk_hdmiphy_pixel_clko_user", + mout_phyclk_hdmiphy_pixel_clko_user_p, MUX_SEL_DISP2, + 0, 1), + + /* MUX_SEL_DISP3 */ + MUX(CLK_MOUT_SCLK_DSIM0, "mout_sclk_dsim0", mout_sclk_dsim0_p, + MUX_SEL_DISP3, 12, 1), + MUX(CLK_MOUT_SCLK_DECON_TV_ECLK, "mout_sclk_decon_tv_eclk", + mout_sclk_decon_tv_eclk_p, MUX_SEL_DISP3, 8, 1), + MUX(CLK_MOUT_SCLK_DECON_VCLK, "mout_sclk_decon_vclk", + mout_sclk_decon_vclk_p, MUX_SEL_DISP3, 4, 1), + MUX(CLK_MOUT_SCLK_DECON_ECLK, "mout_sclk_decon_eclk", + mout_sclk_decon_eclk_p, MUX_SEL_DISP3, 0, 1), + + /* MUX_SEL_DISP4 */ + MUX(CLK_MOUT_SCLK_DSIM1_B_DISP, "mout_sclk_dsim1_b_disp", + mout_sclk_dsim1_b_disp_p, MUX_SEL_DISP4, 16, 1), + MUX(CLK_MOUT_SCLK_DSIM1_A_DISP, "mout_sclk_dsim1_a_disp", + mout_sclk_dsim0_p, MUX_SEL_DISP4, 12, 1), + MUX(CLK_MOUT_SCLK_DECON_TV_VCLK_C_DISP, + "mout_sclk_decon_tv_vclk_c_disp", + mout_sclk_decon_tv_vclk_c_disp_p, MUX_SEL_DISP4, 8, 1), + MUX(CLK_MOUT_SCLK_DECON_TV_VCLK_B_DISP, + "mout_sclk_decon_tv_vclk_b_disp", + mout_sclk_decon_tv_vclk_b_disp_p, MUX_SEL_DISP4, 4, 1), + MUX(CLK_MOUT_SCLK_DECON_TV_VCLK_A_DISP, + "mout_sclk_decon_tv_vclk_a_disp", + mout_sclk_decon_vclk_p, MUX_SEL_DISP4, 0, 1), +}; + +static struct samsung_div_clock disp_div_clks[] __initdata = { + /* DIV_DISP */ + DIV(CLK_DIV_SCLK_DSIM1_DISP, "div_sclk_dsim1_disp", + "mout_sclk_dsim1_b_disp", DIV_DISP, 24, 3), + DIV(CLK_DIV_SCLK_DECON_TV_VCLK_DISP, "div_sclk_decon_tv_vclk_disp", + "mout_sclk_decon_tv_vclk_c_disp", DIV_DISP, 20, 3), + DIV(CLK_DIV_SCLK_DSIM0_DISP, "div_sclk_dsim0_disp", "mout_sclk_dsim0", + DIV_DISP, 16, 3), + DIV(CLK_DIV_SCLK_DECON_TV_ECLK_DISP, "div_sclk_decon_tv_eclk_disp", + "mout_sclk_decon_tv_eclk", DIV_DISP, 12, 3), + DIV(CLK_DIV_SCLK_DECON_VCLK_DISP, "div_sclk_decon_vclk_disp", + "mout_sclk_decon_vclk", DIV_DISP, 8, 3), + DIV(CLK_DIV_SCLK_DECON_ECLK_DISP, "div_sclk_decon_eclk_disp", + "mout_sclk_decon_eclk", DIV_DISP, 4, 3), + DIV(CLK_DIV_PCLK_DISP, "div_pclk_disp", "mout_aclk_disp_333_user", + DIV_DISP, 0, 2), +}; + +static struct samsung_gate_clock disp_gate_clks[] __initdata = { + /* ENABLE_ACLK_DISP0 */ + GATE(CLK_ACLK_DECON_TV, "aclk_decon_tv", "mout_aclk_disp_333_user", + ENABLE_ACLK_DISP0, 2, 0, 0), + GATE(CLK_ACLK_DECON, "aclk_decon", "mout_aclk_disp_333_user", + ENABLE_ACLK_DISP0, 0, 0, 0), + + /* ENABLE_ACLK_DISP1 */ + GATE(CLK_ACLK_SMMU_TV1X, "aclk_smmu_tv1x", "mout_aclk_disp_333_user", + ENABLE_ACLK_DISP1, 25, 0, 0), + GATE(CLK_ACLK_SMMU_TV0X, "aclk_smmu_tv0x", "mout_aclk_disp_333_user", + ENABLE_ACLK_DISP1, 24, 0, 0), + GATE(CLK_ACLK_SMMU_DECON1X, "aclk_smmu_decon1x", + "mout_aclk_disp_333_user", ENABLE_ACLK_DISP1, 23, 0, 0), + GATE(CLK_ACLK_SMMU_DECON0X, "aclk_smmu_decon0x", + "mout_aclk_disp_333_user", ENABLE_ACLK_DISP1, 22, 0, 0), + GATE(CLK_ACLK_BTS_DECON_TV_M3, "aclk_bts_decon_tv_m3", + "mout_aclk_disp_333_user", ENABLE_ACLK_DISP1, 21, 0, 0), + GATE(CLK_ACLK_BTS_DECON_TV_M2, "aclk_bts_decon_tv_m2", + "mout_aclk_disp_333_user", ENABLE_ACLK_DISP1, 20, 0, 0), + GATE(CLK_ACLK_BTS_DECON_TV_M1, "aclk_bts_decon_tv_m1", + "mout_aclk_disp_333_user", ENABLE_ACLK_DISP1, 19, 0, 0), + GATE(CLK_ACLK_BTS_DECON_TV_M0, "aclk-bts_decon_tv_m0", + "mout_aclk_disp_333_user", ENABLE_ACLK_DISP1, 18, 0, 0), + GATE(CLK_ACLK_BTS_DECON_NM4, "aclk_bts_decon_nm4", + "mout_aclk_disp_333_user", ENABLE_ACLK_DISP1, 17, 0, 0), + GATE(CLK_ACLK_BTS_DECON_NM3, "aclk_bts_decon_nm3", + "mout_aclk_disp_333_user", ENABLE_ACLK_DISP1, 16, 0, 0), + GATE(CLK_ACLK_BTS_DECON_NM2, "aclk_bts_decon_nm2", + "mout_aclk_disp_333_user", ENABLE_ACLK_DISP1, 15, 0, 0), + GATE(CLK_ACLK_BTS_DECON_NM1, "aclk_bts_decon_nm1", + "mout_aclk_disp_333_user", ENABLE_ACLK_DISP1, 14, 0, 0), + GATE(CLK_ACLK_BTS_DECON_NM0, "aclk_bts_decon_nm0", + "mout_aclk_disp_333_user", ENABLE_ACLK_DISP1, 13, 0, 0), + GATE(CLK_ACLK_AHB2APB_DISPSFR2P, "aclk_ahb2apb_dispsfr2p", + "div_pclk_disp", ENABLE_ACLK_DISP1, + 12, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_AHB2APB_DISPSFR1P, "aclk_ahb2apb_dispsfr1p", + "div_pclk_disp", ENABLE_ACLK_DISP1, + 11, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_AHB2APB_DISPSFR0P, "aclk_ahb2apb_dispsfr0p", + "div_pclk_disp", ENABLE_ACLK_DISP1, + 10, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_AHB_DISPH, "aclk_ahb_disph", "div_pclk_disp", + ENABLE_ACLK_DISP1, 8, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_XIU_TV1X, "aclk_xiu_tv1x", "mout_aclk_disp_333_user", + ENABLE_ACLK_DISP1, 7, 0, 0), + GATE(CLK_ACLK_XIU_TV0X, "aclk_xiu_tv0x", "mout_aclk_disp_333_user", + ENABLE_ACLK_DISP1, 6, 0, 0), + GATE(CLK_ACLK_XIU_DECON1X, "aclk_xiu_decon1x", + "mout_aclk_disp_333_user", ENABLE_ACLK_DISP1, 5, 0, 0), + GATE(CLK_ACLK_XIU_DECON0X, "aclk_xiu_decon0x", + "mout_aclk_disp_333_user", ENABLE_ACLK_DISP1, 4, 0, 0), + GATE(CLK_ACLK_XIU_DISP1X, "aclk_xiu_disp1x", "mout_aclk_disp_333_user", + ENABLE_ACLK_DISP1, 3, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_XIU_DISPNP_100, "aclk_xiu_dispnp_100", "div_pclk_disp", + ENABLE_ACLK_DISP1, 2, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_DISP1ND_333, "aclk_disp1nd_333", + "mout_aclk_disp_333_user", ENABLE_ACLK_DISP1, 1, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_DISP0ND_333, "aclk_disp0nd_333", + "mout_aclk_disp_333_user", ENABLE_ACLK_DISP1, + 0, CLK_IGNORE_UNUSED, 0), + + /* ENABLE_PCLK_DISP */ + GATE(CLK_PCLK_SMMU_TV1X, "pclk_smmu_tv1x", "div_pclk_disp", + ENABLE_PCLK_DISP, 23, 0, 0), + GATE(CLK_PCLK_SMMU_TV0X, "pclk_smmu_tv0x", "div_pclk_disp", + ENABLE_PCLK_DISP, 22, 0, 0), + GATE(CLK_PCLK_SMMU_DECON1X, "pclk_smmu_decon1x", "div_pclk_disp", + ENABLE_PCLK_DISP, 21, 0, 0), + GATE(CLK_PCLK_SMMU_DECON0X, "pclk_smmu_decon0x", "div_pclk_disp", + ENABLE_PCLK_DISP, 20, 0, 0), + GATE(CLK_PCLK_BTS_DECON_TV_M3, "pclk_bts_decon_tv_m3", "div_pclk_disp", + ENABLE_PCLK_DISP, 19, 0, 0), + GATE(CLK_PCLK_BTS_DECON_TV_M2, "pclk_bts_decon_tv_m2", "div_pclk_disp", + ENABLE_PCLK_DISP, 18, 0, 0), + GATE(CLK_PCLK_BTS_DECON_TV_M1, "pclk_bts_decon_tv_m1", "div_pclk_disp", + ENABLE_PCLK_DISP, 17, 0, 0), + GATE(CLK_PCLK_BTS_DECON_TV_M0, "pclk_bts_decon_tv_m0", "div_pclk_disp", + ENABLE_PCLK_DISP, 16, 0, 0), + GATE(CLK_PCLK_BTS_DECONM4, "pclk_bts_deconm4", "div_pclk_disp", + ENABLE_PCLK_DISP, 15, 0, 0), + GATE(CLK_PCLK_BTS_DECONM3, "pclk_bts_deconm3", "div_pclk_disp", + ENABLE_PCLK_DISP, 14, 0, 0), + GATE(CLK_PCLK_BTS_DECONM2, "pclk_bts_deconm2", "div_pclk_disp", + ENABLE_PCLK_DISP, 13, 0, 0), + GATE(CLK_PCLK_BTS_DECONM1, "pclk_bts_deconm1", "div_pclk_disp", + ENABLE_PCLK_DISP, 12, 0, 0), + GATE(CLK_PCLK_BTS_DECONM0, "pclk_bts_deconm0", "div_pclk_disp", + ENABLE_PCLK_DISP, 11, 0, 0), + GATE(CLK_PCLK_MIC1, "pclk_mic1", "div_pclk_disp", + ENABLE_PCLK_DISP, 10, 0, 0), + GATE(CLK_PCLK_PMU_DISP, "pclk_pmu_disp", "div_pclk_disp", + ENABLE_PCLK_DISP, 9, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_SYSREG_DISP, "pclk_sysreg_disp", "div_pclk_disp", + ENABLE_PCLK_DISP, 8, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_HDMIPHY, "pclk_hdmiphy", "div_pclk_disp", + ENABLE_PCLK_DISP, 7, 0, 0), + GATE(CLK_PCLK_HDMI, "pclk_hdmi", "div_pclk_disp", + ENABLE_PCLK_DISP, 6, 0, 0), + GATE(CLK_PCLK_MIC0, "pclk_mic0", "div_pclk_disp", + ENABLE_PCLK_DISP, 5, 0, 0), + GATE(CLK_PCLK_DSIM1, "pclk_dsim1", "div_pclk_disp", + ENABLE_PCLK_DISP, 3, 0, 0), + GATE(CLK_PCLK_DSIM0, "pclk_dsim0", "div_pclk_disp", + ENABLE_PCLK_DISP, 2, 0, 0), + GATE(CLK_PCLK_DECON_TV, "pclk_decon_tv", "div_pclk_disp", + ENABLE_PCLK_DISP, 1, 0, 0), + + /* ENABLE_SCLK_DISP */ + GATE(CLK_PHYCLK_MIPIDPHY1_BITCLKDIV8, "phyclk_mipidphy1_bitclkdiv8", + "mout_phyclk_mipidphy1_bitclkdiv8_user", + ENABLE_SCLK_DISP, 26, 0, 0), + GATE(CLK_PHYCLK_MIPIDPHY1_RXCLKESC0, "phyclk_mipidphy1_rxclkesc0", + "mout_phyclk_mipidphy1_rxclkesc0_user", + ENABLE_SCLK_DISP, 25, 0, 0), + GATE(CLK_SCLK_RGB_TV_VCLK_TO_DSIM1, "sclk_rgb_tv_vclk_to_dsim1", + "sclk_rgb_tv_vclk", ENABLE_SCLK_DISP, 24, 0, 0), + GATE(CLK_SCLK_RGB_TV_VCLK_TO_MIC1, "sclk_rgb_tv_vclk_to_mic1", + "sclk_rgb_tv_vclk", ENABLE_SCLK_DISP, 23, 0, 0), + GATE(CLK_SCLK_DSIM1, "sclk_dsim1", "div_sclk_dsim1_disp", + ENABLE_SCLK_DISP, 22, 0, 0), + GATE(CLK_SCLK_DECON_TV_VCLK, "sclk_decon_tv_vclk", + "div_sclk_decon_tv_vclk_disp", + ENABLE_SCLK_DISP, 21, 0, 0), + GATE(CLK_PHYCLK_MIPIDPHY0_BITCLKDIV8, "phyclk_mipidphy0_bitclkdiv8", + "mout_phyclk_mipidphy0_bitclkdiv8_user", + ENABLE_SCLK_DISP, 15, 0, 0), + GATE(CLK_PHYCLK_MIPIDPHY0_RXCLKESC0, "phyclk_mipidphy0_rxclkesc0", + "mout_phyclk_mipidphy0_rxclkesc0_user", + ENABLE_SCLK_DISP, 14, 0, 0), + GATE(CLK_PHYCLK_HDMIPHY_TMDS_CLKO, "phyclk_hdmiphy_tmds_clko", + "mout_phyclk_hdmiphy_tmds_clko_user", + ENABLE_SCLK_DISP, 13, 0, 0), + GATE(CLK_PHYCLK_HDMI_PIXEL, "phyclk_hdmi_pixel", + "sclk_rgb_tv_vclk", ENABLE_SCLK_DISP, 12, 0, 0), + GATE(CLK_SCLK_RGB_VCLK_TO_SMIES, "sclk_rgb_vclk_to_smies", + "sclk_rgb_vclk", ENABLE_SCLK_DISP, 11, 0, 0), + GATE(CLK_SCLK_RGB_VCLK_TO_DSIM0, "sclk_rgb_vclk_to_dsim0", + "sclk_rgb_vclk", ENABLE_SCLK_DISP, 9, 0, 0), + GATE(CLK_SCLK_RGB_VCLK_TO_MIC0, "sclk_rgb_vclk_to_mic0", + "sclk_rgb_vclk", ENABLE_SCLK_DISP, 8, 0, 0), + GATE(CLK_SCLK_DSD, "sclk_dsd", "mout_sclk_dsd_user", + ENABLE_SCLK_DISP, 7, 0, 0), + GATE(CLK_SCLK_HDMI_SPDIF, "sclk_hdmi_spdif", "sclk_hdmi_spdif_disp", + ENABLE_SCLK_DISP, 6, 0, 0), + GATE(CLK_SCLK_DSIM0, "sclk_dsim0", "div_sclk_dsim0_disp", + ENABLE_SCLK_DISP, 5, 0, 0), + GATE(CLK_SCLK_DECON_TV_ECLK, "sclk_decon_tv_eclk", + "div_sclk_decon_tv_eclk_disp", + ENABLE_SCLK_DISP, 4, 0, 0), + GATE(CLK_SCLK_DECON_VCLK, "sclk_decon_vclk", + "div_sclk_decon_vclk_disp", ENABLE_SCLK_DISP, 3, 0, 0), + GATE(CLK_SCLK_DECON_ECLK, "sclk_decon_eclk", + "div_sclk_decon_eclk_disp", ENABLE_SCLK_DISP, 2, 0, 0), +}; + +static struct samsung_cmu_info disp_cmu_info __initdata = { + .pll_clks = disp_pll_clks, + .nr_pll_clks = ARRAY_SIZE(disp_pll_clks), + .mux_clks = disp_mux_clks, + .nr_mux_clks = ARRAY_SIZE(disp_mux_clks), + .div_clks = disp_div_clks, + .nr_div_clks = ARRAY_SIZE(disp_div_clks), + .gate_clks = disp_gate_clks, + .nr_gate_clks = ARRAY_SIZE(disp_gate_clks), + .fixed_clks = disp_fixed_clks, + .nr_fixed_clks = ARRAY_SIZE(disp_fixed_clks), + .fixed_factor_clks = disp_fixed_factor_clks, + .nr_fixed_factor_clks = ARRAY_SIZE(disp_fixed_factor_clks), + .nr_clk_ids = DISP_NR_CLK, + .clk_regs = disp_clk_regs, + .nr_clk_regs = ARRAY_SIZE(disp_clk_regs), +}; + +static void __init exynos5433_cmu_disp_init(struct device_node *np) +{ + samsung_cmu_register_one(np, &disp_cmu_info); +} + +CLK_OF_DECLARE(exynos5433_cmu_disp, "samsung,exynos5433-cmu-disp", + exynos5433_cmu_disp_init); diff --git a/include/dt-bindings/clock/exynos5433.h b/include/dt-bindings/clock/exynos5433.h index 6a3ce113e1e5..fe0650fad766 100644 --- a/include/dt-bindings/clock/exynos5433.h +++ b/include/dt-bindings/clock/exynos5433.h @@ -68,6 +68,7 @@ #define CLK_MOUT_SCLK_SPDIF 61 #define CLK_MOUT_SCLK_AUDIO1 62 #define CLK_MOUT_SCLK_AUDIO0 63 +#define CLK_MOUT_SCLK_HDMI_SPDIF 64 #define CLK_DIV_ACLK_FSYS_200 100 #define CLK_DIV_ACLK_IMEM_SSSX_266 101 @@ -337,8 +338,9 @@ #define CLK_SCLK_BUS_PLL 198 #define CLK_SCLK_BUS_PLL_APOLLO 199 #define CLK_SCLK_BUS_PLL_ATLAS 200 +#define CLK_SCLK_HDMI_SPDIF_DISP 201 -#define MIF_NR_CLK 201 +#define MIF_NR_CLK 202 /* CMU_PERIC */ #define CLK_PCLK_SPI2 1 @@ -514,4 +516,114 @@ #define G2D_NR_CLK 27 +/* CMU_DISP */ +#define CLK_FOUT_DISP_PLL 1 + +#define CLK_MOUT_DISP_PLL 2 +#define CLK_MOUT_SCLK_DSIM1_USER 3 +#define CLK_MOUT_SCLK_DSIM0_USER 4 +#define CLK_MOUT_SCLK_DSD_USER 5 +#define CLK_MOUT_SCLK_DECON_TV_ECLK_USER 6 +#define CLK_MOUT_SCLK_DECON_VCLK_USER 7 +#define CLK_MOUT_SCLK_DECON_ECLK_USER 8 +#define CLK_MOUT_SCLK_DECON_TV_VCLK_USER 9 +#define CLK_MOUT_ACLK_DISP_333_USER 10 +#define CLK_MOUT_PHYCLK_MIPIDPHY1_BITCLKDIV8_USER 11 +#define CLK_MOUT_PHYCLK_MIPIDPHY1_RXCLKESC0_USER 12 +#define CLK_MOUT_PHYCLK_MIPIDPHY0_BITCLKDIV8_USER 13 +#define CLK_MOUT_PHYCLK_MIPIDPHY0_RXCLKESC0_USER 14 +#define CLK_MOUT_PHYCLK_HDMIPHY_TMDS_CLKO_USER 15 +#define CLK_MOUT_PHYCLK_HDMIPHY_PIXEL_CLKO_USER 16 +#define CLK_MOUT_SCLK_DSIM0 17 +#define CLK_MOUT_SCLK_DECON_TV_ECLK 18 +#define CLK_MOUT_SCLK_DECON_VCLK 19 +#define CLK_MOUT_SCLK_DECON_ECLK 20 +#define CLK_MOUT_SCLK_DSIM1_B_DISP 21 +#define CLK_MOUT_SCLK_DSIM1_A_DISP 22 +#define CLK_MOUT_SCLK_DECON_TV_VCLK_C_DISP 23 +#define CLK_MOUT_SCLK_DECON_TV_VCLK_B_DISP 24 +#define CLK_MOUT_SCLK_DECON_TV_VCLK_A_DISP 25 + +#define CLK_DIV_SCLK_DSIM1_DISP 30 +#define CLK_DIV_SCLK_DECON_TV_VCLK_DISP 31 +#define CLK_DIV_SCLK_DSIM0_DISP 32 +#define CLK_DIV_SCLK_DECON_TV_ECLK_DISP 33 +#define CLK_DIV_SCLK_DECON_VCLK_DISP 34 +#define CLK_DIV_SCLK_DECON_ECLK_DISP 35 +#define CLK_DIV_PCLK_DISP 36 + +#define CLK_ACLK_DECON_TV 40 +#define CLK_ACLK_DECON 41 +#define CLK_ACLK_SMMU_TV1X 42 +#define CLK_ACLK_SMMU_TV0X 43 +#define CLK_ACLK_SMMU_DECON1X 44 +#define CLK_ACLK_SMMU_DECON0X 45 +#define CLK_ACLK_BTS_DECON_TV_M3 46 +#define CLK_ACLK_BTS_DECON_TV_M2 47 +#define CLK_ACLK_BTS_DECON_TV_M1 48 +#define CLK_ACLK_BTS_DECON_TV_M0 49 +#define CLK_ACLK_BTS_DECON_NM4 50 +#define CLK_ACLK_BTS_DECON_NM3 51 +#define CLK_ACLK_BTS_DECON_NM2 52 +#define CLK_ACLK_BTS_DECON_NM1 53 +#define CLK_ACLK_BTS_DECON_NM0 54 +#define CLK_ACLK_AHB2APB_DISPSFR2P 55 +#define CLK_ACLK_AHB2APB_DISPSFR1P 56 +#define CLK_ACLK_AHB2APB_DISPSFR0P 57 +#define CLK_ACLK_AHB_DISPH 58 +#define CLK_ACLK_XIU_TV1X 59 +#define CLK_ACLK_XIU_TV0X 60 +#define CLK_ACLK_XIU_DECON1X 61 +#define CLK_ACLK_XIU_DECON0X 62 +#define CLK_ACLK_XIU_DISP1X 63 +#define CLK_ACLK_XIU_DISPNP_100 64 +#define CLK_ACLK_DISP1ND_333 65 +#define CLK_ACLK_DISP0ND_333 66 +#define CLK_PCLK_SMMU_TV1X 67 +#define CLK_PCLK_SMMU_TV0X 68 +#define CLK_PCLK_SMMU_DECON1X 69 +#define CLK_PCLK_SMMU_DECON0X 70 +#define CLK_PCLK_BTS_DECON_TV_M3 71 +#define CLK_PCLK_BTS_DECON_TV_M2 72 +#define CLK_PCLK_BTS_DECON_TV_M1 73 +#define CLK_PCLK_BTS_DECON_TV_M0 74 +#define CLK_PCLK_BTS_DECONM4 75 +#define CLK_PCLK_BTS_DECONM3 76 +#define CLK_PCLK_BTS_DECONM2 77 +#define CLK_PCLK_BTS_DECONM1 78 +#define CLK_PCLK_BTS_DECONM0 79 +#define CLK_PCLK_MIC1 80 +#define CLK_PCLK_PMU_DISP 81 +#define CLK_PCLK_SYSREG_DISP 82 +#define CLK_PCLK_HDMIPHY 83 +#define CLK_PCLK_HDMI 84 +#define CLK_PCLK_MIC0 85 +#define CLK_PCLK_DSIM1 86 +#define CLK_PCLK_DSIM0 87 +#define CLK_PCLK_DECON_TV 88 +#define CLK_PHYCLK_MIPIDPHY1_BITCLKDIV8 89 +#define CLK_PHYCLK_MIPIDPHY1_RXCLKESC0 90 +#define CLK_SCLK_RGB_TV_VCLK_TO_DSIM1 91 +#define CLK_SCLK_RGB_TV_VCLK_TO_MIC1 92 +#define CLK_SCLK_DSIM1 93 +#define CLK_SCLK_DECON_TV_VCLK 94 +#define CLK_PHYCLK_MIPIDPHY0_BITCLKDIV8 95 +#define CLK_PHYCLK_MIPIDPHY0_RXCLKESC0 96 +#define CLK_PHYCLK_HDMIPHY_TMDS_CLKO 97 +#define CLK_PHYCLK_HDMI_PIXEL 98 +#define CLK_SCLK_RGB_VCLK_TO_SMIES 99 +#define CLK_SCLK_FREQ_DET_DISP_PLL 100 +#define CLK_SCLK_RGB_VCLK_TO_DSIM0 101 +#define CLK_SCLK_RGB_VCLK_TO_MIC0 102 +#define CLK_SCLK_DSD 103 +#define CLK_SCLK_HDMI_SPDIF 104 +#define CLK_SCLK_DSIM0 105 +#define CLK_SCLK_DECON_TV_ECLK 106 +#define CLK_SCLK_DECON_VCLK 107 +#define CLK_SCLK_DECON_ECLK 108 +#define CLK_SCLK_RGB_VCLK 109 +#define CLK_SCLK_RGB_TV_VCLK 110 + +#define DISP_NR_CLK 111 + #endif /* _DT_BINDINGS_CLOCK_EXYNOS5433_H */ -- GitLab From 2e997c035945784fb8c564305c0f0ddacc374fe4 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Mon, 2 Feb 2015 23:24:03 +0900 Subject: [PATCH 00041/11651] clk: samsung: exynos5433: Add clocks for CMU_AUD domain This patch adds the mux/divider/gate clocks for CMU_AUD domain which includes the clocks of Cortex-A5/Bus/Audio clocks. Signed-off-by: Chanwoo Choi Acked-by: Inki Dae Signed-off-by: Sylwester Nawrocki --- drivers/clk/samsung/clk-exynos5433.c | 172 +++++++++++++++++++++++++ include/dt-bindings/clock/exynos5433.h | 53 ++++++++ 2 files changed, 225 insertions(+) diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c index 3e6c3d595e96..ad0105aa0de6 100644 --- a/drivers/clk/samsung/clk-exynos5433.c +++ b/drivers/clk/samsung/clk-exynos5433.c @@ -2459,3 +2459,175 @@ static void __init exynos5433_cmu_disp_init(struct device_node *np) CLK_OF_DECLARE(exynos5433_cmu_disp, "samsung,exynos5433-cmu-disp", exynos5433_cmu_disp_init); + +/* + * Register offset definitions for CMU_AUD + */ +#define MUX_SEL_AUD0 0x0200 +#define MUX_SEL_AUD1 0x0204 +#define MUX_ENABLE_AUD0 0x0300 +#define MUX_ENABLE_AUD1 0x0304 +#define MUX_STAT_AUD0 0x0400 +#define DIV_AUD0 0x0600 +#define DIV_AUD1 0x0604 +#define DIV_STAT_AUD0 0x0700 +#define DIV_STAT_AUD1 0x0704 +#define ENABLE_ACLK_AUD 0x0800 +#define ENABLE_PCLK_AUD 0x0900 +#define ENABLE_SCLK_AUD0 0x0a00 +#define ENABLE_SCLK_AUD1 0x0a04 +#define ENABLE_IP_AUD0 0x0b00 +#define ENABLE_IP_AUD1 0x0b04 + +static unsigned long aud_clk_regs[] __initdata = { + MUX_SEL_AUD0, + MUX_SEL_AUD1, + MUX_ENABLE_AUD0, + MUX_ENABLE_AUD1, + MUX_STAT_AUD0, + DIV_AUD0, + DIV_AUD1, + DIV_STAT_AUD0, + DIV_STAT_AUD1, + ENABLE_ACLK_AUD, + ENABLE_PCLK_AUD, + ENABLE_SCLK_AUD0, + ENABLE_SCLK_AUD1, + ENABLE_IP_AUD0, + ENABLE_IP_AUD1, +}; + +/* list of all parent clock list */ +PNAME(mout_aud_pll_user_aud_p) = { "oscclk", "fout_aud_pll", }; +PNAME(mout_sclk_aud_pcm_p) = { "mout_aud_pll_user", "ioclk_audiocdclk0",}; + +static struct samsung_fixed_rate_clock aud_fixed_clks[] __initdata = { + FRATE(0, "ioclk_jtag_tclk", NULL, CLK_IS_ROOT, 33000000), + FRATE(0, "ioclk_slimbus_clk", NULL, CLK_IS_ROOT, 25000000), + FRATE(0, "ioclk_i2s_bclk", NULL, CLK_IS_ROOT, 50000000), +}; + +static struct samsung_mux_clock aud_mux_clks[] __initdata = { + /* MUX_SEL_AUD0 */ + MUX(CLK_MOUT_AUD_PLL_USER, "mout_aud_pll_user", + mout_aud_pll_user_aud_p, MUX_SEL_AUD0, 0, 1), + + /* MUX_SEL_AUD1 */ + MUX(CLK_MOUT_SCLK_AUD_PCM, "mout_sclk_aud_pcm", mout_sclk_aud_pcm_p, + MUX_SEL_AUD1, 8, 1), + MUX(CLK_MOUT_SCLK_AUD_I2S, "mout_sclk_aud_i2s", mout_sclk_aud_pcm_p, + MUX_SEL_AUD1, 0, 1), +}; + +static struct samsung_div_clock aud_div_clks[] __initdata = { + /* DIV_AUD0 */ + DIV(CLK_DIV_ATCLK_AUD, "div_atclk_aud", "div_aud_ca5", DIV_AUD0, + 12, 4), + DIV(CLK_DIV_PCLK_DBG_AUD, "div_pclk_dbg_aud", "div_aud_ca5", DIV_AUD0, + 8, 4), + DIV(CLK_DIV_ACLK_AUD, "div_aclk_aud", "div_aud_ca5", DIV_AUD0, + 4, 4), + DIV(CLK_DIV_AUD_CA5, "div_aud_ca5", "mout_aud_pll_user", DIV_AUD0, + 0, 4), + + /* DIV_AUD1 */ + DIV(CLK_DIV_SCLK_AUD_SLIMBUS, "div_sclk_aud_slimbus", + "mout_aud_pll_user", DIV_AUD1, 16, 5), + DIV(CLK_DIV_SCLK_AUD_UART, "div_sclk_aud_uart", "mout_aud_pll_user", + DIV_AUD1, 12, 4), + DIV(CLK_DIV_SCLK_AUD_PCM, "div_sclk_aud_pcm", "mout_sclk_aud_pcm", + DIV_AUD1, 4, 8), + DIV(CLK_DIV_SCLK_AUD_I2S, "div_sclk_aud_i2s", "mout_sclk_aud_i2s", + DIV_AUD1, 0, 4), +}; + +static struct samsung_gate_clock aud_gate_clks[] __initdata = { + /* ENABLE_ACLK_AUD */ + GATE(CLK_ACLK_INTR_CTRL, "aclk_intr_ctrl", "div_aclk_aud", + ENABLE_ACLK_AUD, 12, 0, 0), + GATE(CLK_ACLK_SMMU_LPASSX, "aclk_smmu_lpassx", "div_aclk_aud", + ENABLE_ACLK_AUD, 7, 0, 0), + GATE(CLK_ACLK_XIU_LPASSX, "aclk_xiu_lpassx", "div_aclk_aud", + ENABLE_ACLK_AUD, 0, 4, 0), + GATE(CLK_ACLK_AUDNP_133, "aclk_audnp_133", "div_aclk_aud", + ENABLE_ACLK_AUD, 0, 3, 0), + GATE(CLK_ACLK_AUDND_133, "aclk_audnd_133", "div_aclk_aud", + ENABLE_ACLK_AUD, 0, 2, 0), + GATE(CLK_ACLK_SRAMC, "aclk_sramc", "div_aclk_aud", ENABLE_ACLK_AUD, + 0, 1, 0), + GATE(CLK_ACLK_DMAC, "aclk_dmac", "div_aclk_aud", ENABLE_ACLK_AUD, + 0, CLK_IGNORE_UNUSED, 0), + + /* ENABLE_PCLK_AUD */ + GATE(CLK_PCLK_WDT1, "pclk_wdt1", "div_aclk_aud", ENABLE_PCLK_AUD, + 13, 0, 0), + GATE(CLK_PCLK_WDT0, "pclk_wdt0", "div_aclk_aud", ENABLE_PCLK_AUD, + 12, 0, 0), + GATE(CLK_PCLK_SFR1, "pclk_sfr1", "div_aclk_aud", ENABLE_PCLK_AUD, + 11, 0, 0), + GATE(CLK_PCLK_SMMU_LPASSX, "pclk_smmu_lpassx", "div_aclk_aud", + ENABLE_PCLK_AUD, 10, 0, 0), + GATE(CLK_PCLK_GPIO_AUD, "pclk_gpio_aud", "div_aclk_aud", + ENABLE_PCLK_AUD, 9, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_PMU_AUD, "pclk_pmu_aud", "div_aclk_aud", + ENABLE_PCLK_AUD, 8, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_SYSREG_AUD, "pclk_sysreg_aud", "div_aclk_aud", + ENABLE_PCLK_AUD, 7, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_AUD_SLIMBUS, "pclk_aud_slimbus", "div_aclk_aud", + ENABLE_PCLK_AUD, 6, 0, 0), + GATE(CLK_PCLK_AUD_UART, "pclk_aud_uart", "div_aclk_aud", + ENABLE_PCLK_AUD, 5, 0, 0), + GATE(CLK_PCLK_AUD_PCM, "pclk_aud_pcm", "div_aclk_aud", + ENABLE_PCLK_AUD, 4, 0, 0), + GATE(CLK_PCLK_AUD_I2S, "pclk_aud_i2s", "div_aclk_aud", + ENABLE_PCLK_AUD, 3, 0, 0), + GATE(CLK_PCLK_TIMER, "pclk_timer", "div_aclk_aud", ENABLE_PCLK_AUD, + 2, 0, 0), + GATE(CLK_PCLK_SFR0_CTRL, "pclk_sfr0_ctrl", "div_aclk_aud", + ENABLE_PCLK_AUD, 0, 0, 0), + + /* ENABLE_SCLK_AUD0 */ + GATE(CLK_ATCLK_AUD, "atclk_aud", "div_atclk_aud", ENABLE_SCLK_AUD0, + 2, 0, 0), + GATE(CLK_PCLK_DBG_AUD, "pclk_dbg_aud", "div_pclk_dbg_aud", + ENABLE_SCLK_AUD0, 1, 0, 0), + GATE(CLK_SCLK_AUD_CA5, "sclk_aud_ca5", "div_aud_ca5", ENABLE_SCLK_AUD0, + 0, 0, 0), + + /* ENABLE_SCLK_AUD1 */ + GATE(CLK_SCLK_JTAG_TCK, "sclk_jtag_tck", "ioclk_jtag_tclk", + ENABLE_SCLK_AUD1, 6, 0, 0), + GATE(CLK_SCLK_SLIMBUS_CLKIN, "sclk_slimbus_clkin", "ioclk_slimbus_clk", + ENABLE_SCLK_AUD1, 5, 0, 0), + GATE(CLK_SCLK_AUD_SLIMBUS, "sclk_aud_slimbus", "div_sclk_aud_slimbus", + ENABLE_SCLK_AUD1, 4, 0, 0), + GATE(CLK_SCLK_AUD_UART, "sclk_aud_uart", "div_sclk_aud_uart", + ENABLE_SCLK_AUD1, 3, 0, 0), + GATE(CLK_SCLK_AUD_PCM, "sclk_aud_pcm", "div_sclk_aud_pcm", + ENABLE_SCLK_AUD1, 2, 0, 0), + GATE(CLK_SCLK_I2S_BCLK, "sclk_i2s_bclk", "ioclk_i2s_bclk", + ENABLE_SCLK_AUD1, 1, CLK_IGNORE_UNUSED, 0), + GATE(CLK_SCLK_AUD_I2S, "sclk_aud_i2s", "div_sclk_aud_i2s", + ENABLE_SCLK_AUD1, 0, CLK_IGNORE_UNUSED, 0), +}; + +static struct samsung_cmu_info aud_cmu_info __initdata = { + .mux_clks = aud_mux_clks, + .nr_mux_clks = ARRAY_SIZE(aud_mux_clks), + .div_clks = aud_div_clks, + .nr_div_clks = ARRAY_SIZE(aud_div_clks), + .gate_clks = aud_gate_clks, + .nr_gate_clks = ARRAY_SIZE(aud_gate_clks), + .fixed_clks = aud_fixed_clks, + .nr_fixed_clks = ARRAY_SIZE(aud_fixed_clks), + .nr_clk_ids = AUD_NR_CLK, + .clk_regs = aud_clk_regs, + .nr_clk_regs = ARRAY_SIZE(aud_clk_regs), +}; + +static void __init exynos5433_cmu_aud_init(struct device_node *np) +{ + samsung_cmu_register_one(np, &aud_cmu_info); +} +CLK_OF_DECLARE(exynos5433_cmu_aud, "samsung,exynos5433-cmu-aud", + exynos5433_cmu_aud_init); diff --git a/include/dt-bindings/clock/exynos5433.h b/include/dt-bindings/clock/exynos5433.h index fe0650fad766..4d150e244057 100644 --- a/include/dt-bindings/clock/exynos5433.h +++ b/include/dt-bindings/clock/exynos5433.h @@ -626,4 +626,57 @@ #define DISP_NR_CLK 111 +/* CMU_AUD */ +#define CLK_MOUT_AUD_PLL_USER 1 +#define CLK_MOUT_SCLK_AUD_PCM 2 +#define CLK_MOUT_SCLK_AUD_I2S 3 + +#define CLK_DIV_ATCLK_AUD 4 +#define CLK_DIV_PCLK_DBG_AUD 5 +#define CLK_DIV_ACLK_AUD 6 +#define CLK_DIV_AUD_CA5 7 +#define CLK_DIV_SCLK_AUD_SLIMBUS 8 +#define CLK_DIV_SCLK_AUD_UART 9 +#define CLK_DIV_SCLK_AUD_PCM 10 +#define CLK_DIV_SCLK_AUD_I2S 11 + +#define CLK_ACLK_INTR_CTRL 12 +#define CLK_ACLK_AXIDS2_LPASSP 13 +#define CLK_ACLK_AXIDS1_LPASSP 14 +#define CLK_ACLK_AXI2APB1_LPASSP 15 +#define CLK_ACLK_AXI2APH_LPASSP 16 +#define CLK_ACLK_SMMU_LPASSX 17 +#define CLK_ACLK_AXIDS0_LPASSP 18 +#define CLK_ACLK_AXI2APB0_LPASSP 19 +#define CLK_ACLK_XIU_LPASSX 20 +#define CLK_ACLK_AUDNP_133 21 +#define CLK_ACLK_AUDND_133 22 +#define CLK_ACLK_SRAMC 23 +#define CLK_ACLK_DMAC 24 +#define CLK_PCLK_WDT1 25 +#define CLK_PCLK_WDT0 26 +#define CLK_PCLK_SFR1 27 +#define CLK_PCLK_SMMU_LPASSX 28 +#define CLK_PCLK_GPIO_AUD 29 +#define CLK_PCLK_PMU_AUD 30 +#define CLK_PCLK_SYSREG_AUD 31 +#define CLK_PCLK_AUD_SLIMBUS 32 +#define CLK_PCLK_AUD_UART 33 +#define CLK_PCLK_AUD_PCM 34 +#define CLK_PCLK_AUD_I2S 35 +#define CLK_PCLK_TIMER 36 +#define CLK_PCLK_SFR0_CTRL 37 +#define CLK_ATCLK_AUD 38 +#define CLK_PCLK_DBG_AUD 39 +#define CLK_SCLK_AUD_CA5 40 +#define CLK_SCLK_JTAG_TCK 41 +#define CLK_SCLK_SLIMBUS_CLKIN 42 +#define CLK_SCLK_AUD_SLIMBUS 43 +#define CLK_SCLK_AUD_UART 44 +#define CLK_SCLK_AUD_PCM 45 +#define CLK_SCLK_I2S_BCLK 46 +#define CLK_SCLK_AUD_I2S 47 + +#define AUD_NR_CLK 48 + #endif /* _DT_BINDINGS_CLOCK_EXYNOS5433_H */ -- GitLab From 5785d6e61f27f7af4d239c1647d5a22e0dbff19b Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Mon, 2 Feb 2015 23:24:04 +0900 Subject: [PATCH 00042/11651] clk: samsung: exynos5433: Add clocks for CMU_BUS{0|1|2} domains This patch adds the mux/divider/gate clocks for CMU_BUS{0|1|2} domains which contain global data buses clocked at up the 400MHz. These blocks transfer data between DRAM and various sub-blocks. These clock domains also contain global peripheral buses clocked at 67/111/200/222/266/333/400 MHz and used for register accesses. Signed-off-by: Chanwoo Choi Acked-by: Inki Dae Reviewed-by: Pankaj Dubey Signed-off-by: Sylwester Nawrocki --- drivers/clk/samsung/clk-exynos5433.c | 187 +++++++++++++++++++++++++ include/dt-bindings/clock/exynos5433.h | 27 +++- 2 files changed, 213 insertions(+), 1 deletion(-) diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c index ad0105aa0de6..7c4e91a440e5 100644 --- a/drivers/clk/samsung/clk-exynos5433.c +++ b/drivers/clk/samsung/clk-exynos5433.c @@ -438,6 +438,14 @@ static struct samsung_div_clock top_div_clks[] __initdata = { DIV(CLK_DIV_ACLK_PERIS_66_A, "div_aclk_peris_66_a", "mout_bus_pll_user", DIV_TOP3, 0, 3), + /* DIV_TOP4 */ + DIV(CLK_DIV_ACLK_G3D_400, "div_aclk_g3d_400", "mout_bus_pll_user", + DIV_TOP4, 8, 3), + DIV(CLK_DIV_ACLK_BUS0_400, "div_aclk_bus0_400", "mout_aclk_bus0_400", + DIV_TOP4, 4, 3), + DIV(CLK_DIV_ACLK_BUS1_400, "div_aclk_bus1_400", "mout_bus_pll_user", + DIV_TOP4, 0, 3), + /* DIV_TOP_FSYS0 */ DIV(CLK_DIV_SCLK_MMC1_B, "div_sclk_mmc1_b", "div_sclk_mmc1_a", DIV_TOP_FSYS0, 16, 8), @@ -501,6 +509,23 @@ static struct samsung_div_clock top_div_clks[] __initdata = { static struct samsung_gate_clock top_gate_clks[] __initdata = { /* ENABLE_ACLK_TOP */ + GATE(CLK_ACLK_G3D_400, "aclk_g3d_400", "div_aclk_g3d_400", + ENABLE_ACLK_TOP, 30, 0, 0), + GATE(CLK_ACLK_IMEM_SSX_266, "aclk_imem_ssx_266", + "div_aclk_imem_sssx_266", ENABLE_ACLK_TOP, + 29, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_BUS0_400, "aclk_bus0_400", "div_aclk_bus0_400", + ENABLE_ACLK_TOP, 26, + CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0), + GATE(CLK_ACLK_BUS1_400, "aclk_bus1_400", "div_aclk_bus1_400", + ENABLE_ACLK_TOP, 25, + CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0), + GATE(CLK_ACLK_IMEM_200, "aclk_imem_200", "div_aclk_imem_266", + ENABLE_ACLK_TOP, 24, + CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0), + GATE(CLK_ACLK_IMEM_266, "aclk_imem_266", "div_aclk_imem_200", + ENABLE_ACLK_TOP, 23, + CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0), GATE(CLK_ACLK_PERIC_66, "aclk_peric_66", "div_aclk_peric_66_b", ENABLE_ACLK_TOP, 22, CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0), @@ -2631,3 +2656,165 @@ static void __init exynos5433_cmu_aud_init(struct device_node *np) } CLK_OF_DECLARE(exynos5433_cmu_aud, "samsung,exynos5433-cmu-aud", exynos5433_cmu_aud_init); + + +/* + * Register offset definitions for CMU_BUS{0|1|2} + */ +#define DIV_BUS 0x0600 +#define DIV_STAT_BUS 0x0700 +#define ENABLE_ACLK_BUS 0x0800 +#define ENABLE_PCLK_BUS 0x0900 +#define ENABLE_IP_BUS0 0x0b00 +#define ENABLE_IP_BUS1 0x0b04 + +#define MUX_SEL_BUS2 0x0200 /* Only for CMU_BUS2 */ +#define MUX_ENABLE_BUS2 0x0300 /* Only for CMU_BUS2 */ +#define MUX_STAT_BUS2 0x0400 /* Only for CMU_BUS2 */ + +/* list of all parent clock list */ +PNAME(mout_aclk_bus2_400_p) = { "oscclk", "aclk_bus2_400", }; + +#define CMU_BUS_COMMON_CLK_REGS \ + DIV_BUS, \ + DIV_STAT_BUS, \ + ENABLE_ACLK_BUS, \ + ENABLE_PCLK_BUS, \ + ENABLE_IP_BUS0, \ + ENABLE_IP_BUS1 + +static unsigned long bus01_clk_regs[] __initdata = { + CMU_BUS_COMMON_CLK_REGS, +}; + +static unsigned long bus2_clk_regs[] __initdata = { + MUX_SEL_BUS2, + MUX_ENABLE_BUS2, + MUX_STAT_BUS2, + CMU_BUS_COMMON_CLK_REGS, +}; + +static struct samsung_div_clock bus0_div_clks[] __initdata = { + /* DIV_BUS0 */ + DIV(CLK_DIV_PCLK_BUS_133, "div_pclk_bus0_133", "aclk_bus0_400", + DIV_BUS, 0, 3), +}; + +/* CMU_BUS0 clocks */ +static struct samsung_gate_clock bus0_gate_clks[] __initdata = { + /* ENABLE_ACLK_BUS0 */ + GATE(CLK_ACLK_AHB2APB_BUSP, "aclk_ahb2apb_bus0p", "div_pclk_bus0_133", + ENABLE_ACLK_BUS, 4, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_BUSNP_133, "aclk_bus0np_133", "div_pclk_bus0_133", + ENABLE_ACLK_BUS, 2, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_BUSND_400, "aclk_bus0nd_400", "aclk_bus0_400", + ENABLE_ACLK_BUS, 0, CLK_IGNORE_UNUSED, 0), + + /* ENABLE_PCLK_BUS0 */ + GATE(CLK_PCLK_BUSSRVND_133, "pclk_bus0srvnd_133", "div_pclk_bus0_133", + ENABLE_PCLK_BUS, 2, 0, 0), + GATE(CLK_PCLK_PMU_BUS, "pclk_pmu_bus0", "div_pclk_bus0_133", + ENABLE_PCLK_BUS, 1, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_SYSREG_BUS, "pclk_sysreg_bus0", "div_pclk_bus0_133", + ENABLE_PCLK_BUS, 0, CLK_IGNORE_UNUSED, 0), +}; + +/* CMU_BUS1 clocks */ +static struct samsung_div_clock bus1_div_clks[] __initdata = { + /* DIV_BUS1 */ + DIV(CLK_DIV_PCLK_BUS_133, "div_pclk_bus1_133", "aclk_bus1_400", + DIV_BUS, 0, 3), +}; + +static struct samsung_gate_clock bus1_gate_clks[] __initdata = { + /* ENABLE_ACLK_BUS1 */ + GATE(CLK_ACLK_AHB2APB_BUSP, "aclk_ahb2apb_bus1p", "div_pclk_bus1_133", + ENABLE_ACLK_BUS, 4, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_BUSNP_133, "aclk_bus1np_133", "div_pclk_bus1_133", + ENABLE_ACLK_BUS, 2, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_BUSND_400, "aclk_bus1nd_400", "aclk_bus1_400", + ENABLE_ACLK_BUS, 0, CLK_IGNORE_UNUSED, 0), + + /* ENABLE_PCLK_BUS1 */ + GATE(CLK_PCLK_BUSSRVND_133, "pclk_bus1srvnd_133", "div_pclk_bus1_133", + ENABLE_PCLK_BUS, 2, 0, 0), + GATE(CLK_PCLK_PMU_BUS, "pclk_pmu_bus1", "div_pclk_bus1_133", + ENABLE_PCLK_BUS, 1, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_SYSREG_BUS, "pclk_sysreg_bus1", "div_pclk_bus1_133", + ENABLE_PCLK_BUS, 0, CLK_IGNORE_UNUSED, 0), +}; + +/* CMU_BUS2 clocks */ +static struct samsung_mux_clock bus2_mux_clks[] __initdata = { + /* MUX_SEL_BUS2 */ + MUX(CLK_MOUT_ACLK_BUS2_400_USER, "mout_aclk_bus2_400_user", + mout_aclk_bus2_400_p, MUX_SEL_BUS2, 0, 1), +}; + +static struct samsung_div_clock bus2_div_clks[] __initdata = { + /* DIV_BUS2 */ + DIV(CLK_DIV_PCLK_BUS_133, "div_pclk_bus2_133", + "mout_aclk_bus2_400_user", DIV_BUS, 0, 3), +}; + +static struct samsung_gate_clock bus2_gate_clks[] __initdata = { + /* ENABLE_ACLK_BUS2 */ + GATE(CLK_ACLK_AHB2APB_BUSP, "aclk_ahb2apb_bus2p", "div_pclk_bus2_133", + ENABLE_ACLK_BUS, 3, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_BUSNP_133, "aclk_bus2np_133", "div_pclk_bus2_133", + ENABLE_ACLK_BUS, 2, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_BUS2BEND_400, "aclk_bus2bend_400", + "mout_aclk_bus2_400_user", ENABLE_ACLK_BUS, + 1, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_BUS2RTND_400, "aclk_bus2rtnd_400", + "mout_aclk_bus2_400_user", ENABLE_ACLK_BUS, + 0, CLK_IGNORE_UNUSED, 0), + + /* ENABLE_PCLK_BUS2 */ + GATE(CLK_PCLK_BUSSRVND_133, "pclk_bus2srvnd_133", "div_pclk_bus2_133", + ENABLE_PCLK_BUS, 2, 0, 0), + GATE(CLK_PCLK_PMU_BUS, "pclk_pmu_bus2", "div_pclk_bus2_133", + ENABLE_PCLK_BUS, 1, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_SYSREG_BUS, "pclk_sysreg_bus2", "div_pclk_bus2_133", + ENABLE_PCLK_BUS, 0, CLK_IGNORE_UNUSED, 0), +}; + +#define CMU_BUS_INFO_CLKS(id) \ + .div_clks = bus##id##_div_clks, \ + .nr_div_clks = ARRAY_SIZE(bus##id##_div_clks), \ + .gate_clks = bus##id##_gate_clks, \ + .nr_gate_clks = ARRAY_SIZE(bus##id##_gate_clks), \ + .nr_clk_ids = BUSx_NR_CLK + +static struct samsung_cmu_info bus0_cmu_info __initdata = { + CMU_BUS_INFO_CLKS(0), + .clk_regs = bus01_clk_regs, + .nr_clk_regs = ARRAY_SIZE(bus01_clk_regs), +}; + +static struct samsung_cmu_info bus1_cmu_info __initdata = { + CMU_BUS_INFO_CLKS(1), + .clk_regs = bus01_clk_regs, + .nr_clk_regs = ARRAY_SIZE(bus01_clk_regs), +}; + +static struct samsung_cmu_info bus2_cmu_info __initdata = { + CMU_BUS_INFO_CLKS(2), + .mux_clks = bus2_mux_clks, + .nr_mux_clks = ARRAY_SIZE(bus2_mux_clks), + .clk_regs = bus2_clk_regs, + .nr_clk_regs = ARRAY_SIZE(bus2_clk_regs), +}; + +#define exynos5433_cmu_bus_init(id) \ +static void __init exynos5433_cmu_bus##id##_init(struct device_node *np)\ +{ \ + samsung_cmu_register_one(np, &bus##id##_cmu_info); \ +} \ +CLK_OF_DECLARE(exynos5433_cmu_bus##id, \ + "samsung,exynos5433-cmu-bus"#id, \ + exynos5433_cmu_bus##id##_init) + +exynos5433_cmu_bus_init(0); +exynos5433_cmu_bus_init(1); +exynos5433_cmu_bus_init(2); diff --git a/include/dt-bindings/clock/exynos5433.h b/include/dt-bindings/clock/exynos5433.h index 4d150e244057..8d388e700a80 100644 --- a/include/dt-bindings/clock/exynos5433.h +++ b/include/dt-bindings/clock/exynos5433.h @@ -107,6 +107,9 @@ #define CLK_DIV_ACLK_MFC_400 134 #define CLK_DIV_ACLK_G2D_266 135 #define CLK_DIV_ACLK_G2D_400 136 +#define CLK_DIV_ACLK_G3D_400 137 +#define CLK_DIV_ACLK_BUS0_400 138 +#define CLK_DIV_ACLK_BUS1_400 139 #define CLK_ACLK_PERIC_66 200 #define CLK_ACLK_PERIS_66 201 @@ -130,8 +133,14 @@ #define CLK_SCLK_AUDIO0 219 #define CLK_ACLK_G2D_266 220 #define CLK_ACLK_G2D_400 221 +#define CLK_ACLK_G3D_400 222 +#define CLK_ACLK_IMEM_SSX_266 223 +#define CLK_ACLK_BUS0_400 224 +#define CLK_ACLK_BUS1_400 225 +#define CLK_ACLK_IMEM_200 226 +#define CLK_ACLK_IMEM_266 227 -#define TOP_NR_CLK 222 +#define TOP_NR_CLK 228 /* CMU_CPIF */ #define CLK_FOUT_MPHY_PLL 1 @@ -679,4 +688,20 @@ #define AUD_NR_CLK 48 +/* CMU_BUS{0|1|2} */ +#define CLK_DIV_PCLK_BUS_133 1 + +#define CLK_ACLK_AHB2APB_BUSP 2 +#define CLK_ACLK_BUSNP_133 3 +#define CLK_ACLK_BUSND_400 4 +#define CLK_PCLK_BUSSRVND_133 5 +#define CLK_PCLK_PMU_BUS 6 +#define CLK_PCLK_SYSREG_BUS 7 + +#define CLK_MOUT_ACLK_BUS2_400_USER 8 /* Only CMU_BUS2 */ +#define CLK_ACLK_BUS2BEND_400 9 /* Only CMU_BUS2 */ +#define CLK_ACLK_BUS2RTND_400 10 /* Only CMU_BUS2 */ + +#define BUSx_NR_CLK 11 + #endif /* _DT_BINDINGS_CLOCK_EXYNOS5433_H */ -- GitLab From 4b8013554b0454984e71bc20bc31966886079e15 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Mon, 2 Feb 2015 23:24:05 +0900 Subject: [PATCH 00043/11651] clk: samsung: exynos5433: Add missing clocks for CMU_FSYS domain This patch adds the mux/divider/gate clocks for CMU_FSYS domain which contains the clocks of USB/UFS/SDMMC/TSI/PDMA IPs. Signed-off-by: Chanwoo Choi Acked-by: Inki Dae Signed-off-by: Sylwester Nawrocki --- drivers/clk/samsung/clk-exynos5433.c | 302 +++++++++++++++++++++++++ include/dt-bindings/clock/exynos5433.h | 96 +++++++- 2 files changed, 395 insertions(+), 3 deletions(-) diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c index 7c4e91a440e5..1cdc47e05ac1 100644 --- a/drivers/clk/samsung/clk-exynos5433.c +++ b/drivers/clk/samsung/clk-exynos5433.c @@ -462,6 +462,16 @@ static struct samsung_div_clock top_div_clks[] __initdata = { DIV(CLK_DIV_SCLK_MMC2_A, "div_sclk_mmc2_a", "mout_sclk_mmc2_b", DIV_TOP_FSYS1, 0, 4), + /* DIV_TOP_FSYS2 */ + DIV(CLK_DIV_SCLK_PCIE_100, "div_sclk_pcie_100", "mout_sclk_pcie_100", + DIV_TOP_FSYS2, 12, 3), + DIV(CLK_DIV_SCLK_USBHOST30, "div_sclk_usbhost30", + "mout_sclk_usbhost30", DIV_TOP_FSYS2, 8, 4), + DIV(CLK_DIV_SCLK_UFSUNIPRO, "div_sclk_ufsunipro", + "mout_sclk_ufsunipro", DIV_TOP_FSYS2, 4, 4), + DIV(CLK_DIV_SCLK_USBDRD30, "div_sclk_usbdrd30", "mout_sclk_usbdrd30", + DIV_TOP_FSYS2, 0, 4), + /* DIV_TOP_PERIC0 */ DIV(CLK_DIV_SCLK_SPI1_B, "div_sclk_spi1_b", "div_sclk_spi1_a", DIV_TOP_PERIC0, 16, 8), @@ -543,12 +553,23 @@ static struct samsung_gate_clock top_gate_clks[] __initdata = { CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0), /* ENABLE_SCLK_TOP_FSYS */ + GATE(CLK_SCLK_PCIE_100_FSYS, "sclk_pcie_100_fsys", "div_sclk_pcie_100", + ENABLE_SCLK_TOP_FSYS, 7, 0, 0), GATE(CLK_SCLK_MMC2_FSYS, "sclk_mmc2_fsys", "div_sclk_mmc2_b", ENABLE_SCLK_TOP_FSYS, 6, CLK_SET_RATE_PARENT, 0), GATE(CLK_SCLK_MMC1_FSYS, "sclk_mmc1_fsys", "div_sclk_mmc1_b", ENABLE_SCLK_TOP_FSYS, 5, CLK_SET_RATE_PARENT, 0), GATE(CLK_SCLK_MMC0_FSYS, "sclk_mmc0_fsys", "div_sclk_mmc0_b", ENABLE_SCLK_TOP_FSYS, 4, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_UFSUNIPRO_FSYS, "sclk_ufsunipro_fsys", + "div_sclk_ufsunipro", ENABLE_SCLK_TOP_FSYS, + 3, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_USBHOST30_FSYS, "sclk_usbhost30_fsys", + "div_sclk_usbhost30", ENABLE_SCLK_TOP_FSYS, + 1, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_USBDRD30_FSYS, "sclk_usbdrd30_fsys", + "div_sclk_usbdrd30", ENABLE_SCLK_TOP_FSYS, + 0, CLK_SET_RATE_PARENT, 0), /* ENABLE_SCLK_TOP_PERIC */ GATE(CLK_SCLK_SPI4_PERIC, "sclk_spi4_peric", "div_sclk_spi4_b", @@ -1832,10 +1853,45 @@ CLK_OF_DECLARE(exynos5433_cmu_peris, "samsung,exynos5433-cmu-peris", #define ENABLE_IP_FSYS1 0x0b04 /* list of all parent clock list */ +PNAME(mout_sclk_ufs_mphy_user_p) = { "oscclk", "sclk_ufs_mphy", }; PNAME(mout_aclk_fsys_200_user_p) = { "oscclk", "div_aclk_fsys_200", }; +PNAME(mout_sclk_pcie_100_user_p) = { "oscclk", "sclk_pcie_100_fsys",}; +PNAME(mout_sclk_ufsunipro_user_p) = { "oscclk", "sclk_ufsunipro_fsys",}; PNAME(mout_sclk_mmc2_user_p) = { "oscclk", "sclk_mmc2_fsys", }; PNAME(mout_sclk_mmc1_user_p) = { "oscclk", "sclk_mmc1_fsys", }; PNAME(mout_sclk_mmc0_user_p) = { "oscclk", "sclk_mmc0_fsys", }; +PNAME(mout_sclk_usbhost30_user_p) = { "oscclk", "sclk_usbhost30_fsys",}; +PNAME(mout_sclk_usbdrd30_user_p) = { "oscclk", "sclk_usbdrd30_fsys", }; + +PNAME(mout_phyclk_usbhost30_uhost30_pipe_pclk_user_p) + = { "oscclk", "phyclk_usbhost30_uhost30_pipe_pclk_phy", }; +PNAME(mout_phyclk_usbhost30_uhost30_phyclock_user_p) + = { "oscclk", "phyclk_usbhost30_uhost30_phyclock_phy", }; +PNAME(mout_phyclk_usbhost20_phy_hsic1_p) + = { "oscclk", "phyclk_usbhost20_phy_hsic1_phy", }; +PNAME(mout_phyclk_usbhost20_phy_clk48mohci_user_p) + = { "oscclk", "phyclk_usbhost20_phy_clk48mohci_phy", }; +PNAME(mout_phyclk_usbhost20_phy_phyclock_user_p) + = { "oscclk", "phyclk_usbhost20_phy_phyclock_phy", }; +PNAME(mout_phyclk_usbhost20_phy_freeclk_user_p) + = { "oscclk", "phyclk_usbhost20_phy_freeclk_phy", }; +PNAME(mout_phyclk_usbdrd30_udrd30_pipe_pclk_p) + = { "oscclk", "phyclk_usbdrd30_udrd30_pipe_pclk_phy", }; +PNAME(mout_phyclk_usbdrd30_udrd30_phyclock_user_p) + = { "oscclk", "phyclk_usbdrd30_udrd30_phyclock_phy", }; +PNAME(mout_phyclk_ufs_rx1_symbol_user_p) + = { "oscclk", "phyclk_ufs_rx1_symbol_phy", }; +PNAME(mout_phyclk_ufs_rx0_symbol_user_p) + = { "oscclk", "phyclk_ufs_rx0_symbol_phy", }; +PNAME(mout_phyclk_ufs_tx1_symbol_user_p) + = { "oscclk", "phyclk_ufs_tx1_symbol_phy", }; +PNAME(mout_phyclk_ufs_tx0_symbol_user_p) + = { "oscclk", "phyclk_ufs_tx0_symbol_phy", }; +PNAME(mout_phyclk_lli_mphy_to_ufs_user_p) + = { "oscclk", "phyclk_lli_mphy_to_ufs_phy", }; +PNAME(mout_sclk_mphy_p) + = { "mout_sclk_ufs_mphy_user", + "mout_phyclk_lli_mphy_to_ufs_user", }; static unsigned long fsys_clk_regs[] __initdata = { MUX_SEL_FSYS0, @@ -1863,18 +1919,130 @@ static unsigned long fsys_clk_regs[] __initdata = { ENABLE_IP_FSYS1, }; +static struct samsung_fixed_rate_clock fsys_fixed_clks[] __initdata = { + /* PHY clocks from USBDRD30_PHY */ + FRATE(CLK_PHYCLK_USBDRD30_UDRD30_PHYCLOCK_PHY, + "phyclk_usbdrd30_udrd30_phyclock_phy", NULL, + CLK_IS_ROOT, 60000000), + FRATE(CLK_PHYCLK_USBDRD30_UDRD30_PIPE_PCLK_PHY, + "phyclk_usbdrd30_udrd30_pipe_pclk_phy", NULL, + CLK_IS_ROOT, 125000000), + /* PHY clocks from USBHOST30_PHY */ + FRATE(CLK_PHYCLK_USBHOST30_UHOST30_PHYCLOCK_PHY, + "phyclk_usbhost30_uhost30_phyclock_phy", NULL, + CLK_IS_ROOT, 60000000), + FRATE(CLK_PHYCLK_USBHOST30_UHOST30_PIPE_PCLK_PHY, + "phyclk_usbhost30_uhost30_pipe_pclk_phy", NULL, + CLK_IS_ROOT, 125000000), + /* PHY clocks from USBHOST20_PHY */ + FRATE(CLK_PHYCLK_USBHOST20_PHY_FREECLK_PHY, + "phyclk_usbhost20_phy_freeclk_phy", NULL, CLK_IS_ROOT, + 60000000), + FRATE(CLK_PHYCLK_USBHOST20_PHY_PHYCLOCK_PHY, + "phyclk_usbhost20_phy_phyclock_phy", NULL, CLK_IS_ROOT, + 60000000), + FRATE(CLK_PHYCLK_USBHOST20_PHY_CLK48MOHCI_PHY, + "phyclk_usbhost20_phy_clk48mohci_phy", NULL, + CLK_IS_ROOT, 48000000), + FRATE(CLK_PHYCLK_USBHOST20_PHY_HSIC1_PHY, + "phyclk_usbhost20_phy_hsic1_phy", NULL, CLK_IS_ROOT, + 60000000), + /* PHY clocks from UFS_PHY */ + FRATE(CLK_PHYCLK_UFS_TX0_SYMBOL_PHY, "phyclk_ufs_tx0_symbol_phy", + NULL, CLK_IS_ROOT, 300000000), + FRATE(CLK_PHYCLK_UFS_RX0_SYMBOL_PHY, "phyclk_ufs_rx0_symbol_phy", + NULL, CLK_IS_ROOT, 300000000), + FRATE(CLK_PHYCLK_UFS_TX1_SYMBOL_PHY, "phyclk_ufs_tx1_symbol_phy", + NULL, CLK_IS_ROOT, 300000000), + FRATE(CLK_PHYCLK_UFS_RX1_SYMBOL_PHY, "phyclk_ufs_rx1_symbol_phy", + NULL, CLK_IS_ROOT, 300000000), + /* PHY clocks from LLI_PHY */ + FRATE(CLK_PHYCLK_LLI_MPHY_TO_UFS_PHY, "phyclk_lli_mphy_to_ufs_phy", + NULL, CLK_IS_ROOT, 26000000), +}; + static struct samsung_mux_clock fsys_mux_clks[] __initdata = { /* MUX_SEL_FSYS0 */ + MUX(CLK_MOUT_SCLK_UFS_MPHY_USER, "mout_sclk_ufs_mphy_user", + mout_sclk_ufs_mphy_user_p, MUX_SEL_FSYS0, 4, 1), MUX(CLK_MOUT_ACLK_FSYS_200_USER, "mout_aclk_fsys_200_user", mout_aclk_fsys_200_user_p, MUX_SEL_FSYS0, 0, 1), /* MUX_SEL_FSYS1 */ + MUX(CLK_MOUT_SCLK_PCIE_100_USER, "mout_sclk_pcie_100_user", + mout_sclk_pcie_100_user_p, MUX_SEL_FSYS1, 28, 1), + MUX(CLK_MOUT_SCLK_UFSUNIPRO_USER, "mout_sclk_ufsunipro_user", + mout_sclk_ufsunipro_user_p, MUX_SEL_FSYS1, 24, 1), MUX(CLK_MOUT_SCLK_MMC2_USER, "mout_sclk_mmc2_user", mout_sclk_mmc2_user_p, MUX_SEL_FSYS1, 20, 1), MUX(CLK_MOUT_SCLK_MMC1_USER, "mout_sclk_mmc1_user", mout_sclk_mmc1_user_p, MUX_SEL_FSYS1, 16, 1), MUX(CLK_MOUT_SCLK_MMC0_USER, "mout_sclk_mmc0_user", mout_sclk_mmc0_user_p, MUX_SEL_FSYS1, 12, 1), + MUX(CLK_MOUT_SCLK_USBHOST30_USER, "mout_sclk_usbhost30_user", + mout_sclk_usbhost30_user_p, MUX_SEL_FSYS1, 4, 1), + MUX(CLK_MOUT_SCLK_USBDRD30_USER, "mout_sclk_usbdrd30_user", + mout_sclk_usbdrd30_user_p, MUX_SEL_FSYS1, 0, 1), + + /* MUX_SEL_FSYS2 */ + MUX(CLK_MOUT_PHYCLK_USBHOST30_UHOST30_PIPE_PCLK_USER, + "mout_phyclk_usbhost30_uhost30_pipe_pclk_user", + mout_phyclk_usbhost30_uhost30_pipe_pclk_user_p, + MUX_SEL_FSYS2, 28, 1), + MUX(CLK_MOUT_PHYCLK_USBHOST30_UHOST30_PHYCLOCK_USER, + "mout_phyclk_usbhost30_uhost30_phyclock_user", + mout_phyclk_usbhost30_uhost30_phyclock_user_p, + MUX_SEL_FSYS2, 24, 1), + MUX(CLK_MOUT_PHYCLK_USBHOST20_PHY_HSIC1_USER, + "mout_phyclk_usbhost20_phy_hsic1", + mout_phyclk_usbhost20_phy_hsic1_p, + MUX_SEL_FSYS2, 20, 1), + MUX(CLK_MOUT_PHYCLK_USBHOST20_PHY_CLK48MOHCI_USER, + "mout_phyclk_usbhost20_phy_clk48mohci_user", + mout_phyclk_usbhost20_phy_clk48mohci_user_p, + MUX_SEL_FSYS2, 16, 1), + MUX(CLK_MOUT_PHYCLK_USBHOST20_PHY_PHYCLOCK_USER, + "mout_phyclk_usbhost20_phy_phyclock_user", + mout_phyclk_usbhost20_phy_phyclock_user_p, + MUX_SEL_FSYS2, 12, 1), + MUX(CLK_MOUT_PHYCLK_USBHOST20_PHY_PHY_FREECLK_USER, + "mout_phyclk_usbhost20_phy_freeclk_user", + mout_phyclk_usbhost20_phy_freeclk_user_p, + MUX_SEL_FSYS2, 8, 1), + MUX(CLK_MOUT_PHYCLK_USBDRD30_UDRD30_PIPE_PCLK_USER, + "mout_phyclk_usbdrd30_udrd30_pipe_pclk_user", + mout_phyclk_usbdrd30_udrd30_pipe_pclk_p, + MUX_SEL_FSYS2, 4, 1), + MUX(CLK_MOUT_PHYCLK_USBDRD30_UDRD30_PHYCLOCK_USER, + "mout_phyclk_usbdrd30_udrd30_phyclock_user", + mout_phyclk_usbdrd30_udrd30_phyclock_user_p, + MUX_SEL_FSYS2, 0, 1), + + /* MUX_SEL_FSYS3 */ + MUX(CLK_MOUT_PHYCLK_UFS_RX1_SYMBOL_USER, + "mout_phyclk_ufs_rx1_symbol_user", + mout_phyclk_ufs_rx1_symbol_user_p, + MUX_SEL_FSYS3, 16, 1), + MUX(CLK_MOUT_PHYCLK_UFS_RX0_SYMBOL_USER, + "mout_phyclk_ufs_rx0_symbol_user", + mout_phyclk_ufs_rx0_symbol_user_p, + MUX_SEL_FSYS3, 12, 1), + MUX(CLK_MOUT_PHYCLK_UFS_TX1_SYMBOL_USER, + "mout_phyclk_ufs_tx1_symbol_user", + mout_phyclk_ufs_tx1_symbol_user_p, + MUX_SEL_FSYS3, 8, 1), + MUX(CLK_MOUT_PHYCLK_UFS_TX0_SYMBOL_USER, + "mout_phyclk_ufs_tx0_symbol_user", + mout_phyclk_ufs_tx0_symbol_user_p, + MUX_SEL_FSYS3, 4, 1), + MUX(CLK_MOUT_PHYCLK_LLI_MPHY_TO_UFS_USER, + "mout_phyclk_lli_mphy_to_ufs_user", + mout_phyclk_lli_mphy_to_ufs_user_p, + MUX_SEL_FSYS3, 0, 1), + + /* MUX_SEL_FSYS4 */ + MUX(CLK_MOUT_SCLK_MPHY, "mout_sclk_mphy", mout_sclk_mphy_p, + MUX_SEL_FSYS4, 0, 1), }; static struct samsung_gate_clock fsys_gate_clks[] __initdata = { @@ -1902,13 +2070,145 @@ static struct samsung_gate_clock fsys_gate_clks[] __initdata = { GATE(CLK_ACLK_PDMA0, "aclk_pdma0", "mout_aclk_fsys_200_user", ENABLE_ACLK_FSYS0, 0, CLK_IGNORE_UNUSED, 0), + /* ENABLE_ACLK_FSYS1 */ + GATE(CLK_ACLK_XIU_FSYSPX, "aclk_xiu_fsyspx", "mout_aclk_fsys_200_user", + ENABLE_ACLK_FSYS1, 27, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_AHB_USBLINKH1, "aclk_ahb_usblinkh1", + "mout_aclk_fsys_200_user", ENABLE_ACLK_FSYS1, + 26, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_SMMU_PDMA1, "aclk_smmu_pdma1", "mout_aclk_fsys_200_user", + ENABLE_ACLK_FSYS1, 25, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_BTS_PCIE, "aclk_bts_pcie", "mout_aclk_fsys_200_user", + ENABLE_ACLK_FSYS1, 24, 0, 0), + GATE(CLK_ACLK_AXIUS_PDMA1, "aclk_axius_pdma1", + "mout_aclk_fsys_200_user", ENABLE_ACLK_FSYS1, + 22, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_SMMU_PDMA0, "aclk_smmu_pdma0", "mout_aclk_fsys_200_user", + ENABLE_ACLK_FSYS1, 17, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_BTS_UFS, "aclk_bts_ufs", "mout_aclk_fsys_200_user", + ENABLE_ACLK_FSYS1, 14, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_BTS_USBHOST30, "aclk_bts_usbhost30", + "mout_aclk_fsys_200_user", ENABLE_ACLK_FSYS1, + 13, 0, 0), + GATE(CLK_ACLK_BTS_USBDRD30, "aclk_bts_usbdrd30", + "mout_aclk_fsys_200_user", ENABLE_ACLK_FSYS1, + 12, 0, 0), + GATE(CLK_ACLK_AXIUS_PDMA0, "aclk_axius_pdma0", + "mout_aclk_fsys_200_user", ENABLE_ACLK_FSYS1, + 11, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_AXIUS_USBHS, "aclk_axius_usbhs", + "mout_aclk_fsys_200_user", ENABLE_ACLK_FSYS1, + 10, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_AXIUS_FSYSSX, "aclk_axius_fsyssx", + "mout_aclk_fsys_200_user", ENABLE_ACLK_FSYS1, + 9, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_AHB2APB_FSYSP, "aclk_ahb2apb_fsysp", + "mout_aclk_fsys_200_user", ENABLE_ACLK_FSYS1, + 8, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_AHB2AXI_USBHS, "aclk_ahb2axi_usbhs", + "mout_aclk_fsys_200_user", ENABLE_ACLK_FSYS1, + 7, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_AHB_USBLINKH0, "aclk_ahb_usblinkh0", + "mout_aclk_fsys_200_user", ENABLE_ACLK_FSYS1, + 6, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_AHB_USBHS, "aclk_ahb_usbhs", "mout_aclk_fsys_200_user", + ENABLE_ACLK_FSYS1, 5, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_AHB_FSYSH, "aclk_ahb_fsysh", "mout_aclk_fsys_200_user", + ENABLE_ACLK_FSYS1, 4, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_XIU_FSYSX, "aclk_xiu_fsysx", "mout_aclk_fsys_200_user", + ENABLE_ACLK_FSYS1, 3, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_XIU_FSYSSX, "aclk_xiu_fsyssx", "mout_aclk_fsys_200_user", + ENABLE_ACLK_FSYS1, 2, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_FSYSNP_200, "aclk_fsysnp_200", "mout_aclk_fsys_200_user", + ENABLE_ACLK_FSYS1, 1, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_FSYSND_200, "aclk_fsysnd_200", "mout_aclk_fsys_200_user", + ENABLE_ACLK_FSYS1, 0, CLK_IGNORE_UNUSED, 0), + + /* ENABLE_PCLK_FSYS */ + GATE(CLK_PCLK_PCIE_CTRL, "pclk_pcie_ctrl", "mout_aclk_fsys_200_user", + ENABLE_PCLK_FSYS, 17, 0, 0), + GATE(CLK_PCLK_SMMU_PDMA1, "pclk_smmu_pdma1", "mout_aclk_fsys_200_user", + ENABLE_PCLK_FSYS, 16, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_PCIE_PHY, "pclk_pcie_phy", "mout_aclk_fsys_200_user", + ENABLE_PCLK_FSYS, 14, 0, 0), + GATE(CLK_PCLK_BTS_PCIE, "pclk_bts_pcie", "mout_aclk_fsys_200_user", + ENABLE_PCLK_FSYS, 13, 0, 0), + GATE(CLK_PCLK_SMMU_PDMA0, "pclk_smmu_pdma0", "mout_aclk_fsys_200_user", + ENABLE_PCLK_FSYS, 8, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_BTS_UFS, "pclk_bts_ufs", "mout_aclk_fsys_200_user", + ENABLE_PCLK_FSYS, 5, 0, 0), + GATE(CLK_PCLK_BTS_USBHOST30, "pclk_bts_usbhost30", + "mout_aclk_fsys_200_user", ENABLE_PCLK_FSYS, 4, 0, 0), + GATE(CLK_PCLK_BTS_USBDRD30, "pclk_bts_usbdrd30", + "mout_aclk_fsys_200_user", ENABLE_PCLK_FSYS, 3, 0, 0), + GATE(CLK_PCLK_GPIO_FSYS, "pclk_gpio_fsys", "mout_aclk_fsys_200_user", + ENABLE_PCLK_FSYS, 2, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_PMU_FSYS, "pclk_pmu_fsys", "mout_aclk_fsys_200_user", + ENABLE_PCLK_FSYS, 1, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_SYSREG_FSYS, "pclk_sysreg_fsys", + "mout_aclk_fsys_200_user", ENABLE_PCLK_FSYS, + 0, CLK_IGNORE_UNUSED, 0), + /* ENABLE_SCLK_FSYS */ + GATE(CLK_SCLK_PCIE_100, "sclk_pcie_100", "mout_sclk_pcie_100_user", + ENABLE_SCLK_FSYS, 21, 0, 0), + GATE(CLK_PHYCLK_USBHOST30_UHOST30_PIPE_PCLK, + "phyclk_usbhost30_uhost30_pipe_pclk", + "mout_phyclk_usbhost30_uhost30_pipe_pclk_user", + ENABLE_SCLK_FSYS, 18, 0, 0), + GATE(CLK_PHYCLK_USBHOST30_UHOST30_PHYCLOCK, + "phyclk_usbhost30_uhost30_phyclock", + "mout_phyclk_usbhost30_uhost30_phyclock_user", + ENABLE_SCLK_FSYS, 17, 0, 0), + GATE(CLK_PHYCLK_UFS_RX1_SYMBOL, "phyclk_ufs_rx1_symbol", + "mout_phyclk_ufs_rx1_symbol_user", ENABLE_SCLK_FSYS, + 16, 0, 0), + GATE(CLK_PHYCLK_UFS_RX0_SYMBOL, "phyclk_ufs_rx0_symbol", + "mout_phyclk_ufs_rx0_symbol_user", ENABLE_SCLK_FSYS, + 15, 0, 0), + GATE(CLK_PHYCLK_UFS_TX1_SYMBOL, "phyclk_ufs_tx1_symbol", + "mout_phyclk_ufs_tx1_symbol_user", ENABLE_SCLK_FSYS, + 14, 0, 0), + GATE(CLK_PHYCLK_UFS_TX0_SYMBOL, "phyclk_ufs_tx0_symbol", + "mout_phyclk_ufs_tx0_symbol_user", ENABLE_SCLK_FSYS, + 13, 0, 0), + GATE(CLK_PHYCLK_USBHOST20_PHY_HSIC1, "phyclk_usbhost20_phy_hsic1", + "mout_phyclk_usbhost20_phy_hsic1", ENABLE_SCLK_FSYS, + 12, 0, 0), + GATE(CLK_PHYCLK_USBHOST20_PHY_CLK48MOHCI, + "phyclk_usbhost20_phy_clk48mohci", + "mout_phyclk_usbhost20_phy_clk48mohci_user", + ENABLE_SCLK_FSYS, 11, 0, 0), + GATE(CLK_PHYCLK_USBHOST20_PHY_PHYCLOCK, + "phyclk_usbhost20_phy_phyclock", + "mout_phyclk_usbhost20_phy_phyclock_user", + ENABLE_SCLK_FSYS, 10, 0, 0), + GATE(CLK_PHYCLK_USBHOST20_PHY_FREECLK, + "phyclk_usbhost20_phy_freeclk", + "mout_phyclk_usbhost20_phy_freeclk_user", + ENABLE_SCLK_FSYS, 9, 0, 0), + GATE(CLK_PHYCLK_USBDRD30_UDRD30_PIPE_PCLK, + "phyclk_usbdrd30_udrd30_pipe_pclk", + "mout_phyclk_usbdrd30_udrd30_pipe_pclk_user", + ENABLE_SCLK_FSYS, 8, 0, 0), + GATE(CLK_PHYCLK_USBDRD30_UDRD30_PHYCLOCK, + "phyclk_usbdrd30_udrd30_phyclock", + "mout_phyclk_usbdrd30_udrd30_phyclock_user", + ENABLE_SCLK_FSYS, 7, 0, 0), + GATE(CLK_SCLK_MPHY, "sclk_mphy", "mout_sclk_mphy", + ENABLE_SCLK_FSYS, 6, 0, 0), + GATE(CLK_SCLK_UFSUNIPRO, "sclk_ufsunipro", "mout_sclk_ufsunipro_user", + ENABLE_SCLK_FSYS, 5, 0, 0), GATE(CLK_SCLK_MMC2, "sclk_mmc2", "mout_sclk_mmc2_user", ENABLE_SCLK_FSYS, 4, CLK_SET_RATE_PARENT, 0), GATE(CLK_SCLK_MMC1, "sclk_mmc1", "mout_sclk_mmc1_user", ENABLE_SCLK_FSYS, 3, CLK_SET_RATE_PARENT, 0), GATE(CLK_SCLK_MMC0, "sclk_mmc0", "mout_sclk_mmc0_user", ENABLE_SCLK_FSYS, 2, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_USBHOST30, "sclk_usbhost30", "mout_sclk_usbhost30_user", + ENABLE_SCLK_FSYS, 1, 0, 0), + GATE(CLK_SCLK_USBDRD30, "sclk_usbdrd30", "mout_sclk_usbdrd30_user", + ENABLE_SCLK_FSYS, 0, 0, 0), /* ENABLE_IP_FSYS0 */ GATE(CLK_PDMA1, "pdma1", "aclk_pdma1", ENABLE_IP_FSYS0, 15, 0, 0), @@ -1920,6 +2220,8 @@ static struct samsung_cmu_info fsys_cmu_info __initdata = { .nr_mux_clks = ARRAY_SIZE(fsys_mux_clks), .gate_clks = fsys_gate_clks, .nr_gate_clks = ARRAY_SIZE(fsys_gate_clks), + .fixed_clks = fsys_fixed_clks, + .nr_fixed_clks = ARRAY_SIZE(fsys_fixed_clks), .nr_clk_ids = FSYS_NR_CLK, .clk_regs = fsys_clk_regs, .nr_clk_regs = ARRAY_SIZE(fsys_clk_regs), diff --git a/include/dt-bindings/clock/exynos5433.h b/include/dt-bindings/clock/exynos5433.h index 8d388e700a80..294a2d0a67ff 100644 --- a/include/dt-bindings/clock/exynos5433.h +++ b/include/dt-bindings/clock/exynos5433.h @@ -110,6 +110,10 @@ #define CLK_DIV_ACLK_G3D_400 137 #define CLK_DIV_ACLK_BUS0_400 138 #define CLK_DIV_ACLK_BUS1_400 139 +#define CLK_DIV_SCLK_PCIE_100 140 +#define CLK_DIV_SCLK_USBHOST30 141 +#define CLK_DIV_SCLK_UFSUNIPRO 142 +#define CLK_DIV_SCLK_USBDRD30 143 #define CLK_ACLK_PERIC_66 200 #define CLK_ACLK_PERIS_66 201 @@ -139,8 +143,12 @@ #define CLK_ACLK_BUS1_400 225 #define CLK_ACLK_IMEM_200 226 #define CLK_ACLK_IMEM_266 227 +#define CLK_SCLK_PCIE_100_FSYS 228 +#define CLK_SCLK_UFSUNIPRO_FSYS 229 +#define CLK_SCLK_USBHOST30_FSYS 230 +#define CLK_SCLK_USBDRD30_FSYS 231 -#define TOP_NR_CLK 228 +#define TOP_NR_CLK 232 /* CMU_CPIF */ #define CLK_FOUT_MPHY_PLL 1 @@ -473,6 +481,39 @@ #define CLK_MOUT_SCLK_MMC2_USER 2 #define CLK_MOUT_SCLK_MMC1_USER 3 #define CLK_MOUT_SCLK_MMC0_USER 4 +#define CLK_MOUT_SCLK_UFS_MPHY_USER 5 +#define CLK_MOUT_SCLK_PCIE_100_USER 6 +#define CLK_MOUT_SCLK_UFSUNIPRO_USER 7 +#define CLK_MOUT_SCLK_USBHOST30_USER 8 +#define CLK_MOUT_SCLK_USBDRD30_USER 9 +#define CLK_MOUT_PHYCLK_USBHOST30_UHOST30_PIPE_PCLK_USER 10 +#define CLK_MOUT_PHYCLK_USBHOST30_UHOST30_PHYCLOCK_USER 11 +#define CLK_MOUT_PHYCLK_USBHOST20_PHY_HSIC1_USER 12 +#define CLK_MOUT_PHYCLK_USBHOST20_PHY_CLK48MOHCI_USER 13 +#define CLK_MOUT_PHYCLK_USBHOST20_PHY_PHYCLOCK_USER 14 +#define CLK_MOUT_PHYCLK_USBHOST20_PHY_PHY_FREECLK_USER 15 +#define CLK_MOUT_PHYCLK_USBDRD30_UDRD30_PIPE_PCLK_USER 16 +#define CLK_MOUT_PHYCLK_USBDRD30_UDRD30_PHYCLOCK_USER 17 +#define CLK_MOUT_PHYCLK_UFS_RX1_SYMBOL_USER 18 +#define CLK_MOUT_PHYCLK_UFS_RX0_SYMBOL_USER 19 +#define CLK_MOUT_PHYCLK_UFS_TX1_SYMBOL_USER 20 +#define CLK_MOUT_PHYCLK_UFS_TX0_SYMBOL_USER 21 +#define CLK_MOUT_PHYCLK_LLI_MPHY_TO_UFS_USER 22 +#define CLK_MOUT_SCLK_MPHY 23 + +#define CLK_PHYCLK_USBDRD30_UDRD30_PHYCLOCK_PHY 25 +#define CLK_PHYCLK_USBDRD30_UDRD30_PIPE_PCLK_PHY 26 +#define CLK_PHYCLK_USBHOST30_UHOST30_PHYCLOCK_PHY 27 +#define CLK_PHYCLK_USBHOST30_UHOST30_PIPE_PCLK_PHY 28 +#define CLK_PHYCLK_USBHOST20_PHY_FREECLK_PHY 29 +#define CLK_PHYCLK_USBHOST20_PHY_PHYCLOCK_PHY 30 +#define CLK_PHYCLK_USBHOST20_PHY_CLK48MOHCI_PHY 31 +#define CLK_PHYCLK_USBHOST20_PHY_HSIC1_PHY 32 +#define CLK_PHYCLK_UFS_TX0_SYMBOL_PHY 33 +#define CLK_PHYCLK_UFS_RX0_SYMBOL_PHY 34 +#define CLK_PHYCLK_UFS_TX1_SYMBOL_PHY 35 +#define CLK_PHYCLK_UFS_RX1_SYMBOL_PHY 36 +#define CLK_PHYCLK_LLI_MPHY_TO_UFS_PHY 37 #define CLK_ACLK_PCIE 50 #define CLK_ACLK_PDMA1 51 @@ -490,8 +531,57 @@ #define CLK_SCLK_MMC0 63 #define CLK_PDMA1 64 #define CLK_PDMA0 65 - -#define FSYS_NR_CLK 66 +#define CLK_ACLK_XIU_FSYSPX 66 +#define CLK_ACLK_AHB_USBLINKH1 67 +#define CLK_ACLK_SMMU_PDMA1 68 +#define CLK_ACLK_BTS_PCIE 69 +#define CLK_ACLK_AXIUS_PDMA1 70 +#define CLK_ACLK_SMMU_PDMA0 71 +#define CLK_ACLK_BTS_UFS 72 +#define CLK_ACLK_BTS_USBHOST30 73 +#define CLK_ACLK_BTS_USBDRD30 74 +#define CLK_ACLK_AXIUS_PDMA0 75 +#define CLK_ACLK_AXIUS_USBHS 76 +#define CLK_ACLK_AXIUS_FSYSSX 77 +#define CLK_ACLK_AHB2APB_FSYSP 78 +#define CLK_ACLK_AHB2AXI_USBHS 79 +#define CLK_ACLK_AHB_USBLINKH0 80 +#define CLK_ACLK_AHB_USBHS 81 +#define CLK_ACLK_AHB_FSYSH 82 +#define CLK_ACLK_XIU_FSYSX 83 +#define CLK_ACLK_XIU_FSYSSX 84 +#define CLK_ACLK_FSYSNP_200 85 +#define CLK_ACLK_FSYSND_200 86 +#define CLK_PCLK_PCIE_CTRL 87 +#define CLK_PCLK_SMMU_PDMA1 88 +#define CLK_PCLK_PCIE_PHY 89 +#define CLK_PCLK_BTS_PCIE 90 +#define CLK_PCLK_SMMU_PDMA0 91 +#define CLK_PCLK_BTS_UFS 92 +#define CLK_PCLK_BTS_USBHOST30 93 +#define CLK_PCLK_BTS_USBDRD30 94 +#define CLK_PCLK_GPIO_FSYS 95 +#define CLK_PCLK_PMU_FSYS 96 +#define CLK_PCLK_SYSREG_FSYS 97 +#define CLK_SCLK_PCIE_100 98 +#define CLK_PHYCLK_USBHOST30_UHOST30_PIPE_PCLK 99 +#define CLK_PHYCLK_USBHOST30_UHOST30_PHYCLOCK 100 +#define CLK_PHYCLK_UFS_RX1_SYMBOL 101 +#define CLK_PHYCLK_UFS_RX0_SYMBOL 102 +#define CLK_PHYCLK_UFS_TX1_SYMBOL 103 +#define CLK_PHYCLK_UFS_TX0_SYMBOL 104 +#define CLK_PHYCLK_USBHOST20_PHY_HSIC1 105 +#define CLK_PHYCLK_USBHOST20_PHY_CLK48MOHCI 106 +#define CLK_PHYCLK_USBHOST20_PHY_PHYCLOCK 107 +#define CLK_PHYCLK_USBHOST20_PHY_FREECLK 108 +#define CLK_PHYCLK_USBDRD30_UDRD30_PIPE_PCLK 109 +#define CLK_PHYCLK_USBDRD30_UDRD30_PHYCLOCK 110 +#define CLK_SCLK_MPHY 111 +#define CLK_SCLK_UFSUNIPRO 112 +#define CLK_SCLK_USBHOST30 113 +#define CLK_SCLK_USBDRD30 114 + +#define FSYS_NR_CLK 115 /* CMU_G2D */ #define CLK_MUX_ACLK_G2D_266_USER 1 -- GitLab From 453e519e5aed806c1b70bcbe92aeab39a93dda22 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Mon, 2 Feb 2015 23:24:06 +0900 Subject: [PATCH 00044/11651] clk: samsung: exynos5433: Add clocks for CMU_G3D domain This patch adds the mux/divider/gate clocks for CMU_G3D domain which contains the clocks for GPU(3D Graphics Engine). Signed-off-by: Chanwoo Choi Acked-by: Inki Dae Reviewed-by: Pankaj Dubey Signed-off-by: Sylwester Nawrocki --- drivers/clk/samsung/clk-exynos5433.c | 127 +++++++++++++++++++++++++ include/dt-bindings/clock/exynos5433.h | 25 +++++ 2 files changed, 152 insertions(+) diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c index 1cdc47e05ac1..f422485a92c0 100644 --- a/drivers/clk/samsung/clk-exynos5433.c +++ b/drivers/clk/samsung/clk-exynos5433.c @@ -3120,3 +3120,130 @@ CLK_OF_DECLARE(exynos5433_cmu_bus##id, \ exynos5433_cmu_bus_init(0); exynos5433_cmu_bus_init(1); exynos5433_cmu_bus_init(2); + +/* + * Register offset definitions for CMU_G3D + */ +#define G3D_PLL_LOCK 0x0000 +#define G3D_PLL_CON0 0x0100 +#define G3D_PLL_CON1 0x0104 +#define G3D_PLL_FREQ_DET 0x010c +#define MUX_SEL_G3D 0x0200 +#define MUX_ENABLE_G3D 0x0300 +#define MUX_STAT_G3D 0x0400 +#define DIV_G3D 0x0600 +#define DIV_G3D_PLL_FREQ_DET 0x0604 +#define DIV_STAT_G3D 0x0700 +#define DIV_STAT_G3D_PLL_FREQ_DET 0x0704 +#define ENABLE_ACLK_G3D 0x0800 +#define ENABLE_PCLK_G3D 0x0900 +#define ENABLE_SCLK_G3D 0x0a00 +#define ENABLE_IP_G3D0 0x0b00 +#define ENABLE_IP_G3D1 0x0b04 +#define CLKOUT_CMU_G3D 0x0c00 +#define CLKOUT_CMU_G3D_DIV_STAT 0x0c04 +#define CLK_STOPCTRL 0x1000 + +static unsigned long g3d_clk_regs[] __initdata = { + G3D_PLL_LOCK, + G3D_PLL_CON0, + G3D_PLL_CON1, + G3D_PLL_FREQ_DET, + MUX_SEL_G3D, + MUX_ENABLE_G3D, + MUX_STAT_G3D, + DIV_G3D, + DIV_G3D_PLL_FREQ_DET, + DIV_STAT_G3D, + DIV_STAT_G3D_PLL_FREQ_DET, + ENABLE_ACLK_G3D, + ENABLE_PCLK_G3D, + ENABLE_SCLK_G3D, + ENABLE_IP_G3D0, + ENABLE_IP_G3D1, + CLKOUT_CMU_G3D, + CLKOUT_CMU_G3D_DIV_STAT, + CLK_STOPCTRL, +}; + +/* list of all parent clock list */ +PNAME(mout_aclk_g3d_400_p) = { "mout_g3d_pll", "aclk_g3d_400", }; +PNAME(mout_g3d_pll_p) = { "oscclk", "fout_g3d_pll", }; + +static struct samsung_pll_clock g3d_pll_clks[] __initdata = { + PLL(pll_35xx, CLK_FOUT_G3D_PLL, "fout_g3d_pll", "oscclk", + G3D_PLL_LOCK, G3D_PLL_CON0, exynos5443_pll_rates), +}; + +static struct samsung_mux_clock g3d_mux_clks[] __initdata = { + /* MUX_SEL_G3D */ + MUX(CLK_MOUT_ACLK_G3D_400, "mout_aclk_g3d_400", mout_aclk_g3d_400_p, + MUX_SEL_G3D, 8, 1), + MUX(CLK_MOUT_G3D_PLL, "mout_g3d_pll", mout_g3d_pll_p, + MUX_SEL_G3D, 0, 1), +}; + +static struct samsung_div_clock g3d_div_clks[] __initdata = { + /* DIV_G3D */ + DIV(CLK_DIV_SCLK_HPM_G3D, "div_sclk_hpm_g3d", "mout_g3d_pll", DIV_G3D, + 8, 2), + DIV(CLK_DIV_PCLK_G3D, "div_pclk_g3d", "div_aclk_g3d", DIV_G3D, + 4, 3), + DIV(CLK_DIV_ACLK_G3D, "div_aclk_g3d", "mout_aclk_g3d_400", DIV_G3D, + 0, 3), +}; + +static struct samsung_gate_clock g3d_gate_clks[] __initdata = { + /* ENABLE_ACLK_G3D */ + GATE(CLK_ACLK_BTS_G3D1, "aclk_bts_g3d1", "div_aclk_g3d", + ENABLE_ACLK_G3D, 7, 0, 0), + GATE(CLK_ACLK_BTS_G3D0, "aclk_bts_g3d0", "div_aclk_g3d", + ENABLE_ACLK_G3D, 6, 0, 0), + GATE(CLK_ACLK_ASYNCAPBS_G3D, "aclk_asyncapbs_g3d", "div_pclk_g3d", + ENABLE_ACLK_G3D, 5, 0, 0), + GATE(CLK_ACLK_ASYNCAPBM_G3D, "aclk_asyncapbm_g3d", "div_aclk_g3d", + ENABLE_ACLK_G3D, 4, 0, 0), + GATE(CLK_ACLK_AHB2APB_G3DP, "aclk_ahb2apb_g3dp", "div_pclk_g3d", + ENABLE_ACLK_G3D, 3, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_G3DNP_150, "aclk_g3dnp_150", "div_pclk_g3d", + ENABLE_ACLK_G3D, 2, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_G3DND_600, "aclk_g3dnd_600", "div_aclk_g3d", + ENABLE_ACLK_G3D, 1, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_G3D, "aclk_g3d", "div_aclk_g3d", + ENABLE_ACLK_G3D, 0, 0, 0), + + /* ENABLE_PCLK_G3D */ + GATE(CLK_PCLK_BTS_G3D1, "pclk_bts_g3d1", "div_pclk_g3d", + ENABLE_PCLK_G3D, 3, 0, 0), + GATE(CLK_PCLK_BTS_G3D0, "pclk_bts_g3d0", "div_pclk_g3d", + ENABLE_PCLK_G3D, 2, 0, 0), + GATE(CLK_PCLK_PMU_G3D, "pclk_pmu_g3d", "div_pclk_g3d", + ENABLE_PCLK_G3D, 1, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_SYSREG_G3D, "pclk_sysreg_g3d", "div_pclk_g3d", + ENABLE_PCLK_G3D, 0, CLK_IGNORE_UNUSED, 0), + + /* ENABLE_SCLK_G3D */ + GATE(CLK_SCLK_HPM_G3D, "sclk_hpm_g3d", "div_sclk_hpm_g3d", + ENABLE_SCLK_G3D, 0, 0, 0), +}; + +static struct samsung_cmu_info g3d_cmu_info __initdata = { + .pll_clks = g3d_pll_clks, + .nr_pll_clks = ARRAY_SIZE(g3d_pll_clks), + .mux_clks = g3d_mux_clks, + .nr_mux_clks = ARRAY_SIZE(g3d_mux_clks), + .div_clks = g3d_div_clks, + .nr_div_clks = ARRAY_SIZE(g3d_div_clks), + .gate_clks = g3d_gate_clks, + .nr_gate_clks = ARRAY_SIZE(g3d_gate_clks), + .nr_clk_ids = G3D_NR_CLK, + .clk_regs = g3d_clk_regs, + .nr_clk_regs = ARRAY_SIZE(g3d_clk_regs), +}; + +static void __init exynos5433_cmu_g3d_init(struct device_node *np) +{ + samsung_cmu_register_one(np, &g3d_cmu_info); +} +CLK_OF_DECLARE(exynos5433_cmu_g3d, "samsung,exynos5433-cmu-g3d", + exynos5433_cmu_g3d_init); diff --git a/include/dt-bindings/clock/exynos5433.h b/include/dt-bindings/clock/exynos5433.h index 294a2d0a67ff..60ccc169e9ff 100644 --- a/include/dt-bindings/clock/exynos5433.h +++ b/include/dt-bindings/clock/exynos5433.h @@ -794,4 +794,29 @@ #define BUSx_NR_CLK 11 +/* CMU_G3D */ +#define CLK_FOUT_G3D_PLL 1 + +#define CLK_MOUT_ACLK_G3D_400 2 +#define CLK_MOUT_G3D_PLL 3 + +#define CLK_DIV_SCLK_HPM_G3D 4 +#define CLK_DIV_PCLK_G3D 5 +#define CLK_DIV_ACLK_G3D 6 +#define CLK_ACLK_BTS_G3D1 7 +#define CLK_ACLK_BTS_G3D0 8 +#define CLK_ACLK_ASYNCAPBS_G3D 9 +#define CLK_ACLK_ASYNCAPBM_G3D 10 +#define CLK_ACLK_AHB2APB_G3DP 11 +#define CLK_ACLK_G3DNP_150 12 +#define CLK_ACLK_G3DND_600 13 +#define CLK_ACLK_G3D 14 +#define CLK_PCLK_BTS_G3D1 15 +#define CLK_PCLK_BTS_G3D0 16 +#define CLK_PCLK_PMU_G3D 17 +#define CLK_PCLK_SYSREG_G3D 18 +#define CLK_SCLK_HPM_G3D 19 + +#define G3D_NR_CLK 20 + #endif /* _DT_BINDINGS_CLOCK_EXYNOS5433_H */ -- GitLab From 2a2f33e83ddb6c0abe3d32075f795aa14e4b9476 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Mon, 2 Feb 2015 23:24:07 +0900 Subject: [PATCH 00045/11651] clk: samsung: exynos5433: Add clocks for CMU_GSCL domain This patch adds the divider/gate of CMU_GSCL domain which contains gscaler clocks. Signed-off-by: Chanwoo Choi Acked-by: Inki Dae Signed-off-by: Sylwester Nawrocki --- drivers/clk/samsung/clk-exynos5433.c | 146 +++++++++++++++++++++++++ include/dt-bindings/clock/exynos5433.h | 37 ++++++- 2 files changed, 182 insertions(+), 1 deletion(-) diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c index f422485a92c0..12f60c6a5a7a 100644 --- a/drivers/clk/samsung/clk-exynos5433.c +++ b/drivers/clk/samsung/clk-exynos5433.c @@ -545,6 +545,12 @@ static struct samsung_gate_clock top_gate_clks[] __initdata = { GATE(CLK_ACLK_FSYS_200, "aclk_fsys_200", "div_aclk_fsys_200", ENABLE_ACLK_TOP, 18, CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_GSCL_111, "aclk_gscl_111", "div_aclk_gscl_111", + ENABLE_ACLK_TOP, 15, + CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_GSCL_333, "aclk_gscl_333", "div_aclk_gscl_333", + ENABLE_ACLK_TOP, 14, + CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0), GATE(CLK_ACLK_G2D_266, "aclk_g2d_266", "div_aclk_g2d_266", ENABLE_ACLK_TOP, 2, CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0), @@ -3247,3 +3253,143 @@ static void __init exynos5433_cmu_g3d_init(struct device_node *np) } CLK_OF_DECLARE(exynos5433_cmu_g3d, "samsung,exynos5433-cmu-g3d", exynos5433_cmu_g3d_init); + +/* + * Register offset definitions for CMU_GSCL + */ +#define MUX_SEL_GSCL 0x0200 +#define MUX_ENABLE_GSCL 0x0300 +#define MUX_STAT_GSCL 0x0400 +#define ENABLE_ACLK_GSCL 0x0800 +#define ENABLE_ACLK_GSCL_SECURE_SMMU_GSCL0 0x0804 +#define ENABLE_ACLK_GSCL_SECURE_SMMU_GSCL1 0x0808 +#define ENABLE_ACLK_GSCL_SECURE_SMMU_GSCL2 0x080c +#define ENABLE_PCLK_GSCL 0x0900 +#define ENABLE_PCLK_GSCL_SECURE_SMMU_GSCL0 0x0904 +#define ENABLE_PCLK_GSCL_SECURE_SMMU_GSCL1 0x0908 +#define ENABLE_PCLK_GSCL_SECURE_SMMU_GSCL2 0x090c +#define ENABLE_IP_GSCL0 0x0b00 +#define ENABLE_IP_GSCL1 0x0b04 +#define ENABLE_IP_GSCL_SECURE_SMMU_GSCL0 0x0b08 +#define ENABLE_IP_GSCL_SECURE_SMMU_GSCL1 0x0b0c +#define ENABLE_IP_GSCL_SECURE_SMMU_GSCL2 0x0b10 + +static unsigned long gscl_clk_regs[] __initdata = { + MUX_SEL_GSCL, + MUX_ENABLE_GSCL, + MUX_STAT_GSCL, + ENABLE_ACLK_GSCL, + ENABLE_ACLK_GSCL_SECURE_SMMU_GSCL0, + ENABLE_ACLK_GSCL_SECURE_SMMU_GSCL1, + ENABLE_ACLK_GSCL_SECURE_SMMU_GSCL2, + ENABLE_PCLK_GSCL, + ENABLE_PCLK_GSCL_SECURE_SMMU_GSCL0, + ENABLE_PCLK_GSCL_SECURE_SMMU_GSCL1, + ENABLE_PCLK_GSCL_SECURE_SMMU_GSCL2, + ENABLE_IP_GSCL0, + ENABLE_IP_GSCL1, + ENABLE_IP_GSCL_SECURE_SMMU_GSCL0, + ENABLE_IP_GSCL_SECURE_SMMU_GSCL1, + ENABLE_IP_GSCL_SECURE_SMMU_GSCL2, +}; + +/* list of all parent clock list */ +PNAME(aclk_gscl_111_user_p) = { "oscclk", "aclk_gscl_111", }; +PNAME(aclk_gscl_333_user_p) = { "oscclk", "aclk_gscl_333", }; + +static struct samsung_mux_clock gscl_mux_clks[] __initdata = { + /* MUX_SEL_GSCL */ + MUX(CLK_MOUT_ACLK_GSCL_111_USER, "mout_aclk_gscl_111_user", + aclk_gscl_111_user_p, MUX_SEL_GSCL, 4, 1), + MUX(CLK_MOUT_ACLK_GSCL_333_USER, "mout_aclk_gscl_333_user", + aclk_gscl_333_user_p, MUX_SEL_GSCL, 0, 1), +}; + +static struct samsung_gate_clock gscl_gate_clks[] __initdata = { + /* ENABLE_ACLK_GSCL */ + GATE(CLK_ACLK_BTS_GSCL2, "aclk_bts_gscl2", "mout_aclk_gscl_333_user", + ENABLE_ACLK_GSCL, 11, 0, 0), + GATE(CLK_ACLK_BTS_GSCL1, "aclk_bts_gscl1", "mout_aclk_gscl_333_user", + ENABLE_ACLK_GSCL, 10, 0, 0), + GATE(CLK_ACLK_BTS_GSCL0, "aclk_bts_gscl0", "mout_aclk_gscl_333_user", + ENABLE_ACLK_GSCL, 9, 0, 0), + GATE(CLK_ACLK_AHB2APB_GSCLP, "aclk_ahb2apb_gsclp", + "mout_aclk_gscl_111_user", ENABLE_ACLK_GSCL, + 8, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_XIU_GSCLX, "aclk_xiu_gsclx", "mout_aclk_gscl_333_user", + ENABLE_ACLK_GSCL, 7, 0, 0), + GATE(CLK_ACLK_GSCLNP_111, "aclk_gsclnp_111", "mout_aclk_gscl_111_user", + ENABLE_ACLK_GSCL, 6, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_GSCLRTND_333, "aclk_gsclrtnd_333", + "mout_aclk_gscl_333_user", ENABLE_ACLK_GSCL, 5, 0, 0), + GATE(CLK_ACLK_GSCLBEND_333, "aclk_gsclbend_333", + "mout_aclk_gscl_333_user", ENABLE_ACLK_GSCL, 4, 0, 0), + GATE(CLK_ACLK_GSD, "aclk_gsd", "mout_aclk_gscl_333_user", + ENABLE_ACLK_GSCL, 3, 0, 0), + GATE(CLK_ACLK_GSCL2, "aclk_gscl2", "mout_aclk_gscl_333_user", + ENABLE_ACLK_GSCL, 2, 0, 0), + GATE(CLK_ACLK_GSCL1, "aclk_gscl1", "mout_aclk_gscl_333_user", + ENABLE_ACLK_GSCL, 1, 0, 0), + GATE(CLK_ACLK_GSCL0, "aclk_gscl0", "mout_aclk_gscl_333_user", + ENABLE_ACLK_GSCL, 0, 0, 0), + + /* ENABLE_ACLK_GSCL_SECURE_SMMU_GSCL0 */ + GATE(CLK_ACLK_SMMU_GSCL0, "aclk_smmu_gscl0", "mout_aclk_gscl_333_user", + ENABLE_ACLK_GSCL_SECURE_SMMU_GSCL0, 0, 0, 0), + + /* ENABLE_ACLK_GSCL_SECURE_SMMU_GSCL1 */ + GATE(CLK_ACLK_SMMU_GSCL1, "aclk_smmu_gscl1", "mout_aclk_gscl_333_user", + ENABLE_ACLK_GSCL_SECURE_SMMU_GSCL1, 0, 0, 0), + + /* ENABLE_ACLK_GSCL_SECURE_SMMU_GSCL2 */ + GATE(CLK_ACLK_SMMU_GSCL2, "aclk_smmu_gscl2", "mout_aclk_gscl_333_user", + ENABLE_ACLK_GSCL_SECURE_SMMU_GSCL2, 0, 0, 0), + + /* ENABLE_PCLK_GSCL */ + GATE(CLK_PCLK_BTS_GSCL2, "pclk_bts_gscl2", "mout_aclk_gscl_111_user", + ENABLE_PCLK_GSCL, 7, 0, 0), + GATE(CLK_PCLK_BTS_GSCL1, "pclk_bts_gscl1", "mout_aclk_gscl_111_user", + ENABLE_PCLK_GSCL, 6, 0, 0), + GATE(CLK_PCLK_BTS_GSCL0, "pclk_bts_gscl0", "mout_aclk_gscl_111_user", + ENABLE_PCLK_GSCL, 5, 0, 0), + GATE(CLK_PCLK_PMU_GSCL, "pclk_pmu_gscl", "mout_aclk_gscl_111_user", + ENABLE_PCLK_GSCL, 4, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_SYSREG_GSCL, "pclk_sysreg_gscl", + "mout_aclk_gscl_111_user", ENABLE_PCLK_GSCL, + 3, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_GSCL2, "pclk_gscl2", "mout_aclk_gscl_111_user", + ENABLE_PCLK_GSCL, 2, 0, 0), + GATE(CLK_PCLK_GSCL1, "pclk_gscl1", "mout_aclk_gscl_111_user", + ENABLE_PCLK_GSCL, 1, 0, 0), + GATE(CLK_PCLK_GSCL0, "pclk_gscl0", "mout_aclk_gscl_111_user", + ENABLE_PCLK_GSCL, 0, 0, 0), + + /* ENABLE_PCLK_GSCL_SECURE_SMMU_GSCL0 */ + GATE(CLK_PCLK_SMMU_GSCL0, "pclk_smmu_gscl0", "mout_aclk_gscl_111_user", + ENABLE_PCLK_GSCL_SECURE_SMMU_GSCL0, 0, 0, 0), + + /* ENABLE_PCLK_GSCL_SECURE_SMMU_GSCL1 */ + GATE(CLK_PCLK_SMMU_GSCL1, "pclk_smmu_gscl1", "mout_aclk_gscl_111_user", + ENABLE_PCLK_GSCL_SECURE_SMMU_GSCL0, 0, 0, 0), + + /* ENABLE_PCLK_GSCL_SECURE_SMMU_GSCL2 */ + GATE(CLK_PCLK_SMMU_GSCL2, "pclk_smmu_gscl2", "mout_aclk_gscl_111_user", + ENABLE_PCLK_GSCL_SECURE_SMMU_GSCL0, 0, 0, 0), +}; + +static struct samsung_cmu_info gscl_cmu_info __initdata = { + .mux_clks = gscl_mux_clks, + .nr_mux_clks = ARRAY_SIZE(gscl_mux_clks), + .gate_clks = gscl_gate_clks, + .nr_gate_clks = ARRAY_SIZE(gscl_gate_clks), + .nr_clk_ids = GSCL_NR_CLK, + .clk_regs = gscl_clk_regs, + .nr_clk_regs = ARRAY_SIZE(gscl_clk_regs), +}; + +static void __init exynos5433_cmu_gscl_init(struct device_node *np) +{ + samsung_cmu_register_one(np, &gscl_cmu_info); +} +CLK_OF_DECLARE(exynos5433_cmu_gscl, "samsung,exynos5433-cmu-gscl", + exynos5433_cmu_gscl_init); diff --git a/include/dt-bindings/clock/exynos5433.h b/include/dt-bindings/clock/exynos5433.h index 60ccc169e9ff..fef8893c3ec2 100644 --- a/include/dt-bindings/clock/exynos5433.h +++ b/include/dt-bindings/clock/exynos5433.h @@ -147,8 +147,10 @@ #define CLK_SCLK_UFSUNIPRO_FSYS 229 #define CLK_SCLK_USBHOST30_FSYS 230 #define CLK_SCLK_USBDRD30_FSYS 231 +#define CLK_ACLK_GSCL_111 232 +#define CLK_ACLK_GSCL_333 233 -#define TOP_NR_CLK 232 +#define TOP_NR_CLK 234 /* CMU_CPIF */ #define CLK_FOUT_MPHY_PLL 1 @@ -819,4 +821,37 @@ #define G3D_NR_CLK 20 +/* CMU_GSCL */ +#define CLK_MOUT_ACLK_GSCL_111_USER 1 +#define CLK_MOUT_ACLK_GSCL_333_USER 2 + +#define CLK_ACLK_BTS_GSCL2 3 +#define CLK_ACLK_BTS_GSCL1 4 +#define CLK_ACLK_BTS_GSCL0 5 +#define CLK_ACLK_AHB2APB_GSCLP 6 +#define CLK_ACLK_XIU_GSCLX 7 +#define CLK_ACLK_GSCLNP_111 8 +#define CLK_ACLK_GSCLRTND_333 9 +#define CLK_ACLK_GSCLBEND_333 10 +#define CLK_ACLK_GSD 11 +#define CLK_ACLK_GSCL2 12 +#define CLK_ACLK_GSCL1 13 +#define CLK_ACLK_GSCL0 14 +#define CLK_ACLK_SMMU_GSCL0 15 +#define CLK_ACLK_SMMU_GSCL1 16 +#define CLK_ACLK_SMMU_GSCL2 17 +#define CLK_PCLK_BTS_GSCL2 18 +#define CLK_PCLK_BTS_GSCL1 19 +#define CLK_PCLK_BTS_GSCL0 20 +#define CLK_PCLK_PMU_GSCL 21 +#define CLK_PCLK_SYSREG_GSCL 22 +#define CLK_PCLK_GSCL2 23 +#define CLK_PCLK_GSCL1 24 +#define CLK_PCLK_GSCL0 25 +#define CLK_PCLK_SMMU_GSCL0 26 +#define CLK_PCLK_SMMU_GSCL1 27 +#define CLK_PCLK_SMMU_GSCL2 28 + +#define GSCL_NR_CLK 29 + #endif /* _DT_BINDINGS_CLOCK_EXYNOS5433_H */ -- GitLab From 6da9b382bd2b6e1b910d7e3512a8a115c8c5f113 Mon Sep 17 00:00:00 2001 From: Octavian Purdila Date: Sat, 31 Jan 2015 02:00:00 +0200 Subject: [PATCH 00046/11651] iio: buffer: refactor buffer attributes setup Move all core (non-custom) buffer attributes to a vector to make it easier to add more of them in the future. Signed-off-by: Octavian Purdila Signed-off-by: Jonathan Cameron --- drivers/iio/industrialio-buffer.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index 71333140d42c..c2d5440aa226 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -761,6 +761,11 @@ static struct device_attribute dev_attr_length_ro = __ATTR(length, static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, iio_buffer_show_enable, iio_buffer_store_enable); +static struct attribute *iio_buffer_attrs[] = { + &dev_attr_length.attr, + &dev_attr_enable.attr, +}; + int iio_buffer_alloc_sysfs_and_mask(struct iio_dev *indio_dev) { struct iio_dev_attr *p; @@ -778,21 +783,23 @@ int iio_buffer_alloc_sysfs_and_mask(struct iio_dev *indio_dev) attrcount++; } - buffer->buffer_group.name = "buffer"; - buffer->buffer_group.attrs = kcalloc(attrcount + 3, - sizeof(*buffer->buffer_group.attrs), GFP_KERNEL); - if (!buffer->buffer_group.attrs) + attr = kcalloc(attrcount + ARRAY_SIZE(iio_buffer_attrs) + 1, + sizeof(struct attribute *), GFP_KERNEL); + if (!attr) return -ENOMEM; - if (buffer->access->set_length) - buffer->buffer_group.attrs[0] = &dev_attr_length.attr; - else - buffer->buffer_group.attrs[0] = &dev_attr_length_ro.attr; - buffer->buffer_group.attrs[1] = &dev_attr_enable.attr; + memcpy(attr, iio_buffer_attrs, sizeof(iio_buffer_attrs)); + if (!buffer->access->set_length) + attr[0] = &dev_attr_length_ro.attr; + if (buffer->attrs) - memcpy(&buffer->buffer_group.attrs[2], buffer->attrs, - sizeof(*&buffer->buffer_group.attrs) * attrcount); - buffer->buffer_group.attrs[attrcount+2] = NULL; + memcpy(&attr[ARRAY_SIZE(iio_buffer_attrs)], buffer->attrs, + sizeof(struct attribute *) * attrcount); + + attr[attrcount + ARRAY_SIZE(iio_buffer_attrs)] = NULL; + + buffer->buffer_group.name = "buffer"; + buffer->buffer_group.attrs = attr; indio_dev->groups[indio_dev->groupcounter++] = &buffer->buffer_group; -- GitLab From df40a13ca53e6f83ead88e718dd96654e75365ec Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Tue, 3 Feb 2015 09:13:49 +0900 Subject: [PATCH 00047/11651] clk: samsung: exynos5433: Add clocks for CMU_APOLLO domain This patch adds the mux/divider/gate clocks for CMU_APOLLO domain which generates the clocks for Cortex-A53 Quad-core processsor. Signed-off-by: Chanwoo Choi Acked-by: Inki Dae [s.nawrocki@samsung.com: Renamed pclk_pmu_sysreg_apollo to pclk_sysreg_apollo] Signed-off-by: Sylwester Nawrocki --- .../bindings/clock/exynos5433-clock.txt | 15 ++ drivers/clk/samsung/clk-exynos5433.c | 193 ++++++++++++++++++ include/dt-bindings/clock/exynos5433.h | 37 ++++ 3 files changed, 245 insertions(+) diff --git a/Documentation/devicetree/bindings/clock/exynos5433-clock.txt b/Documentation/devicetree/bindings/clock/exynos5433-clock.txt index 9e7ed2d43a15..0a7146861a27 100644 --- a/Documentation/devicetree/bindings/clock/exynos5433-clock.txt +++ b/Documentation/devicetree/bindings/clock/exynos5433-clock.txt @@ -32,6 +32,8 @@ Required Properties: which generates clocks for 3D Graphics Engine IP. - "samsung,exynos5433-cmu-gscl" - clock controller compatible for CMU_GSCL which generates clocks for GSCALER IPs. + - "samsung,exynos5433-cmu-apollo"- clock controller compatible for CMU_APOLLO + which generates clocks for Cortex-A53 Quad-core processor. - reg: physical base address of the controller and length of memory mapped region. @@ -105,6 +107,10 @@ Required Properties: - aclk_gscl_111 - aclk_gscl_333 + Input clocks for apollo clock controller: + - oscclk + - sclk_bus_pll_apollo + Each clock is assigned an identifier and client nodes can use this identifier to specify the clock which they consume. @@ -289,6 +295,15 @@ Example 2: Examples of clock controller nodes are listed below. <&cmu_top CLK_ACLK_GSCL_333>; }; + cmu_apollo: clock-controller@11900000 { + compatible = "samsung,exynos5433-cmu-apollo"; + reg = <0x11900000 0x1088>; + #clock-cells = <1>; + + clock-names = "oscclk", "sclk_bus_pll_apollo"; + clocks = <&xxti>, <&cmu_mif CLK_SCLK_BUS_PLL_APOLLO>; + }; + Example 3: UART controller node that consumes the clock generated by the clock controller. diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c index 12f60c6a5a7a..f7d1e8390cdf 100644 --- a/drivers/clk/samsung/clk-exynos5433.c +++ b/drivers/clk/samsung/clk-exynos5433.c @@ -3393,3 +3393,196 @@ static void __init exynos5433_cmu_gscl_init(struct device_node *np) } CLK_OF_DECLARE(exynos5433_cmu_gscl, "samsung,exynos5433-cmu-gscl", exynos5433_cmu_gscl_init); + +/* + * Register offset definitions for CMU_APOLLO + */ +#define APOLLO_PLL_LOCK 0x0000 +#define APOLLO_PLL_CON0 0x0100 +#define APOLLO_PLL_CON1 0x0104 +#define APOLLO_PLL_FREQ_DET 0x010c +#define MUX_SEL_APOLLO0 0x0200 +#define MUX_SEL_APOLLO1 0x0204 +#define MUX_SEL_APOLLO2 0x0208 +#define MUX_ENABLE_APOLLO0 0x0300 +#define MUX_ENABLE_APOLLO1 0x0304 +#define MUX_ENABLE_APOLLO2 0x0308 +#define MUX_STAT_APOLLO0 0x0400 +#define MUX_STAT_APOLLO1 0x0404 +#define MUX_STAT_APOLLO2 0x0408 +#define DIV_APOLLO0 0x0600 +#define DIV_APOLLO1 0x0604 +#define DIV_APOLLO_PLL_FREQ_DET 0x0608 +#define DIV_STAT_APOLLO0 0x0700 +#define DIV_STAT_APOLLO1 0x0704 +#define DIV_STAT_APOLLO_PLL_FREQ_DET 0x0708 +#define ENABLE_ACLK_APOLLO 0x0800 +#define ENABLE_PCLK_APOLLO 0x0900 +#define ENABLE_SCLK_APOLLO 0x0a00 +#define ENABLE_IP_APOLLO0 0x0b00 +#define ENABLE_IP_APOLLO1 0x0b04 +#define CLKOUT_CMU_APOLLO 0x0c00 +#define CLKOUT_CMU_APOLLO_DIV_STAT 0x0c04 +#define ARMCLK_STOPCTRL 0x1000 +#define APOLLO_PWR_CTRL 0x1020 +#define APOLLO_PWR_CTRL2 0x1024 +#define APOLLO_INTR_SPREAD_ENABLE 0x1080 +#define APOLLO_INTR_SPREAD_USE_STANDBYWFI 0x1084 +#define APOLLO_INTR_SPREAD_BLOCKING_DURATION 0x1088 + +static unsigned long apollo_clk_regs[] __initdata = { + APOLLO_PLL_LOCK, + APOLLO_PLL_CON0, + APOLLO_PLL_CON1, + APOLLO_PLL_FREQ_DET, + MUX_SEL_APOLLO0, + MUX_SEL_APOLLO1, + MUX_SEL_APOLLO2, + MUX_ENABLE_APOLLO0, + MUX_ENABLE_APOLLO1, + MUX_ENABLE_APOLLO2, + MUX_STAT_APOLLO0, + MUX_STAT_APOLLO1, + MUX_STAT_APOLLO2, + DIV_APOLLO0, + DIV_APOLLO1, + DIV_APOLLO_PLL_FREQ_DET, + DIV_STAT_APOLLO0, + DIV_STAT_APOLLO1, + DIV_STAT_APOLLO_PLL_FREQ_DET, + ENABLE_ACLK_APOLLO, + ENABLE_PCLK_APOLLO, + ENABLE_SCLK_APOLLO, + ENABLE_IP_APOLLO0, + ENABLE_IP_APOLLO1, + CLKOUT_CMU_APOLLO, + CLKOUT_CMU_APOLLO_DIV_STAT, + ARMCLK_STOPCTRL, + APOLLO_PWR_CTRL, + APOLLO_PWR_CTRL2, + APOLLO_INTR_SPREAD_ENABLE, + APOLLO_INTR_SPREAD_USE_STANDBYWFI, + APOLLO_INTR_SPREAD_BLOCKING_DURATION, +}; + +/* list of all parent clock list */ +PNAME(mout_apollo_pll_p) = { "oscclk", "fout_apollo_pll", }; +PNAME(mout_bus_pll_apollo_user_p) = { "oscclk", "sclk_bus_pll_apollo", }; +PNAME(mout_apollo_p) = { "mout_apollo_pll", + "mout_bus_pll_apollo_user", }; + +static struct samsung_pll_clock apollo_pll_clks[] __initdata = { + PLL(pll_35xx, CLK_FOUT_APOLLO_PLL, "fout_apollo_pll", "oscclk", + APOLLO_PLL_LOCK, APOLLO_PLL_CON0, exynos5443_pll_rates), +}; + +static struct samsung_mux_clock apollo_mux_clks[] __initdata = { + /* MUX_SEL_APOLLO0 */ + MUX_F(CLK_MOUT_APOLLO_PLL, "mout_apollo_pll", mout_apollo_pll_p, + MUX_SEL_APOLLO0, 0, 1, 0, CLK_MUX_READ_ONLY), + + /* MUX_SEL_APOLLO1 */ + MUX(CLK_MOUT_BUS_PLL_APOLLO_USER, "mout_bus_pll_apollo_user", + mout_bus_pll_apollo_user_p, MUX_SEL_APOLLO1, 0, 1), + + /* MUX_SEL_APOLLO2 */ + MUX_F(CLK_MOUT_APOLLO, "mout_apollo", mout_apollo_p, MUX_SEL_APOLLO2, + 0, 1, 0, CLK_MUX_READ_ONLY), +}; + +static struct samsung_div_clock apollo_div_clks[] __initdata = { + /* DIV_APOLLO0 */ + DIV_F(CLK_DIV_CNTCLK_APOLLO, "div_cntclk_apollo", "div_apollo2", + DIV_APOLLO0, 24, 3, CLK_GET_RATE_NOCACHE, + CLK_DIVIDER_READ_ONLY), + DIV_F(CLK_DIV_PCLK_DBG_APOLLO, "div_pclk_dbg_apollo", "div_apollo2", + DIV_APOLLO0, 20, 3, CLK_GET_RATE_NOCACHE, + CLK_DIVIDER_READ_ONLY), + DIV_F(CLK_DIV_ATCLK_APOLLO, "div_atclk_apollo", "div_apollo2", + DIV_APOLLO0, 16, 3, CLK_GET_RATE_NOCACHE, + CLK_DIVIDER_READ_ONLY), + DIV_F(CLK_DIV_PCLK_APOLLO, "div_pclk_apollo", "div_apollo2", + DIV_APOLLO0, 12, 3, CLK_GET_RATE_NOCACHE, + CLK_DIVIDER_READ_ONLY), + DIV_F(CLK_DIV_ACLK_APOLLO, "div_aclk_apollo", "div_apollo2", + DIV_APOLLO0, 8, 3, CLK_GET_RATE_NOCACHE, + CLK_DIVIDER_READ_ONLY), + DIV_F(CLK_DIV_APOLLO2, "div_apollo2", "div_apollo1", + DIV_APOLLO0, 4, 3, CLK_GET_RATE_NOCACHE, + CLK_DIVIDER_READ_ONLY), + DIV_F(CLK_DIV_APOLLO1, "div_apollo1", "mout_apollo", + DIV_APOLLO0, 0, 3, CLK_GET_RATE_NOCACHE, + CLK_DIVIDER_READ_ONLY), + + /* DIV_APOLLO1 */ + DIV_F(CLK_DIV_SCLK_HPM_APOLLO, "div_sclk_hpm_apollo", "mout_apollo", + DIV_APOLLO1, 4, 3, CLK_GET_RATE_NOCACHE, + CLK_DIVIDER_READ_ONLY), + DIV_F(CLK_DIV_APOLLO_PLL, "div_apollo_pll", "mout_apollo", + DIV_APOLLO1, 0, 3, CLK_GET_RATE_NOCACHE, + CLK_DIVIDER_READ_ONLY), +}; + +static struct samsung_gate_clock apollo_gate_clks[] __initdata = { + /* ENABLE_ACLK_APOLLO */ + GATE(CLK_ACLK_ASATBSLV_APOLLO_3_CSSYS, "aclk_asatbslv_apollo_3_cssys", + "div_atclk_apollo", ENABLE_ACLK_APOLLO, + 6, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASATBSLV_APOLLO_2_CSSYS, "aclk_asatbslv_apollo_2_cssys", + "div_atclk_apollo", ENABLE_ACLK_APOLLO, + 5, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASATBSLV_APOLLO_1_CSSYS, "aclk_asatbslv_apollo_1_cssys", + "div_atclk_apollo", ENABLE_ACLK_APOLLO, + 4, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASATBSLV_APOLLO_0_CSSYS, "aclk_asatbslv_apollo_0_cssys", + "div_atclk_apollo", ENABLE_ACLK_APOLLO, + 3, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCACES_APOLLO_CCI, "aclk_asyncaces_apollo_cci", + "div_aclk_apollo", ENABLE_ACLK_APOLLO, + 2, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_AHB2APB_APOLLOP, "aclk_ahb2apb_apollop", + "div_pclk_apollo", ENABLE_ACLK_APOLLO, + 1, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_APOLLONP_200, "aclk_apollonp_200", + "div_pclk_apollo", ENABLE_ACLK_APOLLO, + 0, CLK_IGNORE_UNUSED, 0), + + /* ENABLE_PCLK_APOLLO */ + GATE(CLK_PCLK_ASAPBMST_CSSYS_APOLLO, "pclk_asapbmst_cssys_apollo", + "div_pclk_dbg_apollo", ENABLE_PCLK_APOLLO, + 2, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_PMU_APOLLO, "pclk_pmu_apollo", "div_pclk_apollo", + ENABLE_PCLK_APOLLO, 1, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_SYSREG_APOLLO, "pclk_sysreg_apollo", + "div_pclk_apollo", ENABLE_PCLK_APOLLO, + 0, CLK_IGNORE_UNUSED, 0), + + /* ENABLE_SCLK_APOLLO */ + GATE(CLK_CNTCLK_APOLLO, "cntclk_apollo", "div_cntclk_apollo", + ENABLE_SCLK_APOLLO, 3, CLK_IGNORE_UNUSED, 0), + GATE(CLK_SCLK_HPM_APOLLO, "sclk_hpm_apollo", "div_sclk_hpm_apollo", + ENABLE_SCLK_APOLLO, 1, CLK_IGNORE_UNUSED, 0), + GATE(CLK_SCLK_APOLLO, "sclk_apollo", "div_apollo_pll", + ENABLE_SCLK_APOLLO, 0, CLK_IGNORE_UNUSED, 0), +}; + +static struct samsung_cmu_info apollo_cmu_info __initdata = { + .pll_clks = apollo_pll_clks, + .nr_pll_clks = ARRAY_SIZE(apollo_pll_clks), + .mux_clks = apollo_mux_clks, + .nr_mux_clks = ARRAY_SIZE(apollo_mux_clks), + .div_clks = apollo_div_clks, + .nr_div_clks = ARRAY_SIZE(apollo_div_clks), + .gate_clks = apollo_gate_clks, + .nr_gate_clks = ARRAY_SIZE(apollo_gate_clks), + .nr_clk_ids = APOLLO_NR_CLK, + .clk_regs = apollo_clk_regs, + .nr_clk_regs = ARRAY_SIZE(apollo_clk_regs), +}; + +static void __init exynos5433_cmu_apollo_init(struct device_node *np) +{ + samsung_cmu_register_one(np, &apollo_cmu_info); +} +CLK_OF_DECLARE(exynos5433_cmu_apollo, "samsung,exynos5433-cmu-apollo", + exynos5433_cmu_apollo_init); diff --git a/include/dt-bindings/clock/exynos5433.h b/include/dt-bindings/clock/exynos5433.h index fef8893c3ec2..90184e3a42d5 100644 --- a/include/dt-bindings/clock/exynos5433.h +++ b/include/dt-bindings/clock/exynos5433.h @@ -854,4 +854,41 @@ #define GSCL_NR_CLK 29 +/* CMU_APOLLO */ +#define CLK_FOUT_APOLLO_PLL 1 + +#define CLK_MOUT_APOLLO_PLL 2 +#define CLK_MOUT_BUS_PLL_APOLLO_USER 3 +#define CLK_MOUT_APOLLO 4 + +#define CLK_DIV_CNTCLK_APOLLO 5 +#define CLK_DIV_PCLK_DBG_APOLLO 6 +#define CLK_DIV_ATCLK_APOLLO 7 +#define CLK_DIV_PCLK_APOLLO 8 +#define CLK_DIV_ACLK_APOLLO 9 +#define CLK_DIV_APOLLO2 10 +#define CLK_DIV_APOLLO1 11 +#define CLK_DIV_SCLK_HPM_APOLLO 12 +#define CLK_DIV_APOLLO_PLL 13 + +#define CLK_ACLK_ATBDS_APOLLO_3 14 +#define CLK_ACLK_ATBDS_APOLLO_2 15 +#define CLK_ACLK_ATBDS_APOLLO_1 16 +#define CLK_ACLK_ATBDS_APOLLO_0 17 +#define CLK_ACLK_ASATBSLV_APOLLO_3_CSSYS 18 +#define CLK_ACLK_ASATBSLV_APOLLO_2_CSSYS 19 +#define CLK_ACLK_ASATBSLV_APOLLO_1_CSSYS 20 +#define CLK_ACLK_ASATBSLV_APOLLO_0_CSSYS 21 +#define CLK_ACLK_ASYNCACES_APOLLO_CCI 22 +#define CLK_ACLK_AHB2APB_APOLLOP 23 +#define CLK_ACLK_APOLLONP_200 24 +#define CLK_PCLK_ASAPBMST_CSSYS_APOLLO 25 +#define CLK_PCLK_PMU_APOLLO 26 +#define CLK_PCLK_SYSREG_APOLLO 27 +#define CLK_CNTCLK_APOLLO 28 +#define CLK_SCLK_HPM_APOLLO 29 +#define CLK_SCLK_APOLLO 30 + +#define APOLLO_NR_CLK 31 + #endif /* _DT_BINDINGS_CLOCK_EXYNOS5433_H */ -- GitLab From 6c5d76d15ab6da9b30af020a44e071eb5145e1a0 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Tue, 3 Feb 2015 09:13:50 +0900 Subject: [PATCH 00048/11651] clk: samsung: exynos5433: Add clocks for CMU_ATLAS domain This patch adds the mux/divider/gate clocks for CMU_ATLAS domain which generates the clocks for Cortex-A57 Quad-core processsor, L2 cache controller and CoreSight. Signed-off-by: Chanwoo Choi Acked-by: Inki Dae Reviewed-by: Pankaj Dubey Signed-off-by: Sylwester Nawrocki --- .../bindings/clock/exynos5433-clock.txt | 16 ++ drivers/clk/samsung/clk-exynos5433.c | 219 ++++++++++++++++++ include/dt-bindings/clock/exynos5433.h | 46 ++++ 3 files changed, 281 insertions(+) diff --git a/Documentation/devicetree/bindings/clock/exynos5433-clock.txt b/Documentation/devicetree/bindings/clock/exynos5433-clock.txt index 0a7146861a27..7c1dccc4d72e 100644 --- a/Documentation/devicetree/bindings/clock/exynos5433-clock.txt +++ b/Documentation/devicetree/bindings/clock/exynos5433-clock.txt @@ -34,6 +34,9 @@ Required Properties: which generates clocks for GSCALER IPs. - "samsung,exynos5433-cmu-apollo"- clock controller compatible for CMU_APOLLO which generates clocks for Cortex-A53 Quad-core processor. + - "samsung,exynos5433-cmu-atlas" - clock controller compatible for CMU_ATLAS + which generates clocks for Cortex-A57 Quad-core processor, CoreSight and + L2 cache controller. - reg: physical base address of the controller and length of memory mapped region. @@ -111,6 +114,10 @@ Required Properties: - oscclk - sclk_bus_pll_apollo + Input clocks for atlas clock controller: + - oscclk + - sclk_bus_pll_atlas + Each clock is assigned an identifier and client nodes can use this identifier to specify the clock which they consume. @@ -304,6 +311,15 @@ Example 2: Examples of clock controller nodes are listed below. clocks = <&xxti>, <&cmu_mif CLK_SCLK_BUS_PLL_APOLLO>; }; + cmu_atlas: clock-controller@11800000 { + compatible = "samsung,exynos5433-cmu-atlas"; + reg = <0x11800000 0x1088>; + #clock-cells = <1>; + + clock-names = "oscclk", "sclk_bus_pll_atlas"; + clocks = <&xxti>, <&cmu_mif CLK_SCLK_BUS_PLL_ATLAS>; + }; + Example 3: UART controller node that consumes the clock generated by the clock controller. diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c index f7d1e8390cdf..c44062d2904e 100644 --- a/drivers/clk/samsung/clk-exynos5433.c +++ b/drivers/clk/samsung/clk-exynos5433.c @@ -3586,3 +3586,222 @@ static void __init exynos5433_cmu_apollo_init(struct device_node *np) } CLK_OF_DECLARE(exynos5433_cmu_apollo, "samsung,exynos5433-cmu-apollo", exynos5433_cmu_apollo_init); + +/* + * Register offset definitions for CMU_ATLAS + */ +#define ATLAS_PLL_LOCK 0x0000 +#define ATLAS_PLL_CON0 0x0100 +#define ATLAS_PLL_CON1 0x0104 +#define ATLAS_PLL_FREQ_DET 0x010c +#define MUX_SEL_ATLAS0 0x0200 +#define MUX_SEL_ATLAS1 0x0204 +#define MUX_SEL_ATLAS2 0x0208 +#define MUX_ENABLE_ATLAS0 0x0300 +#define MUX_ENABLE_ATLAS1 0x0304 +#define MUX_ENABLE_ATLAS2 0x0308 +#define MUX_STAT_ATLAS0 0x0400 +#define MUX_STAT_ATLAS1 0x0404 +#define MUX_STAT_ATLAS2 0x0408 +#define DIV_ATLAS0 0x0600 +#define DIV_ATLAS1 0x0604 +#define DIV_ATLAS_PLL_FREQ_DET 0x0608 +#define DIV_STAT_ATLAS0 0x0700 +#define DIV_STAT_ATLAS1 0x0704 +#define DIV_STAT_ATLAS_PLL_FREQ_DET 0x0708 +#define ENABLE_ACLK_ATLAS 0x0800 +#define ENABLE_PCLK_ATLAS 0x0900 +#define ENABLE_SCLK_ATLAS 0x0a00 +#define ENABLE_IP_ATLAS0 0x0b00 +#define ENABLE_IP_ATLAS1 0x0b04 +#define CLKOUT_CMU_ATLAS 0x0c00 +#define CLKOUT_CMU_ATLAS_DIV_STAT 0x0c04 +#define ARMCLK_STOPCTRL 0x1000 +#define ATLAS_PWR_CTRL 0x1020 +#define ATLAS_PWR_CTRL2 0x1024 +#define ATLAS_INTR_SPREAD_ENABLE 0x1080 +#define ATLAS_INTR_SPREAD_USE_STANDBYWFI 0x1084 +#define ATLAS_INTR_SPREAD_BLOCKING_DURATION 0x1088 + +static unsigned long atlas_clk_regs[] __initdata = { + ATLAS_PLL_LOCK, + ATLAS_PLL_CON0, + ATLAS_PLL_CON1, + ATLAS_PLL_FREQ_DET, + MUX_SEL_ATLAS0, + MUX_SEL_ATLAS1, + MUX_SEL_ATLAS2, + MUX_ENABLE_ATLAS0, + MUX_ENABLE_ATLAS1, + MUX_ENABLE_ATLAS2, + MUX_STAT_ATLAS0, + MUX_STAT_ATLAS1, + MUX_STAT_ATLAS2, + DIV_ATLAS0, + DIV_ATLAS1, + DIV_ATLAS_PLL_FREQ_DET, + DIV_STAT_ATLAS0, + DIV_STAT_ATLAS1, + DIV_STAT_ATLAS_PLL_FREQ_DET, + ENABLE_ACLK_ATLAS, + ENABLE_PCLK_ATLAS, + ENABLE_SCLK_ATLAS, + ENABLE_IP_ATLAS0, + ENABLE_IP_ATLAS1, + CLKOUT_CMU_ATLAS, + CLKOUT_CMU_ATLAS_DIV_STAT, + ARMCLK_STOPCTRL, + ATLAS_PWR_CTRL, + ATLAS_PWR_CTRL2, + ATLAS_INTR_SPREAD_ENABLE, + ATLAS_INTR_SPREAD_USE_STANDBYWFI, + ATLAS_INTR_SPREAD_BLOCKING_DURATION, +}; + +/* list of all parent clock list */ +PNAME(mout_atlas_pll_p) = { "oscclk", "fout_atlas_pll", }; +PNAME(mout_bus_pll_atlas_user_p) = { "oscclk", "sclk_bus_pll_atlas", }; +PNAME(mout_atlas_p) = { "mout_atlas_pll", + "mout_bus_pll_atlas_user", }; + +static struct samsung_pll_clock atlas_pll_clks[] __initdata = { + PLL(pll_35xx, CLK_FOUT_ATLAS_PLL, "fout_atlas_pll", "oscclk", + ATLAS_PLL_LOCK, ATLAS_PLL_CON0, exynos5443_pll_rates), +}; + +static struct samsung_mux_clock atlas_mux_clks[] __initdata = { + /* MUX_SEL_ATLAS0 */ + MUX_F(CLK_MOUT_ATLAS_PLL, "mout_atlas_pll", mout_atlas_pll_p, + MUX_SEL_ATLAS0, 0, 1, 0, CLK_MUX_READ_ONLY), + + /* MUX_SEL_ATLAS1 */ + MUX(CLK_MOUT_BUS_PLL_ATLAS_USER, "mout_bus_pll_atlas_user", + mout_bus_pll_atlas_user_p, MUX_SEL_ATLAS1, 0, 1), + + /* MUX_SEL_ATLAS2 */ + MUX_F(CLK_MOUT_ATLAS, "mout_atlas", mout_atlas_p, MUX_SEL_ATLAS2, + 0, 1, 0, CLK_MUX_READ_ONLY), +}; + +static struct samsung_div_clock atlas_div_clks[] __initdata = { + /* DIV_ATLAS0 */ + DIV_F(CLK_DIV_CNTCLK_ATLAS, "div_cntclk_atlas", "div_atlas2", + DIV_ATLAS0, 24, 3, CLK_GET_RATE_NOCACHE, + CLK_DIVIDER_READ_ONLY), + DIV_F(CLK_DIV_PCLK_DBG_ATLAS, "div_pclk_dbg_atlas", "div_atclk_atlas", + DIV_ATLAS0, 20, 3, CLK_GET_RATE_NOCACHE, + CLK_DIVIDER_READ_ONLY), + DIV_F(CLK_DIV_ATCLK_ATLASO, "div_atclk_atlas", "div_atlas2", + DIV_ATLAS0, 16, 3, CLK_GET_RATE_NOCACHE, + CLK_DIVIDER_READ_ONLY), + DIV_F(CLK_DIV_PCLK_ATLAS, "div_pclk_atlas", "div_atlas2", + DIV_ATLAS0, 12, 3, CLK_GET_RATE_NOCACHE, + CLK_DIVIDER_READ_ONLY), + DIV_F(CLK_DIV_ACLK_ATLAS, "div_aclk_atlas", "div_atlas2", + DIV_ATLAS0, 8, 3, CLK_GET_RATE_NOCACHE, + CLK_DIVIDER_READ_ONLY), + DIV_F(CLK_DIV_ATLAS2, "div_atlas2", "div_atlas1", + DIV_ATLAS0, 4, 3, CLK_GET_RATE_NOCACHE, + CLK_DIVIDER_READ_ONLY), + DIV_F(CLK_DIV_ATLAS1, "div_atlas1", "mout_atlas", + DIV_ATLAS0, 0, 3, CLK_GET_RATE_NOCACHE, + CLK_DIVIDER_READ_ONLY), + + /* DIV_ATLAS1 */ + DIV_F(CLK_DIV_SCLK_HPM_ATLAS, "div_sclk_hpm_atlas", "mout_atlas", + DIV_ATLAS1, 4, 3, CLK_GET_RATE_NOCACHE, + CLK_DIVIDER_READ_ONLY), + DIV_F(CLK_DIV_ATLAS_PLL, "div_atlas_pll", "mout_atlas", + DIV_ATLAS1, 0, 3, CLK_GET_RATE_NOCACHE, + CLK_DIVIDER_READ_ONLY), +}; + +static struct samsung_gate_clock atlas_gate_clks[] __initdata = { + /* ENABLE_ACLK_ATLAS */ + GATE(CLK_ACLK_ATB_AUD_CSSYS, "aclk_atb_aud_cssys", + "div_atclk_atlas", ENABLE_ACLK_ATLAS, + 9, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ATB_APOLLO3_CSSYS, "aclk_atb_apollo3_cssys", + "div_atclk_atlas", ENABLE_ACLK_ATLAS, + 8, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ATB_APOLLO2_CSSYS, "aclk_atb_apollo2_cssys", + "div_atclk_atlas", ENABLE_ACLK_ATLAS, + 7, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ATB_APOLLO1_CSSYS, "aclk_atb_apollo1_cssys", + "div_atclk_atlas", ENABLE_ACLK_ATLAS, + 6, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ATB_APOLLO0_CSSYS, "aclk_atb_apollo0_cssys", + "div_atclk_atlas", ENABLE_ACLK_ATLAS, + 5, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAHBS_CSSYS_SSS, "aclk_asyncahbs_cssys_sss", + "div_atclk_atlas", ENABLE_ACLK_ATLAS, + 4, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAXIS_CSSYS_CCIX, "aclk_asyncaxis_cssys_ccix", + "div_pclk_dbg_atlas", ENABLE_ACLK_ATLAS, + 3, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCACES_ATLAS_CCI, "aclk_asyncaces_atlas_cci", + "div_aclk_atlas", ENABLE_ACLK_ATLAS, + 2, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_AHB2APB_ATLASP, "aclk_ahb2apb_atlasp", "div_pclk_atlas", + ENABLE_ACLK_ATLAS, 1, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ATLASNP_200, "aclk_atlasnp_200", "div_pclk_atlas", + ENABLE_ACLK_ATLAS, 0, CLK_IGNORE_UNUSED, 0), + + /* ENABLE_PCLK_ATLAS */ + GATE(CLK_PCLK_ASYNCAPB_AUD_CSSYS, "pclk_asyncapb_aud_cssys", + "div_pclk_dbg_atlas", ENABLE_PCLK_ATLAS, + 5, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_ASYNCAPB_ISP_CSSYS, "pclk_asyncapb_isp_cssys", + "div_pclk_dbg_atlas", ENABLE_PCLK_ATLAS, + 4, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_ASYNCAPB_APOLLO_CSSYS, "pclk_asyncapb_apollo_cssys", + "div_pclk_dbg_atlas", ENABLE_PCLK_ATLAS, + 3, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_PMU_ATLAS, "pclk_pmu_atlas", "div_pclk_atlas", + ENABLE_PCLK_ATLAS, 2, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_SYSREG_ATLAS, "pclk_sysreg_atlas", "div_pclk_atlas", + ENABLE_PCLK_ATLAS, 1, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_SECJTAG, "pclk_secjtag", "div_pclk_dbg_atlas", + ENABLE_PCLK_ATLAS, 0, CLK_IGNORE_UNUSED, 0), + + /* ENABLE_SCLK_ATLAS */ + GATE(CLK_CNTCLK_ATLAS, "cntclk_atlas", "div_cntclk_atlas", + ENABLE_SCLK_ATLAS, 10, CLK_IGNORE_UNUSED, 0), + GATE(CLK_SCLK_HPM_ATLAS, "sclk_hpm_atlas", "div_sclk_hpm_atlas", + ENABLE_SCLK_ATLAS, 7, CLK_IGNORE_UNUSED, 0), + GATE(CLK_TRACECLK, "traceclk", "div_atclk_atlas", + ENABLE_SCLK_ATLAS, 6, CLK_IGNORE_UNUSED, 0), + GATE(CLK_CTMCLK, "ctmclk", "div_atclk_atlas", + ENABLE_SCLK_ATLAS, 5, CLK_IGNORE_UNUSED, 0), + GATE(CLK_HCLK_CSSYS, "hclk_cssys", "div_atclk_atlas", + ENABLE_SCLK_ATLAS, 4, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_DBG_CSSYS, "pclk_dbg_cssys", "div_pclk_dbg_atlas", + ENABLE_SCLK_ATLAS, 3, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_DBG, "pclk_dbg", "div_pclk_dbg_atlas", + ENABLE_SCLK_ATLAS, 2, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ATCLK, "atclk", "div_atclk_atlas", + ENABLE_SCLK_ATLAS, 1, CLK_IGNORE_UNUSED, 0), + GATE(CLK_SCLK_ATLAS, "sclk_atlas", "div_atlas2", + ENABLE_SCLK_ATLAS, 0, CLK_IGNORE_UNUSED, 0), +}; + +static struct samsung_cmu_info atlas_cmu_info __initdata = { + .pll_clks = atlas_pll_clks, + .nr_pll_clks = ARRAY_SIZE(atlas_pll_clks), + .mux_clks = atlas_mux_clks, + .nr_mux_clks = ARRAY_SIZE(atlas_mux_clks), + .div_clks = atlas_div_clks, + .nr_div_clks = ARRAY_SIZE(atlas_div_clks), + .gate_clks = atlas_gate_clks, + .nr_gate_clks = ARRAY_SIZE(atlas_gate_clks), + .nr_clk_ids = ATLAS_NR_CLK, + .clk_regs = atlas_clk_regs, + .nr_clk_regs = ARRAY_SIZE(atlas_clk_regs), +}; + +static void __init exynos5433_cmu_atlas_init(struct device_node *np) +{ + samsung_cmu_register_one(np, &atlas_cmu_info); +} +CLK_OF_DECLARE(exynos5433_cmu_atlas, "samsung,exynos5433-cmu-atlas", + exynos5433_cmu_atlas_init); diff --git a/include/dt-bindings/clock/exynos5433.h b/include/dt-bindings/clock/exynos5433.h index 90184e3a42d5..cdc91f7e6ec8 100644 --- a/include/dt-bindings/clock/exynos5433.h +++ b/include/dt-bindings/clock/exynos5433.h @@ -891,4 +891,50 @@ #define APOLLO_NR_CLK 31 +/* CMU_ATLAS */ +#define CLK_FOUT_ATLAS_PLL 1 + +#define CLK_MOUT_ATLAS_PLL 2 +#define CLK_MOUT_BUS_PLL_ATLAS_USER 3 +#define CLK_MOUT_ATLAS 4 + +#define CLK_DIV_CNTCLK_ATLAS 5 +#define CLK_DIV_PCLK_DBG_ATLAS 6 +#define CLK_DIV_ATCLK_ATLASO 7 +#define CLK_DIV_PCLK_ATLAS 8 +#define CLK_DIV_ACLK_ATLAS 9 +#define CLK_DIV_ATLAS2 10 +#define CLK_DIV_ATLAS1 11 +#define CLK_DIV_SCLK_HPM_ATLAS 12 +#define CLK_DIV_ATLAS_PLL 13 + +#define CLK_ACLK_ATB_AUD_CSSYS 14 +#define CLK_ACLK_ATB_APOLLO3_CSSYS 15 +#define CLK_ACLK_ATB_APOLLO2_CSSYS 16 +#define CLK_ACLK_ATB_APOLLO1_CSSYS 17 +#define CLK_ACLK_ATB_APOLLO0_CSSYS 18 +#define CLK_ACLK_ASYNCAHBS_CSSYS_SSS 19 +#define CLK_ACLK_ASYNCAXIS_CSSYS_CCIX 20 +#define CLK_ACLK_ASYNCACES_ATLAS_CCI 21 +#define CLK_ACLK_AHB2APB_ATLASP 22 +#define CLK_ACLK_ATLASNP_200 23 +#define CLK_PCLK_ASYNCAPB_AUD_CSSYS 24 +#define CLK_PCLK_ASYNCAPB_ISP_CSSYS 25 +#define CLK_PCLK_ASYNCAPB_APOLLO_CSSYS 26 +#define CLK_PCLK_PMU_ATLAS 27 +#define CLK_PCLK_SYSREG_ATLAS 28 +#define CLK_PCLK_SECJTAG 29 +#define CLK_CNTCLK_ATLAS 30 +#define CLK_SCLK_FREQ_DET_ATLAS_PLL 31 +#define CLK_SCLK_HPM_ATLAS 32 +#define CLK_TRACECLK 33 +#define CLK_CTMCLK 34 +#define CLK_HCLK_CSSYS 35 +#define CLK_PCLK_DBG_CSSYS 36 +#define CLK_PCLK_DBG 37 +#define CLK_ATCLK 38 +#define CLK_SCLK_ATLAS 39 + +#define ATLAS_NR_CLK 40 + #endif /* _DT_BINDINGS_CLOCK_EXYNOS5433_H */ -- GitLab From b274bbfd8b4a94cb5bd6fe21801264a27dd8ec75 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Tue, 3 Feb 2015 09:13:51 +0900 Subject: [PATCH 00049/11651] clk: samsung: exynos5433: Add clocks for CMU_MSCL domain This patch adds the mux/divider/gate clocks for CMU_MSCL domain which generates the clocks for M2M (Memory to Memory) scaler, JPEG IPs. Signed-off-by: Chanwoo Choi Acked-by: Inki Dae Reviewed-by: Pankaj Dubey Signed-off-by: Sylwester Nawrocki --- .../bindings/clock/exynos5433-clock.txt | 20 ++ drivers/clk/samsung/clk-exynos5433.c | 185 ++++++++++++++++++ include/dt-bindings/clock/exynos5433.h | 41 +++- 3 files changed, 245 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/clock/exynos5433-clock.txt b/Documentation/devicetree/bindings/clock/exynos5433-clock.txt index 7c1dccc4d72e..ecb9534c2ea6 100644 --- a/Documentation/devicetree/bindings/clock/exynos5433-clock.txt +++ b/Documentation/devicetree/bindings/clock/exynos5433-clock.txt @@ -37,6 +37,8 @@ Required Properties: - "samsung,exynos5433-cmu-atlas" - clock controller compatible for CMU_ATLAS which generates clocks for Cortex-A57 Quad-core processor, CoreSight and L2 cache controller. + - "samsung,exynos5433-cmu-mscl" - clock controller compatible for CMU_MSCL + which generates clocks for M2M (Memory to Memory) scaler and JPEG IPs. - reg: physical base address of the controller and length of memory mapped region. @@ -118,6 +120,11 @@ Required Properties: - oscclk - sclk_bus_pll_atlas + Input clocks for mscl clock controller: + - oscclk + - sclk_jpeg_mscl + - aclk_mscl_400 + Each clock is assigned an identifier and client nodes can use this identifier to specify the clock which they consume. @@ -320,6 +327,19 @@ Example 2: Examples of clock controller nodes are listed below. clocks = <&xxti>, <&cmu_mif CLK_SCLK_BUS_PLL_ATLAS>; }; + cmu_mscl: clock-controller@105d0000 { + compatible = "samsung,exynos5433-cmu-mscl"; + reg = <0x105d0000 0x0b10>; + #clock-cells = <1>; + + clock-names = "oscclk", + "sclk_jpeg_mscl", + "aclk_mscl_400"; + clocks = <&xxti>, + <&cmu_top CLK_SCLK_JPEG_MSCL>, + <&cmu_top CLK_ACLK_MSCL_400>; + }; + Example 3: UART controller node that consumes the clock generated by the clock controller. diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c index c44062d2904e..d272e42eb48c 100644 --- a/drivers/clk/samsung/clk-exynos5433.c +++ b/drivers/clk/samsung/clk-exynos5433.c @@ -419,6 +419,8 @@ static struct samsung_div_clock top_div_clks[] __initdata = { DIV_TOP1, 0, 3), /* DIV_TOP2 */ + DIV(CLK_DIV_ACLK_MSCL_400, "div_aclk_mscl_400", "mout_aclk_mscl_400_b", + DIV_TOP2, 4, 3), DIV(CLK_DIV_ACLK_FSYS_200, "div_aclk_fsys_200", "mout_bus_pll_user", DIV_TOP2, 0, 3), @@ -446,6 +448,10 @@ static struct samsung_div_clock top_div_clks[] __initdata = { DIV(CLK_DIV_ACLK_BUS1_400, "div_aclk_bus1_400", "mout_bus_pll_user", DIV_TOP4, 0, 3), + /* DIV_TOP_MSCL */ + DIV(CLK_DIV_SCLK_JPEG, "div_sclk_jpeg", "mout_sclk_jpeg_c", + DIV_TOP_MSCL, 0, 4), + /* DIV_TOP_FSYS0 */ DIV(CLK_DIV_SCLK_MMC1_B, "div_sclk_mmc1_b", "div_sclk_mmc1_a", DIV_TOP_FSYS0, 16, 8), @@ -542,6 +548,9 @@ static struct samsung_gate_clock top_gate_clks[] __initdata = { GATE(CLK_ACLK_PERIS_66, "aclk_peris_66", "div_aclk_peris_66_b", ENABLE_ACLK_TOP, 21, CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_MSCL_400, "aclk_mscl_400", "div_aclk_mscl_400", + ENABLE_ACLK_TOP, 19, + CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0), GATE(CLK_ACLK_FSYS_200, "aclk_fsys_200", "div_aclk_fsys_200", ENABLE_ACLK_TOP, 18, CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0), @@ -558,6 +567,10 @@ static struct samsung_gate_clock top_gate_clks[] __initdata = { ENABLE_ACLK_TOP, 0, CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0), + /* ENABLE_SCLK_TOP_MSCL */ + GATE(CLK_SCLK_JPEG_MSCL, "sclk_jpeg_mscl", "div_sclk_jpeg", + ENABLE_SCLK_TOP_MSCL, 0, 0, 0), + /* ENABLE_SCLK_TOP_FSYS */ GATE(CLK_SCLK_PCIE_100_FSYS, "sclk_pcie_100_fsys", "div_sclk_pcie_100", ENABLE_SCLK_TOP_FSYS, 7, 0, 0), @@ -3805,3 +3818,175 @@ static void __init exynos5433_cmu_atlas_init(struct device_node *np) } CLK_OF_DECLARE(exynos5433_cmu_atlas, "samsung,exynos5433-cmu-atlas", exynos5433_cmu_atlas_init); + +/* + * Register offset definitions for CMU_MSCL + */ +#define MUX_SEL_MSCL0 0x0200 +#define MUX_SEL_MSCL1 0x0204 +#define MUX_ENABLE_MSCL0 0x0300 +#define MUX_ENABLE_MSCL1 0x0304 +#define MUX_STAT_MSCL0 0x0400 +#define MUX_STAT_MSCL1 0x0404 +#define DIV_MSCL 0x0600 +#define DIV_STAT_MSCL 0x0700 +#define ENABLE_ACLK_MSCL 0x0800 +#define ENABLE_ACLK_MSCL_SECURE_SMMU_M2MSCALER0 0x0804 +#define ENABLE_ACLK_MSCL_SECURE_SMMU_M2MSCALER1 0x0808 +#define ENABLE_ACLK_MSCL_SECURE_SMMU_JPEG 0x080c +#define ENABLE_PCLK_MSCL 0x0900 +#define ENABLE_PCLK_MSCL_SECURE_SMMU_M2MSCALER0 0x0904 +#define ENABLE_PCLK_MSCL_SECURE_SMMU_M2MSCALER1 0x0908 +#define ENABLE_PCLK_MSCL_SECURE_SMMU_JPEG 0x000c +#define ENABLE_SCLK_MSCL 0x0a00 +#define ENABLE_IP_MSCL0 0x0b00 +#define ENABLE_IP_MSCL1 0x0b04 +#define ENABLE_IP_MSCL_SECURE_SMMU_M2MSCALER0 0x0b08 +#define ENABLE_IP_MSCL_SECURE_SMMU_M2MSCALER1 0x0b0c +#define ENABLE_IP_MSCL_SECURE_SMMU_JPEG 0x0b10 + +static unsigned long mscl_clk_regs[] __initdata = { + MUX_SEL_MSCL0, + MUX_SEL_MSCL1, + MUX_ENABLE_MSCL0, + MUX_ENABLE_MSCL1, + MUX_STAT_MSCL0, + MUX_STAT_MSCL1, + DIV_MSCL, + DIV_STAT_MSCL, + ENABLE_ACLK_MSCL, + ENABLE_ACLK_MSCL_SECURE_SMMU_M2MSCALER0, + ENABLE_ACLK_MSCL_SECURE_SMMU_M2MSCALER1, + ENABLE_ACLK_MSCL_SECURE_SMMU_JPEG, + ENABLE_PCLK_MSCL, + ENABLE_PCLK_MSCL_SECURE_SMMU_M2MSCALER0, + ENABLE_PCLK_MSCL_SECURE_SMMU_M2MSCALER1, + ENABLE_PCLK_MSCL_SECURE_SMMU_JPEG, + ENABLE_SCLK_MSCL, + ENABLE_IP_MSCL0, + ENABLE_IP_MSCL1, + ENABLE_IP_MSCL_SECURE_SMMU_M2MSCALER0, + ENABLE_IP_MSCL_SECURE_SMMU_M2MSCALER1, + ENABLE_IP_MSCL_SECURE_SMMU_JPEG, +}; + +/* list of all parent clock list */ +PNAME(mout_sclk_jpeg_user_p) = { "oscclk", "sclk_jpeg_mscl", }; +PNAME(mout_aclk_mscl_400_user_p) = { "oscclk", "aclk_mscl_400", }; +PNAME(mout_sclk_jpeg_p) = { "mout_sclk_jpeg_user", + "mout_aclk_mscl_400_user", }; + +static struct samsung_mux_clock mscl_mux_clks[] __initdata = { + /* MUX_SEL_MSCL0 */ + MUX(CLK_MOUT_SCLK_JPEG_USER, "mout_sclk_jpeg_user", + mout_sclk_jpeg_user_p, MUX_SEL_MSCL0, 4, 1), + MUX(CLK_MOUT_ACLK_MSCL_400_USER, "mout_aclk_mscl_400_user", + mout_aclk_mscl_400_user_p, MUX_SEL_MSCL0, 0, 1), + + /* MUX_SEL_MSCL1 */ + MUX(CLK_MOUT_SCLK_JPEG, "mout_sclk_jpeg", mout_sclk_jpeg_p, + MUX_SEL_MSCL1, 0, 1), +}; + +static struct samsung_div_clock mscl_div_clks[] __initdata = { + /* DIV_MSCL */ + DIV(CLK_DIV_PCLK_MSCL, "div_pclk_mscl", "mout_aclk_mscl_400_user", + DIV_MSCL, 0, 3), +}; + +static struct samsung_gate_clock mscl_gate_clks[] __initdata = { + /* ENABLE_ACLK_MSCL */ + GATE(CLK_ACLK_BTS_JPEG, "aclk_bts_jpeg", "mout_aclk_mscl_400_user", + ENABLE_ACLK_MSCL, 9, 0, 0), + GATE(CLK_ACLK_BTS_M2MSCALER1, "aclk_bts_m2mscaler1", + "mout_aclk_mscl_400_user", ENABLE_ACLK_MSCL, 8, 0, 0), + GATE(CLK_ACLK_BTS_M2MSCALER0, "aclk_bts_m2mscaler0", + "mout_aclk_mscl_400_user", ENABLE_ACLK_MSCL, 7, 0, 0), + GATE(CLK_ACLK_AHB2APB_MSCL0P, "aclk_abh2apb_mscl0p", "div_pclk_mscl", + ENABLE_ACLK_MSCL, 6, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_XIU_MSCLX, "aclk_xiu_msclx", "mout_aclk_mscl_400_user", + ENABLE_ACLK_MSCL, 5, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_MSCLNP_100, "aclk_msclnp_100", "div_pclk_mscl", + ENABLE_ACLK_MSCL, 4, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_MSCLND_400, "aclk_msclnd_400", "mout_aclk_mscl_400_user", + ENABLE_ACLK_MSCL, 3, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_JPEG, "aclk_jpeg", "mout_aclk_mscl_400_user", + ENABLE_ACLK_MSCL, 2, 0, 0), + GATE(CLK_ACLK_M2MSCALER1, "aclk_m2mscaler1", "mout_aclk_mscl_400_user", + ENABLE_ACLK_MSCL, 1, 0, 0), + GATE(CLK_ACLK_M2MSCALER0, "aclk_m2mscaler0", "mout_aclk_mscl_400_user", + ENABLE_ACLK_MSCL, 0, 0, 0), + + /* ENABLE_ACLK_MSCL_SECURE_SMMU_M2MSCALER0 */ + GATE(CLK_ACLK_SMMU_M2MSCALER0, "aclk_smmu_m2mscaler0", + "mout_aclk_mscl_400_user", + ENABLE_ACLK_MSCL_SECURE_SMMU_M2MSCALER0, + 0, CLK_IGNORE_UNUSED, 0), + + /* ENABLE_ACLK_MSCL_SECURE_SMMU_M2MSCALER1 */ + GATE(CLK_ACLK_SMMU_M2MSCALER1, "aclk_smmu_m2mscaler1", + "mout_aclk_mscl_400_user", + ENABLE_ACLK_MSCL_SECURE_SMMU_M2MSCALER1, + 0, CLK_IGNORE_UNUSED, 0), + + /* ENABLE_ACLK_MSCL_SECURE_SMMU_JPEG */ + GATE(CLK_ACLK_SMMU_JPEG, "aclk_smmu_jpeg", "mout_aclk_mscl_400_user", + ENABLE_ACLK_MSCL_SECURE_SMMU_JPEG, + 0, CLK_IGNORE_UNUSED, 0), + + /* ENABLE_PCLK_MSCL */ + GATE(CLK_PCLK_BTS_JPEG, "pclk_bts_jpeg", "div_pclk_mscl", + ENABLE_PCLK_MSCL, 7, 0, 0), + GATE(CLK_PCLK_BTS_M2MSCALER1, "pclk_bts_m2mscaler1", "div_pclk_mscl", + ENABLE_PCLK_MSCL, 6, 0, 0), + GATE(CLK_PCLK_BTS_M2MSCALER0, "pclk_bts_m2mscaler0", "div_pclk_mscl", + ENABLE_PCLK_MSCL, 5, 0, 0), + GATE(CLK_PCLK_PMU_MSCL, "pclk_pmu_mscl", "div_pclk_mscl", + ENABLE_PCLK_MSCL, 4, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_SYSREG_MSCL, "pclk_sysreg_mscl", "div_pclk_mscl", + ENABLE_PCLK_MSCL, 3, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_JPEG, "pclk_jpeg", "div_pclk_mscl", + ENABLE_PCLK_MSCL, 2, 0, 0), + GATE(CLK_PCLK_M2MSCALER1, "pclk_m2mscaler1", "div_pclk_mscl", + ENABLE_PCLK_MSCL, 1, 0, 0), + GATE(CLK_PCLK_M2MSCALER0, "pclk_m2mscaler0", "div_pclk_mscl", + ENABLE_PCLK_MSCL, 0, 0, 0), + + /* ENABLE_PCLK_MSCL_SECURE_SMMU_M2MSCALER0 */ + GATE(CLK_PCLK_SMMU_M2MSCALER0, "pclk_smmu_m2mscaler0", "div_pclk_mscl", + ENABLE_PCLK_MSCL_SECURE_SMMU_M2MSCALER0, + 0, CLK_IGNORE_UNUSED, 0), + + /* ENABLE_PCLK_MSCL_SECURE_SMMU_M2MSCALER1 */ + GATE(CLK_PCLK_SMMU_M2MSCALER1, "pclk_smmu_m2mscaler1", "div_pclk_mscl", + ENABLE_PCLK_MSCL_SECURE_SMMU_M2MSCALER1, + 0, CLK_IGNORE_UNUSED, 0), + + /* ENABLE_PCLK_MSCL_SECURE_SMMU_JPEG */ + GATE(CLK_PCLK_SMMU_JPEG, "pclk_smmu_jpeg", "div_pclk_mscl", + ENABLE_PCLK_MSCL_SECURE_SMMU_JPEG, + 0, CLK_IGNORE_UNUSED, 0), + + /* ENABLE_SCLK_MSCL */ + GATE(CLK_SCLK_JPEG, "sclk_jpeg", "mout_sclk_jpeg", ENABLE_SCLK_MSCL, 0, + CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0), +}; + +static struct samsung_cmu_info mscl_cmu_info __initdata = { + .mux_clks = mscl_mux_clks, + .nr_mux_clks = ARRAY_SIZE(mscl_mux_clks), + .div_clks = mscl_div_clks, + .nr_div_clks = ARRAY_SIZE(mscl_div_clks), + .gate_clks = mscl_gate_clks, + .nr_gate_clks = ARRAY_SIZE(mscl_gate_clks), + .nr_clk_ids = MSCL_NR_CLK, + .clk_regs = mscl_clk_regs, + .nr_clk_regs = ARRAY_SIZE(mscl_clk_regs), +}; + +static void __init exynos5433_cmu_mscl_init(struct device_node *np) +{ + samsung_cmu_register_one(np, &mscl_cmu_info); +} +CLK_OF_DECLARE(exynos5433_cmu_mscl, "samsung,exynos5433-cmu-mscl", + exynos5433_cmu_mscl_init); diff --git a/include/dt-bindings/clock/exynos5433.h b/include/dt-bindings/clock/exynos5433.h index cdc91f7e6ec8..9898390710e6 100644 --- a/include/dt-bindings/clock/exynos5433.h +++ b/include/dt-bindings/clock/exynos5433.h @@ -114,6 +114,8 @@ #define CLK_DIV_SCLK_USBHOST30 141 #define CLK_DIV_SCLK_UFSUNIPRO 142 #define CLK_DIV_SCLK_USBDRD30 143 +#define CLK_DIV_SCLK_JPEG 144 +#define CLK_DIV_ACLK_MSCL_400 145 #define CLK_ACLK_PERIC_66 200 #define CLK_ACLK_PERIS_66 201 @@ -149,8 +151,10 @@ #define CLK_SCLK_USBDRD30_FSYS 231 #define CLK_ACLK_GSCL_111 232 #define CLK_ACLK_GSCL_333 233 +#define CLK_SCLK_JPEG_MSCL 234 +#define CLK_ACLK_MSCL_400 235 -#define TOP_NR_CLK 234 +#define TOP_NR_CLK 236 /* CMU_CPIF */ #define CLK_FOUT_MPHY_PLL 1 @@ -937,4 +941,39 @@ #define ATLAS_NR_CLK 40 +/* CMU_MSCL */ +#define CLK_MOUT_SCLK_JPEG_USER 1 +#define CLK_MOUT_ACLK_MSCL_400_USER 2 +#define CLK_MOUT_SCLK_JPEG 3 + +#define CLK_DIV_PCLK_MSCL 4 + +#define CLK_ACLK_BTS_JPEG 5 +#define CLK_ACLK_BTS_M2MSCALER1 6 +#define CLK_ACLK_BTS_M2MSCALER0 7 +#define CLK_ACLK_AHB2APB_MSCL0P 8 +#define CLK_ACLK_XIU_MSCLX 9 +#define CLK_ACLK_MSCLNP_100 10 +#define CLK_ACLK_MSCLND_400 11 +#define CLK_ACLK_JPEG 12 +#define CLK_ACLK_M2MSCALER1 13 +#define CLK_ACLK_M2MSCALER0 14 +#define CLK_ACLK_SMMU_M2MSCALER0 15 +#define CLK_ACLK_SMMU_M2MSCALER1 16 +#define CLK_ACLK_SMMU_JPEG 17 +#define CLK_PCLK_BTS_JPEG 18 +#define CLK_PCLK_BTS_M2MSCALER1 19 +#define CLK_PCLK_BTS_M2MSCALER0 20 +#define CLK_PCLK_PMU_MSCL 21 +#define CLK_PCLK_SYSREG_MSCL 22 +#define CLK_PCLK_JPEG 23 +#define CLK_PCLK_M2MSCALER1 24 +#define CLK_PCLK_M2MSCALER0 25 +#define CLK_PCLK_SMMU_M2MSCALER0 26 +#define CLK_PCLK_SMMU_M2MSCALER1 27 +#define CLK_PCLK_SMMU_JPEG 28 +#define CLK_SCLK_JPEG 29 + +#define MSCL_NR_CLK 30 + #endif /* _DT_BINDINGS_CLOCK_EXYNOS5433_H */ -- GitLab From 9910b6bbaa7b16cd3a8a7d8be53980fa1b8183a6 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Tue, 3 Feb 2015 09:13:52 +0900 Subject: [PATCH 00050/11651] clk: samsung: exynos5433: Add clocks for CMU_MFC domain This patch adds the mux/divider/gate clocks for CMU_MFC domain which generates the clocks for MFC(Multi-Format Codec) IP. Signed-off-by: Chanwoo Choi Acked-by: Inki Dae Signed-off-by: Sylwester Nawrocki --- .../bindings/clock/exynos5433-clock.txt | 15 +++ drivers/clk/samsung/clk-exynos5433.c | 113 ++++++++++++++++++ include/dt-bindings/clock/exynos5433.h | 27 ++++- 3 files changed, 154 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/clock/exynos5433-clock.txt b/Documentation/devicetree/bindings/clock/exynos5433-clock.txt index ecb9534c2ea6..0f35167ec15c 100644 --- a/Documentation/devicetree/bindings/clock/exynos5433-clock.txt +++ b/Documentation/devicetree/bindings/clock/exynos5433-clock.txt @@ -39,6 +39,8 @@ Required Properties: L2 cache controller. - "samsung,exynos5433-cmu-mscl" - clock controller compatible for CMU_MSCL which generates clocks for M2M (Memory to Memory) scaler and JPEG IPs. + - "samsung,exynos5433-cmu-mfc" - clock controller compatible for CMU_MFC + which generates clocks for MFC(Multi-Format Codec) IP. - reg: physical base address of the controller and length of memory mapped region. @@ -125,6 +127,10 @@ Required Properties: - sclk_jpeg_mscl - aclk_mscl_400 + Input clocks for mfc clock controller: + - oscclk + - aclk_mfc_400 + Each clock is assigned an identifier and client nodes can use this identifier to specify the clock which they consume. @@ -340,6 +346,15 @@ Example 2: Examples of clock controller nodes are listed below. <&cmu_top CLK_ACLK_MSCL_400>; }; + cmu_mfc: clock-controller@15280000 { + compatible = "samsung,exynos5433-cmu-mfc"; + reg = <0x15280000 0x0b08>; + #clock-cells = <1>; + + clock-names = "oscclk", "aclk_mfc_400"; + clocks = <&xxti>, <&cmu_top CLK_ACLK_MFC_400>; + }; + Example 3: UART controller node that consumes the clock generated by the clock controller. diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c index d272e42eb48c..40558930711f 100644 --- a/drivers/clk/samsung/clk-exynos5433.c +++ b/drivers/clk/samsung/clk-exynos5433.c @@ -560,6 +560,9 @@ static struct samsung_gate_clock top_gate_clks[] __initdata = { GATE(CLK_ACLK_GSCL_333, "aclk_gscl_333", "div_aclk_gscl_333", ENABLE_ACLK_TOP, 14, CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_MFC_400, "aclk_mfc_400", "div_aclk_mfc_400", + ENABLE_ACLK_TOP, 3, + CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0), GATE(CLK_ACLK_G2D_266, "aclk_g2d_266", "div_aclk_g2d_266", ENABLE_ACLK_TOP, 2, CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0), @@ -3990,3 +3993,113 @@ static void __init exynos5433_cmu_mscl_init(struct device_node *np) } CLK_OF_DECLARE(exynos5433_cmu_mscl, "samsung,exynos5433-cmu-mscl", exynos5433_cmu_mscl_init); + +/* + * Register offset definitions for CMU_MFC + */ +#define MUX_SEL_MFC 0x0200 +#define MUX_ENABLE_MFC 0x0300 +#define MUX_STAT_MFC 0x0400 +#define DIV_MFC 0x0600 +#define DIV_STAT_MFC 0x0700 +#define ENABLE_ACLK_MFC 0x0800 +#define ENABLE_ACLK_MFC_SECURE_SMMU_MFC 0x0804 +#define ENABLE_PCLK_MFC 0x0900 +#define ENABLE_PCLK_MFC_SECURE_SMMU_MFC 0x0904 +#define ENABLE_IP_MFC0 0x0b00 +#define ENABLE_IP_MFC1 0x0b04 +#define ENABLE_IP_MFC_SECURE_SMMU_MFC 0x0b08 + +static unsigned long mfc_clk_regs[] __initdata = { + MUX_SEL_MFC, + MUX_ENABLE_MFC, + MUX_STAT_MFC, + DIV_MFC, + DIV_STAT_MFC, + ENABLE_ACLK_MFC, + ENABLE_ACLK_MFC_SECURE_SMMU_MFC, + ENABLE_PCLK_MFC, + ENABLE_PCLK_MFC_SECURE_SMMU_MFC, + ENABLE_IP_MFC0, + ENABLE_IP_MFC1, + ENABLE_IP_MFC_SECURE_SMMU_MFC, +}; + +PNAME(mout_aclk_mfc_400_user_p) = { "oscclk", "aclk_mfc_400", }; + +static struct samsung_mux_clock mfc_mux_clks[] __initdata = { + /* MUX_SEL_MFC */ + MUX(CLK_MOUT_ACLK_MFC_400_USER, "mout_aclk_mfc_400_user", + mout_aclk_mfc_400_user_p, MUX_SEL_MFC, 0, 0), +}; + +static struct samsung_div_clock mfc_div_clks[] __initdata = { + /* DIV_MFC */ + DIV(CLK_DIV_PCLK_MFC, "div_pclk_mfc", "mout_aclk_mfc_400_user", + DIV_MFC, 0, 2), +}; + +static struct samsung_gate_clock mfc_gate_clks[] __initdata = { + /* ENABLE_ACLK_MFC */ + GATE(CLK_ACLK_BTS_MFC_1, "aclk_bts_mfc_1", "mout_aclk_mfc_400_user", + ENABLE_ACLK_MFC, 6, 0, 0), + GATE(CLK_ACLK_BTS_MFC_0, "aclk_bts_mfc_0", "mout_aclk_mfc_400_user", + ENABLE_ACLK_MFC, 5, 0, 0), + GATE(CLK_ACLK_AHB2APB_MFCP, "aclk_ahb2apb_mfcp", "div_pclk_mfc", + ENABLE_ACLK_MFC, 4, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_XIU_MFCX, "aclk_xiu_mfcx", "mout_aclk_mfc_400_user", + ENABLE_ACLK_MFC, 3, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_MFCNP_100, "aclk_mfcnp_100", "div_pclk_mfc", + ENABLE_ACLK_MFC, 2, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_MFCND_400, "aclk_mfcnd_400", "mout_aclk_mfc_400_user", + ENABLE_ACLK_MFC, 1, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_MFC, "aclk_mfc", "mout_aclk_mfc_400_user", + ENABLE_ACLK_MFC, 0, 0, 0), + + /* ENABLE_ACLK_MFC_SECURE_SMMU_MFC */ + GATE(CLK_ACLK_SMMU_MFC_1, "aclk_smmu_mfc_1", "mout_aclk_mfc_400_user", + ENABLE_ACLK_MFC_SECURE_SMMU_MFC, + 1, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_SMMU_MFC_0, "aclk_smmu_mfc_0", "mout_aclk_mfc_400_user", + ENABLE_ACLK_MFC_SECURE_SMMU_MFC, + 0, CLK_IGNORE_UNUSED, 0), + + /* ENABLE_PCLK_MFC */ + GATE(CLK_PCLK_BTS_MFC_1, "pclk_bts_mfc_1", "div_pclk_mfc", + ENABLE_PCLK_MFC, 4, 0, 0), + GATE(CLK_PCLK_BTS_MFC_0, "pclk_bts_mfc_0", "div_pclk_mfc", + ENABLE_PCLK_MFC, 3, 0, 0), + GATE(CLK_PCLK_PMU_MFC, "pclk_pmu_mfc", "div_pclk_mfc", + ENABLE_PCLK_MFC, 2, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_SYSREG_MFC, "pclk_sysreg_mfc", "div_pclk_mfc", + ENABLE_PCLK_MFC, 1, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_MFC, "pclk_mfc", "div_pclk_mfc", + ENABLE_PCLK_MFC, 4, CLK_IGNORE_UNUSED, 0), + + /* ENABLE_PCLK_MFC_SECURE_SMMU_MFC */ + GATE(CLK_PCLK_SMMU_MFC_1, "pclk_smmu_mfc_1", "div_pclk_mfc", + ENABLE_PCLK_MFC_SECURE_SMMU_MFC, + 1, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_SMMU_MFC_0, "pclk_smmu_mfc_0", "div_pclk_mfc", + ENABLE_PCLK_MFC_SECURE_SMMU_MFC, + 0, CLK_IGNORE_UNUSED, 0), +}; + +static struct samsung_cmu_info mfc_cmu_info __initdata = { + .mux_clks = mfc_mux_clks, + .nr_mux_clks = ARRAY_SIZE(mfc_mux_clks), + .div_clks = mfc_div_clks, + .nr_div_clks = ARRAY_SIZE(mfc_div_clks), + .gate_clks = mfc_gate_clks, + .nr_gate_clks = ARRAY_SIZE(mfc_gate_clks), + .nr_clk_ids = MFC_NR_CLK, + .clk_regs = mfc_clk_regs, + .nr_clk_regs = ARRAY_SIZE(mfc_clk_regs), +}; + +static void __init exynos5433_cmu_mfc_init(struct device_node *np) +{ + samsung_cmu_register_one(np, &mfc_cmu_info); +} +CLK_OF_DECLARE(exynos5433_cmu_mfc, "samsung,exynos5433-cmu-mfc", + exynos5433_cmu_mfc_init); diff --git a/include/dt-bindings/clock/exynos5433.h b/include/dt-bindings/clock/exynos5433.h index 9898390710e6..3301ab72c80d 100644 --- a/include/dt-bindings/clock/exynos5433.h +++ b/include/dt-bindings/clock/exynos5433.h @@ -153,8 +153,9 @@ #define CLK_ACLK_GSCL_333 233 #define CLK_SCLK_JPEG_MSCL 234 #define CLK_ACLK_MSCL_400 235 +#define CLK_ACLK_MFC_400 236 -#define TOP_NR_CLK 236 +#define TOP_NR_CLK 237 /* CMU_CPIF */ #define CLK_FOUT_MPHY_PLL 1 @@ -976,4 +977,28 @@ #define MSCL_NR_CLK 30 +/* CMU_MFC */ +#define CLK_MOUT_ACLK_MFC_400_USER 1 + +#define CLK_DIV_PCLK_MFC 2 + +#define CLK_ACLK_BTS_MFC_1 3 +#define CLK_ACLK_BTS_MFC_0 4 +#define CLK_ACLK_AHB2APB_MFCP 5 +#define CLK_ACLK_XIU_MFCX 6 +#define CLK_ACLK_MFCNP_100 7 +#define CLK_ACLK_MFCND_400 8 +#define CLK_ACLK_MFC 9 +#define CLK_ACLK_SMMU_MFC_1 10 +#define CLK_ACLK_SMMU_MFC_0 11 +#define CLK_PCLK_BTS_MFC_1 12 +#define CLK_PCLK_BTS_MFC_0 13 +#define CLK_PCLK_PMU_MFC 14 +#define CLK_PCLK_SYSREG_MFC 15 +#define CLK_PCLK_MFC 16 +#define CLK_PCLK_SMMU_MFC_1 17 +#define CLK_PCLK_SMMU_MFC_0 18 + +#define MFC_NR_CLK 19 + #endif /* _DT_BINDINGS_CLOCK_EXYNOS5433_H */ -- GitLab From 45e58aa5f751fd861d46f7b6d438c1be147458c6 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Tue, 3 Feb 2015 09:13:53 +0900 Subject: [PATCH 00051/11651] clk: samsung: exynos5433: Add clocks for CMU_HEVC domain This patch adds the mux/divider/gate clocks for CMU_HEVC domain which generates the clocks for HEVC(High Efficiency Video Codec) decoder IP. Signed-off-by: Chanwoo Choi Acked-by: Inki Dae Signed-off-by: Sylwester Nawrocki --- .../bindings/clock/exynos5433-clock.txt | 15 +++ drivers/clk/samsung/clk-exynos5433.c | 115 ++++++++++++++++++ include/dt-bindings/clock/exynos5433.h | 27 +++- 3 files changed, 156 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/clock/exynos5433-clock.txt b/Documentation/devicetree/bindings/clock/exynos5433-clock.txt index 0f35167ec15c..acc1d8aac95c 100644 --- a/Documentation/devicetree/bindings/clock/exynos5433-clock.txt +++ b/Documentation/devicetree/bindings/clock/exynos5433-clock.txt @@ -41,6 +41,8 @@ Required Properties: which generates clocks for M2M (Memory to Memory) scaler and JPEG IPs. - "samsung,exynos5433-cmu-mfc" - clock controller compatible for CMU_MFC which generates clocks for MFC(Multi-Format Codec) IP. + - "samsung,exynos5433-cmu-hevc" - clock controller compatible for CMU_HEVC + which generates clocks for HEVC(High Efficiency Video Codec) decoder IP. - reg: physical base address of the controller and length of memory mapped region. @@ -131,6 +133,10 @@ Required Properties: - oscclk - aclk_mfc_400 + Input clocks for hevc clock controller: + - oscclk + - aclk_hevc_400 + Each clock is assigned an identifier and client nodes can use this identifier to specify the clock which they consume. @@ -355,6 +361,15 @@ Example 2: Examples of clock controller nodes are listed below. clocks = <&xxti>, <&cmu_top CLK_ACLK_MFC_400>; }; + cmu_hevc: clock-controller@14f80000 { + compatible = "samsung,exynos5433-cmu-hevc"; + reg = <0x14f80000 0x0b08>; + #clock-cells = <1>; + + clock-names = "oscclk", "aclk_hevc_400"; + clocks = <&xxti>, <&cmu_top CLK_ACLK_HEVC_400>; + }; + Example 3: UART controller node that consumes the clock generated by the clock controller. diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c index 40558930711f..482a603c7e6b 100644 --- a/drivers/clk/samsung/clk-exynos5433.c +++ b/drivers/clk/samsung/clk-exynos5433.c @@ -560,6 +560,9 @@ static struct samsung_gate_clock top_gate_clks[] __initdata = { GATE(CLK_ACLK_GSCL_333, "aclk_gscl_333", "div_aclk_gscl_333", ENABLE_ACLK_TOP, 14, CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_HEVC_400, "aclk_hevc_400", "div_aclk_hevc_400", + ENABLE_ACLK_TOP, 5, + CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0), GATE(CLK_ACLK_MFC_400, "aclk_mfc_400", "div_aclk_mfc_400", ENABLE_ACLK_TOP, 3, CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0), @@ -4103,3 +4106,115 @@ static void __init exynos5433_cmu_mfc_init(struct device_node *np) } CLK_OF_DECLARE(exynos5433_cmu_mfc, "samsung,exynos5433-cmu-mfc", exynos5433_cmu_mfc_init); + +/* + * Register offset definitions for CMU_HEVC + */ +#define MUX_SEL_HEVC 0x0200 +#define MUX_ENABLE_HEVC 0x0300 +#define MUX_STAT_HEVC 0x0400 +#define DIV_HEVC 0x0600 +#define DIV_STAT_HEVC 0x0700 +#define ENABLE_ACLK_HEVC 0x0800 +#define ENABLE_ACLK_HEVC_SECURE_SMMU_HEVC 0x0804 +#define ENABLE_PCLK_HEVC 0x0900 +#define ENABLE_PCLK_HEVC_SECURE_SMMU_HEVC 0x0904 +#define ENABLE_IP_HEVC0 0x0b00 +#define ENABLE_IP_HEVC1 0x0b04 +#define ENABLE_IP_HEVC_SECURE_SMMU_HEVC 0x0b08 + +static unsigned long hevc_clk_regs[] __initdata = { + MUX_SEL_HEVC, + MUX_ENABLE_HEVC, + MUX_STAT_HEVC, + DIV_HEVC, + DIV_STAT_HEVC, + ENABLE_ACLK_HEVC, + ENABLE_ACLK_HEVC_SECURE_SMMU_HEVC, + ENABLE_PCLK_HEVC, + ENABLE_PCLK_HEVC_SECURE_SMMU_HEVC, + ENABLE_IP_HEVC0, + ENABLE_IP_HEVC1, + ENABLE_IP_HEVC_SECURE_SMMU_HEVC, +}; + +PNAME(mout_aclk_hevc_400_user_p) = { "oscclk", "aclk_hevc_400", }; + +static struct samsung_mux_clock hevc_mux_clks[] __initdata = { + /* MUX_SEL_HEVC */ + MUX(CLK_MOUT_ACLK_HEVC_400_USER, "mout_aclk_hevc_400_user", + mout_aclk_hevc_400_user_p, MUX_SEL_HEVC, 0, 0), +}; + +static struct samsung_div_clock hevc_div_clks[] __initdata = { + /* DIV_HEVC */ + DIV(CLK_DIV_PCLK_HEVC, "div_pclk_hevc", "mout_aclk_hevc_400_user", + DIV_HEVC, 0, 2), +}; + +static struct samsung_gate_clock hevc_gate_clks[] __initdata = { + /* ENABLE_ACLK_HEVC */ + GATE(CLK_ACLK_BTS_HEVC_1, "aclk_bts_hevc_1", "mout_aclk_hevc_400_user", + ENABLE_ACLK_HEVC, 6, 0, 0), + GATE(CLK_ACLK_BTS_HEVC_0, "aclk_bts_hevc_0", "mout_aclk_hevc_400_user", + ENABLE_ACLK_HEVC, 5, 0, 0), + GATE(CLK_ACLK_AHB2APB_HEVCP, "aclk_ahb2apb_hevcp", "div_pclk_hevc", + ENABLE_ACLK_HEVC, 4, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_XIU_HEVCX, "aclk_xiu_hevcx", "mout_aclk_hevc_400_user", + ENABLE_ACLK_HEVC, 3, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_HEVCNP_100, "aclk_hevcnp_100", "div_pclk_hevc", + ENABLE_ACLK_HEVC, 2, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_HEVCND_400, "aclk_hevcnd_400", "mout_aclk_hevc_400_user", + ENABLE_ACLK_HEVC, 1, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_HEVC, "aclk_hevc", "mout_aclk_hevc_400_user", + ENABLE_ACLK_HEVC, 0, 0, 0), + + /* ENABLE_ACLK_HEVC_SECURE_SMMU_HEVC */ + GATE(CLK_ACLK_SMMU_HEVC_1, "aclk_smmu_hevc_1", + "mout_aclk_hevc_400_user", + ENABLE_ACLK_HEVC_SECURE_SMMU_HEVC, + 1, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_SMMU_HEVC_0, "aclk_smmu_hevc_0", + "mout_aclk_hevc_400_user", + ENABLE_ACLK_HEVC_SECURE_SMMU_HEVC, + 0, CLK_IGNORE_UNUSED, 0), + + /* ENABLE_PCLK_HEVC */ + GATE(CLK_PCLK_BTS_HEVC_1, "pclk_bts_hevc_1", "div_pclk_hevc", + ENABLE_PCLK_HEVC, 4, 0, 0), + GATE(CLK_PCLK_BTS_HEVC_0, "pclk_bts_hevc_0", "div_pclk_hevc", + ENABLE_PCLK_HEVC, 3, 0, 0), + GATE(CLK_PCLK_PMU_HEVC, "pclk_pmu_hevc", "div_pclk_hevc", + ENABLE_PCLK_HEVC, 2, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_SYSREG_HEVC, "pclk_sysreg_hevc", "div_pclk_hevc", + ENABLE_PCLK_HEVC, 1, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_HEVC, "pclk_hevc", "div_pclk_hevc", + ENABLE_PCLK_HEVC, 4, CLK_IGNORE_UNUSED, 0), + + /* ENABLE_PCLK_HEVC_SECURE_SMMU_HEVC */ + GATE(CLK_PCLK_SMMU_HEVC_1, "pclk_smmu_hevc_1", "div_pclk_hevc", + ENABLE_PCLK_HEVC_SECURE_SMMU_HEVC, + 1, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_SMMU_HEVC_0, "pclk_smmu_hevc_0", "div_pclk_hevc", + ENABLE_PCLK_HEVC_SECURE_SMMU_HEVC, + 0, CLK_IGNORE_UNUSED, 0), +}; + +static struct samsung_cmu_info hevc_cmu_info __initdata = { + .mux_clks = hevc_mux_clks, + .nr_mux_clks = ARRAY_SIZE(hevc_mux_clks), + .div_clks = hevc_div_clks, + .nr_div_clks = ARRAY_SIZE(hevc_div_clks), + .gate_clks = hevc_gate_clks, + .nr_gate_clks = ARRAY_SIZE(hevc_gate_clks), + .nr_clk_ids = HEVC_NR_CLK, + .clk_regs = hevc_clk_regs, + .nr_clk_regs = ARRAY_SIZE(hevc_clk_regs), +}; + +static void __init exynos5433_cmu_hevc_init(struct device_node *np) +{ + samsung_cmu_register_one(np, &hevc_cmu_info); +} +CLK_OF_DECLARE(exynos5433_cmu_hevc, "samsung,exynos5433-cmu-hevc", + exynos5433_cmu_hevc_init); diff --git a/include/dt-bindings/clock/exynos5433.h b/include/dt-bindings/clock/exynos5433.h index 3301ab72c80d..1b2d333c1786 100644 --- a/include/dt-bindings/clock/exynos5433.h +++ b/include/dt-bindings/clock/exynos5433.h @@ -154,8 +154,9 @@ #define CLK_SCLK_JPEG_MSCL 234 #define CLK_ACLK_MSCL_400 235 #define CLK_ACLK_MFC_400 236 +#define CLK_ACLK_HEVC_400 237 -#define TOP_NR_CLK 237 +#define TOP_NR_CLK 238 /* CMU_CPIF */ #define CLK_FOUT_MPHY_PLL 1 @@ -1001,4 +1002,28 @@ #define MFC_NR_CLK 19 +/* CMU_HEVC */ +#define CLK_MOUT_ACLK_HEVC_400_USER 1 + +#define CLK_DIV_PCLK_HEVC 2 + +#define CLK_ACLK_BTS_HEVC_1 3 +#define CLK_ACLK_BTS_HEVC_0 4 +#define CLK_ACLK_AHB2APB_HEVCP 5 +#define CLK_ACLK_XIU_HEVCX 6 +#define CLK_ACLK_HEVCNP_100 7 +#define CLK_ACLK_HEVCND_400 8 +#define CLK_ACLK_HEVC 9 +#define CLK_ACLK_SMMU_HEVC_1 10 +#define CLK_ACLK_SMMU_HEVC_0 11 +#define CLK_PCLK_BTS_HEVC_1 12 +#define CLK_PCLK_BTS_HEVC_0 13 +#define CLK_PCLK_PMU_HEVC 14 +#define CLK_PCLK_SYSREG_HEVC 15 +#define CLK_PCLK_HEVC 16 +#define CLK_PCLK_SMMU_HEVC_1 17 +#define CLK_PCLK_SMMU_HEVC_0 18 + +#define HEVC_NR_CLK 19 + #endif /* _DT_BINDINGS_CLOCK_EXYNOS5433_H */ -- GitLab From 8e46c4b84faf317773d5a4ec6d807ceae2d0eb41 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Tue, 3 Feb 2015 09:13:54 +0900 Subject: [PATCH 00052/11651] clk: samsung: exynos5433: Add clocks for CMU_ISP domain This patch adds the mux/divider/gate clocks for CMU_ISP domain which generates the clocks for FIMC-ISP/DRC/SCLC/DIS/3DNR IPs. Signed-off-by: Chanwoo Choi Acked-by: Inki Dae Signed-off-by: Sylwester Nawrocki --- .../bindings/clock/exynos5433-clock.txt | 20 ++ drivers/clk/samsung/clk-exynos5433.c | 267 ++++++++++++++++++ include/dt-bindings/clock/exynos5433.h | 89 +++++- 3 files changed, 375 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/clock/exynos5433-clock.txt b/Documentation/devicetree/bindings/clock/exynos5433-clock.txt index acc1d8aac95c..4f3bfcd366a3 100644 --- a/Documentation/devicetree/bindings/clock/exynos5433-clock.txt +++ b/Documentation/devicetree/bindings/clock/exynos5433-clock.txt @@ -43,6 +43,8 @@ Required Properties: which generates clocks for MFC(Multi-Format Codec) IP. - "samsung,exynos5433-cmu-hevc" - clock controller compatible for CMU_HEVC which generates clocks for HEVC(High Efficiency Video Codec) decoder IP. + - "samsung,exynos5433-cmu-isp" - clock controller compatible for CMU_ISP + which generates clocks for FIMC-ISP/DRC/SCLC/DIS/3DNR IPs. - reg: physical base address of the controller and length of memory mapped region. @@ -137,6 +139,11 @@ Required Properties: - oscclk - aclk_hevc_400 + Input clocks for isp clock controller: + - oscclk + - aclk_isp_dis_400 + - aclk_isp_400 + Each clock is assigned an identifier and client nodes can use this identifier to specify the clock which they consume. @@ -370,6 +377,19 @@ Example 2: Examples of clock controller nodes are listed below. clocks = <&xxti>, <&cmu_top CLK_ACLK_HEVC_400>; }; + cmu_isp: clock-controller@146d0000 { + compatible = "samsung,exynos5433-cmu-isp"; + reg = <0x146d0000 0x0b0c>; + #clock-cells = <1>; + + clock-names = "oscclk", + "aclk_isp_dis_400", + "aclk_isp_400"; + clocks = <&xxti>, + <&cmu_top CLK_ACLK_ISP_DIS_400>, + <&cmu_top CLK_ACLK_ISP_400>; + }; + Example 3: UART controller node that consumes the clock generated by the clock controller. diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c index 482a603c7e6b..a8ea6e1fbffc 100644 --- a/drivers/clk/samsung/clk-exynos5433.c +++ b/drivers/clk/samsung/clk-exynos5433.c @@ -404,6 +404,12 @@ static struct samsung_mux_clock top_mux_clks[] __initdata = { }; static struct samsung_div_clock top_div_clks[] __initdata = { + /* DIV_TOP0 */ + DIV(CLK_DIV_ACLK_ISP_DIS_400, "div_aclk_isp_dis_400", + "mout_aclk_isp_dis_400", DIV_TOP0, 4, 4), + DIV(CLK_DIV_ACLK_ISP_400, "div_aclk_isp_400", + "mout_aclk_isp_400", DIV_TOP0, 0, 4), + /* DIV_TOP1 */ DIV(CLK_DIV_ACLK_GSCL_111, "div_aclk_gscl_111", "mout_aclk_gscl_333", DIV_TOP1, 28, 3), @@ -560,6 +566,12 @@ static struct samsung_gate_clock top_gate_clks[] __initdata = { GATE(CLK_ACLK_GSCL_333, "aclk_gscl_333", "div_aclk_gscl_333", ENABLE_ACLK_TOP, 14, CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ISP_DIS_400, "aclk_isp_dis_400", "div_aclk_isp_dis_400", + ENABLE_ACLK_TOP, 7, + CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ISP_400, "aclk_isp_400", "div_aclk_isp_400", + ENABLE_ACLK_TOP, 6, + CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0), GATE(CLK_ACLK_HEVC_400, "aclk_hevc_400", "div_aclk_hevc_400", ENABLE_ACLK_TOP, 5, CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0), @@ -4218,3 +4230,258 @@ static void __init exynos5433_cmu_hevc_init(struct device_node *np) } CLK_OF_DECLARE(exynos5433_cmu_hevc, "samsung,exynos5433-cmu-hevc", exynos5433_cmu_hevc_init); + +/* + * Register offset definitions for CMU_ISP + */ +#define MUX_SEL_ISP 0x0200 +#define MUX_ENABLE_ISP 0x0300 +#define MUX_STAT_ISP 0x0400 +#define DIV_ISP 0x0600 +#define DIV_STAT_ISP 0x0700 +#define ENABLE_ACLK_ISP0 0x0800 +#define ENABLE_ACLK_ISP1 0x0804 +#define ENABLE_ACLK_ISP2 0x0808 +#define ENABLE_PCLK_ISP 0x0900 +#define ENABLE_SCLK_ISP 0x0a00 +#define ENABLE_IP_ISP0 0x0b00 +#define ENABLE_IP_ISP1 0x0b04 +#define ENABLE_IP_ISP2 0x0b08 +#define ENABLE_IP_ISP3 0x0b0c + +static unsigned long isp_clk_regs[] __initdata = { + MUX_SEL_ISP, + MUX_ENABLE_ISP, + MUX_STAT_ISP, + DIV_ISP, + DIV_STAT_ISP, + ENABLE_ACLK_ISP0, + ENABLE_ACLK_ISP1, + ENABLE_ACLK_ISP2, + ENABLE_PCLK_ISP, + ENABLE_SCLK_ISP, + ENABLE_IP_ISP0, + ENABLE_IP_ISP1, + ENABLE_IP_ISP2, + ENABLE_IP_ISP3, +}; + +PNAME(mout_aclk_isp_dis_400_user_p) = { "oscclk", "aclk_isp_dis_400", }; +PNAME(mout_aclk_isp_400_user_p) = { "oscclk", "aclk_isp_400", }; + +static struct samsung_mux_clock isp_mux_clks[] __initdata = { + /* MUX_SEL_ISP */ + MUX(CLK_MOUT_ACLK_ISP_DIS_400_USER, "mout_aclk_isp_dis_400_user", + mout_aclk_isp_dis_400_user_p, MUX_SEL_ISP, 4, 0), + MUX(CLK_MOUT_ACLK_ISP_400_USER, "mout_aclk_isp_400_user", + mout_aclk_isp_400_user_p, MUX_SEL_ISP, 0, 0), +}; + +static struct samsung_div_clock isp_div_clks[] __initdata = { + /* DIV_ISP */ + DIV(CLK_DIV_PCLK_ISP_DIS, "div_pclk_isp_dis", + "mout_aclk_isp_dis_400_user", DIV_ISP, 12, 3), + DIV(CLK_DIV_PCLK_ISP, "div_pclk_isp", "mout_aclk_isp_400_user", + DIV_ISP, 8, 3), + DIV(CLK_DIV_ACLK_ISP_D_200, "div_aclk_isp_d_200", + "mout_aclk_isp_400_user", DIV_ISP, 4, 3), + DIV(CLK_DIV_ACLK_ISP_C_200, "div_aclk_isp_c_200", + "mout_aclk_isp_400_user", DIV_ISP, 0, 3), +}; + +static struct samsung_gate_clock isp_gate_clks[] __initdata = { + /* ENABLE_ACLK_ISP0 */ + GATE(CLK_ACLK_ISP_D_GLUE, "aclk_isp_d_glue", "mout_aclk_isp_400_user", + ENABLE_ACLK_ISP0, 6, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_SCALERP, "aclk_scalerp", "mout_aclk_isp_400_user", + ENABLE_ACLK_ISP0, 5, 0, 0), + GATE(CLK_ACLK_3DNR, "aclk_3dnr", "mout_aclk_isp_400_user", + ENABLE_ACLK_ISP0, 4, 0, 0), + GATE(CLK_ACLK_DIS, "aclk_dis", "mout_aclk_isp_dis_400_user", + ENABLE_ACLK_ISP0, 3, 0, 0), + GATE(CLK_ACLK_SCALERC, "aclk_scalerc", "mout_aclk_isp_400_user", + ENABLE_ACLK_ISP0, 2, 0, 0), + GATE(CLK_ACLK_DRC, "aclk_drc", "mout_aclk_isp_400_user", + ENABLE_ACLK_ISP0, 1, 0, 0), + GATE(CLK_ACLK_ISP, "aclk_isp", "mout_aclk_isp_400_user", + ENABLE_ACLK_ISP0, 0, 0, 0), + + /* ENABLE_ACLK_ISP1 */ + GATE(CLK_ACLK_AXIUS_SCALERP, "aclk_axius_scalerp", + "mout_aclk_isp_400_user", ENABLE_ACLK_ISP1, + 17, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_AXIUS_SCALERC, "aclk_axius_scalerc", + "mout_aclk_isp_400_user", ENABLE_ACLK_ISP1, + 16, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_AXIUS_DRC, "aclk_axius_drc", + "mout_aclk_isp_400_user", ENABLE_ACLK_ISP1, + 15, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAHBM_ISP2P, "aclk_asyncahbm_isp2p", + "div_pclk_isp", ENABLE_ACLK_ISP1, + 14, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAHBM_ISP1P, "aclk_asyncahbm_isp1p", + "div_pclk_isp", ENABLE_ACLK_ISP1, + 13, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAXIS_DIS1, "aclk_asyncaxis_dis1", + "mout_aclk_isp_dis_400_user", ENABLE_ACLK_ISP1, + 12, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAXIS_DIS0, "aclk_asyncaxis_dis0", + "mout_aclk_isp_dis_400_user", ENABLE_ACLK_ISP1, + 11, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAXIM_DIS1, "aclk_asyncaxim_dis1", + "mout_aclk_isp_400_user", ENABLE_ACLK_ISP1, + 10, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAXIM_DIS0, "aclk_asyncaxim_dis0", + "mout_aclk_isp_400_user", ENABLE_ACLK_ISP1, + 9, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAXIM_ISP2P, "aclk_asyncaxim_isp2p", + "div_aclk_isp_d_200", ENABLE_ACLK_ISP1, + 8, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAXIM_ISP1P, "aclk_asyncaxim_isp1p", + "div_aclk_isp_c_200", ENABLE_ACLK_ISP1, + 7, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_AHB2APB_ISP2P, "aclk_ahb2apb_isp2p", "div_pclk_isp", + ENABLE_ACLK_ISP1, 6, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_AHB2APB_ISP1P, "aclk_ahb2apb_isp1p", "div_pclk_isp", + ENABLE_ACLK_ISP1, 5, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_AXI2APB_ISP2P, "aclk_axi2apb_isp2p", + "div_aclk_isp_d_200", ENABLE_ACLK_ISP1, + 4, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_AXI2APB_ISP1P, "aclk_axi2apb_isp1p", + "div_aclk_isp_c_200", ENABLE_ACLK_ISP1, + 3, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_XIU_ISPEX1, "aclk_xiu_ispex1", "mout_aclk_isp_400_user", + ENABLE_ACLK_ISP1, 2, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_XIU_ISPEX0, "aclk_xiu_ispex0", "mout_aclk_isp_400_user", + ENABLE_ACLK_ISP1, 1, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ISPND_400, "aclk_ispnd_400", "mout_aclk_isp_400_user", + ENABLE_ACLK_ISP1, 1, CLK_IGNORE_UNUSED, 0), + + /* ENABLE_ACLK_ISP2 */ + GATE(CLK_ACLK_SMMU_SCALERP, "aclk_smmu_scalerp", + "mout_aclk_isp_400_user", ENABLE_ACLK_ISP2, + 13, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_SMMU_3DNR, "aclk_smmu_3dnr", "mout_aclk_isp_400_user", + ENABLE_ACLK_ISP2, 12, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_SMMU_DIS1, "aclk_smmu_dis1", "mout_aclk_isp_400_user", + ENABLE_ACLK_ISP2, 11, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_SMMU_DIS0, "aclk_smmu_dis0", "mout_aclk_isp_400_user", + ENABLE_ACLK_ISP2, 10, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_SMMU_SCALERC, "aclk_smmu_scalerc", + "mout_aclk_isp_400_user", ENABLE_ACLK_ISP2, + 9, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_SMMU_DRC, "aclk_smmu_drc", "mout_aclk_isp_400_user", + ENABLE_ACLK_ISP2, 8, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_SMMU_ISP, "aclk_smmu_isp", "mout_aclk_isp_400_user", + ENABLE_ACLK_ISP2, 7, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_BTS_SCALERP, "aclk_bts_scalerp", + "mout_aclk_isp_400_user", ENABLE_ACLK_ISP2, + 6, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_BTS_3DR, "aclk_bts_3dnr", "mout_aclk_isp_400_user", + ENABLE_ACLK_ISP2, 5, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_BTS_DIS1, "aclk_bts_dis1", "mout_aclk_isp_400_user", + ENABLE_ACLK_ISP2, 4, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_BTS_DIS0, "aclk_bts_dis0", "mout_aclk_isp_400_user", + ENABLE_ACLK_ISP2, 3, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_BTS_SCALERC, "aclk_bts_scalerc", + "mout_aclk_isp_400_user", ENABLE_ACLK_ISP2, + 2, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_BTS_DRC, "aclk_bts_drc", "mout_aclk_isp_400_user", + ENABLE_ACLK_ISP2, 1, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_BTS_ISP, "aclk_bts_isp", "mout_aclk_isp_400_user", + ENABLE_ACLK_ISP2, 0, CLK_IGNORE_UNUSED, 0), + + /* ENABLE_PCLK_ISP */ + GATE(CLK_PCLK_SMMU_SCALERP, "pclk_smmu_scalerp", "div_aclk_isp_d_200", + ENABLE_PCLK_ISP, 25, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_SMMU_3DNR, "pclk_smmu_3dnr", "div_aclk_isp_d_200", + ENABLE_PCLK_ISP, 24, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_SMMU_DIS1, "pclk_smmu_dis1", "div_aclk_isp_d_200", + ENABLE_PCLK_ISP, 23, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_SMMU_DIS0, "pclk_smmu_dis0", "div_aclk_isp_d_200", + ENABLE_PCLK_ISP, 22, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_SMMU_SCALERC, "pclk_smmu_scalerc", "div_aclk_isp_c_200", + ENABLE_PCLK_ISP, 21, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_SMMU_DRC, "pclk_smmu_drc", "div_aclk_isp_c_200", + ENABLE_PCLK_ISP, 20, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_SMMU_ISP, "pclk_smmu_isp", "div_aclk_isp_c_200", + ENABLE_PCLK_ISP, 19, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_BTS_SCALERP, "pclk_bts_scalerp", "div_pclk_isp", + ENABLE_PCLK_ISP, 18, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_BTS_3DNR, "pclk_bts_3dnr", "div_pclk_isp", + ENABLE_PCLK_ISP, 17, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_BTS_DIS1, "pclk_bts_dis1", "div_pclk_isp", + ENABLE_PCLK_ISP, 16, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_BTS_DIS0, "pclk_bts_dis0", "div_pclk_isp", + ENABLE_PCLK_ISP, 15, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_BTS_SCALERC, "pclk_bts_scalerc", "div_pclk_isp", + ENABLE_PCLK_ISP, 14, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_BTS_DRC, "pclk_bts_drc", "div_pclk_isp", + ENABLE_PCLK_ISP, 13, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_BTS_ISP, "pclk_bts_isp", "div_pclk_isp", + ENABLE_PCLK_ISP, 12, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_ASYNCAXI_DIS1, "pclk_asyncaxi_dis1", "div_pclk_isp", + ENABLE_PCLK_ISP, 11, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_ASYNCAXI_DIS0, "pclk_asyncaxi_dis0", "div_pclk_isp", + ENABLE_PCLK_ISP, 10, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_PMU_ISP, "pclk_pmu_isp", "div_pclk_isp", + ENABLE_PCLK_ISP, 9, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_SYSREG_ISP, "pclk_sysreg_isp", "div_pclk_isp", + ENABLE_PCLK_ISP, 8, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_CMU_ISP_LOCAL, "pclk_cmu_isp_local", + "div_aclk_isp_c_200", ENABLE_PCLK_ISP, + 7, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_SCALERP, "pclk_scalerp", "div_aclk_isp_d_200", + ENABLE_PCLK_ISP, 6, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_3DNR, "pclk_3dnr", "div_aclk_isp_d_200", + ENABLE_PCLK_ISP, 5, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_DIS_CORE, "pclk_dis_core", "div_pclk_isp_dis", + ENABLE_PCLK_ISP, 4, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_DIS, "pclk_dis", "div_aclk_isp_d_200", + ENABLE_PCLK_ISP, 3, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_SCALERC, "pclk_scalerc", "div_aclk_isp_c_200", + ENABLE_PCLK_ISP, 2, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_DRC, "pclk_drc", "div_aclk_isp_c_200", + ENABLE_PCLK_ISP, 1, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_ISP, "pclk_isp", "div_aclk_isp_c_200", + ENABLE_PCLK_ISP, 0, CLK_IGNORE_UNUSED, 0), + + /* ENABLE_SCLK_ISP */ + GATE(CLK_SCLK_PIXELASYNCS_DIS, "sclk_pixelasyncs_dis", + "mout_aclk_isp_dis_400_user", ENABLE_SCLK_ISP, + 5, CLK_IGNORE_UNUSED, 0), + GATE(CLK_SCLK_PIXELASYNCM_DIS, "sclk_pixelasyncm_dis", + "mout_aclk_isp_dis_400_user", ENABLE_SCLK_ISP, + 4, CLK_IGNORE_UNUSED, 0), + GATE(CLK_SCLK_PIXELASYNCS_SCALERP, "sclk_pixelasyncs_scalerp", + "mout_aclk_isp_400_user", ENABLE_SCLK_ISP, + 3, CLK_IGNORE_UNUSED, 0), + GATE(CLK_SCLK_PIXELASYNCM_ISPD, "sclk_pixelasyncm_ispd", + "mout_aclk_isp_400_user", ENABLE_SCLK_ISP, + 2, CLK_IGNORE_UNUSED, 0), + GATE(CLK_SCLK_PIXELASYNCS_ISPC, "sclk_pixelasyncs_ispc", + "mout_aclk_isp_400_user", ENABLE_SCLK_ISP, + 1, CLK_IGNORE_UNUSED, 0), + GATE(CLK_SCLK_PIXELASYNCM_ISPC, "sclk_pixelasyncm_ispc", + "mout_aclk_isp_400_user", ENABLE_SCLK_ISP, + 0, CLK_IGNORE_UNUSED, 0), +}; + +static struct samsung_cmu_info isp_cmu_info __initdata = { + .mux_clks = isp_mux_clks, + .nr_mux_clks = ARRAY_SIZE(isp_mux_clks), + .div_clks = isp_div_clks, + .nr_div_clks = ARRAY_SIZE(isp_div_clks), + .gate_clks = isp_gate_clks, + .nr_gate_clks = ARRAY_SIZE(isp_gate_clks), + .nr_clk_ids = ISP_NR_CLK, + .clk_regs = isp_clk_regs, + .nr_clk_regs = ARRAY_SIZE(isp_clk_regs), +}; + +static void __init exynos5433_cmu_isp_init(struct device_node *np) +{ + samsung_cmu_register_one(np, &isp_cmu_info); +} +CLK_OF_DECLARE(exynos5433_cmu_isp, "samsung,exynos5433-cmu-isp", + exynos5433_cmu_isp_init); diff --git a/include/dt-bindings/clock/exynos5433.h b/include/dt-bindings/clock/exynos5433.h index 1b2d333c1786..fbc81e3424a6 100644 --- a/include/dt-bindings/clock/exynos5433.h +++ b/include/dt-bindings/clock/exynos5433.h @@ -116,6 +116,8 @@ #define CLK_DIV_SCLK_USBDRD30 143 #define CLK_DIV_SCLK_JPEG 144 #define CLK_DIV_ACLK_MSCL_400 145 +#define CLK_DIV_ACLK_ISP_DIS_400 146 +#define CLK_DIV_ACLK_ISP_400 147 #define CLK_ACLK_PERIC_66 200 #define CLK_ACLK_PERIS_66 201 @@ -155,8 +157,10 @@ #define CLK_ACLK_MSCL_400 235 #define CLK_ACLK_MFC_400 236 #define CLK_ACLK_HEVC_400 237 +#define CLK_ACLK_ISP_DIS_400 238 +#define CLK_ACLK_ISP_400 239 -#define TOP_NR_CLK 238 +#define TOP_NR_CLK 240 /* CMU_CPIF */ #define CLK_FOUT_MPHY_PLL 1 @@ -1026,4 +1030,87 @@ #define HEVC_NR_CLK 19 +/* CMU_ISP */ +#define CLK_MOUT_ACLK_ISP_DIS_400_USER 1 +#define CLK_MOUT_ACLK_ISP_400_USER 2 + +#define CLK_DIV_PCLK_ISP_DIS 3 +#define CLK_DIV_PCLK_ISP 4 +#define CLK_DIV_ACLK_ISP_D_200 5 +#define CLK_DIV_ACLK_ISP_C_200 6 + +#define CLK_ACLK_ISP_D_GLUE 7 +#define CLK_ACLK_SCALERP 8 +#define CLK_ACLK_3DNR 9 +#define CLK_ACLK_DIS 10 +#define CLK_ACLK_SCALERC 11 +#define CLK_ACLK_DRC 12 +#define CLK_ACLK_ISP 13 +#define CLK_ACLK_AXIUS_SCALERP 14 +#define CLK_ACLK_AXIUS_SCALERC 15 +#define CLK_ACLK_AXIUS_DRC 16 +#define CLK_ACLK_ASYNCAHBM_ISP2P 17 +#define CLK_ACLK_ASYNCAHBM_ISP1P 18 +#define CLK_ACLK_ASYNCAXIS_DIS1 19 +#define CLK_ACLK_ASYNCAXIS_DIS0 20 +#define CLK_ACLK_ASYNCAXIM_DIS1 21 +#define CLK_ACLK_ASYNCAXIM_DIS0 22 +#define CLK_ACLK_ASYNCAXIM_ISP2P 23 +#define CLK_ACLK_ASYNCAXIM_ISP1P 24 +#define CLK_ACLK_AHB2APB_ISP2P 25 +#define CLK_ACLK_AHB2APB_ISP1P 26 +#define CLK_ACLK_AXI2APB_ISP2P 27 +#define CLK_ACLK_AXI2APB_ISP1P 28 +#define CLK_ACLK_XIU_ISPEX1 29 +#define CLK_ACLK_XIU_ISPEX0 30 +#define CLK_ACLK_ISPND_400 31 +#define CLK_ACLK_SMMU_SCALERP 32 +#define CLK_ACLK_SMMU_3DNR 33 +#define CLK_ACLK_SMMU_DIS1 34 +#define CLK_ACLK_SMMU_DIS0 35 +#define CLK_ACLK_SMMU_SCALERC 36 +#define CLK_ACLK_SMMU_DRC 37 +#define CLK_ACLK_SMMU_ISP 38 +#define CLK_ACLK_BTS_SCALERP 39 +#define CLK_ACLK_BTS_3DR 40 +#define CLK_ACLK_BTS_DIS1 41 +#define CLK_ACLK_BTS_DIS0 42 +#define CLK_ACLK_BTS_SCALERC 43 +#define CLK_ACLK_BTS_DRC 44 +#define CLK_ACLK_BTS_ISP 45 +#define CLK_PCLK_SMMU_SCALERP 46 +#define CLK_PCLK_SMMU_3DNR 47 +#define CLK_PCLK_SMMU_DIS1 48 +#define CLK_PCLK_SMMU_DIS0 49 +#define CLK_PCLK_SMMU_SCALERC 50 +#define CLK_PCLK_SMMU_DRC 51 +#define CLK_PCLK_SMMU_ISP 52 +#define CLK_PCLK_BTS_SCALERP 53 +#define CLK_PCLK_BTS_3DNR 54 +#define CLK_PCLK_BTS_DIS1 55 +#define CLK_PCLK_BTS_DIS0 56 +#define CLK_PCLK_BTS_SCALERC 57 +#define CLK_PCLK_BTS_DRC 58 +#define CLK_PCLK_BTS_ISP 59 +#define CLK_PCLK_ASYNCAXI_DIS1 60 +#define CLK_PCLK_ASYNCAXI_DIS0 61 +#define CLK_PCLK_PMU_ISP 62 +#define CLK_PCLK_SYSREG_ISP 63 +#define CLK_PCLK_CMU_ISP_LOCAL 64 +#define CLK_PCLK_SCALERP 65 +#define CLK_PCLK_3DNR 66 +#define CLK_PCLK_DIS_CORE 67 +#define CLK_PCLK_DIS 68 +#define CLK_PCLK_SCALERC 69 +#define CLK_PCLK_DRC 70 +#define CLK_PCLK_ISP 71 +#define CLK_SCLK_PIXELASYNCS_DIS 72 +#define CLK_SCLK_PIXELASYNCM_DIS 73 +#define CLK_SCLK_PIXELASYNCS_SCALERP 74 +#define CLK_SCLK_PIXELASYNCM_ISPD 75 +#define CLK_SCLK_PIXELASYNCS_ISPC 76 +#define CLK_SCLK_PIXELASYNCM_ISPC 77 + +#define ISP_NR_CLK 78 + #endif /* _DT_BINDINGS_CLOCK_EXYNOS5433_H */ -- GitLab From 6958f22f39f9292f6e871b4383a11f183c1271ed Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Tue, 3 Feb 2015 09:13:55 +0900 Subject: [PATCH 00053/11651] clk: samsung: exynos5433: Add clocks for CMU_CAM0 domain This patch adds the mux/divider/gate clocks for CMU_CAM0 domain which generates the clocks for MIPI_CSIS{0|1}/FIMC_LITE_{A|B|D}/FIMC_3AA{0|1} IPs. Signed-off-by: Chanwoo Choi Acked-by: Inki Dae Signed-off-by: Sylwester Nawrocki --- .../bindings/clock/exynos5433-clock.txt | 24 + drivers/clk/samsung/clk-exynos5433.c | 501 ++++++++++++++++++ include/dt-bindings/clock/exynos5433.h | 146 ++++- 3 files changed, 670 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/clock/exynos5433-clock.txt b/Documentation/devicetree/bindings/clock/exynos5433-clock.txt index 4f3bfcd366a3..84002e4b52e5 100644 --- a/Documentation/devicetree/bindings/clock/exynos5433-clock.txt +++ b/Documentation/devicetree/bindings/clock/exynos5433-clock.txt @@ -45,6 +45,9 @@ Required Properties: which generates clocks for HEVC(High Efficiency Video Codec) decoder IP. - "samsung,exynos5433-cmu-isp" - clock controller compatible for CMU_ISP which generates clocks for FIMC-ISP/DRC/SCLC/DIS/3DNR IPs. + - "samsung,exynos5433-cmu-cam0" - clock controller compatible for CMU_CAM0 + which generates clocks for MIPI_CSIS{0|1}/FIMC_LITE_{A|B|D}/FIMC_3AA{0|1} + IPs. - reg: physical base address of the controller and length of memory mapped region. @@ -144,6 +147,12 @@ Required Properties: - aclk_isp_dis_400 - aclk_isp_400 + Input clocks for cam0 clock controller: + - oscclk + - aclk_cam0_333 + - aclk_cam0_400 + - aclk_cam0_552 + Each clock is assigned an identifier and client nodes can use this identifier to specify the clock which they consume. @@ -390,6 +399,21 @@ Example 2: Examples of clock controller nodes are listed below. <&cmu_top CLK_ACLK_ISP_400>; }; + cmu_cam0: clock-controller@120d0000 { + compatible = "samsung,exynos5433-cmu-cam0"; + reg = <0x120d0000 0x0b0c>; + #clock-cells = <1>; + + clock-names = "oscclk", + "aclk_cam0_333", + "aclk_cam0_400", + "aclk_cam0_552"; + clocks = <&xxti>, + <&cmu_top CLK_ACLK_CAM0_333>, + <&cmu_top CLK_ACLK_CAM0_400>, + <&cmu_top CLK_ACLK_CAM0_552>; + }; + Example 3: UART controller node that consumes the clock generated by the clock controller. diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c index a8ea6e1fbffc..ce6487375670 100644 --- a/drivers/clk/samsung/clk-exynos5433.c +++ b/drivers/clk/samsung/clk-exynos5433.c @@ -405,6 +405,12 @@ static struct samsung_mux_clock top_mux_clks[] __initdata = { static struct samsung_div_clock top_div_clks[] __initdata = { /* DIV_TOP0 */ + DIV(CLK_DIV_ACLK_CAM0_333, "div_aclk_cam0_333", "mout_mfc_pll_user", + DIV_TOP0, 16, 3), + DIV(CLK_DIV_ACLK_CAM0_400, "div_aclk_cam0_400", "mout_bus_pll_user", + DIV_TOP0, 12, 3), + DIV(CLK_DIV_ACLK_CAM0_552, "div_aclk_cam0_552", "mout_isp_pll", + DIV_TOP0, 8, 3), DIV(CLK_DIV_ACLK_ISP_DIS_400, "div_aclk_isp_dis_400", "mout_aclk_isp_dis_400", DIV_TOP0, 4, 4), DIV(CLK_DIV_ACLK_ISP_400, "div_aclk_isp_400", @@ -566,6 +572,15 @@ static struct samsung_gate_clock top_gate_clks[] __initdata = { GATE(CLK_ACLK_GSCL_333, "aclk_gscl_333", "div_aclk_gscl_333", ENABLE_ACLK_TOP, 14, CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_CAM0_333, "aclk_cam0_333", "div_aclk_cam0_333", + ENABLE_ACLK_TOP, 10, + CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_CAM0_400, "aclk_cam0_400", "div_aclk_cam0_400", + ENABLE_ACLK_TOP, 9, + CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_CAM0_552, "aclk_cam0_552", "div_aclk_cam0_552", + ENABLE_ACLK_TOP, 8, + CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0), GATE(CLK_ACLK_ISP_DIS_400, "aclk_isp_dis_400", "div_aclk_isp_dis_400", ENABLE_ACLK_TOP, 7, CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0), @@ -4485,3 +4500,489 @@ static void __init exynos5433_cmu_isp_init(struct device_node *np) } CLK_OF_DECLARE(exynos5433_cmu_isp, "samsung,exynos5433-cmu-isp", exynos5433_cmu_isp_init); + +/* + * Register offset definitions for CMU_CAM0 + */ +#define MUX_SEL_CAM00 0x0200 +#define MUX_SEL_CAM01 0x0204 +#define MUX_SEL_CAM02 0x0208 +#define MUX_SEL_CAM03 0x020c +#define MUX_SEL_CAM04 0x0210 +#define MUX_ENABLE_CAM00 0x0300 +#define MUX_ENABLE_CAM01 0x0304 +#define MUX_ENABLE_CAM02 0x0308 +#define MUX_ENABLE_CAM03 0x030c +#define MUX_ENABLE_CAM04 0x0310 +#define MUX_STAT_CAM00 0x0400 +#define MUX_STAT_CAM01 0x0404 +#define MUX_STAT_CAM02 0x0408 +#define MUX_STAT_CAM03 0x040c +#define MUX_STAT_CAM04 0x0410 +#define MUX_IGNORE_CAM01 0x0504 +#define DIV_CAM00 0x0600 +#define DIV_CAM01 0x0604 +#define DIV_CAM02 0x0608 +#define DIV_CAM03 0x060c +#define DIV_STAT_CAM00 0x0700 +#define DIV_STAT_CAM01 0x0704 +#define DIV_STAT_CAM02 0x0708 +#define DIV_STAT_CAM03 0x070c +#define ENABLE_ACLK_CAM00 0X0800 +#define ENABLE_ACLK_CAM01 0X0804 +#define ENABLE_ACLK_CAM02 0X0808 +#define ENABLE_PCLK_CAM0 0X0900 +#define ENABLE_SCLK_CAM0 0X0a00 +#define ENABLE_IP_CAM00 0X0b00 +#define ENABLE_IP_CAM01 0X0b04 +#define ENABLE_IP_CAM02 0X0b08 +#define ENABLE_IP_CAM03 0X0b0C + +static unsigned long cam0_clk_regs[] __initdata = { + MUX_SEL_CAM00, + MUX_SEL_CAM01, + MUX_SEL_CAM02, + MUX_SEL_CAM03, + MUX_SEL_CAM04, + MUX_ENABLE_CAM00, + MUX_ENABLE_CAM01, + MUX_ENABLE_CAM02, + MUX_ENABLE_CAM03, + MUX_ENABLE_CAM04, + MUX_STAT_CAM00, + MUX_STAT_CAM01, + MUX_STAT_CAM02, + MUX_STAT_CAM03, + MUX_STAT_CAM04, + MUX_IGNORE_CAM01, + DIV_CAM00, + DIV_CAM01, + DIV_CAM02, + DIV_CAM03, + DIV_STAT_CAM00, + DIV_STAT_CAM01, + DIV_STAT_CAM02, + DIV_STAT_CAM03, + ENABLE_ACLK_CAM00, + ENABLE_ACLK_CAM01, + ENABLE_ACLK_CAM02, + ENABLE_PCLK_CAM0, + ENABLE_SCLK_CAM0, + ENABLE_IP_CAM00, + ENABLE_IP_CAM01, + ENABLE_IP_CAM02, + ENABLE_IP_CAM03, +}; +PNAME(mout_aclk_cam0_333_user_p) = { "oscclk", "aclk_cam0_333", }; +PNAME(mout_aclk_cam0_400_user_p) = { "oscclk", "aclk_cam0_400", }; +PNAME(mout_aclk_cam0_552_user_p) = { "oscclk", "aclk_cam0_552", }; + +PNAME(mout_phyclk_rxbyteclkhs0_s4_user_p) = { "oscclk", + "phyclk_rxbyteclkhs0_s4_phy", }; +PNAME(mout_phyclk_rxbyteclkhs0_s2a_user_p) = { "oscclk", + "phyclk_rxbyteclkhs0_s2a_phy", }; + +PNAME(mout_aclk_lite_d_b_p) = { "mout_aclk_lite_d_a", + "mout_aclk_cam0_333_user", }; +PNAME(mout_aclk_lite_d_a_p) = { "mout_aclk_cam0_552_user", + "mout_aclk_cam0_400_user", }; +PNAME(mout_aclk_lite_b_b_p) = { "mout_aclk_lite_b_a", + "mout_aclk_cam0_333_user", }; +PNAME(mout_aclk_lite_b_a_p) = { "mout_aclk_cam0_552_user", + "mout_aclk_cam0_400_user", }; +PNAME(mout_aclk_lite_a_b_p) = { "mout_aclk_lite_a_a", + "mout_aclk_cam0_333_user", }; +PNAME(mout_aclk_lite_a_a_p) = { "mout_aclk_cam0_552_user", + "mout_aclk_cam0_400_user", }; +PNAME(mout_aclk_cam0_400_p) = { "mout_aclk_cam0_400_user", + "mout_aclk_cam0_333_user", }; + +PNAME(mout_aclk_csis1_b_p) = { "mout_aclk_csis1_a", + "mout_aclk_cam0_333_user" }; +PNAME(mout_aclk_csis1_a_p) = { "mout_aclk_cam0_552_user", + "mout_aclk_cam0_400_user", }; +PNAME(mout_aclk_csis0_b_p) = { "mout_aclk_csis0_a", + "mout_aclk_cam0_333_user", }; +PNAME(mout_aclk_csis0_a_p) = { "mout_aclk_cam0_552_user", + "mout_aclk-cam0_400_user", }; +PNAME(mout_aclk_3aa1_b_p) = { "mout_aclk_3aa1_a", + "mout_aclk_cam0_333_user", }; +PNAME(mout_aclk_3aa1_a_p) = { "mout_aclk_cam0_552_user", + "mout_aclk_cam0_400_user", }; +PNAME(mout_aclk_3aa0_b_p) = { "mout_aclk_3aa0_a", + "mout_aclk_cam0_333_user", }; +PNAME(mout_aclk_3aa0_a_p) = { "mout_aclk_cam0_552_user", + "mout_aclk_cam0_400_user", }; + +PNAME(mout_sclk_lite_freecnt_c_p) = { "mout_sclk_lite_freecnt_b", + "div_pclk_lite_d", }; +PNAME(mout_sclk_lite_freecnt_b_p) = { "mout_sclk_lite_freecnt_a", + "div_pclk_pixelasync_lite_c", }; +PNAME(mout_sclk_lite_freecnt_a_p) = { "div_pclk_lite_a", + "div_pclk_lite_b", }; +PNAME(mout_sclk_pixelasync_lite_c_b_p) = { "mout_sclk_pixelasync_lite_c_a", + "mout_aclk_cam0_333_user", }; +PNAME(mout_sclk_pixelasync_lite_c_a_p) = { "mout_aclk_cam0_552_user", + "mout_aclk_cam0_400_user", }; +PNAME(mout_sclk_pixelasync_lite_c_init_b_p) = { + "mout_sclk_pixelasync_lite_c_init_a", + "mout_aclk_cam0_400_user", }; +PNAME(mout_sclk_pixelasync_lite_c_init_a_p) = { + "mout_aclk_cam0_552_user", + "mout_aclk_cam0_400_user", }; + +static struct samsung_fixed_rate_clock cam0_fixed_clks[] __initdata = { + FRATE(CLK_PHYCLK_RXBYTEECLKHS0_S4_PHY, "phyclk_rxbyteclkhs0_s4_phy", + NULL, CLK_IS_ROOT, 100000000), + FRATE(CLK_PHYCLK_RXBYTEECLKHS0_S2A_PHY, "phyclk_rxbyteclkhs0_s2a_phy", + NULL, CLK_IS_ROOT, 100000000), +}; + +static struct samsung_mux_clock cam0_mux_clks[] __initdata = { + /* MUX_SEL_CAM00 */ + MUX(CLK_MOUT_ACLK_CAM0_333_USER, "mout_aclk_cam0_333_user", + mout_aclk_cam0_333_user_p, MUX_SEL_CAM00, 8, 1), + MUX(CLK_MOUT_ACLK_CAM0_400_USER, "mout_aclk_cam0_400_user", + mout_aclk_cam0_400_user_p, MUX_SEL_CAM00, 4, 1), + MUX(CLK_MOUT_ACLK_CAM0_552_USER, "mout_aclk_cam0_552_user", + mout_aclk_cam0_552_user_p, MUX_SEL_CAM00, 0, 1), + + /* MUX_SEL_CAM01 */ + MUX(CLK_MOUT_PHYCLK_RXBYTECLKHS0_S4_USER, + "mout_phyclk_rxbyteclkhs0_s4_user", + mout_phyclk_rxbyteclkhs0_s4_user_p, + MUX_SEL_CAM01, 4, 1), + MUX(CLK_MOUT_PHYCLK_RXBYTECLKHS0_S2A_USER, + "mout_phyclk_rxbyteclkhs0_s2a_user", + mout_phyclk_rxbyteclkhs0_s2a_user_p, + MUX_SEL_CAM01, 0, 1), + + /* MUX_SEL_CAM02 */ + MUX(CLK_MOUT_ACLK_LITE_D_B, "mout_aclk_lite_d_b", mout_aclk_lite_d_b_p, + MUX_SEL_CAM02, 24, 1), + MUX(CLK_MOUT_ACLK_LITE_D_A, "mout_aclk_lite_d_a", mout_aclk_lite_d_a_p, + MUX_SEL_CAM02, 20, 1), + MUX(CLK_MOUT_ACLK_LITE_B_B, "mout_aclk_lite_b_b", mout_aclk_lite_b_b_p, + MUX_SEL_CAM02, 16, 1), + MUX(CLK_MOUT_ACLK_LITE_B_A, "mout_aclk_lite_b_a", mout_aclk_lite_b_a_p, + MUX_SEL_CAM02, 12, 1), + MUX(CLK_MOUT_ACLK_LITE_A_B, "mout_aclk_lite_a_b", mout_aclk_lite_a_b_p, + MUX_SEL_CAM02, 8, 1), + MUX(CLK_MOUT_ACLK_LITE_A_A, "mout_aclk_lite_a_a", mout_aclk_lite_a_a_p, + MUX_SEL_CAM02, 4, 1), + MUX(CLK_MOUT_ACLK_CAM0_400, "mout_aclk_cam0_400", mout_aclk_cam0_400_p, + MUX_SEL_CAM02, 0, 1), + + /* MUX_SEL_CAM03 */ + MUX(CLK_MOUT_ACLK_CSIS1_B, "mout_aclk_csis1_b", mout_aclk_csis1_b_p, + MUX_SEL_CAM03, 28, 1), + MUX(CLK_MOUT_ACLK_CSIS1_A, "mout_aclk_csis1_a", mout_aclk_csis1_a_p, + MUX_SEL_CAM03, 24, 1), + MUX(CLK_MOUT_ACLK_CSIS0_B, "mout_aclk_csis0_b", mout_aclk_csis0_b_p, + MUX_SEL_CAM03, 20, 1), + MUX(CLK_MOUT_ACLK_CSIS0_A, "mout_aclk_csis0_a", mout_aclk_csis0_a_p, + MUX_SEL_CAM03, 16, 1), + MUX(CLK_MOUT_ACLK_3AA1_B, "mout_aclk_3aa1_b", mout_aclk_3aa1_b_p, + MUX_SEL_CAM03, 12, 1), + MUX(CLK_MOUT_ACLK_3AA1_A, "mout_aclk_3aa1_a", mout_aclk_3aa1_a_p, + MUX_SEL_CAM03, 8, 1), + MUX(CLK_MOUT_ACLK_3AA0_B, "mout_aclk_3aa0_b", mout_aclk_3aa0_b_p, + MUX_SEL_CAM03, 4, 1), + MUX(CLK_MOUT_ACLK_3AA0_A, "mout_aclk_3aa0_a", mout_aclk_3aa0_a_p, + MUX_SEL_CAM03, 0, 1), + + /* MUX_SEL_CAM04 */ + MUX(CLK_MOUT_SCLK_LITE_FREECNT_C, "mout_sclk_lite_freecnt_c", + mout_sclk_lite_freecnt_c_p, MUX_SEL_CAM04, 24, 1), + MUX(CLK_MOUT_SCLK_LITE_FREECNT_B, "mout_sclk_lite_freecnt_b", + mout_sclk_lite_freecnt_b_p, MUX_SEL_CAM04, 24, 1), + MUX(CLK_MOUT_SCLK_LITE_FREECNT_A, "mout_sclk_lite_freecnt_a", + mout_sclk_lite_freecnt_a_p, MUX_SEL_CAM04, 24, 1), + MUX(CLK_MOUT_SCLK_PIXELASYNC_LITE_C_B, "mout_sclk_pixelasync_lite_c_b", + mout_sclk_pixelasync_lite_c_b_p, MUX_SEL_CAM04, 24, 1), + MUX(CLK_MOUT_SCLK_PIXELASYNC_LITE_C_A, "mout_sclk_pixelasync_lite_c_a", + mout_sclk_pixelasync_lite_c_a_p, MUX_SEL_CAM04, 24, 1), + MUX(CLK_MOUT_SCLK_PIXELASYNC_LITE_C_INIT_B, + "mout_sclk_pixelasync_lite_c_init_b", + mout_sclk_pixelasync_lite_c_init_b_p, + MUX_SEL_CAM04, 24, 1), + MUX(CLK_MOUT_SCLK_PIXELASYNC_LITE_C_INIT_A, + "mout_sclk_pixelasync_lite_c_init_a", + mout_sclk_pixelasync_lite_c_init_a_p, + MUX_SEL_CAM04, 24, 1), +}; + +static struct samsung_div_clock cam0_div_clks[] __initdata = { + /* DIV_CAM00 */ + DIV(CLK_DIV_PCLK_CAM0_50, "div_pclk_cam0_50", "div_aclk_cam0_200", + DIV_CAM00, 8, 2), + DIV(CLK_DIV_ACLK_CAM0_200, "div_aclk_cam0_200", "mout_aclk_cam0_400", + DIV_CAM00, 4, 3), + DIV(CLK_DIV_ACLK_CAM0_BUS_400, "div_aclk_cam0_bus_400", + "mout_aclk_cam0_400", DIV_CAM00, 0, 3), + + /* DIV_CAM01 */ + DIV(CLK_DIV_PCLK_LITE_D, "div_pclk_lite_d", "div_aclk_lite_d", + DIV_CAM01, 20, 2), + DIV(CLK_DIV_ACLK_LITE_D, "div_aclk_lite_d", "mout_aclk_lite_d_b", + DIV_CAM01, 16, 3), + DIV(CLK_DIV_PCLK_LITE_B, "div_pclk_lite_b", "div_aclk_lite_b", + DIV_CAM01, 12, 2), + DIV(CLK_DIV_ACLK_LITE_B, "div_aclk_lite_b", "mout_aclk_lite_b_b", + DIV_CAM01, 8, 3), + DIV(CLK_DIV_PCLK_LITE_A, "div_pclk_lite_a", "div_aclk_lite_a", + DIV_CAM01, 4, 2), + DIV(CLK_DIV_ACLK_LITE_A, "div_aclk_lite_a", "mout_aclk_lite_a_b", + DIV_CAM01, 0, 3), + + /* DIV_CAM02 */ + DIV(CLK_DIV_ACLK_CSIS1, "div_aclk_csis1", "mout_aclk_csis1_b", + DIV_CAM02, 20, 3), + DIV(CLK_DIV_ACLK_CSIS0, "div_aclk_csis0", "mout_aclk_csis0_b", + DIV_CAM02, 16, 3), + DIV(CLK_DIV_PCLK_3AA1, "div_pclk_3aa1", "div_aclk_3aa1", + DIV_CAM02, 12, 2), + DIV(CLK_DIV_ACLK_3AA1, "div_aclk_3aa1", "mout_aclk_3aa1_b", + DIV_CAM02, 8, 3), + DIV(CLK_DIV_PCLK_3AA0, "div_pclk_3aa0", "div_aclk_3aa0", + DIV_CAM02, 4, 2), + DIV(CLK_DIV_ACLK_3AA0, "div_aclk_3aa0", "mout_aclk_3aa0_b", + DIV_CAM02, 0, 3), + + /* DIV_CAM03 */ + DIV(CLK_DIV_SCLK_PIXELASYNC_LITE_C, "div_sclk_pixelasync_lite_c", + "mout_sclk_pixelasync_lite_c_b", DIV_CAM03, 8, 3), + DIV(CLK_DIV_PCLK_PIXELASYNC_LITE_C, "div_pclk_pixelasync_lite_c", + "div_sclk_pixelasync_lite_c_init", DIV_CAM03, 4, 2), + DIV(CLK_DIV_SCLK_PIXELASYNC_LITE_C_INIT, + "div_sclk_pixelasync_lite_c_init", + "mout_sclk_pixelasync_lite_c_init_b", DIV_CAM03, 0, 3), +}; + +static struct samsung_gate_clock cam0_gate_clks[] __initdata = { + /* ENABLE_ACLK_CAM00 */ + GATE(CLK_ACLK_CSIS1, "aclk_csis1", "div_aclk_csis1", ENABLE_ACLK_CAM00, + 6, 0, 0), + GATE(CLK_ACLK_CSIS0, "aclk_csis0", "div_aclk_csis0", ENABLE_ACLK_CAM00, + 5, 0, 0), + GATE(CLK_ACLK_3AA1, "aclk_3aa1", "div_aclk_3aa1", ENABLE_ACLK_CAM00, + 4, 0, 0), + GATE(CLK_ACLK_3AA0, "aclk_3aa0", "div_aclk_3aa0", ENABLE_ACLK_CAM00, + 3, 0, 0), + GATE(CLK_ACLK_LITE_D, "aclk_lite_d", "div_aclk_lite_d", + ENABLE_ACLK_CAM00, 2, 0, 0), + GATE(CLK_ACLK_LITE_B, "aclk_lite_b", "div_aclk_lite_b", + ENABLE_ACLK_CAM00, 1, 0, 0), + GATE(CLK_ACLK_LITE_A, "aclk_lite_a", "div_aclk_lite_a", + ENABLE_ACLK_CAM00, 0, 0, 0), + + /* ENABLE_ACLK_CAM01 */ + GATE(CLK_ACLK_AHBSYNCDN, "aclk_ahbsyncdn", "div_aclk_cam0_200", + ENABLE_ACLK_CAM01, 31, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_AXIUS_LITE_D, "aclk_axius_lite_d", "div_aclk_cam0_bus_400", + ENABLE_ACLK_CAM01, 30, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_AXIUS_LITE_B, "aclk_axius_lite_b", "div_aclk_cam0_bus_400", + ENABLE_ACLK_CAM01, 29, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_AXIUS_LITE_A, "aclk_axius_lite_a", "div_aclk_cam0_bus_400", + ENABLE_ACLK_CAM01, 28, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAPBM_3AA1, "aclk_asyncapbm_3aa1", "div_pclk_3aa1", + ENABLE_ACLK_CAM01, 27, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAPBS_3AA1, "aclk_asyncapbs_3aa1", "div_aclk_3aa1", + ENABLE_ACLK_CAM01, 26, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAPBM_3AA0, "aclk_asyncapbm_3aa0", "div_pclk_3aa0", + ENABLE_ACLK_CAM01, 25, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAPBS_3AA0, "aclk_asyncapbs_3aa0", "div_aclk_3aa0", + ENABLE_ACLK_CAM01, 24, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAPBM_LITE_D, "aclk_asyncapbm_lite_d", + "div_pclk_lite_d", ENABLE_ACLK_CAM01, + 23, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAPBS_LITE_D, "aclk_asyncapbs_lite_d", + "div_aclk_cam0_200", ENABLE_ACLK_CAM01, + 22, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAPBM_LITE_B, "aclk_asyncapbm_lite_b", + "div_pclk_lite_b", ENABLE_ACLK_CAM01, + 21, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAPBS_LITE_B, "aclk_asyncapbs_lite_b", + "div_aclk_cam0_200", ENABLE_ACLK_CAM01, + 20, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAPBM_LITE_A, "aclk_asyncapbm_lite_a", + "div_pclk_lite_a", ENABLE_ACLK_CAM01, + 19, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAPBS_LITE_A, "aclk_asyncapbs_lite_a", + "div_aclk_cam0_200", ENABLE_ACLK_CAM01, + 18, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAXIM_ISP0P, "aclk_asyncaxim_isp0p", + "div_aclk_cam0_200", ENABLE_ACLK_CAM01, + 17, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAXIM_3AA1, "aclk_asyncaxim_3aa1", + "div_aclk_cam0_bus_400", ENABLE_ACLK_CAM01, + 16, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAXIS_3AA1, "aclk_asyncaxis_3aa1", + "div_aclk_3aa1", ENABLE_ACLK_CAM01, + 15, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAXIM_3AA0, "aclk_asyncaxim_3aa0", + "div_aclk_cam0_bus_400", ENABLE_ACLK_CAM01, + 14, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAXIS_3AA0, "aclk_asyncaxis_3aa0", + "div_aclk_3aa0", ENABLE_ACLK_CAM01, + 13, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAXIM_LITE_D, "aclk_asyncaxim_lite_d", + "div_aclk_cam0_bus_400", ENABLE_ACLK_CAM01, + 12, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAXIS_LITE_D, "aclk_asyncaxis_lite_d", + "div_aclk_lite_d", ENABLE_ACLK_CAM01, + 11, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAXIM_LITE_B, "aclk_asyncaxim_lite_b", + "div_aclk_cam0_bus_400", ENABLE_ACLK_CAM01, + 10, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAXIS_LITE_B, "aclk_asyncaxis_lite_b", + "div_aclk_lite_b", ENABLE_ACLK_CAM01, + 9, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAXIM_LITE_A, "aclk_asyncaxim_lite_a", + "div_aclk_cam0_bus_400", ENABLE_ACLK_CAM01, + 8, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAXIS_LITE_A, "aclk_asyncaxis_lite_a", + "div_aclk_lite_a", ENABLE_ACLK_CAM01, + 7, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_AHB2APB_ISPSFRP, "aclk_ahb2apb_ispsfrp", + "div_pclk_cam0_50", ENABLE_ACLK_CAM01, + 6, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_AXI2APB_ISP0P, "aclk_axi2apb_isp0p", "div_aclk_cam0_200", + ENABLE_ACLK_CAM01, 5, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_AXI2AHB_ISP0P, "aclk_axi2ahb_isp0p", "div_aclk_cam0_200", + ENABLE_ACLK_CAM01, 4, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_XIU_IS0X, "aclk_xiu_is0x", "div_aclk_cam0_200", + ENABLE_ACLK_CAM01, 3, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_XIU_ISP0EX, "aclk_xiu_isp0ex", "div_aclk_cam0_bus_400", + ENABLE_ACLK_CAM01, 2, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_CAM0NP_276, "aclk_cam0np_276", "div_aclk_cam0_200", + ENABLE_ACLK_CAM01, 1, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_CAM0ND_400, "aclk_cam0nd_400", "div_aclk_cam0_bus_400", + ENABLE_ACLK_CAM01, 0, CLK_IGNORE_UNUSED, 0), + + /* ENABLE_ACLK_CAM02 */ + GATE(CLK_ACLK_SMMU_3AA1, "aclk_smmu_3aa1", "div_aclk_cam0_bus_400", + ENABLE_ACLK_CAM02, 9, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_SMMU_3AA0, "aclk_smmu_3aa0", "div_aclk_cam0_bus_400", + ENABLE_ACLK_CAM02, 8, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_SMMU_LITE_D, "aclk_smmu_lite_d", "div_aclk_cam0_bus_400", + ENABLE_ACLK_CAM02, 7, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_SMMU_LITE_B, "aclk_smmu_lite_b", "div_aclk_cam0_bus_400", + ENABLE_ACLK_CAM02, 6, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_SMMU_LITE_A, "aclk_smmu_lite_a", "div_aclk_cam0_bus_400", + ENABLE_ACLK_CAM02, 5, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_BTS_3AA1, "aclk_bts_3aa1", "div_aclk_cam0_bus_400", + ENABLE_ACLK_CAM02, 4, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_BTS_3AA0, "aclk_bts_3aa0", "div_aclk_cam0_bus_400", + ENABLE_ACLK_CAM02, 3, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_BTS_LITE_D, "aclk_bts_lite_d", "div_aclk_cam0_bus_400", + ENABLE_ACLK_CAM02, 2, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_BTS_LITE_B, "aclk_bts_lite_b", "div_aclk_cam0_bus_400", + ENABLE_ACLK_CAM02, 1, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_BTS_LITE_A, "aclk_bts_lite_a", "div_aclk_cam0_bus_400", + ENABLE_ACLK_CAM02, 0, CLK_IGNORE_UNUSED, 0), + + /* ENABLE_PCLK_CAM0 */ + GATE(CLK_PCLK_SMMU_3AA1, "pclk_smmu_3aa1", "div_aclk_cam0_200", + ENABLE_PCLK_CAM0, 25, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_SMMU_3AA0, "pclk_smmu_3aa0", "div_aclk_cam0_200", + ENABLE_PCLK_CAM0, 24, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_SMMU_LITE_D, "pclk_smmu_lite_d", "div_aclk_cam0_200", + ENABLE_PCLK_CAM0, 23, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_SMMU_LITE_B, "pclk_smmu_lite_b", "div_aclk_cam0_200", + ENABLE_PCLK_CAM0, 22, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_SMMU_LITE_A, "pclk_smmu_lite_a", "div_aclk_cam0_200", + ENABLE_PCLK_CAM0, 21, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_BTS_3AA1, "pclk_bts_3aa1", "div_pclk_cam0_50", + ENABLE_PCLK_CAM0, 20, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_BTS_3AA0, "pclk_bts_3aa0", "div_pclk_cam0_50", + ENABLE_PCLK_CAM0, 19, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_BTS_LITE_D, "pclk_bts_lite_d", "div_pclk_cam0_50", + ENABLE_PCLK_CAM0, 18, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_BTS_LITE_B, "pclk_bts_lite_b", "div_pclk_cam0_50", + ENABLE_PCLK_CAM0, 17, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_BTS_LITE_A, "pclk_bts_lite_a", "div_pclk_cam0_50", + ENABLE_PCLK_CAM0, 16, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_ASYNCAXI_CAM1, "pclk_asyncaxi_cam1", "div_pclk_cam0_50", + ENABLE_PCLK_CAM0, 15, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_ASYNCAXI_3AA1, "pclk_asyncaxi_3aa1", "div_pclk_cam0_50", + ENABLE_PCLK_CAM0, 14, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_ASYNCAXI_3AA0, "pclk_asyncaxi_3aa0", "div_pclk_cam0_50", + ENABLE_PCLK_CAM0, 13, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_ASYNCAXI_LITE_D, "pclk_asyncaxi_lite_d", + "div_pclk_cam0_50", ENABLE_PCLK_CAM0, + 12, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_ASYNCAXI_LITE_B, "pclk_asyncaxi_lite_b", + "div_pclk_cam0_50", ENABLE_PCLK_CAM0, + 11, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_ASYNCAXI_LITE_A, "pclk_asyncaxi_lite_a", + "div_pclk_cam0_50", ENABLE_PCLK_CAM0, + 10, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_PMU_CAM0, "pclk_pmu_cam0", "div_pclk_cam0_50", + ENABLE_PCLK_CAM0, 9, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_SYSREG_CAM0, "pclk_sysreg_cam0", "div_pclk_cam0_50", + ENABLE_PCLK_CAM0, 8, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_CMU_CAM0_LOCAL, "pclk_cmu_cam0_local", + "div_aclk_cam0_200", ENABLE_PCLK_CAM0, + 7, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_CSIS1, "pclk_csis1", "div_aclk_cam0_200", + ENABLE_PCLK_CAM0, 6, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_CSIS0, "pclk_csis0", "div_aclk_cam0_200", + ENABLE_PCLK_CAM0, 5, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_3AA1, "pclk_3aa1", "div_pclk_3aa1", + ENABLE_PCLK_CAM0, 4, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_3AA0, "pclk_3aa0", "div_pclk_3aa0", + ENABLE_PCLK_CAM0, 3, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_LITE_D, "pclk_lite_d", "div_pclk_lite_d", + ENABLE_PCLK_CAM0, 2, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_LITE_B, "pclk_lite_b", "div_pclk_lite_b", + ENABLE_PCLK_CAM0, 1, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_LITE_A, "pclk_lite_a", "div_pclk_lite_a", + ENABLE_PCLK_CAM0, 0, CLK_IGNORE_UNUSED, 0), + + /* ENABLE_SCLK_CAM0 */ + GATE(CLK_PHYCLK_RXBYTECLKHS0_S4, "phyclk_rxbyteclkhs0_s4", + "mout_phyclk_rxbyteclkhs0_s4_user", + ENABLE_SCLK_CAM0, 8, 0, 0), + GATE(CLK_PHYCLK_RXBYTECLKHS0_S2A, "phyclk_rxbyteclkhs0_s2a", + "mout_phyclk_rxbyteclkhs0_s2a_user", + ENABLE_SCLK_CAM0, 7, 0, 0), + GATE(CLK_SCLK_LITE_FREECNT, "sclk_lite_freecnt", + "mout_sclk_lite_freecnt_c", ENABLE_SCLK_CAM0, 6, 0, 0), + GATE(CLK_SCLK_PIXELASYNCM_3AA1, "sclk_pixelasycm_3aa1", + "div_aclk_3aa1", ENABLE_SCLK_CAM0, 5, 0, 0), + GATE(CLK_SCLK_PIXELASYNCM_3AA0, "sclk_pixelasycm_3aa0", + "div_aclk_3aa0", ENABLE_SCLK_CAM0, 4, 0, 0), + GATE(CLK_SCLK_PIXELASYNCS_3AA0, "sclk_pixelasycs_3aa0", + "div_aclk_3aa0", ENABLE_SCLK_CAM0, 3, 0, 0), + GATE(CLK_SCLK_PIXELASYNCM_LITE_C, "sclk_pixelasyncm_lite_c", + "div_sclk_pixelasync_lite_c", + ENABLE_SCLK_CAM0, 2, 0, 0), + GATE(CLK_SCLK_PIXELASYNCM_LITE_C_INIT, "sclk_pixelasyncm_lite_c_init", + "div_sclk_pixelasync_lite_c_init", + ENABLE_SCLK_CAM0, 1, 0, 0), + GATE(CLK_SCLK_PIXELASYNCS_LITE_C_INIT, "sclk_pixelasyncs_lite_c_init", + "div_sclk_pixelasync_lite_c", + ENABLE_SCLK_CAM0, 0, 0, 0), +}; + +static struct samsung_cmu_info cam0_cmu_info __initdata = { + .mux_clks = cam0_mux_clks, + .nr_mux_clks = ARRAY_SIZE(cam0_mux_clks), + .div_clks = cam0_div_clks, + .nr_div_clks = ARRAY_SIZE(cam0_div_clks), + .gate_clks = cam0_gate_clks, + .nr_gate_clks = ARRAY_SIZE(cam0_gate_clks), + .fixed_clks = cam0_fixed_clks, + .nr_fixed_clks = ARRAY_SIZE(cam0_fixed_clks), + .nr_clk_ids = CAM0_NR_CLK, + .clk_regs = cam0_clk_regs, + .nr_clk_regs = ARRAY_SIZE(cam0_clk_regs), +}; + +static void __init exynos5433_cmu_cam0_init(struct device_node *np) +{ + samsung_cmu_register_one(np, &cam0_cmu_info); +} +CLK_OF_DECLARE(exynos5433_cmu_cam0, "samsung,exynos5433-cmu-cam0", + exynos5433_cmu_cam0_init); diff --git a/include/dt-bindings/clock/exynos5433.h b/include/dt-bindings/clock/exynos5433.h index fbc81e3424a6..f99cde7a278d 100644 --- a/include/dt-bindings/clock/exynos5433.h +++ b/include/dt-bindings/clock/exynos5433.h @@ -118,6 +118,9 @@ #define CLK_DIV_ACLK_MSCL_400 145 #define CLK_DIV_ACLK_ISP_DIS_400 146 #define CLK_DIV_ACLK_ISP_400 147 +#define CLK_DIV_ACLK_CAM0_333 148 +#define CLK_DIV_ACLK_CAM0_400 149 +#define CLK_DIV_ACLK_CAM0_552 150 #define CLK_ACLK_PERIC_66 200 #define CLK_ACLK_PERIS_66 201 @@ -159,8 +162,11 @@ #define CLK_ACLK_HEVC_400 237 #define CLK_ACLK_ISP_DIS_400 238 #define CLK_ACLK_ISP_400 239 +#define CLK_ACLK_CAM0_333 240 +#define CLK_ACLK_CAM0_400 241 +#define CLK_ACLK_CAM0_552 242 -#define TOP_NR_CLK 240 +#define TOP_NR_CLK 243 /* CMU_CPIF */ #define CLK_FOUT_MPHY_PLL 1 @@ -1113,4 +1119,142 @@ #define ISP_NR_CLK 78 +/* CMU_CAM0 */ +#define CLK_PHYCLK_RXBYTEECLKHS0_S4_PHY 1 +#define CLK_PHYCLK_RXBYTEECLKHS0_S2A_PHY 2 + +#define CLK_MOUT_ACLK_CAM0_333_USER 3 +#define CLK_MOUT_ACLK_CAM0_400_USER 4 +#define CLK_MOUT_ACLK_CAM0_552_USER 5 +#define CLK_MOUT_PHYCLK_RXBYTECLKHS0_S4_USER 6 +#define CLK_MOUT_PHYCLK_RXBYTECLKHS0_S2A_USER 7 +#define CLK_MOUT_ACLK_LITE_D_B 8 +#define CLK_MOUT_ACLK_LITE_D_A 9 +#define CLK_MOUT_ACLK_LITE_B_B 10 +#define CLK_MOUT_ACLK_LITE_B_A 11 +#define CLK_MOUT_ACLK_LITE_A_B 12 +#define CLK_MOUT_ACLK_LITE_A_A 13 +#define CLK_MOUT_ACLK_CAM0_400 14 +#define CLK_MOUT_ACLK_CSIS1_B 15 +#define CLK_MOUT_ACLK_CSIS1_A 16 +#define CLK_MOUT_ACLK_CSIS0_B 17 +#define CLK_MOUT_ACLK_CSIS0_A 18 +#define CLK_MOUT_ACLK_3AA1_B 19 +#define CLK_MOUT_ACLK_3AA1_A 20 +#define CLK_MOUT_ACLK_3AA0_B 21 +#define CLK_MOUT_ACLK_3AA0_A 22 +#define CLK_MOUT_SCLK_LITE_FREECNT_C 23 +#define CLK_MOUT_SCLK_LITE_FREECNT_B 24 +#define CLK_MOUT_SCLK_LITE_FREECNT_A 25 +#define CLK_MOUT_SCLK_PIXELASYNC_LITE_C_B 26 +#define CLK_MOUT_SCLK_PIXELASYNC_LITE_C_A 27 +#define CLK_MOUT_SCLK_PIXELASYNC_LITE_C_INIT_B 28 +#define CLK_MOUT_SCLK_PIXELASYNC_LITE_C_INIT_A 29 + +#define CLK_DIV_PCLK_CAM0_50 30 +#define CLK_DIV_ACLK_CAM0_200 31 +#define CLK_DIV_ACLK_CAM0_BUS_400 32 +#define CLK_DIV_PCLK_LITE_D 33 +#define CLK_DIV_ACLK_LITE_D 34 +#define CLK_DIV_PCLK_LITE_B 35 +#define CLK_DIV_ACLK_LITE_B 36 +#define CLK_DIV_PCLK_LITE_A 37 +#define CLK_DIV_ACLK_LITE_A 38 +#define CLK_DIV_ACLK_CSIS1 39 +#define CLK_DIV_ACLK_CSIS0 40 +#define CLK_DIV_PCLK_3AA1 41 +#define CLK_DIV_ACLK_3AA1 42 +#define CLK_DIV_PCLK_3AA0 43 +#define CLK_DIV_ACLK_3AA0 44 +#define CLK_DIV_SCLK_PIXELASYNC_LITE_C 45 +#define CLK_DIV_PCLK_PIXELASYNC_LITE_C 46 +#define CLK_DIV_SCLK_PIXELASYNC_LITE_C_INIT 47 + +#define CLK_ACLK_CSIS1 50 +#define CLK_ACLK_CSIS0 51 +#define CLK_ACLK_3AA1 52 +#define CLK_ACLK_3AA0 53 +#define CLK_ACLK_LITE_D 54 +#define CLK_ACLK_LITE_B 55 +#define CLK_ACLK_LITE_A 56 +#define CLK_ACLK_AHBSYNCDN 57 +#define CLK_ACLK_AXIUS_LITE_D 58 +#define CLK_ACLK_AXIUS_LITE_B 59 +#define CLK_ACLK_AXIUS_LITE_A 60 +#define CLK_ACLK_ASYNCAPBM_3AA1 61 +#define CLK_ACLK_ASYNCAPBS_3AA1 62 +#define CLK_ACLK_ASYNCAPBM_3AA0 63 +#define CLK_ACLK_ASYNCAPBS_3AA0 64 +#define CLK_ACLK_ASYNCAPBM_LITE_D 65 +#define CLK_ACLK_ASYNCAPBS_LITE_D 66 +#define CLK_ACLK_ASYNCAPBM_LITE_B 67 +#define CLK_ACLK_ASYNCAPBS_LITE_B 68 +#define CLK_ACLK_ASYNCAPBM_LITE_A 69 +#define CLK_ACLK_ASYNCAPBS_LITE_A 70 +#define CLK_ACLK_ASYNCAXIM_ISP0P 71 +#define CLK_ACLK_ASYNCAXIM_3AA1 72 +#define CLK_ACLK_ASYNCAXIS_3AA1 73 +#define CLK_ACLK_ASYNCAXIM_3AA0 74 +#define CLK_ACLK_ASYNCAXIS_3AA0 75 +#define CLK_ACLK_ASYNCAXIM_LITE_D 76 +#define CLK_ACLK_ASYNCAXIS_LITE_D 77 +#define CLK_ACLK_ASYNCAXIM_LITE_B 78 +#define CLK_ACLK_ASYNCAXIS_LITE_B 79 +#define CLK_ACLK_ASYNCAXIM_LITE_A 80 +#define CLK_ACLK_ASYNCAXIS_LITE_A 81 +#define CLK_ACLK_AHB2APB_ISPSFRP 82 +#define CLK_ACLK_AXI2APB_ISP0P 83 +#define CLK_ACLK_AXI2AHB_ISP0P 84 +#define CLK_ACLK_XIU_IS0X 85 +#define CLK_ACLK_XIU_ISP0EX 86 +#define CLK_ACLK_CAM0NP_276 87 +#define CLK_ACLK_CAM0ND_400 88 +#define CLK_ACLK_SMMU_3AA1 89 +#define CLK_ACLK_SMMU_3AA0 90 +#define CLK_ACLK_SMMU_LITE_D 91 +#define CLK_ACLK_SMMU_LITE_B 92 +#define CLK_ACLK_SMMU_LITE_A 93 +#define CLK_ACLK_BTS_3AA1 94 +#define CLK_ACLK_BTS_3AA0 95 +#define CLK_ACLK_BTS_LITE_D 96 +#define CLK_ACLK_BTS_LITE_B 97 +#define CLK_ACLK_BTS_LITE_A 98 +#define CLK_PCLK_SMMU_3AA1 99 +#define CLK_PCLK_SMMU_3AA0 100 +#define CLK_PCLK_SMMU_LITE_D 101 +#define CLK_PCLK_SMMU_LITE_B 102 +#define CLK_PCLK_SMMU_LITE_A 103 +#define CLK_PCLK_BTS_3AA1 104 +#define CLK_PCLK_BTS_3AA0 105 +#define CLK_PCLK_BTS_LITE_D 106 +#define CLK_PCLK_BTS_LITE_B 107 +#define CLK_PCLK_BTS_LITE_A 108 +#define CLK_PCLK_ASYNCAXI_CAM1 109 +#define CLK_PCLK_ASYNCAXI_3AA1 110 +#define CLK_PCLK_ASYNCAXI_3AA0 111 +#define CLK_PCLK_ASYNCAXI_LITE_D 112 +#define CLK_PCLK_ASYNCAXI_LITE_B 113 +#define CLK_PCLK_ASYNCAXI_LITE_A 114 +#define CLK_PCLK_PMU_CAM0 115 +#define CLK_PCLK_SYSREG_CAM0 116 +#define CLK_PCLK_CMU_CAM0_LOCAL 117 +#define CLK_PCLK_CSIS1 118 +#define CLK_PCLK_CSIS0 119 +#define CLK_PCLK_3AA1 120 +#define CLK_PCLK_3AA0 121 +#define CLK_PCLK_LITE_D 122 +#define CLK_PCLK_LITE_B 123 +#define CLK_PCLK_LITE_A 124 +#define CLK_PHYCLK_RXBYTECLKHS0_S4 125 +#define CLK_PHYCLK_RXBYTECLKHS0_S2A 126 +#define CLK_SCLK_LITE_FREECNT 127 +#define CLK_SCLK_PIXELASYNCM_3AA1 128 +#define CLK_SCLK_PIXELASYNCM_3AA0 129 +#define CLK_SCLK_PIXELASYNCS_3AA0 130 +#define CLK_SCLK_PIXELASYNCM_LITE_C 131 +#define CLK_SCLK_PIXELASYNCM_LITE_C_INIT 132 +#define CLK_SCLK_PIXELASYNCS_LITE_C_INIT 133 + +#define CAM0_NR_CLK 134 + #endif /* _DT_BINDINGS_CLOCK_EXYNOS5433_H */ -- GitLab From a5958a939bbf93e6b77cb3626c6aebde237ad759 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Tue, 3 Feb 2015 09:13:56 +0900 Subject: [PATCH 00054/11651] clk: samsung: exynos5433: Add clocks for CMU_CAM1 domain This patch adds the mux/divider/gate clocks for CMU_CAM1 domain which generates the clocks for Cortex-A5/MIPI_CSIS2/FIMC-LITE_C/FIMC-FD IPs. Signed-off-by: Chanwoo Choi Acked-by: Inki Dae Signed-off-by: Sylwester Nawrocki --- .../bindings/clock/exynos5433-clock.txt | 32 ++ drivers/clk/samsung/clk-exynos5433.c | 435 ++++++++++++++++++ include/dt-bindings/clock/exynos5433.h | 147 +++++- 3 files changed, 612 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/clock/exynos5433-clock.txt b/Documentation/devicetree/bindings/clock/exynos5433-clock.txt index 84002e4b52e5..63379b04e052 100644 --- a/Documentation/devicetree/bindings/clock/exynos5433-clock.txt +++ b/Documentation/devicetree/bindings/clock/exynos5433-clock.txt @@ -48,6 +48,8 @@ Required Properties: - "samsung,exynos5433-cmu-cam0" - clock controller compatible for CMU_CAM0 which generates clocks for MIPI_CSIS{0|1}/FIMC_LITE_{A|B|D}/FIMC_3AA{0|1} IPs. + - "samsung,exynos5433-cmu-cam1" - clock controller compatible for CMU_CAM1 + which generates clocks for Cortex-A5/MIPI_CSIS2/FIMC-LITE_C/FIMC-FD IPs. - reg: physical base address of the controller and length of memory mapped region. @@ -153,6 +155,15 @@ Required Properties: - aclk_cam0_400 - aclk_cam0_552 + Input clocks for cam1 clock controller: + - oscclk + - sclk_isp_uart_cam1 + - sclk_isp_spi1_cam1 + - sclk_isp_spi0_cam1 + - aclk_cam1_333 + - aclk_cam1_400 + - aclk_cam1_552 + Each clock is assigned an identifier and client nodes can use this identifier to specify the clock which they consume. @@ -414,6 +425,27 @@ Example 2: Examples of clock controller nodes are listed below. <&cmu_top CLK_ACLK_CAM0_552>; }; + cmu_cam1: clock-controller@145d0000 { + compatible = "samsung,exynos5433-cmu-cam1"; + reg = <0x145d0000 0x0b08>; + #clock-cells = <1>; + + clock-names = "oscclk", + "sclk_isp_uart_cam1", + "sclk_isp_spi1_cam1", + "sclk_isp_spi0_cam1", + "aclk_cam1_333", + "aclk_cam1_400", + "aclk_cam1_552"; + clocks = <&xxti>, + <&cmu_top CLK_SCLK_ISP_UART_CAM1>, + <&cmu_top CLK_SCLK_ISP_SPI1_CAM1>, + <&cmu_top CLK_SCLK_ISP_SPI0_CAM1>, + <&cmu_top CLK_ACLK_CAM1_333>, + <&cmu_top CLK_ACLK_CAM1_400>, + <&cmu_top CLK_ACLK_CAM1_552>; + }; + Example 3: UART controller node that consumes the clock generated by the clock controller. diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c index ce6487375670..1a005c1f7c4b 100644 --- a/drivers/clk/samsung/clk-exynos5433.c +++ b/drivers/clk/samsung/clk-exynos5433.c @@ -405,6 +405,12 @@ static struct samsung_mux_clock top_mux_clks[] __initdata = { static struct samsung_div_clock top_div_clks[] __initdata = { /* DIV_TOP0 */ + DIV(CLK_DIV_ACLK_CAM1_333, "div_aclk_cam1_333", "mout_aclk_cam1_333", + DIV_TOP0, 28, 3), + DIV(CLK_DIV_ACLK_CAM1_400, "div_aclk_cam1_400", "mout_bus_pll_user", + DIV_TOP0, 24, 3), + DIV(CLK_DIV_ACLK_CAM1_552, "div_aclk_cam1_552", "mout_aclk_cam1_552_b", + DIV_TOP0, 20, 3), DIV(CLK_DIV_ACLK_CAM0_333, "div_aclk_cam0_333", "mout_mfc_pll_user", DIV_TOP0, 16, 3), DIV(CLK_DIV_ACLK_CAM0_400, "div_aclk_cam0_400", "mout_bus_pll_user", @@ -464,6 +470,32 @@ static struct samsung_div_clock top_div_clks[] __initdata = { DIV(CLK_DIV_SCLK_JPEG, "div_sclk_jpeg", "mout_sclk_jpeg_c", DIV_TOP_MSCL, 0, 4), + /* DIV_TOP_CAM10 */ + DIV(CLK_DIV_SCLK_ISP_UART, "div_sclk_isp_uart", "mout_sclk_isp_uart", + DIV_TOP_CAM10, 24, 5), + DIV(CLK_DIV_SCLK_ISP_SPI1_B, "div_sclk_isp_spi1_b", + "div_sclk_isp_spi1_a", DIV_TOP_CAM10, 16, 8), + DIV(CLK_DIV_SCLK_ISP_SPI1_A, "div_sclk_isp_spi1_a", + "mout_sclk_isp_spi1", DIV_TOP_CAM10, 12, 4), + DIV(CLK_DIV_SCLK_ISP_SPI0_B, "div_sclk_isp_spi0_b", + "div_sclk_isp_spi0_a", DIV_TOP_CAM10, 4, 8), + DIV(CLK_DIV_SCLK_ISP_SPI0_A, "div_sclk_isp_spi0_a", + "mout_sclk_isp_spi0", DIV_TOP_CAM10, 0, 4), + + /* DIV_TOP_CAM11 */ + DIV(CLK_DIV_SCLK_ISP_SENSOR2_B, "div_sclk_isp_sensor2_b", + "div_sclk_isp_sensor2_a", DIV_TOP_CAM11, 20, 4), + DIV(CLK_DIV_SCLK_ISP_SENSOR2_A, "div_sclk_isp_sensor2_a", + "mout_sclk_isp_sensor2", DIV_TOP_CAM11, 16, 4), + DIV(CLK_DIV_SCLK_ISP_SENSOR1_B, "div_sclk_isp_sensor1_b", + "div_sclk_isp_sensor1_a", DIV_TOP_CAM11, 12, 4), + DIV(CLK_DIV_SCLK_ISP_SENSOR1_A, "div_sclk_isp_sensor1_a", + "mout_sclk_isp_sensor1", DIV_TOP_CAM11, 8, 4), + DIV(CLK_DIV_SCLK_ISP_SENSOR0_B, "div_sclk_isp_sensor0_b", + "div_sclk_isp_sensor0_a", DIV_TOP_CAM11, 12, 4), + DIV(CLK_DIV_SCLK_ISP_SENSOR0_A, "div_sclk_isp_sensor0_a", + "mout_sclk_isp_sensor0", DIV_TOP_CAM11, 8, 4), + /* DIV_TOP_FSYS0 */ DIV(CLK_DIV_SCLK_MMC1_B, "div_sclk_mmc1_b", "div_sclk_mmc1_a", DIV_TOP_FSYS0, 16, 8), @@ -572,6 +604,15 @@ static struct samsung_gate_clock top_gate_clks[] __initdata = { GATE(CLK_ACLK_GSCL_333, "aclk_gscl_333", "div_aclk_gscl_333", ENABLE_ACLK_TOP, 14, CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_CAM1_333, "aclk_cam1_333", "div_aclk_cam1_333", + ENABLE_ACLK_TOP, 13, + CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_CAM1_400, "aclk_cam1_400", "div_aclk_cam1_400", + ENABLE_ACLK_TOP, 12, + CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_CAM1_552, "aclk_cam1_552", "div_aclk_cam1_552", + ENABLE_ACLK_TOP, 11, + CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0), GATE(CLK_ACLK_CAM0_333, "aclk_cam0_333", "div_aclk_cam0_333", ENABLE_ACLK_TOP, 10, CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0), @@ -604,6 +645,22 @@ static struct samsung_gate_clock top_gate_clks[] __initdata = { GATE(CLK_SCLK_JPEG_MSCL, "sclk_jpeg_mscl", "div_sclk_jpeg", ENABLE_SCLK_TOP_MSCL, 0, 0, 0), + /* ENABLE_SCLK_TOP_CAM1 */ + GATE(CLK_SCLK_ISP_SENSOR2, "sclk_isp_sensor2", "div_sclk_isp_sensor2_b", + ENABLE_SCLK_TOP_CAM1, 7, 0, 0), + GATE(CLK_SCLK_ISP_SENSOR1, "sclk_isp_sensor1", "div_sclk_isp_sensor1_b", + ENABLE_SCLK_TOP_CAM1, 6, 0, 0), + GATE(CLK_SCLK_ISP_SENSOR0, "sclk_isp_sensor0", "div_sclk_isp_sensor0_b", + ENABLE_SCLK_TOP_CAM1, 5, 0, 0), + GATE(CLK_SCLK_ISP_MCTADC_CAM1, "sclk_isp_mctadc_cam1", "oscclk", + ENABLE_SCLK_TOP_CAM1, 4, 0, 0), + GATE(CLK_SCLK_ISP_UART_CAM1, "sclk_isp_uart_cam1", "div_sclk_isp_uart", + ENABLE_SCLK_TOP_CAM1, 2, 0, 0), + GATE(CLK_SCLK_ISP_SPI1_CAM1, "sclk_isp_spi1_cam1", "div_sclk_isp_spi1_b", + ENABLE_SCLK_TOP_CAM1, 1, 0, 0), + GATE(CLK_SCLK_ISP_SPI0_CAM1, "sclk_isp_spi0_cam1", "div_sclk_isp_spi0_b", + ENABLE_SCLK_TOP_CAM1, 0, 0, 0), + /* ENABLE_SCLK_TOP_FSYS */ GATE(CLK_SCLK_PCIE_100_FSYS, "sclk_pcie_100_fsys", "div_sclk_pcie_100", ENABLE_SCLK_TOP_FSYS, 7, 0, 0), @@ -4986,3 +5043,381 @@ static void __init exynos5433_cmu_cam0_init(struct device_node *np) } CLK_OF_DECLARE(exynos5433_cmu_cam0, "samsung,exynos5433-cmu-cam0", exynos5433_cmu_cam0_init); + +/* + * Register offset definitions for CMU_CAM1 + */ +#define MUX_SEL_CAM10 0x0200 +#define MUX_SEL_CAM11 0x0204 +#define MUX_SEL_CAM12 0x0208 +#define MUX_ENABLE_CAM10 0x0300 +#define MUX_ENABLE_CAM11 0x0304 +#define MUX_ENABLE_CAM12 0x0308 +#define MUX_STAT_CAM10 0x0400 +#define MUX_STAT_CAM11 0x0404 +#define MUX_STAT_CAM12 0x0408 +#define MUX_IGNORE_CAM11 0x0504 +#define DIV_CAM10 0x0600 +#define DIV_CAM11 0x0604 +#define DIV_STAT_CAM10 0x0700 +#define DIV_STAT_CAM11 0x0704 +#define ENABLE_ACLK_CAM10 0X0800 +#define ENABLE_ACLK_CAM11 0X0804 +#define ENABLE_ACLK_CAM12 0X0808 +#define ENABLE_PCLK_CAM1 0X0900 +#define ENABLE_SCLK_CAM1 0X0a00 +#define ENABLE_IP_CAM10 0X0b00 +#define ENABLE_IP_CAM11 0X0b04 +#define ENABLE_IP_CAM12 0X0b08 + +static unsigned long cam1_clk_regs[] __initdata = { + MUX_SEL_CAM10, + MUX_SEL_CAM11, + MUX_SEL_CAM12, + MUX_ENABLE_CAM10, + MUX_ENABLE_CAM11, + MUX_ENABLE_CAM12, + MUX_STAT_CAM10, + MUX_STAT_CAM11, + MUX_STAT_CAM12, + MUX_IGNORE_CAM11, + DIV_CAM10, + DIV_CAM11, + DIV_STAT_CAM10, + DIV_STAT_CAM11, + ENABLE_ACLK_CAM10, + ENABLE_ACLK_CAM11, + ENABLE_ACLK_CAM12, + ENABLE_PCLK_CAM1, + ENABLE_SCLK_CAM1, + ENABLE_IP_CAM10, + ENABLE_IP_CAM11, + ENABLE_IP_CAM12, +}; + +PNAME(mout_sclk_isp_uart_user_p) = { "oscclk", "sclk_isp_uart_cam1", }; +PNAME(mout_sclk_isp_spi1_user_p) = { "oscclk", "sclk_isp_spi1_cam1", }; +PNAME(mout_sclk_isp_spi0_user_p) = { "oscclk", "sclk_isp_spi0_cam1", }; + +PNAME(mout_aclk_cam1_333_user_p) = { "oscclk", "aclk_cam1_333", }; +PNAME(mout_aclk_cam1_400_user_p) = { "oscclk", "aclk_cam1_400", }; +PNAME(mout_aclk_cam1_552_user_p) = { "oscclk", "aclk_cam1_552", }; + +PNAME(mout_phyclk_rxbyteclkhs0_s2b_user_p) = { "oscclk", + "phyclk_rxbyteclkhs0_s2b_phy", }; + +PNAME(mout_aclk_csis2_b_p) = { "mout_aclk_csis2_a", + "mout_aclk_cam1_333_user", }; +PNAME(mout_aclk_csis2_a_p) = { "mout_aclk_cam1_552_user", + "mout_aclk_cam1_400_user", }; + +PNAME(mout_aclk_fd_b_p) = { "mout_aclk_fd_a", + "mout_aclk_cam1_333_user", }; +PNAME(mout_aclk_fd_a_p) = { "mout_aclk_cam1_552_user", + "mout_aclk_cam1_400_user", }; + +PNAME(mout_aclk_lite_c_b_p) = { "mout_aclk_lite_c_a", + "mout_aclk_cam1_333_user", }; +PNAME(mout_aclk_lite_c_a_p) = { "mout_aclk_cam1_552_user", + "mout_aclk_cam1_400_user", }; + +static struct samsung_fixed_rate_clock cam1_fixed_clks[] __initdata = { + FRATE(CLK_PHYCLK_RXBYTEECLKHS0_S2B, "phyclk_rxbyteclkhs0_s2b_phy", NULL, + CLK_IS_ROOT, 100000000), +}; + +static struct samsung_mux_clock cam1_mux_clks[] __initdata = { + /* MUX_SEL_CAM10 */ + MUX(CLK_MOUT_SCLK_ISP_UART_USER, "mout_sclk_isp_uart_user", + mout_sclk_isp_uart_user_p, MUX_SEL_CAM10, 20, 1), + MUX(CLK_MOUT_SCLK_ISP_SPI1_USER, "mout_sclk_isp_spi1_user", + mout_sclk_isp_spi1_user_p, MUX_SEL_CAM10, 16, 1), + MUX(CLK_MOUT_SCLK_ISP_SPI0_USER, "mout_sclk_isp_spi0_user", + mout_sclk_isp_spi0_user_p, MUX_SEL_CAM10, 12, 1), + MUX(CLK_MOUT_ACLK_CAM1_333_USER, "mout_aclk_cam1_333_user", + mout_aclk_cam1_333_user_p, MUX_SEL_CAM10, 8, 1), + MUX(CLK_MOUT_ACLK_CAM1_400_USER, "mout_aclk_cam1_400_user", + mout_aclk_cam1_400_user_p, MUX_SEL_CAM01, 4, 1), + MUX(CLK_MOUT_ACLK_CAM1_552_USER, "mout_aclk_cam1_552_user", + mout_aclk_cam1_552_user_p, MUX_SEL_CAM01, 0, 1), + + /* MUX_SEL_CAM11 */ + MUX(CLK_MOUT_PHYCLK_RXBYTECLKHS0_S2B_USER, + "mout_phyclk_rxbyteclkhs0_s2b_user", + mout_phyclk_rxbyteclkhs0_s2b_user_p, + MUX_SEL_CAM11, 0, 1), + + /* MUX_SEL_CAM12 */ + MUX(CLK_MOUT_ACLK_CSIS2_B, "mout_aclk_csis2_b", mout_aclk_csis2_b_p, + MUX_SEL_CAM12, 20, 1), + MUX(CLK_MOUT_ACLK_CSIS2_A, "mout_aclk_csis2_a", mout_aclk_csis2_a_p, + MUX_SEL_CAM12, 16, 1), + MUX(CLK_MOUT_ACLK_FD_B, "mout_aclk_fd_b", mout_aclk_fd_b_p, + MUX_SEL_CAM12, 12, 1), + MUX(CLK_MOUT_ACLK_FD_A, "mout_aclk_fd_a", mout_aclk_fd_a_p, + MUX_SEL_CAM12, 8, 1), + MUX(CLK_MOUT_ACLK_LITE_C_B, "mout_aclk_lite_c_b", mout_aclk_lite_c_b_p, + MUX_SEL_CAM12, 4, 1), + MUX(CLK_MOUT_ACLK_LITE_C_A, "mout_aclk_lite_c_a", mout_aclk_lite_c_a_p, + MUX_SEL_CAM12, 0, 1), +}; + +static struct samsung_div_clock cam1_div_clks[] __initdata = { + /* DIV_CAM10 */ + DIV(CLK_DIV_SCLK_ISP_WPWM, "div_sclk_isp_wpwm", + "div_pclk_cam1_83", DIV_CAM10, 16, 2), + DIV(CLK_DIV_PCLK_CAM1_83, "div_pclk_cam1_83", + "mout_aclk_cam1_333_user", DIV_CAM10, 12, 2), + DIV(CLK_DIV_PCLK_CAM1_166, "div_pclk_cam1_166", + "mout_aclk_cam1_333_user", DIV_CAM10, 8, 2), + DIV(CLK_DIV_PCLK_DBG_CAM1, "div_pclk_dbg_cam1", + "mout_aclk_cam1_552_user", DIV_CAM10, 4, 3), + DIV(CLK_DIV_ATCLK_CAM1, "div_atclk_cam1", "mout_aclk_cam1_552_user", + DIV_CAM10, 0, 3), + + /* DIV_CAM11 */ + DIV(CLK_DIV_ACLK_CSIS2, "div_aclk_csis2", "mout_aclk_csis2_b", + DIV_CAM11, 16, 3), + DIV(CLK_DIV_PCLK_FD, "div_pclk_fd", "div_aclk_fd", DIV_CAM11, 12, 2), + DIV(CLK_DIV_ACLK_FD, "div_aclk_fd", "mout_aclk_fd_b", DIV_CAM11, 8, 3), + DIV(CLK_DIV_PCLK_LITE_C, "div_pclk_lite_c", "div_aclk_lite_c", + DIV_CAM11, 4, 2), + DIV(CLK_DIV_ACLK_LITE_C, "div_aclk_lite_c", "mout_aclk_lite_c_b", + DIV_CAM11, 0, 3), +}; + +static struct samsung_gate_clock cam1_gate_clks[] __initdata = { + /* ENABLE_ACLK_CAM10 */ + GATE(CLK_ACLK_ISP_GIC, "aclk_isp_gic", "mout_aclk_cam1_333_user", + ENABLE_ACLK_CAM10, 4, 0, 0), + GATE(CLK_ACLK_FD, "aclk_fd", "div_aclk_fd", + ENABLE_ACLK_CAM10, 3, 0, 0), + GATE(CLK_ACLK_LITE_C, "aclk_lite_c", "div_aclk_lite_c", + ENABLE_ACLK_CAM10, 1, 0, 0), + GATE(CLK_ACLK_CSIS2, "aclk_csis2", "div_aclk_csis2", + ENABLE_ACLK_CAM10, 0, 0, 0), + + /* ENABLE_ACLK_CAM11 */ + GATE(CLK_ACLK_ASYNCAPBM_FD, "aclk_asyncapbm_fd", "div_pclk_fd", + ENABLE_ACLK_CAM11, 29, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAPBS_FD, "aclk_asyncapbs_fd", "div_pclk_cam1_166", + ENABLE_ACLK_CAM11, 28, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAPBM_LITE_C, "aclk_asyncapbm_lite_c", + "div_pclk_lite_c", ENABLE_ACLK_CAM11, + 27, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAPBS_LITE_C, "aclk_asyncapbs_lite_c", + "div_pclk_cam1_166", ENABLE_ACLK_CAM11, + 26, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAHBS_SFRISP2H2, "aclk_asyncahbs_sfrisp2h2", + "div_pclk_cam1_83", ENABLE_ACLK_CAM11, + 25, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAHBS_SFRISP2H1, "aclk_asyncahbs_sfrisp2h1", + "div_pclk_cam1_83", ENABLE_ACLK_CAM11, + 24, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAXIM_CA5, "aclk_asyncaxim_ca5", + "mout_aclk_cam1_333_user", ENABLE_ACLK_CAM11, + 23, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAXIS_CA5, "aclk_asyncaxis_ca5", + "mout_aclk_cam1_552_user", ENABLE_ACLK_CAM11, + 22, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAXIS_ISPX2, "aclk_asyncaxis_ispx2", + "mout_aclk_cam1_333_user", ENABLE_ACLK_CAM11, + 21, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAXIS_ISPX1, "aclk_asyncaxis_ispx1", + "mout_aclk_cam1_333_user", ENABLE_ACLK_CAM11, + 20, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAXIS_ISPX0, "aclk_asyncaxis_ispx0", + "mout_aclk_cam1_333_user", ENABLE_ACLK_CAM11, + 19, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAXIM_ISPEX, "aclk_asyncaxim_ispex", + "mout_aclk_cam1_400_user", ENABLE_ACLK_CAM11, + 18, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAXIM_ISP3P, "aclk_asyncaxim_isp3p", + "mout_aclk_cam1_400_user", ENABLE_ACLK_CAM11, + 17, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAXIS_ISP3P, "aclk_asyncaxis_isp3p", + "mout_aclk_cam1_333_user", ENABLE_ACLK_CAM11, + 16, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAXIM_FD, "aclk_asyncaxim_fd", + "mout_aclk_cam1_400_user", ENABLE_ACLK_CAM11, + 15, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAXIS_FD, "aclk_asyncaxis_fd", "div_aclk_fd", + ENABLE_ACLK_CAM11, 14, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAXIM_LITE_C, "aclk_asyncaxim_lite_c", + "mout_aclk_cam1_400_user", ENABLE_ACLK_CAM11, + 13, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_ASYNCAXIS_LITE_C, "aclk_asyncaxis_lite_c", + "div_aclk_lite_c", ENABLE_ACLK_CAM11, + 12, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_AHB2APB_ISP5P, "aclk_ahb2apb_isp5p", "div_pclk_cam1_83", + ENABLE_ACLK_CAM11, 11, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_AHB2APB_ISP3P, "aclk_ahb2apb_isp3p", "div_pclk_cam1_83", + ENABLE_ACLK_CAM11, 10, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_AXI2APB_ISP3P, "aclk_axi2apb_isp3p", + "mout_aclk_cam1_333_user", ENABLE_ACLK_CAM11, + 9, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_AHB_SFRISP2H, "aclk_ahb_sfrisp2h", "div_pclk_cam1_83", + ENABLE_ACLK_CAM11, 8, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_AXI_ISP_HX_R, "aclk_axi_isp_hx_r", "div_pclk_cam1_166", + ENABLE_ACLK_CAM11, 7, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_AXI_ISP_CX_R, "aclk_axi_isp_cx_r", "div_pclk_cam1_166", + ENABLE_ACLK_CAM11, 6, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_AXI_ISP_HX, "aclk_axi_isp_hx", "mout_aclk_cam1_333_user", + ENABLE_ACLK_CAM11, 5, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_AXI_ISP_CX, "aclk_axi_isp_cx", "mout_aclk_cam1_333_user", + ENABLE_ACLK_CAM11, 4, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_XIU_ISPX, "aclk_xiu_ispx", "mout_aclk_cam1_333_user", + ENABLE_ACLK_CAM11, 3, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_XIU_ISPEX, "aclk_xiu_ispex", "mout_aclk_cam1_400_user", + ENABLE_ACLK_CAM11, 2, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_CAM1NP_333, "aclk_cam1np_333", "mout_aclk_cam1_333_user", + ENABLE_ACLK_CAM11, 1, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_CAM1ND_400, "aclk_cam1nd_400", "mout_aclk_cam1_400_user", + ENABLE_ACLK_CAM11, 0, CLK_IGNORE_UNUSED, 0), + + /* ENABLE_ACLK_CAM12 */ + GATE(CLK_ACLK_SMMU_ISPCPU, "aclk_smmu_ispcpu", + "mout_aclk_cam1_400_user", ENABLE_ACLK_CAM12, + 10, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_SMMU_FD, "aclk_smmu_fd", "mout_aclk_cam1_400_user", + ENABLE_ACLK_CAM12, 9, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_SMMU_LITE_C, "aclk_smmu_lite_c", + "mout_aclk_cam1_400_user", ENABLE_ACLK_CAM12, + 8, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_BTS_ISP3P, "aclk_bts_isp3p", "mout_aclk_cam1_400_user", + ENABLE_ACLK_CAM12, 7, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_BTS_FD, "aclk_bts_fd", "mout_aclk_cam1_400_user", + ENABLE_ACLK_CAM12, 6, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_BTS_LITE_C, "aclk_bts_lite_c", "mout_aclk_cam1_400_user", + ENABLE_ACLK_CAM12, 5, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_AHBDN_SFRISP2H, "aclk_ahbdn_sfrisp2h", + "mout_aclk_cam1_333_user", ENABLE_ACLK_CAM12, + 4, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_AHBDN_ISP5P, "aclk_aclk-shbdn_isp5p", + "mout_aclk_cam1_333_user", ENABLE_ACLK_CAM12, + 3, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_AXIUS_ISP3P, "aclk_axius_isp3p", + "mout_aclk_cam1_400_user", ENABLE_ACLK_CAM12, + 2, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_AXIUS_FD, "aclk_axius_fd", "mout_aclk_cam1_400_user", + ENABLE_ACLK_CAM12, 1, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ACLK_AXIUS_LITE_C, "aclk_axius_lite_c", + "mout_aclk_cam1_400_user", ENABLE_ACLK_CAM12, + 0, CLK_IGNORE_UNUSED, 0), + + /* ENABLE_PCLK_CAM1 */ + GATE(CLK_PCLK_SMMU_ISPCPU, "pclk_smmu_ispcpu", "div_pclk_cam1_166", + ENABLE_PCLK_CAM1, 27, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_SMMU_FD, "pclk_smmu_fd", "div_pclk_cam1_166", + ENABLE_PCLK_CAM1, 26, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_SMMU_LITE_C, "pclk_smmu_lite_c", "div_pclk_cam1_166", + ENABLE_PCLK_CAM1, 25, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_BTS_ISP3P, "pclk_bts_isp3p", "div_pclk_cam1_83", + ENABLE_PCLK_CAM1, 24, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_BTS_FD, "pclk_bts_fd", "div_pclk_cam1_83", + ENABLE_PCLK_CAM1, 23, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_BTS_LITE_C, "pclk_bts_lite_c", "div_pclk_cam1_83", + ENABLE_PCLK_CAM1, 22, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_ASYNCAXIM_CA5, "pclk_asyncaxim_ca5", "div_pclk_cam1_166", + ENABLE_PCLK_CAM1, 21, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_ASYNCAXIM_ISPEX, "pclk_asyncaxim_ispex", + "div_pclk_cam1_83", ENABLE_PCLK_CAM1, + 20, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_ASYNCAXIM_ISP3P, "pclk_asyncaxim_isp3p", + "div_pclk_cam1_83", ENABLE_PCLK_CAM1, + 19, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_ASYNCAXIM_FD, "pclk_asyncaxim_fd", "div_pclk_cam1_83", + ENABLE_PCLK_CAM1, 18, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_ASYNCAXIM_LITE_C, "pclk_asyncaxim_lite_c", + "div_pclk_cam1_83", ENABLE_PCLK_CAM1, + 17, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_PMU_CAM1, "pclk_pmu_cam1", "div_pclk_cam1_83", + ENABLE_PCLK_CAM1, 16, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_SYSREG_CAM1, "pclk_sysreg_cam1", "div_pclk_cam1_83", + ENABLE_PCLK_CAM1, 15, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_CMU_CAM1_LOCAL, "pclk_cmu_cam1_local", + "div_pclk_cam1_166", ENABLE_PCLK_CAM1, + 14, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_ISP_MCTADC, "pclk_isp_mctadc", "div_pclk_cam1_83", + ENABLE_PCLK_CAM1, 13, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_ISP_WDT, "pclk_isp_wdt", "div_pclk_cam1_83", + ENABLE_PCLK_CAM1, 12, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_ISP_PWM, "pclk_isp_pwm", "div_pclk_cam1_83", + ENABLE_PCLK_CAM1, 11, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_ISP_UART, "pclk_isp_uart", "div_pclk_cam1_83", + ENABLE_PCLK_CAM1, 10, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_ISP_MCUCTL, "pclk_isp_mcuctl", "div_pclk_cam1_83", + ENABLE_PCLK_CAM1, 9, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_ISP_SPI1, "pclk_isp_spi1", "div_pclk_cam1_83", + ENABLE_PCLK_CAM1, 8, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_ISP_SPI0, "pclk_isp_spi0", "div_pclk_cam1_83", + ENABLE_PCLK_CAM1, 7, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_ISP_I2C2, "pclk_isp_i2c2", "div_pclk_cam1_83", + ENABLE_PCLK_CAM1, 6, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_ISP_I2C1, "pclk_isp_i2c1", "div_pclk_cam1_83", + ENABLE_PCLK_CAM1, 5, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_ISP_I2C0, "pclk_isp_i2c0", "div_pclk_cam1_83", + ENABLE_PCLK_CAM1, 4, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_ISP_MPWM, "pclk_isp_wpwm", "div_pclk_cam1_83", + ENABLE_PCLK_CAM1, 3, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_FD, "pclk_fd", "div_pclk_fd", + ENABLE_PCLK_CAM1, 3, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_LITE_C, "pclk_lite_c", "div_pclk_lite_c", + ENABLE_PCLK_CAM1, 1, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PCLK_CSIS2, "pclk_csis2", "div_pclk_cam1_166", + ENABLE_PCLK_CAM1, 0, CLK_IGNORE_UNUSED, 0), + + /* ENABLE_SCLK_CAM1 */ + GATE(CLK_SCLK_ISP_I2C2, "sclk_isp_i2c2", "oscclk", ENABLE_SCLK_CAM1, + 15, 0, 0), + GATE(CLK_SCLK_ISP_I2C1, "sclk_isp_i2c1", "oscclk", ENABLE_SCLK_CAM1, + 14, 0, 0), + GATE(CLK_SCLK_ISP_I2C0, "sclk_isp_i2c0", "oscclk", ENABLE_SCLK_CAM1, + 13, 0, 0), + GATE(CLK_SCLK_ISP_PWM, "sclk_isp_pwm", "oscclk", ENABLE_SCLK_CAM1, + 12, 0, 0), + GATE(CLK_PHYCLK_RXBYTECLKHS0_S2B, "phyclk_rxbyteclkhs0_s2b", + "mout_phyclk_rxbyteclkhs0_s2b_user", + ENABLE_SCLK_CAM1, 11, 0, 0), + GATE(CLK_SCLK_LITE_C_FREECNT, "sclk_lite_c_freecnt", "div_pclk_lite_c", + ENABLE_SCLK_CAM1, 10, 0, 0), + GATE(CLK_SCLK_PIXELASYNCM_FD, "sclk_pixelasyncm_fd", "div_aclk_fd", + ENABLE_SCLK_CAM1, 9, 0, 0), + GATE(CLK_SCLK_ISP_MCTADC, "sclk_isp_mctadc", "sclk_isp_mctadc_cam1", + ENABLE_SCLK_CAM1, 7, 0, 0), + GATE(CLK_SCLK_ISP_UART, "sclk_isp_uart", "mout_sclk_isp_uart_user", + ENABLE_SCLK_CAM1, 6, 0, 0), + GATE(CLK_SCLK_ISP_SPI1, "sclk_isp_spi1", "mout_sclk_isp_spi1_user", + ENABLE_SCLK_CAM1, 5, 0, 0), + GATE(CLK_SCLK_ISP_SPI0, "sclk_isp_spi0", "mout_sclk_isp_spi0_user", + ENABLE_SCLK_CAM1, 4, 0, 0), + GATE(CLK_SCLK_ISP_MPWM, "sclk_isp_wpwm", "div_sclk_isp_wpwm", + ENABLE_SCLK_CAM1, 3, 0, 0), + GATE(CLK_PCLK_DBG_ISP, "sclk_dbg_isp", "div_pclk_dbg_cam1", + ENABLE_SCLK_CAM1, 2, 0, 0), + GATE(CLK_ATCLK_ISP, "atclk_isp", "div_atclk_cam1", + ENABLE_SCLK_CAM1, 1, 0, 0), + GATE(CLK_SCLK_ISP_CA5, "sclk_isp_ca5", "mout_aclk_cam1_552_user", + ENABLE_SCLK_CAM1, 0, 0, 0), +}; + +static struct samsung_cmu_info cam1_cmu_info __initdata = { + .mux_clks = cam1_mux_clks, + .nr_mux_clks = ARRAY_SIZE(cam1_mux_clks), + .div_clks = cam1_div_clks, + .nr_div_clks = ARRAY_SIZE(cam1_div_clks), + .gate_clks = cam1_gate_clks, + .nr_gate_clks = ARRAY_SIZE(cam1_gate_clks), + .fixed_clks = cam1_fixed_clks, + .nr_fixed_clks = ARRAY_SIZE(cam1_fixed_clks), + .nr_clk_ids = CAM1_NR_CLK, + .clk_regs = cam1_clk_regs, + .nr_clk_regs = ARRAY_SIZE(cam1_clk_regs), +}; + +static void __init exynos5433_cmu_cam1_init(struct device_node *np) +{ + samsung_cmu_register_one(np, &cam1_cmu_info); +} +CLK_OF_DECLARE(exynos5433_cmu_cam1, "samsung,exynos5433-cmu-cam1", + exynos5433_cmu_cam1_init); diff --git a/include/dt-bindings/clock/exynos5433.h b/include/dt-bindings/clock/exynos5433.h index f99cde7a278d..4853bc598b57 100644 --- a/include/dt-bindings/clock/exynos5433.h +++ b/include/dt-bindings/clock/exynos5433.h @@ -121,6 +121,20 @@ #define CLK_DIV_ACLK_CAM0_333 148 #define CLK_DIV_ACLK_CAM0_400 149 #define CLK_DIV_ACLK_CAM0_552 150 +#define CLK_DIV_ACLK_CAM1_333 151 +#define CLK_DIV_ACLK_CAM1_400 152 +#define CLK_DIV_ACLK_CAM1_552 153 +#define CLK_DIV_SCLK_ISP_UART 154 +#define CLK_DIV_SCLK_ISP_SPI1_B 155 +#define CLK_DIV_SCLK_ISP_SPI1_A 156 +#define CLK_DIV_SCLK_ISP_SPI0_B 157 +#define CLK_DIV_SCLK_ISP_SPI0_A 158 +#define CLK_DIV_SCLK_ISP_SENSOR2_B 159 +#define CLK_DIV_SCLK_ISP_SENSOR2_A 160 +#define CLK_DIV_SCLK_ISP_SENSOR1_B 161 +#define CLK_DIV_SCLK_ISP_SENSOR1_A 162 +#define CLK_DIV_SCLK_ISP_SENSOR0_B 163 +#define CLK_DIV_SCLK_ISP_SENSOR0_A 164 #define CLK_ACLK_PERIC_66 200 #define CLK_ACLK_PERIS_66 201 @@ -165,8 +179,18 @@ #define CLK_ACLK_CAM0_333 240 #define CLK_ACLK_CAM0_400 241 #define CLK_ACLK_CAM0_552 242 - -#define TOP_NR_CLK 243 +#define CLK_ACLK_CAM1_333 243 +#define CLK_ACLK_CAM1_400 244 +#define CLK_ACLK_CAM1_552 245 +#define CLK_SCLK_ISP_SENSOR2 246 +#define CLK_SCLK_ISP_SENSOR1 247 +#define CLK_SCLK_ISP_SENSOR0 248 +#define CLK_SCLK_ISP_MCTADC_CAM1 249 +#define CLK_SCLK_ISP_UART_CAM1 250 +#define CLK_SCLK_ISP_SPI1_CAM1 251 +#define CLK_SCLK_ISP_SPI0_CAM1 252 + +#define TOP_NR_CLK 253 /* CMU_CPIF */ #define CLK_FOUT_MPHY_PLL 1 @@ -1257,4 +1281,123 @@ #define CAM0_NR_CLK 134 +/* CMU_CAM1 */ +#define CLK_PHYCLK_RXBYTEECLKHS0_S2B 1 + +#define CLK_MOUT_SCLK_ISP_UART_USER 2 +#define CLK_MOUT_SCLK_ISP_SPI1_USER 3 +#define CLK_MOUT_SCLK_ISP_SPI0_USER 4 +#define CLK_MOUT_ACLK_CAM1_333_USER 5 +#define CLK_MOUT_ACLK_CAM1_400_USER 6 +#define CLK_MOUT_ACLK_CAM1_552_USER 7 +#define CLK_MOUT_PHYCLK_RXBYTECLKHS0_S2B_USER 8 +#define CLK_MOUT_ACLK_CSIS2_B 9 +#define CLK_MOUT_ACLK_CSIS2_A 10 +#define CLK_MOUT_ACLK_FD_B 11 +#define CLK_MOUT_ACLK_FD_A 12 +#define CLK_MOUT_ACLK_LITE_C_B 13 +#define CLK_MOUT_ACLK_LITE_C_A 14 + +#define CLK_DIV_SCLK_ISP_WPWM 15 +#define CLK_DIV_PCLK_CAM1_83 16 +#define CLK_DIV_PCLK_CAM1_166 17 +#define CLK_DIV_PCLK_DBG_CAM1 18 +#define CLK_DIV_ATCLK_CAM1 19 +#define CLK_DIV_ACLK_CSIS2 20 +#define CLK_DIV_PCLK_FD 21 +#define CLK_DIV_ACLK_FD 22 +#define CLK_DIV_PCLK_LITE_C 23 +#define CLK_DIV_ACLK_LITE_C 24 + +#define CLK_ACLK_ISP_GIC 25 +#define CLK_ACLK_FD 26 +#define CLK_ACLK_LITE_C 27 +#define CLK_ACLK_CSIS2 28 +#define CLK_ACLK_ASYNCAPBM_FD 29 +#define CLK_ACLK_ASYNCAPBS_FD 30 +#define CLK_ACLK_ASYNCAPBM_LITE_C 31 +#define CLK_ACLK_ASYNCAPBS_LITE_C 32 +#define CLK_ACLK_ASYNCAHBS_SFRISP2H2 33 +#define CLK_ACLK_ASYNCAHBS_SFRISP2H1 34 +#define CLK_ACLK_ASYNCAXIM_CA5 35 +#define CLK_ACLK_ASYNCAXIS_CA5 36 +#define CLK_ACLK_ASYNCAXIS_ISPX2 37 +#define CLK_ACLK_ASYNCAXIS_ISPX1 38 +#define CLK_ACLK_ASYNCAXIS_ISPX0 39 +#define CLK_ACLK_ASYNCAXIM_ISPEX 40 +#define CLK_ACLK_ASYNCAXIM_ISP3P 41 +#define CLK_ACLK_ASYNCAXIS_ISP3P 42 +#define CLK_ACLK_ASYNCAXIM_FD 43 +#define CLK_ACLK_ASYNCAXIS_FD 44 +#define CLK_ACLK_ASYNCAXIM_LITE_C 45 +#define CLK_ACLK_ASYNCAXIS_LITE_C 46 +#define CLK_ACLK_AHB2APB_ISP5P 47 +#define CLK_ACLK_AHB2APB_ISP3P 48 +#define CLK_ACLK_AXI2APB_ISP3P 49 +#define CLK_ACLK_AHB_SFRISP2H 50 +#define CLK_ACLK_AXI_ISP_HX_R 51 +#define CLK_ACLK_AXI_ISP_CX_R 52 +#define CLK_ACLK_AXI_ISP_HX 53 +#define CLK_ACLK_AXI_ISP_CX 54 +#define CLK_ACLK_XIU_ISPX 55 +#define CLK_ACLK_XIU_ISPEX 56 +#define CLK_ACLK_CAM1NP_333 57 +#define CLK_ACLK_CAM1ND_400 58 +#define CLK_ACLK_SMMU_ISPCPU 59 +#define CLK_ACLK_SMMU_FD 60 +#define CLK_ACLK_SMMU_LITE_C 61 +#define CLK_ACLK_BTS_ISP3P 62 +#define CLK_ACLK_BTS_FD 63 +#define CLK_ACLK_BTS_LITE_C 64 +#define CLK_ACLK_AHBDN_SFRISP2H 65 +#define CLK_ACLK_AHBDN_ISP5P 66 +#define CLK_ACLK_AXIUS_ISP3P 67 +#define CLK_ACLK_AXIUS_FD 68 +#define CLK_ACLK_AXIUS_LITE_C 69 +#define CLK_PCLK_SMMU_ISPCPU 70 +#define CLK_PCLK_SMMU_FD 71 +#define CLK_PCLK_SMMU_LITE_C 72 +#define CLK_PCLK_BTS_ISP3P 73 +#define CLK_PCLK_BTS_FD 74 +#define CLK_PCLK_BTS_LITE_C 75 +#define CLK_PCLK_ASYNCAXIM_CA5 76 +#define CLK_PCLK_ASYNCAXIM_ISPEX 77 +#define CLK_PCLK_ASYNCAXIM_ISP3P 78 +#define CLK_PCLK_ASYNCAXIM_FD 79 +#define CLK_PCLK_ASYNCAXIM_LITE_C 80 +#define CLK_PCLK_PMU_CAM1 81 +#define CLK_PCLK_SYSREG_CAM1 82 +#define CLK_PCLK_CMU_CAM1_LOCAL 83 +#define CLK_PCLK_ISP_MCTADC 84 +#define CLK_PCLK_ISP_WDT 85 +#define CLK_PCLK_ISP_PWM 86 +#define CLK_PCLK_ISP_UART 87 +#define CLK_PCLK_ISP_MCUCTL 88 +#define CLK_PCLK_ISP_SPI1 89 +#define CLK_PCLK_ISP_SPI0 90 +#define CLK_PCLK_ISP_I2C2 91 +#define CLK_PCLK_ISP_I2C1 92 +#define CLK_PCLK_ISP_I2C0 93 +#define CLK_PCLK_ISP_MPWM 94 +#define CLK_PCLK_FD 95 +#define CLK_PCLK_LITE_C 96 +#define CLK_PCLK_CSIS2 97 +#define CLK_SCLK_ISP_I2C2 98 +#define CLK_SCLK_ISP_I2C1 99 +#define CLK_SCLK_ISP_I2C0 100 +#define CLK_SCLK_ISP_PWM 101 +#define CLK_PHYCLK_RXBYTECLKHS0_S2B 102 +#define CLK_SCLK_LITE_C_FREECNT 103 +#define CLK_SCLK_PIXELASYNCM_FD 104 +#define CLK_SCLK_ISP_MCTADC 105 +#define CLK_SCLK_ISP_UART 106 +#define CLK_SCLK_ISP_SPI1 107 +#define CLK_SCLK_ISP_SPI0 108 +#define CLK_SCLK_ISP_MPWM 109 +#define CLK_PCLK_DBG_ISP 110 +#define CLK_ATCLK_ISP 111 +#define CLK_SCLK_ISP_CA5 112 + +#define CAM1_NR_CLK 113 + #endif /* _DT_BINDINGS_CLOCK_EXYNOS5433_H */ -- GitLab From 6166c01caf9394701a367b20422bcd558333795e Mon Sep 17 00:00:00 2001 From: Inha Song Date: Tue, 3 Feb 2015 09:13:57 +0900 Subject: [PATCH 00055/11651] clk: samsung: Add CLKOUT driver support for Exynos5433 SoC This patch add CLKOUT driver support for Exynos5433 SoC. Signed-off-by: Inha Song Acked-by: Inki Dae Signed-off-by: Sylwester Nawrocki --- drivers/clk/samsung/clk-exynos-clkout.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/clk/samsung/clk-exynos-clkout.c b/drivers/clk/samsung/clk-exynos-clkout.c index 3a7cb2506731..1eb16b868421 100644 --- a/drivers/clk/samsung/clk-exynos-clkout.c +++ b/drivers/clk/samsung/clk-exynos-clkout.c @@ -151,3 +151,5 @@ CLK_OF_DECLARE(exynos5250_clkout, "samsung,exynos5250-pmu", exynos5_clkout_init); CLK_OF_DECLARE(exynos5420_clkout, "samsung,exynos5420-pmu", exynos5_clkout_init); +CLK_OF_DECLARE(exynos5433_clkout, "samsung,exynos5433-pmu", + exynos5_clkout_init); -- GitLab From b2f0e5f28e0686c0d5db238357a2e32555e97633 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Wed, 4 Feb 2015 10:12:59 +0900 Subject: [PATCH 00056/11651] clk: samsung: exynos5433: Move CLK_SCLK_HDMI_SPDIF_DISP clock to CMU_TOP domain This patch fixes the bug of CLK_SCLK_HDMI_SPDIF_DISP clock because this clock should be included in CMU_TOP domain. So, this patch moves the CLK_SCLK_HDMI_ SPDIF_DISP clock from CMU_MIF to CMU_TOP domain. Reported-by: Sylwester Nawrocki Signed-off-by: Chanwoo Choi Signed-off-by: Sylwester Nawrocki --- drivers/clk/samsung/clk-exynos5433.c | 10 +++++----- include/dt-bindings/clock/exynos5433.h | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c index 1a005c1f7c4b..387e3e39e635 100644 --- a/drivers/clk/samsung/clk-exynos5433.c +++ b/drivers/clk/samsung/clk-exynos5433.c @@ -661,6 +661,11 @@ static struct samsung_gate_clock top_gate_clks[] __initdata = { GATE(CLK_SCLK_ISP_SPI0_CAM1, "sclk_isp_spi0_cam1", "div_sclk_isp_spi0_b", ENABLE_SCLK_TOP_CAM1, 0, 0, 0), + /* ENABLE_SCLK_TOP_DISP */ + GATE(CLK_SCLK_HDMI_SPDIF_DISP, "sclk_hdmi_spdif_disp", + "mout_sclk_hdmi_spdif", ENABLE_SCLK_TOP_DISP, 0, + CLK_IGNORE_UNUSED, 0), + /* ENABLE_SCLK_TOP_FSYS */ GATE(CLK_SCLK_PCIE_100_FSYS, "sclk_pcie_100_fsys", "div_sclk_pcie_100", ENABLE_SCLK_TOP_FSYS, 7, 0, 0), @@ -1521,11 +1526,6 @@ static struct samsung_gate_clock mif_gate_clks[] __initdata = { ENABLE_SCLK_MIF, 1, CLK_IGNORE_UNUSED, 0), GATE(CLK_SCLK_BUS_PLL_ATLAS, "sclk_bus_pll_atlas", "sclk_bus_pll", ENABLE_SCLK_MIF, 0, CLK_IGNORE_UNUSED, 0), - - /* ENABLE_SCLK_TOP_DISP */ - GATE(CLK_SCLK_HDMI_SPDIF_DISP, "sclk_hdmi_spdif_disp", - "mout_sclk_hdmi_spdif", ENABLE_SCLK_TOP_DISP, 0, - CLK_IGNORE_UNUSED, 0), }; static struct samsung_cmu_info mif_cmu_info __initdata = { diff --git a/include/dt-bindings/clock/exynos5433.h b/include/dt-bindings/clock/exynos5433.h index 4853bc598b57..5bd80d5ecd0f 100644 --- a/include/dt-bindings/clock/exynos5433.h +++ b/include/dt-bindings/clock/exynos5433.h @@ -189,8 +189,9 @@ #define CLK_SCLK_ISP_UART_CAM1 250 #define CLK_SCLK_ISP_SPI1_CAM1 251 #define CLK_SCLK_ISP_SPI0_CAM1 252 +#define CLK_SCLK_HDMI_SPDIF_DISP 253 -#define TOP_NR_CLK 253 +#define TOP_NR_CLK 254 /* CMU_CPIF */ #define CLK_FOUT_MPHY_PLL 1 @@ -397,9 +398,8 @@ #define CLK_SCLK_BUS_PLL 198 #define CLK_SCLK_BUS_PLL_APOLLO 199 #define CLK_SCLK_BUS_PLL_ATLAS 200 -#define CLK_SCLK_HDMI_SPDIF_DISP 201 -#define MIF_NR_CLK 202 +#define MIF_NR_CLK 201 /* CMU_PERIC */ #define CLK_PCLK_SPI2 1 -- GitLab From cd3bafc73d11eb51cb2d3691629718431e1768ce Mon Sep 17 00:00:00 2001 From: Hajime Tazaki Date: Wed, 4 Feb 2015 23:31:10 +0900 Subject: [PATCH 00057/11651] xfrm6: Fix a offset value for network header in _decode_session6 When a network-layer header has multiple IPv6 extension headers, then offset for mobility header goes wrong. This regression breaks an xfrm policy lookup for a particular receive packet. Binding update packets of Mobile IPv6 are all discarded without this fix. Fixes: de3b7a06dfe1 ("xfrm6: Fix transport header offset in _decode_session6.") Signed-off-by: Hajime Tazaki Signed-off-by: Steffen Klassert --- net/ipv6/xfrm6_policy.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index 48bf5a06847b..8d2d01b4800a 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c @@ -200,6 +200,7 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse) #if IS_ENABLED(CONFIG_IPV6_MIP6) case IPPROTO_MH: + offset += ipv6_optlen(exthdr); if (!onlyproto && pskb_may_pull(skb, nh + offset + 3 - skb->data)) { struct ip6_mh *mh; -- GitLab From 66af43d56345a7ca549ba1089fe11a6953072417 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 30 Jan 2015 11:33:27 +0900 Subject: [PATCH 00058/11651] perf test: Fix dso cache testcase The current dso cache permits to keep dso->data.fd is open under a half of open file limit. But test__dso_data_cache() sets dso_cnt to limit / 2 + 1 so it'll reach the limit in the loop even though the loop count is one less than the dso_cnt and it makes the final dso__data_fd() after the loop meaningless. I guess the intention was dsos[0]->data.fd is open before the last open and gets closed after it. So add an assert before the last open. Signed-off-by: Namhyung Kim Acked-by: Jiri Olsa Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1422585209-32742-1-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/dso-data.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tools/perf/tests/dso-data.c b/tools/perf/tests/dso-data.c index caaf37f079b1..22a8c428283a 100644 --- a/tools/perf/tests/dso-data.c +++ b/tools/perf/tests/dso-data.c @@ -243,8 +243,8 @@ int test__dso_data_cache(void) limit = nr * 4; TEST_ASSERT_VAL("failed to set file limit", !set_fd_limit(limit)); - /* and this is now our dso open FDs limit + 1 extra */ - dso_cnt = limit / 2 + 1; + /* and this is now our dso open FDs limit */ + dso_cnt = limit / 2; TEST_ASSERT_VAL("failed to create dsos\n", !dsos__create(dso_cnt, TEST_FILE_SIZE)); @@ -268,7 +268,10 @@ int test__dso_data_cache(void) } } - /* open +1 dso over the allowed limit */ + /* verify the first one is already open */ + TEST_ASSERT_VAL("dsos[0] is not open", dsos[0]->data.fd != -1); + + /* open +1 dso to reach the allowed limit */ fd = dso__data_fd(dsos[i], &machine); TEST_ASSERT_VAL("failed to get fd", fd > 0); -- GitLab From 63d3c6f3835d011c783c606c8a1583b041f579aa Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 30 Jan 2015 11:33:28 +0900 Subject: [PATCH 00059/11651] perf tests: Do not rely on dso__data_read_offset() to open dso Do not rely on dso__data_read_offset() will always call dso__data_fd() internally. With multi-thread support, accessing a fd will be protected by a lock and it'll cause a huge contention. It can be avoided since we can skip reading from file if there's a data in the dso cache. If one needs to call the dso__data_read_offset(), [s]he also needs to call dso__data_fd() (or set dso->binary_type at least) first like the dwarf unwind code does. Signed-off-by: Namhyung Kim Acked-by: Jiri Olsa Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1422585209-32742-2-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/dso-data.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/tools/perf/tests/dso-data.c b/tools/perf/tests/dso-data.c index 22a8c428283a..513e5febbe5a 100644 --- a/tools/perf/tests/dso-data.c +++ b/tools/perf/tests/dso-data.c @@ -112,6 +112,9 @@ int test__dso_data(void) dso = dso__new((const char *)file); + TEST_ASSERT_VAL("Failed to access to dso", + dso__data_fd(dso, &machine) >= 0); + /* Basic 10 bytes tests. */ for (i = 0; i < ARRAY_SIZE(offsets); i++) { struct test_data_offset *data = &offsets[i]; @@ -252,13 +255,13 @@ int test__dso_data_cache(void) struct dso *dso = dsos[i]; /* - * Open dsos via dso__data_fd or dso__data_read_offset. - * Both opens the data file and keep it open. + * Open dsos via dso__data_fd(), it opens the data + * file and keep it open (unless open file limit). */ + fd = dso__data_fd(dso, &machine); + TEST_ASSERT_VAL("failed to get fd", fd > 0); + if (i % 2) { - fd = dso__data_fd(dso, &machine); - TEST_ASSERT_VAL("failed to get fd", fd > 0); - } else { #define BUFSIZE 10 u8 buf[BUFSIZE]; ssize_t n; -- GitLab From a3c0cc2ac03bd9db032f590d59cdbf0b447503b8 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 30 Jan 2015 11:33:29 +0900 Subject: [PATCH 00060/11651] perf tools: Fix a dso open fail message It's not related to mmap, remove it from the message. Signed-off-by: Namhyung Kim Cc: Jiri Olsa Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1422585209-32742-3-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/dso.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index c2f7d3b90966..a8b3f18db1a5 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c @@ -240,7 +240,7 @@ static int do_open(char *name) if (fd >= 0) return fd; - pr_debug("dso open failed, mmap: %s\n", + pr_debug("dso open failed: %s\n", strerror_r(errno, sbuf, sizeof(sbuf))); if (!dso__data_open_cnt || errno != EMFILE) break; -- GitLab From e1ecbbc3fa834cc6b4b344edb1968e734d57189b Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Fri, 30 Jan 2015 18:37:44 +0900 Subject: [PATCH 00061/11651] perf probe: Fix to handle optimized not-inlined functions Fix to handle optimized no-inline functions which have only function definition but no actual instance at that point. To fix this problem, we need to find actual instance of the function. Without this patch: ---- # perf probe -a __up Failed to get entry address of __up. Error: Failed to add events. # perf probe -L __up Specified source line is not found. Error: Failed to show lines. ---- With this patch: ---- # perf probe -a __up Added new event: probe:__up (on __up) You can now use it in all perf tools, such as: perf record -e probe:__up -aR sleep 1 # perf probe -L __up <__up@/home/fedora/ksrc/linux-3/kernel/locking/semaphore.c:0> 0 static noinline void __sched __up(struct semaphore *sem) { struct semaphore_waiter *waiter = list_first_entry(&sem->wait_ struct semaphore_waite 4 list_del(&waiter->list); 5 waiter->up = true; 6 wake_up_process(waiter->task); 7 } ---- Signed-off-by: Masami Hiramatsu Tested-by: Arnaldo Carvalho de Melo Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20150130093744.30575.43290.stgit@localhost.localdomain Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/dwarf-aux.c | 15 +++++++++++++++ tools/perf/util/dwarf-aux.h | 3 +++ tools/perf/util/probe-finder.c | 12 ++++-------- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c index cc66c4049e09..780b2bc11128 100644 --- a/tools/perf/util/dwarf-aux.c +++ b/tools/perf/util/dwarf-aux.c @@ -277,6 +277,21 @@ bool die_is_func_def(Dwarf_Die *dw_die) dwarf_attr(dw_die, DW_AT_declaration, &attr) == NULL); } +/** + * die_is_func_instance - Ensure that this DIE is an instance of a subprogram + * @dw_die: a DIE + * + * Ensure that this DIE is an instance (which has an entry address). + * This returns true if @dw_die is a function instance. If not, you need to + * call die_walk_instances() to find actual instances. + **/ +bool die_is_func_instance(Dwarf_Die *dw_die) +{ + Dwarf_Addr tmp; + + /* Actually gcc optimizes non-inline as like as inlined */ + return !dwarf_func_inline(dw_die) && dwarf_entrypc(dw_die, &tmp) == 0; +} /** * die_get_data_member_location - Get the data-member offset * @mb_die: a DIE of a member of a data structure diff --git a/tools/perf/util/dwarf-aux.h b/tools/perf/util/dwarf-aux.h index b4fe90c6cb2d..af7dbcd5f929 100644 --- a/tools/perf/util/dwarf-aux.h +++ b/tools/perf/util/dwarf-aux.h @@ -41,6 +41,9 @@ extern int cu_walk_functions_at(Dwarf_Die *cu_die, Dwarf_Addr addr, /* Ensure that this DIE is a subprogram and definition (not declaration) */ extern bool die_is_func_def(Dwarf_Die *dw_die); +/* Ensure that this DIE is an instance of a subprogram */ +extern bool die_is_func_instance(Dwarf_Die *dw_die); + /* Compare diename and tname */ extern bool die_compare_name(Dwarf_Die *dw_die, const char *tname); diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index b5247d777f0e..d14193518e4d 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c @@ -915,17 +915,13 @@ static int probe_point_search_cb(Dwarf_Die *sp_die, void *data) dwarf_decl_line(sp_die, &pf->lno); pf->lno += pp->line; param->retval = find_probe_point_by_line(pf); - } else if (!dwarf_func_inline(sp_die)) { + } else if (die_is_func_instance(sp_die)) { + /* Instances always have the entry address */ + dwarf_entrypc(sp_die, &pf->addr); /* Real function */ if (pp->lazy_line) param->retval = find_probe_point_lazy(sp_die, pf); else { - if (dwarf_entrypc(sp_die, &pf->addr) != 0) { - pr_warning("Failed to get entry address of " - "%s.\n", dwarf_diename(sp_die)); - param->retval = -ENOENT; - return DWARF_CB_ABORT; - } pf->addr += pp->offset; /* TODO: Check the address in this function */ param->retval = call_probe_finder(sp_die, pf); @@ -1536,7 +1532,7 @@ static int line_range_search_cb(Dwarf_Die *sp_die, void *data) pr_debug("New line range: %d to %d\n", lf->lno_s, lf->lno_e); lr->start = lf->lno_s; lr->end = lf->lno_e; - if (dwarf_func_inline(sp_die)) + if (!die_is_func_instance(sp_die)) param->retval = die_walk_instances(sp_die, line_range_inline_cb, lf); else -- GitLab From 8b72805fd1dbfd697c5d4492d0cf1ebbd994950d Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Fri, 30 Jan 2015 18:37:46 +0900 Subject: [PATCH 00062/11651] perf probe: Update man page Update Documentation/perf-probe.txt to add descriptions of some newer options. Signed-off-by: Masami Hiramatsu Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20150130093746.30575.8571.stgit@localhost.localdomain Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-probe.txt | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/tools/perf/Documentation/perf-probe.txt b/tools/perf/Documentation/perf-probe.txt index aaa869be3dc1..239609c09f83 100644 --- a/tools/perf/Documentation/perf-probe.txt +++ b/tools/perf/Documentation/perf-probe.txt @@ -47,6 +47,12 @@ OPTIONS -v:: --verbose:: Be more verbose (show parsed arguments, etc). + Can not use with -q. + +-q:: +--quiet:: + Be quiet (do not show any messages including errors). + Can not use with -v. -a:: --add=:: @@ -96,7 +102,7 @@ OPTIONS Dry run. With this option, --add and --del doesn't execute actual adding and removal operations. ---max-probes:: +--max-probes=NUM:: Set the maximum number of probe points for an event. Default is 128. -x:: @@ -104,8 +110,13 @@ OPTIONS Specify path to the executable or shared library file for user space tracing. Can also be used with --funcs option. +--demangle:: + Demangle application symbols. --no-demangle is also available + for disabling demangling. + --demangle-kernel:: - Demangle kernel symbols. + Demangle kernel symbols. --no-demangle-kernel is also available + for disabling kernel demangling. In absence of -m/-x options, perf probe checks if the first argument after the options is an absolute path name. If its an absolute path, perf probe @@ -137,6 +148,7 @@ Each probe argument follows below syntax. [NAME=]LOCALVAR|$retval|%REG|@SYMBOL[:TYPE] 'NAME' specifies the name of this argument (optional). You can use the name of local variable, local data structure member (e.g. var->field, var.field2), local array with fixed index (e.g. array[1], var->array[0], var->pointer[2]), or kprobe-tracer argument format (e.g. $retval, %ax, etc). Note that the name of this argument will be set as the last member name if you specify a local data structure member (e.g. field2 for 'var->field1.field2'.) +'$vars' special argument is also available for NAME, it is expanded to the local variables which can access at given probe point. 'TYPE' casts the type of this argument (optional). If omitted, perf probe automatically set the type based on debuginfo. You can specify 'string' type only for the local variable or structure member which is an array of or a pointer to 'char' or 'unsigned char' type. On x86 systems %REG is always the short form of the register: for example %AX. %RAX or %EAX is not valid. -- GitLab From 4886f2ca19f6ff22ebfbe8e78c79c699e572b89f Mon Sep 17 00:00:00 2001 From: Victor Kamensky Date: Mon, 26 Jan 2015 22:34:01 -0800 Subject: [PATCH 00063/11651] perf symbols: Ignore mapping symbols on aarch64 Aarch64 ELF files use mapping symbols with special names $x, $d to identify regions of Aarch64 code (see Aarch64 ELF ABI - "ARM IHI 0056B", section "4.5.4 Mapping symbols"). The patch filters out these symbols at load time, similar to "696b97a perf symbols: Ignore mapping symbols on ARM" changes done for ARM before V8. Also added handling of mapping symbols that has format "$d." and similar for both cases. Note we are not making difference between EM_ARM and EM_AARCH64 mapping symbols instead code handles superset of both. Signed-off-by: Victor Kamensky Acked-by: Namhyung Kim Acked-by: Will Deacon Cc: Adrian Hunter Cc: Anton Blanchard Cc: Avi Kivity Cc: Dave Martin Cc: David Ahern Cc: Jiri Olsa Cc: linux-arm-kernel@lists.infradead.org Cc: Masami Hiramatsu Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Russell King Link: http://lkml.kernel.org/r/1422340442-4673-2-git-send-email-victor.kamensky@linaro.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/symbol-elf.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index b24f9d8727a8..225eb73ee78b 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -859,10 +859,9 @@ int dso__load_sym(struct dso *dso, struct map *map, /* Reject ARM ELF "mapping symbols": these aren't unique and * don't identify functions, so will confuse the profile * output: */ - if (ehdr.e_machine == EM_ARM) { - if (!strcmp(elf_name, "$a") || - !strcmp(elf_name, "$d") || - !strcmp(elf_name, "$t")) + if (ehdr.e_machine == EM_ARM || ehdr.e_machine == EM_AARCH64) { + if (elf_name[0] == '$' && strchr("adtx", elf_name[1]) + && (elf_name[2] == '\0' || elf_name[2] == '.')) continue; } -- GitLab From dc6254cf870732804b76a83ff2d8a72fea4365f6 Mon Sep 17 00:00:00 2001 From: Victor Kamensky Date: Mon, 26 Jan 2015 22:34:02 -0800 Subject: [PATCH 00064/11651] perf symbols: debuglink should take symfs option into account Currently code that tries to read corresponding debug symbol file from .gnu_debuglink section (DSO_BINARY_TYPE__DEBUGLINK) does not take in account symfs option, so filename__read_debuglink function cannot open ELF file, if symfs option is used. Fix is to add proper handling of symfs as it is done in other places: use __symbol__join_symfs function to get real file name of target ELF file. Signed-off-by: Victor Kamensky Tested-by: David Ahern Acked-by: David Ahern Acked-by: Namhyung Kim Cc: Adrian Hunter Cc: Anton Blanchard Cc: Avi Kivity Cc: Dave Martin Cc: Jiri Olsa Cc: Masami Hiramatsu Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Russell King Cc: Waiman Long Cc: Will Deacon Cc: linux-arm-kernel@lists.infradead.org Link: http://lkml.kernel.org/r/1422340442-4673-3-git-send-email-victor.kamensky@linaro.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/dso.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index a8b3f18db1a5..814554d1b857 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c @@ -45,13 +45,13 @@ int dso__read_binary_type_filename(const struct dso *dso, case DSO_BINARY_TYPE__DEBUGLINK: { char *debuglink; - strncpy(filename, dso->long_name, size); - debuglink = filename + dso->long_name_len; + len = __symbol__join_symfs(filename, size, dso->long_name); + debuglink = filename + len; while (debuglink != filename && *debuglink != '/') debuglink--; if (*debuglink == '/') debuglink++; - ret = filename__read_debuglink(dso->long_name, debuglink, + ret = filename__read_debuglink(filename, debuglink, size - (debuglink - filename)); } break; -- GitLab From 402bb4e6ec6507ccbb2e556d7996bbc989db7f27 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 3 Feb 2015 12:44:09 -0300 Subject: [PATCH 00065/11651] tools lib traceevent: Introduce trace_seq_do_fprintf function So that we can specify a FILE object where to direct the formatted output. Cc: Adrian Hunter Cc: Borislav Petkov Cc: David Ahern Cc: Don Zickus Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Steven Rostedt Link: http://lkml.kernel.org/n/tip-a49bhdrx8851f04hppn8bqxq@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/traceevent/event-parse.h | 2 ++ tools/lib/traceevent/trace-seq.c | 13 +++++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h index 7a3873ff9a4f..5b4efc062320 100644 --- a/tools/lib/traceevent/event-parse.h +++ b/tools/lib/traceevent/event-parse.h @@ -22,6 +22,7 @@ #include #include +#include #include #include @@ -91,6 +92,7 @@ extern int trace_seq_putc(struct trace_seq *s, unsigned char c); extern void trace_seq_terminate(struct trace_seq *s); +extern int trace_seq_do_fprintf(struct trace_seq *s, FILE *fp); extern int trace_seq_do_printf(struct trace_seq *s); diff --git a/tools/lib/traceevent/trace-seq.c b/tools/lib/traceevent/trace-seq.c index ec3bd16a5488..292dc9f1d233 100644 --- a/tools/lib/traceevent/trace-seq.c +++ b/tools/lib/traceevent/trace-seq.c @@ -231,19 +231,24 @@ void trace_seq_terminate(struct trace_seq *s) s->buffer[s->len] = 0; } -int trace_seq_do_printf(struct trace_seq *s) +int trace_seq_do_fprintf(struct trace_seq *s, FILE *fp) { TRACE_SEQ_CHECK(s); switch (s->state) { case TRACE_SEQ__GOOD: - return printf("%.*s", s->len, s->buffer); + return fprintf(fp, "%.*s", s->len, s->buffer); case TRACE_SEQ__BUFFER_POISONED: - puts("Usage of trace_seq after it was destroyed"); + fprintf(fp, "%s\n", "Usage of trace_seq after it was destroyed"); break; case TRACE_SEQ__MEM_ALLOC_FAILED: - puts("Can't allocate trace_seq buffer memory"); + fprintf(fp, "%s\n", "Can't allocate trace_seq buffer memory"); break; } return -1; } + +int trace_seq_do_printf(struct trace_seq *s) +{ + return trace_seq_do_fprintf(s, stdout); +} -- GitLab From aa1aac17a15cbf64236bd6f3b855262dcfb845c9 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 3 Feb 2015 12:46:58 -0300 Subject: [PATCH 00066/11651] perf tools: Introduce event_format__fprintf method The existing one, event_format__print() uses stdout unconditionally, and 'perf trace' needs to use it to format into a file that may have been set by the user, i.e. 'trace -o file.output'. Cc: Adrian Hunter Cc: Borislav Petkov Cc: David Ahern Cc: Don Zickus Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Steven Rostedt Link: http://lkml.kernel.org/n/tip-7l0mgm91hwg0bby00s5pse8r@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/trace-event-parse.c | 12 +++++++++--- tools/perf/util/trace-event.h | 3 +++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c index c36636fd825b..25d6c737be3e 100644 --- a/tools/perf/util/trace-event-parse.c +++ b/tools/perf/util/trace-event-parse.c @@ -112,8 +112,8 @@ unsigned long long read_size(struct event_format *event, void *ptr, int size) return pevent_read_number(event->pevent, ptr, size); } -void event_format__print(struct event_format *event, - int cpu, void *data, int size) +void event_format__fprintf(struct event_format *event, + int cpu, void *data, int size, FILE *fp) { struct pevent_record record; struct trace_seq s; @@ -125,10 +125,16 @@ void event_format__print(struct event_format *event, trace_seq_init(&s); pevent_event_info(&s, event, &record); - trace_seq_do_printf(&s); + trace_seq_do_fprintf(&s, fp); trace_seq_destroy(&s); } +void event_format__print(struct event_format *event, + int cpu, void *data, int size) +{ + return event_format__fprintf(event, cpu, data, size, stdout); +} + void parse_proc_kallsyms(struct pevent *pevent, char *file, unsigned int size __maybe_unused) { diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h index 52aaa19e1eb1..356629a30ca9 100644 --- a/tools/perf/util/trace-event.h +++ b/tools/perf/util/trace-event.h @@ -23,6 +23,9 @@ trace_event__tp_format(const char *sys, const char *name); int bigendian(void); +void event_format__fprintf(struct event_format *event, + int cpu, void *data, int size, FILE *fp); + void event_format__print(struct event_format *event, int cpu, void *data, int size); -- GitLab From c2c62e61fb8559420bb0346953843e557cdddba7 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Fri, 19 Apr 2013 21:01:31 +0400 Subject: [PATCH 00067/11651] xtensa: xtfpga: add audio card to xtfpga DTS This includes OpenCores I2C host controller, TI CDCE706 clock generator, xtfpga I2S master controller, xtfpga SPI master controller, TI TLV320AIC23 audio codec and a simple audio card. Signed-off-by: Max Filippov --- arch/xtensa/boot/dts/xtfpga.dtsi | 64 ++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/arch/xtensa/boot/dts/xtfpga.dtsi b/arch/xtensa/boot/dts/xtfpga.dtsi index dec9178840f6..cd0b9e34adc8 100644 --- a/arch/xtensa/boot/dts/xtfpga.dtsi +++ b/arch/xtensa/boot/dts/xtfpga.dtsi @@ -40,6 +40,12 @@ #clock-cells = <0>; compatible = "fixed-clock"; }; + + clk54: clk54 { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <54000000>; + }; }; soc { @@ -65,5 +71,63 @@ local-mac-address = [00 50 c2 13 6f 00]; clocks = <&osc>; }; + + i2s0: xtfpga-i2s@0d080000 { + #sound-dai-cells = <0>; + compatible = "cdns,xtfpga-i2s"; + reg = <0x0d080000 0x40>; + interrupts = <2 1>; /* external irq 2 */ + clocks = <&cdce706 4>; + }; + + i2c0: i2c-master@0d090000 { + compatible = "opencores,i2c-ocores"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x0d090000 0x20>; + reg-shift = <2>; + reg-io-width = <1>; + interrupts = <4 1>; + clocks = <&osc>; + + cdce706: clock-synth@69 { + compatible = "ti,cdce706"; + #clock-cells = <1>; + reg = <0x69>; + clocks = <&clk54>; + clock-names = "clk_in0"; + }; + }; + + spi0: spi-master@0d0a0000 { + compatible = "cdns,xtfpga-spi"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x0d0a0000 0xc>; + + tlv320aic23: sound-codec@0 { + #sound-dai-cells = <0>; + compatible = "tlv320aic23"; + reg = <0>; + spi-max-frequency = <12500000>; + }; + }; + }; + + sound { + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; + simple-audio-card,mclk-fs = <256>; + + simple-audio-card,cpu { + sound-dai = <&i2s0>; + }; + + simple-audio-card,codec { + sound-dai = <&tlv320aic23>; + simple-audio-card,bitclock-master = <0>; + simple-audio-card,frame-master = <0>; + clocks = <&cdce706 4>; + }; }; }; -- GitLab From 04ddc5b5ad4eca2b96160663431f041bec2efc2e Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Sat, 7 Feb 2015 12:47:56 +0300 Subject: [PATCH 00068/11651] xtensa: xtfpga: provide defconfig with audio subsystem This is the generic KC705 defconfig with all pieces of xtfpga audio subsystem enabled: I2C, SPI and ASoC support, I2C master, SPI master, clock synthesizer, I2S master, audio codec and audio card drivers. Signed-off-by: Max Filippov --- arch/xtensa/configs/audio_kc705_defconfig | 142 ++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 arch/xtensa/configs/audio_kc705_defconfig diff --git a/arch/xtensa/configs/audio_kc705_defconfig b/arch/xtensa/configs/audio_kc705_defconfig new file mode 100644 index 000000000000..c4904db15582 --- /dev/null +++ b/arch/xtensa/configs/audio_kc705_defconfig @@ -0,0 +1,142 @@ +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +CONFIG_FHANDLE=y +CONFIG_IRQ_DOMAIN_DEBUG=y +CONFIG_NO_HZ_IDLE=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_IRQ_TIME_ACCOUNTING=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_CGROUP_DEBUG=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CPUSETS=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_MEMCG=y +CONFIG_NAMESPACES=y +CONFIG_SCHED_AUTOGROUP=y +CONFIG_RELAY=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_EXPERT=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS_ALL=y +CONFIG_PROFILING=y +CONFIG_OPROFILE=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_IOSCHED_DEADLINE is not set +# CONFIG_IOSCHED_CFQ is not set +CONFIG_XTENSA_VARIANT_CUSTOM=y +CONFIG_XTENSA_VARIANT_CUSTOM_NAME="test_kc705_hifi" +CONFIG_XTENSA_UNALIGNED_USER=y +CONFIG_PREEMPT=y +CONFIG_HIGHMEM=y +# CONFIG_PCI is not set +CONFIG_XTENSA_PLATFORM_XTFPGA=y +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="earlycon=uart8250,mmio32,0xfd050020,115200n8 console=ttyS0,115200n8 ip=dhcp root=/dev/nfs rw debug" +CONFIG_USE_OF=y +CONFIG_BUILTIN_DTB="kc705" +# CONFIG_COMPACTION is not set +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_PM=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +# CONFIG_IPV6 is not set +CONFIG_NETFILTER=y +# CONFIG_WIRELESS is not set +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +# CONFIG_STANDALONE is not set +CONFIG_MTD=y +CONFIG_MTD_CFI=y +CONFIG_MTD_JEDECPROBE=y +CONFIG_MTD_CFI_INTELEXT=y +CONFIG_MTD_CFI_AMDSTD=y +CONFIG_MTD_CFI_STAA=y +CONFIG_MTD_PHYSMAP_OF=y +CONFIG_MTD_UBI=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_RAM=y +CONFIG_SCSI=y +CONFIG_BLK_DEV_SD=y +CONFIG_NETDEVICES=y +# CONFIG_NET_VENDOR_ARC is not set +# CONFIG_NET_VENDOR_BROADCOM is not set +# CONFIG_NET_VENDOR_INTEL is not set +# CONFIG_NET_VENDOR_MARVELL is not set +# CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_NET_VENDOR_SAMSUNG is not set +# CONFIG_NET_VENDOR_SEEQ is not set +# CONFIG_NET_VENDOR_SMSC is not set +# CONFIG_NET_VENDOR_STMICRO is not set +# CONFIG_NET_VENDOR_VIA is not set +# CONFIG_NET_VENDOR_WIZNET is not set +CONFIG_MARVELL_PHY=y +# CONFIG_WLAN is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_SERIO is not set +CONFIG_SERIAL_8250=y +# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_HW_RANDOM=y +CONFIG_I2C=y +CONFIG_I2C_OCORES=y +CONFIG_SPI=y +CONFIG_SPI_XTENSA_XTFPGA=y +# CONFIG_HWMON is not set +CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_NOWAYOUT=y +CONFIG_SOFT_WATCHDOG=y +# CONFIG_VGA_CONSOLE is not set +CONFIG_SOUND=y +CONFIG_SND=y +CONFIG_SND_SOC=y +CONFIG_SND_SOC_XTFPGA_I2S=y +CONFIG_SND_SOC_TLV320AIC23_SPI=y +CONFIG_SND_SIMPLE_CARD=y +# CONFIG_USB_SUPPORT is not set +CONFIG_COMMON_CLK_CDCE706=y +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_EXT3_FS=y +CONFIG_EXT4_FS=y +CONFIG_FANOTIFY=y +CONFIG_VFAT_FS=y +CONFIG_PROC_KCORE=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_UBIFS_FS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V4=y +CONFIG_NFS_SWAP=y +CONFIG_ROOT_NFS=y +CONFIG_SUNRPC_DEBUG=y +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ISO8859_1=y +CONFIG_PRINTK_TIME=y +CONFIG_DYNAMIC_DEBUG=y +CONFIG_DEBUG_INFO=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_LOCKUP_DETECTOR=y +# CONFIG_SCHED_DEBUG is not set +CONFIG_SCHEDSTATS=y +CONFIG_TIMER_STATS=y +CONFIG_DEBUG_RT_MUTEXES=y +CONFIG_DEBUG_SPINLOCK=y +CONFIG_DEBUG_MUTEXES=y +CONFIG_DEBUG_ATOMIC_SLEEP=y +CONFIG_STACKTRACE=y +CONFIG_RCU_TRACE=y +# CONFIG_FTRACE is not set +# CONFIG_S32C1I_SELFTEST is not set +CONFIG_CRYPTO_ANSI_CPRNG=y -- GitLab From f7aa222ff397bd99153a039578864c1a36b8f391 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 3 Feb 2015 13:25:39 -0300 Subject: [PATCH 00069/11651] perf trace: No need to enable evsels for workload started from perf As they will have perf_event_attr.enable_on_exec set, starting as soon as we exec() the workload. Cc: Adrian Hunter Cc: Borislav Petkov Cc: David Ahern Cc: Don Zickus Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-vmj3f6o3vxrg7mrdipts09li@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 7e935f1083ec..66300aea08b0 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -2109,10 +2109,10 @@ static int trace__run(struct trace *trace, int argc, const char **argv) if (err < 0) goto out_error_mmap; - perf_evlist__enable(evlist); - if (forks) perf_evlist__start_workload(evlist); + else + perf_evlist__enable(evlist); trace->multiple_threads = evlist->threads->map[0] == -1 || evlist->threads->nr > 1; again: -- GitLab From 20f86fc1fde14c6d913ebf5f569ee85e058a7dbd Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 3 Feb 2015 13:29:05 -0300 Subject: [PATCH 00070/11651] perf evlist: Fix typo in comment Link: http://lkml.kernel.org/n/tip-qzg2qrdgta6dmcrxqdeexthu@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evlist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 28b8ce86bf12..c602ebb5b991 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -1329,7 +1329,7 @@ int perf_evlist__prepare_workload(struct perf_evlist *evlist, struct target *tar * writing exactly one byte, in workload.cork_fd, usually via * perf_evlist__start_workload(). * - * For cancelling the workload without actuallin running it, + * For cancelling the workload without actually running it, * the parent will just close workload.cork_fd, without writing * anything, i.e. read will return zero and we just exit() * here. -- GitLab From 5693c92660970851e95f769ff27397f5098a6296 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Mon, 2 Feb 2015 14:35:02 -0500 Subject: [PATCH 00071/11651] perf tools: Do not check debugfs MAGIC for tracing files It's rather strange to be checking the debugfs MAGIC number for the tracing directory. A system admin may want to have a custom set of events to trace and it should be allowed to let the admin make a temp file (even for tracing virtual boxes, this is useful). Also with the coming tracefs, the files may not even be under debugfs, so checking the debugfs MAGIC number is pointless. Signed-off-by: Steven Rostedt Acked-by: Jiri Olsa Cc: Andrew Morton Cc: Ingo Molnar Cc: Masami Hiramatsu Cc: Namhyung Kim Link: http://lkml.kernel.org/r/20150202193552.546175764@goodmis.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/api/fs/debugfs.c | 28 ++++++++++++++-------------- tools/lib/api/fs/debugfs.h | 1 - tools/perf/util/parse-events.c | 19 ------------------- 3 files changed, 14 insertions(+), 34 deletions(-) diff --git a/tools/lib/api/fs/debugfs.c b/tools/lib/api/fs/debugfs.c index d2b18e887071..d21d4d6b4fd2 100644 --- a/tools/lib/api/fs/debugfs.c +++ b/tools/lib/api/fs/debugfs.c @@ -20,6 +20,20 @@ static const char * const debugfs_known_mountpoints[] = { static bool debugfs_found; +/* verify that a mountpoint is actually a debugfs instance */ + +static int debugfs_valid_mountpoint(const char *debugfs) +{ + struct statfs st_fs; + + if (statfs(debugfs, &st_fs) < 0) + return -ENOENT; + else if ((long)st_fs.f_type != (long)DEBUGFS_MAGIC) + return -ENOENT; + + return 0; +} + /* find the path to the mounted debugfs */ const char *debugfs_find_mountpoint(void) { @@ -60,20 +74,6 @@ const char *debugfs_find_mountpoint(void) return debugfs_mountpoint; } -/* verify that a mountpoint is actually a debugfs instance */ - -int debugfs_valid_mountpoint(const char *debugfs) -{ - struct statfs st_fs; - - if (statfs(debugfs, &st_fs) < 0) - return -ENOENT; - else if ((long)st_fs.f_type != (long)DEBUGFS_MAGIC) - return -ENOENT; - - return 0; -} - /* mount the debugfs somewhere if it's not mounted */ char *debugfs_mount(const char *mountpoint) { diff --git a/tools/lib/api/fs/debugfs.h b/tools/lib/api/fs/debugfs.h index 0739881a9897..77bb36a95b07 100644 --- a/tools/lib/api/fs/debugfs.h +++ b/tools/lib/api/fs/debugfs.h @@ -21,7 +21,6 @@ #endif const char *debugfs_find_mountpoint(void); -int debugfs_valid_mountpoint(const char *debugfs); char *debugfs_mount(const char *mountpoint); extern char debugfs_mountpoint[]; diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 7f8ec6ce2823..ecf069b1661f 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -175,9 +175,6 @@ struct tracepoint_path *tracepoint_id_to_path(u64 config) char evt_path[MAXPATHLEN]; char dir_path[MAXPATHLEN]; - if (debugfs_valid_mountpoint(tracing_events_path)) - return NULL; - sys_dir = opendir(tracing_events_path); if (!sys_dir) return NULL; @@ -473,12 +470,6 @@ static int add_tracepoint_multi_sys(struct list_head *list, int *idx, int parse_events_add_tracepoint(struct list_head *list, int *idx, char *sys, char *event) { - int ret; - - ret = debugfs_valid_mountpoint(tracing_events_path); - if (ret) - return ret; - if (strpbrk(sys, "*?")) return add_tracepoint_multi_sys(list, idx, sys, event); else @@ -1109,13 +1100,6 @@ void print_tracepoint_events(const char *subsys_glob, const char *event_glob, struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; char evt_path[MAXPATHLEN]; char dir_path[MAXPATHLEN]; - char sbuf[STRERR_BUFSIZE]; - - if (debugfs_valid_mountpoint(tracing_events_path)) { - printf(" [ Tracepoints not available: %s ]\n", - strerror_r(errno, sbuf, sizeof(sbuf))); - return; - } sys_dir = opendir(tracing_events_path); if (!sys_dir) @@ -1163,9 +1147,6 @@ int is_valid_tracepoint(const char *event_string) char evt_path[MAXPATHLEN]; char dir_path[MAXPATHLEN]; - if (debugfs_valid_mountpoint(tracing_events_path)) - return 0; - sys_dir = opendir(tracing_events_path); if (!sys_dir) return 0; -- GitLab From cde164aee9e0343831467035eb96dd5506742648 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Mon, 2 Feb 2015 14:35:03 -0500 Subject: [PATCH 00072/11651] tools lib fs: Add helper to find mounted file systems In preparation for adding tracefs for perf to use, create a findfs helper utility that find_debugfs uses instead of hard coding the search in the code. This will allow for a find_tracefs to be used as well. Signed-off-by: Steven Rostedt Acked-by: Jiri Olsa Cc: Andrew Morton Cc: Ingo Molnar Cc: Masami Hiramatsu Cc: Namhyung Kim Link: http://lkml.kernel.org/r/20150202193552.735023362@goodmis.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/api/Makefile | 2 ++ tools/lib/api/fs/debugfs.c | 51 +++++------------------------- tools/lib/api/fs/debugfs.h | 11 +------ tools/lib/api/fs/findfs.c | 63 ++++++++++++++++++++++++++++++++++++++ tools/lib/api/fs/findfs.h | 21 +++++++++++++ 5 files changed, 94 insertions(+), 54 deletions(-) create mode 100644 tools/lib/api/fs/findfs.c create mode 100644 tools/lib/api/fs/findfs.h diff --git a/tools/lib/api/Makefile b/tools/lib/api/Makefile index 36c08b1f4afb..22b2f15d7255 100644 --- a/tools/lib/api/Makefile +++ b/tools/lib/api/Makefile @@ -9,11 +9,13 @@ LIB_H= LIB_OBJS= LIB_H += fs/debugfs.h +LIB_H += fs/findfs.h LIB_H += fs/fs.h # See comment below about piggybacking... LIB_H += fd/array.h LIB_OBJS += $(OUTPUT)fs/debugfs.o +LIB_OBJS += $(OUTPUT)fs/findfs.o LIB_OBJS += $(OUTPUT)fs/fs.o # XXX piggybacking here, need to introduce libapikfd, or rename this # to plain libapik.a and make it have it all api goodies diff --git a/tools/lib/api/fs/debugfs.c b/tools/lib/api/fs/debugfs.c index d21d4d6b4fd2..91e1668348ce 100644 --- a/tools/lib/api/fs/debugfs.c +++ b/tools/lib/api/fs/debugfs.c @@ -20,58 +20,21 @@ static const char * const debugfs_known_mountpoints[] = { static bool debugfs_found; -/* verify that a mountpoint is actually a debugfs instance */ - -static int debugfs_valid_mountpoint(const char *debugfs) -{ - struct statfs st_fs; - - if (statfs(debugfs, &st_fs) < 0) - return -ENOENT; - else if ((long)st_fs.f_type != (long)DEBUGFS_MAGIC) - return -ENOENT; - - return 0; -} - /* find the path to the mounted debugfs */ const char *debugfs_find_mountpoint(void) { - const char * const *ptr; - char type[100]; - FILE *fp; + const char *ret; if (debugfs_found) return (const char *)debugfs_mountpoint; - ptr = debugfs_known_mountpoints; - while (*ptr) { - if (debugfs_valid_mountpoint(*ptr) == 0) { - debugfs_found = true; - strcpy(debugfs_mountpoint, *ptr); - return debugfs_mountpoint; - } - ptr++; - } + ret = find_mountpoint("debugfs", (long) DEBUGFS_MAGIC, + debugfs_mountpoint, PATH_MAX + 1, + debugfs_known_mountpoints); + if (ret) + debugfs_found = true; - /* give up and parse /proc/mounts */ - fp = fopen("/proc/mounts", "r"); - if (fp == NULL) - return NULL; - - while (fscanf(fp, "%*s %" STR(PATH_MAX) "s %99s %*s %*d %*d\n", - debugfs_mountpoint, type) == 2) { - if (strcmp(type, "debugfs") == 0) - break; - } - fclose(fp); - - if (strcmp(type, "debugfs") != 0) - return NULL; - - debugfs_found = true; - - return debugfs_mountpoint; + return ret; } /* mount the debugfs somewhere if it's not mounted */ diff --git a/tools/lib/api/fs/debugfs.h b/tools/lib/api/fs/debugfs.h index 77bb36a95b07..1074ac81358e 100644 --- a/tools/lib/api/fs/debugfs.h +++ b/tools/lib/api/fs/debugfs.h @@ -1,16 +1,7 @@ #ifndef __API_DEBUGFS_H__ #define __API_DEBUGFS_H__ -#define _STR(x) #x -#define STR(x) _STR(x) - -/* - * On most systems would have given us this, but not on some systems - * (e.g. GNU/Hurd). - */ -#ifndef PATH_MAX -#define PATH_MAX 4096 -#endif +#include "findfs.h" #ifndef DEBUGFS_MAGIC #define DEBUGFS_MAGIC 0x64626720 diff --git a/tools/lib/api/fs/findfs.c b/tools/lib/api/fs/findfs.c new file mode 100644 index 000000000000..49946cb6d7af --- /dev/null +++ b/tools/lib/api/fs/findfs.c @@ -0,0 +1,63 @@ +#include +#include +#include +#include +#include +#include + +#include "findfs.h" + +/* verify that a mountpoint is actually the type we want */ + +int valid_mountpoint(const char *mount, long magic) +{ + struct statfs st_fs; + + if (statfs(mount, &st_fs) < 0) + return -ENOENT; + else if ((long)st_fs.f_type != magic) + return -ENOENT; + + return 0; +} + +/* find the path to a mounted file system */ +const char *find_mountpoint(const char *fstype, long magic, + char *mountpoint, int len, + const char * const *known_mountpoints) +{ + const char * const *ptr; + char format[128]; + char type[100]; + FILE *fp; + + if (known_mountpoints) { + ptr = known_mountpoints; + while (*ptr) { + if (valid_mountpoint(*ptr, magic) == 0) { + strncpy(mountpoint, *ptr, len - 1); + mountpoint[len-1] = 0; + return mountpoint; + } + ptr++; + } + } + + /* give up and parse /proc/mounts */ + fp = fopen("/proc/mounts", "r"); + if (fp == NULL) + return NULL; + + snprintf(format, 128, "%%*s %%%ds %%99s %%*s %%*d %%*d\n", len); + + while (fscanf(fp, format, mountpoint, type) == 2) { + if (strcmp(type, fstype) == 0) + break; + } + fclose(fp); + + if (strcmp(type, fstype) != 0) + return NULL; + + return mountpoint; +} diff --git a/tools/lib/api/fs/findfs.h b/tools/lib/api/fs/findfs.h new file mode 100644 index 000000000000..9e7d876791e1 --- /dev/null +++ b/tools/lib/api/fs/findfs.h @@ -0,0 +1,21 @@ +#ifndef __API_FINDFS_H__ +#define __API_FINDFS_H__ + +#define _STR(x) #x +#define STR(x) _STR(x) + +/* + * On most systems would have given us this, but not on some systems + * (e.g. GNU/Hurd). + */ +#ifndef PATH_MAX +#define PATH_MAX 4096 +#endif + +const char *find_mountpoint(const char *fstype, long magic, + char *mountpoint, int len, + const char * const *known_mountpoints); + +int valid_mountpoint(const char *mount, long magic); + +#endif /* __API_FINDFS_H__ */ -- GitLab From 4ef92c2ecd96ebad171e554020c83ce9fdb343ae Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Mon, 2 Feb 2015 14:35:04 -0500 Subject: [PATCH 00073/11651] tools lib api fs: Add tracefs mount helper functions Since tracefs will now hold the event directory for perf, and even though by default, debugfs still mounts tracefs on the debugfs/tracing directory, the system admin may now choose to not mount debugfs and instead just mount tracefs instead. Having tracefs helper functions will facilitate having perf look for tracefs first, and then try debugfs as a fallback. Signed-off-by: Steven Rostedt Acked-by: Jiri Olsa Cc: Andrew Morton Cc: Ingo Molnar Cc: Masami Hiramatsu Cc: Namhyung Kim Link: http://lkml.kernel.org/r/20150202193552.898934751@goodmis.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/api/Makefile | 2 ++ tools/lib/api/fs/tracefs.c | 70 ++++++++++++++++++++++++++++++++++++++ tools/lib/api/fs/tracefs.h | 20 +++++++++++ 3 files changed, 92 insertions(+) create mode 100644 tools/lib/api/fs/tracefs.c create mode 100644 tools/lib/api/fs/tracefs.h diff --git a/tools/lib/api/Makefile b/tools/lib/api/Makefile index 22b2f15d7255..212aa4fd65a0 100644 --- a/tools/lib/api/Makefile +++ b/tools/lib/api/Makefile @@ -9,12 +9,14 @@ LIB_H= LIB_OBJS= LIB_H += fs/debugfs.h +LIB_H += fs/tracefs.h LIB_H += fs/findfs.h LIB_H += fs/fs.h # See comment below about piggybacking... LIB_H += fd/array.h LIB_OBJS += $(OUTPUT)fs/debugfs.o +LIB_OBJS += $(OUTPUT)fs/tracefs.o LIB_OBJS += $(OUTPUT)fs/findfs.o LIB_OBJS += $(OUTPUT)fs/fs.o # XXX piggybacking here, need to introduce libapikfd, or rename this diff --git a/tools/lib/api/fs/tracefs.c b/tools/lib/api/fs/tracefs.c new file mode 100644 index 000000000000..ef40d15821e9 --- /dev/null +++ b/tools/lib/api/fs/tracefs.c @@ -0,0 +1,70 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tracefs.h" + +#ifndef TRACEFS_DEFAULT_PATH +#define TRACEFS_DEFAULT_PATH "/sys/kernel/tracing" +#endif + +char tracefs_mountpoint[PATH_MAX + 1] = TRACEFS_DEFAULT_PATH; + +static const char * const tracefs_known_mountpoints[] = { + TRACEFS_DEFAULT_PATH, + "/sys/kernel/debug/tracing", + "/tracing", + "/trace", + 0, +}; + +static bool tracefs_found; + +/* find the path to the mounted tracefs */ +const char *tracefs_find_mountpoint(void) +{ + const char *ret; + + if (tracefs_found) + return (const char *)tracefs_mountpoint; + + ret = find_mountpoint("tracefs", (long) TRACEFS_MAGIC, + tracefs_mountpoint, PATH_MAX + 1, + tracefs_known_mountpoints); + + if (ret) + tracefs_found = true; + + return ret; +} + +/* mount the tracefs somewhere if it's not mounted */ +char *tracefs_mount(const char *mountpoint) +{ + /* see if it's already mounted */ + if (tracefs_find_mountpoint()) + goto out; + + /* if not mounted and no argument */ + if (mountpoint == NULL) { + /* see if environment variable set */ + mountpoint = getenv(PERF_TRACEFS_ENVIRONMENT); + /* if no environment variable, use default */ + if (mountpoint == NULL) + mountpoint = TRACEFS_DEFAULT_PATH; + } + + if (mount(NULL, mountpoint, "tracefs", 0, NULL) < 0) + return NULL; + + /* save the mountpoint */ + tracefs_found = true; + strncpy(tracefs_mountpoint, mountpoint, sizeof(tracefs_mountpoint)); +out: + return tracefs_mountpoint; +} diff --git a/tools/lib/api/fs/tracefs.h b/tools/lib/api/fs/tracefs.h new file mode 100644 index 000000000000..e6f7f5183c87 --- /dev/null +++ b/tools/lib/api/fs/tracefs.h @@ -0,0 +1,20 @@ +#ifndef __API_TRACEFS_H__ +#define __API_TRACEFS_H__ + +#include "findfs.h" + +#ifndef TRACEFS_MAGIC +#define TRACEFS_MAGIC 0x74726163 +#endif + +#ifndef PERF_TRACEFS_ENVIRONMENT +#define PERF_TRACEFS_ENVIRONMENT "PERF_TRACEFS_DIR" +#endif + +const char *tracefs_find_mountpoint(void); +int tracefs_valid_mountpoint(const char *debugfs); +char *tracefs_mount(const char *mountpoint); + +extern char tracefs_mountpoint[]; + +#endif /* __API_DEBUGFS_H__ */ -- GitLab From a9edf60749a9483341facfa7c28bcf8afb3c8311 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Mon, 2 Feb 2015 14:35:05 -0500 Subject: [PATCH 00074/11651] tools lib api debugfs: Add DEBUGFS_DEFAULT_PATH macro Instead of hard coding "/sys/kernel/debug" everywhere, create a macro to hold where the default path exists. Signed-off-by: Steven Rostedt Acked-by: Jiri Olsa Cc: Andrew Morton Cc: Ingo Molnar Cc: Masami Hiramatsu Cc: Namhyung Kim Link: http://lkml.kernel.org/r/20150202193553.032117017@goodmis.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/api/fs/debugfs.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tools/lib/api/fs/debugfs.c b/tools/lib/api/fs/debugfs.c index 91e1668348ce..07d74b03d828 100644 --- a/tools/lib/api/fs/debugfs.c +++ b/tools/lib/api/fs/debugfs.c @@ -10,10 +10,14 @@ #include "debugfs.h" -char debugfs_mountpoint[PATH_MAX + 1] = "/sys/kernel/debug"; +#ifndef DEBUGFS_DEFAULT_PATH +#define DEBUGFS_DEFAULT_PATH "/sys/kernel/debug" +#endif + +char debugfs_mountpoint[PATH_MAX + 1] = DEBUGFS_DEFAULT_PATH; static const char * const debugfs_known_mountpoints[] = { - "/sys/kernel/debug", + DEBUGFS_DEFAULT_PATH, "/debug", 0, }; @@ -50,7 +54,7 @@ char *debugfs_mount(const char *mountpoint) mountpoint = getenv(PERF_DEBUGFS_ENVIRONMENT); /* if no environment variable, use default */ if (mountpoint == NULL) - mountpoint = "/sys/kernel/debug"; + mountpoint = DEBUGFS_DEFAULT_PATH; } if (mount(NULL, mountpoint, "debugfs", 0, NULL) < 0) -- GitLab From dd6dda27a8be563eaebb3f38b1d1d50920bb7991 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Mon, 2 Feb 2015 14:35:06 -0500 Subject: [PATCH 00075/11651] tools lib api fs: Add {tracefs,debugfs}_configured() functions Add tracefs_configured() to return true if tracefs is configured in the kernel (succeeds to find tracefs), and debugfs_configured() if debugfs is configured in the kernel (succeeds to find debugfs). Signed-off-by: Steven Rostedt Acked-by: Jiri Olsa Cc: Andrew Morton Cc: Ingo Molnar Cc: Masami Hiramatsu Cc: Namhyung Kim Link: http://lkml.kernel.org/r/20150202193553.190606690@goodmis.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/api/fs/debugfs.c | 8 ++++++++ tools/lib/api/fs/debugfs.h | 1 + tools/lib/api/fs/findfs.h | 2 ++ tools/lib/api/fs/tracefs.c | 8 ++++++++ tools/lib/api/fs/tracefs.h | 1 + 5 files changed, 20 insertions(+) diff --git a/tools/lib/api/fs/debugfs.c b/tools/lib/api/fs/debugfs.c index 07d74b03d828..8305b3e9d48e 100644 --- a/tools/lib/api/fs/debugfs.c +++ b/tools/lib/api/fs/debugfs.c @@ -3,8 +3,11 @@ #include #include #include +#include #include #include +#include +#include #include #include @@ -24,6 +27,11 @@ static const char * const debugfs_known_mountpoints[] = { static bool debugfs_found; +bool debugfs_configured(void) +{ + return debugfs_find_mountpoint() != NULL; +} + /* find the path to the mounted debugfs */ const char *debugfs_find_mountpoint(void) { diff --git a/tools/lib/api/fs/debugfs.h b/tools/lib/api/fs/debugfs.h index 1074ac81358e..455023698d2b 100644 --- a/tools/lib/api/fs/debugfs.h +++ b/tools/lib/api/fs/debugfs.h @@ -11,6 +11,7 @@ #define PERF_DEBUGFS_ENVIRONMENT "PERF_DEBUGFS_DIR" #endif +bool debugfs_configured(void); const char *debugfs_find_mountpoint(void); char *debugfs_mount(const char *mountpoint); diff --git a/tools/lib/api/fs/findfs.h b/tools/lib/api/fs/findfs.h index 9e7d876791e1..b6f5d05acc42 100644 --- a/tools/lib/api/fs/findfs.h +++ b/tools/lib/api/fs/findfs.h @@ -1,6 +1,8 @@ #ifndef __API_FINDFS_H__ #define __API_FINDFS_H__ +#include + #define _STR(x) #x #define STR(x) _STR(x) diff --git a/tools/lib/api/fs/tracefs.c b/tools/lib/api/fs/tracefs.c index ef40d15821e9..e4aa9688b71e 100644 --- a/tools/lib/api/fs/tracefs.c +++ b/tools/lib/api/fs/tracefs.c @@ -2,8 +2,11 @@ #include #include #include +#include #include #include +#include +#include #include #include @@ -25,6 +28,11 @@ static const char * const tracefs_known_mountpoints[] = { static bool tracefs_found; +bool tracefs_configured(void) +{ + return tracefs_find_mountpoint() != NULL; +} + /* find the path to the mounted tracefs */ const char *tracefs_find_mountpoint(void) { diff --git a/tools/lib/api/fs/tracefs.h b/tools/lib/api/fs/tracefs.h index e6f7f5183c87..da780ac49acb 100644 --- a/tools/lib/api/fs/tracefs.h +++ b/tools/lib/api/fs/tracefs.h @@ -11,6 +11,7 @@ #define PERF_TRACEFS_ENVIRONMENT "PERF_TRACEFS_DIR" #endif +bool tracefs_configured(void); const char *tracefs_find_mountpoint(void); int tracefs_valid_mountpoint(const char *debugfs); char *tracefs_mount(const char *mountpoint); -- GitLab From 802a3aef30917cc20279d17fe4d0e8568d5c7814 Mon Sep 17 00:00:00 2001 From: Octavian Purdila Date: Sat, 31 Jan 2015 02:00:03 +0200 Subject: [PATCH 00076/11651] iio: bmc150: refactor slope duration and threshold update Move the slope duration and threshold update in a separate function to reduce code duplicate between chip init and motion interrupt setup. Also move the slope update code from the interrupt setup function to the trigger set state function so that we can later refactor the interrupt code. Signed-off-by: Octavian Purdila Acked-by: Srinivas Pandruvada Signed-off-by: Jonathan Cameron --- drivers/iio/accel/bmc150-accel.c | 97 ++++++++++++++++---------------- 1 file changed, 47 insertions(+), 50 deletions(-) diff --git a/drivers/iio/accel/bmc150-accel.c b/drivers/iio/accel/bmc150-accel.c index 066d0c04072c..2b6b80d700e4 100644 --- a/drivers/iio/accel/bmc150-accel.c +++ b/drivers/iio/accel/bmc150-accel.c @@ -269,6 +269,37 @@ static int bmc150_accel_set_bw(struct bmc150_accel_data *data, int val, return -EINVAL; } +static int bmc150_accel_update_slope(struct bmc150_accel_data *data) +{ + int ret, val; + + ret = i2c_smbus_write_byte_data(data->client, BMC150_ACCEL_REG_INT_6, + data->slope_thres); + if (ret < 0) { + dev_err(&data->client->dev, "Error writing reg_int_6\n"); + return ret; + } + + ret = i2c_smbus_read_byte_data(data->client, BMC150_ACCEL_REG_INT_5); + if (ret < 0) { + dev_err(&data->client->dev, "Error reading reg_int_5\n"); + return ret; + } + + val = (ret & ~BMC150_ACCEL_SLOPE_DUR_MASK) | data->slope_dur; + ret = i2c_smbus_write_byte_data(data->client, BMC150_ACCEL_REG_INT_5, + val); + if (ret < 0) { + dev_err(&data->client->dev, "Error write reg_int_5\n"); + return ret; + } + + dev_dbg(&data->client->dev, "%s: %x %x\n", __func__, data->slope_thres, + data->slope_dur); + + return ret; +} + static int bmc150_accel_chip_init(struct bmc150_accel_data *data) { int ret; @@ -307,32 +338,12 @@ static int bmc150_accel_chip_init(struct bmc150_accel_data *data) data->range = BMC150_ACCEL_DEF_RANGE_4G; - /* Set default slope duration */ - ret = i2c_smbus_read_byte_data(data->client, BMC150_ACCEL_REG_INT_5); - if (ret < 0) { - dev_err(&data->client->dev, "Error reading reg_int_5\n"); - return ret; - } - data->slope_dur |= BMC150_ACCEL_DEF_SLOPE_DURATION; - ret = i2c_smbus_write_byte_data(data->client, - BMC150_ACCEL_REG_INT_5, - data->slope_dur); - if (ret < 0) { - dev_err(&data->client->dev, "Error writing reg_int_5\n"); - return ret; - } - dev_dbg(&data->client->dev, "slope_dur %x\n", data->slope_dur); - - /* Set default slope thresholds */ - ret = i2c_smbus_write_byte_data(data->client, - BMC150_ACCEL_REG_INT_6, - BMC150_ACCEL_DEF_SLOPE_THRESHOLD); - if (ret < 0) { - dev_err(&data->client->dev, "Error writing reg_int_6\n"); - return ret; - } + /* Set default slope duration and thresholds */ data->slope_thres = BMC150_ACCEL_DEF_SLOPE_THRESHOLD; - dev_dbg(&data->client->dev, "slope_thres %x\n", data->slope_thres); + data->slope_dur = BMC150_ACCEL_DEF_SLOPE_DURATION; + ret = bmc150_accel_update_slope(data); + if (ret < 0) + return ret; /* Set default as latched interrupts */ ret = i2c_smbus_write_byte_data(data->client, @@ -375,24 +386,6 @@ static int bmc150_accel_setup_any_motion_interrupt( } if (status) { - /* Set slope duration (no of samples) */ - ret = i2c_smbus_write_byte_data(data->client, - BMC150_ACCEL_REG_INT_5, - data->slope_dur); - if (ret < 0) { - dev_err(&data->client->dev, "Error write reg_int_5\n"); - return ret; - } - - /* Set slope thresholds */ - ret = i2c_smbus_write_byte_data(data->client, - BMC150_ACCEL_REG_INT_6, - data->slope_thres); - if (ret < 0) { - dev_err(&data->client->dev, "Error write reg_int_6\n"); - return ret; - } - /* * New data interrupt is always non-latched, * which will have higher priority, so no need @@ -732,7 +725,7 @@ static int bmc150_accel_read_event(struct iio_dev *indio_dev, *val = data->slope_thres; break; case IIO_EV_INFO_PERIOD: - *val = data->slope_dur & BMC150_ACCEL_SLOPE_DUR_MASK; + *val = data->slope_dur; break; default: return -EINVAL; @@ -755,11 +748,10 @@ static int bmc150_accel_write_event(struct iio_dev *indio_dev, switch (info) { case IIO_EV_INFO_VALUE: - data->slope_thres = val; + data->slope_thres = val & 0xFF; break; case IIO_EV_INFO_PERIOD: - data->slope_dur &= ~BMC150_ACCEL_SLOPE_DUR_MASK; - data->slope_dur |= val & BMC150_ACCEL_SLOPE_DUR_MASK; + data->slope_dur = val & BMC150_ACCEL_SLOPE_DUR_MASK; break; default: return -EINVAL; @@ -1056,10 +1048,15 @@ static int bmc150_accel_data_rdy_trigger_set_state(struct iio_trigger *trig, mutex_unlock(&data->mutex); return ret; } - if (data->motion_trig == trig) - ret = bmc150_accel_setup_any_motion_interrupt(data, state); - else + + if (data->motion_trig == trig) { + ret = bmc150_accel_update_slope(data); + if (!ret) + ret = bmc150_accel_setup_any_motion_interrupt(data, + state); + } else { ret = bmc150_accel_setup_new_data_interrupt(data, state); + } if (ret < 0) { bmc150_accel_set_power_state(data, false); mutex_unlock(&data->mutex); -- GitLab From 8e22f477e1432ace88b762f5f66e0f96631a1462 Mon Sep 17 00:00:00 2001 From: Octavian Purdila Date: Sat, 31 Jan 2015 02:00:04 +0200 Subject: [PATCH 00077/11651] iio: bmc150: refactor interrupt enabling This patch combines the any motion and new data interrupts function into a single, generic, interrupt enable function. On top of this, we can later refactor triggers to make it easier to add new triggers. Signed-off-by: Octavian Purdila Acked-by: Srinivas Pandruvada Signed-off-by: Jonathan Cameron --- drivers/iio/accel/bmc150-accel.c | 272 +++++++++++++------------------ 1 file changed, 113 insertions(+), 159 deletions(-) diff --git a/drivers/iio/accel/bmc150-accel.c b/drivers/iio/accel/bmc150-accel.c index 2b6b80d700e4..087392514e54 100644 --- a/drivers/iio/accel/bmc150-accel.c +++ b/drivers/iio/accel/bmc150-accel.c @@ -359,137 +359,6 @@ static int bmc150_accel_chip_init(struct bmc150_accel_data *data) return 0; } -static int bmc150_accel_setup_any_motion_interrupt( - struct bmc150_accel_data *data, - bool status) -{ - int ret; - - /* Enable/Disable INT1 mapping */ - ret = i2c_smbus_read_byte_data(data->client, - BMC150_ACCEL_REG_INT_MAP_0); - if (ret < 0) { - dev_err(&data->client->dev, "Error reading reg_int_map_0\n"); - return ret; - } - if (status) - ret |= BMC150_ACCEL_INT_MAP_0_BIT_SLOPE; - else - ret &= ~BMC150_ACCEL_INT_MAP_0_BIT_SLOPE; - - ret = i2c_smbus_write_byte_data(data->client, - BMC150_ACCEL_REG_INT_MAP_0, - ret); - if (ret < 0) { - dev_err(&data->client->dev, "Error writing reg_int_map_0\n"); - return ret; - } - - if (status) { - /* - * New data interrupt is always non-latched, - * which will have higher priority, so no need - * to set latched mode, we will be flooded anyway with INTR - */ - if (!data->dready_trigger_on) { - ret = i2c_smbus_write_byte_data(data->client, - BMC150_ACCEL_REG_INT_RST_LATCH, - BMC150_ACCEL_INT_MODE_LATCH_INT | - BMC150_ACCEL_INT_MODE_LATCH_RESET); - if (ret < 0) { - dev_err(&data->client->dev, - "Error writing reg_int_rst_latch\n"); - return ret; - } - } - - ret = i2c_smbus_write_byte_data(data->client, - BMC150_ACCEL_REG_INT_EN_0, - BMC150_ACCEL_INT_EN_BIT_SLP_X | - BMC150_ACCEL_INT_EN_BIT_SLP_Y | - BMC150_ACCEL_INT_EN_BIT_SLP_Z); - } else - ret = i2c_smbus_write_byte_data(data->client, - BMC150_ACCEL_REG_INT_EN_0, - 0); - - if (ret < 0) { - dev_err(&data->client->dev, "Error writing reg_int_en_0\n"); - return ret; - } - - return 0; -} - -static int bmc150_accel_setup_new_data_interrupt(struct bmc150_accel_data *data, - bool status) -{ - int ret; - - /* Enable/Disable INT1 mapping */ - ret = i2c_smbus_read_byte_data(data->client, - BMC150_ACCEL_REG_INT_MAP_1); - if (ret < 0) { - dev_err(&data->client->dev, "Error reading reg_int_map_1\n"); - return ret; - } - if (status) - ret |= BMC150_ACCEL_INT_MAP_1_BIT_DATA; - else - ret &= ~BMC150_ACCEL_INT_MAP_1_BIT_DATA; - - ret = i2c_smbus_write_byte_data(data->client, - BMC150_ACCEL_REG_INT_MAP_1, - ret); - if (ret < 0) { - dev_err(&data->client->dev, "Error writing reg_int_map_1\n"); - return ret; - } - - if (status) { - /* - * Set non latched mode interrupt and clear any latched - * interrupt - */ - ret = i2c_smbus_write_byte_data(data->client, - BMC150_ACCEL_REG_INT_RST_LATCH, - BMC150_ACCEL_INT_MODE_NON_LATCH_INT | - BMC150_ACCEL_INT_MODE_LATCH_RESET); - if (ret < 0) { - dev_err(&data->client->dev, - "Error writing reg_int_rst_latch\n"); - return ret; - } - - ret = i2c_smbus_write_byte_data(data->client, - BMC150_ACCEL_REG_INT_EN_1, - BMC150_ACCEL_INT_EN_BIT_DATA_EN); - - } else { - /* Restore default interrupt mode */ - ret = i2c_smbus_write_byte_data(data->client, - BMC150_ACCEL_REG_INT_RST_LATCH, - BMC150_ACCEL_INT_MODE_LATCH_INT | - BMC150_ACCEL_INT_MODE_LATCH_RESET); - if (ret < 0) { - dev_err(&data->client->dev, - "Error writing reg_int_rst_latch\n"); - return ret; - } - - ret = i2c_smbus_write_byte_data(data->client, - BMC150_ACCEL_REG_INT_EN_1, - 0); - } - - if (ret < 0) { - dev_err(&data->client->dev, "Error writing reg_int_en_1\n"); - return ret; - } - - return 0; -} - static int bmc150_accel_get_bw(struct bmc150_accel_data *data, int *val, int *val2) { @@ -547,6 +416,105 @@ static int bmc150_accel_set_power_state(struct bmc150_accel_data *data, bool on) } #endif +static const struct bmc150_accel_interrupt_info { + u8 map_reg; + u8 map_bitmask; + u8 en_reg; + u8 en_bitmask; +} bmc150_accel_interrupts[] = { + { /* data ready interrupt */ + .map_reg = BMC150_ACCEL_REG_INT_MAP_1, + .map_bitmask = BMC150_ACCEL_INT_MAP_1_BIT_DATA, + .en_reg = BMC150_ACCEL_REG_INT_EN_1, + .en_bitmask = BMC150_ACCEL_INT_EN_BIT_DATA_EN, + }, + { /* motion interrupt */ + .map_reg = BMC150_ACCEL_REG_INT_MAP_0, + .map_bitmask = BMC150_ACCEL_INT_MAP_0_BIT_SLOPE, + .en_reg = BMC150_ACCEL_REG_INT_EN_0, + .en_bitmask = BMC150_ACCEL_INT_EN_BIT_SLP_X | + BMC150_ACCEL_INT_EN_BIT_SLP_Y | + BMC150_ACCEL_INT_EN_BIT_SLP_Z + }, +}; + +static int bmc150_accel_set_interrupt(struct bmc150_accel_data *data, + const struct bmc150_accel_interrupt_info *info, + bool state) +{ + int ret; + + /* + * We will expect the enable and disable to do operation in + * in reverse order. This will happen here anyway as our + * resume operation uses sync mode runtime pm calls, the + * suspend operation will be delayed by autosuspend delay + * So the disable operation will still happen in reverse of + * enable operation. When runtime pm is disabled the mode + * is always on so sequence doesn't matter + */ + ret = bmc150_accel_set_power_state(data, state); + if (ret < 0) + return ret; + + /* map the interrupt to the appropriate pins */ + ret = i2c_smbus_read_byte_data(data->client, info->map_reg); + if (ret < 0) { + dev_err(&data->client->dev, "Error reading reg_int_map\n"); + goto out_fix_power_state; + } + if (state) + ret |= info->map_bitmask; + else + ret &= ~info->map_bitmask; + + ret = i2c_smbus_write_byte_data(data->client, info->map_reg, + ret); + if (ret < 0) { + dev_err(&data->client->dev, "Error writing reg_int_map\n"); + goto out_fix_power_state; + } + + /* enable/disable the interrupt */ + ret = i2c_smbus_read_byte_data(data->client, info->en_reg); + if (ret < 0) { + dev_err(&data->client->dev, "Error reading reg_int_en\n"); + goto out_fix_power_state; + } + + if (state) + ret |= info->en_bitmask; + else + ret &= ~info->en_bitmask; + + ret = i2c_smbus_write_byte_data(data->client, info->en_reg, ret); + if (ret < 0) { + dev_err(&data->client->dev, "Error writing reg_int_en\n"); + goto out_fix_power_state; + } + + return 0; + +out_fix_power_state: + bmc150_accel_set_power_state(data, false); + return ret; +} + +static int bmc150_accel_setup_any_motion_interrupt( + struct bmc150_accel_data *data, + bool status) +{ + return bmc150_accel_set_interrupt(data, &bmc150_accel_interrupts[1], + status); +} + +static int bmc150_accel_setup_new_data_interrupt(struct bmc150_accel_data *data, + bool status) +{ + return bmc150_accel_set_interrupt(data, &bmc150_accel_interrupts[0], + status); +} + static int bmc150_accel_set_scale(struct bmc150_accel_data *data, int val) { int ret, i; @@ -791,25 +759,8 @@ static int bmc150_accel_write_event_config(struct iio_dev *indio_dev, return 0; } - /* - * We will expect the enable and disable to do operation in - * in reverse order. This will happen here anyway as our - * resume operation uses sync mode runtime pm calls, the - * suspend operation will be delayed by autosuspend delay - * So the disable operation will still happen in reverse of - * enable operation. When runtime pm is disabled the mode - * is always on so sequence doesn't matter - */ - - ret = bmc150_accel_set_power_state(data, state); - if (ret < 0) { - mutex_unlock(&data->mutex); - return ret; - } - ret = bmc150_accel_setup_any_motion_interrupt(data, state); if (ret < 0) { - bmc150_accel_set_power_state(data, false); mutex_unlock(&data->mutex); return ret; } @@ -1039,16 +990,6 @@ static int bmc150_accel_data_rdy_trigger_set_state(struct iio_trigger *trig, return 0; } - /* - * Refer to comment in bmc150_accel_write_event_config for - * enable/disable operation order - */ - ret = bmc150_accel_set_power_state(data, state); - if (ret < 0) { - mutex_unlock(&data->mutex); - return ret; - } - if (data->motion_trig == trig) { ret = bmc150_accel_update_slope(data); if (!ret) @@ -1058,7 +999,6 @@ static int bmc150_accel_data_rdy_trigger_set_state(struct iio_trigger *trig, ret = bmc150_accel_setup_new_data_interrupt(data, state); } if (ret < 0) { - bmc150_accel_set_power_state(data, false); mutex_unlock(&data->mutex); return ret; } @@ -1244,6 +1184,20 @@ static int bmc150_accel_probe(struct i2c_client *client, if (ret) return ret; + /* + * Set latched mode interrupt. While certain interrupts are + * non-latched regardless of this settings (e.g. new data) we + * want to use latch mode when we can to prevent interrupt + * flooding. + */ + ret = i2c_smbus_write_byte_data(data->client, + BMC150_ACCEL_REG_INT_RST_LATCH, + BMC150_ACCEL_INT_MODE_LATCH_RESET); + if (ret < 0) { + dev_err(&data->client->dev, "Error writing reg_int_rst_latch\n"); + return ret; + } + data->dready_trig = devm_iio_trigger_alloc(&client->dev, "%s-dev%d", indio_dev->name, -- GitLab From 14ee64f438b8e85d1c78939d301956d9a775cc9a Mon Sep 17 00:00:00 2001 From: Octavian Purdila Date: Sat, 31 Jan 2015 02:00:05 +0200 Subject: [PATCH 00078/11651] iio: bmc150: exit early if event / trigger state is not changed Previous of this patch the check was only done if we enabled the event and it was already enabled. We can do the same if the event is disabled and we want to disable it. The patch also adds the same check on the trigger code. Signed-off-by: Octavian Purdila Acked-by: Srinivas Pandruvada Signed-off-by: Jonathan Cameron --- drivers/iio/accel/bmc150-accel.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/iio/accel/bmc150-accel.c b/drivers/iio/accel/bmc150-accel.c index 087392514e54..f040f405d826 100644 --- a/drivers/iio/accel/bmc150-accel.c +++ b/drivers/iio/accel/bmc150-accel.c @@ -748,7 +748,7 @@ static int bmc150_accel_write_event_config(struct iio_dev *indio_dev, struct bmc150_accel_data *data = iio_priv(indio_dev); int ret; - if (state && data->ev_enable_state) + if (state == data->ev_enable_state) return 0; mutex_lock(&data->mutex); @@ -984,6 +984,18 @@ static int bmc150_accel_data_rdy_trigger_set_state(struct iio_trigger *trig, mutex_lock(&data->mutex); + if (data->motion_trig == trig) { + if (data->motion_trigger_on == state) { + mutex_unlock(&data->mutex); + return 0; + } + } else { + if (data->dready_trigger_on == state) { + mutex_unlock(&data->mutex); + return 0; + } + } + if (!state && data->ev_enable_state && data->motion_trigger_on) { data->motion_trigger_on = false; mutex_unlock(&data->mutex); -- GitLab From 98a3d2e1d57611840b0c252e718f1fc7fb32b381 Mon Sep 17 00:00:00 2001 From: Tolga Ceylan Date: Sun, 8 Feb 2015 00:04:53 -0800 Subject: [PATCH 00079/11651] Staging:iio:hmc5843:Coding Style Correction Indentation corrections in struct initializations and one line over 80 characters split into two lines Signed-off-by: Tolga Ceylan Signed-off-by: Jonathan Cameron --- .../staging/iio/magnetometer/hmc5843_i2c.c | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/staging/iio/magnetometer/hmc5843_i2c.c b/drivers/staging/iio/magnetometer/hmc5843_i2c.c index 6acd614cdbc6..e221a58a7673 100644 --- a/drivers/staging/iio/magnetometer/hmc5843_i2c.c +++ b/drivers/staging/iio/magnetometer/hmc5843_i2c.c @@ -19,49 +19,49 @@ #include "hmc5843.h" static const struct regmap_range hmc5843_readable_ranges[] = { - regmap_reg_range(0, HMC5843_ID_END), + regmap_reg_range(0, HMC5843_ID_END), }; static struct regmap_access_table hmc5843_readable_table = { - .yes_ranges = hmc5843_readable_ranges, - .n_yes_ranges = ARRAY_SIZE(hmc5843_readable_ranges), + .yes_ranges = hmc5843_readable_ranges, + .n_yes_ranges = ARRAY_SIZE(hmc5843_readable_ranges), }; static const struct regmap_range hmc5843_writable_ranges[] = { - regmap_reg_range(0, HMC5843_MODE_REG), + regmap_reg_range(0, HMC5843_MODE_REG), }; static struct regmap_access_table hmc5843_writable_table = { - .yes_ranges = hmc5843_writable_ranges, - .n_yes_ranges = ARRAY_SIZE(hmc5843_writable_ranges), + .yes_ranges = hmc5843_writable_ranges, + .n_yes_ranges = ARRAY_SIZE(hmc5843_writable_ranges), }; static const struct regmap_range hmc5843_volatile_ranges[] = { - regmap_reg_range(HMC5843_DATA_OUT_MSB_REGS, HMC5843_STATUS_REG), + regmap_reg_range(HMC5843_DATA_OUT_MSB_REGS, HMC5843_STATUS_REG), }; static struct regmap_access_table hmc5843_volatile_table = { - .yes_ranges = hmc5843_volatile_ranges, - .n_yes_ranges = ARRAY_SIZE(hmc5843_volatile_ranges), + .yes_ranges = hmc5843_volatile_ranges, + .n_yes_ranges = ARRAY_SIZE(hmc5843_volatile_ranges), }; static struct regmap_config hmc5843_i2c_regmap_config = { - .reg_bits = 8, - .val_bits = 8, + .reg_bits = 8, + .val_bits = 8, - .rd_table = &hmc5843_readable_table, - .wr_table = &hmc5843_writable_table, - .volatile_table = &hmc5843_volatile_table, + .rd_table = &hmc5843_readable_table, + .wr_table = &hmc5843_writable_table, + .volatile_table = &hmc5843_volatile_table, - .cache_type = REGCACHE_RBTREE, + .cache_type = REGCACHE_RBTREE, }; static int hmc5843_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { return hmc5843_common_probe(&client->dev, - devm_regmap_init_i2c(client, &hmc5843_i2c_regmap_config), - id->driver_data); + devm_regmap_init_i2c(client, &hmc5843_i2c_regmap_config), + id->driver_data); } static int hmc5843_i2c_remove(struct i2c_client *client) -- GitLab From c726aadd731de7b3cd2a0c2ceb2cc5ce9745c5ad Mon Sep 17 00:00:00 2001 From: Tolga Ceylan Date: Sat, 7 Feb 2015 23:40:33 -0800 Subject: [PATCH 00080/11651] Staging:iio:ade7854 Coding style correction Line over 80 characters corrected Signed-off-by: Tolga Ceylan Signed-off-by: Jonathan Cameron --- drivers/staging/iio/meter/ade7854-i2c.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/iio/meter/ade7854-i2c.c b/drivers/staging/iio/meter/ade7854-i2c.c index 5b33c7f1aa91..5d0671a198fe 100644 --- a/drivers/staging/iio/meter/ade7854-i2c.c +++ b/drivers/staging/iio/meter/ade7854-i2c.c @@ -195,7 +195,8 @@ static int ade7854_i2c_read_reg_32(struct device *dev, if (ret) goto out; - *val = (st->rx[0] << 24) | (st->rx[1] << 16) | (st->rx[2] << 8) | st->rx[3]; + *val = (st->rx[0] << 24) | (st->rx[1] << 16) | + (st->rx[2] << 8) | st->rx[3]; out: mutex_unlock(&st->buf_lock); return ret; -- GitLab From 31a3dda6489dd68552e1e6af56abcf65405d6b5c Mon Sep 17 00:00:00 2001 From: Rickard Strandqvist Date: Tue, 27 Jan 2015 23:22:34 +0100 Subject: [PATCH 00081/11651] staging: iio: resolver: ad2s1210: Change type in printf format string Wrong type in printf format string, requires 'int' but the argument type is 'unsigned int' This was found using a static code analysis program called cppcheck Signed-off-by: Rickard Strandqvist Signed-off-by: Jonathan Cameron --- drivers/staging/iio/resolver/ad2s1210.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c index b4c14ba5fdee..a8ecf87ef4a9 100644 --- a/drivers/staging/iio/resolver/ad2s1210.c +++ b/drivers/staging/iio/resolver/ad2s1210.c @@ -198,7 +198,7 @@ static ssize_t ad2s1210_show_fclkin(struct device *dev, { struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev)); - return sprintf(buf, "%d\n", st->fclkin); + return sprintf(buf, "%u\n", st->fclkin); } static ssize_t ad2s1210_store_fclkin(struct device *dev, @@ -237,7 +237,7 @@ static ssize_t ad2s1210_show_fexcit(struct device *dev, { struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev)); - return sprintf(buf, "%d\n", st->fexcit); + return sprintf(buf, "%u\n", st->fexcit); } static ssize_t ad2s1210_store_fexcit(struct device *dev, -- GitLab From e257a16e680a27ddc3dcbfc9fd39ad7f9d7ea135 Mon Sep 17 00:00:00 2001 From: Rickard Strandqvist Date: Tue, 27 Jan 2015 23:23:33 +0100 Subject: [PATCH 00082/11651] staging: iio: adc: mxs-lradc: Change type in printf format string Wrong type in printf format string, requires 'int' but the argument type is 'unsigned int' This was found using a static code analysis program called cppcheck Signed-off-by: Rickard Strandqvist Reviewed-by: Marek Vasut Signed-off-by: Jonathan Cameron --- drivers/staging/iio/adc/mxs-lradc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/iio/adc/mxs-lradc.c b/drivers/staging/iio/adc/mxs-lradc.c index d9d6fad7cb00..d5f8ea96f4bc 100644 --- a/drivers/staging/iio/adc/mxs-lradc.c +++ b/drivers/staging/iio/adc/mxs-lradc.c @@ -1008,7 +1008,7 @@ static ssize_t mxs_lradc_show_scale_available_ch(struct device *dev, int i, len = 0; for (i = 0; i < ARRAY_SIZE(lradc->scale_avail[ch]); i++) - len += sprintf(buf + len, "%d.%09u ", + len += sprintf(buf + len, "%u.%09u ", lradc->scale_avail[ch][i].integer, lradc->scale_avail[ch][i].nano); -- GitLab From dd3733b3e798daf778a1ec08557f388f00fdc2f6 Mon Sep 17 00:00:00 2001 From: Alexey Andriyanov Date: Fri, 6 Feb 2015 22:32:20 +0300 Subject: [PATCH 00083/11651] ipvs: fix inability to remove a mixed-family RS The current code prevents any operation with a mixed-family dest unless IP_VS_CONN_F_TUNNEL flag is set. The problem is that it's impossible for the client to follow this rule, because ip_vs_genl_parse_dest does not even read the destination conn_flags when cmd = IPVS_CMD_DEL_DEST (need_full_dest = 0). Also, not every client can pass this flag when removing a dest. ipvsadm, for example, does not support the "-i" command line option together with the "-d" option. This change disables any checks for mixed-family on IPVS_CMD_DEL_DEST command. Signed-off-by: Alexey Andriyanov Fixes: bc18d37f676f ("ipvs: Allow heterogeneous pools now that we support them") Acked-by: Julian Anastasov Signed-off-by: Simon Horman --- net/netfilter/ipvs/ip_vs_ctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index b8295a430a56..fdcda8be1f0f 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c @@ -3399,7 +3399,7 @@ static int ip_vs_genl_set_cmd(struct sk_buff *skb, struct genl_info *info) if (udest.af == 0) udest.af = svc->af; - if (udest.af != svc->af) { + if (udest.af != svc->af && cmd != IPVS_CMD_DEL_DEST) { /* The synchronization protocol is incompatible * with mixed family services */ -- GitLab From cd67cd5eb25ae9a7bafbfd3d52d4c05e1d80af3b Mon Sep 17 00:00:00 2001 From: Julian Anastasov Date: Fri, 6 Feb 2015 09:44:44 +0200 Subject: [PATCH 00084/11651] ipvs: use 64-bit rates in stats IPVS stats are limited to 2^(32-10) conns/s and packets/s, 2^(32-5) bytes/s. It is time to use 64 bits: * Change all conn/packet kernel counters to 64-bit and update them in u64_stats_update_{begin,end} section * In kernel use struct ip_vs_kstats instead of the user-space struct ip_vs_stats_user and use new func ip_vs_export_stats_user to export it to sockopt users to preserve compatibility with 32-bit values * Rename cpu counters "ustats" to "cnt" * To netlink users provide additionally 64-bit stats: IPVS_SVC_ATTR_STATS64 and IPVS_DEST_ATTR_STATS64. Old stats remain for old binaries. * We can use ip_vs_copy_stats in ip_vs_stats_percpu_show Thanks to Chris Caputo for providing initial patch for ip_vs_est.c Signed-off-by: Chris Caputo Signed-off-by: Julian Anastasov Signed-off-by: Simon Horman --- include/net/ip_vs.h | 50 +++++---- include/uapi/linux/ip_vs.h | 7 +- net/netfilter/ipvs/ip_vs_core.c | 36 ++++--- net/netfilter/ipvs/ip_vs_ctl.c | 174 +++++++++++++++++++++----------- net/netfilter/ipvs/ip_vs_est.c | 102 +++++++++---------- 5 files changed, 226 insertions(+), 143 deletions(-) diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h index 615b20b58545..a627fe690c19 100644 --- a/include/net/ip_vs.h +++ b/include/net/ip_vs.h @@ -365,15 +365,15 @@ struct ip_vs_seq { /* counters per cpu */ struct ip_vs_counters { - __u32 conns; /* connections scheduled */ - __u32 inpkts; /* incoming packets */ - __u32 outpkts; /* outgoing packets */ + __u64 conns; /* connections scheduled */ + __u64 inpkts; /* incoming packets */ + __u64 outpkts; /* outgoing packets */ __u64 inbytes; /* incoming bytes */ __u64 outbytes; /* outgoing bytes */ }; /* Stats per cpu */ struct ip_vs_cpu_stats { - struct ip_vs_counters ustats; + struct ip_vs_counters cnt; struct u64_stats_sync syncp; }; @@ -383,23 +383,40 @@ struct ip_vs_estimator { u64 last_inbytes; u64 last_outbytes; - u32 last_conns; - u32 last_inpkts; - u32 last_outpkts; - - u32 cps; - u32 inpps; - u32 outpps; - u32 inbps; - u32 outbps; + u64 last_conns; + u64 last_inpkts; + u64 last_outpkts; + + u64 cps; + u64 inpps; + u64 outpps; + u64 inbps; + u64 outbps; +}; + +/* + * IPVS statistics object, 64-bit kernel version of struct ip_vs_stats_user + */ +struct ip_vs_kstats { + u64 conns; /* connections scheduled */ + u64 inpkts; /* incoming packets */ + u64 outpkts; /* outgoing packets */ + u64 inbytes; /* incoming bytes */ + u64 outbytes; /* outgoing bytes */ + + u64 cps; /* current connection rate */ + u64 inpps; /* current in packet rate */ + u64 outpps; /* current out packet rate */ + u64 inbps; /* current in byte rate */ + u64 outbps; /* current out byte rate */ }; struct ip_vs_stats { - struct ip_vs_stats_user ustats; /* statistics */ + struct ip_vs_kstats kstats; /* kernel statistics */ struct ip_vs_estimator est; /* estimator */ struct ip_vs_cpu_stats __percpu *cpustats; /* per cpu counters */ spinlock_t lock; /* spin lock */ - struct ip_vs_stats_user ustats0; /* reset values */ + struct ip_vs_kstats kstats0; /* reset values */ }; struct dst_entry; @@ -1388,8 +1405,7 @@ void ip_vs_sync_conn(struct net *net, struct ip_vs_conn *cp, int pkts); void ip_vs_start_estimator(struct net *net, struct ip_vs_stats *stats); void ip_vs_stop_estimator(struct net *net, struct ip_vs_stats *stats); void ip_vs_zero_estimator(struct ip_vs_stats *stats); -void ip_vs_read_estimator(struct ip_vs_stats_user *dst, - struct ip_vs_stats *stats); +void ip_vs_read_estimator(struct ip_vs_kstats *dst, struct ip_vs_stats *stats); /* Various IPVS packet transmitters (from ip_vs_xmit.c) */ int ip_vs_null_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, diff --git a/include/uapi/linux/ip_vs.h b/include/uapi/linux/ip_vs.h index cabe95d5b461..3199243f2028 100644 --- a/include/uapi/linux/ip_vs.h +++ b/include/uapi/linux/ip_vs.h @@ -358,6 +358,8 @@ enum { IPVS_SVC_ATTR_PE_NAME, /* name of ct retriever */ + IPVS_SVC_ATTR_STATS64, /* nested attribute for service stats */ + __IPVS_SVC_ATTR_MAX, }; @@ -387,6 +389,8 @@ enum { IPVS_DEST_ATTR_ADDR_FAMILY, /* Address family of address */ + IPVS_DEST_ATTR_STATS64, /* nested attribute for dest stats */ + __IPVS_DEST_ATTR_MAX, }; @@ -410,7 +414,8 @@ enum { /* * Attributes used to describe service or destination entry statistics * - * Used inside nested attributes IPVS_SVC_ATTR_STATS and IPVS_DEST_ATTR_STATS + * Used inside nested attributes IPVS_SVC_ATTR_STATS, IPVS_DEST_ATTR_STATS, + * IPVS_SVC_ATTR_STATS64 and IPVS_DEST_ATTR_STATS64. */ enum { IPVS_STATS_ATTR_UNSPEC = 0, diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c index 990decba1fe4..c9470c86308f 100644 --- a/net/netfilter/ipvs/ip_vs_core.c +++ b/net/netfilter/ipvs/ip_vs_core.c @@ -119,24 +119,24 @@ ip_vs_in_stats(struct ip_vs_conn *cp, struct sk_buff *skb) struct ip_vs_service *svc; s = this_cpu_ptr(dest->stats.cpustats); - s->ustats.inpkts++; u64_stats_update_begin(&s->syncp); - s->ustats.inbytes += skb->len; + s->cnt.inpkts++; + s->cnt.inbytes += skb->len; u64_stats_update_end(&s->syncp); rcu_read_lock(); svc = rcu_dereference(dest->svc); s = this_cpu_ptr(svc->stats.cpustats); - s->ustats.inpkts++; u64_stats_update_begin(&s->syncp); - s->ustats.inbytes += skb->len; + s->cnt.inpkts++; + s->cnt.inbytes += skb->len; u64_stats_update_end(&s->syncp); rcu_read_unlock(); s = this_cpu_ptr(ipvs->tot_stats.cpustats); - s->ustats.inpkts++; u64_stats_update_begin(&s->syncp); - s->ustats.inbytes += skb->len; + s->cnt.inpkts++; + s->cnt.inbytes += skb->len; u64_stats_update_end(&s->syncp); } } @@ -153,24 +153,24 @@ ip_vs_out_stats(struct ip_vs_conn *cp, struct sk_buff *skb) struct ip_vs_service *svc; s = this_cpu_ptr(dest->stats.cpustats); - s->ustats.outpkts++; u64_stats_update_begin(&s->syncp); - s->ustats.outbytes += skb->len; + s->cnt.outpkts++; + s->cnt.outbytes += skb->len; u64_stats_update_end(&s->syncp); rcu_read_lock(); svc = rcu_dereference(dest->svc); s = this_cpu_ptr(svc->stats.cpustats); - s->ustats.outpkts++; u64_stats_update_begin(&s->syncp); - s->ustats.outbytes += skb->len; + s->cnt.outpkts++; + s->cnt.outbytes += skb->len; u64_stats_update_end(&s->syncp); rcu_read_unlock(); s = this_cpu_ptr(ipvs->tot_stats.cpustats); - s->ustats.outpkts++; u64_stats_update_begin(&s->syncp); - s->ustats.outbytes += skb->len; + s->cnt.outpkts++; + s->cnt.outbytes += skb->len; u64_stats_update_end(&s->syncp); } } @@ -183,13 +183,19 @@ ip_vs_conn_stats(struct ip_vs_conn *cp, struct ip_vs_service *svc) struct ip_vs_cpu_stats *s; s = this_cpu_ptr(cp->dest->stats.cpustats); - s->ustats.conns++; + u64_stats_update_begin(&s->syncp); + s->cnt.conns++; + u64_stats_update_end(&s->syncp); s = this_cpu_ptr(svc->stats.cpustats); - s->ustats.conns++; + u64_stats_update_begin(&s->syncp); + s->cnt.conns++; + u64_stats_update_end(&s->syncp); s = this_cpu_ptr(ipvs->tot_stats.cpustats); - s->ustats.conns++; + u64_stats_update_begin(&s->syncp); + s->cnt.conns++; + u64_stats_update_end(&s->syncp); } diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index e55759056361..6fd60059faf0 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c @@ -729,9 +729,9 @@ static void ip_vs_trash_cleanup(struct net *net) } static void -ip_vs_copy_stats(struct ip_vs_stats_user *dst, struct ip_vs_stats *src) +ip_vs_copy_stats(struct ip_vs_kstats *dst, struct ip_vs_stats *src) { -#define IP_VS_SHOW_STATS_COUNTER(c) dst->c = src->ustats.c - src->ustats0.c +#define IP_VS_SHOW_STATS_COUNTER(c) dst->c = src->kstats.c - src->kstats0.c spin_lock_bh(&src->lock); @@ -746,6 +746,21 @@ ip_vs_copy_stats(struct ip_vs_stats_user *dst, struct ip_vs_stats *src) spin_unlock_bh(&src->lock); } +static void +ip_vs_export_stats_user(struct ip_vs_stats_user *dst, struct ip_vs_kstats *src) +{ + dst->conns = (u32)src->conns; + dst->inpkts = (u32)src->inpkts; + dst->outpkts = (u32)src->outpkts; + dst->inbytes = src->inbytes; + dst->outbytes = src->outbytes; + dst->cps = (u32)src->cps; + dst->inpps = (u32)src->inpps; + dst->outpps = (u32)src->outpps; + dst->inbps = (u32)src->inbps; + dst->outbps = (u32)src->outbps; +} + static void ip_vs_zero_stats(struct ip_vs_stats *stats) { @@ -753,7 +768,7 @@ ip_vs_zero_stats(struct ip_vs_stats *stats) /* get current counters as zero point, rates are zeroed */ -#define IP_VS_ZERO_STATS_COUNTER(c) stats->ustats0.c = stats->ustats.c +#define IP_VS_ZERO_STATS_COUNTER(c) stats->kstats0.c = stats->kstats.c IP_VS_ZERO_STATS_COUNTER(conns); IP_VS_ZERO_STATS_COUNTER(inpkts); @@ -2044,7 +2059,7 @@ static const struct file_operations ip_vs_info_fops = { static int ip_vs_stats_show(struct seq_file *seq, void *v) { struct net *net = seq_file_single_net(seq); - struct ip_vs_stats_user show; + struct ip_vs_kstats show; /* 01234567 01234567 01234567 0123456701234567 0123456701234567 */ seq_puts(seq, @@ -2053,17 +2068,22 @@ static int ip_vs_stats_show(struct seq_file *seq, void *v) " Conns Packets Packets Bytes Bytes\n"); ip_vs_copy_stats(&show, &net_ipvs(net)->tot_stats); - seq_printf(seq, "%8X %8X %8X %16LX %16LX\n\n", show.conns, - show.inpkts, show.outpkts, - (unsigned long long) show.inbytes, - (unsigned long long) show.outbytes); - -/* 01234567 01234567 01234567 0123456701234567 0123456701234567 */ + seq_printf(seq, "%8LX %8LX %8LX %16LX %16LX\n\n", + (unsigned long long)show.conns, + (unsigned long long)show.inpkts, + (unsigned long long)show.outpkts, + (unsigned long long)show.inbytes, + (unsigned long long)show.outbytes); + +/* 01234567 01234567 01234567 0123456701234567 0123456701234567*/ seq_puts(seq, - " Conns/s Pkts/s Pkts/s Bytes/s Bytes/s\n"); - seq_printf(seq, "%8X %8X %8X %16X %16X\n", - show.cps, show.inpps, show.outpps, - show.inbps, show.outbps); + " Conns/s Pkts/s Pkts/s Bytes/s Bytes/s\n"); + seq_printf(seq, "%8LX %8LX %8LX %16LX %16LX\n", + (unsigned long long)show.cps, + (unsigned long long)show.inpps, + (unsigned long long)show.outpps, + (unsigned long long)show.inbps, + (unsigned long long)show.outbps); return 0; } @@ -2086,7 +2106,7 @@ static int ip_vs_stats_percpu_show(struct seq_file *seq, void *v) struct net *net = seq_file_single_net(seq); struct ip_vs_stats *tot_stats = &net_ipvs(net)->tot_stats; struct ip_vs_cpu_stats __percpu *cpustats = tot_stats->cpustats; - struct ip_vs_stats_user rates; + struct ip_vs_kstats kstats; int i; /* 01234567 01234567 01234567 0123456701234567 0123456701234567 */ @@ -2098,41 +2118,41 @@ static int ip_vs_stats_percpu_show(struct seq_file *seq, void *v) for_each_possible_cpu(i) { struct ip_vs_cpu_stats *u = per_cpu_ptr(cpustats, i); unsigned int start; - __u64 inbytes, outbytes; + u64 conns, inpkts, outpkts, inbytes, outbytes; do { start = u64_stats_fetch_begin_irq(&u->syncp); - inbytes = u->ustats.inbytes; - outbytes = u->ustats.outbytes; + conns = u->cnt.conns; + inpkts = u->cnt.inpkts; + outpkts = u->cnt.outpkts; + inbytes = u->cnt.inbytes; + outbytes = u->cnt.outbytes; } while (u64_stats_fetch_retry_irq(&u->syncp, start)); - seq_printf(seq, "%3X %8X %8X %8X %16LX %16LX\n", - i, u->ustats.conns, u->ustats.inpkts, - u->ustats.outpkts, (__u64)inbytes, - (__u64)outbytes); + seq_printf(seq, "%3X %8LX %8LX %8LX %16LX %16LX\n", + i, (u64)conns, (u64)inpkts, + (u64)outpkts, (u64)inbytes, + (u64)outbytes); } - spin_lock_bh(&tot_stats->lock); - - seq_printf(seq, " ~ %8X %8X %8X %16LX %16LX\n\n", - tot_stats->ustats.conns, tot_stats->ustats.inpkts, - tot_stats->ustats.outpkts, - (unsigned long long) tot_stats->ustats.inbytes, - (unsigned long long) tot_stats->ustats.outbytes); - - ip_vs_read_estimator(&rates, tot_stats); + ip_vs_copy_stats(&kstats, tot_stats); - spin_unlock_bh(&tot_stats->lock); + seq_printf(seq, " ~ %8LX %8LX %8LX %16LX %16LX\n\n", + (unsigned long long)kstats.conns, + (unsigned long long)kstats.inpkts, + (unsigned long long)kstats.outpkts, + (unsigned long long)kstats.inbytes, + (unsigned long long)kstats.outbytes); -/* 01234567 01234567 01234567 0123456701234567 0123456701234567 */ +/* ... 01234567 01234567 01234567 0123456701234567 0123456701234567 */ seq_puts(seq, - " Conns/s Pkts/s Pkts/s Bytes/s Bytes/s\n"); - seq_printf(seq, " %8X %8X %8X %16X %16X\n", - rates.cps, - rates.inpps, - rates.outpps, - rates.inbps, - rates.outbps); + " Conns/s Pkts/s Pkts/s Bytes/s Bytes/s\n"); + seq_printf(seq, " %8LX %8LX %8LX %16LX %16LX\n", + kstats.cps, + kstats.inpps, + kstats.outpps, + kstats.inbps, + kstats.outbps); return 0; } @@ -2400,6 +2420,7 @@ static void ip_vs_copy_service(struct ip_vs_service_entry *dst, struct ip_vs_service *src) { struct ip_vs_scheduler *sched; + struct ip_vs_kstats kstats; sched = rcu_dereference_protected(src->scheduler, 1); dst->protocol = src->protocol; @@ -2411,7 +2432,8 @@ ip_vs_copy_service(struct ip_vs_service_entry *dst, struct ip_vs_service *src) dst->timeout = src->timeout / HZ; dst->netmask = src->netmask; dst->num_dests = src->num_dests; - ip_vs_copy_stats(&dst->stats, &src->stats); + ip_vs_copy_stats(&kstats, &src->stats); + ip_vs_export_stats_user(&dst->stats, &kstats); } static inline int @@ -2485,6 +2507,7 @@ __ip_vs_get_dest_entries(struct net *net, const struct ip_vs_get_dests *get, int count = 0; struct ip_vs_dest *dest; struct ip_vs_dest_entry entry; + struct ip_vs_kstats kstats; memset(&entry, 0, sizeof(entry)); list_for_each_entry(dest, &svc->destinations, n_list) { @@ -2506,7 +2529,8 @@ __ip_vs_get_dest_entries(struct net *net, const struct ip_vs_get_dests *get, entry.activeconns = atomic_read(&dest->activeconns); entry.inactconns = atomic_read(&dest->inactconns); entry.persistconns = atomic_read(&dest->persistconns); - ip_vs_copy_stats(&entry.stats, &dest->stats); + ip_vs_copy_stats(&kstats, &dest->stats); + ip_vs_export_stats_user(&entry.stats, &kstats); if (copy_to_user(&uptr->entrytable[count], &entry, sizeof(entry))) { ret = -EFAULT; @@ -2798,25 +2822,51 @@ static const struct nla_policy ip_vs_dest_policy[IPVS_DEST_ATTR_MAX + 1] = { }; static int ip_vs_genl_fill_stats(struct sk_buff *skb, int container_type, - struct ip_vs_stats *stats) + struct ip_vs_kstats *kstats) +{ + struct nlattr *nl_stats = nla_nest_start(skb, container_type); + + if (!nl_stats) + return -EMSGSIZE; + + if (nla_put_u32(skb, IPVS_STATS_ATTR_CONNS, (u32)kstats->conns) || + nla_put_u32(skb, IPVS_STATS_ATTR_INPKTS, (u32)kstats->inpkts) || + nla_put_u32(skb, IPVS_STATS_ATTR_OUTPKTS, (u32)kstats->outpkts) || + nla_put_u64(skb, IPVS_STATS_ATTR_INBYTES, kstats->inbytes) || + nla_put_u64(skb, IPVS_STATS_ATTR_OUTBYTES, kstats->outbytes) || + nla_put_u32(skb, IPVS_STATS_ATTR_CPS, (u32)kstats->cps) || + nla_put_u32(skb, IPVS_STATS_ATTR_INPPS, (u32)kstats->inpps) || + nla_put_u32(skb, IPVS_STATS_ATTR_OUTPPS, (u32)kstats->outpps) || + nla_put_u32(skb, IPVS_STATS_ATTR_INBPS, (u32)kstats->inbps) || + nla_put_u32(skb, IPVS_STATS_ATTR_OUTBPS, (u32)kstats->outbps)) + goto nla_put_failure; + nla_nest_end(skb, nl_stats); + + return 0; + +nla_put_failure: + nla_nest_cancel(skb, nl_stats); + return -EMSGSIZE; +} + +static int ip_vs_genl_fill_stats64(struct sk_buff *skb, int container_type, + struct ip_vs_kstats *kstats) { - struct ip_vs_stats_user ustats; struct nlattr *nl_stats = nla_nest_start(skb, container_type); + if (!nl_stats) return -EMSGSIZE; - ip_vs_copy_stats(&ustats, stats); - - if (nla_put_u32(skb, IPVS_STATS_ATTR_CONNS, ustats.conns) || - nla_put_u32(skb, IPVS_STATS_ATTR_INPKTS, ustats.inpkts) || - nla_put_u32(skb, IPVS_STATS_ATTR_OUTPKTS, ustats.outpkts) || - nla_put_u64(skb, IPVS_STATS_ATTR_INBYTES, ustats.inbytes) || - nla_put_u64(skb, IPVS_STATS_ATTR_OUTBYTES, ustats.outbytes) || - nla_put_u32(skb, IPVS_STATS_ATTR_CPS, ustats.cps) || - nla_put_u32(skb, IPVS_STATS_ATTR_INPPS, ustats.inpps) || - nla_put_u32(skb, IPVS_STATS_ATTR_OUTPPS, ustats.outpps) || - nla_put_u32(skb, IPVS_STATS_ATTR_INBPS, ustats.inbps) || - nla_put_u32(skb, IPVS_STATS_ATTR_OUTBPS, ustats.outbps)) + if (nla_put_u64(skb, IPVS_STATS_ATTR_CONNS, kstats->conns) || + nla_put_u64(skb, IPVS_STATS_ATTR_INPKTS, kstats->inpkts) || + nla_put_u64(skb, IPVS_STATS_ATTR_OUTPKTS, kstats->outpkts) || + nla_put_u64(skb, IPVS_STATS_ATTR_INBYTES, kstats->inbytes) || + nla_put_u64(skb, IPVS_STATS_ATTR_OUTBYTES, kstats->outbytes) || + nla_put_u64(skb, IPVS_STATS_ATTR_CPS, kstats->cps) || + nla_put_u64(skb, IPVS_STATS_ATTR_INPPS, kstats->inpps) || + nla_put_u64(skb, IPVS_STATS_ATTR_OUTPPS, kstats->outpps) || + nla_put_u64(skb, IPVS_STATS_ATTR_INBPS, kstats->inbps) || + nla_put_u64(skb, IPVS_STATS_ATTR_OUTBPS, kstats->outbps)) goto nla_put_failure; nla_nest_end(skb, nl_stats); @@ -2835,6 +2885,7 @@ static int ip_vs_genl_fill_service(struct sk_buff *skb, struct nlattr *nl_service; struct ip_vs_flags flags = { .flags = svc->flags, .mask = ~0 }; + struct ip_vs_kstats kstats; nl_service = nla_nest_start(skb, IPVS_CMD_ATTR_SERVICE); if (!nl_service) @@ -2860,7 +2911,10 @@ static int ip_vs_genl_fill_service(struct sk_buff *skb, nla_put_u32(skb, IPVS_SVC_ATTR_TIMEOUT, svc->timeout / HZ) || nla_put_be32(skb, IPVS_SVC_ATTR_NETMASK, svc->netmask)) goto nla_put_failure; - if (ip_vs_genl_fill_stats(skb, IPVS_SVC_ATTR_STATS, &svc->stats)) + ip_vs_copy_stats(&kstats, &svc->stats); + if (ip_vs_genl_fill_stats(skb, IPVS_SVC_ATTR_STATS, &kstats)) + goto nla_put_failure; + if (ip_vs_genl_fill_stats64(skb, IPVS_SVC_ATTR_STATS64, &kstats)) goto nla_put_failure; nla_nest_end(skb, nl_service); @@ -3032,6 +3086,7 @@ static struct ip_vs_service *ip_vs_genl_find_service(struct net *net, static int ip_vs_genl_fill_dest(struct sk_buff *skb, struct ip_vs_dest *dest) { struct nlattr *nl_dest; + struct ip_vs_kstats kstats; nl_dest = nla_nest_start(skb, IPVS_CMD_ATTR_DEST); if (!nl_dest) @@ -3054,7 +3109,10 @@ static int ip_vs_genl_fill_dest(struct sk_buff *skb, struct ip_vs_dest *dest) atomic_read(&dest->persistconns)) || nla_put_u16(skb, IPVS_DEST_ATTR_ADDR_FAMILY, dest->af)) goto nla_put_failure; - if (ip_vs_genl_fill_stats(skb, IPVS_DEST_ATTR_STATS, &dest->stats)) + ip_vs_copy_stats(&kstats, &dest->stats); + if (ip_vs_genl_fill_stats(skb, IPVS_DEST_ATTR_STATS, &kstats)) + goto nla_put_failure; + if (ip_vs_genl_fill_stats64(skb, IPVS_DEST_ATTR_STATS64, &kstats)) goto nla_put_failure; nla_nest_end(skb, nl_dest); diff --git a/net/netfilter/ipvs/ip_vs_est.c b/net/netfilter/ipvs/ip_vs_est.c index 1425e9a924c4..ef0eb0a8d552 100644 --- a/net/netfilter/ipvs/ip_vs_est.c +++ b/net/netfilter/ipvs/ip_vs_est.c @@ -45,17 +45,19 @@ NOTES. - * The stored value for average bps is scaled by 2^5, so that maximal - rate is ~2.15Gbits/s, average pps and cps are scaled by 2^10. + * Average bps is scaled by 2^5, while average pps and cps are scaled by 2^10. - * A lot code is taken from net/sched/estimator.c + * Netlink users can see 64-bit values but sockopt users are restricted + to 32-bit values for conns, packets, bps, cps and pps. + + * A lot of code is taken from net/core/gen_estimator.c */ /* * Make a summary from each cpu */ -static void ip_vs_read_cpu_stats(struct ip_vs_stats_user *sum, +static void ip_vs_read_cpu_stats(struct ip_vs_kstats *sum, struct ip_vs_cpu_stats __percpu *stats) { int i; @@ -64,27 +66,31 @@ static void ip_vs_read_cpu_stats(struct ip_vs_stats_user *sum, for_each_possible_cpu(i) { struct ip_vs_cpu_stats *s = per_cpu_ptr(stats, i); unsigned int start; - __u64 inbytes, outbytes; + u64 conns, inpkts, outpkts, inbytes, outbytes; + if (add) { - sum->conns += s->ustats.conns; - sum->inpkts += s->ustats.inpkts; - sum->outpkts += s->ustats.outpkts; do { start = u64_stats_fetch_begin(&s->syncp); - inbytes = s->ustats.inbytes; - outbytes = s->ustats.outbytes; + conns = s->cnt.conns; + inpkts = s->cnt.inpkts; + outpkts = s->cnt.outpkts; + inbytes = s->cnt.inbytes; + outbytes = s->cnt.outbytes; } while (u64_stats_fetch_retry(&s->syncp, start)); + sum->conns += conns; + sum->inpkts += inpkts; + sum->outpkts += outpkts; sum->inbytes += inbytes; sum->outbytes += outbytes; } else { add = true; - sum->conns = s->ustats.conns; - sum->inpkts = s->ustats.inpkts; - sum->outpkts = s->ustats.outpkts; do { start = u64_stats_fetch_begin(&s->syncp); - sum->inbytes = s->ustats.inbytes; - sum->outbytes = s->ustats.outbytes; + sum->conns = s->cnt.conns; + sum->inpkts = s->cnt.inpkts; + sum->outpkts = s->cnt.outpkts; + sum->inbytes = s->cnt.inbytes; + sum->outbytes = s->cnt.outbytes; } while (u64_stats_fetch_retry(&s->syncp, start)); } } @@ -95,10 +101,7 @@ static void estimation_timer(unsigned long arg) { struct ip_vs_estimator *e; struct ip_vs_stats *s; - u32 n_conns; - u32 n_inpkts, n_outpkts; - u64 n_inbytes, n_outbytes; - u32 rate; + u64 rate; struct net *net = (struct net *)arg; struct netns_ipvs *ipvs; @@ -108,33 +111,29 @@ static void estimation_timer(unsigned long arg) s = container_of(e, struct ip_vs_stats, est); spin_lock(&s->lock); - ip_vs_read_cpu_stats(&s->ustats, s->cpustats); - n_conns = s->ustats.conns; - n_inpkts = s->ustats.inpkts; - n_outpkts = s->ustats.outpkts; - n_inbytes = s->ustats.inbytes; - n_outbytes = s->ustats.outbytes; + ip_vs_read_cpu_stats(&s->kstats, s->cpustats); /* scaled by 2^10, but divided 2 seconds */ - rate = (n_conns - e->last_conns) << 9; - e->last_conns = n_conns; - e->cps += ((long)rate - (long)e->cps) >> 2; - - rate = (n_inpkts - e->last_inpkts) << 9; - e->last_inpkts = n_inpkts; - e->inpps += ((long)rate - (long)e->inpps) >> 2; - - rate = (n_outpkts - e->last_outpkts) << 9; - e->last_outpkts = n_outpkts; - e->outpps += ((long)rate - (long)e->outpps) >> 2; - - rate = (n_inbytes - e->last_inbytes) << 4; - e->last_inbytes = n_inbytes; - e->inbps += ((long)rate - (long)e->inbps) >> 2; - - rate = (n_outbytes - e->last_outbytes) << 4; - e->last_outbytes = n_outbytes; - e->outbps += ((long)rate - (long)e->outbps) >> 2; + rate = (s->kstats.conns - e->last_conns) << 9; + e->last_conns = s->kstats.conns; + e->cps += ((s64)rate - (s64)e->cps) >> 2; + + rate = (s->kstats.inpkts - e->last_inpkts) << 9; + e->last_inpkts = s->kstats.inpkts; + e->inpps += ((s64)rate - (s64)e->inpps) >> 2; + + rate = (s->kstats.outpkts - e->last_outpkts) << 9; + e->last_outpkts = s->kstats.outpkts; + e->outpps += ((s64)rate - (s64)e->outpps) >> 2; + + /* scaled by 2^5, but divided 2 seconds */ + rate = (s->kstats.inbytes - e->last_inbytes) << 4; + e->last_inbytes = s->kstats.inbytes; + e->inbps += ((s64)rate - (s64)e->inbps) >> 2; + + rate = (s->kstats.outbytes - e->last_outbytes) << 4; + e->last_outbytes = s->kstats.outbytes; + e->outbps += ((s64)rate - (s64)e->outbps) >> 2; spin_unlock(&s->lock); } spin_unlock(&ipvs->est_lock); @@ -166,14 +165,14 @@ void ip_vs_stop_estimator(struct net *net, struct ip_vs_stats *stats) void ip_vs_zero_estimator(struct ip_vs_stats *stats) { struct ip_vs_estimator *est = &stats->est; - struct ip_vs_stats_user *u = &stats->ustats; + struct ip_vs_kstats *k = &stats->kstats; /* reset counters, caller must hold the stats->lock lock */ - est->last_inbytes = u->inbytes; - est->last_outbytes = u->outbytes; - est->last_conns = u->conns; - est->last_inpkts = u->inpkts; - est->last_outpkts = u->outpkts; + est->last_inbytes = k->inbytes; + est->last_outbytes = k->outbytes; + est->last_conns = k->conns; + est->last_inpkts = k->inpkts; + est->last_outpkts = k->outpkts; est->cps = 0; est->inpps = 0; est->outpps = 0; @@ -182,8 +181,7 @@ void ip_vs_zero_estimator(struct ip_vs_stats *stats) } /* Get decoded rates */ -void ip_vs_read_estimator(struct ip_vs_stats_user *dst, - struct ip_vs_stats *stats) +void ip_vs_read_estimator(struct ip_vs_kstats *dst, struct ip_vs_stats *stats) { struct ip_vs_estimator *e = &stats->est; -- GitLab From 0b1f6ec7a5fb3faff1a62afee132dac316eec63d Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 9 Feb 2015 08:05:22 +0000 Subject: [PATCH 00085/11651] ASoC: rsnd: set device data before snd_soc_register_platform/component Set device data before snd_soc_register_platform/component. Otherwise, it will use NULL pointer if user calls unbind -> bind or rmmod -> insmod Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 75308bbc2ce8..fc227d3bc021 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -1268,6 +1268,8 @@ static int rsnd_probe(struct platform_device *pdev) goto exit_snd_probe; } + dev_set_drvdata(dev, priv); + /* * asoc register */ @@ -1284,8 +1286,6 @@ static int rsnd_probe(struct platform_device *pdev) goto exit_snd_soc; } - dev_set_drvdata(dev, priv); - pm_runtime_enable(dev); dev_info(dev, "probed\n"); -- GitLab From 044a832a7779c0638bea2d0fea901c055b995f4a Mon Sep 17 00:00:00 2001 From: Steffen Klassert Date: Mon, 12 Jan 2015 13:38:49 +0100 Subject: [PATCH 00086/11651] xfrm: Fix local error reporting crash with interfamily tunnels We set the outer mode protocol too early. As a result, the local error handler might dispatch to the wrong address family and report the error to a wrong socket type. We fix this by setting the outer protocol to the skb after we accessed the inner mode for the last time, right before we do the atcual encapsulation where we switch finally to the outer mode. Reported-by: Chris Ruehl Tested-by: Chris Ruehl Signed-off-by: Steffen Klassert --- net/ipv4/xfrm4_output.c | 2 +- net/ipv6/xfrm6_output.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c index d5f6bd9a210a..dab73813cb92 100644 --- a/net/ipv4/xfrm4_output.c +++ b/net/ipv4/xfrm4_output.c @@ -63,6 +63,7 @@ int xfrm4_prepare_output(struct xfrm_state *x, struct sk_buff *skb) return err; IPCB(skb)->flags |= IPSKB_XFRM_TUNNEL_SIZE; + skb->protocol = htons(ETH_P_IP); return x->outer_mode->output2(x, skb); } @@ -71,7 +72,6 @@ EXPORT_SYMBOL(xfrm4_prepare_output); int xfrm4_output_finish(struct sk_buff *skb) { memset(IPCB(skb), 0, sizeof(*IPCB(skb))); - skb->protocol = htons(ETH_P_IP); #ifdef CONFIG_NETFILTER IPCB(skb)->flags |= IPSKB_XFRM_TRANSFORMED; diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c index ca3f29b98ae5..010f8bd2d577 100644 --- a/net/ipv6/xfrm6_output.c +++ b/net/ipv6/xfrm6_output.c @@ -114,6 +114,7 @@ int xfrm6_prepare_output(struct xfrm_state *x, struct sk_buff *skb) return err; skb->ignore_df = 1; + skb->protocol = htons(ETH_P_IPV6); return x->outer_mode->output2(x, skb); } @@ -122,7 +123,6 @@ EXPORT_SYMBOL(xfrm6_prepare_output); int xfrm6_output_finish(struct sk_buff *skb) { memset(IP6CB(skb), 0, sizeof(*IP6CB(skb))); - skb->protocol = htons(ETH_P_IPV6); #ifdef CONFIG_NETFILTER IP6CB(skb)->flags |= IP6SKB_XFRM_TRANSFORMED; -- GitLab From 5163c1eede8e9073e5b6bf1a988ed07d35820343 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Mon, 9 Feb 2015 13:26:01 +0200 Subject: [PATCH 00087/11651] ASoC: omap: Kconfig: Support for omap5-uevm analog audio The analog audio is supported via omap-abe-twl6040 machine driver on omap5-uevm. Update the Kconfig file to reflect this and select the Palmas clock driver which is providing the 32K clock for audio on omap5-uevm. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/omap/Kconfig | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig index a2cd3486ac55..e7c78b0406b5 100644 --- a/sound/soc/omap/Kconfig +++ b/sound/soc/omap/Kconfig @@ -100,17 +100,19 @@ config SND_OMAP_SOC_OMAP_TWL4030 config SND_OMAP_SOC_OMAP_ABE_TWL6040 tristate "SoC Audio support for OMAP boards using ABE and twl6040 codec" - depends on TWL6040_CORE && SND_OMAP_SOC && (ARCH_OMAP4 || COMPILE_TEST) + depends on TWL6040_CORE && SND_OMAP_SOC && (ARCH_OMAP4 || SOC_OMAP5 || COMPILE_TEST) select SND_OMAP_SOC_DMIC select SND_OMAP_SOC_MCPDM select SND_SOC_TWL6040 select SND_SOC_DMIC + select COMMON_CLK_PALMAS if SOC_OMAP5 help Say Y if you want to add support for SoC audio on OMAP boards using ABE and twl6040 codec. This driver currently supports: - SDP4430/Blaze boards - PandaBoard (4430) - PandaBoardES (4460) + - omap5-uevm (5432) config SND_OMAP_SOC_OMAP3_PANDORA tristate "SoC Audio support for OMAP3 Pandora" -- GitLab From b6d6c6e95ff0e78f9b8393e6b9f25d5a4341ae1a Mon Sep 17 00:00:00 2001 From: Peter Rosin Date: Mon, 9 Feb 2015 16:08:25 +0100 Subject: [PATCH 00088/11651] ASoC: atmel_ssc_dai: Allow more rates When the SSC acts as BCK master, use a ratnum rule to limit the rate instead of only doing the standard rates. When the SSC acts as BCK slave, allow any BCK frequency up to the SSC master clock, divided by either of 2, 3 or 6. Put a cap at 384kHz. Who's /ever/ going to need more than that? The divider of 2, 3 or 6 is selected based on the Serial Clock Ratio Considerations section from the SSC documentation: The Transmitter and the Receiver can be programmed to operate with the clock signals provided on either the TK or RK pins. This allows the SSC to support many slave-mode data transfers. In this case, the maximum clock speed allowed on the RK pin is: - Peripheral clock divided by 2 if Receiver Frame Synchro is input - Peripheral clock divided by 3 if Receiver Frame Synchro is output In addition, the maximum clock speed allowed on the TK pin is: - Peripheral clock divided by 6 if Transmit Frame Synchro is input - Peripheral clock divided by 2 if Transmit Frame Synchro is output Signed-off-by: Peter Rosin Acked-by: Bo Shen Signed-off-by: Mark Brown --- sound/soc/atmel/atmel_ssc_dai.c | 111 ++++++++++++++++++++++++++++++-- sound/soc/atmel/atmel_ssc_dai.h | 1 + 2 files changed, 108 insertions(+), 4 deletions(-) diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c index 379ac2a6ab16..6b8e64899205 100644 --- a/sound/soc/atmel/atmel_ssc_dai.c +++ b/sound/soc/atmel/atmel_ssc_dai.c @@ -187,6 +187,94 @@ static irqreturn_t atmel_ssc_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } +/* + * When the bit clock is input, limit the maximum rate according to the + * Serial Clock Ratio Considerations section from the SSC documentation: + * + * The Transmitter and the Receiver can be programmed to operate + * with the clock signals provided on either the TK or RK pins. + * This allows the SSC to support many slave-mode data transfers. + * In this case, the maximum clock speed allowed on the RK pin is: + * - Peripheral clock divided by 2 if Receiver Frame Synchro is input + * - Peripheral clock divided by 3 if Receiver Frame Synchro is output + * In addition, the maximum clock speed allowed on the TK pin is: + * - Peripheral clock divided by 6 if Transmit Frame Synchro is input + * - Peripheral clock divided by 2 if Transmit Frame Synchro is output + * + * When the bit clock is output, limit the rate according to the + * SSC divider restrictions. + */ +static int atmel_ssc_hw_rule_rate(struct snd_pcm_hw_params *params, + struct snd_pcm_hw_rule *rule) +{ + struct atmel_ssc_info *ssc_p = rule->private; + struct ssc_device *ssc = ssc_p->ssc; + struct snd_interval *i = hw_param_interval(params, rule->var); + struct snd_interval t; + struct snd_ratnum r = { + .den_min = 1, + .den_max = 4095, + .den_step = 1, + }; + unsigned int num = 0, den = 0; + int frame_size; + int mck_div = 2; + int ret; + + frame_size = snd_soc_params_to_frame_size(params); + if (frame_size < 0) + return frame_size; + + switch (ssc_p->daifmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBM_CFS: + if ((ssc_p->dir_mask & SSC_DIR_MASK_CAPTURE) + && ssc->clk_from_rk_pin) + /* Receiver Frame Synchro (i.e. capture) + * is output (format is _CFS) and the RK pin + * is used for input (format is _CBM_). + */ + mck_div = 3; + break; + + case SND_SOC_DAIFMT_CBM_CFM: + if ((ssc_p->dir_mask & SSC_DIR_MASK_PLAYBACK) + && !ssc->clk_from_rk_pin) + /* Transmit Frame Synchro (i.e. playback) + * is input (format is _CFM) and the TK pin + * is used for input (format _CBM_ but not + * using the RK pin). + */ + mck_div = 6; + break; + } + + switch (ssc_p->daifmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFS: + r.num = ssc_p->mck_rate / mck_div / frame_size; + + ret = snd_interval_ratnum(i, 1, &r, &num, &den); + if (ret >= 0 && den && rule->var == SNDRV_PCM_HW_PARAM_RATE) { + params->rate_num = num; + params->rate_den = den; + } + break; + + case SND_SOC_DAIFMT_CBM_CFS: + case SND_SOC_DAIFMT_CBM_CFM: + t.min = 8000; + t.max = ssc_p->mck_rate / mck_div / frame_size; + t.openmin = t.openmax = 0; + t.integer = 0; + ret = snd_interval_refine(i, &t); + break; + + default: + ret = -EINVAL; + break; + } + + return ret; +} /*-------------------------------------------------------------------------*\ * DAI functions @@ -200,6 +288,7 @@ static int atmel_ssc_startup(struct snd_pcm_substream *substream, struct atmel_ssc_info *ssc_p = &ssc_info[dai->id]; struct atmel_pcm_dma_params *dma_params; int dir, dir_mask; + int ret; pr_debug("atmel_ssc_startup: SSC_SR=0x%u\n", ssc_readl(ssc_p->ssc->regs, SR)); @@ -207,6 +296,7 @@ static int atmel_ssc_startup(struct snd_pcm_substream *substream, /* Enable PMC peripheral clock for this SSC */ pr_debug("atmel_ssc_dai: Starting clock\n"); clk_enable(ssc_p->ssc->clk); + ssc_p->mck_rate = clk_get_rate(ssc_p->ssc->clk); /* Reset the SSC to keep it at a clean status */ ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_SWRST)); @@ -219,6 +309,17 @@ static int atmel_ssc_startup(struct snd_pcm_substream *substream, dir_mask = SSC_DIR_MASK_CAPTURE; } + ret = snd_pcm_hw_rule_add(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, + atmel_ssc_hw_rule_rate, + ssc_p, + SNDRV_PCM_HW_PARAM_FRAME_BITS, + SNDRV_PCM_HW_PARAM_CHANNELS, -1); + if (ret < 0) { + dev_err(dai->dev, "Failed to specify rate rule: %d\n", ret); + return ret; + } + dma_params = &ssc_dma_params[dai->id][dir]; dma_params->ssc = ssc_p->ssc; dma_params->substream = substream; @@ -783,8 +884,6 @@ static int atmel_ssc_resume(struct snd_soc_dai *cpu_dai) # define atmel_ssc_resume NULL #endif /* CONFIG_PM */ -#define ATMEL_SSC_RATES (SNDRV_PCM_RATE_8000_96000) - #define ATMEL_SSC_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) @@ -804,12 +903,16 @@ static struct snd_soc_dai_driver atmel_ssc_dai = { .playback = { .channels_min = 1, .channels_max = 2, - .rates = ATMEL_SSC_RATES, + .rates = SNDRV_PCM_RATE_CONTINUOUS, + .rate_min = 8000, + .rate_max = 384000, .formats = ATMEL_SSC_FORMATS,}, .capture = { .channels_min = 1, .channels_max = 2, - .rates = ATMEL_SSC_RATES, + .rates = SNDRV_PCM_RATE_CONTINUOUS, + .rate_min = 8000, + .rate_max = 384000, .formats = ATMEL_SSC_FORMATS,}, .ops = &atmel_ssc_dai_ops, }; diff --git a/sound/soc/atmel/atmel_ssc_dai.h b/sound/soc/atmel/atmel_ssc_dai.h index b1f08d511495..80b153857a88 100644 --- a/sound/soc/atmel/atmel_ssc_dai.h +++ b/sound/soc/atmel/atmel_ssc_dai.h @@ -115,6 +115,7 @@ struct atmel_ssc_info { unsigned short rcmr_period; struct atmel_pcm_dma_params *dma_params[2]; struct atmel_ssc_state ssc_state; + unsigned long mck_rate; }; int atmel_ssc_set_audio(int ssc_id); -- GitLab From b3e7766bc459af941c311a3cb03f2082b2fe60ba Mon Sep 17 00:00:00 2001 From: Nicholas Mc Guire Date: Sun, 8 Feb 2015 10:11:05 -0500 Subject: [PATCH 00089/11651] spi: bcm53xx: use msecs_to_jiffies for conversion Converting milliseconds to jiffies by "val * HZ / 1000" is technically ok but msecs_to_jiffies(val) is the cleaner solution and handles all corner cases correctly. This is only an API consolidation and should make things more readable Signed-off-by: Nicholas Mc Guire Signed-off-by: Mark Brown --- drivers/spi/spi-bcm53xx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi-bcm53xx.c b/drivers/spi/spi-bcm53xx.c index 17b34cbadc03..1933ef332bbb 100644 --- a/drivers/spi/spi-bcm53xx.c +++ b/drivers/spi/spi-bcm53xx.c @@ -44,7 +44,7 @@ static int bcm53xxspi_wait(struct bcm53xxspi *b53spi, unsigned int timeout_ms) u32 tmp; /* SPE bit has to be 0 before we read MSPI STATUS */ - deadline = jiffies + BCM53XXSPI_SPE_TIMEOUT_MS * HZ / 1000; + deadline = jiffies + msecs_to_jiffies(BCM53XXSPI_SPE_TIMEOUT_MS); do { tmp = bcm53xxspi_read(b53spi, B53SPI_MSPI_SPCR2); if (!(tmp & B53SPI_MSPI_SPCR2_SPE)) @@ -56,7 +56,7 @@ static int bcm53xxspi_wait(struct bcm53xxspi *b53spi, unsigned int timeout_ms) goto spi_timeout; /* Check status */ - deadline = jiffies + timeout_ms * HZ / 1000; + deadline = jiffies + msecs_to_jiffies(timeout_ms); do { tmp = bcm53xxspi_read(b53spi, B53SPI_MSPI_MSPI_STATUS); if (tmp & B53SPI_MSPI_MSPI_STATUS_SPIF) { -- GitLab From 750d8065d88bc72bd6e1fd9f896a964c35dda818 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 10 Feb 2015 21:24:55 -0800 Subject: [PATCH 00090/11651] crypto: Fix regressions caused by iov_iter changes. Signed-off-by: Al Viro Signed-off-by: David S. Miller --- crypto/af_alg.c | 2 +- crypto/algif_skcipher.c | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/crypto/af_alg.c b/crypto/af_alg.c index eb78fe8a60c8..5b11d645343d 100644 --- a/crypto/af_alg.c +++ b/crypto/af_alg.c @@ -348,7 +348,7 @@ int af_alg_make_sg(struct af_alg_sgl *sgl, struct iov_iter *iter, int len) if (n < 0) return n; - npages = PAGE_ALIGN(off + n); + npages = DIV_ROUND_UP(off + n, PAGE_SIZE); if (WARN_ON(npages == 0)) return -EINVAL; diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c index 37110fd68adf..0eb31a69a0a6 100644 --- a/crypto/algif_skcipher.c +++ b/crypto/algif_skcipher.c @@ -427,11 +427,11 @@ static int skcipher_recvmsg(struct kiocb *unused, struct socket *sock, struct skcipher_sg_list *sgl; struct scatterlist *sg; int err = -EAGAIN; - int used; long copied = 0; lock_sock(sk); while (iov_iter_count(&msg->msg_iter)) { + int used; sgl = list_first_entry(&ctx->tsgl, struct skcipher_sg_list, list); sg = sgl->sg; @@ -439,14 +439,13 @@ static int skcipher_recvmsg(struct kiocb *unused, struct socket *sock, while (!sg->length) sg++; - used = ctx->used; - if (!used) { + if (!ctx->used) { err = skcipher_wait_for_data(sk, flags); if (err) goto unlock; } - used = min_t(unsigned long, used, iov_iter_count(&msg->msg_iter)); + used = min_t(unsigned long, ctx->used, iov_iter_count(&msg->msg_iter)); used = af_alg_make_sg(&ctx->rsgl, &msg->msg_iter, used); err = used; -- GitLab From b4e27545224e263d271a9d9aa8763357a7e40eaa Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Fri, 6 Feb 2015 12:27:54 -0800 Subject: [PATCH 00091/11651] spi: sc18is602: Support multiple devices on a single I2C bus if DT is configured The driver currently only supports a single device per I2C bus since it uses the I2C bus number to set the SPI bus number. This makes it impossible to connect more than one chip to a single I2C bus. We don't want to use dynamic bus numbers unconditionally since this would result in every instantiation getting a different bus number starting with 65,535 counting down unless devicetree is configured. If devicetree is configured, however, the SPI bus number is obtained from devicetree data. So we can use dynamic SPI bus numbers in this case. Reported-and-Tested-by: Marco Menchise Signed-off-by: Guenter Roeck Signed-off-by: Mark Brown --- drivers/spi/spi-sc18is602.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/spi-sc18is602.c b/drivers/spi/spi-sc18is602.c index 237f2e7a7179..c04e601152f1 100644 --- a/drivers/spi/spi-sc18is602.c +++ b/drivers/spi/spi-sc18is602.c @@ -290,7 +290,7 @@ static int sc18is602_probe(struct i2c_client *client, hw->freq = SC18IS602_CLOCK; break; } - master->bus_num = client->adapter->nr; + master->bus_num = np ? -1 : client->adapter->nr; master->mode_bits = SPI_CPHA | SPI_CPOL | SPI_LSB_FIRST; master->bits_per_word_mask = SPI_BPW_MASK(8); master->setup = sc18is602_setup; -- GitLab From 541b03ad6cfe0e415273f096fd8c47d2879c6c15 Mon Sep 17 00:00:00 2001 From: Nicolin Chen Date: Tue, 10 Feb 2015 21:31:43 -0800 Subject: [PATCH 00092/11651] ASoC: fsl_ssi: Fix the incorrect limitation of the bit clock rate According to i.MX Reference Manual, the bit-clock frequency generated by SSI must be never greater than 1/5 of the peripheral clock frequency. This peripheral clock, however, is not baudclk but the IPG clock (i.e. ssi_private->clk in the fsl_ssi driver). So this patch just simply fixes the incorrect limitation applied to the bit clock (baudclk) rate. Signed-off-by: Nicolin Chen Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_ssi.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 059496ed9ad7..d7365c5d7ec0 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -603,10 +603,6 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream *substream, factor = (div2 + 1) * (7 * psr + 1) * 2; for (i = 0; i < 255; i++) { - /* The bclk rate must be smaller than 1/5 sysclk rate */ - if (factor * (i + 1) < 5) - continue; - tmprate = freq * factor * (i + 2); if (baudclk_is_used) @@ -614,6 +610,13 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream *substream, else clkrate = clk_round_rate(ssi_private->baudclk, tmprate); + /* + * Hardware limitation: The bclk rate must be + * never greater than 1/5 IPG clock rate + */ + if (clkrate * 5 > clk_get_rate(ssi_private->clk)) + continue; + clkrate /= factor; afreq = clkrate / (i + 1); -- GitLab From 5cca4ace0fac4474edb02120bf1284ed6eb059aa Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Wed, 21 Jan 2015 10:53:50 +1100 Subject: [PATCH 00093/11651] netfilter: Don't hide NETFILTER_XT_MATCH_ADDRTYPE behind NETFILTER_ADVANCED Docker needs NETFILTER_XT_MATCH_ADDRTYPE, so move it out from behind NETFILTER_ADVANCED and make it default to a module. Signed-off-by: Anton Blanchard Signed-off-by: Pablo Neira Ayuso --- net/netfilter/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig index b02660fa9eb0..c68c3b441381 100644 --- a/net/netfilter/Kconfig +++ b/net/netfilter/Kconfig @@ -951,7 +951,7 @@ comment "Xtables matches" config NETFILTER_XT_MATCH_ADDRTYPE tristate '"addrtype" address type match support' - depends on NETFILTER_ADVANCED + default m if NETFILTER_ADVANCED=n ---help--- This option allows you to match what routing thinks of an address, eg. UNICAST, LOCAL, BROADCAST, ... -- GitLab From 7f73b9f1ca7334eec0ff9a40e37ece92dd3e420f Mon Sep 17 00:00:00 2001 From: Wu Fengguang Date: Wed, 11 Feb 2015 20:33:05 +0800 Subject: [PATCH 00094/11651] netfilter: ipset: fix boolreturn.cocci warnings net/netfilter/xt_set.c:196:9-10: WARNING: return of 0/1 in function 'set_match_v3' with return type bool net/netfilter/xt_set.c:242:9-10: WARNING: return of 0/1 in function 'set_match_v4' with return type bool Return statements in functions returning bool should use true/false instead of 1/0. Generated by: scripts/coccinelle/misc/boolreturn.cocci CC: Jozsef Kadlecsik Signed-off-by: Fengguang Wu Acked-by: Jozsef Kadlecsik Signed-off-by: Pablo Neira Ayuso --- net/netfilter/xt_set.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/netfilter/xt_set.c b/net/netfilter/xt_set.c index 0d47afea9682..89045982ec94 100644 --- a/net/netfilter/xt_set.c +++ b/net/netfilter/xt_set.c @@ -193,7 +193,7 @@ set_match_v3(const struct sk_buff *skb, struct xt_action_param *par) return ret; if (!match_counter0(opt.ext.packets, &info->packets)) - return 0; + return false; return match_counter0(opt.ext.bytes, &info->bytes); } @@ -239,7 +239,7 @@ set_match_v4(const struct sk_buff *skb, struct xt_action_param *par) return ret; if (!match_counter(opt.ext.packets, &info->packets)) - return 0; + return false; return match_counter(opt.ext.bytes, &info->bytes); } -- GitLab From 23773ca18b399051eb94f98b689cf7a9173c795b Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Mon, 2 Feb 2015 14:35:07 -0500 Subject: [PATCH 00095/11651] perf tools: Make perf aware of tracefs As tracefs may be mounted instead of debugfs to get to the event directories, have perf know about tracefs, and use that file system over debugfs if it is present. Signed-off-by: Steven Rostedt Acked-by: Jiri Olsa Cc: Andrew Morton Cc: Ingo Molnar Cc: Masami Hiramatsu Cc: Namhyung Kim Link: http://lkml.kernel.org/r/20150202193553.340946602@goodmis.org [ Fixed up error messages about tracefs pointed out by Namhyung ] Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/open-syscall-all-cpus.c | 7 ++- tools/perf/tests/open-syscall.c | 7 ++- tools/perf/tests/parse-events.c | 13 ++++- tools/perf/util/cache.h | 1 + tools/perf/util/evlist.c | 1 - tools/perf/util/parse-events.h | 2 +- tools/perf/util/probe-event.c | 24 ++++++---- tools/perf/util/util.c | 60 +++++++++++++++++++----- tools/perf/util/util.h | 1 + 9 files changed, 91 insertions(+), 25 deletions(-) diff --git a/tools/perf/tests/open-syscall-all-cpus.c b/tools/perf/tests/open-syscall-all-cpus.c index 8fa82d1700c7..3ec885c48f8f 100644 --- a/tools/perf/tests/open-syscall-all-cpus.c +++ b/tools/perf/tests/open-syscall-all-cpus.c @@ -29,7 +29,12 @@ int test__open_syscall_event_on_all_cpus(void) evsel = perf_evsel__newtp("syscalls", "sys_enter_open"); if (evsel == NULL) { - pr_debug("is debugfs mounted on /sys/kernel/debug?\n"); + if (tracefs_configured()) + pr_debug("is tracefs mounted on /sys/kernel/tracing?\n"); + else if (debugfs_configured()) + pr_debug("is debugfs mounted on /sys/kernel/debug?\n"); + else + pr_debug("Neither tracefs or debugfs is enabled in this kernel\n"); goto out_thread_map_delete; } diff --git a/tools/perf/tests/open-syscall.c b/tools/perf/tests/open-syscall.c index a33b2daae40f..07aa319bf334 100644 --- a/tools/perf/tests/open-syscall.c +++ b/tools/perf/tests/open-syscall.c @@ -18,7 +18,12 @@ int test__open_syscall_event(void) evsel = perf_evsel__newtp("syscalls", "sys_enter_open"); if (evsel == NULL) { - pr_debug("is debugfs mounted on /sys/kernel/debug?\n"); + if (tracefs_configured()) + pr_debug("is tracefs mounted on /sys/kernel/tracing?\n"); + else if (debugfs_configured()) + pr_debug("is debugfs mounted on /sys/kernel/debug?\n"); + else + pr_debug("Neither tracefs or debugfs is enabled in this kernel\n"); goto out_thread_map_delete; } diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c index 1cdab0ce00e2..ac243ebcb20a 100644 --- a/tools/perf/tests/parse-events.c +++ b/tools/perf/tests/parse-events.c @@ -3,6 +3,7 @@ #include "evsel.h" #include "evlist.h" #include +#include #include #include "tests.h" #include "debug.h" @@ -1192,11 +1193,19 @@ static int count_tracepoints(void) { char events_path[PATH_MAX]; struct dirent *events_ent; + const char *mountpoint; DIR *events_dir; int cnt = 0; - scnprintf(events_path, PATH_MAX, "%s/tracing/events", - debugfs_find_mountpoint()); + mountpoint = tracefs_find_mountpoint(); + if (mountpoint) { + scnprintf(events_path, PATH_MAX, "%s/events", + mountpoint); + } else { + mountpoint = debugfs_find_mountpoint(); + scnprintf(events_path, PATH_MAX, "%s/tracing/events", + mountpoint); + } events_dir = opendir(events_path); diff --git a/tools/perf/util/cache.h b/tools/perf/util/cache.h index d04d770d90f6..fbcca21d66ab 100644 --- a/tools/perf/util/cache.h +++ b/tools/perf/util/cache.h @@ -17,6 +17,7 @@ #define EXEC_PATH_ENVIRONMENT "PERF_EXEC_PATH" #define DEFAULT_PERF_DIR_ENVIRONMENT ".perf" #define PERF_DEBUGFS_ENVIRONMENT "PERF_DEBUGFS_DIR" +#define PERF_TRACEFS_ENVIRONMENT "PERF_TRACEFS_DIR" typedef int (*config_fn_t)(const char *, const char *, void *); extern int perf_default_config(const char *, const char *, void *); diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index c602ebb5b991..a8b2c5726aba 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -7,7 +7,6 @@ * Released under the GPL v2. (and only v2, not any later version) */ #include "util.h" -#include #include #include #include "cpumap.h" diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h index ff6e1fa4111e..39c3b57965d1 100644 --- a/tools/perf/util/parse-events.h +++ b/tools/perf/util/parse-events.h @@ -122,6 +122,6 @@ void print_tracepoint_events(const char *subsys_glob, const char *event_glob, int print_hwcache_events(const char *event_glob, bool name_only); extern int is_valid_tracepoint(const char *event_string); -extern int valid_debugfs_mount(const char *debugfs); +int valid_event_mount(const char *eventfs); #endif /* __PERF_PARSE_EVENTS_H */ diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 919937eb0be2..9dfbed96bf39 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -41,6 +41,7 @@ #include "symbol.h" #include "thread.h" #include +#include #include "trace-event.h" /* For __maybe_unused */ #include "probe-event.h" #include "probe-finder.h" @@ -1805,7 +1806,7 @@ static void print_open_warning(int err, bool is_kprobe) " - please rebuild kernel with %s.\n", is_kprobe ? 'k' : 'u', config); } else if (err == -ENOTSUP) - pr_warning("Debugfs is not mounted.\n"); + pr_warning("Tracefs or debugfs is not mounted.\n"); else pr_warning("Failed to open %cprobe_events: %s\n", is_kprobe ? 'k' : 'u', @@ -1816,7 +1817,7 @@ static void print_both_open_warning(int kerr, int uerr) { /* Both kprobes and uprobes are disabled, warn it. */ if (kerr == -ENOTSUP && uerr == -ENOTSUP) - pr_warning("Debugfs is not mounted.\n"); + pr_warning("Tracefs or debugfs is not mounted.\n"); else if (kerr == -ENOENT && uerr == -ENOENT) pr_warning("Please rebuild kernel with CONFIG_KPROBE_EVENTS " "or/and CONFIG_UPROBE_EVENTS.\n"); @@ -1833,13 +1834,20 @@ static int open_probe_events(const char *trace_file, bool readwrite) { char buf[PATH_MAX]; const char *__debugfs; + const char *tracing_dir = ""; int ret; - __debugfs = debugfs_find_mountpoint(); - if (__debugfs == NULL) - return -ENOTSUP; + __debugfs = tracefs_find_mountpoint(); + if (__debugfs == NULL) { + tracing_dir = "tracing/"; - ret = e_snprintf(buf, PATH_MAX, "%s/%s", __debugfs, trace_file); + __debugfs = debugfs_find_mountpoint(); + if (__debugfs == NULL) + return -ENOTSUP; + } + + ret = e_snprintf(buf, PATH_MAX, "%s/%s%s", + __debugfs, tracing_dir, trace_file); if (ret >= 0) { pr_debug("Opening %s write=%d\n", buf, readwrite); if (readwrite && !probe_event_dry_run) @@ -1855,12 +1863,12 @@ static int open_probe_events(const char *trace_file, bool readwrite) static int open_kprobe_events(bool readwrite) { - return open_probe_events("tracing/kprobe_events", readwrite); + return open_probe_events("kprobe_events", readwrite); } static int open_uprobe_events(bool readwrite) { - return open_probe_events("tracing/uprobe_events", readwrite); + return open_probe_events("uprobe_events", readwrite); } /* Get raw string list of current kprobe_events or uprobe_events */ diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c index b86744f29eef..92db3f156b63 100644 --- a/tools/perf/util/util.c +++ b/tools/perf/util/util.c @@ -303,13 +303,26 @@ void set_term_quiet_input(struct termios *old) tcsetattr(0, TCSANOW, &tc); } -static void set_tracing_events_path(const char *mountpoint) +static void set_tracing_events_path(const char *tracing, const char *mountpoint) { - snprintf(tracing_events_path, sizeof(tracing_events_path), "%s/%s", - mountpoint, "tracing/events"); + snprintf(tracing_events_path, sizeof(tracing_events_path), "%s/%s%s", + mountpoint, tracing, "events"); } -const char *perf_debugfs_mount(const char *mountpoint) +static const char *__perf_tracefs_mount(const char *mountpoint) +{ + const char *mnt; + + mnt = tracefs_mount(mountpoint); + if (!mnt) + return NULL; + + set_tracing_events_path("", mnt); + + return mnt; +} + +static const char *__perf_debugfs_mount(const char *mountpoint) { const char *mnt; @@ -317,7 +330,20 @@ const char *perf_debugfs_mount(const char *mountpoint) if (!mnt) return NULL; - set_tracing_events_path(mnt); + set_tracing_events_path("tracing/", mnt); + + return mnt; +} + +const char *perf_debugfs_mount(const char *mountpoint) +{ + const char *mnt; + + mnt = __perf_tracefs_mount(mountpoint); + if (mnt) + return mnt; + + mnt = __perf_debugfs_mount(mountpoint); return mnt; } @@ -325,12 +351,19 @@ const char *perf_debugfs_mount(const char *mountpoint) void perf_debugfs_set_path(const char *mntpt) { snprintf(debugfs_mountpoint, strlen(debugfs_mountpoint), "%s", mntpt); - set_tracing_events_path(mntpt); + set_tracing_events_path("tracing/", mntpt); +} + +static const char *find_tracefs(void) +{ + const char *path = __perf_tracefs_mount(NULL); + + return path; } static const char *find_debugfs(void) { - const char *path = perf_debugfs_mount(NULL); + const char *path = __perf_debugfs_mount(NULL); if (!path) fprintf(stderr, "Your kernel does not support the debugfs filesystem"); @@ -344,6 +377,7 @@ static const char *find_debugfs(void) */ const char *find_tracing_dir(void) { + const char *tracing_dir = ""; static char *tracing; static int tracing_found; const char *debugfs; @@ -351,11 +385,15 @@ const char *find_tracing_dir(void) if (tracing_found) return tracing; - debugfs = find_debugfs(); - if (!debugfs) - return NULL; + debugfs = find_tracefs(); + if (!debugfs) { + tracing_dir = "/tracing"; + debugfs = find_debugfs(); + if (!debugfs) + return NULL; + } - if (asprintf(&tracing, "%s/tracing", debugfs) < 0) + if (asprintf(&tracing, "%s%s", debugfs, tracing_dir) < 0) return NULL; tracing_found = 1; diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index 027a5153495c..73c2f8e557ab 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h @@ -75,6 +75,7 @@ #include #include #include +#include #include #include #include -- GitLab From 4e31050f482c02c822b150d71cf1ea5be7c9d6e4 Mon Sep 17 00:00:00 2001 From: Vinson Lee Date: Mon, 9 Feb 2015 16:29:37 -0800 Subject: [PATCH 00096/11651] perf symbols: Define STT_GNU_IFUNC for glibc 2.9 and older. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The token STT_GNU_IFUNC is not available with glibc 2.9 and older. Define this token if it is not already defined. This patch fixes this build errors with older versions of glibc. CC util/symbol-elf.o util/symbol-elf.c: In function ‘elf_sym__is_function’: util/symbol-elf.c:75: error: ‘STT_GNU_IFUNC’ undeclared (first use in this function) util/symbol-elf.c:75: error: (Each undeclared identifier is reported only once util/symbol-elf.c:75: error: for each function it appears in.) make: *** [util/symbol-elf.o] Error 1 Signed-off-by: Vinson Lee Acked-by: Namhyung Kim Cc: Adrian Hunter Cc: Anton Blanchard Cc: Avi Kivity Cc: Jiri Olsa Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Waiman Long Cc: stable@vger.kernel.org # 3.17+ Link: http://lkml.kernel.org/r/1423528286-13630-1-git-send-email-vlee@twopensource.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/symbol-elf.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 225eb73ee78b..b02731a19d1f 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -69,6 +69,10 @@ static inline uint8_t elf_sym__type(const GElf_Sym *sym) return GELF_ST_TYPE(sym->st_info); } +#ifndef STT_GNU_IFUNC +#define STT_GNU_IFUNC 10 +#endif + static inline int elf_sym__is_function(const GElf_Sym *sym) { return (elf_sym__type(sym) == STT_FUNC || -- GitLab From e35f7362bab455fb5c13ea4ce53f959f3e1610b2 Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Tue, 10 Feb 2015 18:18:51 +0900 Subject: [PATCH 00097/11651] perf buildid-cache: Remove unneeded debugdir parameters Functions related to buildid-cache subcommand use debugdir parameters for passing buildid cache directory path. However all callers just pass buildid_dir global variable. Moreover, other functions which refer buildid cache use buildid_dir directly. This removes unneeded debugdir parameters from those functions and use buildid_dir if needed. Signed-off-by: Masami Hiramatsu Acked-by: Namhyung Kim Cc: Adrian Hunter Cc: Borislav Petkov Cc: Hemant Kumar Cc: Jiri Olsa Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20150210091851.19264.72741.stgit@localhost.localdomain Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-buildid-cache.c | 37 +++++++++++-------------- tools/perf/util/build-id.c | 44 ++++++++++++++---------------- tools/perf/util/build-id.h | 4 +-- 3 files changed, 38 insertions(+), 47 deletions(-) diff --git a/tools/perf/builtin-buildid-cache.c b/tools/perf/builtin-buildid-cache.c index 50e6b66aea1f..d929d9544664 100644 --- a/tools/perf/builtin-buildid-cache.c +++ b/tools/perf/builtin-buildid-cache.c @@ -125,8 +125,7 @@ static int build_id_cache__kcore_existing(const char *from_dir, char *to_dir, return ret; } -static int build_id_cache__add_kcore(const char *filename, const char *debugdir, - bool force) +static int build_id_cache__add_kcore(const char *filename, bool force) { char dir[32], sbuildid[BUILD_ID_SIZE * 2 + 1]; char from_dir[PATH_MAX], to_dir[PATH_MAX]; @@ -143,7 +142,7 @@ static int build_id_cache__add_kcore(const char *filename, const char *debugdir, return -1; scnprintf(to_dir, sizeof(to_dir), "%s/[kernel.kcore]/%s", - debugdir, sbuildid); + buildid_dir, sbuildid); if (!force && !build_id_cache__kcore_existing(from_dir, to_dir, sizeof(to_dir))) { @@ -155,7 +154,7 @@ static int build_id_cache__add_kcore(const char *filename, const char *debugdir, return -1; scnprintf(to_dir, sizeof(to_dir), "%s/[kernel.kcore]/%s/%s", - debugdir, sbuildid, dir); + buildid_dir, sbuildid, dir); if (mkdir_p(to_dir, 0755)) return -1; @@ -183,7 +182,7 @@ static int build_id_cache__add_kcore(const char *filename, const char *debugdir, return 0; } -static int build_id_cache__add_file(const char *filename, const char *debugdir) +static int build_id_cache__add_file(const char *filename) { char sbuild_id[BUILD_ID_SIZE * 2 + 1]; u8 build_id[BUILD_ID_SIZE]; @@ -195,7 +194,7 @@ static int build_id_cache__add_file(const char *filename, const char *debugdir) } build_id__sprintf(build_id, sizeof(build_id), sbuild_id); - err = build_id_cache__add_s(sbuild_id, debugdir, filename, + err = build_id_cache__add_s(sbuild_id, filename, false, false); if (verbose) pr_info("Adding %s %s: %s\n", sbuild_id, filename, @@ -203,8 +202,7 @@ static int build_id_cache__add_file(const char *filename, const char *debugdir) return err; } -static int build_id_cache__remove_file(const char *filename, - const char *debugdir) +static int build_id_cache__remove_file(const char *filename) { u8 build_id[BUILD_ID_SIZE]; char sbuild_id[BUILD_ID_SIZE * 2 + 1]; @@ -217,7 +215,7 @@ static int build_id_cache__remove_file(const char *filename, } build_id__sprintf(build_id, sizeof(build_id), sbuild_id); - err = build_id_cache__remove_s(sbuild_id, debugdir); + err = build_id_cache__remove_s(sbuild_id); if (verbose) pr_info("Removing %s %s: %s\n", sbuild_id, filename, err ? "FAIL" : "Ok"); @@ -252,8 +250,7 @@ static int build_id_cache__fprintf_missing(struct perf_session *session, FILE *f return 0; } -static int build_id_cache__update_file(const char *filename, - const char *debugdir) +static int build_id_cache__update_file(const char *filename) { u8 build_id[BUILD_ID_SIZE]; char sbuild_id[BUILD_ID_SIZE * 2 + 1]; @@ -266,11 +263,10 @@ static int build_id_cache__update_file(const char *filename, } build_id__sprintf(build_id, sizeof(build_id), sbuild_id); - err = build_id_cache__remove_s(sbuild_id, debugdir); - if (!err) { - err = build_id_cache__add_s(sbuild_id, debugdir, filename, - false, false); - } + err = build_id_cache__remove_s(sbuild_id); + if (!err) + err = build_id_cache__add_s(sbuild_id, filename, false, false); + if (verbose) pr_info("Updating %s %s: %s\n", sbuild_id, filename, err ? "FAIL" : "Ok"); @@ -338,7 +334,7 @@ int cmd_buildid_cache(int argc, const char **argv, list = strlist__new(true, add_name_list_str); if (list) { strlist__for_each(pos, list) - if (build_id_cache__add_file(pos->s, buildid_dir)) { + if (build_id_cache__add_file(pos->s)) { if (errno == EEXIST) { pr_debug("%s already in the cache\n", pos->s); @@ -356,7 +352,7 @@ int cmd_buildid_cache(int argc, const char **argv, list = strlist__new(true, remove_name_list_str); if (list) { strlist__for_each(pos, list) - if (build_id_cache__remove_file(pos->s, buildid_dir)) { + if (build_id_cache__remove_file(pos->s)) { if (errno == ENOENT) { pr_debug("%s wasn't in the cache\n", pos->s); @@ -377,7 +373,7 @@ int cmd_buildid_cache(int argc, const char **argv, list = strlist__new(true, update_name_list_str); if (list) { strlist__for_each(pos, list) - if (build_id_cache__update_file(pos->s, buildid_dir)) { + if (build_id_cache__update_file(pos->s)) { if (errno == ENOENT) { pr_debug("%s wasn't in the cache\n", pos->s); @@ -391,8 +387,7 @@ int cmd_buildid_cache(int argc, const char **argv, } } - if (kcore_filename && - build_id_cache__add_kcore(kcore_filename, buildid_dir, force)) + if (kcore_filename && build_id_cache__add_kcore(kcore_filename, force)) pr_warning("Couldn't add %s\n", kcore_filename); out: diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index 0c72680a977f..9f764f633e57 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c @@ -259,8 +259,8 @@ void disable_buildid_cache(void) no_buildid_cache = true; } -int build_id_cache__add_s(const char *sbuild_id, const char *debugdir, - const char *name, bool is_kallsyms, bool is_vdso) +int build_id_cache__add_s(const char *sbuild_id, const char *name, + bool is_kallsyms, bool is_vdso) { const size_t size = PATH_MAX; char *realname, *filename = zalloc(size), @@ -282,7 +282,7 @@ int build_id_cache__add_s(const char *sbuild_id, const char *debugdir, goto out_free; len = scnprintf(filename, size, "%s%s%s", - debugdir, slash ? "/" : "", + buildid_dir, slash ? "/" : "", is_vdso ? DSO__NAME_VDSO : realname); if (mkdir_p(filename, 0755)) goto out_free; @@ -298,13 +298,13 @@ int build_id_cache__add_s(const char *sbuild_id, const char *debugdir, } len = scnprintf(linkname, size, "%s/.build-id/%.2s", - debugdir, sbuild_id); + buildid_dir, sbuild_id); if (access(linkname, X_OK) && mkdir_p(linkname, 0755)) goto out_free; snprintf(linkname + len, size - len, "/%s", sbuild_id + 2); - targetname = filename + strlen(debugdir) - 5; + targetname = filename + strlen(buildid_dir) - 5; memcpy(targetname, "../..", 5); if (symlink(targetname, linkname) == 0) @@ -318,18 +318,17 @@ out_free: } static int build_id_cache__add_b(const u8 *build_id, size_t build_id_size, - const char *name, const char *debugdir, - bool is_kallsyms, bool is_vdso) + const char *name, bool is_kallsyms, + bool is_vdso) { char sbuild_id[BUILD_ID_SIZE * 2 + 1]; build_id__sprintf(build_id, build_id_size, sbuild_id); - return build_id_cache__add_s(sbuild_id, debugdir, name, - is_kallsyms, is_vdso); + return build_id_cache__add_s(sbuild_id, name, is_kallsyms, is_vdso); } -int build_id_cache__remove_s(const char *sbuild_id, const char *debugdir) +int build_id_cache__remove_s(const char *sbuild_id) { const size_t size = PATH_MAX; char *filename = zalloc(size), @@ -340,7 +339,7 @@ int build_id_cache__remove_s(const char *sbuild_id, const char *debugdir) goto out_free; snprintf(linkname, size, "%s/.build-id/%.2s/%s", - debugdir, sbuild_id, sbuild_id + 2); + buildid_dir, sbuild_id, sbuild_id + 2); if (access(linkname, F_OK)) goto out_free; @@ -355,7 +354,7 @@ int build_id_cache__remove_s(const char *sbuild_id, const char *debugdir) * Since the link is relative, we must make it absolute: */ snprintf(linkname, size, "%s/.build-id/%.2s/%s", - debugdir, sbuild_id, filename); + buildid_dir, sbuild_id, filename); if (unlink(linkname)) goto out_free; @@ -367,8 +366,7 @@ out_free: return err; } -static int dso__cache_build_id(struct dso *dso, struct machine *machine, - const char *debugdir) +static int dso__cache_build_id(struct dso *dso, struct machine *machine) { bool is_kallsyms = dso->kernel && dso->long_name[0] != '/'; bool is_vdso = dso__is_vdso(dso); @@ -381,28 +379,26 @@ static int dso__cache_build_id(struct dso *dso, struct machine *machine, name = nm; } return build_id_cache__add_b(dso->build_id, sizeof(dso->build_id), name, - debugdir, is_kallsyms, is_vdso); + is_kallsyms, is_vdso); } static int __dsos__cache_build_ids(struct list_head *head, - struct machine *machine, const char *debugdir) + struct machine *machine) { struct dso *pos; int err = 0; dsos__for_each_with_build_id(pos, head) - if (dso__cache_build_id(pos, machine, debugdir)) + if (dso__cache_build_id(pos, machine)) err = -1; return err; } -static int machine__cache_build_ids(struct machine *machine, const char *debugdir) +static int machine__cache_build_ids(struct machine *machine) { - int ret = __dsos__cache_build_ids(&machine->kernel_dsos.head, machine, - debugdir); - ret |= __dsos__cache_build_ids(&machine->user_dsos.head, machine, - debugdir); + int ret = __dsos__cache_build_ids(&machine->kernel_dsos.head, machine); + ret |= __dsos__cache_build_ids(&machine->user_dsos.head, machine); return ret; } @@ -417,11 +413,11 @@ int perf_session__cache_build_ids(struct perf_session *session) if (mkdir(buildid_dir, 0755) != 0 && errno != EEXIST) return -1; - ret = machine__cache_build_ids(&session->machines.host, buildid_dir); + ret = machine__cache_build_ids(&session->machines.host); for (nd = rb_first(&session->machines.guests); nd; nd = rb_next(nd)) { struct machine *pos = rb_entry(nd, struct machine, rb_node); - ret |= machine__cache_build_ids(pos, buildid_dir); + ret |= machine__cache_build_ids(pos); } return ret ? -1 : 0; } diff --git a/tools/perf/util/build-id.h b/tools/perf/util/build-id.h index 8236319514d5..31b3c6332a1a 100644 --- a/tools/perf/util/build-id.h +++ b/tools/perf/util/build-id.h @@ -22,9 +22,9 @@ bool perf_session__read_build_ids(struct perf_session *session, bool with_hits); int perf_session__write_buildid_table(struct perf_session *session, int fd); int perf_session__cache_build_ids(struct perf_session *session); -int build_id_cache__add_s(const char *sbuild_id, const char *debugdir, +int build_id_cache__add_s(const char *sbuild_id, const char *name, bool is_kallsyms, bool is_vdso); -int build_id_cache__remove_s(const char *sbuild_id, const char *debugdir); +int build_id_cache__remove_s(const char *sbuild_id); void disable_buildid_cache(void); #endif -- GitLab From 5cb113fd84f72b6e08c1970d612fd61327781d4e Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Tue, 10 Feb 2015 18:18:53 +0900 Subject: [PATCH 00098/11651] perf buildid-cache: Consolidate .build-id cache path generators Consolidate .build-id cache path generating routines to build_id__filename() function. Other functions must use it to get the buildid cache path (link path) from build-id. This can reduce the risk of partial-update. Signed-off-by: Masami Hiramatsu Acked-by: Namhyung Kim Cc: Adrian Hunter Cc: Borislav Petkov Cc: Hemant Kumar Cc: Jiri Olsa Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20150210091853.19264.58513.stgit@localhost.localdomain Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/build-id.c | 58 +++++++++++++++++++++++++++----------- 1 file changed, 41 insertions(+), 17 deletions(-) diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index 9f764f633e57..adbc36028636 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c @@ -93,6 +93,35 @@ int build_id__sprintf(const u8 *build_id, int len, char *bf) return raw - build_id; } +/* asnprintf consolidates asprintf and snprintf */ +static int asnprintf(char **strp, size_t size, const char *fmt, ...) +{ + va_list ap; + int ret; + + if (!strp) + return -EINVAL; + + va_start(ap, fmt); + if (*strp) + ret = vsnprintf(*strp, size, fmt, ap); + else + ret = vasprintf(strp, fmt, ap); + va_end(ap); + + return ret; +} + +static char *build_id__filename(const char *sbuild_id, char *bf, size_t size) +{ + char *tmp = bf; + int ret = asnprintf(&bf, size, "%s/.build-id/%.2s/%s", buildid_dir, + sbuild_id, sbuild_id + 2); + if (ret < 0 || (tmp && size < (unsigned int)ret)) + return NULL; + return bf; +} + char *dso__build_id_filename(const struct dso *dso, char *bf, size_t size) { char build_id_hex[BUILD_ID_SIZE * 2 + 1]; @@ -101,14 +130,7 @@ char *dso__build_id_filename(const struct dso *dso, char *bf, size_t size) return NULL; build_id__sprintf(dso->build_id, sizeof(dso->build_id), build_id_hex); - if (bf == NULL) { - if (asprintf(&bf, "%s/.build-id/%.2s/%s", buildid_dir, - build_id_hex, build_id_hex + 2) < 0) - return NULL; - } else - snprintf(bf, size, "%s/.build-id/%.2s/%s", buildid_dir, - build_id_hex, build_id_hex + 2); - return bf; + return build_id__filename(build_id_hex, bf, size); } #define dsos__for_each_with_build_id(pos, head) \ @@ -264,7 +286,7 @@ int build_id_cache__add_s(const char *sbuild_id, const char *name, { const size_t size = PATH_MAX; char *realname, *filename = zalloc(size), - *linkname = zalloc(size), *targetname; + *linkname = zalloc(size), *targetname, *tmp; int len, err = -1; bool slash = is_kallsyms || is_vdso; @@ -297,13 +319,15 @@ int build_id_cache__add_s(const char *sbuild_id, const char *name, goto out_free; } - len = scnprintf(linkname, size, "%s/.build-id/%.2s", - buildid_dir, sbuild_id); + if (!build_id__filename(sbuild_id, linkname, size)) + goto out_free; + tmp = strrchr(linkname, '/'); + *tmp = '\0'; if (access(linkname, X_OK) && mkdir_p(linkname, 0755)) goto out_free; - snprintf(linkname + len, size - len, "/%s", sbuild_id + 2); + *tmp = '/'; targetname = filename + strlen(buildid_dir) - 5; memcpy(targetname, "../..", 5); @@ -332,14 +356,14 @@ int build_id_cache__remove_s(const char *sbuild_id) { const size_t size = PATH_MAX; char *filename = zalloc(size), - *linkname = zalloc(size); + *linkname = zalloc(size), *tmp; int err = -1; if (filename == NULL || linkname == NULL) goto out_free; - snprintf(linkname, size, "%s/.build-id/%.2s/%s", - buildid_dir, sbuild_id, sbuild_id + 2); + if (!build_id__filename(sbuild_id, linkname, size)) + goto out_free; if (access(linkname, F_OK)) goto out_free; @@ -353,8 +377,8 @@ int build_id_cache__remove_s(const char *sbuild_id) /* * Since the link is relative, we must make it absolute: */ - snprintf(linkname, size, "%s/.build-id/%.2s/%s", - buildid_dir, sbuild_id, filename); + tmp = strrchr(linkname, '/') + 1; + snprintf(tmp, size - (tmp - linkname), "%s", filename); if (unlink(linkname)) goto out_free; -- GitLab From 39f5704399042fff5f0d5f6af32bbbc3e787a897 Mon Sep 17 00:00:00 2001 From: Josh Boyer Date: Wed, 11 Feb 2015 11:24:05 -0500 Subject: [PATCH 00099/11651] perf tools: Define _GNU_SOURCE on pthread_attr_setaffinity_np feature check The man page for pthread_attr_set_affinity_np states that _GNU_SOURCE must be defined before pthread.h is included in order to get the proper function declaration. Define this in the Makefile. Without this defined, the feature check fails on a Fedora system with gcc5 and then the perf build later fails with conflicting prototypes for the function. Signed-off-by: Josh Boyer Cc: Jiri Olsa Cc: Peter Zijlstra Cc: Vineet Gupta Link: http://lkml.kernel.org/r/20150211162404.GA15522@hansolo.redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/config/feature-checks/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/config/feature-checks/Makefile b/tools/perf/config/feature-checks/Makefile index 42ac05aaf8ac..b32ff3372514 100644 --- a/tools/perf/config/feature-checks/Makefile +++ b/tools/perf/config/feature-checks/Makefile @@ -49,7 +49,7 @@ test-hello.bin: $(BUILD) test-pthread-attr-setaffinity-np.bin: - $(BUILD) -Werror -lpthread + $(BUILD) -D_GNU_SOURCE -Werror -lpthread test-stackprotector-all.bin: $(BUILD) -Werror -fstack-protector-all -- GitLab From c819e2cf2eb6f65d3208d195d7a0edef6108d533 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 29 Dec 2014 13:51:45 +0100 Subject: [PATCH 00100/11651] tools build: Add new build support Adding new build framework into 'tools/build' to be used by tools. There's no change for actual building at this point, it comes in the next patches. The idea and more details are explained in the 'tools/build/Documentation/Build.txt' file. I adopted everything from the kernel build system, with some changes to allow for multiple binaries build definitions. While the kernel's build output is single image (forget modules) we need to be able to build several binaries/libraries. The basic idea is that sser provides 'Build' files with objects definitions like: perf-y += a.o perf-y += b.o libperf-y += c.o libperf-y += d.o and the build framework outputs files: perf-in.o # a.o, b.o compiled in libperf-in.o # c.o, d.o compiled in Signed-off-by: Jiri Olsa Tested-by: Sukadev Bhattiprolu Tested-by: Will Deacon Cc: Alexis Berlemont Cc: Borislav Petkov Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-fbj22h4av0otlxupwcmrxgpa@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/build/Build.include | 81 ++++++++++++++++ tools/build/Documentation/Build.txt | 139 ++++++++++++++++++++++++++++ tools/build/Makefile.build | 97 +++++++++++++++++++ tools/build/tests/ex/Build | 8 ++ tools/build/tests/ex/Makefile | 23 +++++ tools/build/tests/ex/a.c | 5 + tools/build/tests/ex/arch/Build | 2 + tools/build/tests/ex/arch/e.c | 5 + tools/build/tests/ex/arch/f.c | 5 + tools/build/tests/ex/b.c | 5 + tools/build/tests/ex/c.c | 5 + tools/build/tests/ex/d.c | 5 + tools/build/tests/ex/empty/Build | 0 tools/build/tests/ex/ex.c | 19 ++++ tools/build/tests/run.sh | 42 +++++++++ tools/perf/MANIFEST | 1 + 16 files changed, 442 insertions(+) create mode 100644 tools/build/Build.include create mode 100644 tools/build/Documentation/Build.txt create mode 100644 tools/build/Makefile.build create mode 100644 tools/build/tests/ex/Build create mode 100644 tools/build/tests/ex/Makefile create mode 100644 tools/build/tests/ex/a.c create mode 100644 tools/build/tests/ex/arch/Build create mode 100644 tools/build/tests/ex/arch/e.c create mode 100644 tools/build/tests/ex/arch/f.c create mode 100644 tools/build/tests/ex/b.c create mode 100644 tools/build/tests/ex/c.c create mode 100644 tools/build/tests/ex/d.c create mode 100644 tools/build/tests/ex/empty/Build create mode 100644 tools/build/tests/ex/ex.c create mode 100755 tools/build/tests/run.sh diff --git a/tools/build/Build.include b/tools/build/Build.include new file mode 100644 index 000000000000..4c8daaccb82a --- /dev/null +++ b/tools/build/Build.include @@ -0,0 +1,81 @@ +### +# build: Generic definitions +# +# Lots of this code have been borrowed or heavily inspired from parts +# of kbuild code, which is not credited, but mostly developed by: +# +# Copyright (C) Sam Ravnborg , 2015 +# Copyright (C) Linus Torvalds , 2015 +# + +### +# Convenient variables +comma := , +squote := ' + +### +# Name of target with a '.' as filename prefix. foo/bar.o => foo/.bar.o +dot-target = $(dir $@).$(notdir $@) + +### +# filename of target with directory and extension stripped +basetarget = $(basename $(notdir $@)) + +### +# The temporary file to save gcc -MD generated dependencies must not +# contain a comma +depfile = $(subst $(comma),_,$(dot-target).d) + +### +# Check if both arguments has same arguments. Result is empty string if equal. +arg-check = $(strip $(filter-out $(cmd_$(1)), $(cmd_$@)) \ + $(filter-out $(cmd_$@), $(cmd_$(1))) ) + +### +# Escape single quote for use in echo statements +escsq = $(subst $(squote),'\$(squote)',$1) + +# Echo command +# Short version is used, if $(quiet) equals `quiet_', otherwise full one. +echo-cmd = $(if $($(quiet)cmd_$(1)),\ + echo ' $(call escsq,$($(quiet)cmd_$(1)))';) + +### +# Replace >$< with >$$< to preserve $ when reloading the .cmd file +# (needed for make) +# Replace >#< with >\#< to avoid starting a comment in the .cmd file +# (needed for make) +# Replace >'< with >'\''< to be able to enclose the whole string in '...' +# (needed for the shell) +make-cmd = $(call escsq,$(subst \#,\\\#,$(subst $$,$$$$,$(cmd_$(1))))) + +### +# Find any prerequisites that is newer than target or that does not exist. +# PHONY targets skipped in both cases. +any-prereq = $(filter-out $(PHONY),$?) $(filter-out $(PHONY) $(wildcard $^),$^) + +### +# if_changed_dep - execute command if any prerequisite is newer than +# target, or command line has changed and update +# dependencies in the cmd file +if_changed_dep = $(if $(strip $(any-prereq) $(arg-check)), \ + @set -e; \ + $(echo-cmd) $(cmd_$(1)); \ + cat $(depfile) > $(dot-target).cmd; \ + printf '%s\n' 'cmd_$@ := $(make-cmd)' >> $(dot-target).cmd) + +# if_changed - execute command if any prerequisite is newer than +# target, or command line has changed +if_changed = $(if $(strip $(any-prereq) $(arg-check)), \ + @set -e; \ + $(echo-cmd) $(cmd_$(1)); \ + printf '%s\n' 'cmd_$@ := $(make-cmd)' > $(dot-target).cmd) + +### +# C flags to be used in rule definitions, includes: +# - depfile generation +# - global $(CFLAGS) +# - per target C flags +# - per object C flags +# - BUILD_STR macro to allow '-D"$(variable)"' constructs +c_flags = -Wp,-MD,$(depfile),-MT,$@ $(CFLAGS) -D"BUILD_STR(s)=\#s" $(CFLAGS_$(basetarget).o) $(CFLAGS_$(obj)) diff --git a/tools/build/Documentation/Build.txt b/tools/build/Documentation/Build.txt new file mode 100644 index 000000000000..00ad2d608727 --- /dev/null +++ b/tools/build/Documentation/Build.txt @@ -0,0 +1,139 @@ +Build Framework +=============== + +The perf build framework was adopted from the kernel build system, hence the +idea and the way how objects are built is the same. + +Basically the user provides set of 'Build' files that list objects and +directories to nest for specific target to be build. + +Unlike the kernel we don't have a single build object 'obj-y' list that where +we setup source objects, but we support more. This allows one 'Build' file to +carry a sources list for multiple build objects. + +a) Build framework makefiles +---------------------------- + +The build framework consists of 2 Makefiles: + + Build.include + Makefile.build + +While the 'Build.include' file contains just some generic definitions, the +'Makefile.build' file is the makefile used from the outside. It's +interface/usage is following: + + $ make -f tools/build/Makefile srctree=$(KSRC) dir=$(DIR) obj=$(OBJECT) + +where: + + KSRC - is the path to kernel sources + DIR - is the path to the project to be built + OBJECT - is the name of the build object + +When succefully finished the $(DIR) directory contains the final object file +called $(OBJECT)-in.o: + + $ ls $(DIR)/$(OBJECT)-in.o + +which includes all compiled sources described in 'Build' makefiles. + +a) Build makefiles +------------------ + +The user supplies 'Build' makefiles that contains a objects list, and connects +the build to nested directories. + +Assume we have the following project structure: + + ex/a.c + /b.c + /c.c + /d.c + /arch/e.c + /arch/f.c + +Out of which you build the 'ex' binary ' and the 'libex.a' library: + + 'ex' - consists of 'a.o', 'b.o' and libex.a + 'libex.a' - consists of 'c.o', 'd.o', 'e.o' and 'f.o' + +The build framework does not create the 'ex' and 'libex.a' binaries for you, it +only prepares proper objects to be compiled and grouped together. + +To follow the above example, the user provides following 'Build' files: + + ex/Build: + ex-y += a.o + ex-y += b.o + + libex-y += c.o + libex-y += d.o + libex-y += arch/ + + ex/arch/Build: + libex-y += e.o + libex-y += f.o + +and runs: + + $ make -f tools/build/Makefile.build dir=. obj=ex + $ make -f tools/build/Makefile.build dir=. obj=libex + +which creates the following objects: + + ex/ex-in.o + ex/libex-in.o + +that contain request objects names in Build files. + +It's only a matter of 2 single commands to create the final binaries: + + $ ar rcs libex.a libex-in.o + $ gcc -o ex ex-in.o libex.a + +You can check the 'ex' example in 'tools/build/tests/ex' for more details. + +b) Rules +-------- + +The build framework provides standard compilation rules to handle .S and .c +compilation. + +It's possible to include special rule if needed (like we do for flex or bison +code generation). + +c) CFLAGS +--------- + +It's possible to alter the standard object C flags in the following way: + + CFLAGS_perf.o += '...' - alters CFLAGS for perf.o object + CFLAGS_gtk += '...' - alters CFLAGS for gtk build object + +This C flags changes has the scope of the Build makefile they are defined in. + + +d) Dependencies +--------------- + +For each built object file 'a.o' the '.a.cmd' is created and holds: + + - Command line used to built that object + (for each object) + + - Dependency rules generated by 'gcc -Wp,-MD,...' + (for compiled object) + +All existing '.cmd' files are included in the Build process to follow properly +the dependencies and trigger a rebuild when necessary. + + +e) Single rules +--------------- + +It's possible to build single object file by choice, like: + + $ make util/map.o # objects + $ make util/map.i # preprocessor + $ make util/map.s # assembly diff --git a/tools/build/Makefile.build b/tools/build/Makefile.build new file mode 100644 index 000000000000..ae203f21cc86 --- /dev/null +++ b/tools/build/Makefile.build @@ -0,0 +1,97 @@ +### +# Main build makefile. +# +# Lots of this code have been borrowed or heavily inspired from parts +# of kbuild code, which is not credited, but mostly developed by: +# +# Copyright (C) Sam Ravnborg , 2015 +# Copyright (C) Linus Torvalds , 2015 +# + +PHONY := __build +__build: + +ifeq ($(V),1) + quiet = +else + quiet=quiet_ +endif + +build-dir := $(srctree)/tools/build + +# Generic definitions +include $(build-dir)/Build.include + +# Init all relevant variables used in build files so +# 1) they have correct type +# 2) they do not inherit any value from the environment +subdir-y := +obj-y := +subdir-y := +subdir-obj-y := + +# Build definitions +build-file := $(dir)/Build +include $(build-file) + +# Compile command +quiet_cmd_cc_o_c = CC $@ + cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< + +# Link agregate command +# If there's nothing to link, create empty $@ object. +quiet_cmd_ld_multi = LD $@ + cmd_ld_multi = $(if $(strip $(obj-y)),\ + $(LD) -r -o $@ $(obj-y),rm -f $@; $(AR) rcs $@) + +# Build rules +$(OUTPUT)%.o: %.c FORCE + $(call if_changed_dep,cc_o_c) + +$(OUTPUT)%.o: %.S FORCE + $(call if_changed_dep,cc_o_c) + +# Gather build data: +# obj-y - list of build objects +# subdir-y - list of directories to nest +# subdir-obj-y - list of directories objects 'dir/$(obj)-in.o' +obj-y := $($(obj)-y) +subdir-y := $(patsubst %/,%,$(filter %/, $(obj-y))) +obj-y := $(patsubst %/, %/$(obj)-in.o, $(obj-y)) +subdir-obj-y := $(filter %/$(obj)-in.o, $(obj-y)) + +# '$(OUTPUT)/dir' prefix to all objects +prefix := $(subst ./,,$(OUTPUT)$(dir)/) +obj-y := $(addprefix $(prefix),$(obj-y)) +subdir-obj-y := $(addprefix $(prefix),$(subdir-obj-y)) + +# Final '$(obj)-in.o' object +in-target := $(prefix)$(obj)-in.o + +PHONY += $(subdir-y) + +$(subdir-y): + @$(MAKE) -f $(build-dir)/Makefile.build dir=$(dir)/$@ obj=$(obj) + +$(sort $(subdir-obj-y)): $(subdir-y) ; + +$(in-target): $(obj-y) FORCE + $(call rule_mkdir) + $(call if_changed,ld_multi) + +__build: $(in-target) + @: + +PHONY += FORCE +FORCE: + +# Include all cmd files to get all the dependency rules +# for all objects included +targets := $(wildcard $(sort $(obj-y) $(in-target))) +cmd_files := $(wildcard $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd)) + +ifneq ($(cmd_files),) + include $(cmd_files) +endif + +.PHONY: $(PHONY) diff --git a/tools/build/tests/ex/Build b/tools/build/tests/ex/Build new file mode 100644 index 000000000000..0e6c3e6767e6 --- /dev/null +++ b/tools/build/tests/ex/Build @@ -0,0 +1,8 @@ +ex-y += ex.o +ex-y += a.o +ex-y += b.o +ex-y += empty/ + +libex-y += c.o +libex-y += d.o +libex-y += arch/ diff --git a/tools/build/tests/ex/Makefile b/tools/build/tests/ex/Makefile new file mode 100644 index 000000000000..52d2476073a3 --- /dev/null +++ b/tools/build/tests/ex/Makefile @@ -0,0 +1,23 @@ +export srctree := ../../../.. +export CC := gcc +export LD := ld +export AR := ar + +build := -f $(srctree)/tools/build/Makefile.build dir=. obj +ex: ex-in.o libex-in.o + gcc -o $@ $^ + +ex.%: FORCE + make -f $(srctree)/tools/build/Makefile.build dir=. $@ + +ex-in.o: FORCE + make $(build)=ex + +libex-in.o: FORCE + make $(build)=libex + +clean: + find . -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete + rm -f ex ex.i ex.s + +.PHONY: FORCE diff --git a/tools/build/tests/ex/a.c b/tools/build/tests/ex/a.c new file mode 100644 index 000000000000..851762798c83 --- /dev/null +++ b/tools/build/tests/ex/a.c @@ -0,0 +1,5 @@ + +int a(void) +{ + return 0; +} diff --git a/tools/build/tests/ex/arch/Build b/tools/build/tests/ex/arch/Build new file mode 100644 index 000000000000..55506189efae --- /dev/null +++ b/tools/build/tests/ex/arch/Build @@ -0,0 +1,2 @@ +libex-y += e.o +libex-y += f.o diff --git a/tools/build/tests/ex/arch/e.c b/tools/build/tests/ex/arch/e.c new file mode 100644 index 000000000000..beaa4a1d7ba8 --- /dev/null +++ b/tools/build/tests/ex/arch/e.c @@ -0,0 +1,5 @@ + +int e(void) +{ + return 0; +} diff --git a/tools/build/tests/ex/arch/f.c b/tools/build/tests/ex/arch/f.c new file mode 100644 index 000000000000..7c3e9e9da5b7 --- /dev/null +++ b/tools/build/tests/ex/arch/f.c @@ -0,0 +1,5 @@ + +int f(void) +{ + return 0; +} diff --git a/tools/build/tests/ex/b.c b/tools/build/tests/ex/b.c new file mode 100644 index 000000000000..c24ff9ca9a97 --- /dev/null +++ b/tools/build/tests/ex/b.c @@ -0,0 +1,5 @@ + +int b(void) +{ + return 0; +} diff --git a/tools/build/tests/ex/c.c b/tools/build/tests/ex/c.c new file mode 100644 index 000000000000..e216d0217499 --- /dev/null +++ b/tools/build/tests/ex/c.c @@ -0,0 +1,5 @@ + +int c(void) +{ + return 0; +} diff --git a/tools/build/tests/ex/d.c b/tools/build/tests/ex/d.c new file mode 100644 index 000000000000..80dc0f06151b --- /dev/null +++ b/tools/build/tests/ex/d.c @@ -0,0 +1,5 @@ + +int d(void) +{ + return 0; +} diff --git a/tools/build/tests/ex/empty/Build b/tools/build/tests/ex/empty/Build new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/tools/build/tests/ex/ex.c b/tools/build/tests/ex/ex.c new file mode 100644 index 000000000000..dc42eb2e1a67 --- /dev/null +++ b/tools/build/tests/ex/ex.c @@ -0,0 +1,19 @@ + +int a(void); +int b(void); +int c(void); +int d(void); +int e(void); +int f(void); + +int main(void) +{ + a(); + b(); + c(); + d(); + e(); + f(); + + return 0; +} diff --git a/tools/build/tests/run.sh b/tools/build/tests/run.sh new file mode 100755 index 000000000000..5494f8ea7567 --- /dev/null +++ b/tools/build/tests/run.sh @@ -0,0 +1,42 @@ +#!/bin/sh + +function test_ex { + make -C ex V=1 clean > ex.out 2>&1 + make -C ex V=1 >> ex.out 2>&1 + + if [ ! -x ./ex/ex ]; then + echo FAILED + exit -1 + fi + + make -C ex V=1 clean > /dev/null 2>&1 + rm -f ex.out +} + +function test_ex_suffix { + make -C ex V=1 clean > ex.out 2>&1 + + # use -rR to disable make's builtin rules + make -rR -C ex V=1 ex.o >> ex.out 2>&1 + make -rR -C ex V=1 ex.i >> ex.out 2>&1 + make -rR -C ex V=1 ex.s >> ex.out 2>&1 + + if [ -x ./ex/ex ]; then + echo FAILED + exit -1 + fi + + if [ ! -f ./ex/ex.o -o ! -f ./ex/ex.i -o ! -f ./ex/ex.s ]; then + echo FAILED + exit -1 + fi + + make -C ex V=1 clean > /dev/null 2>&1 + rm -f ex.out +} +echo -n Testing.. + +test_ex +test_ex_suffix + +echo OK diff --git a/tools/perf/MANIFEST b/tools/perf/MANIFEST index fbbfdc39271d..11ccbb22ea2b 100644 --- a/tools/perf/MANIFEST +++ b/tools/perf/MANIFEST @@ -1,5 +1,6 @@ tools/perf tools/scripts +tools/build tools/lib/traceevent tools/lib/api tools/lib/symbol/kallsyms.c -- GitLab From ffa047577127336861d91f3934133f8e8906d1b4 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Wed, 11 Feb 2015 13:13:18 -0800 Subject: [PATCH 00101/11651] ASoC: Fix MAX98357A codec driver dependencies The max98357a driver depends on GPIOLIB. This may cause the following build failure. sound/soc/codecs/max98357a.c: In function 'max98357a_daiops_trigger': sound/soc/codecs/max98357a.c:30:3: error: implicit declaration of function 'gpiod_set_value' sound/soc/codecs/max98357a.c: In function 'max98357a_codec_probe': sound/soc/codecs/max98357a.c:55:2: error: implicit declaration of function 'devm_gpiod_get' sound/soc/codecs/max98357a.c:61:2: error: implicit declaration of function 'gpiod_direction_output' Seen with mips:allmodconfig as well as various randconfig builds. Fixes: af5adf129369 ("ASoC: max98357a: Add MAX98357A codec driver") Cc: Kenneth Westfield Signed-off-by: Guenter Roeck Signed-off-by: Mark Brown --- sound/soc/codecs/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 064e6c18e109..ea9f0e31f9d4 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -69,7 +69,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_MAX98088 if I2C select SND_SOC_MAX98090 if I2C select SND_SOC_MAX98095 if I2C - select SND_SOC_MAX98357A + select SND_SOC_MAX98357A if GPIOLIB select SND_SOC_MAX9850 if I2C select SND_SOC_MAX9768 if I2C select SND_SOC_MAX9877 if I2C -- GitLab From 5c8be987d4d9c0262e6229e342fa0da8a5aeee47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vincent=20Stehl=C3=A9?= Date: Wed, 11 Feb 2015 23:08:59 +0100 Subject: [PATCH 00102/11651] ASoC: max98357a: Fix missing include MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes the following compilation errors: sound/soc/codecs/max98357a.c: In function ‘max98357a_daiops_trigger’: sound/soc/codecs/max98357a.c:30:3: error: implicit declaration of function ‘gpiod_set_value’ [-Werror=implicit-function-declaration] sound/soc/codecs/max98357a.c: In function ‘max98357a_codec_probe’: sound/soc/codecs/max98357a.c:55:2: error: implicit declaration of function ‘devm_gpiod_get’ [-Werror=implicit-function-declaration] sound/soc/codecs/max98357a.c:61:2: error: implicit declaration of function ‘gpiod_direction_output’ [-Werror=implicit-function-declaration] cc1: some warnings being treated as errors Signed-off-by: Vincent Stehlé Cc: Kenneth Westfield Cc: Mark Brown Signed-off-by: Mark Brown --- sound/soc/codecs/max98357a.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/codecs/max98357a.c b/sound/soc/codecs/max98357a.c index 1806333ea29e..f493fb6fd4ea 100644 --- a/sound/soc/codecs/max98357a.c +++ b/sound/soc/codecs/max98357a.c @@ -14,6 +14,7 @@ #include #include +#include #include #define DRV_NAME "max98357a" -- GitLab From e09dcd2e7913aa50b5cb4836bc1e990e429e4aff Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 11 Feb 2015 19:47:00 -0800 Subject: [PATCH 00103/11651] Revert "crypto: Fix regressions caused by iov_iter changes." This reverts commit 750d8065d88bc72bd6e1fd9f896a964c35dda818. Linus already fixed this in his tree so just use what he did. Signed-off-by: David S. Miller --- crypto/af_alg.c | 2 +- crypto/algif_skcipher.c | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/crypto/af_alg.c b/crypto/af_alg.c index 5b11d645343d..eb78fe8a60c8 100644 --- a/crypto/af_alg.c +++ b/crypto/af_alg.c @@ -348,7 +348,7 @@ int af_alg_make_sg(struct af_alg_sgl *sgl, struct iov_iter *iter, int len) if (n < 0) return n; - npages = DIV_ROUND_UP(off + n, PAGE_SIZE); + npages = PAGE_ALIGN(off + n); if (WARN_ON(npages == 0)) return -EINVAL; diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c index 0eb31a69a0a6..37110fd68adf 100644 --- a/crypto/algif_skcipher.c +++ b/crypto/algif_skcipher.c @@ -427,11 +427,11 @@ static int skcipher_recvmsg(struct kiocb *unused, struct socket *sock, struct skcipher_sg_list *sgl; struct scatterlist *sg; int err = -EAGAIN; + int used; long copied = 0; lock_sock(sk); while (iov_iter_count(&msg->msg_iter)) { - int used; sgl = list_first_entry(&ctx->tsgl, struct skcipher_sg_list, list); sg = sgl->sg; @@ -439,13 +439,14 @@ static int skcipher_recvmsg(struct kiocb *unused, struct socket *sock, while (!sg->length) sg++; - if (!ctx->used) { + used = ctx->used; + if (!used) { err = skcipher_wait_for_data(sk, flags); if (err) goto unlock; } - used = min_t(unsigned long, ctx->used, iov_iter_count(&msg->msg_iter)); + used = min_t(unsigned long, used, iov_iter_count(&msg->msg_iter)); used = af_alg_make_sg(&ctx->rsgl, &msg->msg_iter, used); err = used; -- GitLab From ac37e2515c1a89c477459a2020b6bfdedabdb91b Mon Sep 17 00:00:00 2001 From: huaibin Wang Date: Wed, 11 Feb 2015 18:10:36 +0100 Subject: [PATCH 00104/11651] xfrm: release dst_orig in case of error in xfrm_lookup() dst_orig should be released on error. Function like __xfrm_route_forward() expects that behavior. Since a recent commit, xfrm_lookup() may also be called by xfrm_lookup_route(), which expects the opposite. Let's introduce a new flag (XFRM_LOOKUP_KEEP_DST_REF) to tell what should be done in case of error. Fixes: f92ee61982d("xfrm: Generate blackhole routes only from route lookup functions") Signed-off-by: huaibin Wang Signed-off-by: Nicolas Dichtel Signed-off-by: Steffen Klassert --- include/net/dst.h | 1 + net/xfrm/xfrm_policy.c | 12 ++++++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/include/net/dst.h b/include/net/dst.h index a8ae4e760778..0fb99a26e973 100644 --- a/include/net/dst.h +++ b/include/net/dst.h @@ -481,6 +481,7 @@ void dst_init(void); enum { XFRM_LOOKUP_ICMP = 1 << 0, XFRM_LOOKUP_QUEUE = 1 << 1, + XFRM_LOOKUP_KEEP_DST_REF = 1 << 2, }; struct flowi; diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index cee479bc655c..638af0655aaf 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -2269,11 +2269,9 @@ struct dst_entry *xfrm_lookup(struct net *net, struct dst_entry *dst_orig, * have the xfrm_state's. We need to wait for KM to * negotiate new SA's or bail out with error.*/ if (net->xfrm.sysctl_larval_drop) { - dst_release(dst); - xfrm_pols_put(pols, drop_pols); XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTNOSTATES); - - return ERR_PTR(-EREMOTE); + err = -EREMOTE; + goto error; } err = -EAGAIN; @@ -2324,7 +2322,8 @@ nopol: error: dst_release(dst); dropdst: - dst_release(dst_orig); + if (!(flags & XFRM_LOOKUP_KEEP_DST_REF)) + dst_release(dst_orig); xfrm_pols_put(pols, drop_pols); return ERR_PTR(err); } @@ -2338,7 +2337,8 @@ struct dst_entry *xfrm_lookup_route(struct net *net, struct dst_entry *dst_orig, struct sock *sk, int flags) { struct dst_entry *dst = xfrm_lookup(net, dst_orig, fl, sk, - flags | XFRM_LOOKUP_QUEUE); + flags | XFRM_LOOKUP_QUEUE | + XFRM_LOOKUP_KEEP_DST_REF); if (IS_ERR(dst) && PTR_ERR(dst) == -EREMOTE) return make_blackhole(net, dst_orig->ops->family, dst_orig); -- GitLab From b6a42670e074da39b5a9f990774359e0733ca9cd Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 11 Feb 2015 22:37:16 +0100 Subject: [PATCH 00105/11651] ALSA: seq: Move EXPORT_SYMBOL() after each function ... to follow the standard coding style. Signed-off-by: Takashi Iwai --- sound/core/seq/seq_device.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/sound/core/seq/seq_device.c b/sound/core/seq/seq_device.c index 0631bdadd12b..a752a79a8d3a 100644 --- a/sound/core/seq/seq_device.c +++ b/sound/core/seq/seq_device.c @@ -133,11 +133,13 @@ void snd_seq_autoload_lock(void) { atomic_inc(&snd_seq_in_init); } +EXPORT_SYMBOL(snd_seq_autoload_lock); void snd_seq_autoload_unlock(void) { atomic_dec(&snd_seq_in_init); } +EXPORT_SYMBOL(snd_seq_autoload_unlock); static void autoload_drivers(void) { @@ -195,10 +197,12 @@ void snd_seq_autoload_init(void) queue_autoload_drivers(); #endif } +EXPORT_SYMBOL(snd_seq_autoload_init); #else #define try_autoload(ops) /* NOP */ #endif + void snd_seq_device_load_drivers(void) { #ifdef CONFIG_MODULES @@ -206,6 +210,7 @@ void snd_seq_device_load_drivers(void) flush_work(&autoload_work); #endif } +EXPORT_SYMBOL(snd_seq_device_load_drivers); /* * register a sequencer device @@ -268,6 +273,7 @@ int snd_seq_device_new(struct snd_card *card, int device, char *id, int argsize, return 0; } +EXPORT_SYMBOL(snd_seq_device_new); /* * free the existing device @@ -326,6 +332,7 @@ static int snd_seq_device_dev_register(struct snd_device *device) unlock_driver(ops); return 0; } +EXPORT_SYMBOL(snd_seq_device_register_driver); /* * disconnect the device @@ -344,6 +351,7 @@ static int snd_seq_device_dev_disconnect(struct snd_device *device) unlock_driver(ops); return 0; } +EXPORT_SYMBOL(snd_seq_device_unregister_driver); /* * register device driver @@ -604,13 +612,3 @@ static void __exit alsa_seq_device_exit(void) module_init(alsa_seq_device_init) module_exit(alsa_seq_device_exit) - -EXPORT_SYMBOL(snd_seq_device_load_drivers); -EXPORT_SYMBOL(snd_seq_device_new); -EXPORT_SYMBOL(snd_seq_device_register_driver); -EXPORT_SYMBOL(snd_seq_device_unregister_driver); -#ifdef CONFIG_MODULES -EXPORT_SYMBOL(snd_seq_autoload_init); -EXPORT_SYMBOL(snd_seq_autoload_lock); -EXPORT_SYMBOL(snd_seq_autoload_unlock); -#endif -- GitLab From 72496edcf85e048b4c5373d518e4f27938d9594e Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 11 Feb 2015 22:39:51 +0100 Subject: [PATCH 00106/11651] ALSA: seq: Don't compile snd_seq_device_load_drivers() for built-in Signed-off-by: Takashi Iwai --- include/sound/seq_device.h | 4 ++++ sound/core/seq/seq_device.c | 9 +++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/include/sound/seq_device.h b/include/sound/seq_device.h index 2b5f24cc7548..d52433563da2 100644 --- a/include/sound/seq_device.h +++ b/include/sound/seq_device.h @@ -67,7 +67,11 @@ struct snd_seq_dev_ops { /* * prototypes */ +#ifdef CONFIG_MODULES void snd_seq_device_load_drivers(void); +#else +#define snd_seq_device_load_drivers() +#endif int snd_seq_device_new(struct snd_card *card, int device, char *id, int argsize, struct snd_seq_device **result); int snd_seq_device_register_driver(char *id, struct snd_seq_dev_ops *entry, int argsize); int snd_seq_device_unregister_driver(char *id); diff --git a/sound/core/seq/seq_device.c b/sound/core/seq/seq_device.c index a752a79a8d3a..075a66c0cc6a 100644 --- a/sound/core/seq/seq_device.c +++ b/sound/core/seq/seq_device.c @@ -198,19 +198,16 @@ void snd_seq_autoload_init(void) #endif } EXPORT_SYMBOL(snd_seq_autoload_init); -#else -#define try_autoload(ops) /* NOP */ -#endif - void snd_seq_device_load_drivers(void) { -#ifdef CONFIG_MODULES queue_autoload_drivers(); flush_work(&autoload_work); -#endif } EXPORT_SYMBOL(snd_seq_device_load_drivers); +#else +#define try_autoload(ops) /* NOP */ +#endif /* * register a sequencer device -- GitLab From 7c37ae5c625aaa4836466cfaea829a3199dfc571 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 12 Feb 2015 10:51:59 +0100 Subject: [PATCH 00107/11651] ALSA: seq: Rewrite sequencer device binding with standard bus We've used the old house-made code for binding the sequencer device and driver. This can be far better implemented with the standard bus nowadays. This patch refactors the whole sequencer binding code with the bus /sys/bus/snd_seq. The devices appear as id-card-device on this bus and are bound with the drivers corresponding to the given id like the former implementation. The module autoload is also kept like before. There is no change in API functions by this patch, and almost all transitions are kept inside seq_device.c. The proc file output will change slightly but kept compatible as much as possible. Further integration works will follow in later patches. Signed-off-by: Takashi Iwai --- include/sound/seq_device.h | 3 + sound/core/seq/seq_device.c | 541 +++++++++++------------------------- 2 files changed, 170 insertions(+), 374 deletions(-) diff --git a/include/sound/seq_device.h b/include/sound/seq_device.h index d52433563da2..ea256b825146 100644 --- a/include/sound/seq_device.h +++ b/include/sound/seq_device.h @@ -43,8 +43,11 @@ struct snd_seq_device { void *private_data; /* private data for the caller */ void (*private_free)(struct snd_seq_device *device); struct list_head list; /* link to next device */ + struct device dev; }; +#define to_seq_dev(_dev) \ + container_of(_dev, struct snd_seq_device, dev) /* driver operators * init_device: diff --git a/sound/core/seq/seq_device.c b/sound/core/seq/seq_device.c index 075a66c0cc6a..d3320ffe43c2 100644 --- a/sound/core/seq/seq_device.c +++ b/sound/core/seq/seq_device.c @@ -36,6 +36,7 @@ * */ +#include #include #include #include @@ -51,77 +52,57 @@ MODULE_AUTHOR("Takashi Iwai "); MODULE_DESCRIPTION("ALSA sequencer device management"); MODULE_LICENSE("GPL"); -/* driver state */ -#define DRIVER_EMPTY 0 -#define DRIVER_LOADED (1<<0) -#define DRIVER_REQUESTED (1<<1) -#define DRIVER_LOCKED (1<<2) -#define DRIVER_REQUESTING (1<<3) +struct snd_seq_driver { + struct device_driver driver; + char id[ID_LEN]; + int argsize; + struct snd_seq_dev_ops ops; +}; -struct ops_list { - char id[ID_LEN]; /* driver id */ - int driver; /* driver state */ - int used; /* reference counter */ - int argsize; /* argument size */ +#define to_seq_drv(_drv) \ + container_of(_drv, struct snd_seq_driver, driver) - /* operators */ - struct snd_seq_dev_ops ops; +/* + * bus definition + */ +static int snd_seq_bus_match(struct device *dev, struct device_driver *drv) +{ + struct snd_seq_device *sdev = to_seq_dev(dev); + struct snd_seq_driver *sdrv = to_seq_drv(drv); - /* registered devices */ - struct list_head dev_list; /* list of devices */ - int num_devices; /* number of associated devices */ - int num_init_devices; /* number of initialized devices */ - struct mutex reg_mutex; + return strcmp(sdrv->id, sdev->id) == 0 && + sdrv->argsize == sdev->argsize; +} - struct list_head list; /* next driver */ +static struct bus_type snd_seq_bus_type = { + .name = "snd_seq", + .match = snd_seq_bus_match, }; - -static LIST_HEAD(opslist); -static int num_ops; -static DEFINE_MUTEX(ops_mutex); +/* + * proc interface -- just for compatibility + */ #ifdef CONFIG_PROC_FS static struct snd_info_entry *info_entry; -#endif -/* - * prototypes - */ -static int snd_seq_device_free(struct snd_seq_device *dev); -static int snd_seq_device_dev_free(struct snd_device *device); -static int snd_seq_device_dev_register(struct snd_device *device); -static int snd_seq_device_dev_disconnect(struct snd_device *device); - -static int init_device(struct snd_seq_device *dev, struct ops_list *ops); -static int free_device(struct snd_seq_device *dev, struct ops_list *ops); -static struct ops_list *find_driver(char *id, int create_if_empty); -static struct ops_list *create_driver(char *id); -static void unlock_driver(struct ops_list *ops); -static void remove_drivers(void); +static int print_dev_info(struct device *dev, void *data) +{ + struct snd_seq_device *sdev = to_seq_dev(dev); + struct snd_info_buffer *buffer = data; -/* - * show all drivers and their status - */ + snd_iprintf(buffer, "snd-%s,%s,%d\n", sdev->id, + dev->driver ? "loaded" : "empty", + dev->driver ? 1 : 0); + return 0; +} -#ifdef CONFIG_PROC_FS static void snd_seq_device_info(struct snd_info_entry *entry, struct snd_info_buffer *buffer) { - struct ops_list *ops; - - mutex_lock(&ops_mutex); - list_for_each_entry(ops, &opslist, list) { - snd_iprintf(buffer, "snd-%s%s%s%s,%d\n", - ops->id, - ops->driver & DRIVER_LOADED ? ",loaded" : (ops->driver == DRIVER_EMPTY ? ",empty" : ""), - ops->driver & DRIVER_REQUESTED ? ",requested" : "", - ops->driver & DRIVER_LOCKED ? ",locked" : "", - ops->num_devices); - } - mutex_unlock(&ops_mutex); + bus_for_each_dev(&snd_seq_bus_type, NULL, buffer, print_dev_info); } #endif - + /* * load all registered drivers (called from seq_clientmgr.c) */ @@ -141,52 +122,29 @@ void snd_seq_autoload_unlock(void) } EXPORT_SYMBOL(snd_seq_autoload_unlock); -static void autoload_drivers(void) +static int request_seq_drv(struct device *dev, void *data) { - /* avoid reentrance */ - if (atomic_inc_return(&snd_seq_in_init) == 1) { - struct ops_list *ops; - - mutex_lock(&ops_mutex); - list_for_each_entry(ops, &opslist, list) { - if ((ops->driver & DRIVER_REQUESTING) && - !(ops->driver & DRIVER_REQUESTED)) { - ops->used++; - mutex_unlock(&ops_mutex); - ops->driver |= DRIVER_REQUESTED; - request_module("snd-%s", ops->id); - mutex_lock(&ops_mutex); - ops->used--; - } - } - mutex_unlock(&ops_mutex); - } - atomic_dec(&snd_seq_in_init); -} + struct snd_seq_device *sdev = to_seq_dev(dev); -static void call_autoload(struct work_struct *work) -{ - autoload_drivers(); + if (!dev->driver) + request_module("snd-%s", sdev->id); + return 0; } -static DECLARE_WORK(autoload_work, call_autoload); - -static void try_autoload(struct ops_list *ops) +static void autoload_drivers(struct work_struct *work) { - if (!ops->driver) { - ops->driver |= DRIVER_REQUESTING; - schedule_work(&autoload_work); - } + /* avoid reentrance */ + if (atomic_inc_return(&snd_seq_in_init) == 1) + bus_for_each_dev(&snd_seq_bus_type, NULL, NULL, + request_seq_drv); + atomic_dec(&snd_seq_in_init); } +static DECLARE_WORK(autoload_work, autoload_drivers); + static void queue_autoload_drivers(void) { - struct ops_list *ops; - - mutex_lock(&ops_mutex); - list_for_each_entry(ops, &opslist, list) - try_autoload(ops); - mutex_unlock(&ops_mutex); + schedule_work(&autoload_work); } void snd_seq_autoload_init(void) @@ -206,9 +164,50 @@ void snd_seq_device_load_drivers(void) } EXPORT_SYMBOL(snd_seq_device_load_drivers); #else -#define try_autoload(ops) /* NOP */ +#define queue_autoload_drivers() /* NOP */ #endif +/* + * device management + */ +static int snd_seq_device_dev_free(struct snd_device *device) +{ + struct snd_seq_device *dev = device->device_data; + + put_device(&dev->dev); + return 0; +} + +static int snd_seq_device_dev_register(struct snd_device *device) +{ + struct snd_seq_device *dev = device->device_data; + int err; + + err = device_add(&dev->dev); + if (err < 0) + return err; + if (!dev->dev.driver) + queue_autoload_drivers(); + return 0; +} + +static int snd_seq_device_dev_disconnect(struct snd_device *device) +{ + struct snd_seq_device *dev = device->device_data; + + device_del(&dev->dev); + return 0; +} + +static void snd_seq_dev_release(struct device *dev) +{ + struct snd_seq_device *sdev = to_seq_dev(dev); + + if (sdev->private_free) + sdev->private_free(sdev); + kfree(sdev); +} + /* * register a sequencer device * card = card info @@ -220,7 +219,6 @@ int snd_seq_device_new(struct snd_card *card, int device, char *id, int argsize, struct snd_seq_device **result) { struct snd_seq_device *dev; - struct ops_list *ops; int err; static struct snd_device_ops dops = { .dev_free = snd_seq_device_dev_free, @@ -234,15 +232,9 @@ int snd_seq_device_new(struct snd_card *card, int device, char *id, int argsize, if (snd_BUG_ON(!id)) return -EINVAL; - ops = find_driver(id, 1); - if (ops == NULL) - return -ENOMEM; - - dev = kzalloc(sizeof(*dev)*2 + argsize, GFP_KERNEL); - if (dev == NULL) { - unlock_driver(ops); + dev = kzalloc(sizeof(*dev) + argsize, GFP_KERNEL); + if (!dev) return -ENOMEM; - } /* set up device info */ dev->card = card; @@ -251,20 +243,19 @@ int snd_seq_device_new(struct snd_card *card, int device, char *id, int argsize, dev->argsize = argsize; dev->status = SNDRV_SEQ_DEVICE_FREE; - /* add this device to the list */ - mutex_lock(&ops->reg_mutex); - list_add_tail(&dev->list, &ops->dev_list); - ops->num_devices++; - mutex_unlock(&ops->reg_mutex); + device_initialize(&dev->dev); + dev->dev.parent = &card->card_dev; + dev->dev.bus = &snd_seq_bus_type; + dev->dev.release = snd_seq_dev_release; + dev_set_name(&dev->dev, "%s-%d-%d", dev->id, card->number, device); - if ((err = snd_device_new(card, SNDRV_DEV_SEQUENCER, dev, &dops)) < 0) { - snd_seq_device_free(dev); + /* add this device to the list */ + err = snd_device_new(card, SNDRV_DEV_SEQUENCER, dev, &dops); + if (err < 0) { + put_device(&dev->dev); return err; } - try_autoload(ops); - unlock_driver(ops); - if (result) *result = dev; @@ -273,82 +264,33 @@ int snd_seq_device_new(struct snd_card *card, int device, char *id, int argsize, EXPORT_SYMBOL(snd_seq_device_new); /* - * free the existing device - */ -static int snd_seq_device_free(struct snd_seq_device *dev) -{ - struct ops_list *ops; - - if (snd_BUG_ON(!dev)) - return -EINVAL; - - ops = find_driver(dev->id, 0); - if (ops == NULL) - return -ENXIO; - - /* remove the device from the list */ - mutex_lock(&ops->reg_mutex); - list_del(&dev->list); - ops->num_devices--; - mutex_unlock(&ops->reg_mutex); - - free_device(dev, ops); - if (dev->private_free) - dev->private_free(dev); - kfree(dev); - - unlock_driver(ops); - - return 0; -} - -static int snd_seq_device_dev_free(struct snd_device *device) -{ - struct snd_seq_device *dev = device->device_data; - return snd_seq_device_free(dev); -} - -/* - * register the device + * driver binding - just pass to each driver callback */ -static int snd_seq_device_dev_register(struct snd_device *device) +static int snd_seq_drv_probe(struct device *dev) { - struct snd_seq_device *dev = device->device_data; - struct ops_list *ops; - - ops = find_driver(dev->id, 0); - if (ops == NULL) - return -ENOENT; - - /* initialize this device if the corresponding driver was - * already loaded - */ - if (ops->driver & DRIVER_LOADED) - init_device(dev, ops); + struct snd_seq_driver *sdrv = to_seq_drv(dev->driver); + struct snd_seq_device *sdev = to_seq_dev(dev); + int err; - unlock_driver(ops); + err = sdrv->ops.init_device(sdev); + if (err < 0) + return err; + sdev->status = SNDRV_SEQ_DEVICE_REGISTERED; return 0; } -EXPORT_SYMBOL(snd_seq_device_register_driver); -/* - * disconnect the device - */ -static int snd_seq_device_dev_disconnect(struct snd_device *device) +static int snd_seq_drv_remove(struct device *dev) { - struct snd_seq_device *dev = device->device_data; - struct ops_list *ops; - - ops = find_driver(dev->id, 0); - if (ops == NULL) - return -ENOENT; - - free_device(dev, ops); + struct snd_seq_driver *sdrv = to_seq_drv(dev->driver); + struct snd_seq_device *sdev = to_seq_dev(dev); + int err; - unlock_driver(ops); + err = sdrv->ops.free_device(sdev); + if (err < 0) + return err; + sdev->status = SNDRV_SEQ_DEVICE_FREE; return 0; } -EXPORT_SYMBOL(snd_seq_device_unregister_driver); /* * register device driver @@ -358,226 +300,66 @@ EXPORT_SYMBOL(snd_seq_device_unregister_driver); int snd_seq_device_register_driver(char *id, struct snd_seq_dev_ops *entry, int argsize) { - struct ops_list *ops; - struct snd_seq_device *dev; + struct snd_seq_driver *sdrv; + int err; if (id == NULL || entry == NULL || entry->init_device == NULL || entry->free_device == NULL) return -EINVAL; - ops = find_driver(id, 1); - if (ops == NULL) + sdrv = kzalloc(sizeof(*sdrv), GFP_KERNEL); + if (!sdrv) return -ENOMEM; - if (ops->driver & DRIVER_LOADED) { - pr_warn("ALSA: seq: driver_register: driver '%s' already exists\n", id); - unlock_driver(ops); - return -EBUSY; - } - - mutex_lock(&ops->reg_mutex); - /* copy driver operators */ - ops->ops = *entry; - ops->driver |= DRIVER_LOADED; - ops->argsize = argsize; - /* initialize existing devices if necessary */ - list_for_each_entry(dev, &ops->dev_list, list) { - init_device(dev, ops); - } - mutex_unlock(&ops->reg_mutex); - - unlock_driver(ops); - - return 0; + sdrv->driver.name = id; + sdrv->driver.bus = &snd_seq_bus_type; + sdrv->driver.probe = snd_seq_drv_probe; + sdrv->driver.remove = snd_seq_drv_remove; + strlcpy(sdrv->id, id, sizeof(sdrv->id)); + sdrv->argsize = argsize; + sdrv->ops = *entry; + + err = driver_register(&sdrv->driver); + if (err < 0) + kfree(sdrv); + return err; } +EXPORT_SYMBOL(snd_seq_device_register_driver); - -/* - * create driver record +/* callback to find a specific driver; data is a pointer to the id string ptr. + * when the id matches, store the driver pointer in return and break the loop. */ -static struct ops_list * create_driver(char *id) +static int find_drv(struct device_driver *drv, void *data) { - struct ops_list *ops; - - ops = kzalloc(sizeof(*ops), GFP_KERNEL); - if (ops == NULL) - return ops; - - /* set up driver entry */ - strlcpy(ops->id, id, sizeof(ops->id)); - mutex_init(&ops->reg_mutex); - /* - * The ->reg_mutex locking rules are per-driver, so we create - * separate per-driver lock classes: - */ - lockdep_set_class(&ops->reg_mutex, (struct lock_class_key *)id); - - ops->driver = DRIVER_EMPTY; - INIT_LIST_HEAD(&ops->dev_list); - /* lock this instance */ - ops->used = 1; - - /* register driver entry */ - mutex_lock(&ops_mutex); - list_add_tail(&ops->list, &opslist); - num_ops++; - mutex_unlock(&ops_mutex); - - return ops; -} + struct snd_seq_driver *sdrv = to_seq_drv(drv); + void **ptr = (void **)data; + if (strcmp(sdrv->id, *ptr)) + return 0; /* id don't match, continue the loop */ + *ptr = sdrv; + return 1; /* break the loop */ +} /* * unregister the specified driver */ int snd_seq_device_unregister_driver(char *id) { - struct ops_list *ops; - struct snd_seq_device *dev; + struct snd_seq_driver *sdrv = (struct snd_seq_driver *)id; - ops = find_driver(id, 0); - if (ops == NULL) + if (!bus_for_each_drv(&snd_seq_bus_type, NULL, &sdrv, find_drv)) return -ENXIO; - if (! (ops->driver & DRIVER_LOADED) || - (ops->driver & DRIVER_LOCKED)) { - pr_err("ALSA: seq: driver_unregister: cannot unload driver '%s': status=%x\n", - id, ops->driver); - unlock_driver(ops); - return -EBUSY; - } - - /* close and release all devices associated with this driver */ - mutex_lock(&ops->reg_mutex); - ops->driver |= DRIVER_LOCKED; /* do not remove this driver recursively */ - list_for_each_entry(dev, &ops->dev_list, list) { - free_device(dev, ops); - } - - ops->driver = 0; - if (ops->num_init_devices > 0) - pr_err("ALSA: seq: free_driver: init_devices > 0!! (%d)\n", - ops->num_init_devices); - mutex_unlock(&ops->reg_mutex); - - unlock_driver(ops); - - /* remove empty driver entries */ - remove_drivers(); - + driver_unregister(&sdrv->driver); + kfree(sdrv); return 0; } - - -/* - * remove empty driver entries - */ -static void remove_drivers(void) -{ - struct list_head *head; - - mutex_lock(&ops_mutex); - head = opslist.next; - while (head != &opslist) { - struct ops_list *ops = list_entry(head, struct ops_list, list); - if (! (ops->driver & DRIVER_LOADED) && - ops->used == 0 && ops->num_devices == 0) { - head = head->next; - list_del(&ops->list); - kfree(ops); - num_ops--; - } else - head = head->next; - } - mutex_unlock(&ops_mutex); -} - -/* - * initialize the device - call init_device operator - */ -static int init_device(struct snd_seq_device *dev, struct ops_list *ops) -{ - if (! (ops->driver & DRIVER_LOADED)) - return 0; /* driver is not loaded yet */ - if (dev->status != SNDRV_SEQ_DEVICE_FREE) - return 0; /* already initialized */ - if (ops->argsize != dev->argsize) { - pr_err("ALSA: seq: incompatible device '%s' for plug-in '%s' (%d %d)\n", - dev->name, ops->id, ops->argsize, dev->argsize); - return -EINVAL; - } - if (ops->ops.init_device(dev) >= 0) { - dev->status = SNDRV_SEQ_DEVICE_REGISTERED; - ops->num_init_devices++; - } else { - pr_err("ALSA: seq: init_device failed: %s: %s\n", - dev->name, dev->id); - } - - return 0; -} - -/* - * release the device - call free_device operator - */ -static int free_device(struct snd_seq_device *dev, struct ops_list *ops) -{ - int result; - - if (! (ops->driver & DRIVER_LOADED)) - return 0; /* driver is not loaded yet */ - if (dev->status != SNDRV_SEQ_DEVICE_REGISTERED) - return 0; /* not registered */ - if (ops->argsize != dev->argsize) { - pr_err("ALSA: seq: incompatible device '%s' for plug-in '%s' (%d %d)\n", - dev->name, ops->id, ops->argsize, dev->argsize); - return -EINVAL; - } - if ((result = ops->ops.free_device(dev)) >= 0 || result == -ENXIO) { - dev->status = SNDRV_SEQ_DEVICE_FREE; - dev->driver_data = NULL; - ops->num_init_devices--; - } else { - pr_err("ALSA: seq: free_device failed: %s: %s\n", - dev->name, dev->id); - } - - return 0; -} - -/* - * find the matching driver with given id - */ -static struct ops_list * find_driver(char *id, int create_if_empty) -{ - struct ops_list *ops; - - mutex_lock(&ops_mutex); - list_for_each_entry(ops, &opslist, list) { - if (strcmp(ops->id, id) == 0) { - ops->used++; - mutex_unlock(&ops_mutex); - return ops; - } - } - mutex_unlock(&ops_mutex); - if (create_if_empty) - return create_driver(id); - return NULL; -} - -static void unlock_driver(struct ops_list *ops) -{ - mutex_lock(&ops_mutex); - ops->used--; - mutex_unlock(&ops_mutex); -} - +EXPORT_SYMBOL(snd_seq_device_unregister_driver); /* * module part */ -static int __init alsa_seq_device_init(void) +static int __init seq_dev_proc_init(void) { #ifdef CONFIG_PROC_FS info_entry = snd_info_create_module_entry(THIS_MODULE, "drivers", @@ -594,17 +376,28 @@ static int __init alsa_seq_device_init(void) return 0; } +static int __init alsa_seq_device_init(void) +{ + int err; + + err = bus_register(&snd_seq_bus_type); + if (err < 0) + return err; + err = seq_dev_proc_init(); + if (err < 0) + bus_unregister(&snd_seq_bus_type); + return err; +} + static void __exit alsa_seq_device_exit(void) { #ifdef CONFIG_MODULES cancel_work_sync(&autoload_work); #endif - remove_drivers(); #ifdef CONFIG_PROC_FS snd_info_free_entry(info_entry); #endif - if (num_ops) - pr_err("ALSA: seq: drivers not released (%d)\n", num_ops); + bus_unregister(&snd_seq_bus_type); } module_init(alsa_seq_device_init) -- GitLab From a7e6645ee3fef358fb1d88b4a2729d29a467c61a Mon Sep 17 00:00:00 2001 From: Ping Cheng Date: Wed, 4 Feb 2015 16:01:54 -0800 Subject: [PATCH 00108/11651] HID: wacom: Add missing ABS_MISC event and feature declaration for 27QHD 27QHD has the same x_min/y_min (WACOM_CINTIQ_OFFSET) as other Cintiqs. ABS_MISC event is required for PAD packet to work properly with xf86-input-wacom. Signed-off-by: Ping Cheng Signed-off-by: Jiri Kosina --- drivers/hid/wacom_wac.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 1a6507999a65..046351cf17f3 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -778,6 +778,11 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) input_report_abs(input, ABS_X, be16_to_cpup((__be16 *)&data[4])); input_report_abs(input, ABS_Y, be16_to_cpup((__be16 *)&data[6])); input_report_abs(input, ABS_Z, be16_to_cpup((__be16 *)&data[8])); + if ((data[2] & 0x07) | data[4] | data[5] | data[6] | data[7] | data[8] | data[9]) { + input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); + } else { + input_report_abs(input, ABS_MISC, 0); + } } else if (features->type == CINTIQ_HYBRID) { /* * Do not send hardware buttons under Android. They @@ -2725,9 +2730,9 @@ static const struct wacom_features wacom_features_0xF6 = .oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf8, .touch_max = 10, .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; static const struct wacom_features wacom_features_0x32A = - { "Wacom Cintiq 27QHD", 119740, 67520, 2047, - 63, WACOM_27QHD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, - WACOM_27QHD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; + { "Wacom Cintiq 27QHD", 119740, 67520, 2047, 63, + WACOM_27QHD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, + WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET }; static const struct wacom_features wacom_features_0x32B = { "Wacom Cintiq 27QHD touch", 119740, 67520, 2047, 63, WACOM_27QHD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, -- GitLab From af03c243a1f014145dae34368fe975b2f08ed964 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 12 Feb 2015 13:40:50 +0100 Subject: [PATCH 00109/11651] ALSA: seq: Clean up device and driver structs Use const string pointer instead of copying the id string to each object. Also drop the status and list fields of snd_seq_device struct that are no longer used. Signed-off-by: Takashi Iwai --- include/sound/seq_device.h | 18 ++++++------------ sound/core/seq/seq_device.c | 31 ++++++++++--------------------- 2 files changed, 16 insertions(+), 33 deletions(-) diff --git a/include/sound/seq_device.h b/include/sound/seq_device.h index ea256b825146..b13cd2930d32 100644 --- a/include/sound/seq_device.h +++ b/include/sound/seq_device.h @@ -25,24 +25,16 @@ * registered device information */ -#define ID_LEN 32 - -/* status flag */ -#define SNDRV_SEQ_DEVICE_FREE 0 -#define SNDRV_SEQ_DEVICE_REGISTERED 1 - struct snd_seq_device { /* device info */ struct snd_card *card; /* sound card */ int device; /* device number */ - char id[ID_LEN]; /* driver id */ + const char *id; /* driver id */ char name[80]; /* device name */ int argsize; /* size of the argument */ void *driver_data; /* private data for driver */ - int status; /* flag - read only */ void *private_data; /* private data for the caller */ void (*private_free)(struct snd_seq_device *device); - struct list_head list; /* link to next device */ struct device dev; }; @@ -75,9 +67,11 @@ void snd_seq_device_load_drivers(void); #else #define snd_seq_device_load_drivers() #endif -int snd_seq_device_new(struct snd_card *card, int device, char *id, int argsize, struct snd_seq_device **result); -int snd_seq_device_register_driver(char *id, struct snd_seq_dev_ops *entry, int argsize); -int snd_seq_device_unregister_driver(char *id); +int snd_seq_device_new(struct snd_card *card, int device, const char *id, + int argsize, struct snd_seq_device **result); +int snd_seq_device_register_driver(const char *id, + struct snd_seq_dev_ops *entry, int argsize); +int snd_seq_device_unregister_driver(const char *id); #define SNDRV_SEQ_DEVICE_ARGPTR(dev) (void *)((char *)(dev) + sizeof(struct snd_seq_device)) diff --git a/sound/core/seq/seq_device.c b/sound/core/seq/seq_device.c index d3320ffe43c2..49daf6e3a387 100644 --- a/sound/core/seq/seq_device.c +++ b/sound/core/seq/seq_device.c @@ -54,7 +54,7 @@ MODULE_LICENSE("GPL"); struct snd_seq_driver { struct device_driver driver; - char id[ID_LEN]; + const char *id; int argsize; struct snd_seq_dev_ops ops; }; @@ -215,8 +215,8 @@ static void snd_seq_dev_release(struct device *dev) * id = id of driver * result = return pointer (NULL allowed if unnecessary) */ -int snd_seq_device_new(struct snd_card *card, int device, char *id, int argsize, - struct snd_seq_device **result) +int snd_seq_device_new(struct snd_card *card, int device, const char *id, + int argsize, struct snd_seq_device **result) { struct snd_seq_device *dev; int err; @@ -239,9 +239,8 @@ int snd_seq_device_new(struct snd_card *card, int device, char *id, int argsize, /* set up device info */ dev->card = card; dev->device = device; - strlcpy(dev->id, id, sizeof(dev->id)); + dev->id = id; dev->argsize = argsize; - dev->status = SNDRV_SEQ_DEVICE_FREE; device_initialize(&dev->dev); dev->dev.parent = &card->card_dev; @@ -270,26 +269,16 @@ static int snd_seq_drv_probe(struct device *dev) { struct snd_seq_driver *sdrv = to_seq_drv(dev->driver); struct snd_seq_device *sdev = to_seq_dev(dev); - int err; - err = sdrv->ops.init_device(sdev); - if (err < 0) - return err; - sdev->status = SNDRV_SEQ_DEVICE_REGISTERED; - return 0; + return sdrv->ops.init_device(sdev); } static int snd_seq_drv_remove(struct device *dev) { struct snd_seq_driver *sdrv = to_seq_drv(dev->driver); struct snd_seq_device *sdev = to_seq_dev(dev); - int err; - err = sdrv->ops.free_device(sdev); - if (err < 0) - return err; - sdev->status = SNDRV_SEQ_DEVICE_FREE; - return 0; + return sdrv->ops.free_device(sdev); } /* @@ -297,8 +286,8 @@ static int snd_seq_drv_remove(struct device *dev) * id = driver id * entry = driver operators - duplicated to each instance */ -int snd_seq_device_register_driver(char *id, struct snd_seq_dev_ops *entry, - int argsize) +int snd_seq_device_register_driver(const char *id, + struct snd_seq_dev_ops *entry, int argsize) { struct snd_seq_driver *sdrv; int err; @@ -315,7 +304,7 @@ int snd_seq_device_register_driver(char *id, struct snd_seq_dev_ops *entry, sdrv->driver.bus = &snd_seq_bus_type; sdrv->driver.probe = snd_seq_drv_probe; sdrv->driver.remove = snd_seq_drv_remove; - strlcpy(sdrv->id, id, sizeof(sdrv->id)); + sdrv->id = id; sdrv->argsize = argsize; sdrv->ops = *entry; @@ -343,7 +332,7 @@ static int find_drv(struct device_driver *drv, void *data) /* * unregister the specified driver */ -int snd_seq_device_unregister_driver(char *id) +int snd_seq_device_unregister_driver(const char *id) { struct snd_seq_driver *sdrv = (struct snd_seq_driver *)id; -- GitLab From 056622053b8ae02978678ac1321b5bd956e7c812 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 12 Feb 2015 13:43:22 +0100 Subject: [PATCH 00110/11651] ALSA: seq: Define driver object in each driver This patch moves the driver object initialization and allocation to each driver's module init/exit code like other normal drivers. The snd_seq_driver struct is now published in seq_device.h, and each driver is responsible to define it with proper driver attributes (name, probe and remove) with snd_seq_driver specific attributes as id and argsize fields. The helper functions snd_seq_driver_register(), snd_seq_driver_unregister() and module_snd_seq_driver() are used for simplifying codes. Signed-off-by: Takashi Iwai --- include/sound/seq_device.h | 27 ++++++--- sound/core/seq/oss/seq_oss.c | 20 ++++--- sound/core/seq/oss/seq_oss_synth.c | 6 +- sound/core/seq/oss/seq_oss_synth.h | 4 +- sound/core/seq/seq_device.c | 93 ++++-------------------------- sound/core/seq/seq_midi.c | 28 +++++---- sound/drivers/opl3/opl3_seq.c | 34 +++++------ sound/drivers/opl4/opl4_seq.c | 33 +++++------ sound/isa/sb/emu8000_synth.c | 35 +++++------ sound/pci/emu10k1/emu10k1_synth.c | 35 +++++------ 10 files changed, 124 insertions(+), 191 deletions(-) diff --git a/include/sound/seq_device.h b/include/sound/seq_device.h index b13cd2930d32..ddc0d504cf39 100644 --- a/include/sound/seq_device.h +++ b/include/sound/seq_device.h @@ -41,8 +41,10 @@ struct snd_seq_device { #define to_seq_dev(_dev) \ container_of(_dev, struct snd_seq_device, dev) +/* sequencer driver */ + /* driver operators - * init_device: + * probe: * Initialize the device with given parameters. * Typically, * 1. call snd_hwdep_new @@ -50,15 +52,19 @@ struct snd_seq_device { * 3. call snd_hwdep_register * 4. store the instance to dev->driver_data pointer. * - * free_device: + * remove: * Release the private data. * Typically, call snd_device_free(dev->card, dev->driver_data) */ -struct snd_seq_dev_ops { - int (*init_device)(struct snd_seq_device *dev); - int (*free_device)(struct snd_seq_device *dev); +struct snd_seq_driver { + struct device_driver driver; + char *id; + int argsize; }; +#define to_seq_drv(_drv) \ + container_of(_drv, struct snd_seq_driver, driver) + /* * prototypes */ @@ -69,12 +75,17 @@ void snd_seq_device_load_drivers(void); #endif int snd_seq_device_new(struct snd_card *card, int device, const char *id, int argsize, struct snd_seq_device **result); -int snd_seq_device_register_driver(const char *id, - struct snd_seq_dev_ops *entry, int argsize); -int snd_seq_device_unregister_driver(const char *id); #define SNDRV_SEQ_DEVICE_ARGPTR(dev) (void *)((char *)(dev) + sizeof(struct snd_seq_device)) +int __must_check __snd_seq_driver_register(struct snd_seq_driver *drv, + struct module *mod); +#define snd_seq_driver_register(drv) \ + __snd_seq_driver_register(drv, THIS_MODULE) +void snd_seq_driver_unregister(struct snd_seq_driver *drv); + +#define module_snd_seq_driver(drv) \ + module_driver(drv, snd_seq_driver_register, snd_seq_driver_unregister) /* * id strings for generic devices diff --git a/sound/core/seq/oss/seq_oss.c b/sound/core/seq/oss/seq_oss.c index 16d42679e43f..ae1814aa767e 100644 --- a/sound/core/seq/oss/seq_oss.c +++ b/sound/core/seq/oss/seq_oss.c @@ -65,13 +65,19 @@ static unsigned int odev_poll(struct file *file, poll_table * wait); * module interface */ +static struct snd_seq_driver seq_oss_synth_driver = { + .driver = { + .name = KBUILD_MODNAME, + .probe = snd_seq_oss_synth_probe, + .remove = snd_seq_oss_synth_remove, + }, + .id = SNDRV_SEQ_DEV_ID_OSS, + .argsize = sizeof(struct snd_seq_oss_reg), +}; + static int __init alsa_seq_oss_init(void) { int rc; - static struct snd_seq_dev_ops ops = { - snd_seq_oss_synth_register, - snd_seq_oss_synth_unregister, - }; snd_seq_autoload_lock(); if ((rc = register_device()) < 0) @@ -86,8 +92,8 @@ static int __init alsa_seq_oss_init(void) goto error; } - if ((rc = snd_seq_device_register_driver(SNDRV_SEQ_DEV_ID_OSS, &ops, - sizeof(struct snd_seq_oss_reg))) < 0) { + rc = snd_seq_driver_register(&seq_oss_synth_driver); + if (rc < 0) { snd_seq_oss_delete_client(); unregister_proc(); unregister_device(); @@ -104,7 +110,7 @@ static int __init alsa_seq_oss_init(void) static void __exit alsa_seq_oss_exit(void) { - snd_seq_device_unregister_driver(SNDRV_SEQ_DEV_ID_OSS); + snd_seq_driver_unregister(&seq_oss_synth_driver); snd_seq_oss_delete_client(); unregister_proc(); unregister_device(); diff --git a/sound/core/seq/oss/seq_oss_synth.c b/sound/core/seq/oss/seq_oss_synth.c index 701feb71b700..835edc80f918 100644 --- a/sound/core/seq/oss/seq_oss_synth.c +++ b/sound/core/seq/oss/seq_oss_synth.c @@ -98,8 +98,9 @@ snd_seq_oss_synth_init(void) * registration of the synth device */ int -snd_seq_oss_synth_register(struct snd_seq_device *dev) +snd_seq_oss_synth_probe(struct device *_dev) { + struct snd_seq_device *dev = to_seq_dev(_dev); int i; struct seq_oss_synth *rec; struct snd_seq_oss_reg *reg = SNDRV_SEQ_DEVICE_ARGPTR(dev); @@ -149,8 +150,9 @@ snd_seq_oss_synth_register(struct snd_seq_device *dev) int -snd_seq_oss_synth_unregister(struct snd_seq_device *dev) +snd_seq_oss_synth_remove(struct device *_dev) { + struct snd_seq_device *dev = to_seq_dev(_dev); int index; struct seq_oss_synth *rec = dev->driver_data; unsigned long flags; diff --git a/sound/core/seq/oss/seq_oss_synth.h b/sound/core/seq/oss/seq_oss_synth.h index dbdfcbb80eaa..74ac55f166b6 100644 --- a/sound/core/seq/oss/seq_oss_synth.h +++ b/sound/core/seq/oss/seq_oss_synth.h @@ -28,8 +28,8 @@ #include void snd_seq_oss_synth_init(void); -int snd_seq_oss_synth_register(struct snd_seq_device *dev); -int snd_seq_oss_synth_unregister(struct snd_seq_device *dev); +int snd_seq_oss_synth_probe(struct device *dev); +int snd_seq_oss_synth_remove(struct device *dev); void snd_seq_oss_synth_setup(struct seq_oss_devinfo *dp); void snd_seq_oss_synth_setup_midi(struct seq_oss_devinfo *dp); void snd_seq_oss_synth_cleanup(struct seq_oss_devinfo *dp); diff --git a/sound/core/seq/seq_device.c b/sound/core/seq/seq_device.c index 49daf6e3a387..48b20f009598 100644 --- a/sound/core/seq/seq_device.c +++ b/sound/core/seq/seq_device.c @@ -52,16 +52,6 @@ MODULE_AUTHOR("Takashi Iwai "); MODULE_DESCRIPTION("ALSA sequencer device management"); MODULE_LICENSE("GPL"); -struct snd_seq_driver { - struct device_driver driver; - const char *id; - int argsize; - struct snd_seq_dev_ops ops; -}; - -#define to_seq_drv(_drv) \ - container_of(_drv, struct snd_seq_driver, driver) - /* * bus definition */ @@ -263,86 +253,23 @@ int snd_seq_device_new(struct snd_card *card, int device, const char *id, EXPORT_SYMBOL(snd_seq_device_new); /* - * driver binding - just pass to each driver callback + * driver registration */ -static int snd_seq_drv_probe(struct device *dev) +int __snd_seq_driver_register(struct snd_seq_driver *drv, struct module *mod) { - struct snd_seq_driver *sdrv = to_seq_drv(dev->driver); - struct snd_seq_device *sdev = to_seq_dev(dev); - - return sdrv->ops.init_device(sdev); -} - -static int snd_seq_drv_remove(struct device *dev) -{ - struct snd_seq_driver *sdrv = to_seq_drv(dev->driver); - struct snd_seq_device *sdev = to_seq_dev(dev); - - return sdrv->ops.free_device(sdev); -} - -/* - * register device driver - * id = driver id - * entry = driver operators - duplicated to each instance - */ -int snd_seq_device_register_driver(const char *id, - struct snd_seq_dev_ops *entry, int argsize) -{ - struct snd_seq_driver *sdrv; - int err; - - if (id == NULL || entry == NULL || - entry->init_device == NULL || entry->free_device == NULL) + if (WARN_ON(!drv->driver.name || !drv->id)) return -EINVAL; - - sdrv = kzalloc(sizeof(*sdrv), GFP_KERNEL); - if (!sdrv) - return -ENOMEM; - - sdrv->driver.name = id; - sdrv->driver.bus = &snd_seq_bus_type; - sdrv->driver.probe = snd_seq_drv_probe; - sdrv->driver.remove = snd_seq_drv_remove; - sdrv->id = id; - sdrv->argsize = argsize; - sdrv->ops = *entry; - - err = driver_register(&sdrv->driver); - if (err < 0) - kfree(sdrv); - return err; -} -EXPORT_SYMBOL(snd_seq_device_register_driver); - -/* callback to find a specific driver; data is a pointer to the id string ptr. - * when the id matches, store the driver pointer in return and break the loop. - */ -static int find_drv(struct device_driver *drv, void *data) -{ - struct snd_seq_driver *sdrv = to_seq_drv(drv); - void **ptr = (void **)data; - - if (strcmp(sdrv->id, *ptr)) - return 0; /* id don't match, continue the loop */ - *ptr = sdrv; - return 1; /* break the loop */ + drv->driver.bus = &snd_seq_bus_type; + drv->driver.owner = mod; + return driver_register(&drv->driver); } +EXPORT_SYMBOL_GPL(__snd_seq_driver_register); -/* - * unregister the specified driver - */ -int snd_seq_device_unregister_driver(const char *id) +void snd_seq_driver_unregister(struct snd_seq_driver *drv) { - struct snd_seq_driver *sdrv = (struct snd_seq_driver *)id; - - if (!bus_for_each_drv(&snd_seq_bus_type, NULL, &sdrv, find_drv)) - return -ENXIO; - driver_unregister(&sdrv->driver); - kfree(sdrv); - return 0; + driver_unregister(&drv->driver); } -EXPORT_SYMBOL(snd_seq_device_unregister_driver); +EXPORT_SYMBOL_GPL(snd_seq_driver_unregister); /* * module part diff --git a/sound/core/seq/seq_midi.c b/sound/core/seq/seq_midi.c index 68fec776da26..79c73119cedc 100644 --- a/sound/core/seq/seq_midi.c +++ b/sound/core/seq/seq_midi.c @@ -273,8 +273,9 @@ static void snd_seq_midisynth_delete(struct seq_midisynth *msynth) /* register new midi synth port */ static int -snd_seq_midisynth_register_port(struct snd_seq_device *dev) +snd_seq_midisynth_probe(struct device *_dev) { + struct snd_seq_device *dev = to_seq_dev(_dev); struct seq_midisynth_client *client; struct seq_midisynth *msynth, *ms; struct snd_seq_port_info *port; @@ -427,8 +428,9 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev) /* release midi synth port */ static int -snd_seq_midisynth_unregister_port(struct snd_seq_device *dev) +snd_seq_midisynth_remove(struct device *_dev) { + struct snd_seq_device *dev = to_seq_dev(_dev); struct seq_midisynth_client *client; struct seq_midisynth *msynth; struct snd_card *card = dev->card; @@ -457,23 +459,29 @@ snd_seq_midisynth_unregister_port(struct snd_seq_device *dev) return 0; } +static struct snd_seq_driver seq_midisynth_driver = { + .driver = { + .name = KBUILD_MODNAME, + .probe = snd_seq_midisynth_probe, + .remove = snd_seq_midisynth_remove, + }, + .id = SNDRV_SEQ_DEV_ID_MIDISYNTH, + .argsize = 0, +}; static int __init alsa_seq_midi_init(void) { - static struct snd_seq_dev_ops ops = { - snd_seq_midisynth_register_port, - snd_seq_midisynth_unregister_port, - }; - memset(&synths, 0, sizeof(synths)); + int err; + snd_seq_autoload_lock(); - snd_seq_device_register_driver(SNDRV_SEQ_DEV_ID_MIDISYNTH, &ops, 0); + err = snd_seq_driver_register(&seq_midisynth_driver); snd_seq_autoload_unlock(); - return 0; + return err; } static void __exit alsa_seq_midi_exit(void) { - snd_seq_device_unregister_driver(SNDRV_SEQ_DEV_ID_MIDISYNTH); + snd_seq_driver_unregister(&seq_midisynth_driver); } module_init(alsa_seq_midi_init) diff --git a/sound/drivers/opl3/opl3_seq.c b/sound/drivers/opl3/opl3_seq.c index a9f618e06a22..fdae5d7f421f 100644 --- a/sound/drivers/opl3/opl3_seq.c +++ b/sound/drivers/opl3/opl3_seq.c @@ -216,8 +216,9 @@ static int snd_opl3_synth_create_port(struct snd_opl3 * opl3) /* ------------------------------ */ -static int snd_opl3_seq_new_device(struct snd_seq_device *dev) +static int snd_opl3_seq_probe(struct device *_dev) { + struct snd_seq_device *dev = to_seq_dev(_dev); struct snd_opl3 *opl3; int client, err; char name[32]; @@ -257,8 +258,9 @@ static int snd_opl3_seq_new_device(struct snd_seq_device *dev) return 0; } -static int snd_opl3_seq_delete_device(struct snd_seq_device *dev) +static int snd_opl3_seq_remove(struct device *_dev) { + struct snd_seq_device *dev = to_seq_dev(_dev); struct snd_opl3 *opl3; opl3 = *(struct snd_opl3 **)SNDRV_SEQ_DEVICE_ARGPTR(dev); @@ -275,22 +277,14 @@ static int snd_opl3_seq_delete_device(struct snd_seq_device *dev) return 0; } -static int __init alsa_opl3_seq_init(void) -{ - static struct snd_seq_dev_ops ops = - { - snd_opl3_seq_new_device, - snd_opl3_seq_delete_device - }; - - return snd_seq_device_register_driver(SNDRV_SEQ_DEV_ID_OPL3, &ops, - sizeof(struct snd_opl3 *)); -} - -static void __exit alsa_opl3_seq_exit(void) -{ - snd_seq_device_unregister_driver(SNDRV_SEQ_DEV_ID_OPL3); -} +static struct snd_seq_driver opl3_seq_driver = { + .driver = { + .name = KBUILD_MODNAME, + .probe = snd_opl3_seq_probe, + .remove = snd_opl3_seq_remove, + }, + .id = SNDRV_SEQ_DEV_ID_OPL3, + .argsize = sizeof(struct snd_opl3 *), +}; -module_init(alsa_opl3_seq_init) -module_exit(alsa_opl3_seq_exit) +module_snd_seq_driver(opl3_seq_driver); diff --git a/sound/drivers/opl4/opl4_seq.c b/sound/drivers/opl4/opl4_seq.c index 99197699c55a..03d6202f4829 100644 --- a/sound/drivers/opl4/opl4_seq.c +++ b/sound/drivers/opl4/opl4_seq.c @@ -124,8 +124,9 @@ static void snd_opl4_seq_free_port(void *private_data) snd_midi_channel_free_set(opl4->chset); } -static int snd_opl4_seq_new_device(struct snd_seq_device *dev) +static int snd_opl4_seq_probe(struct device *_dev) { + struct snd_seq_device *dev = to_seq_dev(_dev); struct snd_opl4 *opl4; int client; struct snd_seq_port_callback pcallbacks; @@ -180,8 +181,9 @@ static int snd_opl4_seq_new_device(struct snd_seq_device *dev) return 0; } -static int snd_opl4_seq_delete_device(struct snd_seq_device *dev) +static int snd_opl4_seq_remove(struct device *_dev) { + struct snd_seq_device *dev = to_seq_dev(_dev); struct snd_opl4 *opl4; opl4 = *(struct snd_opl4 **)SNDRV_SEQ_DEVICE_ARGPTR(dev); @@ -195,21 +197,14 @@ static int snd_opl4_seq_delete_device(struct snd_seq_device *dev) return 0; } -static int __init alsa_opl4_synth_init(void) -{ - static struct snd_seq_dev_ops ops = { - snd_opl4_seq_new_device, - snd_opl4_seq_delete_device - }; - - return snd_seq_device_register_driver(SNDRV_SEQ_DEV_ID_OPL4, &ops, - sizeof(struct snd_opl4 *)); -} - -static void __exit alsa_opl4_synth_exit(void) -{ - snd_seq_device_unregister_driver(SNDRV_SEQ_DEV_ID_OPL4); -} +static struct snd_seq_driver opl4_seq_driver = { + .driver = { + .name = KBUILD_MODNAME, + .probe = snd_opl4_seq_probe, + .remove = snd_opl4_seq_remove, + }, + .id = SNDRV_SEQ_DEV_ID_OPL4, + .argsize = sizeof(struct snd_opl4 *), +}; -module_init(alsa_opl4_synth_init) -module_exit(alsa_opl4_synth_exit) +module_snd_seq_driver(opl4_seq_driver); diff --git a/sound/isa/sb/emu8000_synth.c b/sound/isa/sb/emu8000_synth.c index 72332dfada9a..4aa719cad331 100644 --- a/sound/isa/sb/emu8000_synth.c +++ b/sound/isa/sb/emu8000_synth.c @@ -34,8 +34,9 @@ MODULE_LICENSE("GPL"); /* * create a new hardware dependent device for Emu8000 */ -static int snd_emu8000_new_device(struct snd_seq_device *dev) +static int snd_emu8000_probe(struct device *_dev) { + struct snd_seq_device *dev = to_seq_dev(_dev); struct snd_emu8000 *hw; struct snd_emux *emu; @@ -93,8 +94,9 @@ static int snd_emu8000_new_device(struct snd_seq_device *dev) /* * free all resources */ -static int snd_emu8000_delete_device(struct snd_seq_device *dev) +static int snd_emu8000_remove(struct device *_dev) { + struct snd_seq_device *dev = to_seq_dev(_dev); struct snd_emu8000 *hw; if (dev->driver_data == NULL) @@ -114,21 +116,14 @@ static int snd_emu8000_delete_device(struct snd_seq_device *dev) * INIT part */ -static int __init alsa_emu8000_init(void) -{ - - static struct snd_seq_dev_ops ops = { - snd_emu8000_new_device, - snd_emu8000_delete_device, - }; - return snd_seq_device_register_driver(SNDRV_SEQ_DEV_ID_EMU8000, &ops, - sizeof(struct snd_emu8000*)); -} - -static void __exit alsa_emu8000_exit(void) -{ - snd_seq_device_unregister_driver(SNDRV_SEQ_DEV_ID_EMU8000); -} - -module_init(alsa_emu8000_init) -module_exit(alsa_emu8000_exit) +static struct snd_seq_driver emu8000_driver = { + .driver = { + .name = KBUILD_MODNAME, + .probe = snd_emu8000_probe, + .remove = snd_emu8000_remove, + }, + .id = SNDRV_SEQ_DEV_ID_EMU8000, + .argsize = sizeof(struct snd_emu8000 *), +}; + +module_snd_seq_driver(emu8000_driver); diff --git a/sound/pci/emu10k1/emu10k1_synth.c b/sound/pci/emu10k1/emu10k1_synth.c index 4c41c903a840..5457d5613f6b 100644 --- a/sound/pci/emu10k1/emu10k1_synth.c +++ b/sound/pci/emu10k1/emu10k1_synth.c @@ -29,8 +29,9 @@ MODULE_LICENSE("GPL"); /* * create a new hardware dependent device for Emu10k1 */ -static int snd_emu10k1_synth_new_device(struct snd_seq_device *dev) +static int snd_emu10k1_synth_probe(struct device *_dev) { + struct snd_seq_device *dev = to_seq_dev(_dev); struct snd_emux *emux; struct snd_emu10k1 *hw; struct snd_emu10k1_synth_arg *arg; @@ -79,8 +80,9 @@ static int snd_emu10k1_synth_new_device(struct snd_seq_device *dev) return 0; } -static int snd_emu10k1_synth_delete_device(struct snd_seq_device *dev) +static int snd_emu10k1_synth_remove(struct device *_dev) { + struct snd_seq_device *dev = to_seq_dev(_dev); struct snd_emux *emux; struct snd_emu10k1 *hw; unsigned long flags; @@ -104,21 +106,14 @@ static int snd_emu10k1_synth_delete_device(struct snd_seq_device *dev) * INIT part */ -static int __init alsa_emu10k1_synth_init(void) -{ - - static struct snd_seq_dev_ops ops = { - snd_emu10k1_synth_new_device, - snd_emu10k1_synth_delete_device, - }; - return snd_seq_device_register_driver(SNDRV_SEQ_DEV_ID_EMU10K1_SYNTH, &ops, - sizeof(struct snd_emu10k1_synth_arg)); -} - -static void __exit alsa_emu10k1_synth_exit(void) -{ - snd_seq_device_unregister_driver(SNDRV_SEQ_DEV_ID_EMU10K1_SYNTH); -} - -module_init(alsa_emu10k1_synth_init) -module_exit(alsa_emu10k1_synth_exit) +static struct snd_seq_driver emu10k1_synth_driver = { + .driver = { + .name = KBUILD_MODNAME, + .probe = snd_emu10k1_synth_probe, + .remove = snd_emu10k1_synth_remove, + }, + .id = SNDRV_SEQ_DEV_ID_EMU10K1_SYNTH, + .argsize = sizeof(struct snd_emu10k1_synth_arg), +}; + +module_snd_seq_driver(emu10k1_synth_driver); -- GitLab From 54a721abd7953a58e5479065c0cfdd8679d785c9 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 12 Feb 2015 14:20:24 +0100 Subject: [PATCH 00111/11651] ALSA: seq: Drop snd_seq_autoload_lock() and _unlock() The autoload lock became already superfluous due to the recent rework of autoload code. Let's drop them now. This allows us to simplify a few codes nicely. Signed-off-by: Takashi Iwai --- include/sound/seq_kernel.h | 6 +----- sound/core/seq/oss/seq_oss.c | 2 -- sound/core/seq/seq_device.c | 19 +++++++------------ sound/core/seq/seq_dummy.c | 6 +----- sound/core/seq/seq_midi.c | 18 +----------------- 5 files changed, 10 insertions(+), 41 deletions(-) diff --git a/include/sound/seq_kernel.h b/include/sound/seq_kernel.h index 18a2ac58b88f..feb58d455560 100644 --- a/include/sound/seq_kernel.h +++ b/include/sound/seq_kernel.h @@ -99,13 +99,9 @@ int snd_seq_event_port_attach(int client, struct snd_seq_port_callback *pcbp, int snd_seq_event_port_detach(int client, int port); #ifdef CONFIG_MODULES -void snd_seq_autoload_lock(void); -void snd_seq_autoload_unlock(void); void snd_seq_autoload_init(void); -#define snd_seq_autoload_exit() snd_seq_autoload_lock() +void snd_seq_autoload_exit(void); #else -#define snd_seq_autoload_lock() -#define snd_seq_autoload_unlock() #define snd_seq_autoload_init() #define snd_seq_autoload_exit() #endif diff --git a/sound/core/seq/oss/seq_oss.c b/sound/core/seq/oss/seq_oss.c index ae1814aa767e..72873a46afeb 100644 --- a/sound/core/seq/oss/seq_oss.c +++ b/sound/core/seq/oss/seq_oss.c @@ -79,7 +79,6 @@ static int __init alsa_seq_oss_init(void) { int rc; - snd_seq_autoload_lock(); if ((rc = register_device()) < 0) goto error; if ((rc = register_proc()) < 0) { @@ -104,7 +103,6 @@ static int __init alsa_seq_oss_init(void) snd_seq_oss_synth_init(); error: - snd_seq_autoload_unlock(); return rc; } diff --git a/sound/core/seq/seq_device.c b/sound/core/seq/seq_device.c index 48b20f009598..355b34269bd1 100644 --- a/sound/core/seq/seq_device.c +++ b/sound/core/seq/seq_device.c @@ -98,19 +98,8 @@ static void snd_seq_device_info(struct snd_info_entry *entry, */ #ifdef CONFIG_MODULES -/* avoid auto-loading during module_init() */ +/* flag to block auto-loading */ static atomic_t snd_seq_in_init = ATOMIC_INIT(1); /* blocked as default */ -void snd_seq_autoload_lock(void) -{ - atomic_inc(&snd_seq_in_init); -} -EXPORT_SYMBOL(snd_seq_autoload_lock); - -void snd_seq_autoload_unlock(void) -{ - atomic_dec(&snd_seq_in_init); -} -EXPORT_SYMBOL(snd_seq_autoload_unlock); static int request_seq_drv(struct device *dev, void *data) { @@ -147,6 +136,12 @@ void snd_seq_autoload_init(void) } EXPORT_SYMBOL(snd_seq_autoload_init); +void snd_seq_autoload_exit(void) +{ + atomic_inc(&snd_seq_in_init); +} +EXPORT_SYMBOL(snd_seq_autoload_exit); + void snd_seq_device_load_drivers(void) { queue_autoload_drivers(); diff --git a/sound/core/seq/seq_dummy.c b/sound/core/seq/seq_dummy.c index 5d905d90d504..d3a2ec4f0561 100644 --- a/sound/core/seq/seq_dummy.c +++ b/sound/core/seq/seq_dummy.c @@ -214,11 +214,7 @@ delete_client(void) static int __init alsa_seq_dummy_init(void) { - int err; - snd_seq_autoload_lock(); - err = register_client(); - snd_seq_autoload_unlock(); - return err; + return register_client(); } static void __exit alsa_seq_dummy_exit(void) diff --git a/sound/core/seq/seq_midi.c b/sound/core/seq/seq_midi.c index 79c73119cedc..5dd0ee258359 100644 --- a/sound/core/seq/seq_midi.c +++ b/sound/core/seq/seq_midi.c @@ -469,20 +469,4 @@ static struct snd_seq_driver seq_midisynth_driver = { .argsize = 0, }; -static int __init alsa_seq_midi_init(void) -{ - int err; - - snd_seq_autoload_lock(); - err = snd_seq_driver_register(&seq_midisynth_driver); - snd_seq_autoload_unlock(); - return err; -} - -static void __exit alsa_seq_midi_exit(void) -{ - snd_seq_driver_unregister(&seq_midisynth_driver); -} - -module_init(alsa_seq_midi_init) -module_exit(alsa_seq_midi_exit) +module_snd_seq_driver(seq_midisynth_driver); -- GitLab From fcfd6611fbccdbf2593bd949097a5c0e45cd96da Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 31 Dec 2014 17:37:00 +0100 Subject: [PATCH 00112/11651] tools build: Add detected config support Adding support to include detected configuration makefile into the build process. This will allow the Build objects to be configurable based on the config data, like: perf-$(CONFIG_KRAVA) += krava.o The configuration is stored in '.config-detected' file, which is generated for each compilation. Signed-off-by: Jiri Olsa Tested-by: Sukadev Bhattiprolu Tested-by: Will Deacon Cc: Alexis Berlemont Cc: Borislav Petkov Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-bl8qho0ubck7aqrbbfu9inlm@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/build/Makefile.build | 3 +++ tools/perf/config/Makefile | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/tools/build/Makefile.build b/tools/build/Makefile.build index ae203f21cc86..35174d920476 100644 --- a/tools/build/Makefile.build +++ b/tools/build/Makefile.build @@ -22,6 +22,9 @@ build-dir := $(srctree)/tools/build # Generic definitions include $(build-dir)/Build.include +# do not force detected configuration +-include .config-detected + # Init all relevant variables used in build files so # 1) they have correct type # 2) they do not inherit any value from the environment diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index cc224080b525..ba414216e506 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -11,6 +11,10 @@ ifneq ($(obj-perf),) obj-perf := $(abspath $(obj-perf))/ endif +$(shell echo -n > .config-detected) +detected = $(shell echo "$(1)=y" >> .config-detected) +detected_var = $(shell echo "$(1)=$($(1))" >> .config-detected) + LIB_INCLUDE := $(srctree)/tools/lib/ CFLAGS := $(EXTRA_CFLAGS) $(EXTRA_WARNINGS) -- GitLab From 579ff6d409afa00e78822be9482d382dffd29ff4 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 30 Dec 2014 16:44:11 +0100 Subject: [PATCH 00113/11651] tools build: Add subdir support Add support to make directory any time we build objects out of the tree (O=/tmp/krava) and the output directory does not exist. Signed-off-by: Jiri Olsa Tested-by: Sukadev Bhattiprolu Tested-by: Will Deacon Cc: Alexis Berlemont Cc: Borislav Petkov Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-h80ukls4o2kpr0e4c4bfln6u@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/build/Makefile.build | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tools/build/Makefile.build b/tools/build/Makefile.build index 35174d920476..692e1b154200 100644 --- a/tools/build/Makefile.build +++ b/tools/build/Makefile.build @@ -37,6 +37,11 @@ subdir-obj-y := build-file := $(dir)/Build include $(build-file) +# Create directory unless it exists +quiet_cmd_mkdir = MKDIR $(dir $@) + cmd_mkdir = mkdir -p $(dir $@) + rule_mkdir = $(if $(wildcard $(dir $@)),,@$(call echo-cmd,mkdir) $(cmd_mkdir)) + # Compile command quiet_cmd_cc_o_c = CC $@ cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< @@ -49,9 +54,11 @@ quiet_cmd_ld_multi = LD $@ # Build rules $(OUTPUT)%.o: %.c FORCE + $(call rule_mkdir) $(call if_changed_dep,cc_o_c) $(OUTPUT)%.o: %.S FORCE + $(call rule_mkdir) $(call if_changed_dep,cc_o_c) # Gather build data: -- GitLab From 885e00be17c07ffb517d471bf39c8acc44ef87a9 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 11 Jan 2015 23:05:29 +0100 Subject: [PATCH 00114/11651] perf tools: Remove api fs object from python build It's already included in libapikfs.a library, which is already used to link perf.so. Signed-off-by: Jiri Olsa Tested-by: Sukadev Bhattiprolu Tested-by: Will Deacon Cc: Alexis Berlemont Cc: Borislav Petkov Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-ijp7xkmj585rqajy4xmvjnar@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/python-ext-sources | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/perf/util/python-ext-sources b/tools/perf/util/python-ext-sources index 6c6a6953fa93..4d28624a1eca 100644 --- a/tools/perf/util/python-ext-sources +++ b/tools/perf/util/python-ext-sources @@ -17,6 +17,5 @@ util/xyarray.c util/cgroup.c util/rblist.c util/strlist.c -../lib/api/fs/fs.c util/trace-event.c ../../lib/rbtree.c -- GitLab From 6dd280cdb8a2cf53deacd6240707ec2f22222b20 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sat, 10 Jan 2015 21:43:32 +0100 Subject: [PATCH 00115/11651] perf build: Disable make's built-in rules We don't use any built-in rules, so we can disable make's checks for that and build faster. Signed-off-by: Jiri Olsa Tested-by: Sukadev Bhattiprolu Tested-by: Will Deacon Cc: Alexis Berlemont Cc: Borislav Petkov Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-fr54ist3woy7efz6z3m720vb@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile.perf | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index aa6a50447c32..0a256fe193ce 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -84,6 +84,10 @@ ifneq ($(OUTPUT),) #$(info Determined 'OUTPUT' to be $(OUTPUT)) endif +# Do not use make's built-in rules +# (this improves performance and avoids hard-to-debug behaviour); +MAKEFLAGS += -r + $(OUTPUT)PERF-VERSION-FILE: ../../.git/HEAD @$(SHELL_PATH) util/PERF-VERSION-GEN $(OUTPUT) @touch $(OUTPUT)PERF-VERSION-FILE -- GitLab From 72965b87c5d5d15e33c620901b46c5ca1a3d6b8b Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 29 Dec 2014 13:52:36 +0100 Subject: [PATCH 00116/11651] perf build: Add bench objects building Move bench objects building under build framework and enable perf-in.o rule. Signed-off-by: Jiri Olsa Tested-by: Sukadev Bhattiprolu Tested-by: Will Deacon Cc: Alexis Berlemont Cc: Borislav Petkov Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-b0gxubmn3qjabaq0lune53y3@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Build | 2 ++ tools/perf/Makefile.perf | 38 ++++++++++++++++---------------------- tools/perf/bench/Build | 11 +++++++++++ tools/perf/config/Makefile | 2 ++ 4 files changed, 31 insertions(+), 22 deletions(-) create mode 100644 tools/perf/Build create mode 100644 tools/perf/bench/Build diff --git a/tools/perf/Build b/tools/perf/Build new file mode 100644 index 000000000000..9ea828de3fde --- /dev/null +++ b/tools/perf/Build @@ -0,0 +1,2 @@ +perf-y += builtin-bench.o +perf-y += bench/ diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 0a256fe193ce..77f67941dfc8 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -93,6 +93,7 @@ $(OUTPUT)PERF-VERSION-FILE: ../../.git/HEAD @touch $(OUTPUT)PERF-VERSION-FILE CC = $(CROSS_COMPILE)gcc +LD = $(CROSS_COMPILE)ld AR = $(CROSS_COMPILE)ar PKG_CONFIG = $(CROSS_COMPILE)pkg-config @@ -464,21 +465,6 @@ LIB_OBJS += $(OUTPUT)tests/thread-mg-share.o LIB_OBJS += $(OUTPUT)tests/switch-tracking.o BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o -BUILTIN_OBJS += $(OUTPUT)builtin-bench.o -# Benchmark modules -BUILTIN_OBJS += $(OUTPUT)bench/sched-messaging.o -BUILTIN_OBJS += $(OUTPUT)bench/sched-pipe.o -ifeq ($(ARCH), x86) -ifeq ($(IS_64_BIT), 1) -BUILTIN_OBJS += $(OUTPUT)bench/mem-memcpy-x86-64-asm.o -BUILTIN_OBJS += $(OUTPUT)bench/mem-memset-x86-64-asm.o -endif -endif -BUILTIN_OBJS += $(OUTPUT)bench/mem-memcpy.o -BUILTIN_OBJS += $(OUTPUT)bench/futex-hash.o -BUILTIN_OBJS += $(OUTPUT)bench/futex-wake.o -BUILTIN_OBJS += $(OUTPUT)bench/futex-requeue.o - BUILTIN_OBJS += $(OUTPUT)builtin-diff.o BUILTIN_OBJS += $(OUTPUT)builtin-evlist.o BUILTIN_OBJS += $(OUTPUT)builtin-help.o @@ -597,10 +583,6 @@ ifeq ($(NO_PERF_REGS),0) LIB_OBJS += $(OUTPUT)util/perf_regs.o endif -ifndef NO_LIBNUMA - BUILTIN_OBJS += $(OUTPUT)bench/numa.o -endif - ifndef NO_ZLIB LIB_OBJS += $(OUTPUT)util/zlib.o endif @@ -627,14 +609,22 @@ shell_compatibility_test: please_set_SHELL_PATH_to_a_more_modern_shell strip: $(PROGRAMS) $(OUTPUT)perf $(STRIP) $(STRIP_OPTS) $(PROGRAMS) $(OUTPUT)perf +PERF_IN := $(OUTPUT)perf-in.o + +export srctree OUTPUT RM CC LD AR CFLAGS V +build := -f $(srctree)/tools/build/Makefile.build dir=. obj + +$(PERF_IN): FORCE + @$(MAKE) $(build)=perf + $(OUTPUT)perf.o: perf.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS $(QUIET_CC)$(CC) -include $(OUTPUT)PERF-VERSION-FILE \ '-DPERF_HTML_PATH="$(htmldir_SQ)"' \ $(CFLAGS) -c $(filter %.c,$^) -o $@ -$(OUTPUT)perf: $(OUTPUT)perf.o $(BUILTIN_OBJS) $(PERFLIBS) +$(OUTPUT)perf: $(OUTPUT)perf.o $(BUILTIN_OBJS) $(PERFLIBS) $(PERF_IN) $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $(OUTPUT)perf.o \ - $(BUILTIN_OBJS) $(LIBS) -o $@ + $(BUILTIN_OBJS) $(PERF_IN) $(LIBS) -o $@ $(GTK_OBJS): $(OUTPUT)%.o: %.c $(LIB_H) $(QUIET_CC)$(CC) -o $@ -c -fPIC $(CFLAGS) $(GTK_CFLAGS) $< @@ -989,6 +979,8 @@ config-clean: clean: $(LIBTRACEEVENT)-clean $(LIBAPIKFS)-clean config-clean $(call QUIET_CLEAN, core-objs) $(RM) $(LIB_OBJS) $(BUILTIN_OBJS) $(LIB_FILE) $(OUTPUT)perf-archive $(OUTPUT)perf-with-kcore $(OUTPUT)perf.o $(LANG_BINDINGS) $(GTK_OBJS) + @find . -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete + @$(RM) .config-detected $(call QUIET_CLEAN, core-progs) $(RM) $(ALL_PROGRAMS) perf perf-read-vdso32 perf-read-vdsox32 $(call QUIET_CLEAN, core-gen) $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope* $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)PERF-CFLAGS $(OUTPUT)PERF-FEATURES $(OUTPUT)util/*-bison* $(OUTPUT)util/*-flex* $(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) clean @@ -1004,7 +996,9 @@ else GIT-HEAD-PHONY = endif +FORCE: + .PHONY: all install clean config-clean strip install-gtk .PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell -.PHONY: $(GIT-HEAD-PHONY) TAGS tags cscope .FORCE-PERF-CFLAGS +.PHONY: $(GIT-HEAD-PHONY) TAGS tags cscope .FORCE-PERF-CFLAGS FORCE diff --git a/tools/perf/bench/Build b/tools/perf/bench/Build new file mode 100644 index 000000000000..5ce98023d518 --- /dev/null +++ b/tools/perf/bench/Build @@ -0,0 +1,11 @@ +perf-y += sched-messaging.o +perf-y += sched-pipe.o +perf-y += mem-memcpy.o +perf-y += futex-hash.o +perf-y += futex-wake.o +perf-y += futex-requeue.o + +perf-$(CONFIG_X86_64) += mem-memcpy-x86-64-asm.o +perf-$(CONFIG_X86_64) += mem-memset-x86-64-asm.o + +perf-$(CONFIG_NUMA) += numa.o diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index ba414216e506..3e90fcab709d 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -28,6 +28,7 @@ ifeq ($(ARCH),x86) CFLAGS += -DHAVE_ARCH_X86_64_SUPPORT ARCH_INCLUDE = ../../arch/x86/lib/memcpy_64.S ../../arch/x86/lib/memset_64.S LIBUNWIND_LIBS = -lunwind -lunwind-x86_64 + $(call detected,CONFIG_X86_64) else LIBUNWIND_LIBS = -lunwind -lunwind-x86 endif @@ -639,6 +640,7 @@ ifndef NO_LIBNUMA else CFLAGS += -DHAVE_LIBNUMA_SUPPORT EXTLIBS += -lnuma + $(call detected,CONFIG_NUMA) endif endif -- GitLab From f39e042a133485e4b1aa73d3bc2249d01421f765 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 29 Dec 2014 15:03:09 +0100 Subject: [PATCH 00117/11651] perf build: Add tests objects building Move test objects building under build framework. Signed-off-by: Jiri Olsa Tested-by: Sukadev Bhattiprolu Tested-by: Will Deacon Cc: Alexis Berlemont Cc: Borislav Petkov Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-azbkwd1fl32t997a4shz4lgp@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Build | 1 + tools/perf/Makefile.perf | 55 -------------------------------------- tools/perf/config/Makefile | 10 +++++++ tools/perf/tests/Build | 42 +++++++++++++++++++++++++++++ 4 files changed, 53 insertions(+), 55 deletions(-) create mode 100644 tools/perf/tests/Build diff --git a/tools/perf/Build b/tools/perf/Build index 9ea828de3fde..b4b6a7ca760b 100644 --- a/tools/perf/Build +++ b/tools/perf/Build @@ -1,2 +1,3 @@ perf-y += builtin-bench.o perf-y += bench/ +perf-y += tests/ diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 77f67941dfc8..80c2a8f875ff 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -425,45 +425,6 @@ LIB_OBJS += $(OUTPUT)ui/stdio/hist.o LIB_OBJS += $(OUTPUT)arch/common.o -LIB_OBJS += $(OUTPUT)tests/parse-events.o -LIB_OBJS += $(OUTPUT)tests/dso-data.o -LIB_OBJS += $(OUTPUT)tests/attr.o -LIB_OBJS += $(OUTPUT)tests/vmlinux-kallsyms.o -LIB_OBJS += $(OUTPUT)tests/open-syscall.o -LIB_OBJS += $(OUTPUT)tests/open-syscall-all-cpus.o -LIB_OBJS += $(OUTPUT)tests/open-syscall-tp-fields.o -LIB_OBJS += $(OUTPUT)tests/mmap-basic.o -LIB_OBJS += $(OUTPUT)tests/perf-record.o -LIB_OBJS += $(OUTPUT)tests/rdpmc.o -LIB_OBJS += $(OUTPUT)tests/evsel-roundtrip-name.o -LIB_OBJS += $(OUTPUT)tests/evsel-tp-sched.o -LIB_OBJS += $(OUTPUT)tests/fdarray.o -LIB_OBJS += $(OUTPUT)tests/pmu.o -LIB_OBJS += $(OUTPUT)tests/hists_common.o -LIB_OBJS += $(OUTPUT)tests/hists_link.o -LIB_OBJS += $(OUTPUT)tests/hists_filter.o -LIB_OBJS += $(OUTPUT)tests/hists_output.o -LIB_OBJS += $(OUTPUT)tests/hists_cumulate.o -LIB_OBJS += $(OUTPUT)tests/python-use.o -LIB_OBJS += $(OUTPUT)tests/bp_signal.o -LIB_OBJS += $(OUTPUT)tests/bp_signal_overflow.o -LIB_OBJS += $(OUTPUT)tests/task-exit.o -LIB_OBJS += $(OUTPUT)tests/sw-clock.o -ifeq ($(ARCH),x86) -LIB_OBJS += $(OUTPUT)tests/perf-time-to-tsc.o -endif -LIB_OBJS += $(OUTPUT)tests/code-reading.o -LIB_OBJS += $(OUTPUT)tests/sample-parsing.o -LIB_OBJS += $(OUTPUT)tests/parse-no-sample-id-all.o -ifndef NO_DWARF_UNWIND -ifeq ($(ARCH),$(filter $(ARCH),x86 arm)) -LIB_OBJS += $(OUTPUT)tests/dwarf-unwind.o -endif -endif -LIB_OBJS += $(OUTPUT)tests/mmap-thread-lookup.o -LIB_OBJS += $(OUTPUT)tests/thread-mg-share.o -LIB_OBJS += $(OUTPUT)tests/switch-tracking.o - BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o BUILTIN_OBJS += $(OUTPUT)builtin-diff.o BUILTIN_OBJS += $(OUTPUT)builtin-evlist.o @@ -483,7 +444,6 @@ BUILTIN_OBJS += $(OUTPUT)builtin-kmem.o BUILTIN_OBJS += $(OUTPUT)builtin-lock.o BUILTIN_OBJS += $(OUTPUT)builtin-kvm.o BUILTIN_OBJS += $(OUTPUT)builtin-inject.o -BUILTIN_OBJS += $(OUTPUT)tests/builtin-test.o BUILTIN_OBJS += $(OUTPUT)builtin-mem.o PERFLIBS = $(LIB_FILE) $(LIBAPIKFS) $(LIBTRACEEVENT) @@ -525,7 +485,6 @@ endif ifndef NO_LIBUNWIND LIB_OBJS += $(OUTPUT)util/unwind-libunwind.o endif -LIB_OBJS += $(OUTPUT)tests/keep-tracking.o ifndef NO_LIBAUDIT BUILTIN_OBJS += $(OUTPUT)builtin-trace.o @@ -700,20 +659,6 @@ $(OUTPUT)util/exec_cmd.o: util/exec_cmd.c $(OUTPUT)PERF-CFLAGS '-DPREFIX="$(prefix_SQ)"' \ $< -$(OUTPUT)tests/attr.o: tests/attr.c $(OUTPUT)PERF-CFLAGS - $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) \ - '-DBINDIR="$(bindir_SQ)"' -DPYTHON='"$(PYTHON_WORD)"' \ - $< - -$(OUTPUT)tests/python-use.o: tests/python-use.c $(OUTPUT)PERF-CFLAGS - $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) \ - -DPYTHONPATH='"$(OUTPUT)python"' \ - -DPYTHON='"$(PYTHON_WORD)"' \ - $< - -$(OUTPUT)tests/dwarf-unwind.o: tests/dwarf-unwind.c - $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -fno-optimize-sibling-calls $< - $(OUTPUT)util/config.o: util/config.c $(OUTPUT)PERF-CFLAGS $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 3e90fcab709d..2fd018529b95 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -20,10 +20,13 @@ CFLAGS := $(EXTRA_CFLAGS) $(EXTRA_WARNINGS) include $(src-perf)/config/Makefile.arch +$(call detected_var,ARCH) + NO_PERF_REGS := 1 # Additional ARCH settings for x86 ifeq ($(ARCH),x86) + $(call detected,CONFIG_X86) ifeq (${IS_64_BIT}, 1) CFLAGS += -DHAVE_ARCH_X86_64_SUPPORT ARCH_INCLUDE = ../../arch/x86/lib/memcpy_64.S ../../arch/x86/lib/memset_64.S @@ -424,6 +427,7 @@ endif ifeq ($(dwarf-post-unwind),1) CFLAGS += -DHAVE_DWARF_UNWIND_SUPPORT + $(call detected,CONFIG_DWARF_UNWIND) else NO_DWARF_UNWIND := 1 endif @@ -821,3 +825,9 @@ endif ifeq ($(display_lib),1) $(info ) endif + +$(call detected_var,bindir_SQ) +$(call detected_var,PYTHON_WORD) +ifneq ($(OUTPUT),) +$(call detected_var,OUTPUT) +endif diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build new file mode 100644 index 000000000000..2de01a4b4084 --- /dev/null +++ b/tools/perf/tests/Build @@ -0,0 +1,42 @@ +perf-y += builtin-test.o +perf-y += parse-events.o +perf-y += dso-data.o +perf-y += attr.o +perf-y += vmlinux-kallsyms.o +perf-y += open-syscall.o +perf-y += open-syscall-all-cpus.o +perf-y += open-syscall-tp-fields.o +perf-y += mmap-basic.o +perf-y += perf-record.o +perf-y += rdpmc.o +perf-y += evsel-roundtrip-name.o +perf-y += evsel-tp-sched.o +perf-y += fdarray.o +perf-y += pmu.o +perf-y += hists_common.o +perf-y += hists_link.o +perf-y += hists_filter.o +perf-y += hists_output.o +perf-y += hists_cumulate.o +perf-y += python-use.o +perf-y += bp_signal.o +perf-y += bp_signal_overflow.o +perf-y += task-exit.o +perf-y += sw-clock.o +perf-y += mmap-thread-lookup.o +perf-y += thread-mg-share.o +perf-y += switch-tracking.o +perf-y += keep-tracking.o +perf-y += code-reading.o +perf-y += sample-parsing.o +perf-y += parse-no-sample-id-all.o + +perf-$(CONFIG_X86) += perf-time-to-tsc.o + +ifeq ($(ARCH),$(filter $(ARCH),x86 arm)) +perf-$(CONFIG_DWARF_UNWIND) += dwarf-unwind.o +endif + +CFLAGS_attr.o += -DBINDIR="BUILD_STR($(bindir_SQ))" -DPYTHON="BUILD_STR($(PYTHON_WORD))" +CFLAGS_python-use.o += -DPYTHONPATH="BUILD_STR($(OUTPUT)python)" -DPYTHON="BUILD_STR($(PYTHON_WORD))" +CFLAGS_dwarf-unwind.o += -fno-optimize-sibling-calls -- GitLab From 285ab8bfc6637780052f663d90e3aa9a653042c9 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 29 Dec 2014 15:13:44 +0100 Subject: [PATCH 00118/11651] perf build: Add builtin objects building Move the rest of builtin objects (bench and test are already in) building under build framework. Signed-off-by: Jiri Olsa Tested-by: Sukadev Bhattiprolu Tested-by: Will Deacon Cc: Alexis Berlemont Cc: Borislav Petkov Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-mrh2d4kfyi4g1el4kmdcghl8@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Build | 29 +++++++++++++++++++++++++++++ tools/perf/Makefile.perf | 37 +------------------------------------ tools/perf/config/Makefile | 4 ++++ 3 files changed, 34 insertions(+), 36 deletions(-) diff --git a/tools/perf/Build b/tools/perf/Build index b4b6a7ca760b..80a944b929da 100644 --- a/tools/perf/Build +++ b/tools/perf/Build @@ -1,3 +1,32 @@ perf-y += builtin-bench.o +perf-y += builtin-annotate.o +perf-y += builtin-diff.o +perf-y += builtin-evlist.o +perf-y += builtin-help.o +perf-y += builtin-sched.o +perf-y += builtin-buildid-list.o +perf-y += builtin-buildid-cache.o +perf-y += builtin-list.o +perf-y += builtin-record.o +perf-y += builtin-report.o +perf-y += builtin-stat.o +perf-y += builtin-timechart.o +perf-y += builtin-top.o +perf-y += builtin-script.o +perf-y += builtin-kmem.o +perf-y += builtin-lock.o +perf-y += builtin-kvm.o +perf-y += builtin-inject.o +perf-y += builtin-mem.o + +perf-$(CONFIG_AUDIT) += builtin-trace.o + perf-y += bench/ perf-y += tests/ + +paths += -DPERF_HTML_PATH="BUILD_STR($(htmldir_SQ))" +paths += -DPERF_INFO_PATH="BUILD_STR($(infodir_SQ))" +paths += -DPERF_MAN_PATH="BUILD_STR($(mandir_SQ))" + +CFLAGS_builtin-help.o += $(paths) +CFLAGS_builtin-timechart.o += $(paths) diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 80c2a8f875ff..4990b999d595 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -425,26 +425,7 @@ LIB_OBJS += $(OUTPUT)ui/stdio/hist.o LIB_OBJS += $(OUTPUT)arch/common.o -BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o -BUILTIN_OBJS += $(OUTPUT)builtin-diff.o -BUILTIN_OBJS += $(OUTPUT)builtin-evlist.o -BUILTIN_OBJS += $(OUTPUT)builtin-help.o -BUILTIN_OBJS += $(OUTPUT)builtin-sched.o -BUILTIN_OBJS += $(OUTPUT)builtin-buildid-list.o -BUILTIN_OBJS += $(OUTPUT)builtin-buildid-cache.o -BUILTIN_OBJS += $(OUTPUT)builtin-list.o -BUILTIN_OBJS += $(OUTPUT)builtin-record.o -BUILTIN_OBJS += $(OUTPUT)builtin-report.o -BUILTIN_OBJS += $(OUTPUT)builtin-stat.o -BUILTIN_OBJS += $(OUTPUT)builtin-timechart.o -BUILTIN_OBJS += $(OUTPUT)builtin-top.o -BUILTIN_OBJS += $(OUTPUT)builtin-script.o BUILTIN_OBJS += $(OUTPUT)builtin-probe.o -BUILTIN_OBJS += $(OUTPUT)builtin-kmem.o -BUILTIN_OBJS += $(OUTPUT)builtin-lock.o -BUILTIN_OBJS += $(OUTPUT)builtin-kvm.o -BUILTIN_OBJS += $(OUTPUT)builtin-inject.o -BUILTIN_OBJS += $(OUTPUT)builtin-mem.o PERFLIBS = $(LIB_FILE) $(LIBAPIKFS) $(LIBTRACEEVENT) @@ -486,10 +467,6 @@ ifndef NO_LIBUNWIND LIB_OBJS += $(OUTPUT)util/unwind-libunwind.o endif -ifndef NO_LIBAUDIT - BUILTIN_OBJS += $(OUTPUT)builtin-trace.o -endif - ifndef NO_SLANG LIB_OBJS += $(OUTPUT)ui/browser.o LIB_OBJS += $(OUTPUT)ui/browsers/annotate.o @@ -573,7 +550,7 @@ PERF_IN := $(OUTPUT)perf-in.o export srctree OUTPUT RM CC LD AR CFLAGS V build := -f $(srctree)/tools/build/Makefile.build dir=. obj -$(PERF_IN): FORCE +$(PERF_IN): $(OUTPUT)common-cmds.h FORCE @$(MAKE) $(build)=perf $(OUTPUT)perf.o: perf.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS @@ -591,18 +568,6 @@ $(GTK_OBJS): $(OUTPUT)%.o: %.c $(LIB_H) $(OUTPUT)libperf-gtk.so: $(GTK_OBJS) $(PERFLIBS) $(QUIET_LINK)$(CC) -o $@ -shared $(LDFLAGS) $(filter %.o,$^) $(GTK_LIBS) -$(OUTPUT)builtin-help.o: builtin-help.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS - $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) \ - '-DPERF_HTML_PATH="$(htmldir_SQ)"' \ - '-DPERF_MAN_PATH="$(mandir_SQ)"' \ - '-DPERF_INFO_PATH="$(infodir_SQ)"' $< - -$(OUTPUT)builtin-timechart.o: builtin-timechart.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS - $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) \ - '-DPERF_HTML_PATH="$(htmldir_SQ)"' \ - '-DPERF_MAN_PATH="$(mandir_SQ)"' \ - '-DPERF_INFO_PATH="$(infodir_SQ)"' $< - $(OUTPUT)common-cmds.h: util/generate-cmdlist.sh command-list.txt $(OUTPUT)common-cmds.h: $(wildcard Documentation/perf-*.txt) diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 2fd018529b95..deb0c596fc15 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -456,6 +456,7 @@ ifndef NO_LIBAUDIT else CFLAGS += -DHAVE_LIBAUDIT_SUPPORT EXTLIBS += -laudit + $(call detected,CONFIG_AUDIT) endif endif @@ -831,3 +832,6 @@ $(call detected_var,PYTHON_WORD) ifneq ($(OUTPUT),) $(call detected_var,OUTPUT) endif +$(call detected_var,htmldir_SQ) +$(call detected_var,infodir_SQ) +$(call detected_var,mandir_SQ) -- GitLab From 9352aabad16af51c4c66fb2470ca01e4005bd282 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 29 Dec 2014 17:42:46 +0100 Subject: [PATCH 00119/11651] perf build: Add libperf objects building Move the util objects building under build framework. Add the new libperf build object so it's separated from the rest of the perf code and could be librarized. Signed-off-by: Jiri Olsa Tested-by: Sukadev Bhattiprolu Tested-by: Will Deacon Cc: Alexis Berlemont Cc: Borislav Petkov Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-574tgt9t23tnxo9td8qjiibc@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/build/Makefile.build | 3 + tools/perf/Build | 3 + tools/perf/Makefile.perf | 139 ++++--------------------------------- tools/perf/arch/Build | 1 + tools/perf/config/Makefile | 5 ++ tools/perf/util/Build | 116 +++++++++++++++++++++++++++++++ 6 files changed, 141 insertions(+), 126 deletions(-) create mode 100644 tools/perf/arch/Build create mode 100644 tools/perf/util/Build diff --git a/tools/build/Makefile.build b/tools/build/Makefile.build index 692e1b154200..aced86d2bbf8 100644 --- a/tools/build/Makefile.build +++ b/tools/build/Makefile.build @@ -37,6 +37,9 @@ subdir-obj-y := build-file := $(dir)/Build include $(build-file) +quiet_cmd_flex = FLEX $@ +quiet_cmd_bison = BISON $@ + # Create directory unless it exists quiet_cmd_mkdir = MKDIR $(dir $@) cmd_mkdir = mkdir -p $(dir $@) diff --git a/tools/perf/Build b/tools/perf/Build index 80a944b929da..31c4c555cc81 100644 --- a/tools/perf/Build +++ b/tools/perf/Build @@ -30,3 +30,6 @@ paths += -DPERF_MAN_PATH="BUILD_STR($(mandir_SQ))" CFLAGS_builtin-help.o += $(paths) CFLAGS_builtin-timechart.o += $(paths) + +libperf-y += util/ +libperf-y += arch/ diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 4990b999d595..8951cd9809a2 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -82,6 +82,11 @@ endif ifneq ($(OUTPUT),) #$(info Determined 'OUTPUT' to be $(OUTPUT)) +# Adding $(OUTPUT) as a directory to look for source files, +# because use generated output files as sources dependency +# for flex/bison parsers. +VPATH += $(OUTPUT) +export VPATH endif # Do not use make's built-in rules @@ -211,21 +216,6 @@ endif export PERL_PATH -$(OUTPUT)util/parse-events-flex.c: util/parse-events.l $(OUTPUT)util/parse-events-bison.c - $(QUIET_FLEX)$(FLEX) -o $@ --header-file=$(OUTPUT)util/parse-events-flex.h $(PARSER_DEBUG_FLEX) util/parse-events.l - -$(OUTPUT)util/parse-events-bison.c: util/parse-events.y - $(QUIET_BISON)$(BISON) -v util/parse-events.y -d $(PARSER_DEBUG_BISON) -o $(OUTPUT)util/parse-events-bison.c -p parse_events_ - -$(OUTPUT)util/pmu-flex.c: util/pmu.l $(OUTPUT)util/pmu-bison.c - $(QUIET_FLEX)$(FLEX) -o $@ --header-file=$(OUTPUT)util/pmu-flex.h util/pmu.l - -$(OUTPUT)util/pmu-bison.c: util/pmu.y - $(QUIET_BISON)$(BISON) -v util/pmu.y -d -o $(OUTPUT)util/pmu-bison.c -p perf_pmu_ - -$(OUTPUT)util/parse-events.o: $(OUTPUT)util/parse-events-flex.c $(OUTPUT)util/parse-events-bison.c -$(OUTPUT)util/pmu.o: $(OUTPUT)util/pmu-flex.c $(OUTPUT)util/pmu-bison.c - LIB_FILE=$(OUTPUT)libperf.a LIB_H += ../lib/symbol/kallsyms.h @@ -337,84 +327,8 @@ LIB_H += util/data.h LIB_H += util/kvm-stat.h LIB_H += util/thread-stack.h -LIB_OBJS += $(OUTPUT)util/abspath.o -LIB_OBJS += $(OUTPUT)util/alias.o -LIB_OBJS += $(OUTPUT)util/annotate.o -LIB_OBJS += $(OUTPUT)util/build-id.o -LIB_OBJS += $(OUTPUT)util/config.o -LIB_OBJS += $(OUTPUT)util/ctype.o -LIB_OBJS += $(OUTPUT)util/db-export.o -LIB_OBJS += $(OUTPUT)util/pmu.o -LIB_OBJS += $(OUTPUT)util/environment.o -LIB_OBJS += $(OUTPUT)util/event.o -LIB_OBJS += $(OUTPUT)util/evlist.o -LIB_OBJS += $(OUTPUT)util/evsel.o -LIB_OBJS += $(OUTPUT)util/exec_cmd.o -LIB_OBJS += $(OUTPUT)util/find_next_bit.o -LIB_OBJS += $(OUTPUT)util/help.o -LIB_OBJS += $(OUTPUT)util/kallsyms.o -LIB_OBJS += $(OUTPUT)util/levenshtein.o -LIB_OBJS += $(OUTPUT)util/parse-options.o -LIB_OBJS += $(OUTPUT)util/parse-events.o -LIB_OBJS += $(OUTPUT)util/path.o -LIB_OBJS += $(OUTPUT)util/rbtree.o -LIB_OBJS += $(OUTPUT)util/bitmap.o -LIB_OBJS += $(OUTPUT)util/hweight.o -LIB_OBJS += $(OUTPUT)util/run-command.o -LIB_OBJS += $(OUTPUT)util/quote.o -LIB_OBJS += $(OUTPUT)util/strbuf.o -LIB_OBJS += $(OUTPUT)util/string.o -LIB_OBJS += $(OUTPUT)util/strlist.o -LIB_OBJS += $(OUTPUT)util/strfilter.o -LIB_OBJS += $(OUTPUT)util/top.o -LIB_OBJS += $(OUTPUT)util/usage.o -LIB_OBJS += $(OUTPUT)util/wrapper.o -LIB_OBJS += $(OUTPUT)util/sigchain.o -LIB_OBJS += $(OUTPUT)util/dso.o -LIB_OBJS += $(OUTPUT)util/symbol.o LIB_OBJS += $(OUTPUT)util/symbol-elf.o -LIB_OBJS += $(OUTPUT)util/color.o -LIB_OBJS += $(OUTPUT)util/pager.o -LIB_OBJS += $(OUTPUT)util/header.o -LIB_OBJS += $(OUTPUT)util/callchain.o -LIB_OBJS += $(OUTPUT)util/values.o -LIB_OBJS += $(OUTPUT)util/debug.o -LIB_OBJS += $(OUTPUT)util/machine.o -LIB_OBJS += $(OUTPUT)util/map.o -LIB_OBJS += $(OUTPUT)util/pstack.o -LIB_OBJS += $(OUTPUT)util/session.o -LIB_OBJS += $(OUTPUT)util/ordered-events.o -LIB_OBJS += $(OUTPUT)util/comm.o -LIB_OBJS += $(OUTPUT)util/thread.o -LIB_OBJS += $(OUTPUT)util/thread_map.o -LIB_OBJS += $(OUTPUT)util/trace-event-parse.o -LIB_OBJS += $(OUTPUT)util/parse-events-flex.o -LIB_OBJS += $(OUTPUT)util/parse-events-bison.o -LIB_OBJS += $(OUTPUT)util/pmu-flex.o -LIB_OBJS += $(OUTPUT)util/pmu-bison.o -LIB_OBJS += $(OUTPUT)util/trace-event-read.o -LIB_OBJS += $(OUTPUT)util/trace-event-info.o -LIB_OBJS += $(OUTPUT)util/trace-event-scripting.o -LIB_OBJS += $(OUTPUT)util/trace-event.o -LIB_OBJS += $(OUTPUT)util/svghelper.o -LIB_OBJS += $(OUTPUT)util/sort.o -LIB_OBJS += $(OUTPUT)util/hist.o LIB_OBJS += $(OUTPUT)util/probe-event.o -LIB_OBJS += $(OUTPUT)util/util.o -LIB_OBJS += $(OUTPUT)util/xyarray.o -LIB_OBJS += $(OUTPUT)util/cpumap.o -LIB_OBJS += $(OUTPUT)util/cgroup.o -LIB_OBJS += $(OUTPUT)util/target.o -LIB_OBJS += $(OUTPUT)util/rblist.o -LIB_OBJS += $(OUTPUT)util/intlist.o -LIB_OBJS += $(OUTPUT)util/vdso.o -LIB_OBJS += $(OUTPUT)util/stat.o -LIB_OBJS += $(OUTPUT)util/record.o -LIB_OBJS += $(OUTPUT)util/srcline.o -LIB_OBJS += $(OUTPUT)util/data.o -LIB_OBJS += $(OUTPUT)util/tsc.o -LIB_OBJS += $(OUTPUT)util/cloexec.o -LIB_OBJS += $(OUTPUT)util/thread-stack.o LIB_OBJS += $(OUTPUT)ui/setup.o LIB_OBJS += $(OUTPUT)ui/helpline.o @@ -423,8 +337,6 @@ LIB_OBJS += $(OUTPUT)ui/util.o LIB_OBJS += $(OUTPUT)ui/hist.o LIB_OBJS += $(OUTPUT)ui/stdio/hist.o -LIB_OBJS += $(OUTPUT)arch/common.o - BUILTIN_OBJS += $(OUTPUT)builtin-probe.o PERFLIBS = $(LIB_FILE) $(LIBAPIKFS) $(LIBTRACEEVENT) @@ -547,7 +459,7 @@ strip: $(PROGRAMS) $(OUTPUT)perf PERF_IN := $(OUTPUT)perf-in.o -export srctree OUTPUT RM CC LD AR CFLAGS V +export srctree OUTPUT RM CC LD AR CFLAGS V BISON FLEX build := -f $(srctree)/tools/build/Makefile.build dir=. obj $(PERF_IN): $(OUTPUT)common-cmds.h FORCE @@ -601,12 +513,6 @@ endif # These two need to be here so that when O= is not used they take precedence # over the general rule for .o -$(OUTPUT)util/%-flex.o: $(OUTPUT)util/%-flex.c $(OUTPUT)PERF-CFLAGS - $(QUIET_CC)$(CC) -o $@ -c -Iutil/ $(CFLAGS) -w $< - -$(OUTPUT)util/%-bison.o: $(OUTPUT)util/%-bison.c $(OUTPUT)PERF-CFLAGS - $(QUIET_CC)$(CC) -o $@ -c -Iutil/ $(CFLAGS) -DYYENABLE_NLS=0 -DYYLTYPE_IS_TRIVIAL=0 -w $< - $(OUTPUT)%.o: %.c $(OUTPUT)PERF-CFLAGS $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $< $(OUTPUT)%.i: %.c $(OUTPUT)PERF-CFLAGS @@ -618,15 +524,6 @@ $(OUTPUT)%.o: %.S $(OUTPUT)%.s: %.S $(QUIET_CC)$(CC) -o $@ -E $(CFLAGS) $< -$(OUTPUT)util/exec_cmd.o: util/exec_cmd.c $(OUTPUT)PERF-CFLAGS - $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) \ - '-DPERF_EXEC_PATH="$(perfexecdir_SQ)"' \ - '-DPREFIX="$(prefix_SQ)"' \ - $< - -$(OUTPUT)util/config.o: util/config.c $(OUTPUT)PERF-CFLAGS - $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< - $(OUTPUT)ui/setup.o: ui/setup.c $(OUTPUT)PERF-CFLAGS $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DLIBDIR='"$(libdir_SQ)"' $< @@ -645,21 +542,6 @@ $(OUTPUT)ui/browsers/map.o: ui/browsers/map.c $(OUTPUT)PERF-CFLAGS $(OUTPUT)ui/browsers/scripts.o: ui/browsers/scripts.c $(OUTPUT)PERF-CFLAGS $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DENABLE_SLFUTURE_CONST $< -$(OUTPUT)util/kallsyms.o: ../lib/symbol/kallsyms.c $(OUTPUT)PERF-CFLAGS - $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $< - -$(OUTPUT)util/rbtree.o: ../../lib/rbtree.c $(OUTPUT)PERF-CFLAGS - $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-unused-parameter -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< - -$(OUTPUT)util/hweight.o: ../../lib/hweight.c $(OUTPUT)PERF-CFLAGS - $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-unused-parameter -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< - -$(OUTPUT)util/find_next_bit.o: ../lib/util/find_next_bit.c $(OUTPUT)PERF-CFLAGS - $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-unused-parameter -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< - -$(OUTPUT)util/parse-events.o: util/parse-events.c $(OUTPUT)PERF-CFLAGS - $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-redundant-decls $< - $(OUTPUT)util/scripting-engines/trace-event-perl.o: util/scripting-engines/trace-event-perl.c $(OUTPUT)PERF-CFLAGS $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow -Wno-undef -Wno-switch-default $< @@ -703,8 +585,13 @@ $(DIRECTORY_DEPS): | $(OUTPUT_DIRECTORIES) $(OUTPUT_DIRECTORIES): $(QUIET_MKDIR)$(MKDIR) -p $@ 2>/dev/null -$(LIB_FILE): $(LIB_OBJS) - $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(LIB_OBJS) +LIBPERF_IN := $(OUTPUT)libperf-in.o + +$(LIBPERF_IN): FORCE + @$(MAKE) $(build)=libperf + +$(LIB_FILE): $(LIB_OBJS) $(LIBPERF_IN) + $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(LIBPERF_IN) $(LIB_OBJS) # libtraceevent.a TE_SOURCES = $(wildcard $(TRACE_EVENT_DIR)*.[ch]) diff --git a/tools/perf/arch/Build b/tools/perf/arch/Build new file mode 100644 index 000000000000..304f5e76c613 --- /dev/null +++ b/tools/perf/arch/Build @@ -0,0 +1 @@ +libperf-y += common.o diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index deb0c596fc15..5b89bb7b2d7d 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -122,6 +122,8 @@ ifdef PARSER_DEBUG PARSER_DEBUG_BISON := -t PARSER_DEBUG_FLEX := -d CFLAGS += -DPARSER_DEBUG + $(call detected_var,PARSER_DEBUG_BISON) + $(call detected_var,PARSER_DEBUG_FLEX) endif ifndef NO_LIBPYTHON @@ -835,3 +837,6 @@ endif $(call detected_var,htmldir_SQ) $(call detected_var,infodir_SQ) $(call detected_var,mandir_SQ) +$(call detected_var,ETC_PERFCONFIG_SQ) +$(call detected_var,prefix_SQ) +$(call detected_var,perfexecdir_SQ) diff --git a/tools/perf/util/Build b/tools/perf/util/Build new file mode 100644 index 000000000000..c107f309d29f --- /dev/null +++ b/tools/perf/util/Build @@ -0,0 +1,116 @@ +libperf-y += abspath.o +libperf-y += alias.o +libperf-y += annotate.o +libperf-y += build-id.o +libperf-y += config.o +libperf-y += ctype.o +libperf-y += db-export.o +libperf-y += environment.o +libperf-y += event.o +libperf-y += evlist.o +libperf-y += evsel.o +libperf-y += exec_cmd.o +libperf-y += find_next_bit.o +libperf-y += help.o +libperf-y += kallsyms.o +libperf-y += levenshtein.o +libperf-y += parse-options.o +libperf-y += parse-events.o +libperf-y += path.o +libperf-y += rbtree.o +libperf-y += bitmap.o +libperf-y += hweight.o +libperf-y += run-command.o +libperf-y += quote.o +libperf-y += strbuf.o +libperf-y += string.o +libperf-y += strlist.o +libperf-y += strfilter.o +libperf-y += top.o +libperf-y += usage.o +libperf-y += wrapper.o +libperf-y += sigchain.o +libperf-y += dso.o +libperf-y += symbol.o +libperf-y += color.o +libperf-y += pager.o +libperf-y += header.o +libperf-y += callchain.o +libperf-y += values.o +libperf-y += debug.o +libperf-y += machine.o +libperf-y += map.o +libperf-y += pstack.o +libperf-y += session.o +libperf-y += ordered-events.o +libperf-y += comm.o +libperf-y += thread.o +libperf-y += thread_map.o +libperf-y += trace-event-parse.o +libperf-y += parse-events-flex.o +libperf-y += parse-events-bison.o +libperf-y += pmu.o +libperf-y += pmu-flex.o +libperf-y += pmu-bison.o +libperf-y += trace-event-read.o +libperf-y += trace-event-info.o +libperf-y += trace-event-scripting.o +libperf-y += trace-event.o +libperf-y += svghelper.o +libperf-y += sort.o +libperf-y += hist.o +libperf-y += util.o +libperf-y += xyarray.o +libperf-y += cpumap.o +libperf-y += cgroup.o +libperf-y += target.o +libperf-y += rblist.o +libperf-y += intlist.o +libperf-y += vdso.o +libperf-y += stat.o +libperf-y += record.o +libperf-y += srcline.o +libperf-y += data.o +libperf-y += tsc.o +libperf-y += cloexec.o +libperf-y += thread-stack.o + +CFLAGS_config.o += -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))" +CFLAGS_exec_cmd.o += -DPERF_EXEC_PATH="BUILD_STR($(perfexecdir_SQ))" -DPREFIX="BUILD_STR($(prefix_SQ))" + +$(OUTPUT)util/parse-events-flex.c: util/parse-events.l $(OUTPUT)util/parse-events-bison.c + @$(call echo-cmd,flex)$(FLEX) -o $@ --header-file=$(OUTPUT)util/parse-events-flex.h $(PARSER_DEBUG_FLEX) util/parse-events.l + +$(OUTPUT)util/parse-events-bison.c: util/parse-events.y + @$(call echo-cmd,bison)$(BISON) -v util/parse-events.y -d $(PARSER_DEBUG_BISON) -o $@ -p parse_events_ + +$(OUTPUT)util/pmu-flex.c: util/pmu.l $(OUTPUT)util/pmu-bison.c + @$(call echo-cmd,flex)$(FLEX) -o $@ --header-file=$(OUTPUT)util/pmu-flex.h util/pmu.l + +$(OUTPUT)util/pmu-bison.c: util/pmu.y + @$(call echo-cmd,bison)$(BISON) -v util/pmu.y -d -o $@ -p perf_pmu_ + +CFLAGS_parse-events-flex.o += -w +CFLAGS_pmu-flex.o += -w +CFLAGS_parse-events-bison.o += -DYYENABLE_NLS=0 -DYYLTYPE_IS_TRIVIAL=0 -w +CFLAGS_pmu-bison.o += -DYYENABLE_NLS=0 -DYYLTYPE_IS_TRIVIAL=0 -w + +$(OUTPUT)util/parse-events.o: $(OUTPUT)util/parse-events-flex.c $(OUTPUT)util/parse-events-bison.c +$(OUTPUT)util/pmu.o: $(OUTPUT)util/pmu-flex.c $(OUTPUT)util/pmu-bison.c + +CFLAGS_find_next_bit.o += -Wno-unused-parameter -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))" +CFLAGS_rbtree.o += -Wno-unused-parameter -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))" +CFLAGS_hweight.o += -Wno-unused-parameter -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))" +CFLAGS_parse-events.o += -Wno-redundant-decls + +$(OUTPUT)util/kallsyms.o: ../lib/symbol/kallsyms.c FORCE + $(call if_changed_dep,cc_o_c) + +$(OUTPUT)util/find_next_bit.o: ../lib/util/find_next_bit.c FORCE + $(call if_changed_dep,cc_o_c) + +$(OUTPUT)util/rbtree.o: ../../lib/rbtree.c FORCE + $(call if_changed_dep,cc_o_c) + +$(OUTPUT)util/hweight.o: ../../lib/hweight.c FORCE + $(call if_changed_dep,cc_o_c) -- GitLab From 709e679193c6e0e39222cd1fd51008225208cbc7 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 29 Dec 2014 23:52:25 +0100 Subject: [PATCH 00120/11651] perf build: Add probe objects building Move the probe objects building under build framework to be included in the libperf build object. Signed-off-by: Jiri Olsa Tested-by: Sukadev Bhattiprolu Tested-by: Will Deacon Cc: Alexis Berlemont Cc: Borislav Petkov Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-p39iitiu2ltgmtbn48bsh7nz@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Build | 1 + tools/perf/Makefile.perf | 19 +------------------ tools/perf/config/Makefile | 1 + tools/perf/util/Build | 7 +++++++ 4 files changed, 10 insertions(+), 18 deletions(-) diff --git a/tools/perf/Build b/tools/perf/Build index 31c4c555cc81..170e4563bb24 100644 --- a/tools/perf/Build +++ b/tools/perf/Build @@ -20,6 +20,7 @@ perf-y += builtin-inject.o perf-y += builtin-mem.o perf-$(CONFIG_AUDIT) += builtin-trace.o +perf-$(CONFIG_LIBELF) += builtin-probe.o perf-y += bench/ perf-y += tests/ diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 8951cd9809a2..0997e2b33c77 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -327,9 +327,6 @@ LIB_H += util/data.h LIB_H += util/kvm-stat.h LIB_H += util/thread-stack.h -LIB_OBJS += $(OUTPUT)util/symbol-elf.o -LIB_OBJS += $(OUTPUT)util/probe-event.o - LIB_OBJS += $(OUTPUT)ui/setup.o LIB_OBJS += $(OUTPUT)ui/helpline.o LIB_OBJS += $(OUTPUT)ui/progress.o @@ -337,8 +334,6 @@ LIB_OBJS += $(OUTPUT)ui/util.o LIB_OBJS += $(OUTPUT)ui/hist.o LIB_OBJS += $(OUTPUT)ui/stdio/hist.o -BUILTIN_OBJS += $(OUTPUT)builtin-probe.o - PERFLIBS = $(LIB_FILE) $(LIBAPIKFS) $(LIBTRACEEVENT) # We choose to avoid "if .. else if .. else .. endif endif" @@ -351,19 +346,7 @@ ifneq ($(OUTPUT),) CFLAGS += -I$(OUTPUT) endif -ifdef NO_LIBELF -# Remove ELF/DWARF dependent codes -LIB_OBJS := $(filter-out $(OUTPUT)util/symbol-elf.o,$(LIB_OBJS)) -LIB_OBJS := $(filter-out $(OUTPUT)util/dwarf-aux.o,$(LIB_OBJS)) -LIB_OBJS := $(filter-out $(OUTPUT)util/probe-event.o,$(LIB_OBJS)) -LIB_OBJS := $(filter-out $(OUTPUT)util/probe-finder.o,$(LIB_OBJS)) - -BUILTIN_OBJS := $(filter-out $(OUTPUT)builtin-probe.o,$(BUILTIN_OBJS)) - -# Use minimal symbol handling -LIB_OBJS += $(OUTPUT)util/symbol-minimal.o - -else # NO_LIBELF +ifndef NO_LIBELF ifndef NO_DWARF LIB_OBJS += $(OUTPUT)util/probe-finder.o LIB_OBJS += $(OUTPUT)util/dwarf-aux.o diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 5b89bb7b2d7d..79ee4ccce3dc 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -371,6 +371,7 @@ endif # NO_LIBELF ifndef NO_LIBELF CFLAGS += -DHAVE_LIBELF_SUPPORT EXTLIBS += -lelf + $(call detected,CONFIG_LIBELF) ifeq ($(feature-libelf-mmap), 1) CFLAGS += -DHAVE_LIBELF_MMAP_SUPPORT diff --git a/tools/perf/util/Build b/tools/perf/util/Build index c107f309d29f..73a0411e2014 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -75,6 +75,13 @@ libperf-y += tsc.o libperf-y += cloexec.o libperf-y += thread-stack.o +libperf-$(CONFIG_LIBELF) += symbol-elf.o +libperf-$(CONFIG_LIBELF) += probe-event.o + +ifndef CONFIG_LIBELF +libperf-y += symbol-minimal.o +endif + CFLAGS_config.o += -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))" CFLAGS_exec_cmd.o += -DPERF_EXEC_PATH="BUILD_STR($(perfexecdir_SQ))" -DPREFIX="BUILD_STR($(prefix_SQ))" -- GitLab From 8379fce485cc57daa42a06f4cf1ad822b794d95d Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 30 Dec 2014 00:06:25 +0100 Subject: [PATCH 00121/11651] perf build: Add dwarf objects building Move the dwarf objects building under build framework to be included in the libperf build object. Signed-off-by: Jiri Olsa Tested-by: Sukadev Bhattiprolu Tested-by: Will Deacon Cc: Alexis Berlemont Cc: Borislav Petkov Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-5ody6tnfnkt4rezvpem8n7rm@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile.perf | 7 ------- tools/perf/config/Makefile | 1 + tools/perf/util/Build | 3 +++ 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 0997e2b33c77..5cb62b070e04 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -346,13 +346,6 @@ ifneq ($(OUTPUT),) CFLAGS += -I$(OUTPUT) endif -ifndef NO_LIBELF -ifndef NO_DWARF - LIB_OBJS += $(OUTPUT)util/probe-finder.o - LIB_OBJS += $(OUTPUT)util/dwarf-aux.o -endif # NO_DWARF -endif # NO_LIBELF - ifndef NO_LIBDW_DWARF_UNWIND LIB_OBJS += $(OUTPUT)util/unwind-libdw.o LIB_H += util/unwind-libdw.h diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 79ee4ccce3dc..5f553989d8a1 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -392,6 +392,7 @@ ifndef NO_LIBELF CFLAGS += -DHAVE_DWARF_SUPPORT $(LIBDW_CFLAGS) LDFLAGS += $(LIBDW_LDFLAGS) EXTLIBS += -ldw + $(call detected,CONFIG_DWARF) endif # PERF_HAVE_DWARF_REGS endif # NO_DWARF endif # NO_LIBELF diff --git a/tools/perf/util/Build b/tools/perf/util/Build index 73a0411e2014..10630fbe43c1 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -82,6 +82,9 @@ ifndef CONFIG_LIBELF libperf-y += symbol-minimal.o endif +libperf-$(CONFIG_DWARF) += probe-finder.o +libperf-$(CONFIG_DWARF) += dwarf-aux.o + CFLAGS_config.o += -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))" CFLAGS_exec_cmd.o += -DPERF_EXEC_PATH="BUILD_STR($(perfexecdir_SQ))" -DPREFIX="BUILD_STR($(prefix_SQ))" -- GitLab From b2e45c322e0298652fc05e65c671b2b88d30ae31 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 30 Dec 2014 00:11:11 +0100 Subject: [PATCH 00122/11651] perf build: Add dwarf unwind objects building Move the dwarf unwind objects building under build framework to be included in the libperf build object. Signed-off-by: Jiri Olsa Tested-by: Sukadev Bhattiprolu Tested-by: Will Deacon Cc: Alexis Berlemont Cc: Borislav Petkov Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-7f7dmhkhs0e7jnqiu9ibzqia@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile.perf | 9 --------- tools/perf/config/Makefile | 2 ++ tools/perf/util/Build | 3 +++ 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 5cb62b070e04..96e3cdc7f89c 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -346,15 +346,6 @@ ifneq ($(OUTPUT),) CFLAGS += -I$(OUTPUT) endif -ifndef NO_LIBDW_DWARF_UNWIND - LIB_OBJS += $(OUTPUT)util/unwind-libdw.o - LIB_H += util/unwind-libdw.h -endif - -ifndef NO_LIBUNWIND - LIB_OBJS += $(OUTPUT)util/unwind-libunwind.o -endif - ifndef NO_SLANG LIB_OBJS += $(OUTPUT)ui/browser.o LIB_OBJS += $(OUTPUT)ui/browsers/annotate.o diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 5f553989d8a1..e55d811e633f 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -420,9 +420,11 @@ ifdef NO_LIBUNWIND dwarf-post-unwind := 0 else dwarf-post-unwind-text := libdw + $(call detected,CONFIG_LIBDW_DWARF_UNWIND) endif else dwarf-post-unwind-text := libunwind + $(call detected,CONFIG_LIBUNWIND) # Enable libunwind support by default. ifndef NO_LIBDW_DWARF_UNWIND NO_LIBDW_DWARF_UNWIND := 1 diff --git a/tools/perf/util/Build b/tools/perf/util/Build index 10630fbe43c1..0401a80bab09 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -85,6 +85,9 @@ endif libperf-$(CONFIG_DWARF) += probe-finder.o libperf-$(CONFIG_DWARF) += dwarf-aux.o +libperf-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o +libperf-$(CONFIG_LIBUNWIND) += unwind-libunwind.o + CFLAGS_config.o += -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))" CFLAGS_exec_cmd.o += -DPERF_EXEC_PATH="BUILD_STR($(perfexecdir_SQ))" -DPREFIX="BUILD_STR($(prefix_SQ))" -- GitLab From 3b939a631b53bdb1bf6826fca2a330b16e995fc2 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 30 Dec 2014 00:16:01 +0100 Subject: [PATCH 00123/11651] perf build: Add ui objects building Move the ui objects building under build framework to be included in the libperf build object. Signed-off-by: Jiri Olsa Tested-by: Sukadev Bhattiprolu Tested-by: Will Deacon Cc: Alexis Berlemont Cc: Borislav Petkov Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-re5vuat8uu396n7hyor9b5ve@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Build | 1 + tools/perf/Makefile.perf | 10 ---------- tools/perf/config/Makefile | 1 + tools/perf/ui/Build | 8 ++++++++ 4 files changed, 10 insertions(+), 10 deletions(-) create mode 100644 tools/perf/ui/Build diff --git a/tools/perf/Build b/tools/perf/Build index 170e4563bb24..e84ced325147 100644 --- a/tools/perf/Build +++ b/tools/perf/Build @@ -34,3 +34,4 @@ CFLAGS_builtin-timechart.o += $(paths) libperf-y += util/ libperf-y += arch/ +libperf-y += ui/ diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 96e3cdc7f89c..c658fa6dc81e 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -327,13 +327,6 @@ LIB_H += util/data.h LIB_H += util/kvm-stat.h LIB_H += util/thread-stack.h -LIB_OBJS += $(OUTPUT)ui/setup.o -LIB_OBJS += $(OUTPUT)ui/helpline.o -LIB_OBJS += $(OUTPUT)ui/progress.o -LIB_OBJS += $(OUTPUT)ui/util.o -LIB_OBJS += $(OUTPUT)ui/hist.o -LIB_OBJS += $(OUTPUT)ui/stdio/hist.o - PERFLIBS = $(LIB_FILE) $(LIBAPIKFS) $(LIBTRACEEVENT) # We choose to avoid "if .. else if .. else .. endif endif" @@ -491,9 +484,6 @@ $(OUTPUT)%.o: %.S $(OUTPUT)%.s: %.S $(QUIET_CC)$(CC) -o $@ -E $(CFLAGS) $< -$(OUTPUT)ui/setup.o: ui/setup.c $(OUTPUT)PERF-CFLAGS - $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DLIBDIR='"$(libdir_SQ)"' $< - $(OUTPUT)ui/browser.o: ui/browser.c $(OUTPUT)PERF-CFLAGS $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DENABLE_SLFUTURE_CONST $< diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index e55d811e633f..07391389aa4c 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -844,3 +844,4 @@ $(call detected_var,mandir_SQ) $(call detected_var,ETC_PERFCONFIG_SQ) $(call detected_var,prefix_SQ) $(call detected_var,perfexecdir_SQ) +$(call detected_var,LIBDIR) diff --git a/tools/perf/ui/Build b/tools/perf/ui/Build new file mode 100644 index 000000000000..077b6a448ddc --- /dev/null +++ b/tools/perf/ui/Build @@ -0,0 +1,8 @@ +libperf-y += setup.o +libperf-y += helpline.o +libperf-y += progress.o +libperf-y += util.o +libperf-y += hist.o +libperf-y += stdio/hist.o + +CFLAGS_setup.o += -DLIBDIR="BUILD_STR($(LIBDIR))" -- GitLab From cf15c74cbdccb8fb5ced91c6f24f9b3a68f9a82b Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 30 Dec 2014 00:27:52 +0100 Subject: [PATCH 00124/11651] perf build: Add slang objects building Move the slang objects building under build framework to be included in the libperf build object. Signed-off-by: Jiri Olsa Tested-by: Sukadev Bhattiprolu Tested-by: Will Deacon Cc: Alexis Berlemont Cc: Borislav Petkov Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-2ofo1r00jl6i143qxcl9n2jr@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile.perf | 33 --------------------------------- tools/perf/config/Makefile | 1 + tools/perf/ui/Build | 6 ++++++ tools/perf/ui/browsers/Build | 10 ++++++++++ tools/perf/ui/tui/Build | 4 ++++ 5 files changed, 21 insertions(+), 33 deletions(-) create mode 100644 tools/perf/ui/browsers/Build create mode 100644 tools/perf/ui/tui/Build diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index c658fa6dc81e..d9de8af55de2 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -339,24 +339,6 @@ ifneq ($(OUTPUT),) CFLAGS += -I$(OUTPUT) endif -ifndef NO_SLANG - LIB_OBJS += $(OUTPUT)ui/browser.o - LIB_OBJS += $(OUTPUT)ui/browsers/annotate.o - LIB_OBJS += $(OUTPUT)ui/browsers/hists.o - LIB_OBJS += $(OUTPUT)ui/browsers/map.o - LIB_OBJS += $(OUTPUT)ui/browsers/scripts.o - LIB_OBJS += $(OUTPUT)ui/browsers/header.o - LIB_OBJS += $(OUTPUT)ui/tui/setup.o - LIB_OBJS += $(OUTPUT)ui/tui/util.o - LIB_OBJS += $(OUTPUT)ui/tui/helpline.o - LIB_OBJS += $(OUTPUT)ui/tui/progress.o - LIB_H += ui/tui/tui.h - LIB_H += ui/browser.h - LIB_H += ui/browsers/map.h - LIB_H += ui/keysyms.h - LIB_H += ui/libslang.h -endif - ifndef NO_GTK2 ALL_PROGRAMS += $(OUTPUT)libperf-gtk.so @@ -484,21 +466,6 @@ $(OUTPUT)%.o: %.S $(OUTPUT)%.s: %.S $(QUIET_CC)$(CC) -o $@ -E $(CFLAGS) $< -$(OUTPUT)ui/browser.o: ui/browser.c $(OUTPUT)PERF-CFLAGS - $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DENABLE_SLFUTURE_CONST $< - -$(OUTPUT)ui/browsers/annotate.o: ui/browsers/annotate.c $(OUTPUT)PERF-CFLAGS - $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DENABLE_SLFUTURE_CONST $< - -$(OUTPUT)ui/browsers/hists.o: ui/browsers/hists.c $(OUTPUT)PERF-CFLAGS - $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DENABLE_SLFUTURE_CONST $< - -$(OUTPUT)ui/browsers/map.o: ui/browsers/map.c $(OUTPUT)PERF-CFLAGS - $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DENABLE_SLFUTURE_CONST $< - -$(OUTPUT)ui/browsers/scripts.o: ui/browsers/scripts.c $(OUTPUT)PERF-CFLAGS - $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DENABLE_SLFUTURE_CONST $< - $(OUTPUT)util/scripting-engines/trace-event-perl.o: util/scripting-engines/trace-event-perl.c $(OUTPUT)PERF-CFLAGS $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow -Wno-undef -Wno-switch-default $< diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 07391389aa4c..4b251114b34d 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -479,6 +479,7 @@ ifndef NO_SLANG CFLAGS += -I/usr/include/slang CFLAGS += -DHAVE_SLANG_SUPPORT EXTLIBS += -lslang + $(call detected,CONFIG_SLANG) endif endif diff --git a/tools/perf/ui/Build b/tools/perf/ui/Build index 077b6a448ddc..0a73538c0441 100644 --- a/tools/perf/ui/Build +++ b/tools/perf/ui/Build @@ -6,3 +6,9 @@ libperf-y += hist.o libperf-y += stdio/hist.o CFLAGS_setup.o += -DLIBDIR="BUILD_STR($(LIBDIR))" + +libperf-$(CONFIG_SLANG) += browser.o +libperf-$(CONFIG_SLANG) += browsers/ +libperf-$(CONFIG_SLANG) += tui/ + +CFLAGS_browser.o += -DENABLE_SLFUTURE_CONST diff --git a/tools/perf/ui/browsers/Build b/tools/perf/ui/browsers/Build new file mode 100644 index 000000000000..de223f5bed58 --- /dev/null +++ b/tools/perf/ui/browsers/Build @@ -0,0 +1,10 @@ +libperf-y += annotate.o +libperf-y += hists.o +libperf-y += map.o +libperf-y += scripts.o +libperf-y += header.o + +CFLAGS_annotate.o += -DENABLE_SLFUTURE_CONST +CFLAGS_hists.o += -DENABLE_SLFUTURE_CONST +CFLAGS_map.o += -DENABLE_SLFUTURE_CONST +CFLAGS_scripts.o += -DENABLE_SLFUTURE_CONST diff --git a/tools/perf/ui/tui/Build b/tools/perf/ui/tui/Build new file mode 100644 index 000000000000..9e4c6ca41a9f --- /dev/null +++ b/tools/perf/ui/tui/Build @@ -0,0 +1,4 @@ +libperf-y += setup.o +libperf-y += util.o +libperf-y += helpline.o +libperf-y += progress.o -- GitLab From 88aeea06ebd2192328c83519f07e5768681e29e7 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 30 Dec 2014 00:34:23 +0100 Subject: [PATCH 00125/11651] perf build: Add gtk objects building Move the gtk objects building under build framework. Add new gtk build object so it's separated from the rest of the code and could be librarized. Signed-off-by: Jiri Olsa Tested-by: Sukadev Bhattiprolu Tested-by: Will Deacon Cc: Alexis Berlemont Cc: Borislav Petkov Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-cd27z7vww85nxdq37rkjkkbm@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Build | 2 ++ tools/perf/Makefile.perf | 17 +++++------------ tools/perf/config/Makefile | 1 + tools/perf/ui/gtk/Build | 9 +++++++++ 4 files changed, 17 insertions(+), 12 deletions(-) create mode 100644 tools/perf/ui/gtk/Build diff --git a/tools/perf/Build b/tools/perf/Build index e84ced325147..a9ff8fd0bff9 100644 --- a/tools/perf/Build +++ b/tools/perf/Build @@ -35,3 +35,5 @@ CFLAGS_builtin-timechart.o += $(paths) libperf-y += util/ libperf-y += arch/ libperf-y += ui/ + +gtk-y += ui/gtk/ diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index d9de8af55de2..18ff8aab582a 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -341,14 +341,7 @@ endif ifndef NO_GTK2 ALL_PROGRAMS += $(OUTPUT)libperf-gtk.so - - GTK_OBJS += $(OUTPUT)ui/gtk/browser.o - GTK_OBJS += $(OUTPUT)ui/gtk/hists.o - GTK_OBJS += $(OUTPUT)ui/gtk/setup.o - GTK_OBJS += $(OUTPUT)ui/gtk/util.o - GTK_OBJS += $(OUTPUT)ui/gtk/helpline.o - GTK_OBJS += $(OUTPUT)ui/gtk/progress.o - GTK_OBJS += $(OUTPUT)ui/gtk/annotate.o + GTK_IN := $(OUTPUT)gtk-in.o install-gtk: $(OUTPUT)libperf-gtk.so $(call QUIET_INSTALL, 'GTK UI') \ @@ -416,10 +409,10 @@ $(OUTPUT)perf: $(OUTPUT)perf.o $(BUILTIN_OBJS) $(PERFLIBS) $(PERF_IN) $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $(OUTPUT)perf.o \ $(BUILTIN_OBJS) $(PERF_IN) $(LIBS) -o $@ -$(GTK_OBJS): $(OUTPUT)%.o: %.c $(LIB_H) - $(QUIET_CC)$(CC) -o $@ -c -fPIC $(CFLAGS) $(GTK_CFLAGS) $< +$(GTK_IN): FORCE + @$(MAKE) $(build)=gtk -$(OUTPUT)libperf-gtk.so: $(GTK_OBJS) $(PERFLIBS) +$(OUTPUT)libperf-gtk.so: $(GTK_IN) $(PERFLIBS) $(QUIET_LINK)$(CC) -o $@ -shared $(LDFLAGS) $(filter %.o,$^) $(GTK_LIBS) $(OUTPUT)common-cmds.h: util/generate-cmdlist.sh command-list.txt @@ -699,7 +692,7 @@ config-clean: @$(MAKE) -C config/feature-checks clean >/dev/null clean: $(LIBTRACEEVENT)-clean $(LIBAPIKFS)-clean config-clean - $(call QUIET_CLEAN, core-objs) $(RM) $(LIB_OBJS) $(BUILTIN_OBJS) $(LIB_FILE) $(OUTPUT)perf-archive $(OUTPUT)perf-with-kcore $(OUTPUT)perf.o $(LANG_BINDINGS) $(GTK_OBJS) + $(call QUIET_CLEAN, core-objs) $(RM) $(LIB_OBJS) $(BUILTIN_OBJS) $(LIB_FILE) $(OUTPUT)perf-archive $(OUTPUT)perf-with-kcore $(OUTPUT)perf.o $(LANG_BINDINGS) @find . -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete @$(RM) .config-detected $(call QUIET_CLEAN, core-progs) $(RM) $(ALL_PROGRAMS) perf perf-read-vdso32 perf-read-vdsox32 diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 4b251114b34d..6b9678248694 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -846,3 +846,4 @@ $(call detected_var,ETC_PERFCONFIG_SQ) $(call detected_var,prefix_SQ) $(call detected_var,perfexecdir_SQ) $(call detected_var,LIBDIR) +$(call detected_var,GTK_CFLAGS) diff --git a/tools/perf/ui/gtk/Build b/tools/perf/ui/gtk/Build new file mode 100644 index 000000000000..ec22e899a224 --- /dev/null +++ b/tools/perf/ui/gtk/Build @@ -0,0 +1,9 @@ +CFLAGS_gtk += -fPIC $(GTK_CFLAGS) + +gtk-y += browser.o +gtk-y += hists.o +gtk-y += setup.o +gtk-y += util.o +gtk-y += helpline.o +gtk-y += progress.o +gtk-y += annotate.o -- GitLab From c7355f842bf84ba7b1c9d6378f85bb53c99284b2 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 30 Dec 2014 13:11:32 +0100 Subject: [PATCH 00126/11651] perf build: Add scripts objects building Move the scripts objects building under build framework to be included in the libperf build object. Signed-off-by: Jiri Olsa Tested-by: Sukadev Bhattiprolu Tested-by: Will Deacon Cc: Alexis Berlemont Cc: Borislav Petkov Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-ry8pd41ahwpq9h46i8te33c7@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Build | 1 + tools/perf/Makefile.perf | 22 ------------------- tools/perf/config/Makefile | 4 ++++ tools/perf/scripts/Build | 2 ++ tools/perf/scripts/perl/Perf-Trace-Util/Build | 3 +++ .../perf/scripts/python/Perf-Trace-Util/Build | 3 +++ tools/perf/util/Build | 2 ++ tools/perf/util/scripting-engines/Build | 6 +++++ 8 files changed, 21 insertions(+), 22 deletions(-) create mode 100644 tools/perf/scripts/Build create mode 100644 tools/perf/scripts/perl/Perf-Trace-Util/Build create mode 100644 tools/perf/scripts/python/Perf-Trace-Util/Build create mode 100644 tools/perf/util/scripting-engines/Build diff --git a/tools/perf/Build b/tools/perf/Build index a9ff8fd0bff9..133ec649e5a2 100644 --- a/tools/perf/Build +++ b/tools/perf/Build @@ -35,5 +35,6 @@ CFLAGS_builtin-timechart.o += $(paths) libperf-y += util/ libperf-y += arch/ libperf-y += ui/ +libperf-y += scripts/ gtk-y += ui/gtk/ diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 18ff8aab582a..4705fa9339eb 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -349,16 +349,6 @@ install-gtk: $(OUTPUT)libperf-gtk.so $(INSTALL) $(OUTPUT)libperf-gtk.so '$(DESTDIR_SQ)$(libdir_SQ)' endif -ifndef NO_LIBPERL - LIB_OBJS += $(OUTPUT)util/scripting-engines/trace-event-perl.o - LIB_OBJS += $(OUTPUT)scripts/perl/Perf-Trace-Util/Context.o -endif - -ifndef NO_LIBPYTHON - LIB_OBJS += $(OUTPUT)util/scripting-engines/trace-event-python.o - LIB_OBJS += $(OUTPUT)scripts/python/Perf-Trace-Util/Context.o -endif - ifeq ($(NO_PERF_REGS),0) ifeq ($(ARCH),x86) LIB_H += arch/x86/include/perf_regs.h @@ -459,18 +449,6 @@ $(OUTPUT)%.o: %.S $(OUTPUT)%.s: %.S $(QUIET_CC)$(CC) -o $@ -E $(CFLAGS) $< -$(OUTPUT)util/scripting-engines/trace-event-perl.o: util/scripting-engines/trace-event-perl.c $(OUTPUT)PERF-CFLAGS - $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow -Wno-undef -Wno-switch-default $< - -$(OUTPUT)scripts/perl/Perf-Trace-Util/Context.o: scripts/perl/Perf-Trace-Util/Context.c $(OUTPUT)PERF-CFLAGS - $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs -Wno-undef -Wno-switch-default $< - -$(OUTPUT)util/scripting-engines/trace-event-python.o: util/scripting-engines/trace-event-python.c $(OUTPUT)PERF-CFLAGS - $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow $< - -$(OUTPUT)scripts/python/Perf-Trace-Util/Context.o: scripts/python/Perf-Trace-Util/Context.c $(OUTPUT)PERF-CFLAGS - $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs $< - $(OUTPUT)perf-%: %.o $(PERFLIBS) $(QUIET_LINK)$(CC) $(CFLAGS) -o $@ $(LDFLAGS) $(filter %.o,$^) $(LIBS) diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 6b9678248694..e92d1a450867 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -518,6 +518,7 @@ else else LDFLAGS += $(PERL_EMBED_LDFLAGS) EXTLIBS += $(PERL_EMBED_LIBADD) + $(call detected,CONFIG_LIBPERL) endif endif @@ -577,6 +578,7 @@ else LDFLAGS += $(PYTHON_EMBED_LDFLAGS) EXTLIBS += $(PYTHON_EMBED_LIBADD) LANG_BINDINGS += $(obj-perf)python/perf.so + $(call detected,CONFIG_LIBPYTHON) endif endif endif @@ -847,3 +849,5 @@ $(call detected_var,prefix_SQ) $(call detected_var,perfexecdir_SQ) $(call detected_var,LIBDIR) $(call detected_var,GTK_CFLAGS) +$(call detected_var,PERL_EMBED_CCOPTS) +$(call detected_var,PYTHON_EMBED_CCOPTS) diff --git a/tools/perf/scripts/Build b/tools/perf/scripts/Build new file mode 100644 index 000000000000..41efd7e368b3 --- /dev/null +++ b/tools/perf/scripts/Build @@ -0,0 +1,2 @@ +libperf-$(CONFIG_LIBPERL) += perl/Perf-Trace-Util/ +libperf-$(CONFIG_LIBPYTHON) += python/Perf-Trace-Util/ diff --git a/tools/perf/scripts/perl/Perf-Trace-Util/Build b/tools/perf/scripts/perl/Perf-Trace-Util/Build new file mode 100644 index 000000000000..928e110179cb --- /dev/null +++ b/tools/perf/scripts/perl/Perf-Trace-Util/Build @@ -0,0 +1,3 @@ +libperf-y += Context.o + +CFLAGS_Context.o += $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs -Wno-undef -Wno-switch-default diff --git a/tools/perf/scripts/python/Perf-Trace-Util/Build b/tools/perf/scripts/python/Perf-Trace-Util/Build new file mode 100644 index 000000000000..aefc15c9444a --- /dev/null +++ b/tools/perf/scripts/python/Perf-Trace-Util/Build @@ -0,0 +1,3 @@ +libperf-y += Context.o + +CFLAGS_Context.o += $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs diff --git a/tools/perf/util/Build b/tools/perf/util/Build index 0401a80bab09..b0a65429da6c 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -88,6 +88,8 @@ libperf-$(CONFIG_DWARF) += dwarf-aux.o libperf-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o libperf-$(CONFIG_LIBUNWIND) += unwind-libunwind.o +libperf-y += scripting-engines/ + CFLAGS_config.o += -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))" CFLAGS_exec_cmd.o += -DPERF_EXEC_PATH="BUILD_STR($(perfexecdir_SQ))" -DPREFIX="BUILD_STR($(prefix_SQ))" diff --git a/tools/perf/util/scripting-engines/Build b/tools/perf/util/scripting-engines/Build new file mode 100644 index 000000000000..6516e220c247 --- /dev/null +++ b/tools/perf/util/scripting-engines/Build @@ -0,0 +1,6 @@ +libperf-$(CONFIG_LIBPERL) += trace-event-perl.o +libperf-$(CONFIG_LIBPYTHON) += trace-event-python.o + +CFLAGS_trace-event-perl.o += $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow -Wno-undef -Wno-switch-default + +CFLAGS_trace-event-python.o += $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow -- GitLab From 3bc3374cc50ce533259b7efed261f3d68307113c Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 30 Dec 2014 13:30:04 +0100 Subject: [PATCH 00127/11651] perf build: Add perf regs objects building Move the regs objects building under build framework to be included in the libperf build object. Signed-off-by: Jiri Olsa Tested-by: Sukadev Bhattiprolu Tested-by: Will Deacon Cc: Alexis Berlemont Cc: Borislav Petkov Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-hgny792g5x5iaklc34aa57uh@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile.perf | 7 ------- tools/perf/config/Makefile | 4 ++++ tools/perf/util/Build | 2 ++ 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 4705fa9339eb..7daccaccd02f 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -349,13 +349,6 @@ install-gtk: $(OUTPUT)libperf-gtk.so $(INSTALL) $(OUTPUT)libperf-gtk.so '$(DESTDIR_SQ)$(libdir_SQ)' endif -ifeq ($(NO_PERF_REGS),0) - ifeq ($(ARCH),x86) - LIB_H += arch/x86/include/perf_regs.h - endif - LIB_OBJS += $(OUTPUT)util/perf_regs.o -endif - ifndef NO_ZLIB LIB_OBJS += $(OUTPUT)util/zlib.o endif diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index e92d1a450867..2fc4d5682c3b 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -48,6 +48,10 @@ ifeq ($(ARCH),arm64) LIBUNWIND_LIBS = -lunwind -lunwind-aarch64 endif +ifeq ($(NO_PERF_REGS),0) + $(call detected,CONFIG_PERF_REGS) +endif + # So far there's only x86 and arm libdw unwind support merged in perf. # Disable it on all other architectures in case libdw unwind # support is detected in system. Add supported architectures diff --git a/tools/perf/util/Build b/tools/perf/util/Build index b0a65429da6c..f69843218228 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -90,6 +90,8 @@ libperf-$(CONFIG_LIBUNWIND) += unwind-libunwind.o libperf-y += scripting-engines/ +libperf-$(CONFIG_PERF_REGS) += perf_regs.o + CFLAGS_config.o += -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))" CFLAGS_exec_cmd.o += -DPERF_EXEC_PATH="BUILD_STR($(perfexecdir_SQ))" -DPREFIX="BUILD_STR($(prefix_SQ))" -- GitLab From 1571b695053c4ccad66c5151d78247a6590338d6 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 30 Dec 2014 13:31:12 +0100 Subject: [PATCH 00128/11651] perf build: Add zlib objects building Move the zlib objects building under build framework to be included in the libperf build object. Signed-off-by: Jiri Olsa Tested-by: Sukadev Bhattiprolu Tested-by: Will Deacon Cc: Alexis Berlemont Cc: Borislav Petkov Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-cpbb47g82ahpa4yqfr9dcobq@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile.perf | 4 ---- tools/perf/config/Makefile | 1 + tools/perf/util/Build | 1 + 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 7daccaccd02f..713f4d17c553 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -349,10 +349,6 @@ install-gtk: $(OUTPUT)libperf-gtk.so $(INSTALL) $(OUTPUT)libperf-gtk.so '$(DESTDIR_SQ)$(libdir_SQ)' endif -ifndef NO_ZLIB - LIB_OBJS += $(OUTPUT)util/zlib.o -endif - ifdef ASCIIDOC8 export ASCIIDOC8 endif diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 2fc4d5682c3b..b97a7b903a23 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -640,6 +640,7 @@ ifndef NO_ZLIB ifeq ($(feature-zlib), 1) CFLAGS += -DHAVE_ZLIB_SUPPORT EXTLIBS += -lz + $(call detected,CONFIG_ZLIB) else NO_ZLIB := 1 endif diff --git a/tools/perf/util/Build b/tools/perf/util/Build index f69843218228..459918872f07 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -91,6 +91,7 @@ libperf-$(CONFIG_LIBUNWIND) += unwind-libunwind.o libperf-y += scripting-engines/ libperf-$(CONFIG_PERF_REGS) += perf_regs.o +libperf-$(CONFIG_ZLIB) += zlib.o CFLAGS_config.o += -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))" CFLAGS_exec_cmd.o += -DPERF_EXEC_PATH="BUILD_STR($(perfexecdir_SQ))" -DPREFIX="BUILD_STR($(prefix_SQ))" -- GitLab From cb4e67fdee46116d6ec5ad37316cf7ff35ad1d7c Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 30 Dec 2014 17:09:15 +0100 Subject: [PATCH 00129/11651] perf build: Add perf.o object building Move the perf object building under build framework to be included in the perf build object. Signed-off-by: Jiri Olsa Tested-by: Sukadev Bhattiprolu Tested-by: Will Deacon Cc: Alexis Berlemont Cc: Borislav Petkov Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-wiiciip2w6ajvj03huqz50xw@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Build | 3 +++ tools/perf/Makefile.perf | 16 +++++----------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/tools/perf/Build b/tools/perf/Build index 133ec649e5a2..976e03849f6d 100644 --- a/tools/perf/Build +++ b/tools/perf/Build @@ -25,12 +25,15 @@ perf-$(CONFIG_LIBELF) += builtin-probe.o perf-y += bench/ perf-y += tests/ +perf-y += perf.o + paths += -DPERF_HTML_PATH="BUILD_STR($(htmldir_SQ))" paths += -DPERF_INFO_PATH="BUILD_STR($(infodir_SQ))" paths += -DPERF_MAN_PATH="BUILD_STR($(mandir_SQ))" CFLAGS_builtin-help.o += $(paths) CFLAGS_builtin-timechart.o += $(paths) +CFLAGS_perf.o += -DPERF_HTML_PATH="BUILD_STR($(htmldir_SQ))" -include $(OUTPUT)PERF-VERSION-FILE libperf-y += util/ libperf-y += arch/ diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 713f4d17c553..0a669f990b68 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -376,16 +376,11 @@ PERF_IN := $(OUTPUT)perf-in.o export srctree OUTPUT RM CC LD AR CFLAGS V BISON FLEX build := -f $(srctree)/tools/build/Makefile.build dir=. obj -$(PERF_IN): $(OUTPUT)common-cmds.h FORCE +$(PERF_IN): $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h FORCE @$(MAKE) $(build)=perf -$(OUTPUT)perf.o: perf.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS - $(QUIET_CC)$(CC) -include $(OUTPUT)PERF-VERSION-FILE \ - '-DPERF_HTML_PATH="$(htmldir_SQ)"' \ - $(CFLAGS) -c $(filter %.c,$^) -o $@ - -$(OUTPUT)perf: $(OUTPUT)perf.o $(BUILTIN_OBJS) $(PERFLIBS) $(PERF_IN) - $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $(OUTPUT)perf.o \ +$(OUTPUT)perf: $(BUILTIN_OBJS) $(PERFLIBS) $(PERF_IN) + $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) \ $(BUILTIN_OBJS) $(PERF_IN) $(LIBS) -o $@ $(GTK_IN): FORCE @@ -403,8 +398,7 @@ $(SCRIPTS) : % : %.sh $(QUIET_GEN)$(INSTALL) '$@.sh' '$(OUTPUT)$@' # These can record PERF_VERSION -$(OUTPUT)perf.o perf.spec \ - $(SCRIPTS) \ +perf.spec $(SCRIPTS) \ : $(OUTPUT)PERF-VERSION-FILE .SUFFIXES: @@ -659,7 +653,7 @@ config-clean: @$(MAKE) -C config/feature-checks clean >/dev/null clean: $(LIBTRACEEVENT)-clean $(LIBAPIKFS)-clean config-clean - $(call QUIET_CLEAN, core-objs) $(RM) $(LIB_OBJS) $(BUILTIN_OBJS) $(LIB_FILE) $(OUTPUT)perf-archive $(OUTPUT)perf-with-kcore $(OUTPUT)perf.o $(LANG_BINDINGS) + $(call QUIET_CLEAN, core-objs) $(RM) $(LIB_OBJS) $(BUILTIN_OBJS) $(LIB_FILE) $(OUTPUT)perf-archive $(OUTPUT)perf-with-kcore $(LANG_BINDINGS) @find . -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete @$(RM) .config-detected $(call QUIET_CLEAN, core-progs) $(RM) $(ALL_PROGRAMS) perf perf-read-vdso32 perf-read-vdsox32 -- GitLab From 5e8c0fb6a95728b852d56c0a9244425d474670c0 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 30 Dec 2014 14:03:40 +0100 Subject: [PATCH 00130/11651] perf build: Add arch x86 objects building Move the x86 arch objects building under build framework to be included in the libperf build object. Adding also arch/$(ARCH)/Build files for the rest of the archs. The reason for this is that in arch/Build we now do: +libperf-y += $(ARCH)/ which would make the build to fail on other architectures, because the build framework requires 'Build' file in nested directories and this patch adds it only for x86. Signed-off-by: Jiri Olsa Tested-by: Sukadev Bhattiprolu Tested-by: Will Deacon Cc: Alexis Berlemont Cc: Borislav Petkov Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-5enob06z07m7ew6nzzdmp3n2@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/Build | 1 + tools/perf/arch/arm/Build | 0 tools/perf/arch/arm64/Build | 0 tools/perf/arch/powerpc/Build | 0 tools/perf/arch/s390/Build | 0 tools/perf/arch/sh/Build | 0 tools/perf/arch/sparc/Build | 0 tools/perf/arch/x86/Build | 2 ++ tools/perf/arch/x86/Makefile | 15 --------------- tools/perf/arch/x86/tests/Build | 2 ++ tools/perf/arch/x86/util/Build | 8 ++++++++ 11 files changed, 13 insertions(+), 15 deletions(-) create mode 100644 tools/perf/arch/arm/Build create mode 100644 tools/perf/arch/arm64/Build create mode 100644 tools/perf/arch/powerpc/Build create mode 100644 tools/perf/arch/s390/Build create mode 100644 tools/perf/arch/sh/Build create mode 100644 tools/perf/arch/sparc/Build create mode 100644 tools/perf/arch/x86/Build create mode 100644 tools/perf/arch/x86/tests/Build create mode 100644 tools/perf/arch/x86/util/Build diff --git a/tools/perf/arch/Build b/tools/perf/arch/Build index 304f5e76c613..109eb75cf7de 100644 --- a/tools/perf/arch/Build +++ b/tools/perf/arch/Build @@ -1 +1,2 @@ libperf-y += common.o +libperf-y += $(ARCH)/ diff --git a/tools/perf/arch/arm/Build b/tools/perf/arch/arm/Build new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/tools/perf/arch/arm64/Build b/tools/perf/arch/arm64/Build new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/tools/perf/arch/powerpc/Build b/tools/perf/arch/powerpc/Build new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/tools/perf/arch/s390/Build b/tools/perf/arch/s390/Build new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/tools/perf/arch/sh/Build b/tools/perf/arch/sh/Build new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/tools/perf/arch/sparc/Build b/tools/perf/arch/sparc/Build new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/tools/perf/arch/x86/Build b/tools/perf/arch/x86/Build new file mode 100644 index 000000000000..41bf61da476a --- /dev/null +++ b/tools/perf/arch/x86/Build @@ -0,0 +1,2 @@ +libperf-y += util/ +libperf-$(CONFIG_DWARF_UNWIND) += tests/ diff --git a/tools/perf/arch/x86/Makefile b/tools/perf/arch/x86/Makefile index 9b21881db52f..21322e0385b8 100644 --- a/tools/perf/arch/x86/Makefile +++ b/tools/perf/arch/x86/Makefile @@ -1,19 +1,4 @@ ifndef NO_DWARF PERF_HAVE_DWARF_REGS := 1 -LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/dwarf-regs.o endif -ifndef NO_LIBUNWIND -LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/unwind-libunwind.o -endif -ifndef NO_LIBDW_DWARF_UNWIND -LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/unwind-libdw.o -endif -ifndef NO_DWARF_UNWIND -LIB_OBJS += $(OUTPUT)arch/$(ARCH)/tests/regs_load.o -LIB_OBJS += $(OUTPUT)arch/$(ARCH)/tests/dwarf-unwind.o -endif -LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/header.o -LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/tsc.o -LIB_H += arch/$(ARCH)/util/tsc.h HAVE_KVM_STAT_SUPPORT := 1 -LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/kvm-stat.o diff --git a/tools/perf/arch/x86/tests/Build b/tools/perf/arch/x86/tests/Build new file mode 100644 index 000000000000..b30eff9bcc83 --- /dev/null +++ b/tools/perf/arch/x86/tests/Build @@ -0,0 +1,2 @@ +libperf-y += regs_load.o +libperf-y += dwarf-unwind.o diff --git a/tools/perf/arch/x86/util/Build b/tools/perf/arch/x86/util/Build new file mode 100644 index 000000000000..cfbccc4e3187 --- /dev/null +++ b/tools/perf/arch/x86/util/Build @@ -0,0 +1,8 @@ +libperf-y += header.o +libperf-y += tsc.o +libperf-y += kvm-stat.o + +libperf-$(CONFIG_DWARF) += dwarf-regs.o + +libperf-$(CONFIG_LIBUNWIND) += unwind-libunwind.o +libperf-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o -- GitLab From f6ff0e6d7bf41e8464b4a50ba48e0e1502ef8438 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 30 Dec 2014 14:07:04 +0100 Subject: [PATCH 00131/11651] perf build: Add arch arm objects building Move the arm arch objects building under build framework to be included in the libperf build object. Signed-off-by: Jiri Olsa Tested-by: Sukadev Bhattiprolu Tested-by: Will Deacon Cc: Alexis Berlemont Cc: Borislav Petkov Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-7bxhmeh4bjabqsmxu4gl6p0b@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/arm/Build | 2 ++ tools/perf/arch/arm/Makefile | 11 ----------- tools/perf/arch/arm/tests/Build | 2 ++ tools/perf/arch/arm/util/Build | 4 ++++ 4 files changed, 8 insertions(+), 11 deletions(-) create mode 100644 tools/perf/arch/arm/tests/Build create mode 100644 tools/perf/arch/arm/util/Build diff --git a/tools/perf/arch/arm/Build b/tools/perf/arch/arm/Build index e69de29bb2d1..41bf61da476a 100644 --- a/tools/perf/arch/arm/Build +++ b/tools/perf/arch/arm/Build @@ -0,0 +1,2 @@ +libperf-y += util/ +libperf-$(CONFIG_DWARF_UNWIND) += tests/ diff --git a/tools/perf/arch/arm/Makefile b/tools/perf/arch/arm/Makefile index 09d62153d384..7fbca175099e 100644 --- a/tools/perf/arch/arm/Makefile +++ b/tools/perf/arch/arm/Makefile @@ -1,14 +1,3 @@ ifndef NO_DWARF PERF_HAVE_DWARF_REGS := 1 -LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/dwarf-regs.o -endif -ifndef NO_LIBUNWIND -LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/unwind-libunwind.o -endif -ifndef NO_LIBDW_DWARF_UNWIND -LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/unwind-libdw.o -endif -ifndef NO_DWARF_UNWIND -LIB_OBJS += $(OUTPUT)arch/$(ARCH)/tests/regs_load.o -LIB_OBJS += $(OUTPUT)arch/$(ARCH)/tests/dwarf-unwind.o endif diff --git a/tools/perf/arch/arm/tests/Build b/tools/perf/arch/arm/tests/Build new file mode 100644 index 000000000000..b30eff9bcc83 --- /dev/null +++ b/tools/perf/arch/arm/tests/Build @@ -0,0 +1,2 @@ +libperf-y += regs_load.o +libperf-y += dwarf-unwind.o diff --git a/tools/perf/arch/arm/util/Build b/tools/perf/arch/arm/util/Build new file mode 100644 index 000000000000..d22e3d07de3d --- /dev/null +++ b/tools/perf/arch/arm/util/Build @@ -0,0 +1,4 @@ +libperf-$(CONFIG_DWARF) += dwarf-regs.o + +libperf-$(CONFIG_LIBUNWIND) += unwind-libunwind.o +libperf-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o -- GitLab From 7db216181484d871fcebfab11cdd146aaf80bf94 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 30 Dec 2014 14:09:08 +0100 Subject: [PATCH 00132/11651] perf build: Add arch arm64 objects building Move the arm64 arch objects building under build framework to be included in the libperf build object. Signed-off-by: Jiri Olsa Tested-by: Sukadev Bhattiprolu Tested-by: Will Deacon Cc: Alexis Berlemont Cc: Borislav Petkov Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-ptqfz1op92yrtccjiww7h1v5@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/arm64/Build | 1 + tools/perf/arch/arm64/Makefile | 4 ---- tools/perf/arch/arm64/util/Build | 2 ++ 3 files changed, 3 insertions(+), 4 deletions(-) create mode 100644 tools/perf/arch/arm64/util/Build diff --git a/tools/perf/arch/arm64/Build b/tools/perf/arch/arm64/Build index e69de29bb2d1..54afe4a467e7 100644 --- a/tools/perf/arch/arm64/Build +++ b/tools/perf/arch/arm64/Build @@ -0,0 +1 @@ +libperf-y += util/ diff --git a/tools/perf/arch/arm64/Makefile b/tools/perf/arch/arm64/Makefile index 67e9b3d38e89..7fbca175099e 100644 --- a/tools/perf/arch/arm64/Makefile +++ b/tools/perf/arch/arm64/Makefile @@ -1,7 +1,3 @@ ifndef NO_DWARF PERF_HAVE_DWARF_REGS := 1 -LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/dwarf-regs.o -endif -ifndef NO_LIBUNWIND -LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/unwind-libunwind.o endif diff --git a/tools/perf/arch/arm64/util/Build b/tools/perf/arch/arm64/util/Build new file mode 100644 index 000000000000..e58123a8912b --- /dev/null +++ b/tools/perf/arch/arm64/util/Build @@ -0,0 +1,2 @@ +libperf-$(CONFIG_DWARF) += dwarf-regs.o +libperf-$(CONFIG_LIBUNWIND) += unwind-libunwind.o -- GitLab From 07a39e11a0e783c3e9f2a653d4b0dcde954edd28 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 30 Dec 2014 14:10:57 +0100 Subject: [PATCH 00133/11651] perf build: Add arch powerpc objects building Move the powerpc arch objects building under build framework to be included in the libperf build object. Signed-off-by: Jiri Olsa Tested-by: Sukadev Bhattiprolu Tested-by: Will Deacon Cc: Alexis Berlemont Cc: Borislav Petkov Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-nqrtlipvjptdyjfuzlnegqgu@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/powerpc/Build | 1 + tools/perf/arch/powerpc/Makefile | 3 --- tools/perf/arch/powerpc/util/Build | 4 ++++ 3 files changed, 5 insertions(+), 3 deletions(-) create mode 100644 tools/perf/arch/powerpc/util/Build diff --git a/tools/perf/arch/powerpc/Build b/tools/perf/arch/powerpc/Build index e69de29bb2d1..54afe4a467e7 100644 --- a/tools/perf/arch/powerpc/Build +++ b/tools/perf/arch/powerpc/Build @@ -0,0 +1 @@ +libperf-y += util/ diff --git a/tools/perf/arch/powerpc/Makefile b/tools/perf/arch/powerpc/Makefile index 6f7782bea5dd..7fbca175099e 100644 --- a/tools/perf/arch/powerpc/Makefile +++ b/tools/perf/arch/powerpc/Makefile @@ -1,6 +1,3 @@ ifndef NO_DWARF PERF_HAVE_DWARF_REGS := 1 -LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/dwarf-regs.o -LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/skip-callchain-idx.o endif -LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/header.o diff --git a/tools/perf/arch/powerpc/util/Build b/tools/perf/arch/powerpc/util/Build new file mode 100644 index 000000000000..0af6e9b3f728 --- /dev/null +++ b/tools/perf/arch/powerpc/util/Build @@ -0,0 +1,4 @@ +libperf-y += header.o + +libperf-$(CONFIG_DWARF) += dwarf-regs.o +libperf-$(CONFIG_DWARF) += skip-callchain-idx.o -- GitLab From 953bce80c01a3e475a5134e8ec410d6f39b9d188 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 30 Dec 2014 14:12:21 +0100 Subject: [PATCH 00134/11651] perf build: Add arch s390 objects building Move the s390 arch objects building under build framework to be included in the libperf build object. Signed-off-by: Jiri Olsa Tested-by: Sukadev Bhattiprolu Tested-by: Will Deacon Cc: Alexis Berlemont Cc: Borislav Petkov Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-8f5tlfwegkirhir2ffz8nw3i@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/s390/Build | 1 + tools/perf/arch/s390/Makefile | 3 --- tools/perf/arch/s390/util/Build | 4 ++++ 3 files changed, 5 insertions(+), 3 deletions(-) create mode 100644 tools/perf/arch/s390/util/Build diff --git a/tools/perf/arch/s390/Build b/tools/perf/arch/s390/Build index e69de29bb2d1..54afe4a467e7 100644 --- a/tools/perf/arch/s390/Build +++ b/tools/perf/arch/s390/Build @@ -0,0 +1 @@ +libperf-y += util/ diff --git a/tools/perf/arch/s390/Makefile b/tools/perf/arch/s390/Makefile index 798ac7379c5f..21322e0385b8 100644 --- a/tools/perf/arch/s390/Makefile +++ b/tools/perf/arch/s390/Makefile @@ -1,7 +1,4 @@ ifndef NO_DWARF PERF_HAVE_DWARF_REGS := 1 -LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/dwarf-regs.o endif -LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/header.o HAVE_KVM_STAT_SUPPORT := 1 -LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/kvm-stat.o diff --git a/tools/perf/arch/s390/util/Build b/tools/perf/arch/s390/util/Build new file mode 100644 index 000000000000..8a61372bb47a --- /dev/null +++ b/tools/perf/arch/s390/util/Build @@ -0,0 +1,4 @@ +libperf-y += header.o +libperf-y += kvm-stat.o + +libperf-$(CONFIG_DWARF) += dwarf-regs.o -- GitLab From 61b021244b328e3cb5b08079b28e4e2742ff7656 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 30 Dec 2014 14:13:25 +0100 Subject: [PATCH 00135/11651] perf build: Add arch sh objects building Move the sh arch objects building under build framework to be included in the libperf build object. Signed-off-by: Jiri Olsa Tested-by: Sukadev Bhattiprolu Tested-by: Will Deacon Cc: Alexis Berlemont Cc: Borislav Petkov Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-nsg1j4djtq85jtrqw830f2az@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/sh/Build | 1 + tools/perf/arch/sh/Makefile | 1 - tools/perf/arch/sh/util/Build | 1 + 3 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 tools/perf/arch/sh/util/Build diff --git a/tools/perf/arch/sh/Build b/tools/perf/arch/sh/Build index e69de29bb2d1..54afe4a467e7 100644 --- a/tools/perf/arch/sh/Build +++ b/tools/perf/arch/sh/Build @@ -0,0 +1 @@ +libperf-y += util/ diff --git a/tools/perf/arch/sh/Makefile b/tools/perf/arch/sh/Makefile index 15130b50dfe3..7fbca175099e 100644 --- a/tools/perf/arch/sh/Makefile +++ b/tools/perf/arch/sh/Makefile @@ -1,4 +1,3 @@ ifndef NO_DWARF PERF_HAVE_DWARF_REGS := 1 -LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/dwarf-regs.o endif diff --git a/tools/perf/arch/sh/util/Build b/tools/perf/arch/sh/util/Build new file mode 100644 index 000000000000..954e287bbb89 --- /dev/null +++ b/tools/perf/arch/sh/util/Build @@ -0,0 +1 @@ +libperf-$(CONFIG_DWARF) += dwarf-regs.o -- GitLab From 6d8e62c302bb9285e8882116fc317916ece5d0ab Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 30 Dec 2014 14:14:20 +0100 Subject: [PATCH 00136/11651] perf build: Add arch sparc objects building Move the sparc arch objects building under build framework to be included in the libperf build object. Signed-off-by: Jiri Olsa Tested-by: Sukadev Bhattiprolu Tested-by: Will Deacon Cc: Alexis Berlemont Cc: Borislav Petkov Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-160hknrqr27c9zf59japw91y@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/sparc/Build | 1 + tools/perf/arch/sparc/Makefile | 1 - tools/perf/arch/sparc/util/Build | 1 + 3 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 tools/perf/arch/sparc/util/Build diff --git a/tools/perf/arch/sparc/Build b/tools/perf/arch/sparc/Build index e69de29bb2d1..54afe4a467e7 100644 --- a/tools/perf/arch/sparc/Build +++ b/tools/perf/arch/sparc/Build @@ -0,0 +1 @@ +libperf-y += util/ diff --git a/tools/perf/arch/sparc/Makefile b/tools/perf/arch/sparc/Makefile index 15130b50dfe3..7fbca175099e 100644 --- a/tools/perf/arch/sparc/Makefile +++ b/tools/perf/arch/sparc/Makefile @@ -1,4 +1,3 @@ ifndef NO_DWARF PERF_HAVE_DWARF_REGS := 1 -LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/dwarf-regs.o endif diff --git a/tools/perf/arch/sparc/util/Build b/tools/perf/arch/sparc/util/Build new file mode 100644 index 000000000000..954e287bbb89 --- /dev/null +++ b/tools/perf/arch/sparc/util/Build @@ -0,0 +1 @@ +libperf-$(CONFIG_DWARF) += dwarf-regs.o -- GitLab From 1999307b469bdfda97baa78c7f4ecf3800fdbacd Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 30 Dec 2014 18:44:38 +0100 Subject: [PATCH 00137/11651] perf build: Add single target build framework support Add support to build single targets, like: $ make util/map.o # objects $ make util/map.i # preprocessor $ make util/map.s # assembly Signed-off-by: Jiri Olsa Tested-by: Sukadev Bhattiprolu Tested-by: Will Deacon Cc: Alexis Berlemont Cc: Borislav Petkov Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-tt10y0dmweq6rjaod937rpb4@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/build/Makefile.build | 20 ++++++++++++++++++- tools/perf/Makefile.perf | 39 +++++++++++++++++++++++++++----------- tools/perf/util/Build | 8 ++++++++ 3 files changed, 55 insertions(+), 12 deletions(-) diff --git a/tools/build/Makefile.build b/tools/build/Makefile.build index aced86d2bbf8..b5ded207f49b 100644 --- a/tools/build/Makefile.build +++ b/tools/build/Makefile.build @@ -49,6 +49,12 @@ quiet_cmd_mkdir = MKDIR $(dir $@) quiet_cmd_cc_o_c = CC $@ cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< +quiet_cmd_cc_i_c = CPP $@ + cmd_cc_i_c = $(CC) $(c_flags) -E -o $@ $< + +quiet_cmd_cc_s_c = AS $@ + cmd_cc_s_c = $(CC) $(c_flags) -S -o $@ $< + # Link agregate command # If there's nothing to link, create empty $@ object. quiet_cmd_ld_multi = LD $@ @@ -64,6 +70,18 @@ $(OUTPUT)%.o: %.S FORCE $(call rule_mkdir) $(call if_changed_dep,cc_o_c) +$(OUTPUT)%.i: %.c FORCE + $(call rule_mkdir) + $(call if_changed_dep,cc_i_c) + +$(OUTPUT)%.i: %.S FORCE + $(call rule_mkdir) + $(call if_changed_dep,cc_i_c) + +$(OUTPUT)%.s: %.c FORCE + $(call rule_mkdir) + $(call if_changed_dep,cc_s_c) + # Gather build data: # obj-y - list of build objects # subdir-y - list of directories to nest @@ -100,7 +118,7 @@ FORCE: # Include all cmd files to get all the dependency rules # for all objects included -targets := $(wildcard $(sort $(obj-y) $(in-target))) +targets := $(wildcard $(sort $(obj-y) $(in-target) $(MAKECMDGOALS))) cmd_files := $(wildcard $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd)) ifneq ($(cmd_files),) diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 0a669f990b68..ef637e99a2fa 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -421,16 +421,33 @@ endif # These two need to be here so that when O= is not used they take precedence # over the general rule for .o -$(OUTPUT)%.o: %.c $(OUTPUT)PERF-CFLAGS - $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $< -$(OUTPUT)%.i: %.c $(OUTPUT)PERF-CFLAGS - $(QUIET_CC)$(CC) -o $@ -E $(CFLAGS) $< -$(OUTPUT)%.s: %.c $(OUTPUT)PERF-CFLAGS - $(QUIET_CC)$(CC) -o $@ -S $(CFLAGS) $< -$(OUTPUT)%.o: %.S - $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $< -$(OUTPUT)%.s: %.S - $(QUIET_CC)$(CC) -o $@ -E $(CFLAGS) $< +# get relative building directory (to $(OUTPUT)) +# and '.' if it's $(OUTPUT) itself +__build-dir = $(subst $(OUTPUT),,$(dir $@)) +build-dir = $(if $(__build-dir),$(__build-dir),.) + +single_dep: $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h + +$(OUTPUT)%.o: %.c single_dep FORCE + @$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@ + +$(OUTPUT)%.i: %.c single_dep FORCE + @$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@ + +$(OUTPUT)%.s: %.c single_dep FORCE + @$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@ + +$(OUTPUT)%-bison.o: %.c single_dep FORCE + @$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@ + +$(OUTPUT)%-flex.o: %.c single_dep FORCE + @$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@ + +$(OUTPUT)%.o: %.S single_dep FORCE + @$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@ + +$(OUTPUT)%.i: %.S single_dep FORCE + @$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@ $(OUTPUT)perf-%: %.o $(PERFLIBS) $(QUIET_LINK)$(CC) $(CFLAGS) -o $@ $(LDFLAGS) $(filter %.o,$^) $(LIBS) @@ -675,5 +692,5 @@ FORCE: .PHONY: all install clean config-clean strip install-gtk .PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell -.PHONY: $(GIT-HEAD-PHONY) TAGS tags cscope .FORCE-PERF-CFLAGS FORCE +.PHONY: $(GIT-HEAD-PHONY) TAGS tags cscope .FORCE-PERF-CFLAGS FORCE single_dep diff --git a/tools/perf/util/Build b/tools/perf/util/Build index 459918872f07..32f9327b1a97 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -97,15 +97,19 @@ CFLAGS_config.o += -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))" CFLAGS_exec_cmd.o += -DPERF_EXEC_PATH="BUILD_STR($(perfexecdir_SQ))" -DPREFIX="BUILD_STR($(prefix_SQ))" $(OUTPUT)util/parse-events-flex.c: util/parse-events.l $(OUTPUT)util/parse-events-bison.c + $(call rule_mkdir) @$(call echo-cmd,flex)$(FLEX) -o $@ --header-file=$(OUTPUT)util/parse-events-flex.h $(PARSER_DEBUG_FLEX) util/parse-events.l $(OUTPUT)util/parse-events-bison.c: util/parse-events.y + $(call rule_mkdir) @$(call echo-cmd,bison)$(BISON) -v util/parse-events.y -d $(PARSER_DEBUG_BISON) -o $@ -p parse_events_ $(OUTPUT)util/pmu-flex.c: util/pmu.l $(OUTPUT)util/pmu-bison.c + $(call rule_mkdir) @$(call echo-cmd,flex)$(FLEX) -o $@ --header-file=$(OUTPUT)util/pmu-flex.h util/pmu.l $(OUTPUT)util/pmu-bison.c: util/pmu.y + $(call rule_mkdir) @$(call echo-cmd,bison)$(BISON) -v util/pmu.y -d -o $@ -p perf_pmu_ CFLAGS_parse-events-flex.o += -w @@ -122,13 +126,17 @@ CFLAGS_hweight.o += -Wno-unused-parameter -DETC_PERFCONFIG="BUILD_STR($(ET CFLAGS_parse-events.o += -Wno-redundant-decls $(OUTPUT)util/kallsyms.o: ../lib/symbol/kallsyms.c FORCE + $(call rule_mkdir) $(call if_changed_dep,cc_o_c) $(OUTPUT)util/find_next_bit.o: ../lib/util/find_next_bit.c FORCE + $(call rule_mkdir) $(call if_changed_dep,cc_o_c) $(OUTPUT)util/rbtree.o: ../../lib/rbtree.c FORCE + $(call rule_mkdir) $(call if_changed_dep,cc_o_c) $(OUTPUT)util/hweight.o: ../../lib/hweight.c FORCE + $(call rule_mkdir) $(call if_changed_dep,cc_o_c) -- GitLab From 64f72f3b7316793ba03bc38f5c3cfc627068afe4 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 30 Dec 2014 16:48:54 +0100 Subject: [PATCH 00138/11651] perf build: Remove directory dependency rules Removing subdirectories creation support from Makefile.perf as it's no longer needed, since it's properly handled by new build system. Signed-off-by: Jiri Olsa Tested-by: Sukadev Bhattiprolu Tested-by: Will Deacon Cc: Alexis Berlemont Cc: Borislav Petkov Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-2i8x5hdllpm6cyhfh1cr88hv@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile.perf | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index ef637e99a2fa..b282cbcf2ac7 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -465,21 +465,6 @@ endif $(LIB_OBJS) $(BUILTIN_OBJS): $(LIB_H) $(patsubst perf-%,%.o,$(PROGRAMS)): $(LIB_H) $(wildcard */*.h) -# we compile into subdirectories. if the target directory is not the source directory, they might not exists. So -# we depend the various files onto their directories. -DIRECTORY_DEPS = $(LIB_OBJS) $(BUILTIN_OBJS) $(GTK_OBJS) -DIRECTORY_DEPS += $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h -# no need to add flex objects, because they depend on bison ones -DIRECTORY_DEPS += $(OUTPUT)util/parse-events-bison.c -DIRECTORY_DEPS += $(OUTPUT)util/pmu-bison.c - -OUTPUT_DIRECTORIES := $(sort $(dir $(DIRECTORY_DEPS))) - -$(DIRECTORY_DEPS): | $(OUTPUT_DIRECTORIES) -# In the second step, we make a rule to actually create these directories -$(OUTPUT_DIRECTORIES): - $(QUIET_MKDIR)$(MKDIR) -p $@ 2>/dev/null - LIBPERF_IN := $(OUTPUT)libperf-in.o $(LIBPERF_IN): FORCE -- GitLab From 8e499ac5376c03fa3ff90ddd7def3fee175aa4b6 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 30 Dec 2014 16:51:35 +0100 Subject: [PATCH 00139/11651] perf build: Remove uneeded variables Removing uneeded variables from Makefile.perf: BUILTIN_OBJS LIB_OBJS GTK_OBJS - objects are now hold by in the build Makefiles LIB_H - header dependencies iare now handled by Build framework Signed-off-by: Jiri Olsa Tested-by: Sukadev Bhattiprolu Tested-by: Will Deacon Cc: Alexis Berlemont Cc: Borislav Petkov Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-o85k0klhwqh3fmvryfgcpr95@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile.perf | 125 ++------------------------------------- 1 file changed, 5 insertions(+), 120 deletions(-) diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index b282cbcf2ac7..d49f7930d544 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -137,10 +137,6 @@ export prefix bindir sharedir sysconfdir DESTDIR SPARSE_FLAGS = -D__BIG_ENDIAN__ -D__powerpc__ # Guard against environment variables -BUILTIN_OBJS = -LIB_H = -LIB_OBJS = -GTK_OBJS = PYRF_OBJS = SCRIPT_SH = @@ -218,115 +214,6 @@ export PERL_PATH LIB_FILE=$(OUTPUT)libperf.a -LIB_H += ../lib/symbol/kallsyms.h -LIB_H += ../../include/uapi/linux/perf_event.h -LIB_H += ../../include/linux/rbtree.h -LIB_H += ../../include/linux/list.h -LIB_H += ../../include/uapi/linux/const.h -LIB_H += ../include/linux/hash.h -LIB_H += ../../include/linux/stringify.h -LIB_H += util/include/linux/bitmap.h -LIB_H += ../include/linux/bitops.h -LIB_H += ../include/asm-generic/bitops/arch_hweight.h -LIB_H += ../include/asm-generic/bitops/atomic.h -LIB_H += ../include/asm-generic/bitops/const_hweight.h -LIB_H += ../include/asm-generic/bitops/find.h -LIB_H += ../include/asm-generic/bitops/fls64.h -LIB_H += ../include/asm-generic/bitops/fls.h -LIB_H += ../include/asm-generic/bitops/__ffs.h -LIB_H += ../include/asm-generic/bitops/__fls.h -LIB_H += ../include/asm-generic/bitops/hweight.h -LIB_H += ../include/asm-generic/bitops.h -LIB_H += ../include/linux/compiler.h -LIB_H += ../include/linux/log2.h -LIB_H += util/include/linux/const.h -LIB_H += util/include/linux/ctype.h -LIB_H += util/include/linux/kernel.h -LIB_H += util/include/linux/list.h -LIB_H += ../include/linux/export.h -LIB_H += util/include/linux/poison.h -LIB_H += util/include/linux/rbtree.h -LIB_H += util/include/linux/rbtree_augmented.h -LIB_H += util/include/linux/string.h -LIB_H += ../include/linux/types.h -LIB_H += util/include/linux/linkage.h -LIB_H += util/include/asm/asm-offsets.h -LIB_H += ../include/asm/bug.h -LIB_H += util/include/asm/byteorder.h -LIB_H += util/include/asm/swab.h -LIB_H += util/include/asm/system.h -LIB_H += util/include/asm/uaccess.h -LIB_H += util/include/dwarf-regs.h -LIB_H += util/include/asm/dwarf2.h -LIB_H += util/include/asm/cpufeature.h -LIB_H += util/include/asm/unistd_32.h -LIB_H += util/include/asm/unistd_64.h -LIB_H += perf.h -LIB_H += util/annotate.h -LIB_H += util/cache.h -LIB_H += util/callchain.h -LIB_H += util/build-id.h -LIB_H += util/db-export.h -LIB_H += util/debug.h -LIB_H += util/pmu.h -LIB_H += util/event.h -LIB_H += util/evsel.h -LIB_H += util/evlist.h -LIB_H += util/exec_cmd.h -LIB_H += util/find-vdso-map.c -LIB_H += util/levenshtein.h -LIB_H += util/machine.h -LIB_H += util/map.h -LIB_H += util/parse-options.h -LIB_H += util/parse-events.h -LIB_H += util/quote.h -LIB_H += util/util.h -LIB_H += util/xyarray.h -LIB_H += util/header.h -LIB_H += util/help.h -LIB_H += util/session.h -LIB_H += util/ordered-events.h -LIB_H += util/strbuf.h -LIB_H += util/strlist.h -LIB_H += util/strfilter.h -LIB_H += util/svghelper.h -LIB_H += util/tool.h -LIB_H += util/run-command.h -LIB_H += util/sigchain.h -LIB_H += util/dso.h -LIB_H += util/symbol.h -LIB_H += util/color.h -LIB_H += util/values.h -LIB_H += util/sort.h -LIB_H += util/hist.h -LIB_H += util/comm.h -LIB_H += util/thread.h -LIB_H += util/thread_map.h -LIB_H += util/trace-event.h -LIB_H += util/probe-finder.h -LIB_H += util/dwarf-aux.h -LIB_H += util/probe-event.h -LIB_H += util/pstack.h -LIB_H += util/cpumap.h -LIB_H += util/top.h -LIB_H += $(ARCH_INCLUDE) -LIB_H += util/cgroup.h -LIB_H += $(LIB_INCLUDE)traceevent/event-parse.h -LIB_H += util/target.h -LIB_H += util/rblist.h -LIB_H += util/intlist.h -LIB_H += util/perf_regs.h -LIB_H += util/unwind.h -LIB_H += util/vdso.h -LIB_H += util/tsc.h -LIB_H += ui/helpline.h -LIB_H += ui/progress.h -LIB_H += ui/util.h -LIB_H += ui/ui.h -LIB_H += util/data.h -LIB_H += util/kvm-stat.h -LIB_H += util/thread-stack.h - PERFLIBS = $(LIB_FILE) $(LIBAPIKFS) $(LIBTRACEEVENT) # We choose to avoid "if .. else if .. else .. endif endif" @@ -379,9 +266,8 @@ build := -f $(srctree)/tools/build/Makefile.build dir=. obj $(PERF_IN): $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h FORCE @$(MAKE) $(build)=perf -$(OUTPUT)perf: $(BUILTIN_OBJS) $(PERFLIBS) $(PERF_IN) - $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) \ - $(BUILTIN_OBJS) $(PERF_IN) $(LIBS) -o $@ +$(OUTPUT)perf: $(PERFLIBS) $(PERF_IN) + $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $(PERF_IN) $(LIBS) -o $@ $(GTK_IN): FORCE @$(MAKE) $(build)=gtk @@ -462,15 +348,14 @@ $(OUTPUT)perf-read-vdsox32: perf-read-vdso.c util/find-vdso-map.c $(QUIET_CC)$(CC) -mx32 $(filter -static,$(LDFLAGS)) -Wall -Werror -o $@ perf-read-vdso.c endif -$(LIB_OBJS) $(BUILTIN_OBJS): $(LIB_H) -$(patsubst perf-%,%.o,$(PROGRAMS)): $(LIB_H) $(wildcard */*.h) +$(patsubst perf-%,%.o,$(PROGRAMS)): $(wildcard */*.h) LIBPERF_IN := $(OUTPUT)libperf-in.o $(LIBPERF_IN): FORCE @$(MAKE) $(build)=libperf -$(LIB_FILE): $(LIB_OBJS) $(LIBPERF_IN) +$(LIB_FILE): $(LIBPERF_IN) $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(LIBPERF_IN) $(LIB_OBJS) # libtraceevent.a @@ -655,7 +540,7 @@ config-clean: @$(MAKE) -C config/feature-checks clean >/dev/null clean: $(LIBTRACEEVENT)-clean $(LIBAPIKFS)-clean config-clean - $(call QUIET_CLEAN, core-objs) $(RM) $(LIB_OBJS) $(BUILTIN_OBJS) $(LIB_FILE) $(OUTPUT)perf-archive $(OUTPUT)perf-with-kcore $(LANG_BINDINGS) + $(call QUIET_CLEAN, core-objs) $(RM) $(LIB_FILE) $(OUTPUT)perf-archive $(OUTPUT)perf-with-kcore $(LANG_BINDINGS) @find . -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete @$(RM) .config-detected $(call QUIET_CLEAN, core-progs) $(RM) $(ALL_PROGRAMS) perf perf-read-vdso32 perf-read-vdsox32 -- GitLab From db8486626246f86d8f6f77ff0020c68a6dda2e23 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 30 Dec 2014 19:02:51 +0100 Subject: [PATCH 00140/11651] perf build: Remove PERF-CFLAGS file Removing PERF-CFLAGS file, because the build framework stores full build command line for each object and triggers rebuilt if necessary. Signed-off-by: Jiri Olsa Tested-by: Sukadev Bhattiprolu Tested-by: Will Deacon Cc: Alexis Berlemont Cc: Borislav Petkov Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-99hamnd2msiwgsi78yauihhd@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile.perf | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index d49f7930d544..710731b4268e 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -365,7 +365,7 @@ LIBTRACEEVENT_FLAGS = $(QUIET_SUBDIR1) O=$(OUTPUT) LIBTRACEEVENT_FLAGS += CFLAGS="-g -Wall $(EXTRA_CFLAGS)" LIBTRACEEVENT_FLAGS += plugin_dir=$(plugindir_SQ) -$(LIBTRACEEVENT): $(TE_SOURCES) $(OUTPUT)PERF-CFLAGS +$(LIBTRACEEVENT): $(TE_SOURCES) $(QUIET_SUBDIR0)$(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) libtraceevent.a plugins $(LIBTRACEEVENT)-clean: @@ -444,17 +444,6 @@ cscope: $(QUIET_GEN)$(RM) cscope*; \ $(FIND) $(TAG_FOLDERS) -name '*.[hcS]' -print | xargs cscope -b $(TAG_FILES) -### Detect prefix changes -TRACK_CFLAGS = $(subst ','\'',$(CFLAGS)):\ - $(bindir_SQ):$(perfexecdir_SQ):$(template_dir_SQ):$(prefix_SQ):$(plugindir_SQ) - -$(OUTPUT)PERF-CFLAGS: .FORCE-PERF-CFLAGS - @FLAGS='$(TRACK_CFLAGS)'; \ - if test x"$$FLAGS" != x"`cat $(OUTPUT)PERF-CFLAGS 2>/dev/null`" ; then \ - echo 1>&2 " FLAGS: * new build flags or prefix"; \ - echo "$$FLAGS" >$(OUTPUT)PERF-CFLAGS; \ - fi - ### Testing rules # GNU make supports exporting all variables by "export" without parameters. @@ -544,7 +533,7 @@ clean: $(LIBTRACEEVENT)-clean $(LIBAPIKFS)-clean config-clean @find . -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete @$(RM) .config-detected $(call QUIET_CLEAN, core-progs) $(RM) $(ALL_PROGRAMS) perf perf-read-vdso32 perf-read-vdsox32 - $(call QUIET_CLEAN, core-gen) $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope* $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)PERF-CFLAGS $(OUTPUT)PERF-FEATURES $(OUTPUT)util/*-bison* $(OUTPUT)util/*-flex* + $(call QUIET_CLEAN, core-gen) $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope* $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)PERF-FEATURES $(OUTPUT)util/*-bison* $(OUTPUT)util/*-flex* $(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) clean $(python-clean) @@ -562,5 +551,5 @@ FORCE: .PHONY: all install clean config-clean strip install-gtk .PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell -.PHONY: $(GIT-HEAD-PHONY) TAGS tags cscope .FORCE-PERF-CFLAGS FORCE single_dep +.PHONY: $(GIT-HEAD-PHONY) TAGS tags cscope FORCE single_dep -- GitLab From f819f703a42eed63443cef796b1852e6baf985bd Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 14 Jan 2015 19:05:27 +0100 Subject: [PATCH 00141/11651] perf build: Add build documentation Adding file describing the basics of perf build process. Signed-off-by: Jiri Olsa Tested-by: Sukadev Bhattiprolu Tested-by: Will Deacon Cc: Alexis Berlemont Cc: Borislav Petkov Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-ibgf7vxyduwohlqqfayl11xb@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/Build.txt | 49 ++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 tools/perf/Documentation/Build.txt diff --git a/tools/perf/Documentation/Build.txt b/tools/perf/Documentation/Build.txt new file mode 100644 index 000000000000..f6fc6507ba55 --- /dev/null +++ b/tools/perf/Documentation/Build.txt @@ -0,0 +1,49 @@ + +1) perf build +============= +The perf build process consists of several separated building blocks, +which are linked together to form the perf binary: + - libperf library (static) + - perf builtin commands + - traceevent library (static) + - GTK ui library + +Several makefiles govern the perf build: + + - Makefile + top level Makefile working as a wrapper that calls the main + Makefile.perf with a -j option to do parallel builds. + + - Makefile.perf + main makefile that triggers build of all perf objects including + installation and documentation processing. + + - tools/build/Makefile.build + main makefile of the build framework + + - tools/build/Build.include + build framework generic definitions + + - Build makefiles + makefiles that defines build objects + +Please refer to tools/build/Documentation/Build.txt for more +information about build framework. + + +2) perf build +============= +The Makefile.perf triggers the build framework for build objects: + perf, libperf, gtk + +resulting in following objects: + $ ls *-in.o + gtk-in.o libperf-in.o perf-in.o + +Those objects are then used in final linking: + libperf-gtk.so <- gtk-in.o libperf-in.o + perf <- perf-in.o libperf-in.o + + +NOTE this description is omitting other libraries involved, only + focusing on build framework outcomes -- GitLab From b4f9166847354cb839c275c062c6b17afba49211 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Fri, 9 Jan 2015 16:38:25 +0100 Subject: [PATCH 00142/11651] tools lib api: Use tools build framework Move the libapikfs library building under tools build framework. Signed-off-by: Jiri Olsa Tested-by: Sukadev Bhattiprolu Tested-by: Will Deacon Cc: Alexis Berlemont Cc: Borislav Petkov Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-xjo8r7nuqy9mvlfrmx9zcfwb@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/api/Build | 2 ++ tools/lib/api/Makefile | 62 +++++++++++++++++----------------------- tools/lib/api/fd/Build | 1 + tools/lib/api/fs/Build | 4 +++ tools/perf/Makefile.perf | 12 ++------ 5 files changed, 35 insertions(+), 46 deletions(-) create mode 100644 tools/lib/api/Build create mode 100644 tools/lib/api/fd/Build create mode 100644 tools/lib/api/fs/Build diff --git a/tools/lib/api/Build b/tools/lib/api/Build new file mode 100644 index 000000000000..64dd8d466d2c --- /dev/null +++ b/tools/lib/api/Build @@ -0,0 +1,2 @@ +libapikfs-y += fd/ +libapikfs-y += fs/ diff --git a/tools/lib/api/Makefile b/tools/lib/api/Makefile index 212aa4fd65a0..1aa47c271313 100644 --- a/tools/lib/api/Makefile +++ b/tools/lib/api/Makefile @@ -1,53 +1,43 @@ include ../../scripts/Makefile.include include ../../perf/config/utilities.mak # QUIET_CLEAN +ifeq ($(srctree),) +srctree := $(patsubst %/,%,$(dir $(shell pwd))) +srctree := $(patsubst %/,%,$(dir $(srctree))) +srctree := $(patsubst %/,%,$(dir $(srctree))) +#$(info Determined 'srctree' to be $(srctree)) +endif + CC = $(CROSS_COMPILE)gcc AR = $(CROSS_COMPILE)ar -# guard against environment variables -LIB_H= -LIB_OBJS= - -LIB_H += fs/debugfs.h -LIB_H += fs/tracefs.h -LIB_H += fs/findfs.h -LIB_H += fs/fs.h -# See comment below about piggybacking... -LIB_H += fd/array.h - -LIB_OBJS += $(OUTPUT)fs/debugfs.o -LIB_OBJS += $(OUTPUT)fs/tracefs.o -LIB_OBJS += $(OUTPUT)fs/findfs.o -LIB_OBJS += $(OUTPUT)fs/fs.o -# XXX piggybacking here, need to introduce libapikfd, or rename this -# to plain libapik.a and make it have it all api goodies -LIB_OBJS += $(OUTPUT)fd/array.o +MAKEFLAGS += --no-print-directory -LIBFILE = libapikfs.a +LIBFILE = $(OUTPUT)libapikfs.a -CFLAGS = -ggdb3 -Wall -Wextra -std=gnu99 -Werror -O6 -D_FORTIFY_SOURCE=2 $(EXTRA_WARNINGS) $(EXTRA_CFLAGS) -fPIC -EXTLIBS = -lelf -lpthread -lrt -lm -ALL_CFLAGS = $(CFLAGS) $(BASIC_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -ALL_LDFLAGS = $(LDFLAGS) +CFLAGS := $(EXTRA_WARNINGS) $(EXTRA_CFLAGS) +CFLAGS += -ggdb3 -Wall -Wextra -std=gnu99 -Werror -O6 -D_FORTIFY_SOURCE=2 -fPIC +CFLAGS += -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 RM = rm -f -$(LIBFILE): $(LIB_OBJS) - $(QUIET_AR)$(RM) $@ && $(AR) rcs $(OUTPUT)$@ $(LIB_OBJS) +build := -f $(srctree)/tools/build/Makefile.build dir=. obj +API_IN := $(OUTPUT)libapikfs-in.o -$(LIB_OBJS): $(LIB_H) +export srctree OUTPUT CC LD CFLAGS V -libapi_dirs: - $(QUIET_MKDIR)mkdir -p $(OUTPUT)fd $(OUTPUT)fs +all: $(LIBFILE) -$(OUTPUT)%.o: %.c libapi_dirs - $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $< -$(OUTPUT)%.s: %.c libapi_dirs - $(QUIET_CC)$(CC) -S $(ALL_CFLAGS) $< -$(OUTPUT)%.o: %.S libapi_dirs - $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $< +$(API_IN): FORCE + @$(MAKE) $(build)=libapikfs + +$(LIBFILE): $(API_IN) + $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(API_IN) clean: - $(call QUIET_CLEAN, libapi) $(RM) $(LIB_OBJS) $(LIBFILE) + $(call QUIET_CLEAN, libapikfs) $(RM) $(LIBFILE); \ + find $(if $(OUTPUT),$(OUTPUT),.) -name \*.o | xargs $(RM) + +FORCE: -.PHONY: clean +.PHONY: clean FORCE diff --git a/tools/lib/api/fd/Build b/tools/lib/api/fd/Build new file mode 100644 index 000000000000..4ddcb0ff7f49 --- /dev/null +++ b/tools/lib/api/fd/Build @@ -0,0 +1 @@ +libapikfs-y += array.o diff --git a/tools/lib/api/fs/Build b/tools/lib/api/fs/Build new file mode 100644 index 000000000000..5f0fe4dfaae6 --- /dev/null +++ b/tools/lib/api/fs/Build @@ -0,0 +1,4 @@ +libapikfs-y += fs.o +libapikfs-y += findfs.o +libapikfs-y += debugfs.o +libapikfs-y += tracefs.o diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 710731b4268e..cc733ac4b744 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -375,20 +375,12 @@ $(LIBTRACEEVENT)-clean: install-traceevent-plugins: $(LIBTRACEEVENT) $(QUIET_SUBDIR0)$(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) install_plugins -LIBAPIKFS_SOURCES = $(wildcard $(LIB_PATH)fs/*.[ch] $(LIB_PATH)fd/*.[ch]) - -# if subdir is set, we've been called from above so target has been built -# already -$(LIBAPIKFS): $(LIBAPIKFS_SOURCES) -ifeq ($(subdir),) - $(QUIET_SUBDIR0)$(LIB_DIR) $(QUIET_SUBDIR1) O=$(OUTPUT) libapikfs.a -endif +$(LIBAPIKFS): FORCE + @$(MAKE) -C $(LIB_DIR) O=$(OUTPUT) $(OUTPUT)libapikfs.a $(LIBAPIKFS)-clean: -ifeq ($(subdir),) $(call QUIET_CLEAN, libapikfs) @$(MAKE) -C $(LIB_DIR) O=$(OUTPUT) clean >/dev/null -endif help: @echo 'Perf make targets:' -- GitLab From 285a8f247b08c2aff83633fb82c217f91455d10b Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sat, 10 Jan 2015 20:53:13 +0100 Subject: [PATCH 00143/11651] tools lib api: Rename libapikfs.a to libapi.a Renaming libapikfs.a to libapi.a, because it's not just 'fs' specific library now. Signed-off-by: Jiri Olsa Tested-by: Sukadev Bhattiprolu Tested-by: Will Deacon Cc: Alexis Berlemont Cc: Borislav Petkov Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-g1mk5oj2ayq4vn653ovfg3gv@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/api/Build | 4 ++-- tools/lib/api/Makefile | 8 ++++---- tools/lib/api/fd/Build | 2 +- tools/lib/api/fs/Build | 8 ++++---- tools/perf/Makefile.perf | 18 +++++++++--------- tools/perf/util/setup.py | 2 +- 6 files changed, 21 insertions(+), 21 deletions(-) diff --git a/tools/lib/api/Build b/tools/lib/api/Build index 64dd8d466d2c..3653965cf481 100644 --- a/tools/lib/api/Build +++ b/tools/lib/api/Build @@ -1,2 +1,2 @@ -libapikfs-y += fd/ -libapikfs-y += fs/ +libapi-y += fd/ +libapi-y += fs/ diff --git a/tools/lib/api/Makefile b/tools/lib/api/Makefile index 1aa47c271313..d8fe29fc19a4 100644 --- a/tools/lib/api/Makefile +++ b/tools/lib/api/Makefile @@ -13,7 +13,7 @@ AR = $(CROSS_COMPILE)ar MAKEFLAGS += --no-print-directory -LIBFILE = $(OUTPUT)libapikfs.a +LIBFILE = $(OUTPUT)libapi.a CFLAGS := $(EXTRA_WARNINGS) $(EXTRA_CFLAGS) CFLAGS += -ggdb3 -Wall -Wextra -std=gnu99 -Werror -O6 -D_FORTIFY_SOURCE=2 -fPIC @@ -22,20 +22,20 @@ CFLAGS += -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 RM = rm -f build := -f $(srctree)/tools/build/Makefile.build dir=. obj -API_IN := $(OUTPUT)libapikfs-in.o +API_IN := $(OUTPUT)libapi-in.o export srctree OUTPUT CC LD CFLAGS V all: $(LIBFILE) $(API_IN): FORCE - @$(MAKE) $(build)=libapikfs + @$(MAKE) $(build)=libapi $(LIBFILE): $(API_IN) $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(API_IN) clean: - $(call QUIET_CLEAN, libapikfs) $(RM) $(LIBFILE); \ + $(call QUIET_CLEAN, libapi) $(RM) $(LIBFILE); \ find $(if $(OUTPUT),$(OUTPUT),.) -name \*.o | xargs $(RM) FORCE: diff --git a/tools/lib/api/fd/Build b/tools/lib/api/fd/Build index 4ddcb0ff7f49..605d99f6d71a 100644 --- a/tools/lib/api/fd/Build +++ b/tools/lib/api/fd/Build @@ -1 +1 @@ -libapikfs-y += array.o +libapi-y += array.o diff --git a/tools/lib/api/fs/Build b/tools/lib/api/fs/Build index 5f0fe4dfaae6..6de5a4f0b501 100644 --- a/tools/lib/api/fs/Build +++ b/tools/lib/api/fs/Build @@ -1,4 +1,4 @@ -libapikfs-y += fs.o -libapikfs-y += findfs.o -libapikfs-y += debugfs.o -libapikfs-y += tracefs.o +libapi-y += fs.o +libapi-y += debugfs.o +libapi-y += findfs.o +libapi-y += tracefs.o diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index cc733ac4b744..c9088400e138 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -161,8 +161,8 @@ endif LIBTRACEEVENT = $(TE_PATH)libtraceevent.a export LIBTRACEEVENT -LIBAPIKFS = $(LIB_PATH)libapikfs.a -export LIBAPIKFS +LIBAPI = $(LIB_PATH)libapi.a +export LIBAPI # python extension build directories PYTHON_EXTBUILD := $(OUTPUT)python_ext_build/ @@ -173,7 +173,7 @@ export PYTHON_EXTBUILD_LIB PYTHON_EXTBUILD_TMP python-clean := $(call QUIET_CLEAN, python) $(RM) -r $(PYTHON_EXTBUILD) $(OUTPUT)python/perf.so PYTHON_EXT_SRCS := $(shell grep -v ^\# util/python-ext-sources) -PYTHON_EXT_DEPS := util/python-ext-sources util/setup.py $(LIBTRACEEVENT) $(LIBAPIKFS) +PYTHON_EXT_DEPS := util/python-ext-sources util/setup.py $(LIBTRACEEVENT) $(LIBAPI) $(OUTPUT)python/perf.so: $(PYTHON_EXT_SRCS) $(PYTHON_EXT_DEPS) $(QUIET_GEN)CFLAGS='$(CFLAGS)' $(PYTHON_WORD) util/setup.py \ @@ -214,7 +214,7 @@ export PERL_PATH LIB_FILE=$(OUTPUT)libperf.a -PERFLIBS = $(LIB_FILE) $(LIBAPIKFS) $(LIBTRACEEVENT) +PERFLIBS = $(LIB_FILE) $(LIBAPI) $(LIBTRACEEVENT) # We choose to avoid "if .. else if .. else .. endif endif" # because maintaining the nesting to match is a pain. If @@ -375,11 +375,11 @@ $(LIBTRACEEVENT)-clean: install-traceevent-plugins: $(LIBTRACEEVENT) $(QUIET_SUBDIR0)$(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) install_plugins -$(LIBAPIKFS): FORCE - @$(MAKE) -C $(LIB_DIR) O=$(OUTPUT) $(OUTPUT)libapikfs.a +$(LIBAPI): FORCE + @$(MAKE) -C $(LIB_DIR) O=$(OUTPUT) $(OUTPUT)libapi.a -$(LIBAPIKFS)-clean: - $(call QUIET_CLEAN, libapikfs) +$(LIBAPI)-clean: + $(call QUIET_CLEAN, libapi) @$(MAKE) -C $(LIB_DIR) O=$(OUTPUT) clean >/dev/null help: @@ -520,7 +520,7 @@ config-clean: $(call QUIET_CLEAN, config) @$(MAKE) -C config/feature-checks clean >/dev/null -clean: $(LIBTRACEEVENT)-clean $(LIBAPIKFS)-clean config-clean +clean: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean config-clean $(call QUIET_CLEAN, core-objs) $(RM) $(LIB_FILE) $(OUTPUT)perf-archive $(OUTPUT)perf-with-kcore $(LANG_BINDINGS) @find . -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete @$(RM) .config-detected diff --git a/tools/perf/util/setup.py b/tools/perf/util/setup.py index d0aee4b9dfd4..1833103768cb 100644 --- a/tools/perf/util/setup.py +++ b/tools/perf/util/setup.py @@ -25,7 +25,7 @@ cflags += ['-fno-strict-aliasing', '-Wno-write-strings', '-Wno-unused-parameter' build_lib = getenv('PYTHON_EXTBUILD_LIB') build_tmp = getenv('PYTHON_EXTBUILD_TMP') libtraceevent = getenv('LIBTRACEEVENT') -libapikfs = getenv('LIBAPIKFS') +libapikfs = getenv('LIBAPI') ext_sources = [f.strip() for f in file('util/python-ext-sources') if len(f.strip()) > 0 and f[0] != '#'] -- GitLab From 2d58ab9bdb1958e94f1007882d67c77edda810c0 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 7 Jan 2015 18:39:45 +0100 Subject: [PATCH 00144/11651] tools lib traceevent: Use tools build framework Move the libtraceevent library building under tools build framework. Signed-off-by: Jiri Olsa Tested-by: Sukadev Bhattiprolu Tested-by: Will Deacon Cc: Alexis Berlemont Cc: Borislav Petkov Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Steven Rostedt Link: http://lkml.kernel.org/n/tip-opvx59tcawlmm916lg4aff4h@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/traceevent/Build | 17 ++++ tools/lib/traceevent/Makefile | 169 +++++++++------------------------- tools/perf/Makefile.perf | 11 +-- 3 files changed, 65 insertions(+), 132 deletions(-) create mode 100644 tools/lib/traceevent/Build diff --git a/tools/lib/traceevent/Build b/tools/lib/traceevent/Build new file mode 100644 index 000000000000..c681d0575d16 --- /dev/null +++ b/tools/lib/traceevent/Build @@ -0,0 +1,17 @@ +libtraceevent-y += event-parse.o +libtraceevent-y += event-plugin.o +libtraceevent-y += trace-seq.o +libtraceevent-y += parse-filter.o +libtraceevent-y += parse-utils.o +libtraceevent-y += kbuffer-parse.o + +plugin_jbd2-y += plugin_jbd2.o +plugin_hrtimer-y += plugin_hrtimer.o +plugin_kmem-y += plugin_kmem.o +plugin_kvm-y += plugin_kvm.o +plugin_mac80211-y += plugin_mac80211.o +plugin_sched_switch-y += plugin_sched_switch.o +plugin_function-y += plugin_function.o +plugin_xen-y += plugin_xen.o +plugin_scsi-y += plugin_scsi.o +plugin_cfg80211-y += plugin_cfg80211.o diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile index 005c9cc06935..d410da335e3d 100644 --- a/tools/lib/traceevent/Makefile +++ b/tools/lib/traceevent/Makefile @@ -67,7 +67,7 @@ PLUGIN_DIR = -DPLUGIN_DIR="$(plugin_dir)" PLUGIN_DIR_SQ = '$(subst ','\'',$(PLUGIN_DIR))' endif -include $(if $(BUILD_SRC),$(BUILD_SRC)/)../../scripts/Makefile.include +include ../../scripts/Makefile.include # copy a bit from Linux kbuild @@ -78,40 +78,13 @@ ifndef VERBOSE VERBOSE = 0 endif -ifeq ("$(origin O)", "command line") - BUILD_OUTPUT := $(O) +ifeq ($(srctree),) +srctree := $(patsubst %/,%,$(dir $(shell pwd))) +srctree := $(patsubst %/,%,$(dir $(srctree))) +srctree := $(patsubst %/,%,$(dir $(srctree))) +#$(info Determined 'srctree' to be $(srctree)) endif -ifeq ($(BUILD_SRC),) -ifneq ($(OUTPUT),) - -define build_output - $(if $(VERBOSE:1=),@)+$(MAKE) -C $(OUTPUT) \ - BUILD_SRC=$(CURDIR)/ -f $(CURDIR)/Makefile $1 -endef - -all: sub-make - -$(MAKECMDGOALS): sub-make - -sub-make: force - $(call build_output, $(MAKECMDGOALS)) - - -# Leave processing to above invocation of make -skip-makefile := 1 - -endif # OUTPUT -endif # BUILD_SRC - -# We process the rest of the Makefile if this is the final invocation of make -ifeq ($(skip-makefile),) - -srctree := $(if $(BUILD_SRC),$(BUILD_SRC),$(CURDIR)) -objtree := $(CURDIR) -src := $(srctree) -obj := $(objtree) - export prefix bindir src obj # Shell quotes @@ -132,16 +105,19 @@ EXTRAVERSION = $(EP_EXTRAVERSION) OBJ = $@ N = -export Q VERBOSE - EVENT_PARSE_VERSION = $(EP_VERSION).$(EP_PATCHLEVEL).$(EP_EXTRAVERSION) -INCLUDES = -I. -I $(srctree)/../../include $(CONFIG_INCLUDES) +INCLUDES = -I. -I $(srctree)/tools/include $(CONFIG_INCLUDES) -# Set compile option CFLAGS if not set elsewhere -CFLAGS ?= -g -Wall +# Set compile option CFLAGS +ifdef EXTRA_CFLAGS + CFLAGS := $(EXTRA_CFLAGS) +else + CFLAGS := -g -Wall +endif # Append required CFLAGS +override CFLAGS += -fPIC override CFLAGS += $(CONFIG_FLAGS) $(INCLUDES) $(PLUGIN_DIR_SQ) override CFLAGS += $(udis86-flags) -D_GNU_SOURCE @@ -151,74 +127,58 @@ else Q = @ endif -do_compile_shared_library = \ - ($(print_shared_lib_compile) \ - $(CC) --shared $^ -o $@) - -do_plugin_build = \ - ($(print_plugin_build) \ - $(CC) $(CFLAGS) -shared -nostartfiles -o $@ $<) - -do_build_static_lib = \ - ($(print_static_lib_build) \ - $(RM) $@; $(AR) rcs $@ $^) - - -do_compile = $(QUIET_CC)$(CC) -c $(CFLAGS) $(EXT) $< -o $(obj)/$@; +# Disable command line variables (CFLAGS) overide from top +# level Makefile (perf), otherwise build Makefile will get +# the same command line setup. +MAKEOVERRIDES= -$(obj)/%.o: $(src)/%.c - $(call do_compile) +export srctree OUTPUT CC LD CFLAGS V +build := -f $(srctree)/tools/build/Makefile.build dir=. obj -%.o: $(src)/%.c - $(call do_compile) +PLUGINS = plugin_jbd2.so +PLUGINS += plugin_hrtimer.so +PLUGINS += plugin_kmem.so +PLUGINS += plugin_kvm.so +PLUGINS += plugin_mac80211.so +PLUGINS += plugin_sched_switch.so +PLUGINS += plugin_function.so +PLUGINS += plugin_xen.so +PLUGINS += plugin_scsi.so +PLUGINS += plugin_cfg80211.so -PEVENT_LIB_OBJS = event-parse.o -PEVENT_LIB_OBJS += event-plugin.o -PEVENT_LIB_OBJS += trace-seq.o -PEVENT_LIB_OBJS += parse-filter.o -PEVENT_LIB_OBJS += parse-utils.o -PEVENT_LIB_OBJS += kbuffer-parse.o +PLUGINS := $(addprefix $(OUTPUT),$(PLUGINS)) +PLUGINS_IN := $(PLUGINS:.so=-in.o) -PLUGIN_OBJS = plugin_jbd2.o -PLUGIN_OBJS += plugin_hrtimer.o -PLUGIN_OBJS += plugin_kmem.o -PLUGIN_OBJS += plugin_kvm.o -PLUGIN_OBJS += plugin_mac80211.o -PLUGIN_OBJS += plugin_sched_switch.o -PLUGIN_OBJS += plugin_function.o -PLUGIN_OBJS += plugin_xen.o -PLUGIN_OBJS += plugin_scsi.o -PLUGIN_OBJS += plugin_cfg80211.o - -PLUGINS := $(PLUGIN_OBJS:.o=.so) - -ALL_OBJS = $(PEVENT_LIB_OBJS) $(PLUGIN_OBJS) +TE_IN := $(OUTPUT)libtraceevent-in.o +LIB_FILE := $(addprefix $(OUTPUT),$(LIB_FILE)) CMD_TARGETS = $(LIB_FILE) $(PLUGINS) TARGETS = $(CMD_TARGETS) - all: all_cmd all_cmd: $(CMD_TARGETS) -libtraceevent.so: $(PEVENT_LIB_OBJS) +$(TE_IN): force + $(Q)$(MAKE) $(build)=libtraceevent + +$(OUTPUT)libtraceevent.so: $(TE_IN) $(QUIET_LINK)$(CC) --shared $^ -o $@ -libtraceevent.a: $(PEVENT_LIB_OBJS) +$(OUTPUT)libtraceevent.a: $(TE_IN) $(QUIET_LINK)$(RM) $@; $(AR) rcs $@ $^ plugins: $(PLUGINS) -$(PEVENT_LIB_OBJS): %.o: $(src)/%.c TRACEEVENT-CFLAGS - $(QUIET_CC_FPIC)$(CC) -c $(CFLAGS) $(EXT) -fPIC $< -o $@ +__plugin_obj = $(notdir $@) + plugin_obj = $(__plugin_obj:-in.o=) -$(PLUGIN_OBJS): %.o : $(src)/%.c - $(QUIET_CC_FPIC)$(CC) -c $(CFLAGS) -fPIC -o $@ $< +$(PLUGINS_IN): force + $(Q)$(MAKE) $(build)=$(plugin_obj) -$(PLUGINS): %.so: %.o - $(QUIET_LINK)$(CC) $(CFLAGS) -shared -nostartfiles -o $@ $< +$(OUTPUT)%.so: $(OUTPUT)%-in.o + $(QUIET_LINK)$(CC) $(CFLAGS) -shared -nostartfiles -o $@ $^ define make_version.h (echo '/* This file is automatically generated. Do not modify. */'; \ @@ -255,40 +215,6 @@ define update_dir fi); endef -## make deps - -all_objs := $(sort $(ALL_OBJS)) -all_deps := $(all_objs:%.o=.%.d) - -# let .d file also depends on the source and header files -define check_deps - @set -e; $(RM) $@; \ - $(CC) -MM $(CFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - $(RM) $@.$$$$ -endef - -$(all_deps): .%.d: $(src)/%.c - $(Q)$(call check_deps) - -$(all_objs) : %.o : .%.d - -dep_includes := $(wildcard $(all_deps)) - -ifneq ($(dep_includes),) - include $(dep_includes) -endif - -### Detect environment changes -TRACK_CFLAGS = $(subst ','\'',$(CFLAGS)):$(ARCH):$(CROSS_COMPILE) - -TRACEEVENT-CFLAGS: force - @FLAGS='$(TRACK_CFLAGS)'; \ - if test x"$$FLAGS" != x"`cat TRACEEVENT-CFLAGS 2>/dev/null`" ; then \ - echo 1>&2 " FLAGS: * new build flags or cross compiler"; \ - echo "$$FLAGS" >TRACEEVENT-CFLAGS; \ - fi - tags: force $(RM) tags find . -name '*.[ch]' | xargs ctags --extra=+f --c-kinds=+px \ @@ -327,14 +253,9 @@ clean: $(RM) *.o *~ $(TARGETS) *.a *.so $(VERSION_FILES) .*.d \ $(RM) TRACEEVENT-CFLAGS tags TAGS -endif # skip-makefile - PHONY += force plugins force: -plugins: - @echo > /dev/null - # Declare the contents of the .PHONY variable as phony. We keep that # information in a variable so we can use it in if_changed and friends. .PHONY: $(PHONY) diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index c9088400e138..4eeec571e102 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -358,22 +358,17 @@ $(LIBPERF_IN): FORCE $(LIB_FILE): $(LIBPERF_IN) $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(LIBPERF_IN) $(LIB_OBJS) -# libtraceevent.a -TE_SOURCES = $(wildcard $(TRACE_EVENT_DIR)*.[ch]) - -LIBTRACEEVENT_FLAGS = $(QUIET_SUBDIR1) O=$(OUTPUT) -LIBTRACEEVENT_FLAGS += CFLAGS="-g -Wall $(EXTRA_CFLAGS)" LIBTRACEEVENT_FLAGS += plugin_dir=$(plugindir_SQ) -$(LIBTRACEEVENT): $(TE_SOURCES) - $(QUIET_SUBDIR0)$(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) libtraceevent.a plugins +$(LIBTRACEEVENT): FORCE + @$(MAKE) -C $(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) O=$(OUTPUT) $(OUTPUT)libtraceevent.a plugins $(LIBTRACEEVENT)-clean: $(call QUIET_CLEAN, libtraceevent) @$(MAKE) -C $(TRACE_EVENT_DIR) O=$(OUTPUT) clean >/dev/null install-traceevent-plugins: $(LIBTRACEEVENT) - $(QUIET_SUBDIR0)$(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) install_plugins + @$(MAKE) -C $(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) O=$(OUTPUT) install_plugins $(LIBAPI): FORCE @$(MAKE) -C $(LIB_DIR) O=$(OUTPUT) $(OUTPUT)libapi.a -- GitLab From 9244e2c673fb148abb7706e47b602d009c537c9b Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Fri, 9 Jan 2015 17:11:04 +0100 Subject: [PATCH 00145/11651] tools lib lockdep: Use tools build framework Move the lockdep library building under tools build framework. Signed-off-by: Jiri Olsa Cc: Alexis Berlemont Cc: Borislav Petkov Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: S. Lockwood-Childs Cc: Sasha Levin Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-i0t25buqyo5jfvzpw2347h1h@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/lockdep/Build | 1 + tools/lib/lockdep/Makefile | 132 +++++++------------------------------ 2 files changed, 24 insertions(+), 109 deletions(-) create mode 100644 tools/lib/lockdep/Build diff --git a/tools/lib/lockdep/Build b/tools/lib/lockdep/Build new file mode 100644 index 000000000000..6f667355b068 --- /dev/null +++ b/tools/lib/lockdep/Build @@ -0,0 +1 @@ +liblockdep-y += common.o lockdep.o preload.o rbtree.o diff --git a/tools/lib/lockdep/Makefile b/tools/lib/lockdep/Makefile index 52f9279c6c13..8c3340a4b9f8 100644 --- a/tools/lib/lockdep/Makefile +++ b/tools/lib/lockdep/Makefile @@ -35,6 +35,10 @@ bindir = $(prefix)/$(bindir_relative) export DESTDIR DESTDIR_SQ INSTALL +MAKEFLAGS += --no-print-directory + +include ../../scripts/Makefile.include + # copy a bit from Linux kbuild ifeq ("$(origin V)", "command line") @@ -44,56 +48,21 @@ ifndef VERBOSE VERBOSE = 0 endif -ifeq ("$(origin O)", "command line") - BUILD_OUTPUT := $(O) +ifeq ($(srctree),) +srctree := $(patsubst %/,%,$(dir $(shell pwd))) +srctree := $(patsubst %/,%,$(dir $(srctree))) +srctree := $(patsubst %/,%,$(dir $(srctree))) +#$(info Determined 'srctree' to be $(srctree)) endif -ifeq ($(BUILD_SRC),) -ifneq ($(BUILD_OUTPUT),) - -define build_output - $(if $(VERBOSE:1=),@)$(MAKE) -C $(BUILD_OUTPUT) \ - BUILD_SRC=$(CURDIR) -f $(CURDIR)/Makefile $1 -endef - -saved-output := $(BUILD_OUTPUT) -BUILD_OUTPUT := $(shell cd $(BUILD_OUTPUT) && /bin/pwd) -$(if $(BUILD_OUTPUT),, \ - $(error output directory "$(saved-output)" does not exist)) - -all: sub-make - -gui: force - $(call build_output, all_cmd) - -$(filter-out gui,$(MAKECMDGOALS)): sub-make - -sub-make: force - $(call build_output, $(MAKECMDGOALS)) - - -# Leave processing to above invocation of make -skip-makefile := 1 - -endif # BUILD_OUTPUT -endif # BUILD_SRC - -# We process the rest of the Makefile if this is the final invocation of make -ifeq ($(skip-makefile),) - -srctree := $(realpath $(if $(BUILD_SRC),$(BUILD_SRC),$(CURDIR))) -objtree := $(realpath $(CURDIR)) -src := $(srctree) -obj := $(objtree) - -export prefix libdir bindir src obj - # Shell quotes libdir_SQ = $(subst ','\'',$(libdir)) bindir_SQ = $(subst ','\'',$(bindir)) -LIB_FILE = liblockdep.a liblockdep.so.$(LIBLOCKDEP_VERSION) +LIB_IN := $(OUTPUT)liblockdep-in.o + BIN_FILE = lockdep +LIB_FILE = $(OUTPUT)liblockdep.a $(OUTPUT)liblockdep.so.$(LIBLOCKDEP_VERSION) CONFIG_INCLUDES = CONFIG_LIBS = @@ -108,33 +77,23 @@ INCLUDES = -I. -I/usr/local/include -I./uinclude -I./include -I../../include $(C # Set compile option CFLAGS if not set elsewhere CFLAGS ?= -g -DCONFIG_LOCKDEP -DCONFIG_STACKTRACE -DCONFIG_PROVE_LOCKING -DBITS_PER_LONG=__WORDSIZE -DLIBLOCKDEP_VERSION='"$(LIBLOCKDEP_VERSION)"' -rdynamic -O0 -g +CFLAGS += -fPIC override CFLAGS += $(CONFIG_FLAGS) $(INCLUDES) $(PLUGIN_DIR_SQ) ifeq ($(VERBOSE),1) Q = - print_compile = - print_app_build = - print_fpic_compile = print_shared_lib_compile = print_install = else Q = @ - print_compile = echo ' CC '$(OBJ); - print_app_build = echo ' BUILD '$(OBJ); - print_fpic_compile = echo ' CC FPIC '$(OBJ); - print_shared_lib_compile = echo ' BUILD SHARED LIB '$(OBJ); - print_static_lib_build = echo ' BUILD STATIC LIB '$(OBJ); - print_install = echo ' INSTALL '$1' to $(DESTDIR_SQ)$2'; + print_shared_lib_compile = echo ' LD '$(OBJ); + print_static_lib_build = echo ' LD '$(OBJ); + print_install = echo ' INSTALL '$1' to $(DESTDIR_SQ)$2'; endif -do_fpic_compile = \ - ($(print_fpic_compile) \ - $(CC) -c $(CFLAGS) $(EXT) -fPIC $< -o $@) - -do_app_build = \ - ($(print_app_build) \ - $(CC) $^ -rdynamic -o $@ $(CONFIG_LIBS) $(LIBS)) +export srctree OUTPUT CC LD CFLAGS V +build := -f $(srctree)/tools/build/Makefile.build dir=. obj do_compile_shared_library = \ ($(print_shared_lib_compile) \ @@ -144,22 +103,6 @@ do_build_static_lib = \ ($(print_static_lib_build) \ $(RM) $@; $(AR) rcs $@ $^) - -define do_compile - $(print_compile) \ - $(CC) -c $(CFLAGS) $(EXT) $< -o $(obj)/$@; -endef - -$(obj)/%.o: $(src)/%.c - $(Q)$(call do_compile) - -%.o: $(src)/%.c - $(Q)$(call do_compile) - -PEVENT_LIB_OBJS = common.o lockdep.o preload.o rbtree.o - -ALL_OBJS = $(PEVENT_LIB_OBJS) - CMD_TARGETS = $(LIB_FILE) TARGETS = $(CMD_TARGETS) @@ -169,42 +112,15 @@ all: all_cmd all_cmd: $(CMD_TARGETS) -liblockdep.so.$(LIBLOCKDEP_VERSION): $(PEVENT_LIB_OBJS) +$(LIB_IN): force + $(Q)$(MAKE) $(build)=liblockdep + +liblockdep.so.$(LIBLOCKDEP_VERSION): $(LIB_IN) $(Q)$(do_compile_shared_library) -liblockdep.a: $(PEVENT_LIB_OBJS) +liblockdep.a: $(LIB_IN) $(Q)$(do_build_static_lib) -$(PEVENT_LIB_OBJS): %.o: $(src)/%.c - $(Q)$(do_fpic_compile) - -## make deps - -all_objs := $(sort $(ALL_OBJS)) -all_deps := $(all_objs:%.o=.%.d) - -# let .d file also depends on the source and header files -define check_deps - @set -e; $(RM) $@; \ - $(CC) -MM $(CFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - $(RM) $@.$$$$ -endef - -$(all_deps): .%.d: $(src)/%.c - $(Q)$(call check_deps) - -$(all_objs) : %.o : .%.d - -dep_includes := $(wildcard $(all_deps)) - -ifneq ($(dep_includes),) - include $(dep_includes) -endif - -### Detect environment changes -TRACK_CFLAGS = $(subst ','\'',$(CFLAGS)):$(ARCH):$(CROSS_COMPILE) - tags: force $(RM) tags find . -name '*.[ch]' | xargs ctags --extra=+f --c-kinds=+px \ @@ -233,8 +149,6 @@ clean: $(RM) *.o *~ $(TARGETS) *.a *liblockdep*.so* $(VERSION_FILES) .*.d $(RM) tags TAGS -endif # skip-makefile - PHONY += force force: -- GitLab From ceed252fe0b8b7975845ed4cb9e6069d8a12f233 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 11 Jan 2015 23:59:55 +0100 Subject: [PATCH 00146/11651] perf build: Display make commands on V=1 Get more verbose output wrt displaying executed commands from make. Signed-off-by: Jiri Olsa Tested-by: Sukadev Bhattiprolu Tested-by: Will Deacon Cc: Alexis Berlemont Cc: Borislav Petkov Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-68v67h59zoz7ilb1ggcuff3j@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/build/Makefile.build | 4 +++- tools/perf/Makefile.perf | 48 +++++++++++++++++++++----------------- 2 files changed, 30 insertions(+), 22 deletions(-) diff --git a/tools/build/Makefile.build b/tools/build/Makefile.build index b5ded207f49b..10df57237a66 100644 --- a/tools/build/Makefile.build +++ b/tools/build/Makefile.build @@ -13,8 +13,10 @@ __build: ifeq ($(V),1) quiet = + Q = else quiet=quiet_ + Q=@ endif build-dir := $(srctree)/tools/build @@ -102,7 +104,7 @@ in-target := $(prefix)$(obj)-in.o PHONY += $(subdir-y) $(subdir-y): - @$(MAKE) -f $(build-dir)/Makefile.build dir=$(dir)/$@ obj=$(obj) + $(Q)$(MAKE) -f $(build-dir)/Makefile.build dir=$(dir)/$@ obj=$(obj) $(sort $(subdir-obj-y)): $(subdir-y) ; diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 4eeec571e102..efc5158738f4 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -89,13 +89,19 @@ VPATH += $(OUTPUT) export VPATH endif +ifeq ($(V),1) + Q = +else + Q = @ +endif + # Do not use make's built-in rules # (this improves performance and avoids hard-to-debug behaviour); MAKEFLAGS += -r $(OUTPUT)PERF-VERSION-FILE: ../../.git/HEAD - @$(SHELL_PATH) util/PERF-VERSION-GEN $(OUTPUT) - @touch $(OUTPUT)PERF-VERSION-FILE + $(Q)$(SHELL_PATH) util/PERF-VERSION-GEN $(OUTPUT) + $(Q)touch $(OUTPUT)PERF-VERSION-FILE CC = $(CROSS_COMPILE)gcc LD = $(CROSS_COMPILE)ld @@ -251,7 +257,7 @@ SHELL = $(SHELL_PATH) all: shell_compatibility_test $(ALL_PROGRAMS) $(LANG_BINDINGS) $(OTHER_PROGRAMS) please_set_SHELL_PATH_to_a_more_modern_shell: - @$$(:) + $(Q)$$(:) shell_compatibility_test: please_set_SHELL_PATH_to_a_more_modern_shell @@ -264,13 +270,13 @@ export srctree OUTPUT RM CC LD AR CFLAGS V BISON FLEX build := -f $(srctree)/tools/build/Makefile.build dir=. obj $(PERF_IN): $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h FORCE - @$(MAKE) $(build)=perf + $(Q)$(MAKE) $(build)=perf $(OUTPUT)perf: $(PERFLIBS) $(PERF_IN) $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $(PERF_IN) $(LIBS) -o $@ $(GTK_IN): FORCE - @$(MAKE) $(build)=gtk + $(Q)$(MAKE) $(build)=gtk $(OUTPUT)libperf-gtk.so: $(GTK_IN) $(PERFLIBS) $(QUIET_LINK)$(CC) -o $@ -shared $(LDFLAGS) $(filter %.o,$^) $(GTK_LIBS) @@ -315,25 +321,25 @@ build-dir = $(if $(__build-dir),$(__build-dir),.) single_dep: $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h $(OUTPUT)%.o: %.c single_dep FORCE - @$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@ + $(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@ $(OUTPUT)%.i: %.c single_dep FORCE - @$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@ + $(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@ $(OUTPUT)%.s: %.c single_dep FORCE - @$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@ + $(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@ $(OUTPUT)%-bison.o: %.c single_dep FORCE - @$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@ + $(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@ $(OUTPUT)%-flex.o: %.c single_dep FORCE - @$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@ + $(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@ $(OUTPUT)%.o: %.S single_dep FORCE - @$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@ + $(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@ $(OUTPUT)%.i: %.S single_dep FORCE - @$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@ + $(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@ $(OUTPUT)perf-%: %.o $(PERFLIBS) $(QUIET_LINK)$(CC) $(CFLAGS) -o $@ $(LDFLAGS) $(filter %.o,$^) $(LIBS) @@ -353,7 +359,7 @@ $(patsubst perf-%,%.o,$(PROGRAMS)): $(wildcard */*.h) LIBPERF_IN := $(OUTPUT)libperf-in.o $(LIBPERF_IN): FORCE - @$(MAKE) $(build)=libperf + $(Q)$(MAKE) $(build)=libperf $(LIB_FILE): $(LIBPERF_IN) $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(LIBPERF_IN) $(LIB_OBJS) @@ -361,21 +367,21 @@ $(LIB_FILE): $(LIBPERF_IN) LIBTRACEEVENT_FLAGS += plugin_dir=$(plugindir_SQ) $(LIBTRACEEVENT): FORCE - @$(MAKE) -C $(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) O=$(OUTPUT) $(OUTPUT)libtraceevent.a plugins + $(Q)$(MAKE) -C $(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) O=$(OUTPUT) $(OUTPUT)libtraceevent.a plugins $(LIBTRACEEVENT)-clean: $(call QUIET_CLEAN, libtraceevent) - @$(MAKE) -C $(TRACE_EVENT_DIR) O=$(OUTPUT) clean >/dev/null + $(Q)$(MAKE) -C $(TRACE_EVENT_DIR) O=$(OUTPUT) clean >/dev/null install-traceevent-plugins: $(LIBTRACEEVENT) - @$(MAKE) -C $(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) O=$(OUTPUT) install_plugins + $(Q)$(MAKE) -C $(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) O=$(OUTPUT) install_plugins $(LIBAPI): FORCE - @$(MAKE) -C $(LIB_DIR) O=$(OUTPUT) $(OUTPUT)libapi.a + $(Q)$(MAKE) -C $(LIB_DIR) O=$(OUTPUT) $(OUTPUT)libapi.a $(LIBAPI)-clean: $(call QUIET_CLEAN, libapi) - @$(MAKE) -C $(LIB_DIR) O=$(OUTPUT) clean >/dev/null + $(Q)$(MAKE) -C $(LIB_DIR) O=$(OUTPUT) clean >/dev/null help: @echo 'Perf make targets:' @@ -513,12 +519,12 @@ $(INSTALL_DOC_TARGETS): # config-clean: $(call QUIET_CLEAN, config) - @$(MAKE) -C config/feature-checks clean >/dev/null + $(Q)$(MAKE) -C config/feature-checks clean >/dev/null clean: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean config-clean $(call QUIET_CLEAN, core-objs) $(RM) $(LIB_FILE) $(OUTPUT)perf-archive $(OUTPUT)perf-with-kcore $(LANG_BINDINGS) - @find . -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete - @$(RM) .config-detected + $(Q)find . -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete + $(Q)$(RM) .config-detected $(call QUIET_CLEAN, core-progs) $(RM) $(ALL_PROGRAMS) perf perf-read-vdso32 perf-read-vdsox32 $(call QUIET_CLEAN, core-gen) $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope* $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)PERF-FEATURES $(OUTPUT)util/*-bison* $(OUTPUT)util/*-flex* $(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) clean -- GitLab From 3a03005ff9445834f3d3b577a11bcbdbdf7a89cf Mon Sep 17 00:00:00 2001 From: Yunlong Song Date: Fri, 13 Feb 2015 21:11:52 +0800 Subject: [PATCH 00147/11651] perf tools: Fix a bug of segmentation fault Fix the 'segmentation fault' bug of 'perf list --list-cmds', which also happens in other cases (e.g. record, report ...). This bug happens when there are no cmds to list at all. Example: Before this patch: $ perf list --list-cmds Segmentation fault $ After this patch: $ perf list --list-cmds $ As shown above, the result prints nothing rather than a segmentation fault. The null result means 'perf list' has no cmds to display at this time. Signed-off-by: Yunlong Song Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Wang Nan Link: http://lkml.kernel.org/r/1423833115-11199-5-git-send-email-yunlong.song@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/parse-options.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/parse-options.c b/tools/perf/util/parse-options.c index 4a015f77e2b5..4ee9a86705ed 100644 --- a/tools/perf/util/parse-options.c +++ b/tools/perf/util/parse-options.c @@ -510,8 +510,10 @@ int parse_options_subcommand(int argc, const char **argv, const struct option *o } exit(130); case PARSE_OPT_LIST_SUBCMDS: - for (int i = 0; subcommands[i]; i++) - printf("%s ", subcommands[i]); + if (subcommands) { + for (int i = 0; subcommands[i]; i++) + printf("%s ", subcommands[i]); + } exit(130); default: /* PARSE_OPT_UNKNOWN */ if (ctx.argv[0][1] == '-') { -- GitLab From 74390aa5567827add5058a3b26eff0ed06a629ba Mon Sep 17 00:00:00 2001 From: Kaixu Xia Date: Tue, 27 Jan 2015 17:55:12 +0800 Subject: [PATCH 00148/11651] perf: Remove the extra validity check on nr_pages The function is_power_of_2() also do the check on nr_pages, so the first check performed is unnecessary. On the other hand, the key point is to ensure @nr_pages is a power-of-two number and mostly @nr_pages is a nonzero value, so in the most cases, the function is_power_of_2() will be called. Signed-off-by: Kaixu Xia Cc: Peter Zijlstra Cc: Paul Mackerras Link: http://lkml.kernel.org/r/1422352512-75150-1-git-send-email-xiakaixu@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- kernel/events/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/events/core.c b/kernel/events/core.c index 7f2fbb8b5069..0969c9b67eec 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -4420,7 +4420,7 @@ static int perf_mmap(struct file *file, struct vm_area_struct *vma) * If we have rb pages ensure they're a power-of-two number, so we * can do bitmasks instead of modulo. */ - if (nr_pages != 0 && !is_power_of_2(nr_pages)) + if (!is_power_of_2(nr_pages)) return -EINVAL; if (vma_size != PAGE_SIZE * (1 + nr_pages)) -- GitLab From 619a303c1b8bd22abc549477d038ef9b5c1fe1bd Mon Sep 17 00:00:00 2001 From: Yunlong Song Date: Fri, 13 Feb 2015 21:11:55 +0800 Subject: [PATCH 00149/11651] perf list: Place the header text in its right position The hearer text 'List of pre-defined events (to be used in -e):' is placed in an improper function, which causes an abnormal output, e.g. 'perf list hw' shows no guiding text at all, and 'perf list hw L1-dcache*' shows the guiding text incorrectly in the middle of the output. Example Before this patch: $ perf list hw L1-dcache* branch-instructions OR branches [Hardware event] branch-misses [Hardware event] bus-cycles [Hardware event] cache-misses [Hardware event] cache-references [Hardware event] cpu-cycles OR cycles [Hardware event] instructions [Hardware event] stalled-cycles-backend OR idle-cycles-backend [Hardware event] stalled-cycles-frontend OR idle-cycles-frontend [Hardware event] List of pre-defined events (to be used in -e): <-- incorrect position L1-dcache-load-misses [Hardware cache event] L1-dcache-loads [Hardware cache event] L1-dcache-prefetch-misses [Hardware cache event] L1-dcache-prefetches [Hardware cache event] L1-dcache-store-misses [Hardware cache event] L1-dcache-stores [Hardware cache event] After this patch: $ perf list hw L1-dcache* List of pre-defined events (to be used in -e): <-- correct position branch-instructions OR branches [Hardware event] branch-misses [Hardware event] bus-cycles [Hardware event] cache-misses [Hardware event] cache-references [Hardware event] cpu-cycles OR cycles [Hardware event] instructions [Hardware event] stalled-cycles-backend OR idle-cycles-backend [Hardware event] stalled-cycles-frontend OR idle-cycles-frontend [Hardware event] L1-dcache-load-misses [Hardware cache event] L1-dcache-loads [Hardware cache event] L1-dcache-prefetch-misses [Hardware cache event] L1-dcache-prefetches [Hardware cache event] L1-dcache-store-misses [Hardware cache event] L1-dcache-stores [Hardware cache event] Signed-off-by: Yunlong Song Cc: Peter Zijlstra Cc: Paul Mackerras Cc: Wang Nan Link: http://lkml.kernel.org/r/1423833115-11199-8-git-send-email-yunlong.song@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-list.c | 3 +++ tools/perf/util/parse-events.c | 5 ----- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c index 198f3c3aff95..ad8018e26aa0 100644 --- a/tools/perf/builtin-list.c +++ b/tools/perf/builtin-list.c @@ -41,6 +41,9 @@ int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused) return 0; } + if (!raw_dump) + printf("\nList of pre-defined events (to be used in -e):\n\n"); + if (argc == 0) { print_events(NULL, false); return 0; diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index ecf069b1661f..109ba5c8c2e5 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -1319,11 +1319,6 @@ static void print_symbol_events(const char *event_glob, unsigned type, */ void print_events(const char *event_glob, bool name_only) { - if (!name_only) { - printf("\n"); - printf("List of pre-defined events (to be used in -e):\n"); - } - print_symbol_events(event_glob, PERF_TYPE_HARDWARE, event_symbols_hw, PERF_COUNT_HW_MAX, name_only); -- GitLab From 42052bea1683fad5a7a06d84a3b4f7bd16131ce8 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 13 Feb 2015 12:32:45 -0300 Subject: [PATCH 00150/11651] perf trace: Print thread info when following children The default for 'trace workload' is to set perf_event_attr.inherit to 1, i.e. to make it equivalent to 'strace -f workload', so we were ending with syscalls for multiple processes mixed up, fix it: Before: [root@ssdandy ~]# trace -e brk time usleep 1 0.071 ( 0.002 ms): brk( ) = 0x100e000 0.802 ( 0.001 ms): brk( ) = 0x1d99000 1.132 ( 0.003 ms): brk( ) = 0x1d99000 1.136 ( 0.003 ms): brk(brk: 0x1dba000) = 0x1dba000 1.140 ( 0.001 ms): brk( ) = 0x1dba000 0.00user 0.00system 0:00.00elapsed 63%CPU (0avgtext+0avgdata 528maxresident)k 0inputs+0outputs (0major+181minor)pagefaults 0swaps [root@ssdandy ~]# After: [root@ssdandy ~]# trace -f -e brk time usleep 1 0.072 ( 0.002 ms): time/26308 brk( ) = 0x1e6e000 0.860 ( 0.001 ms): usleep/26309 brk( ) = 0xb91000 1.193 ( 0.003 ms): usleep/26309 brk( ) = 0xb91000 1.197 ( 0.003 ms): usleep/26309 brk(brk: 0xbb2000) = 0xbb2000 1.201 ( 0.001 ms): usleep/26309 brk( ) = 0xbb2000 0.00user 0.00system 0:00.00elapsed 0%CPU (0avgtext+0avgdata 524maxresident)k 0inputs+0outputs (0major+180minor)pagefaults 0swaps [root@ssdandy ~]# BTW: to achieve the 'strace workload' behaviour, i.e. without a explicit '-f', one has to use --no-inherit. Cc: Adrian Hunter Cc: Borislav Petkov Cc: David Ahern Cc: Don Zickus Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Namhyung Kim Cc: Stephane Eranian echo Link: http://lkml.kernel.org/n/tip-`ranpwd -l 24`@git.kernel.org Link: http://lkml.kernel.org/n/tip-2wu2d5n65msxoq1i7vtcaft2@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 66300aea08b0..2bfb2343b798 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -2114,7 +2114,9 @@ static int trace__run(struct trace *trace, int argc, const char **argv) else perf_evlist__enable(evlist); - trace->multiple_threads = evlist->threads->map[0] == -1 || evlist->threads->nr > 1; + trace->multiple_threads = evlist->threads->map[0] == -1 || + evlist->threads->nr > 1 || + perf_evlist__first(evlist)->attr.inherit; again: before = trace->nr_events; -- GitLab From e596663ebb28a068f5cca57f83285b7b293a2c83 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 13 Feb 2015 13:22:21 -0300 Subject: [PATCH 00151/11651] perf trace: Handle multiple threads better wrt syscalls being intermixed $ trace time taskset -c 0 usleep 1 0.845 ( 0.021 ms): time/16722 wait4(upid: 4294967295, stat_addr: 0x7fff17f443d4, ru: 0x7fff17f44438 ) ... 0.865 ( 0.008 ms): time/16723 execve(arg0: 140733595272004, arg1: 140733595272720, arg2: 140733595272768, arg3: 139755107218496, arg4: 7307199665339051828, arg5: 3) = -2 2.395 ( 1.523 ms): taskset/16723 execve(arg0: 140733595272013, arg1: 140733595272720, arg2: 140733595272768, arg3: 139755107218496, arg4: 7307199665339051828, arg5: 3) = 0 2.411 ( 0.002 ms): taskset/16723 brk( ) = 0x1915000 3.300 ( 0.058 ms): usleep/16723 nanosleep(rqtp: 0x7ffff4ada190 ) = 0 3.305 ( 0.000 ms): usleep/16723 exit_group( 3.363 ( 2.539 ms): time/16722 ... [continued]: wait4()) = 16723 3.366 ( 0.001 ms): time/16722 rt_sigaction(sig: INT, act: 0x7fff17f44160, oact: 0x7fff17f44200, sigsetsize: 8) = 0 We we're not seeing this line: 0.845 ( 0.021 ms): time/16722 wait4(upid: 4294967295, stat_addr: 0x7fff17f443d4, ru: 0x7fff17f44438 ) ... just the one when it finishes: 3.363 ( 2.539 ms): time/16722 ... [continued]: wait4()) = 16723 Still some issues left till we move to ordered_samples when multiple CPUs/threads are involved... Cc: Adrian Hunter Cc: Borislav Petkov Cc: David Ahern Cc: Don Zickus Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Namhyung Kim Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-zq9x30a1ky3djqewqn2v3ja3@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 2bfb2343b798..feabd08ec90d 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -1220,6 +1220,7 @@ struct trace { } syscalls; struct record_opts opts; struct machine *host; + struct thread *current; u64 base_time; FILE *output; unsigned long nr_events; @@ -1642,6 +1643,29 @@ static void thread__update_stats(struct thread_trace *ttrace, update_stats(stats, duration); } +static int trace__printf_interrupted_entry(struct trace *trace, struct perf_sample *sample) +{ + struct thread_trace *ttrace; + u64 duration; + size_t printed; + + if (trace->current == NULL) + return 0; + + ttrace = thread__priv(trace->current); + + if (!ttrace->entry_pending) + return 0; + + duration = sample->time - ttrace->entry_time; + + printed = trace__fprintf_entry_head(trace, trace->current, duration, sample->time, trace->output); + printed += fprintf(trace->output, "%-70s) ...\n", ttrace->entry_str); + ttrace->entry_pending = false; + + return printed; +} + static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel, union perf_event *event __maybe_unused, struct perf_sample *sample) @@ -1673,6 +1697,8 @@ static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel, return -1; } + printed += trace__printf_interrupted_entry(trace, sample); + ttrace->entry_time = sample->time; msg = ttrace->entry_str; printed += scnprintf(msg + printed, 1024 - printed, "%s(", sc->name); @@ -1688,6 +1714,8 @@ static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel, } else ttrace->entry_pending = true; + trace->current = thread; + return 0; } -- GitLab From 14a052df1cfa563093f20847d52caad4be5d2adc Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 3 Feb 2015 12:58:57 -0300 Subject: [PATCH 00152/11651] perf trace: Allow mixing with other events Basically adopting 'perf record' --event command line argument syntax: # trace -e \!mprotect,mmap,munmap,open,close,read,fstat,access,arch_prctl --event sched:*switch,sched:*exec,sched:*exit usleep 1 0.048 ( ): sched:sched_process_exec:filename=/bin/usleep pid=24732 old_pid=24732) 0.078 (0.002 ms): usleep/24732 brk( ) = 0x78f000 0.430 (0.002 ms): usleep/24732 brk( ) = 0x78f000 0.434 (0.003 ms): usleep/24732 brk(brk: 0x7b0000 ) = 0x7b0000 0.438 (0.001 ms): usleep/24732 brk( ) = 0x7b0000 0.460 (0.004 ms): usleep/24732 nanosleep(rqtp: 0x7ffff3696a40) ... 0.460 ( ): sched:sched_switch:prev_comm=usleep prev_pid=24732 prev_prio=120 prev_state=S ==> next_comm=swapper/1 next_pid=0 next_prio=120) 0.515 (0.058 ms): usleep/24732 ... [continued]: nanosleep()) = 0 0.520 (0.000 ms): usleep/24732 exit_group( 0.550 ( ): sched:sched_process_exit:comm=usleep pid=24732 prio=120) # Next steps, probably in this order: 1) Use ordered_events code, the logic in trace needs the events to be time ordered when needed, i.e. when multiple CPUs are involved. 2) Callchains! 3) Automatically account for interruptions when saying how long things took. Cc: Adrian Hunter Cc: Borislav Petkov Cc: David Ahern Cc: Don Zickus Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-gpst8mph575yb4wgf91qibyb@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 51 ++++++++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index feabd08ec90d..a44ac9336219 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -1219,6 +1219,7 @@ struct trace { struct syscall *table; } syscalls; struct record_opts opts; + struct perf_evlist *evlist; struct machine *host; struct thread *current; u64 base_time; @@ -1833,6 +1834,24 @@ out_dump: return 0; } +static int trace__event_handler(struct trace *trace, struct perf_evsel *evsel, + union perf_event *event __maybe_unused, + struct perf_sample *sample) +{ + trace__printf_interrupted_entry(trace, sample); + trace__fprintf_tstamp(trace, sample->time, trace->output); + fprintf(trace->output, "(%9.9s): %s:", " ", evsel->name); + + if (evsel->tp_format) { + event_format__fprintf(evsel->tp_format, sample->cpu, + sample->raw_data, sample->raw_size, + trace->output); + } + + fprintf(trace->output, ")\n"); + return 0; +} + static void print_location(FILE *f, struct perf_sample *sample, struct addr_location *al, bool print_dso, bool print_sym) @@ -2067,7 +2086,7 @@ static int perf_evlist__add_pgfault(struct perf_evlist *evlist, static int trace__run(struct trace *trace, int argc, const char **argv) { - struct perf_evlist *evlist = perf_evlist__new(); + struct perf_evlist *evlist = trace->evlist; struct perf_evsel *evsel; int err = -1, i; unsigned long before; @@ -2076,11 +2095,6 @@ static int trace__run(struct trace *trace, int argc, const char **argv) trace->live = true; - if (evlist == NULL) { - fprintf(trace->output, "Not enough memory to run!\n"); - goto out; - } - if (trace->trace_syscalls && perf_evlist__add_syscall_newtp(evlist, trace__sys_enter, trace__sys_exit)) @@ -2227,7 +2241,7 @@ out_disable: out_delete_evlist: perf_evlist__delete(evlist); -out: + trace->evlist = NULL; trace->live = false; return err; { @@ -2498,6 +2512,14 @@ static int parse_pagefaults(const struct option *opt, const char *str, return 0; } +static void evlist__set_evsel_handler(struct perf_evlist *evlist, void *handler) +{ + struct perf_evsel *evsel; + + evlist__for_each(evlist, evsel) + evsel->handler = handler; +} + int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused) { const char * const trace_usage[] = { @@ -2532,6 +2554,9 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused) const char *output_name = NULL; const char *ev_qualifier_str = NULL; const struct option trace_options[] = { + OPT_CALLBACK(0, "event", &trace.evlist, "event", + "event selector. use 'perf list' to list available events", + parse_events_option), OPT_BOOLEAN(0, "comm", &trace.show_comm, "show the thread COMM next to its id"), OPT_BOOLEAN(0, "tool_stats", &trace.show_tool_stats, "show tool stats"), @@ -2573,6 +2598,15 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused) int err; char bf[BUFSIZ]; + trace.evlist = perf_evlist__new(); + if (trace.evlist == NULL) + return -ENOMEM; + + if (trace.evlist == NULL) { + pr_err("Not enough memory to run!\n"); + goto out; + } + argc = parse_options(argc, argv, trace_options, trace_usage, PARSE_OPT_STOP_AT_NON_OPTION); @@ -2581,6 +2615,9 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused) trace.opts.sample_time = true; } + if (trace.evlist->nr_entries > 0) + evlist__set_evsel_handler(trace.evlist, trace__event_handler); + if ((argc >= 1) && (strcmp(argv[0], "record") == 0)) return trace__record(&trace, argc-1, &argv[1]); -- GitLab From 726f3234dd125633438922a07a80f933f13daf82 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 6 Feb 2015 10:16:45 +0100 Subject: [PATCH 00153/11651] perf trace: Support --events foo:bar --no-syscalls I.e. support tracing just tracepoints, without strace like raw_syscalls:*. [acme@ssdandy linux]$ trace --no-sys --ev sched:*exec,sched:*switch,sched:*exit usleep 1 0.048 ( ): sched:sched_process_exec:filename=/usr/bin/usleep pid=27298 old_pid=27298) 0.369 ( ): sched:sched_switch:usleep:27298 [120] S ==> swapper/5:0 [120]) 0.452 ( ): sched:sched_process_exit:comm=usleep pid=27298 prio=120) [acme@ssdandy linux]$ TODO: remove that (...) thing when --no-syscalls is specified. Cc: Adrian Hunter Cc: Borislav Petkov Cc: David Ahern Cc: Don Zickus Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-vn0hsixsbhm31b2rpj97r96k@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index a44ac9336219..b1c1df9bfb26 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -2625,7 +2625,8 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused) if (trace.summary_only) trace.summary = trace.summary_only; - if (!trace.trace_syscalls && !trace.trace_pgfaults) { + if (!trace.trace_syscalls && !trace.trace_pgfaults && + trace.evlist->nr_entries == 0 /* Was --events used? */) { pr_err("Please specify something to trace.\n"); return -1; } -- GitLab From 1ed1f968b6bec3a8fbeb99b796854f63bdffc558 Mon Sep 17 00:00:00 2001 From: Matt Roper Date: Fri, 30 Jan 2015 16:22:36 -0800 Subject: [PATCH 00154/11651] drm/i915: Keep plane->state updated on pageflip Until all drivers have transitioned to atomic, the framebuffer associated with a plane is tracked in both plane->fb (for legacy) and plane->state->fb (for all the new atomic codeflow). All of our modeset and plane updates use drm_plane->update_plane(), so in theory plane->fb and plane->state->fb should always stay in sync and point at the same thing for i915. However we forgot about the pageflip ioctl case, which currently only updates plane->fb and leaves plane->state->fb at a stale value. Surprisingly, this doesn't cause any real problems at the moment since internally we use the plane->fb pointer in most of the places that matter, and on the next .update_plane() call, we use plane->fb to figure out which framebuffer to cleanup. However when we switch to the full atomic helpers for update_plane()/disable_plane(), those helpers use plane->state->fb to figure out which framebuffer to cleanup, so not having updated the plane->state->fb pointer causes things to blow up following a pageflip ioctl. The fix here is to just make sure we update plane->state->fb at the same time we update plane->fb in the pageflip ioctl. Signed-off-by: Matt Roper Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 3d220a67f865..08e2bab6ef47 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -9801,6 +9801,13 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, crtc->primary->fb = fb; + /* Keep state structure in sync */ + if (crtc->primary->state->fb) + drm_framebuffer_unreference(crtc->primary->state->fb); + crtc->primary->state->fb = fb; + if (crtc->primary->state->fb) + drm_framebuffer_reference(crtc->primary->state->fb); + work->pending_flip_obj = obj; atomic_inc(&intel_crtc->unpin_work_count); -- GitLab From 3f678c96abb43a977d2ea41aefccdc49e8a3e896 Mon Sep 17 00:00:00 2001 From: Matt Roper Date: Fri, 30 Jan 2015 16:22:37 -0800 Subject: [PATCH 00155/11651] drm/i915: Switch planes from transitional helpers to full atomic helpers There are two sets of helper functions provided by the DRM core that can implement the .update_plane() and .disable_plane() hooks in terms of a driver's atomic entrypoints. The transitional helpers (which we have been using so far) create a plane state and then use the plane's atomic entrypoints to perform the atomic begin/check/prepare/commit/finish sequence on that single plane only. The full atomic helpers create a top-level atomic state (which is capable of holding multiple object states for planes, crtc's, and/or connectors) and then passes the top-level atomic state through the full "atomic modeset" pipeline. Switching from the transitional to full helpers here shouldn't result in any functional change, but will enable us to exercise/test more of the internal atomic pipeline with the legacy API's used by existing applications. Signed-off-by: Matt Roper Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 08e2bab6ef47..ebf973c303b7 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -12076,8 +12076,8 @@ void intel_plane_destroy(struct drm_plane *plane) } const struct drm_plane_funcs intel_plane_funcs = { - .update_plane = drm_plane_helper_update, - .disable_plane = drm_plane_helper_disable, + .update_plane = drm_atomic_helper_update_plane, + .disable_plane = drm_atomic_helper_disable_plane, .destroy = intel_plane_destroy, .set_property = drm_atomic_helper_plane_set_property, .atomic_get_property = intel_plane_atomic_get_property, -- GitLab From ab8d66752a9c28cd6c94fa173feacdfc1554aa03 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Mon, 2 Feb 2015 15:44:15 +0000 Subject: [PATCH 00156/11651] drm/i915: Track old framebuffer instead of object Daniel Vetter spotted a bug while reviewing some of my refactoring in this are of the code. I'll quote: """ > @@ -9764,6 +9768,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, > work->event = event; > work->crtc = crtc; > work->old_fb_obj = intel_fb_obj(old_fb); > + work->old_tiling_mode = to_intel_framebuffer(old_fb)->tiling_mode; Hm, that's actually an interesting bugfix - currently userspace could be sneaky and destroy the old fb immediately after the flip completes and the change the tiling of the underlying object before the unpin work had a chance to run (needs some fudgin with rt prios to starve workers to make this work though). Imo the right fix is to hold a reference onto the fb and not the underlying gem object. With that tiling is guaranteed not to change. """ This patch tries to implement the above proposed change. Signed-off-by: Tvrtko Ursulin Cc: Daniel Vetter Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 14 +++++++------- drivers/gpu/drm/i915/intel_drv.h | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index ebf973c303b7..213b870ae06e 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -9055,9 +9055,9 @@ static void intel_unpin_work_fn(struct work_struct *__work) enum pipe pipe = to_intel_crtc(work->crtc)->pipe; mutex_lock(&dev->struct_mutex); - intel_unpin_fb_obj(work->old_fb_obj); + intel_unpin_fb_obj(intel_fb_obj(work->old_fb)); drm_gem_object_unreference(&work->pending_flip_obj->base); - drm_gem_object_unreference(&work->old_fb_obj->base); + drm_framebuffer_unreference(work->old_fb); intel_fbc_update(dev); @@ -9760,7 +9760,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, work->event = event; work->crtc = crtc; - work->old_fb_obj = intel_fb_obj(old_fb); + work->old_fb = old_fb; INIT_WORK(&work->work, intel_unpin_work_fn); ret = drm_crtc_vblank_get(crtc); @@ -9796,7 +9796,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, goto cleanup; /* Reference the objects for the scheduled work. */ - drm_gem_object_reference(&work->old_fb_obj->base); + drm_framebuffer_reference(work->old_fb); drm_gem_object_reference(&obj->base); crtc->primary->fb = fb; @@ -9818,7 +9818,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, if (IS_VALLEYVIEW(dev)) { ring = &dev_priv->ring[BCS]; - if (obj->tiling_mode != work->old_fb_obj->tiling_mode) + if (obj->tiling_mode != intel_fb_obj(work->old_fb)->tiling_mode) /* vlv: DISPLAY_FLIP fails to change tiling */ ring = NULL; } else if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) { @@ -9859,7 +9859,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, work->flip_queued_vblank = drm_vblank_count(dev, intel_crtc->pipe); work->enable_stall_check = true; - i915_gem_track_fb(work->old_fb_obj, obj, + i915_gem_track_fb(intel_fb_obj(work->old_fb), obj, INTEL_FRONTBUFFER_PRIMARY(pipe)); intel_fbc_disable(dev); @@ -9875,7 +9875,7 @@ cleanup_unpin: cleanup_pending: atomic_dec(&intel_crtc->unpin_work_count); crtc->primary->fb = old_fb; - drm_gem_object_unreference(&work->old_fb_obj->base); + drm_framebuffer_unreference(work->old_fb); drm_gem_object_unreference(&obj->base); mutex_unlock(&dev->struct_mutex); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index eef79ccd0b7c..f048f8bb8beb 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -710,7 +710,7 @@ intel_get_crtc_for_plane(struct drm_device *dev, int plane) struct intel_unpin_work { struct work_struct work; struct drm_crtc *crtc; - struct drm_i915_gem_object *old_fb_obj; + struct drm_framebuffer *old_fb; struct drm_i915_gem_object *pending_flip_obj; struct drm_pending_vblank_event *event; atomic_t pending; -- GitLab From ffe02b403dff23798a33a342ab685555aa088786 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 2 Feb 2015 19:09:50 +0200 Subject: [PATCH 00157/11651] drm/i915: Introduce intel_set_rps() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the valleyview_set_rps() and gen6_set_rps() calls with intel_set_rps() which itself does the IS_VALLEYVIEW() check. The code becomes simpler since the callers don't have to do this check themselves. Most of the change was performe with the following semantic patch: @@ expression E1, E2, E3; @@ - if (IS_VALLEYVIEW(E1)) { - valleyview_set_rps(E2, E3); - } else { - gen6_set_rps(E2, E3); - } + intel_set_rps(E2, E3); Adding intel_set_rps() and making valleyview_set_rps() and gen6_set_rps() static was done manually. Also valleyview_set_rps() had to be moved a bit avoid a forward declaration. v2: Use a less greedy semantic patch Cc: Chris Wilson Suggested-by: Chris Wilson Signed-off-by: Ville Syrjälä Reviewed-by Chris Wilson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_debugfs.c | 10 ++---- drivers/gpu/drm/i915/i915_drv.h | 3 +- drivers/gpu/drm/i915/i915_irq.c | 5 +-- drivers/gpu/drm/i915/i915_sysfs.c | 10 ++---- drivers/gpu/drm/i915/intel_pm.c | 53 +++++++++++++++-------------- 5 files changed, 34 insertions(+), 47 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 211d4949a675..9af17fb4f8dc 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -4214,10 +4214,7 @@ i915_max_freq_set(void *data, u64 val) dev_priv->rps.max_freq_softlimit = val; - if (IS_VALLEYVIEW(dev)) - valleyview_set_rps(dev, val); - else - gen6_set_rps(dev, val); + intel_set_rps(dev, val); mutex_unlock(&dev_priv->rps.hw_lock); @@ -4292,10 +4289,7 @@ i915_min_freq_set(void *data, u64 val) dev_priv->rps.min_freq_softlimit = val; - if (IS_VALLEYVIEW(dev)) - valleyview_set_rps(dev, val); - else - gen6_set_rps(dev, val); + intel_set_rps(dev, val); mutex_unlock(&dev_priv->rps.hw_lock); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index d8b4d0a887f8..b6b02f39985d 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3183,8 +3183,7 @@ extern void i915_redisable_vga(struct drm_device *dev); extern void i915_redisable_vga_power_on(struct drm_device *dev); extern bool ironlake_set_drps(struct drm_device *dev, u8 val); extern void intel_init_pch_refclk(struct drm_device *dev); -extern void gen6_set_rps(struct drm_device *dev, u8 val); -extern void valleyview_set_rps(struct drm_device *dev, u8 val); +extern void intel_set_rps(struct drm_device *dev, u8 val); extern void intel_set_memory_cxsr(struct drm_i915_private *dev_priv, bool enable); extern void intel_detect_pch(struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 4145d95902f5..90731195ab52 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1243,10 +1243,7 @@ static void gen6_pm_rps_work(struct work_struct *work) dev_priv->rps.last_adj = new_delay - dev_priv->rps.cur_freq; - if (IS_VALLEYVIEW(dev_priv->dev)) - valleyview_set_rps(dev_priv->dev, new_delay); - else - gen6_set_rps(dev_priv->dev, new_delay); + intel_set_rps(dev_priv->dev, new_delay); mutex_unlock(&dev_priv->rps.hw_lock); } diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c index 49f5ade0edb7..cdc9da001484 100644 --- a/drivers/gpu/drm/i915/i915_sysfs.c +++ b/drivers/gpu/drm/i915/i915_sysfs.c @@ -402,10 +402,7 @@ static ssize_t gt_max_freq_mhz_store(struct device *kdev, /* We still need *_set_rps to process the new max_delay and * update the interrupt limits and PMINTRMSK even though * frequency request may be unchanged. */ - if (IS_VALLEYVIEW(dev)) - valleyview_set_rps(dev, val); - else - gen6_set_rps(dev, val); + intel_set_rps(dev, val); mutex_unlock(&dev_priv->rps.hw_lock); @@ -464,10 +461,7 @@ static ssize_t gt_min_freq_mhz_store(struct device *kdev, /* We still need *_set_rps to process the new min_delay and * update the interrupt limits and PMINTRMSK even though * frequency request may be unchanged. */ - if (IS_VALLEYVIEW(dev)) - valleyview_set_rps(dev, val); - else - gen6_set_rps(dev, val); + intel_set_rps(dev, val); mutex_unlock(&dev_priv->rps.hw_lock); diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 6ece663f3394..bebefe79f7ce 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3750,7 +3750,7 @@ static u32 gen6_rps_pm_mask(struct drm_i915_private *dev_priv, u8 val) /* gen6_set_rps is called to update the frequency request, but should also be * called when the range (min_delay and max_delay) is modified so that we can * update the GEN6_RP_INTERRUPT_LIMITS register accordingly. */ -void gen6_set_rps(struct drm_device *dev, u8 val) +static void gen6_set_rps(struct drm_device *dev, u8 val) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -3786,6 +3786,27 @@ void gen6_set_rps(struct drm_device *dev, u8 val) trace_intel_gpu_freq_change(val * 50); } +static void valleyview_set_rps(struct drm_device *dev, u8 val) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); + WARN_ON(val > dev_priv->rps.max_freq_softlimit); + WARN_ON(val < dev_priv->rps.min_freq_softlimit); + + if (WARN_ONCE(IS_CHERRYVIEW(dev) && (val & 1), + "Odd GPU freq value\n")) + val &= ~1; + + if (val != dev_priv->rps.cur_freq) + vlv_punit_write(dev_priv, PUNIT_REG_GPU_FREQ_REQ, val); + + I915_WRITE(GEN6_PMINTRMSK, gen6_rps_pm_mask(dev_priv, val)); + + dev_priv->rps.cur_freq = val; + trace_intel_gpu_freq_change(intel_gpu_freq(dev_priv, val)); +} + /* vlv_set_rps_idle: Set the frequency to Rpn if Gfx clocks are down * * * If Gfx is Idle, then @@ -3850,38 +3871,20 @@ void gen6_rps_idle(struct drm_i915_private *dev_priv) void gen6_rps_boost(struct drm_i915_private *dev_priv) { - struct drm_device *dev = dev_priv->dev; - mutex_lock(&dev_priv->rps.hw_lock); if (dev_priv->rps.enabled) { - if (IS_VALLEYVIEW(dev)) - valleyview_set_rps(dev_priv->dev, dev_priv->rps.max_freq_softlimit); - else - gen6_set_rps(dev_priv->dev, dev_priv->rps.max_freq_softlimit); + intel_set_rps(dev_priv->dev, dev_priv->rps.max_freq_softlimit); dev_priv->rps.last_adj = 0; } mutex_unlock(&dev_priv->rps.hw_lock); } -void valleyview_set_rps(struct drm_device *dev, u8 val) +void intel_set_rps(struct drm_device *dev, u8 val) { - struct drm_i915_private *dev_priv = dev->dev_private; - - WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); - WARN_ON(val > dev_priv->rps.max_freq_softlimit); - WARN_ON(val < dev_priv->rps.min_freq_softlimit); - - if (WARN_ONCE(IS_CHERRYVIEW(dev) && (val & 1), - "Odd GPU freq value\n")) - val &= ~1; - - if (val != dev_priv->rps.cur_freq) - vlv_punit_write(dev_priv, PUNIT_REG_GPU_FREQ_REQ, val); - - I915_WRITE(GEN6_PMINTRMSK, gen6_rps_pm_mask(dev_priv, val)); - - dev_priv->rps.cur_freq = val; - trace_intel_gpu_freq_change(intel_gpu_freq(dev_priv, val)); + if (IS_VALLEYVIEW(dev)) + valleyview_set_rps(dev, val); + else + gen6_set_rps(dev, val); } static void gen9_disable_rps(struct drm_device *dev) -- GitLab From 87c54d0ee6020f90cc1de2279d81d5d55ca57ee4 Mon Sep 17 00:00:00 2001 From: Shobhit Kumar Date: Tue, 3 Feb 2015 12:17:35 +0530 Subject: [PATCH 00158/11651] drm/i915: Correct the variable holding the value for EOT to write This isuue got introduced in - commit 24ee0e64909bf7f1953d87d3e1e29d93eafcad73 Author: Gaurav K Singh Date: Fri Dec 5 14:24:21 2014 +0530 drm/i915: Update the DSI enable path to support dual Signed-off-by: Shobhit Kumar Reviewed-by: Jani Nikula Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index ef3df5e3d819..6ce9c4592fe4 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -855,7 +855,7 @@ static void intel_dsi_prepare(struct intel_encoder *intel_encoder) /* recovery disables */ - I915_WRITE(MIPI_EOT_DISABLE(port), val); + I915_WRITE(MIPI_EOT_DISABLE(port), tmp); /* in terms of low power clock */ I915_WRITE(MIPI_INIT_COUNT(port), intel_dsi->init_count); -- GitLab From 62659920cf2113b76607b87595dbebe2f5f8601c Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Thu, 29 Jan 2015 14:13:40 +0000 Subject: [PATCH 00159/11651] drm/i915/skl: Remove the check enforcing VCS2 to be gen8 only We already track this in the intel_info struct. Signed-off-by: Damien Lespiau Reviewed-by: Rodrigo Vivi [danvet: Make the commit message a bit less terse.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_ringbuffer.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 0bd3976d88e1..e1036c8e3dd1 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -2597,19 +2597,13 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev) } /** - * Initialize the second BSD ring for Broadwell GT3. - * It is noted that this only exists on Broadwell GT3. + * Initialize the second BSD ring (eg. Broadwell GT3, Skylake GT3) */ int intel_init_bsd2_ring_buffer(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct intel_engine_cs *ring = &dev_priv->ring[VCS2]; - if ((INTEL_INFO(dev)->gen != 8)) { - DRM_ERROR("No dual-BSD ring on non-BDW machine\n"); - return -EINVAL; - } - ring->name = "bsd2 ring"; ring->id = VCS2; -- GitLab From afd65eb4cc0578a9c07d621acdb8a570e2782bf7 Mon Sep 17 00:00:00 2001 From: Matt Roper Date: Tue, 3 Feb 2015 13:10:04 -0800 Subject: [PATCH 00160/11651] drm/i915: Ensure plane->state->fb stays in sync with plane->fb plane->state->fb and plane->fb should always reference the same FB so that atomic and legacy codepaths have the same view of display state. In commit commit db068420560511de80ac59222644f2bdf278c3d5 Author: Matt Roper Date: Fri Jan 30 16:22:36 2015 -0800 drm/i915: Keep plane->state updated on pageflip we already fixed one case where these two pointers could get out of sync. However it turns out there are a few other places (mainly dealing with initial FB setup at boot) that directly set plane->fb and neglect to update plane->state->fb. If we never do a successful update through the atomic pipeline, the RmFB cleanup code will look at the plane->state->fb pointer, which has never actually been set to a legitimate value, and try to clean it up, leading to BUG's. Add a quick helper function to synchronize plane->state->fb with plane->fb (and update reference counts accordingly) and call it everywhere the driver tries to manually set plane->fb outside of the atomic pipeline. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=88909 Signed-off-by: Matt Roper Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 29 +++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 213b870ae06e..e5c057996353 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2410,6 +2410,20 @@ out_unref_obj: return false; } +/* Update plane->state->fb to match plane->fb after driver-internal updates */ +static void +update_state_fb(struct drm_plane *plane) +{ + if (plane->fb == plane->state->fb) + return; + + if (plane->state->fb) + drm_framebuffer_unreference(plane->state->fb); + plane->state->fb = plane->fb; + if (plane->state->fb) + drm_framebuffer_reference(plane->state->fb); +} + static void intel_find_plane_obj(struct intel_crtc *intel_crtc, struct intel_initial_plane_config *plane_config) @@ -2456,6 +2470,8 @@ intel_find_plane_obj(struct intel_crtc *intel_crtc, break; } } + + update_state_fb(intel_crtc->base.primary); } static void i9xx_update_primary_plane(struct drm_crtc *crtc, @@ -6635,6 +6651,7 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc, plane_config->size); crtc->base.primary->fb = fb; + update_state_fb(crtc->base.primary); } static void chv_crtc_clock_get(struct intel_crtc *crtc, @@ -7672,6 +7689,7 @@ skylake_get_initial_plane_config(struct intel_crtc *crtc, plane_config->size); crtc->base.primary->fb = fb; + update_state_fb(crtc->base.primary); return; error: @@ -7763,6 +7781,7 @@ ironlake_get_initial_plane_config(struct intel_crtc *crtc, plane_config->size); crtc->base.primary->fb = fb; + update_state_fb(crtc->base.primary); } static bool ironlake_get_pipe_config(struct intel_crtc *crtc, @@ -9800,13 +9819,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, drm_gem_object_reference(&obj->base); crtc->primary->fb = fb; - - /* Keep state structure in sync */ - if (crtc->primary->state->fb) - drm_framebuffer_unreference(crtc->primary->state->fb); - crtc->primary->state->fb = fb; - if (crtc->primary->state->fb) - drm_framebuffer_reference(crtc->primary->state->fb); + update_state_fb(crtc->primary); work->pending_flip_obj = obj; @@ -9875,6 +9888,7 @@ cleanup_unpin: cleanup_pending: atomic_dec(&intel_crtc->unpin_work_count); crtc->primary->fb = old_fb; + update_state_fb(crtc->primary); drm_framebuffer_unreference(work->old_fb); drm_gem_object_unreference(&obj->base); mutex_unlock(&dev->struct_mutex); @@ -13709,6 +13723,7 @@ void intel_modeset_gem_init(struct drm_device *dev) to_intel_crtc(c)->pipe); drm_framebuffer_unreference(c->primary->fb); c->primary->fb = NULL; + update_state_fb(c->primary); } } mutex_unlock(&dev->struct_mutex); -- GitLab From 94dd5138c5ed02d26982d9704e8c1e9d72e20b40 Mon Sep 17 00:00:00 2001 From: Satheeshakrishna M Date: Wed, 4 Feb 2015 13:57:44 +0000 Subject: [PATCH 00161/11651] drm/i915/skl: Implementation of SKL display power well support This patch implements core logic of SKL display power well. v2: Addressed Imre's comments - Added respective DDIs under power well #1 and #2 - Simplified repetitive code in power well programming v3: Implemented Imre's comments - Further simplified power well programming - Made sure that PW 1 is enabled prior to PW 2 v4: Fix minor conflict with the the cherryview support (Damien) v5: Add the PLL power domain to the always on power well (Damien) v6: Disable BIOS power well (Imre) Use power well data for comparison (Imre) Put the PLL power domain into PW1 as its needed for CDCLK (Satheesh, Damien) v7: Addressed Imre's comments - Lowered the time out to 1ms - Added parantheses in macro - Moved debug message and fixed wait_for interval v8: - Add a WARN() when swiching on an unknown power well (Imre, done by Damien) - Whitespace fixes (spaces instead of tabs) (Damien) v9: (Imre, done by Damien) - Merge the register definitions with this patch - Merge the MISC IO power well in this patch v10: (Imre, done by Damien) - Define the Misc I/O power domains to be the power well 1 ones as Misc I/O needs to be enabled with PW1 - Added Transcoder A and VGA domains to PW 2 - Remove the MISC_IO power domains as well in the the always on domains definition - Move Misc I/O power well at the top of the power well list so it's turned on right after PW1. Reviewed-by: Imre Deak Signed-off-by: Satheeshakrishna M (v3,v6,v7) Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 20 +++ drivers/gpu/drm/i915/intel_runtime_pm.c | 220 ++++++++++++++++++++++++ 2 files changed, 240 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 33b3d0a24071..cd3430f931ed 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -586,6 +586,19 @@ enum punit_power_well { PUNIT_POWER_WELL_NUM, }; +enum skl_disp_power_wells { + SKL_DISP_PW_MISC_IO, + SKL_DISP_PW_DDI_A_E, + SKL_DISP_PW_DDI_B, + SKL_DISP_PW_DDI_C, + SKL_DISP_PW_DDI_D, + SKL_DISP_PW_1 = 14, + SKL_DISP_PW_2, +}; + +#define SKL_POWER_WELL_STATE(pw) (1 << ((pw) * 2)) +#define SKL_POWER_WELL_REQ(pw) (1 << (((pw) * 2) + 1)) + #define PUNIT_REG_PWRGT_CTRL 0x60 #define PUNIT_REG_PWRGT_STATUS 0x61 #define PUNIT_PWRGT_MASK(power_well) (3 << ((power_well) * 2)) @@ -6351,6 +6364,13 @@ enum punit_power_well { #define HSW_PWR_WELL_FORCE_ON (1<<19) #define HSW_PWR_WELL_CTL6 0x45414 +/* SKL Fuse Status */ +#define SKL_FUSE_STATUS 0x42000 +#define SKL_FUSE_DOWNLOAD_STATUS (1<<31) +#define SKL_FUSE_PG0_DIST_STATUS (1<<27) +#define SKL_FUSE_PG1_DIST_STATUS (1<<26) +#define SKL_FUSE_PG2_DIST_STATUS (1<<25) + /* Per-pipe DDI Function Control */ #define TRANS_DDI_FUNC_CTL_A 0x60400 #define TRANS_DDI_FUNC_CTL_B 0x61400 diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index 49695d7d51e3..6d8e29abbc33 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -230,6 +230,136 @@ static void hsw_set_power_well(struct drm_i915_private *dev_priv, } } +#define SKL_DISPLAY_POWERWELL_2_POWER_DOMAINS ( \ + BIT(POWER_DOMAIN_TRANSCODER_A) | \ + BIT(POWER_DOMAIN_PIPE_B) | \ + BIT(POWER_DOMAIN_TRANSCODER_B) | \ + BIT(POWER_DOMAIN_PIPE_C) | \ + BIT(POWER_DOMAIN_TRANSCODER_C) | \ + BIT(POWER_DOMAIN_PIPE_B_PANEL_FITTER) | \ + BIT(POWER_DOMAIN_PIPE_C_PANEL_FITTER) | \ + BIT(POWER_DOMAIN_PORT_DDI_B_2_LANES) | \ + BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) | \ + BIT(POWER_DOMAIN_PORT_DDI_C_2_LANES) | \ + BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) | \ + BIT(POWER_DOMAIN_PORT_DDI_D_2_LANES) | \ + BIT(POWER_DOMAIN_PORT_DDI_D_4_LANES) | \ + BIT(POWER_DOMAIN_AUX_B) | \ + BIT(POWER_DOMAIN_AUX_C) | \ + BIT(POWER_DOMAIN_AUX_D) | \ + BIT(POWER_DOMAIN_AUDIO) | \ + BIT(POWER_DOMAIN_VGA) | \ + BIT(POWER_DOMAIN_INIT)) +#define SKL_DISPLAY_POWERWELL_1_POWER_DOMAINS ( \ + SKL_DISPLAY_POWERWELL_2_POWER_DOMAINS | \ + BIT(POWER_DOMAIN_PLLS) | \ + BIT(POWER_DOMAIN_PIPE_A) | \ + BIT(POWER_DOMAIN_TRANSCODER_EDP) | \ + BIT(POWER_DOMAIN_PIPE_A_PANEL_FITTER) | \ + BIT(POWER_DOMAIN_PORT_DDI_A_2_LANES) | \ + BIT(POWER_DOMAIN_PORT_DDI_A_4_LANES) | \ + BIT(POWER_DOMAIN_AUX_A) | \ + BIT(POWER_DOMAIN_INIT)) +#define SKL_DISPLAY_DDI_A_E_POWER_DOMAINS ( \ + BIT(POWER_DOMAIN_PORT_DDI_A_2_LANES) | \ + BIT(POWER_DOMAIN_PORT_DDI_A_4_LANES) | \ + BIT(POWER_DOMAIN_INIT)) +#define SKL_DISPLAY_DDI_B_POWER_DOMAINS ( \ + BIT(POWER_DOMAIN_PORT_DDI_B_2_LANES) | \ + BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) | \ + BIT(POWER_DOMAIN_INIT)) +#define SKL_DISPLAY_DDI_C_POWER_DOMAINS ( \ + BIT(POWER_DOMAIN_PORT_DDI_C_2_LANES) | \ + BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) | \ + BIT(POWER_DOMAIN_INIT)) +#define SKL_DISPLAY_DDI_D_POWER_DOMAINS ( \ + BIT(POWER_DOMAIN_PORT_DDI_D_2_LANES) | \ + BIT(POWER_DOMAIN_PORT_DDI_D_4_LANES) | \ + BIT(POWER_DOMAIN_INIT)) +#define SKL_DISPLAY_MISC_IO_POWER_DOMAINS ( \ + SKL_DISPLAY_POWERWELL_1_POWER_DOMAINS) +#define SKL_DISPLAY_ALWAYS_ON_POWER_DOMAINS ( \ + (POWER_DOMAIN_MASK & ~(SKL_DISPLAY_POWERWELL_1_POWER_DOMAINS | \ + SKL_DISPLAY_POWERWELL_2_POWER_DOMAINS | \ + SKL_DISPLAY_DDI_A_E_POWER_DOMAINS | \ + SKL_DISPLAY_DDI_B_POWER_DOMAINS | \ + SKL_DISPLAY_DDI_C_POWER_DOMAINS | \ + SKL_DISPLAY_DDI_D_POWER_DOMAINS | \ + SKL_DISPLAY_MISC_IO_POWER_DOMAINS)) | \ + BIT(POWER_DOMAIN_INIT)) + +static void skl_set_power_well(struct drm_i915_private *dev_priv, + struct i915_power_well *power_well, bool enable) +{ + uint32_t tmp, fuse_status; + uint32_t req_mask, state_mask; + bool check_fuse_status = false; + + tmp = I915_READ(HSW_PWR_WELL_DRIVER); + fuse_status = I915_READ(SKL_FUSE_STATUS); + + switch (power_well->data) { + case SKL_DISP_PW_1: + if (wait_for((I915_READ(SKL_FUSE_STATUS) & + SKL_FUSE_PG0_DIST_STATUS), 1)) { + DRM_ERROR("PG0 not enabled\n"); + return; + } + break; + case SKL_DISP_PW_2: + if (!(fuse_status & SKL_FUSE_PG1_DIST_STATUS)) { + DRM_ERROR("PG1 in disabled state\n"); + return; + } + break; + case SKL_DISP_PW_DDI_A_E: + case SKL_DISP_PW_DDI_B: + case SKL_DISP_PW_DDI_C: + case SKL_DISP_PW_DDI_D: + case SKL_DISP_PW_MISC_IO: + break; + default: + WARN(1, "Unknown power well %lu\n", power_well->data); + return; + } + + req_mask = SKL_POWER_WELL_REQ(power_well->data); + state_mask = SKL_POWER_WELL_STATE(power_well->data); + + if (enable) { + if (!(tmp & req_mask)) { + I915_WRITE(HSW_PWR_WELL_DRIVER, tmp | req_mask); + DRM_DEBUG_KMS("Enabling %s\n", power_well->name); + } + + if (!(tmp & state_mask)) { + if (wait_for((I915_READ(HSW_PWR_WELL_DRIVER) & + state_mask), 1)) + DRM_ERROR("%s enable timeout\n", + power_well->name); + check_fuse_status = true; + } + } else { + if (tmp & req_mask) { + I915_WRITE(HSW_PWR_WELL_DRIVER, tmp & ~req_mask); + POSTING_READ(HSW_PWR_WELL_DRIVER); + DRM_DEBUG_KMS("Disabling %s\n", power_well->name); + } + } + + if (check_fuse_status) { + if (power_well->data == SKL_DISP_PW_1) { + if (wait_for((I915_READ(SKL_FUSE_STATUS) & + SKL_FUSE_PG1_DIST_STATUS), 1)) + DRM_ERROR("PG1 distributing status timeout\n"); + } else if (power_well->data == SKL_DISP_PW_2) { + if (wait_for((I915_READ(SKL_FUSE_STATUS) & + SKL_FUSE_PG2_DIST_STATUS), 1)) + DRM_ERROR("PG2 distributing status timeout\n"); + } + } +} + static void hsw_power_well_sync_hw(struct drm_i915_private *dev_priv, struct i915_power_well *power_well) { @@ -255,6 +385,36 @@ static void hsw_power_well_disable(struct drm_i915_private *dev_priv, hsw_set_power_well(dev_priv, power_well, false); } +static bool skl_power_well_enabled(struct drm_i915_private *dev_priv, + struct i915_power_well *power_well) +{ + uint32_t mask = SKL_POWER_WELL_REQ(power_well->data) | + SKL_POWER_WELL_STATE(power_well->data); + + return (I915_READ(HSW_PWR_WELL_DRIVER) & mask) == mask; +} + +static void skl_power_well_sync_hw(struct drm_i915_private *dev_priv, + struct i915_power_well *power_well) +{ + skl_set_power_well(dev_priv, power_well, power_well->count > 0); + + /* Clear any request made by BIOS as driver is taking over */ + I915_WRITE(HSW_PWR_WELL_BIOS, 0); +} + +static void skl_power_well_enable(struct drm_i915_private *dev_priv, + struct i915_power_well *power_well) +{ + skl_set_power_well(dev_priv, power_well, true); +} + +static void skl_power_well_disable(struct drm_i915_private *dev_priv, + struct i915_power_well *power_well) +{ + skl_set_power_well(dev_priv, power_well, false); +} + static void i9xx_always_on_power_well_noop(struct drm_i915_private *dev_priv, struct i915_power_well *power_well) { @@ -829,6 +989,13 @@ static const struct i915_power_well_ops hsw_power_well_ops = { .is_enabled = hsw_power_well_enabled, }; +static const struct i915_power_well_ops skl_power_well_ops = { + .sync_hw = skl_power_well_sync_hw, + .enable = skl_power_well_enable, + .disable = skl_power_well_disable, + .is_enabled = skl_power_well_enabled, +}; + static struct i915_power_well hsw_power_wells[] = { { .name = "always-on", @@ -1059,6 +1226,57 @@ static struct i915_power_well *lookup_power_well(struct drm_i915_private *dev_pr return NULL; } +static struct i915_power_well skl_power_wells[] = { + { + .name = "always-on", + .always_on = 1, + .domains = SKL_DISPLAY_ALWAYS_ON_POWER_DOMAINS, + .ops = &i9xx_always_on_power_well_ops, + }, + { + .name = "power well 1", + .domains = SKL_DISPLAY_POWERWELL_1_POWER_DOMAINS, + .ops = &skl_power_well_ops, + .data = SKL_DISP_PW_1, + }, + { + .name = "MISC IO power well", + .domains = SKL_DISPLAY_MISC_IO_POWER_DOMAINS, + .ops = &skl_power_well_ops, + .data = SKL_DISP_PW_MISC_IO, + }, + { + .name = "power well 2", + .domains = SKL_DISPLAY_POWERWELL_2_POWER_DOMAINS, + .ops = &skl_power_well_ops, + .data = SKL_DISP_PW_2, + }, + { + .name = "DDI A/E power well", + .domains = SKL_DISPLAY_DDI_A_E_POWER_DOMAINS, + .ops = &skl_power_well_ops, + .data = SKL_DISP_PW_DDI_A_E, + }, + { + .name = "DDI B power well", + .domains = SKL_DISPLAY_DDI_B_POWER_DOMAINS, + .ops = &skl_power_well_ops, + .data = SKL_DISP_PW_DDI_B, + }, + { + .name = "DDI C power well", + .domains = SKL_DISPLAY_DDI_C_POWER_DOMAINS, + .ops = &skl_power_well_ops, + .data = SKL_DISP_PW_DDI_C, + }, + { + .name = "DDI D power well", + .domains = SKL_DISPLAY_DDI_D_POWER_DOMAINS, + .ops = &skl_power_well_ops, + .data = SKL_DISP_PW_DDI_D, + }, +}; + #define set_power_wells(power_domains, __power_wells) ({ \ (power_domains)->power_wells = (__power_wells); \ (power_domains)->power_well_count = ARRAY_SIZE(__power_wells); \ @@ -1085,6 +1303,8 @@ int intel_power_domains_init(struct drm_i915_private *dev_priv) set_power_wells(power_domains, hsw_power_wells); } else if (IS_BROADWELL(dev_priv->dev)) { set_power_wells(power_domains, bdw_power_wells); + } else if (IS_SKYLAKE(dev_priv->dev)) { + set_power_wells(power_domains, skl_power_wells); } else if (IS_CHERRYVIEW(dev_priv->dev)) { set_power_wells(power_domains, chv_power_wells); } else if (IS_VALLEYVIEW(dev_priv->dev)) { -- GitLab From bf2b8a515530ee7e3b25214d7ec52c6827f12d70 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Thu, 29 Jan 2015 14:13:38 +0000 Subject: [PATCH 00162/11651] drm/i915/skl: Split the SKL PCI ids by GT We need to have a separate GT3 struct intel_device_info to declare they have a second VCS. Let's start by splitting the PCI ids per-GT. Signed-off-by: Damien Lespiau Reviewed-by: Rodrigo Vivi Signed-off-by: Daniel Vetter --- include/drm/i915_pciids.h | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/include/drm/i915_pciids.h b/include/drm/i915_pciids.h index 180ad0e6de21..38a7c8049e47 100644 --- a/include/drm/i915_pciids.h +++ b/include/drm/i915_pciids.h @@ -259,21 +259,31 @@ INTEL_VGA_DEVICE(0x22b2, info), \ INTEL_VGA_DEVICE(0x22b3, info) -#define INTEL_SKL_IDS(info) \ - INTEL_VGA_DEVICE(0x1916, info), /* ULT GT2 */ \ +#define INTEL_SKL_GT1_IDS(info) \ INTEL_VGA_DEVICE(0x1906, info), /* ULT GT1 */ \ - INTEL_VGA_DEVICE(0x1926, info), /* ULT GT3 */ \ - INTEL_VGA_DEVICE(0x1921, info), /* ULT GT2F */ \ INTEL_VGA_DEVICE(0x190E, info), /* ULX GT1 */ \ + INTEL_VGA_DEVICE(0x1902, info), /* DT GT1 */ \ + INTEL_VGA_DEVICE(0x190B, info), /* Halo GT1 */ \ + INTEL_VGA_DEVICE(0x190A, info) /* SRV GT1 */ + +#define INTEL_SKL_GT2_IDS(info) \ + INTEL_VGA_DEVICE(0x1916, info), /* ULT GT2 */ \ + INTEL_VGA_DEVICE(0x1921, info), /* ULT GT2F */ \ INTEL_VGA_DEVICE(0x191E, info), /* ULX GT2 */ \ INTEL_VGA_DEVICE(0x1912, info), /* DT GT2 */ \ - INTEL_VGA_DEVICE(0x1902, info), /* DT GT1 */ \ INTEL_VGA_DEVICE(0x191B, info), /* Halo GT2 */ \ - INTEL_VGA_DEVICE(0x192B, info), /* Halo GT3 */ \ - INTEL_VGA_DEVICE(0x190B, info), /* Halo GT1 */ \ INTEL_VGA_DEVICE(0x191A, info), /* SRV GT2 */ \ - INTEL_VGA_DEVICE(0x192A, info), /* SRV GT3 */ \ - INTEL_VGA_DEVICE(0x190A, info), /* SRV GT1 */ \ INTEL_VGA_DEVICE(0x191D, info) /* WKS GT2 */ +#define INTEL_SKL_GT3_IDS(info) \ + INTEL_VGA_DEVICE(0x1926, info), /* ULT GT3 */ \ + INTEL_VGA_DEVICE(0x192B, info), /* Halo GT3 */ \ + INTEL_VGA_DEVICE(0x192A, info) /* SRV GT3 */ \ + +#define INTEL_SKL_IDS(info) \ + INTEL_SKL_GT1_IDS(info), \ + INTEL_SKL_GT2_IDS(info), \ + INTEL_SKL_GT3_IDS(info) + + #endif /* _I915_PCIIDS_H */ -- GitLab From 719388e146c34f065c275258e007a39b694aa68f Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Wed, 4 Feb 2015 13:22:27 +0000 Subject: [PATCH 00163/11651] drm/i915/skl: Declare that GT3 has a second VCS v2: leave intel_skylake_info alone (Rodrigo, Daniel) Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 5f50e7033ef7..84a303152c91 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -369,6 +369,19 @@ static const struct intel_device_info intel_skylake_info = { IVB_CURSOR_OFFSETS, }; +static const struct intel_device_info intel_skylake_gt3_info = { + .is_preliminary = 1, + .is_skylake = 1, + .gen = 9, .num_pipes = 3, + .need_gfx_hws = 1, .has_hotplug = 1, + .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING, + .has_llc = 1, + .has_ddi = 1, + .has_fbc = 1, + GEN_DEFAULT_PIPEOFFSETS, + IVB_CURSOR_OFFSETS, +}; + /* * Make sure any device matches here are from most specific to most * general. For example, since the Quanta match is based on the subsystem @@ -406,7 +419,9 @@ static const struct intel_device_info intel_skylake_info = { INTEL_BDW_GT3M_IDS(&intel_broadwell_gt3m_info), \ INTEL_BDW_GT3D_IDS(&intel_broadwell_gt3d_info), \ INTEL_CHV_IDS(&intel_cherryview_info), \ - INTEL_SKL_IDS(&intel_skylake_info) + INTEL_SKL_GT1_IDS(&intel_skylake_info), \ + INTEL_SKL_GT2_IDS(&intel_skylake_info), \ + INTEL_SKL_GT3_IDS(&intel_skylake_gt3_info) \ static const struct pci_device_id pciidlist[] = { /* aka */ INTEL_PCI_IDS, -- GitLab From 60ee5cd24cf1c39d4c7bab7b428a08386a93fe9f Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 5 Feb 2015 12:04:27 +0200 Subject: [PATCH 00164/11651] drm/i915/fbc: fix the check for already reserved fbc size The check for previously reserved stolen space size for FBC in i915_gem_stolen_setup_compression() did not take the compression threshold into account. Fix this by storing and comparing to uncompressed size instead. The bug has been introduced in commit 5e59f7175f96550ede91f58d267d2b551cb6fbba Author: Ben Widawsky Date: Mon Jun 30 10:41:24 2014 -0700 drm/i915: Try harder to get FBC Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=88975 Suggested-by: Chris Wilson Cc: Ben Widawsky Signed-off-by: Jani Nikula Reviewed-by: Chris Wilson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 2 +- drivers/gpu/drm/i915/i915_gem_stolen.c | 8 ++++---- drivers/gpu/drm/i915/intel_fbc.c | 3 ++- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index b6b02f39985d..ddfa701d1b9f 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -772,7 +772,7 @@ struct intel_context { }; struct i915_fbc { - unsigned long size; + unsigned long uncompressed_size; unsigned threshold; unsigned int fb_id; enum plane plane; diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c index a2045848bd1a..59401f3b902c 100644 --- a/drivers/gpu/drm/i915/i915_gem_stolen.c +++ b/drivers/gpu/drm/i915/i915_gem_stolen.c @@ -231,7 +231,7 @@ static int i915_setup_compression(struct drm_device *dev, int size, int fb_cpp) dev_priv->mm.stolen_base + compressed_llb->start); } - dev_priv->fbc.size = size / dev_priv->fbc.threshold; + dev_priv->fbc.uncompressed_size = size; DRM_DEBUG_KMS("reserved %d bytes of contiguous stolen space for FBC\n", size); @@ -253,7 +253,7 @@ int i915_gem_stolen_setup_compression(struct drm_device *dev, int size, int fb_c if (!drm_mm_initialized(&dev_priv->mm.stolen)) return -ENODEV; - if (size < dev_priv->fbc.size) + if (size < dev_priv->fbc.uncompressed_size) return 0; /* Release any current block */ @@ -266,7 +266,7 @@ void i915_gem_stolen_cleanup_compression(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - if (dev_priv->fbc.size == 0) + if (dev_priv->fbc.uncompressed_size == 0) return; drm_mm_remove_node(&dev_priv->fbc.compressed_fb); @@ -276,7 +276,7 @@ void i915_gem_stolen_cleanup_compression(struct drm_device *dev) kfree(dev_priv->fbc.compressed_llb); } - dev_priv->fbc.size = 0; + dev_priv->fbc.uncompressed_size = 0; } void i915_gem_cleanup_stolen(struct drm_device *dev) diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index 624d1d92d284..b572bb6ebcff 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -78,7 +78,8 @@ static void i8xx_fbc_enable(struct drm_crtc *crtc) dev_priv->fbc.enabled = true; - cfb_pitch = dev_priv->fbc.size / FBC_LL_SIZE; + /* Note: fbc.threshold == 1 for i8xx */ + cfb_pitch = dev_priv->fbc.uncompressed_size / FBC_LL_SIZE; if (fb->pitches[0] < cfb_pitch) cfb_pitch = fb->pitches[0]; -- GitLab From 5ba76c41e55c32f35224c956759fcdc154c78b1a Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Thu, 5 Feb 2015 17:22:15 +0000 Subject: [PATCH 00165/11651] drm/i915: Put update_state_fb() next to the fb update update_state_fb() at the end of intel_find_plane_obj() is misleading as it leads us to believe the update is done for all code path. A successful call to intel_alloc_plane_obj() will return and update_state_fb() is then only needed when we share a fb from another CRTC. Put the update() function there then. Signed-off-by: Damien Lespiau Reviewed-by: Matt Roper Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e5c057996353..8900ce09faa0 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2466,12 +2466,12 @@ intel_find_plane_obj(struct intel_crtc *intel_crtc, drm_framebuffer_reference(c->primary->fb); intel_crtc->base.primary->fb = c->primary->fb; + update_state_fb(intel_crtc->base.primary); obj->frontbuffer_bits |= INTEL_FRONTBUFFER_PRIMARY(intel_crtc->pipe); break; } } - update_state_fb(intel_crtc->base.primary); } static void i9xx_update_primary_plane(struct drm_crtc *crtc, -- GitLab From 6bf129df6ffae600e8f12440635cf64d293042b4 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Thu, 5 Feb 2015 17:22:16 +0000 Subject: [PATCH 00166/11651] drm/i915: Use an intermediate variable to avoid repeating ourselves The code look slightly better this way and will ease the next commit, changing where we take the fb pointer from. Signed-off-by: Damien Lespiau Reviewed-by: Matt Roper Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 8900ce09faa0..3301b615555c 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2371,6 +2371,7 @@ intel_alloc_plane_obj(struct intel_crtc *crtc, struct drm_device *dev = crtc->base.dev; struct drm_i915_gem_object *obj = NULL; struct drm_mode_fb_cmd2 mode_cmd = { 0 }; + struct drm_framebuffer *fb = crtc->base.primary->fb; u32 base = plane_config->base; if (plane_config->size == 0) @@ -2383,16 +2384,16 @@ intel_alloc_plane_obj(struct intel_crtc *crtc, obj->tiling_mode = plane_config->tiling; if (obj->tiling_mode == I915_TILING_X) - obj->stride = crtc->base.primary->fb->pitches[0]; + obj->stride = fb->pitches[0]; - mode_cmd.pixel_format = crtc->base.primary->fb->pixel_format; - mode_cmd.width = crtc->base.primary->fb->width; - mode_cmd.height = crtc->base.primary->fb->height; - mode_cmd.pitches[0] = crtc->base.primary->fb->pitches[0]; + mode_cmd.pixel_format = fb->pixel_format; + mode_cmd.width = fb->width; + mode_cmd.height = fb->height; + mode_cmd.pitches[0] = fb->pitches[0]; mutex_lock(&dev->struct_mutex); - if (intel_framebuffer_init(dev, to_intel_framebuffer(crtc->base.primary->fb), + if (intel_framebuffer_init(dev, to_intel_framebuffer(fb), &mode_cmd, obj)) { DRM_DEBUG_KMS("intel fb init failed\n"); goto out_unref_obj; -- GitLab From f55548b5af87ebfc586ca75748947f1c1b1a4a52 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Thu, 5 Feb 2015 18:30:20 +0000 Subject: [PATCH 00167/11651] drm/i915: Don't try to reference the fb in get_initial_plane_config() Tvrtko noticed a new warning on boot: WARNING: CPU: 1 PID: 353 at include/linux/kref.h:47 drm_framebuffer_reference+0x6c/0x80 [drm]() Call Trace: [] dump_stack+0x4f/0x7b [] warn_slowpath_common+0xaa/0xd0 [] warn_slowpath_null+0x1a/0x20 [] drm_framebuffer_reference+0x6c/0x80 [drm] [] update_state_fb.isra.54+0x47/0x50 [i915] [] skylake_get_initial_plane_config+0x93c/0x950 [i915] [] intel_modeset_init+0x1551/0x17c0 [i915] [] i915_driver_load+0xed0/0x11e0 [i915] [] ? _raw_spin_unlock_irqrestore+0x51/0x70 [] drm_dev_register+0x77/0x110 [drm] [] drm_get_pci_dev+0x11b/0x1f0 [drm] [] ? trace_hardirqs_on+0xd/0x10 [] ? _raw_spin_unlock_irqrestore+0x51/0x70 [] i915_pci_probe+0x56/0x60 [i915] [] pci_device_probe+0x7c/0x100 [] driver_probe_device+0x16d/0x380 We cannot take a reference at this point, not before intel_framebuffer_init() and the underlying drm_framebuffer_init(). Introduced in: commit 706dc7b549175e47f23e913b7f1e52874a7d0f56 Author: Matt Roper Date: Tue Feb 3 13:10:04 2015 -0800 drm/i915: Ensure plane->state->fb stays in sync with plane->fb v2: Don't move update_state_fb(). It was moved around because I originally put update_state_fb() in intel_alloc_plane_obj() before finding a better place. (Matt) Reviewed-by: Matt Roper Reported-by: Tvrtko Ursulin Cc: Matt Roper Cc: Tvrtko Ursulin Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 3301b615555c..a25ff006fdb0 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2438,8 +2438,10 @@ intel_find_plane_obj(struct intel_crtc *intel_crtc, if (!intel_crtc->base.primary->fb) return; - if (intel_alloc_plane_obj(intel_crtc, plane_config)) + if (intel_alloc_plane_obj(intel_crtc, plane_config)) { + update_state_fb(intel_crtc->base.primary); return; + } kfree(intel_crtc->base.primary->fb); intel_crtc->base.primary->fb = NULL; @@ -6652,7 +6654,6 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc, plane_config->size); crtc->base.primary->fb = fb; - update_state_fb(crtc->base.primary); } static void chv_crtc_clock_get(struct intel_crtc *crtc, @@ -7690,7 +7691,6 @@ skylake_get_initial_plane_config(struct intel_crtc *crtc, plane_config->size); crtc->base.primary->fb = fb; - update_state_fb(crtc->base.primary); return; error: @@ -7782,7 +7782,6 @@ ironlake_get_initial_plane_config(struct intel_crtc *crtc, plane_config->size); crtc->base.primary->fb = fb; - update_state_fb(crtc->base.primary); } static bool ironlake_get_pipe_config(struct intel_crtc *crtc, -- GitLab From 2d14030b1a9d0e89cfdca6f16851e2eac8cb4de0 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Thu, 5 Feb 2015 17:22:18 +0000 Subject: [PATCH 00168/11651] drm/i915: Store the initial framebuffer in initial_plane_config At the moment we use crtc->base.primary->fb to hold the initial framebuffer allocation, disregarding if it's valid or not. This lead to believe we were actually updating the fb at this point, but it's not true and we haven't even called drm_framebuffer_init() on this fb. Instead, let's store the state in struct intel_initial_plane_config until we know we can reuse that framebuffer. Signed-off-by: Damien Lespiau Reviewed-by: Matt Roper Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 14 +++++++------- drivers/gpu/drm/i915/intel_drv.h | 1 + 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index a25ff006fdb0..86cbc771bce6 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2371,7 +2371,7 @@ intel_alloc_plane_obj(struct intel_crtc *crtc, struct drm_device *dev = crtc->base.dev; struct drm_i915_gem_object *obj = NULL; struct drm_mode_fb_cmd2 mode_cmd = { 0 }; - struct drm_framebuffer *fb = crtc->base.primary->fb; + struct drm_framebuffer *fb = &plane_config->fb->base; u32 base = plane_config->base; if (plane_config->size == 0) @@ -2435,16 +2435,16 @@ intel_find_plane_obj(struct intel_crtc *intel_crtc, struct intel_crtc *i; struct drm_i915_gem_object *obj; - if (!intel_crtc->base.primary->fb) + if (!plane_config->fb) return; if (intel_alloc_plane_obj(intel_crtc, plane_config)) { + intel_crtc->base.primary->fb = &plane_config->fb->base; update_state_fb(intel_crtc->base.primary); return; } - kfree(intel_crtc->base.primary->fb); - intel_crtc->base.primary->fb = NULL; + kfree(plane_config->fb); /* * Failed to alloc the obj, check to see if we should share @@ -6653,7 +6653,7 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc, fb->bits_per_pixel, base, fb->pitches[0], plane_config->size); - crtc->base.primary->fb = fb; + plane_config->fb = intel_fb; } static void chv_crtc_clock_get(struct intel_crtc *crtc, @@ -7690,7 +7690,7 @@ skylake_get_initial_plane_config(struct intel_crtc *crtc, fb->bits_per_pixel, base, fb->pitches[0], plane_config->size); - crtc->base.primary->fb = fb; + plane_config->fb = intel_fb; return; error: @@ -7781,7 +7781,7 @@ ironlake_get_initial_plane_config(struct intel_crtc *crtc, fb->bits_per_pixel, base, fb->pitches[0], plane_config->size); - crtc->base.primary->fb = fb; + plane_config->fb = intel_fb; } static bool ironlake_get_pipe_config(struct intel_crtc *crtc, diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index f048f8bb8beb..76b3c2043954 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -258,6 +258,7 @@ struct intel_plane_state { }; struct intel_initial_plane_config { + struct intel_framebuffer *fb; unsigned int tiling; int size; u32 base; -- GitLab From fb9981aa675eb7b398849915364916fd98833cfa Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Thu, 5 Feb 2015 19:24:25 +0000 Subject: [PATCH 00169/11651] drm/i915: Fix atomic state when reusing the firmware fb Right now, we get a warning when taking over the firmware fb: [drm:drm_atomic_plane_check] FB set but no CRTC with the following backtrace: [] drm_atomic_check_only+0x35d/0x510 [drm] [] drm_atomic_commit+0x17/0x60 [drm] [] drm_atomic_helper_plane_set_property+0x8d/0xd0 [drm_kms_helper] [] drm_mode_plane_set_obj_prop+0x2d/0x90 [drm] [] restore_fbdev_mode+0x6b/0xf0 [drm_kms_helper] [] drm_fb_helper_restore_fbdev_mode_unlocked+0x29/0x80 [drm_kms_helper] [] drm_fb_helper_set_par+0x22/0x50 [drm_kms_helper] [] intel_fbdev_set_par+0x1a/0x60 [i915] [] fbcon_init+0x4f4/0x580 That's because we update the plane state with the fb from the firmware, but we never associate the plane to that CRTC. We don't quite have the full DRM take over from HW state just yet, so fake enough of the plane atomic state to pass the checks. v2: Fix the state on which we set the CRTC in the case we're sharing the initial fb with another pipe. (Matt) Signed-off-by: Damien Lespiau Reviewed-by: Matt Roper Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 86cbc771bce6..074f204fdc35 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2439,8 +2439,12 @@ intel_find_plane_obj(struct intel_crtc *intel_crtc, return; if (intel_alloc_plane_obj(intel_crtc, plane_config)) { - intel_crtc->base.primary->fb = &plane_config->fb->base; - update_state_fb(intel_crtc->base.primary); + struct drm_plane *primary = intel_crtc->base.primary; + + primary->fb = &plane_config->fb->base; + primary->state->crtc = &intel_crtc->base; + update_state_fb(primary); + return; } @@ -2464,11 +2468,14 @@ intel_find_plane_obj(struct intel_crtc *intel_crtc, continue; if (i915_gem_obj_ggtt_offset(obj) == plane_config->base) { + struct drm_plane *primary = intel_crtc->base.primary; + if (obj->tiling_mode != I915_TILING_NONE) dev_priv->preserve_bios_swizzle = true; drm_framebuffer_reference(c->primary->fb); - intel_crtc->base.primary->fb = c->primary->fb; + primary->fb = c->primary->fb; + primary->state->crtc = &intel_crtc->base; update_state_fb(intel_crtc->base.primary); obj->frontbuffer_bits |= INTEL_FRONTBUFFER_PRIMARY(intel_crtc->pipe); break; -- GitLab From 42a7b088127f7725b6d445d7d9e1e1855988a157 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Thu, 5 Feb 2015 19:35:13 +0000 Subject: [PATCH 00170/11651] drm/i915: Make sure the primary plane is enabled before reading out the fb state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We don't want to end up in a state where we track that the pipe has its primary plane enabled when primary plane registers are programmed with values that look possible but the plane actually disabled. Refuse to read out the fb state when the primary plane isn't enabled. Suggested-by: Ville Syrjälä Suggested-by: Matt Roper Signed-off-by: Damien Lespiau Reviewed-by: Matt Roper Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 074f204fdc35..3fe95982be93 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -6613,6 +6613,10 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc, struct drm_framebuffer *fb; struct intel_framebuffer *intel_fb; + val = I915_READ(DSPCNTR(plane)); + if (!(val & DISPLAY_PLANE_ENABLE)) + return; + intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL); if (!intel_fb) { DRM_DEBUG_KMS("failed to alloc fb\n"); @@ -6621,8 +6625,6 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc, fb = &intel_fb->base; - val = I915_READ(DSPCNTR(plane)); - if (INTEL_INFO(dev)->gen >= 4) if (val & DISPPLANE_TILED) plane_config->tiling = I915_TILING_X; @@ -7654,6 +7656,9 @@ skylake_get_initial_plane_config(struct intel_crtc *crtc, fb = &intel_fb->base; val = I915_READ(PLANE_CTL(pipe, 0)); + if (!(val & PLANE_CTL_ENABLE)) + goto error; + if (val & PLANE_CTL_TILED_MASK) plane_config->tiling = I915_TILING_X; @@ -7741,6 +7746,10 @@ ironlake_get_initial_plane_config(struct intel_crtc *crtc, struct drm_framebuffer *fb; struct intel_framebuffer *intel_fb; + val = I915_READ(DSPCNTR(pipe)); + if (!(val & DISPLAY_PLANE_ENABLE)) + return; + intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL); if (!intel_fb) { DRM_DEBUG_KMS("failed to alloc fb\n"); @@ -7749,8 +7758,6 @@ ironlake_get_initial_plane_config(struct intel_crtc *crtc, fb = &intel_fb->base; - val = I915_READ(DSPCNTR(pipe)); - if (INTEL_INFO(dev)->gen >= 4) if (val & DISPPLANE_TILED) plane_config->tiling = I915_TILING_X; -- GitLab From 3b10653178473c44e8909b5f23ab6f515fb63259 Mon Sep 17 00:00:00 2001 From: "Hoath, Nicholas" Date: Thu, 5 Feb 2015 10:47:16 +0000 Subject: [PATCH 00171/11651] drm/i915: ring w/a initialisation for gen 9 Add framework for gen 9 HW WAs v1: Changed SOC specific WA function to gen 9 common function (Req: Damien Lespiau) Signed-off-by: Nick Hoath Reviewed-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_ringbuffer.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index e1036c8e3dd1..fbfe65ac590b 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -873,6 +873,11 @@ static int chv_init_workarounds(struct intel_engine_cs *ring) return 0; } +static int gen9_init_workarounds(struct intel_engine_cs *ring) +{ + return 0; +} + int init_workarounds_ring(struct intel_engine_cs *ring) { struct drm_device *dev = ring->dev; @@ -888,6 +893,9 @@ int init_workarounds_ring(struct intel_engine_cs *ring) if (IS_CHERRYVIEW(dev)) return chv_init_workarounds(ring); + if (IS_GEN9(dev)) + return gen9_init_workarounds(ring); + return 0; } -- GitLab From e90a21d45d7ea269e6700208809a92d35c0c2362 Mon Sep 17 00:00:00 2001 From: "Hoath, Nicholas" Date: Thu, 5 Feb 2015 10:47:17 +0000 Subject: [PATCH 00172/11651] drm/i915: ring w/a gen 9 revision definitions Add Skylake stepping Revision IDs definitions. v1: Use existing revision id. Signed-off-by: Nick Hoath Reviewed-by: Damien Lespiau [danvet: Use magic __I915__ and bikeshed #defines as suggested by Damien.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index ddfa701d1b9f..217845951b7f 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2339,6 +2339,7 @@ struct drm_i915_cmd_table { }) #define INTEL_INFO(p) (&__I915__(p)->info) #define INTEL_DEVID(p) (INTEL_INFO(p)->device_id) +#define INTEL_REVID(p) (__I915__(p)->dev->pdev->revision) #define IS_I830(dev) (INTEL_DEVID(dev) == 0x3577) #define IS_845G(dev) (INTEL_DEVID(dev) == 0x2562) @@ -2387,6 +2388,11 @@ struct drm_i915_cmd_table { INTEL_DEVID(dev) == 0x0A1E) #define IS_PRELIMINARY_HW(intel_info) ((intel_info)->is_preliminary) +#define SKL_REVID_A0 (0x0) +#define SKL_REVID_B0 (0x1) +#define SKL_REVID_C0 (0x2) +#define SKL_REVID_D0 (0x3) + /* * The genX designation typically refers to the render engine, so render * capability related checks should use IS_GEN, while display and other checks -- GitLab From ab0dfafefd85b0abf61f0efad769803bee8e49fb Mon Sep 17 00:00:00 2001 From: "Hoath, Nicholas" Date: Thu, 5 Feb 2015 10:47:18 +0000 Subject: [PATCH 00173/11651] drm/i915/gen9: Implement WaDisablePartialInstShootdown v2: Dont add WaDisableThreadStallDopClockGating as not SKL WA. (Found by Damien Lespiau) Signed-off-by: Nick Hoath Reviewed-by: Damien Lespiau [danvet: Bikeshed commit message a bit as per Damien's suggestions.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_ringbuffer.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index fbfe65ac590b..b869f1c68753 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -875,6 +875,13 @@ static int chv_init_workarounds(struct intel_engine_cs *ring) static int gen9_init_workarounds(struct intel_engine_cs *ring) { + struct drm_device *dev = ring->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + + /* WaDisablePartialInstShootdown:skl */ + WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, + PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE); + return 0; } -- GitLab From 1de4582f98db7eafd12695139aed7df6a0a0ff3a Mon Sep 17 00:00:00 2001 From: Nick Hoath Date: Thu, 5 Feb 2015 10:47:19 +0000 Subject: [PATCH 00174/11651] drm/i915/gen9: Implement WaDisableDgMirrorFixInHalfSliceChicken5 Move WaDisableDgMirrorFixInHalfSliceChicken5 to gen9_init_workarounds v2: Added stepping check v3: Removed unused register bitmap Signed-off-by: Nick Hoath [danvet: Bikesheds.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 8 -------- drivers/gpu/drm/i915/intel_ringbuffer.c | 10 ++++++++++ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index bebefe79f7ce..2b89aacdda90 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -63,14 +63,6 @@ static void gen9_init_clock_gating(struct drm_device *dev) I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) | GEN8_SDEUNIT_CLOCK_GATE_DISABLE); - /* - * WaDisableDgMirrorFixInHalfSliceChicken5:skl - * This is a pre-production w/a. - */ - I915_WRITE(GEN9_HALF_SLICE_CHICKEN5, - I915_READ(GEN9_HALF_SLICE_CHICKEN5) & - ~GEN9_DG_MIRROR_FIX_ENABLE); - /* Wa4x4STCOptimizationDisable:skl */ I915_WRITE(CACHE_MODE_1, _MASKED_BIT_ENABLE(GEN8_4x4_STC_OPTIMIZATION_DISABLE)); diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index b869f1c68753..248db5157e02 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -882,6 +882,16 @@ static int gen9_init_workarounds(struct intel_engine_cs *ring) WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE); + if (INTEL_REVID(dev) == SKL_REVID_A0) { + /* + * WaDisableDgMirrorFixInHalfSliceChicken5:skl + * This is a pre-production w/a. + */ + I915_WRITE(GEN9_HALF_SLICE_CHICKEN5, + I915_READ(GEN9_HALF_SLICE_CHICKEN5) & + ~GEN9_DG_MIRROR_FIX_ENABLE); + } + return 0; } -- GitLab From 8424171e135ce956ed2473493b061909199572c7 Mon Sep 17 00:00:00 2001 From: Nick Hoath Date: Thu, 5 Feb 2015 10:47:20 +0000 Subject: [PATCH 00175/11651] drm/i915/gen9: h/w w/a: syncing dependencies between camera and graphics This one doesn't have one of these nice cryptic names unfortunately. v2: Added missing register bitmap Signed-off-by: Nick Hoath Reviewed-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 1 + drivers/gpu/drm/i915/intel_ringbuffer.c | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index cd3430f931ed..dab4c1ebbc08 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -6213,6 +6213,7 @@ enum skl_disp_power_wells { #define HALF_SLICE_CHICKEN3 0xe184 #define HSW_SAMPLE_C_PERFORMANCE (1<<9) #define GEN8_CENTROID_PIXEL_OPT_DIS (1<<8) +#define GEN9_DISABLE_OCL_OOB_SUPPRESS_LOGIC (1<<5) #define GEN8_SAMPLER_POWER_BYPASS_DIS (1<<1) /* Audio */ diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 248db5157e02..909430ffa7fe 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -882,6 +882,10 @@ static int gen9_init_workarounds(struct intel_engine_cs *ring) WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE); + /* Syncing dependencies between camera and graphics */ + WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3, + GEN9_DISABLE_OCL_OOB_SUPPRESS_LOGIC); + if (INTEL_REVID(dev) == SKL_REVID_A0) { /* * WaDisableDgMirrorFixInHalfSliceChicken5:skl -- GitLab From 3dcd020a8e3ef5b5f5289a4785b85499adc7626b Mon Sep 17 00:00:00 2001 From: "Hoath, Nicholas" Date: Thu, 5 Feb 2015 10:47:21 +0000 Subject: [PATCH 00176/11651] drm/i915/gen9: Implement WaDisableSDEUnitClockGating v2: Add stepping check for WaDisableSDEUnitClockGating. Signed-off-by: Nick Hoath Reviewed-by: Damien Lespiau [danvet: Rebase.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 2b89aacdda90..874ec9f2023c 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -56,12 +56,14 @@ static void gen9_init_clock_gating(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - /* - * WaDisableSDEUnitClockGating:skl - * This seems to be a pre-production w/a. - */ - I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) | - GEN8_SDEUNIT_CLOCK_GATE_DISABLE); + if (INTEL_REVID(dev) == SKL_REVID_A0) { + /* + * WaDisableSDEUnitClockGating:skl + * This seems to be a pre-production w/a. + */ + I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) | + GEN8_SDEUNIT_CLOCK_GATE_DISABLE); + } /* Wa4x4STCOptimizationDisable:skl */ I915_WRITE(CACHE_MODE_1, -- GitLab From cac23df48af531168625f5510912d227c7ce6b8b Mon Sep 17 00:00:00 2001 From: Nick Hoath Date: Thu, 5 Feb 2015 10:47:22 +0000 Subject: [PATCH 00177/11651] drm/i915/gen9: Implement WaEnableYV12BugFixInHalfSliceChicken7 Move WaEnableYV12BugFixInHalfSliceChicken7 to gen9_init_workarounds v2: Add stepping check. Signed-off-by: Nick Hoath Reviewed-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 3 +++ drivers/gpu/drm/i915/intel_ringbuffer.c | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index dab4c1ebbc08..4ee1964d2c7b 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -6216,6 +6216,9 @@ enum skl_disp_power_wells { #define GEN9_DISABLE_OCL_OOB_SUPPRESS_LOGIC (1<<5) #define GEN8_SAMPLER_POWER_BYPASS_DIS (1<<1) +#define GEN9_HALF_SLICE_CHICKEN7 0xe194 +#define GEN9_ENABLE_YV12_BUGFIX (1<<4) + /* Audio */ #define G4X_AUD_VID_DID (dev_priv->info.display_mmio_offset + 0x62020) #define INTEL_AUDIO_DEVCL 0x808629FB diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 909430ffa7fe..2ab447c711bc 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -896,6 +896,12 @@ static int gen9_init_workarounds(struct intel_engine_cs *ring) ~GEN9_DG_MIRROR_FIX_ENABLE); } + if (INTEL_REVID(dev) >= SKL_REVID_C0) { + /* WaEnableYV12BugFixInHalfSliceChicken7:skl */ + WA_SET_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN7, + GEN9_ENABLE_YV12_BUGFIX); + } + return 0; } -- GitLab From 1840481f536b40289b61c13f9111f30f4019e5ff Mon Sep 17 00:00:00 2001 From: "Hoath, Nicholas" Date: Thu, 5 Feb 2015 10:47:23 +0000 Subject: [PATCH 00178/11651] drm/i915/gen9: Implement Wa4x4STCOptimizationDisable Move Wa4x4STCOptimizationDisable to gen9_init_workarounds v2: rebase Signed-off-by: Nick Hoath Reviewed-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 4 ---- drivers/gpu/drm/i915/intel_ringbuffer.c | 3 +++ 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 874ec9f2023c..3c64810d6853 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -64,10 +64,6 @@ static void gen9_init_clock_gating(struct drm_device *dev) I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) | GEN8_SDEUNIT_CLOCK_GATE_DISABLE); } - - /* Wa4x4STCOptimizationDisable:skl */ - I915_WRITE(CACHE_MODE_1, - _MASKED_BIT_ENABLE(GEN8_4x4_STC_OPTIMIZATION_DISABLE)); } static void i915_pineview_get_mem_freq(struct drm_device *dev) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 2ab447c711bc..e35b341c3cef 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -902,6 +902,9 @@ static int gen9_init_workarounds(struct intel_engine_cs *ring) GEN9_ENABLE_YV12_BUGFIX); } + /* Wa4x4STCOptimizationDisable:skl */ + WA_SET_BIT_MASKED(CACHE_MODE_1, GEN8_4x4_STC_OPTIMIZATION_DISABLE); + return 0; } -- GitLab From 13bea49c8b203b0d2eb789c6f91c03de4e09cf4d Mon Sep 17 00:00:00 2001 From: "Hoath, Nicholas" Date: Thu, 5 Feb 2015 10:47:24 +0000 Subject: [PATCH 00179/11651] drm/i915/gen9: Implement WaForceEnableNonCoherent v2: Don't add WaHdcDisableFetchWhenMasked. Add stepping check for WaForceEnableNonCoherent Signed-off-by: Nick Hoath Reviewed-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_ringbuffer.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index e35b341c3cef..573b80f0c153 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -902,6 +902,17 @@ static int gen9_init_workarounds(struct intel_engine_cs *ring) GEN9_ENABLE_YV12_BUGFIX); } + if (INTEL_REVID(dev) <= SKL_REVID_D0) { + /* + *Use Force Non-Coherent whenever executing a 3D context. This + * is a workaround for a possible hang in the unlikely event + * a TLB invalidation occurs during a PSD flush. + */ + /* WaForceEnableNonCoherent:skl */ + WA_SET_BIT_MASKED(HDC_CHICKEN0, + HDC_FORCE_NON_COHERENT); + } + /* Wa4x4STCOptimizationDisable:skl */ WA_SET_BIT_MASKED(CACHE_MODE_1, GEN8_4x4_STC_OPTIMIZATION_DISABLE); -- GitLab From 3393871441d6fe1fcc8683087649b5139e4f7876 Mon Sep 17 00:00:00 2001 From: Ben Widawsky Date: Thu, 22 Jan 2015 17:01:23 +0000 Subject: [PATCH 00180/11651] drm/i915/trace: Fix offsets for 64b Signed-off-by: Ben Widawsky Signed-off-by: Michel Thierry Reviewed-by: Mika Kuoppala Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_trace.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h index 6058a01b4443..f004d3d89b87 100644 --- a/drivers/gpu/drm/i915/i915_trace.h +++ b/drivers/gpu/drm/i915/i915_trace.h @@ -115,7 +115,7 @@ TRACE_EVENT(i915_vma_bind, TP_STRUCT__entry( __field(struct drm_i915_gem_object *, obj) __field(struct i915_address_space *, vm) - __field(u32, offset) + __field(u64, offset) __field(u32, size) __field(unsigned, flags) ), @@ -128,7 +128,7 @@ TRACE_EVENT(i915_vma_bind, __entry->flags = flags; ), - TP_printk("obj=%p, offset=%08x size=%x%s vm=%p", + TP_printk("obj=%p, offset=%016llx size=%x%s vm=%p", __entry->obj, __entry->offset, __entry->size, __entry->flags & PIN_MAPPABLE ? ", mappable" : "", __entry->vm) @@ -141,7 +141,7 @@ TRACE_EVENT(i915_vma_unbind, TP_STRUCT__entry( __field(struct drm_i915_gem_object *, obj) __field(struct i915_address_space *, vm) - __field(u32, offset) + __field(u64, offset) __field(u32, size) ), @@ -152,7 +152,7 @@ TRACE_EVENT(i915_vma_unbind, __entry->size = vma->node.size; ), - TP_printk("obj=%p, offset=%08x size=%x vm=%p", + TP_printk("obj=%p, offset=%016llx size=%x vm=%p", __entry->obj, __entry->offset, __entry->size, __entry->vm) ); -- GitLab From 766436004bde5855dcf9975bff2bcd606bd908ab Mon Sep 17 00:00:00 2001 From: Ben Widawsky Date: Thu, 22 Jan 2015 17:01:24 +0000 Subject: [PATCH 00181/11651] drm/i915: Rename to GEN8_LEGACY_PDPES In gen8, 32b PPGTT has always had one "pdp" (it doesn't actually have one, but it resembles having one). The #define was confusing as is, and using "PDPE" is a much better description. sed -i 's/GEN8_LEGACY_PDPS/GEN8_LEGACY_PDPES/' drivers/gpu/drm/i915/*.[ch] It also matches the x86 pagetable terminology: PTE = Page Table Entry - pagetable level 1 page PDE = Page Directory Entry - pagetable level 2 page PDPE = Page Directory Pointer Entry - pagetable level 3 page And in the near future (for 48b addressing): PML4E = Page Map Level 4 Entry v2: Expanded information about Page Directory/Table nomenclature. Cc: Daniel Vetter CC: Dave Gordon Signed-off-by: Ben Widawsky Signed-off-by: Michel Thierry (v2) Reviewed-by: Mika Kuoppala Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem_gtt.c | 6 +++--- drivers/gpu/drm/i915/i915_gem_gtt.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 746f77fb57a3..58d54bddfb98 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -375,7 +375,7 @@ static void gen8_ppgtt_insert_entries(struct i915_address_space *vm, pt_vaddr = NULL; for_each_sg_page(pages->sgl, &sg_iter, pages->nents, 0) { - if (WARN_ON(pdpe >= GEN8_LEGACY_PDPS)) + if (WARN_ON(pdpe >= GEN8_LEGACY_PDPES)) break; if (pt_vaddr == NULL) @@ -486,7 +486,7 @@ bail: static int gen8_ppgtt_allocate_page_tables(struct i915_hw_ppgtt *ppgtt, const int max_pdp) { - struct page **pt_pages[GEN8_LEGACY_PDPS]; + struct page **pt_pages[GEN8_LEGACY_PDPES]; int i, ret; for (i = 0; i < max_pdp; i++) { @@ -537,7 +537,7 @@ static int gen8_ppgtt_allocate_page_directories(struct i915_hw_ppgtt *ppgtt, return -ENOMEM; ppgtt->num_pd_pages = 1 << get_order(max_pdp << PAGE_SHIFT); - BUG_ON(ppgtt->num_pd_pages > GEN8_LEGACY_PDPS); + BUG_ON(ppgtt->num_pd_pages > GEN8_LEGACY_PDPES); return 0; } diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h index e377c7d27bd4..9d998ecc5943 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.h +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h @@ -88,7 +88,7 @@ typedef gen8_gtt_pte_t gen8_ppgtt_pde_t; #define GEN8_PDE_MASK 0x1ff #define GEN8_PTE_SHIFT 12 #define GEN8_PTE_MASK 0x1ff -#define GEN8_LEGACY_PDPS 4 +#define GEN8_LEGACY_PDPES 4 #define GEN8_PTES_PER_PAGE (PAGE_SIZE / sizeof(gen8_gtt_pte_t)) #define GEN8_PDES_PER_PAGE (PAGE_SIZE / sizeof(gen8_ppgtt_pde_t)) @@ -273,12 +273,12 @@ struct i915_hw_ppgtt { unsigned num_pd_pages; /* gen8+ */ union { struct page **pt_pages; - struct page **gen8_pt_pages[GEN8_LEGACY_PDPS]; + struct page **gen8_pt_pages[GEN8_LEGACY_PDPES]; }; struct page *pd_pages; union { uint32_t pd_offset; - dma_addr_t pd_dma_addr[GEN8_LEGACY_PDPS]; + dma_addr_t pd_dma_addr[GEN8_LEGACY_PDPES]; }; union { dma_addr_t *pt_dma_addr; -- GitLab From c8c26622ae508f9f7e6be3e99b45ccae4d07efca Mon Sep 17 00:00:00 2001 From: Ben Widawsky Date: Thu, 22 Jan 2015 17:01:25 +0000 Subject: [PATCH 00182/11651] drm/i915: Setup less PPGTT on failed page_directory The current code will both potentially print a WARN, and setup part of the PPGTT structure. Neither of these harm the current code, it is simply for clarity, and to perhaps prevent later bugs, or weird debug messages. Signed-off-by: Ben Widawsky Signed-off-by: Michel Thierry Reviewed-by: Mika Kuoppala Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem_gtt.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 58d54bddfb98..b48b586dc287 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -1032,11 +1032,14 @@ alloc: goto alloc; } + if (ret) + return ret; + if (ppgtt->node.start < dev_priv->gtt.mappable_end) DRM_DEBUG("Forced to use aperture for PDEs\n"); ppgtt->num_pd_entries = GEN6_PPGTT_PD_ENTRIES; - return ret; + return 0; } static int gen6_ppgtt_allocate_page_tables(struct i915_hw_ppgtt *ppgtt) -- GitLab From 17d5538d54c9f9d6e2b44e07d4d577304e22c17a Mon Sep 17 00:00:00 2001 From: Ben Widawsky Date: Thu, 22 Jan 2015 17:01:26 +0000 Subject: [PATCH 00183/11651] drm/i915/gen8: Un-hardcode number of page directories Signed-off-by: Ben Widawsky Signed-off-by: Michel Thierry Reviewed-by: Mika Kuoppala Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem_gtt.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h index 9d998ecc5943..8f7699016711 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.h +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h @@ -282,7 +282,7 @@ struct i915_hw_ppgtt { }; union { dma_addr_t *pt_dma_addr; - dma_addr_t *gen8_pt_dma_addr[4]; + dma_addr_t *gen8_pt_dma_addr[GEN8_LEGACY_PDPES]; }; struct drm_i915_file_private *file_priv; -- GitLab From e3eb3250d84ef97b766312345774367b6a310db8 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Thu, 5 Feb 2015 14:41:52 +0000 Subject: [PATCH 00184/11651] drm: add support for tiled/compressed/etc modifier in addfb2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In DRM/KMS we are lacking a good way to deal with tiled/compressed formats. Especially in the case of dmabuf/prime buffer sharing, where we cannot always rely on under-the-hood flags passed to driver specific gem-create ioctl to pass around these extra flags. The proposal is to add a per-plane format modifier. This allows to, if necessary, use different tiling patters for sub-sampled planes, etc. The format modifiers are added at the end of the ioctl struct, so for legacy userspace it will be zero padded. v1: original v1.5: increase modifier to 64b v2: Incorporate review comments from the big thread, plus a few more. - Add a getcap so that userspace doesn't have to jump through hoops. - Allow modifiers only when a flag is set. That way drivers know when they're dealing with old userspace and need to fish out e.g. tiling from other information. - After rolling out checks for ->modifier to all drivers I've decided that this is way too fragile and needs an explicit opt-in flag. So do that instead. - Add a define (just for documentation really) for the "NONE" modifier. Imo we don't need to add mask #defines since drivers really should only do exact matches against values defined with fourcc_mod_code. - Drop the Samsung tiling modifier on Rob's request since he's not yet sure whether that one is accurate. v3: - Also add a new ->modifier[] array to struct drm_framebuffer and fill it in drm_helper_mode_fill_fb_struct. Requested by Tvrkto Uruslin. - Remove TODO in comment and add code comment that modifiers should be properly documented, requested by Rob. Cc: Rob Clark Cc: Tvrtko Ursulin Cc: Laurent Pinchart Cc: Daniel Stone Cc: Ville Syrjälä Cc: Michel Dänzer Signed-off-by: Rob Clark (v1.5) Reviewed-by: Rob Clark Reviewed-by: Daniel Stone Acked-by: Dave Airlie Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_crtc.c | 14 +++++++++++++- drivers/gpu/drm/drm_crtc_helper.c | 1 + drivers/gpu/drm/drm_ioctl.c | 3 +++ include/drm/drm_crtc.h | 4 ++++ include/uapi/drm/drm.h | 1 + include/uapi/drm/drm_fourcc.h | 32 +++++++++++++++++++++++++++++++ include/uapi/drm/drm_mode.h | 9 +++++++++ 7 files changed, 63 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index ad2934ba0bd2..b15d720eda4c 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -3314,6 +3314,12 @@ static int framebuffer_check(const struct drm_mode_fb_cmd2 *r) DRM_DEBUG_KMS("bad pitch %u for plane %d\n", r->pitches[i], i); return -EINVAL; } + + if (r->modifier[i] && !(r->flags & DRM_MODE_FB_MODIFIERS)) { + DRM_DEBUG_KMS("bad fb modifier %llu for plane %d\n", + r->modifier[i], i); + return -EINVAL; + } } return 0; @@ -3327,7 +3333,7 @@ static struct drm_framebuffer *add_framebuffer_internal(struct drm_device *dev, struct drm_framebuffer *fb; int ret; - if (r->flags & ~DRM_MODE_FB_INTERLACED) { + if (r->flags & ~(DRM_MODE_FB_INTERLACED | DRM_MODE_FB_MODIFIERS)) { DRM_DEBUG_KMS("bad framebuffer flags 0x%08x\n", r->flags); return ERR_PTR(-EINVAL); } @@ -3343,6 +3349,12 @@ static struct drm_framebuffer *add_framebuffer_internal(struct drm_device *dev, return ERR_PTR(-EINVAL); } + if (r->flags & DRM_MODE_FB_MODIFIERS && + !dev->mode_config.allow_fb_modifiers) { + DRM_DEBUG_KMS("driver does not support fb modifiers\n"); + return ERR_PTR(-EINVAL); + } + ret = framebuffer_check(r); if (ret) return ERR_PTR(ret); diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index b1979e7bdc88..3053aab968f9 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -837,6 +837,7 @@ void drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb, for (i = 0; i < 4; i++) { fb->pitches[i] = mode_cmd->pitches[i]; fb->offsets[i] = mode_cmd->offsets[i]; + fb->modifier[i] = mode_cmd->modifier[i]; } drm_fb_get_bpp_depth(mode_cmd->pixel_format, &fb->depth, &fb->bits_per_pixel); diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index 3785d66721f2..a6d773a61c2d 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -321,6 +321,9 @@ static int drm_getcap(struct drm_device *dev, void *data, struct drm_file *file_ else req->value = 64; break; + case DRM_CAP_ADDFB2_MODIFIERS: + req->value = dev->mode_config.allow_fb_modifiers; + break; default: return -EINVAL; } diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 0ebd9286b332..cee54c45eba9 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -202,6 +202,7 @@ struct drm_framebuffer { const struct drm_framebuffer_funcs *funcs; unsigned int pitches[4]; unsigned int offsets[4]; + uint64_t modifier[4]; unsigned int width; unsigned int height; /* depth can be 15 or 16 */ @@ -1152,6 +1153,9 @@ struct drm_mode_config { /* whether async page flip is supported or not */ bool async_page_flip; + /* whether the driver supports fb modifiers */ + bool allow_fb_modifiers; + /* cursor size */ uint32_t cursor_width, cursor_height; }; diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h index 01b2d6d0e355..ff6ef62d084b 100644 --- a/include/uapi/drm/drm.h +++ b/include/uapi/drm/drm.h @@ -630,6 +630,7 @@ struct drm_gem_open { */ #define DRM_CAP_CURSOR_WIDTH 0x8 #define DRM_CAP_CURSOR_HEIGHT 0x9 +#define DRM_CAP_ADDFB2_MODIFIERS 0x10 /** DRM_IOCTL_GET_CAP ioctl argument type */ struct drm_get_cap { diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h index 646ae5f39f42..622109677747 100644 --- a/include/uapi/drm/drm_fourcc.h +++ b/include/uapi/drm/drm_fourcc.h @@ -132,4 +132,36 @@ #define DRM_FORMAT_YUV444 fourcc_code('Y', 'U', '2', '4') /* non-subsampled Cb (1) and Cr (2) planes */ #define DRM_FORMAT_YVU444 fourcc_code('Y', 'V', '2', '4') /* non-subsampled Cr (1) and Cb (2) planes */ + +/* + * Format Modifiers: + * + * Format modifiers describe, typically, a re-ordering or modification + * of the data in a plane of an FB. This can be used to express tiled/ + * swizzled formats, or compression, or a combination of the two. + * + * The upper 8 bits of the format modifier are a vendor-id as assigned + * below. The lower 56 bits are assigned as vendor sees fit. + */ + +/* Vendor Ids: */ +#define DRM_FORMAT_MOD_NONE 0 +#define DRM_FORMAT_MOD_VENDOR_INTEL 0x01 +#define DRM_FORMAT_MOD_VENDOR_AMD 0x02 +#define DRM_FORMAT_MOD_VENDOR_NV 0x03 +#define DRM_FORMAT_MOD_VENDOR_SAMSUNG 0x04 +#define DRM_FORMAT_MOD_VENDOR_QCOM 0x05 +/* add more to the end as needed */ + +#define fourcc_mod_code(vendor, val) \ + ((((u64)DRM_FORMAT_MOD_VENDOR_## vendor) << 56) | (val & 0x00ffffffffffffffL)) + +/* + * Format Modifier tokens: + * + * When adding a new token please document the layout with a code comment, + * similar to the fourcc codes above. drm_fourcc.h is considered the + * authoritative source for all of these. + */ + #endif /* DRM_FOURCC_H */ diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h index ca788e01dab2..dbeba949462a 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -336,6 +336,7 @@ struct drm_mode_fb_cmd { }; #define DRM_MODE_FB_INTERLACED (1<<0) /* for interlaced framebuffers */ +#define DRM_MODE_FB_MODIFIERS (1<<1) /* enables ->modifer[] */ struct drm_mode_fb_cmd2 { __u32 fb_id; @@ -356,10 +357,18 @@ struct drm_mode_fb_cmd2 { * So it would consist of Y as offsets[0] and UV as * offsets[1]. Note that offsets[0] will generally * be 0 (but this is not required). + * + * To accommodate tiled, compressed, etc formats, a per-plane + * modifier can be specified. The default value of zero + * indicates "native" format as specified by the fourcc. + * Vendor specific modifier token. This allows, for example, + * different tiling/swizzling pattern on different planes. + * See discussion above of DRM_FORMAT_MOD_xxx. */ __u32 handles[4]; __u32 pitches[4]; /* pitch for each plane */ __u32 offsets[4]; /* offset of each plane */ + __u64 modifier[4]; /* ie, tiling, compressed (per plane) */ }; #define DRM_MODE_FB_DIRTY_ANNOTATE_COPY 0x01 -- GitLab From e90fff154ecb4517bad4b015bbe2af4699e96dca Mon Sep 17 00:00:00 2001 From: Nick Hoath Date: Fri, 6 Feb 2015 11:30:03 +0000 Subject: [PATCH 00185/11651] drm/i915: gen 9 h/w w/a Fix stepping check Fixed the stepping check on WaDisableDgMirrorFixInHalfSliceChicken5 to be for the correct SOC (Skylake) Signed-off-by: Nick Hoath Reviewed-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_ringbuffer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 573b80f0c153..fb71e33ac4d7 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -886,7 +886,8 @@ static int gen9_init_workarounds(struct intel_engine_cs *ring) WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3, GEN9_DISABLE_OCL_OOB_SUPPRESS_LOGIC); - if (INTEL_REVID(dev) == SKL_REVID_A0) { + if (INTEL_REVID(dev) >= SKL_REVID_A0 && + INTEL_REVID(dev) <= SKL_REVID_B0) { /* * WaDisableDgMirrorFixInHalfSliceChicken5:skl * This is a pre-production w/a. -- GitLab From 203a571b21e7613a7b18bd7340ea1ca75327e7c6 Mon Sep 17 00:00:00 2001 From: Nick Hoath Date: Fri, 6 Feb 2015 11:30:04 +0000 Subject: [PATCH 00186/11651] drm/i915: gen 9 h/w w/a (WaEnableForceRestoreInCtxtDescForVCS) Add: WaEnableForceRestoreInCtxtDescForVCS v2: Add stepping check. v3: Fixed stepping check direction. Cleaned up indentation. Signed-off-by: Nick Hoath Reviewed-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_lrc.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index a94346fee160..091555f34731 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -254,8 +254,10 @@ u32 intel_execlists_ctx_id(struct drm_i915_gem_object *ctx_obj) return lrca >> 12; } -static uint64_t execlists_ctx_descriptor(struct drm_i915_gem_object *ctx_obj) +static uint64_t execlists_ctx_descriptor(struct intel_engine_cs *ring, + struct drm_i915_gem_object *ctx_obj) { + struct drm_device *dev = ring->dev; uint64_t desc; uint64_t lrca = i915_gem_obj_ggtt_offset(ctx_obj); @@ -272,6 +274,13 @@ static uint64_t execlists_ctx_descriptor(struct drm_i915_gem_object *ctx_obj) * signalling between Command Streamers */ /* desc |= GEN8_CTX_FORCE_RESTORE; */ + /* WaEnableForceRestoreInCtxtDescForVCS:skl */ + if (IS_GEN9(dev) && + INTEL_REVID(dev) <= SKL_REVID_B0 && + (ring->id == BCS || ring->id == VCS || + ring->id == VECS || ring->id == VCS2)) + desc |= GEN8_CTX_FORCE_RESTORE; + return desc; } @@ -286,13 +295,13 @@ static void execlists_elsp_write(struct intel_engine_cs *ring, /* XXX: You must always write both descriptors in the order below. */ if (ctx_obj1) - temp = execlists_ctx_descriptor(ctx_obj1); + temp = execlists_ctx_descriptor(ring, ctx_obj1); else temp = 0; desc[1] = (u32)(temp >> 32); desc[0] = (u32)temp; - temp = execlists_ctx_descriptor(ctx_obj0); + temp = execlists_ctx_descriptor(ring, ctx_obj0); desc[3] = (u32)(temp >> 32); desc[2] = (u32)temp; -- GitLab From 7cc6574600fdd45eb828a884da4eec6daed786f0 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Mon, 9 Feb 2015 14:46:27 -0200 Subject: [PATCH 00187/11651] drm/i915: don't try to find crtcs for FBC if it's disabled .. because it would be a waste of time, so move the place where the check is done. Also, with this we won't risk printing "more than one pipe active, disabling compression" or "no output, disabling" when FBC is actually disabled. This patch also represents a small behavior difference when using i915.powersave=0: it is now exactly the same as i915.enable_fbc=0 on this part of the code. V2: Rebase. Reviewed-by: Rodrigo Vivi (v1) Signed-off-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_fbc.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index b572bb6ebcff..c9a470f9d880 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -507,10 +507,16 @@ void intel_fbc_update(struct drm_device *dev) return; } - if (!i915.powersave) { + if (i915.enable_fbc < 0) { + if (set_no_fbc_reason(dev_priv, FBC_CHIP_DEFAULT)) + DRM_DEBUG_KMS("disabled per chip default\n"); + goto out_disable; + } + + if (!i915.enable_fbc || !i915.powersave) { if (set_no_fbc_reason(dev_priv, FBC_MODULE_PARAM)) DRM_DEBUG_KMS("fbc disabled per module param\n"); - return; + goto out_disable; } /* @@ -545,16 +551,6 @@ void intel_fbc_update(struct drm_device *dev) obj = intel_fb_obj(fb); adjusted_mode = &intel_crtc->config->base.adjusted_mode; - if (i915.enable_fbc < 0) { - if (set_no_fbc_reason(dev_priv, FBC_CHIP_DEFAULT)) - DRM_DEBUG_KMS("disabled per chip default\n"); - goto out_disable; - } - if (!i915.enable_fbc) { - if (set_no_fbc_reason(dev_priv, FBC_MODULE_PARAM)) - DRM_DEBUG_KMS("fbc disabled per module param\n"); - goto out_disable; - } if ((adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) || (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)) { if (set_no_fbc_reason(dev_priv, FBC_UNSUPPORTED_MODE)) -- GitLab From 104618b3364963d1630297f2b8e0a232c51dc85b Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Mon, 9 Feb 2015 14:46:28 -0200 Subject: [PATCH 00188/11651] drm/i915: don't keep reassigning FBC_UNSUPPORTED This may save a few picoseconds on !HAS_FBC platforms. And it also satisfies my OCD. Reviewed-by: Rodrigo Vivi Signed-off-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_fbc.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index c9a470f9d880..ce7774d1b675 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -502,10 +502,8 @@ void intel_fbc_update(struct drm_device *dev) const struct drm_display_mode *adjusted_mode; unsigned int max_width, max_height; - if (!HAS_FBC(dev)) { - set_no_fbc_reason(dev_priv, FBC_UNSUPPORTED); + if (!HAS_FBC(dev)) return; - } if (i915.enable_fbc < 0) { if (set_no_fbc_reason(dev_priv, FBC_CHIP_DEFAULT)) @@ -670,6 +668,7 @@ void intel_fbc_init(struct drm_i915_private *dev_priv) { if (!HAS_FBC(dev_priv)) { dev_priv->fbc.enabled = false; + dev_priv->fbc.no_fbc_reason = FBC_UNSUPPORTED; return; } -- GitLab From e35fef211bab1a69da1b392c3ece906e287ed6e4 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Mon, 9 Feb 2015 14:46:29 -0200 Subject: [PATCH 00189/11651] drm/i915: change dev_priv->fbc.plane to dev_priv->fbc.crtc Since the mapping from CRTCs to planes is fixed, looking at the CRTC is essentially the same as looking at the plane. Also, the next patches wil start using the frontbuffer_bits macros, and they take the pipe as the parameter instead of the plane, and this could differ on gens 2 and 3. Another nice thing is that we don't risk accidentally initializing things to PLANE_A if we don't set the value before it is used for the first time. But this shouldn't be a problem with the current code. V2: Rebase. Reviewed-by: Rodrigo Vivi (v1) Signed-off-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 2 +- drivers/gpu/drm/i915/intel_display.c | 5 ++--- drivers/gpu/drm/i915/intel_fbc.c | 6 +++--- drivers/gpu/drm/i915/intel_sprite.c | 2 +- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 217845951b7f..3da3dc527315 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -775,7 +775,7 @@ struct i915_fbc { unsigned long uncompressed_size; unsigned threshold; unsigned int fb_id; - enum plane plane; + struct intel_crtc *crtc; int y; struct drm_mm_node compressed_fb; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 3fe95982be93..2655b63d65e9 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4277,11 +4277,10 @@ static void intel_crtc_disable_planes(struct drm_crtc *crtc) struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int pipe = intel_crtc->pipe; - int plane = intel_crtc->plane; intel_crtc_wait_for_pending_flips(crtc); - if (dev_priv->fbc.plane == plane) + if (dev_priv->fbc.crtc == intel_crtc) intel_fbc_disable(dev); hsw_disable_ips(intel_crtc); @@ -11932,7 +11931,7 @@ intel_check_primary_plane(struct drm_plane *plane, */ if (intel_crtc->primary_enabled && INTEL_INFO(dev)->gen <= 4 && !IS_G4X(dev) && - dev_priv->fbc.plane == intel_crtc->plane && + dev_priv->fbc.crtc == intel_crtc && state->base.rotation != BIT(DRM_ROTATE_0)) { intel_crtc->atomic.disable_fbc = true; } diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index ce7774d1b675..7341e87221ae 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -369,7 +369,7 @@ static void intel_fbc_work_fn(struct work_struct *__work) if (work->crtc->primary->fb == work->fb) { dev_priv->display.enable_fbc(work->crtc); - dev_priv->fbc.plane = to_intel_crtc(work->crtc)->plane; + dev_priv->fbc.crtc = to_intel_crtc(work->crtc); dev_priv->fbc.fb_id = work->crtc->primary->fb->base.id; dev_priv->fbc.y = work->crtc->y; } @@ -460,7 +460,7 @@ void intel_fbc_disable(struct drm_device *dev) return; dev_priv->display.disable_fbc(dev); - dev_priv->fbc.plane = -1; + dev_priv->fbc.crtc = NULL; } static bool set_no_fbc_reason(struct drm_i915_private *dev_priv, @@ -612,7 +612,7 @@ void intel_fbc_update(struct drm_device *dev) * cannot be unpinned (and have its GTT offset and fence revoked) * without first being decoupled from the scanout and FBC disabled. */ - if (dev_priv->fbc.plane == intel_crtc->plane && + if (dev_priv->fbc.crtc == intel_crtc && dev_priv->fbc.fb_id == fb->base.id && dev_priv->fbc.y == crtc->y) return; diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 0a52c44ad03d..5afc89e00a2a 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -993,7 +993,7 @@ intel_pre_disable_primary(struct drm_crtc *crtc) struct intel_crtc *intel_crtc = to_intel_crtc(crtc); mutex_lock(&dev->struct_mutex); - if (dev_priv->fbc.plane == intel_crtc->plane) + if (dev_priv->fbc.crtc == intel_crtc) intel_fbc_disable(dev); mutex_unlock(&dev->struct_mutex); -- GitLab From c57e3551225977c9b5ed3b81a2be2a0b8f6f4503 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Mon, 9 Feb 2015 19:33:05 +0000 Subject: [PATCH 00190/11651] drm/i915: Support not having an init clock gating function defined When enabling new platforms, we may not have any W/A to apply, especially that, now, a bunch of them have to be done from the ring. Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 3c64810d6853..a3b979deeeb1 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -6386,7 +6386,8 @@ void intel_init_clock_gating(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - dev_priv->display.init_clock_gating(dev); + if (dev_priv->display.init_clock_gating) + dev_priv->display.init_clock_gating(dev); } void intel_suspend_hw(struct drm_device *dev) -- GitLab From 35cb6f3b4ee352bff28d2541909e30f193788b52 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Tue, 10 Feb 2015 10:31:00 +0000 Subject: [PATCH 00191/11651] drm/i915/bdw: Implement WaForceContextSaveRestoreNonCoherent MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit v2: Reorder defines (Ben) v3: More bikesheds, this time re-ordering comments! (Chris) Reviewed-by: Ben Widawsky Reviewed-by: Ville Syrjälä Signed-off-by: Damien Lespiau [danvet: Resolve conflict.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 5 +++-- drivers/gpu/drm/i915/intel_ringbuffer.c | 8 +++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 4ee1964d2c7b..f13e4e4f29e2 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -5260,9 +5260,10 @@ enum skl_disp_power_wells { /* GEN8 chicken */ #define HDC_CHICKEN0 0x7300 -#define HDC_FORCE_NON_COHERENT (1<<4) -#define HDC_DONOT_FETCH_MEM_WHEN_MASKED (1<<11) #define HDC_FENCE_DEST_SLM_DISABLE (1<<14) +#define HDC_DONOT_FETCH_MEM_WHEN_MASKED (1<<11) +#define HDC_FORCE_CONTEXT_SAVE_RESTORE_NON_COHERENT (1<<5) +#define HDC_FORCE_NON_COHERENT (1<<4) /* WaCatErrorRejectionIssue */ #define GEN7_SQ_CHICKEN_MBCUNIT_CONFIG 0x9030 diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index fb71e33ac4d7..d62681748b87 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -788,12 +788,14 @@ static int bdw_init_workarounds(struct intel_engine_cs *ring) * workaround for for a possible hang in the unlikely event a TLB * invalidation occurs during a PSD flush. */ - /* WaForceEnableNonCoherent:bdw */ - /* WaHdcDisableFetchWhenMasked:bdw */ - /* WaDisableFenceDestinationToSLM:bdw (GT3 pre-production) */ WA_SET_BIT_MASKED(HDC_CHICKEN0, + /* WaForceEnableNonCoherent:bdw */ HDC_FORCE_NON_COHERENT | + /* WaForceContextSaveRestoreNonCoherent:bdw */ + HDC_FORCE_CONTEXT_SAVE_RESTORE_NON_COHERENT | + /* WaHdcDisableFetchWhenMasked:bdw */ HDC_DONOT_FETCH_MEM_WHEN_MASKED | + /* WaDisableFenceDestinationToSLM:bdw (pre-prod) */ (IS_BDW_GT3(dev) ? HDC_FENCE_DEST_SLM_DISABLE : 0)); /* From the Haswell PRM, Command Reference: Registers, CACHE_MODE_0: -- GitLab From 93b81f5102a7cd270a305c2741b17c8d44bb0629 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Tue, 10 Feb 2015 17:16:05 +0000 Subject: [PATCH 00192/11651] drm/i915: Add tiled framebuffer modifiers To be used from the new addfb2 extension. v2: - Drop Intel-specific untiled modfier. - Move to drm_fourcc.h. - Document layouts a bit and denote them as platform-specific and not useable for cross-driver sharing. - Add Y-tiling for completeness. - Drop special docstring markers to avoid confusing kerneldoc. v3: Give Y-tiling a unique idea, noticed by Tvrtko. Signed-off-by: Tvrtko Ursulin (v1) Cc: Tvrtko Ursulin Reviewed-by: Tvrtko Ursulin Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 1 + include/uapi/drm/drm_fourcc.h | 31 +++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 3da3dc527315..99b25928df2f 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -31,6 +31,7 @@ #define _I915_DRV_H_ #include +#include #include "i915_reg.h" #include "intel_bios.h" diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h index 622109677747..4837c3d2319a 100644 --- a/include/uapi/drm/drm_fourcc.h +++ b/include/uapi/drm/drm_fourcc.h @@ -164,4 +164,35 @@ * authoritative source for all of these. */ +/* Intel framebuffer modifiers */ + +/* + * Intel X-tiling layout + * + * This is a tiled layout using 4Kb tiles (except on gen2 where the tiles 2Kb) + * in row-major layout. Within the tile bytes are laid out row-major, with + * a platform-dependent stride. On top of that the memory can apply + * platform-depending swizzling of some higher address bits into bit6. + * + * This format is highly platforms specific and not useful for cross-driver + * sharing. It exists since on a given platform it does uniquely identify the + * layout in a simple way for i915-specific userspace. + */ +#define I915_FORMAT_MOD_X_TILED fourcc_mod_code(INTEL, 1) + +/* + * Intel Y-tiling layout + * + * This is a tiled layout using 4Kb tiles (except on gen2 where the tiles 2Kb) + * in row-major layout. Within the tile bytes are laid out in OWORD (16 bytes) + * chunks column-major, with a platform-dependent height. On top of that the + * memory can apply platform-depending swizzling of some higher address bits + * into bit6. + * + * This format is highly platforms specific and not useful for cross-driver + * sharing. It exists since on a given platform it does uniquely identify the + * layout in a simple way for i915-specific userspace. + */ +#define I915_FORMAT_MOD_Y_TILED fourcc_mod_code(INTEL, 2) + #endif /* DRM_FOURCC_H */ -- GitLab From 2a80eada326fe83d2a1eaaa4c36831d95628770f Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 10 Feb 2015 17:16:06 +0000 Subject: [PATCH 00193/11651] drm/i915: Add fb format modifier support Currently we don't support anything but X tiled. And for an easier transition it makes a lot of sense to just keep requiring that X tiled is properly fenced. Which means we need to do absolutely nothing in old code to support fb modifiers, yay! v2: Fix the Y tiling check, noticed by Tvrtko. v3: Catch Y-tiled fb for legacy addfb again (Tvrtko) and explain why we want X tiling to match in the comment. Cc: Tvrtko Ursulin Reviewed-by: Tvrtko Ursulin Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 2655b63d65e9..da827568671e 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -12706,7 +12706,24 @@ static int intel_framebuffer_init(struct drm_device *dev, WARN_ON(!mutex_is_locked(&dev->struct_mutex)); - if (obj->tiling_mode == I915_TILING_Y) { + if (mode_cmd->flags & DRM_MODE_FB_MODIFIERS) { + /* Enforce that fb modifier and tiling mode match, but only for + * X-tiled. This is needed for FBC. */ + if (!!(obj->tiling_mode == I915_TILING_X) != + !!(mode_cmd->modifier[0] == I915_FORMAT_MOD_X_TILED)) { + DRM_DEBUG("tiling_mode doesn't match fb modifier\n"); + return -EINVAL; + } + } else { + if (obj->tiling_mode == I915_TILING_X) + mode_cmd->modifier[0] = I915_FORMAT_MOD_X_TILED; + else if (obj->tiling_mode == I915_TILING_Y) { + DRM_DEBUG("No Y tiling for legacy addfb\n"); + return -EINVAL; + } + } + + if (mode_cmd->modifier[0] == I915_FORMAT_MOD_Y_TILED) { DRM_DEBUG("hardware does not support tiling Y\n"); return -EINVAL; } @@ -12720,12 +12737,12 @@ static int intel_framebuffer_init(struct drm_device *dev, if (INTEL_INFO(dev)->gen >= 5 && !IS_VALLEYVIEW(dev)) { pitch_limit = 32*1024; } else if (INTEL_INFO(dev)->gen >= 4) { - if (obj->tiling_mode) + if (mode_cmd->modifier[0] == I915_FORMAT_MOD_X_TILED) pitch_limit = 16*1024; else pitch_limit = 32*1024; } else if (INTEL_INFO(dev)->gen >= 3) { - if (obj->tiling_mode) + if (mode_cmd->modifier[0] == I915_FORMAT_MOD_X_TILED) pitch_limit = 8*1024; else pitch_limit = 16*1024; @@ -12735,12 +12752,13 @@ static int intel_framebuffer_init(struct drm_device *dev, if (mode_cmd->pitches[0] > pitch_limit) { DRM_DEBUG("%s pitch (%d) must be at less than %d\n", - obj->tiling_mode ? "tiled" : "linear", + mode_cmd->modifier[0] == I915_FORMAT_MOD_X_TILED ? + "tiled" : "linear", mode_cmd->pitches[0], pitch_limit); return -EINVAL; } - if (obj->tiling_mode != I915_TILING_NONE && + if (mode_cmd->modifier[0] == I915_FORMAT_MOD_X_TILED && mode_cmd->pitches[0] != obj->stride) { DRM_DEBUG("pitch (%d) must match tiling stride (%d)\n", mode_cmd->pitches[0], obj->stride); -- GitLab From c1ca506d173bdbadffce95e1f67ac86a08e9db03 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Tue, 10 Feb 2015 17:16:07 +0000 Subject: [PATCH 00194/11651] drm/i915: Show frame buffer modifier in debug info Signed-off-by: Tvrtko Ursulin Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_debugfs.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 9af17fb4f8dc..661527cb00ea 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1766,11 +1766,12 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data) ifbdev = dev_priv->fbdev; fb = to_intel_framebuffer(ifbdev->helper.fb); - seq_printf(m, "fbcon size: %d x %d, depth %d, %d bpp, refcount %d, obj ", + seq_printf(m, "fbcon size: %d x %d, depth %d, %d bpp, modifier 0x%llx, refcount %d, obj ", fb->base.width, fb->base.height, fb->base.depth, fb->base.bits_per_pixel, + fb->base.modifier[0], atomic_read(&fb->base.refcount.refcount)); describe_obj(m, fb->obj); seq_putc(m, '\n'); @@ -1781,11 +1782,12 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data) if (ifbdev && &fb->base == ifbdev->helper.fb) continue; - seq_printf(m, "user size: %d x %d, depth %d, %d bpp, refcount %d, obj ", + seq_printf(m, "user size: %d x %d, depth %d, %d bpp, modifier 0x%llx, refcount %d, obj ", fb->base.width, fb->base.height, fb->base.depth, fb->base.bits_per_pixel, + fb->base.modifier[0], atomic_read(&fb->base.refcount.refcount)); describe_obj(m, fb->obj); seq_putc(m, '\n'); -- GitLab From 18c5247e1e96d657334dabd8ab611001f16a62b0 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 10 Feb 2015 17:16:09 +0000 Subject: [PATCH 00195/11651] drm/i915: Set up fb format modifier for initial plane config No functional changes yet since intel_framebuffer_init would have fixed this up for us. But this is prep work to be able to handle new tiling layouts in the initial plane config code. Follow-up patches will start to make use of this and switch over to fb modifiers where needed. Reviewed-by: Tvrtko Ursulin Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index da827568671e..85274906f686 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2390,6 +2390,8 @@ intel_alloc_plane_obj(struct intel_crtc *crtc, mode_cmd.width = fb->width; mode_cmd.height = fb->height; mode_cmd.pitches[0] = fb->pitches[0]; + mode_cmd.modifier[0] = fb->modifier[0]; + mode_cmd.flags = DRM_MODE_FB_MODIFIERS; mutex_lock(&dev->struct_mutex); @@ -6624,9 +6626,12 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc, fb = &intel_fb->base; - if (INTEL_INFO(dev)->gen >= 4) - if (val & DISPPLANE_TILED) + if (INTEL_INFO(dev)->gen >= 4) { + if (val & DISPPLANE_TILED) { plane_config->tiling = I915_TILING_X; + fb->modifier[0] = I915_FORMAT_MOD_X_TILED; + } + } pixel_format = val & DISPPLANE_PIXFORMAT_MASK; fourcc = i9xx_format_to_fourcc(pixel_format); @@ -7658,8 +7663,10 @@ skylake_get_initial_plane_config(struct intel_crtc *crtc, if (!(val & PLANE_CTL_ENABLE)) goto error; - if (val & PLANE_CTL_TILED_MASK) + if (val & PLANE_CTL_TILED_MASK) { plane_config->tiling = I915_TILING_X; + fb->modifier[0] = I915_FORMAT_MOD_X_TILED; + } pixel_format = val & PLANE_CTL_FORMAT_MASK; fourcc = skl_format_to_fourcc(pixel_format, @@ -7757,9 +7764,12 @@ ironlake_get_initial_plane_config(struct intel_crtc *crtc, fb = &intel_fb->base; - if (INTEL_INFO(dev)->gen >= 4) - if (val & DISPPLANE_TILED) + if (INTEL_INFO(dev)->gen >= 4) { + if (val & DISPPLANE_TILED) { plane_config->tiling = I915_TILING_X; + fb->modifier[0] = I915_FORMAT_MOD_X_TILED; + } + } pixel_format = val & DISPPLANE_PIXFORMAT_MASK; fourcc = i9xx_format_to_fourcc(pixel_format); -- GitLab From 091df6cbf248811150552d51dacb9dc1fe6b0a23 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 10 Feb 2015 17:16:10 +0000 Subject: [PATCH 00196/11651] drm/i915: Switch intel_fb_align_height to fb format modifiers With this we can treat the fb format modifier completely independently from the fencing mode in obj->tiling_mode in the initial plane code. Which means new tiling modes without any gtt fence are now fully support in the core i915 driver code. v2: Also add pixel_format while at it, we need this to compute the height for the new tiling formats. Reviewed-by: Tvrtko Ursulin Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 20 ++++++++++++++------ drivers/gpu/drm/i915/intel_drv.h | 3 ++- drivers/gpu/drm/i915/intel_fbdev.c | 3 ++- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 85274906f686..a2bb905c2372 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2190,11 +2190,15 @@ static bool need_vtd_wa(struct drm_device *dev) } int -intel_fb_align_height(struct drm_device *dev, int height, unsigned int tiling) +intel_fb_align_height(struct drm_device *dev, int height, + uint32_t pixel_format, + uint64_t fb_format_modifier) { int tile_height; - tile_height = tiling ? (IS_GEN2(dev) ? 16 : 8) : 1; + tile_height = fb_format_modifier == I915_FORMAT_MOD_X_TILED ? + (IS_GEN2(dev) ? 16 : 8) : 1; + return ALIGN(height, tile_height); } @@ -6657,7 +6661,8 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc, fb->pitches[0] = val & 0xffffffc0; aligned_height = intel_fb_align_height(dev, fb->height, - plane_config->tiling); + fb->pixel_format, + fb->modifier[0]); plane_config->size = PAGE_ALIGN(fb->pitches[0] * aligned_height); @@ -7699,7 +7704,8 @@ skylake_get_initial_plane_config(struct intel_crtc *crtc, fb->pitches[0] = (val & 0x3ff) * stride_mult; aligned_height = intel_fb_align_height(dev, fb->height, - plane_config->tiling); + fb->pixel_format, + fb->modifier[0]); plane_config->size = ALIGN(fb->pitches[0] * aligned_height, PAGE_SIZE); @@ -7795,7 +7801,8 @@ ironlake_get_initial_plane_config(struct intel_crtc *crtc, fb->pitches[0] = val & 0xffffffc0; aligned_height = intel_fb_align_height(dev, fb->height, - plane_config->tiling); + fb->pixel_format, + fb->modifier[0]); plane_config->size = PAGE_ALIGN(fb->pitches[0] * aligned_height); @@ -12823,7 +12830,8 @@ static int intel_framebuffer_init(struct drm_device *dev, return -EINVAL; aligned_height = intel_fb_align_height(dev, mode_cmd->height, - obj->tiling_mode); + mode_cmd->pixel_format, + mode_cmd->modifier[0]); /* FIXME drm helper for size checks (especially planar formats)? */ if (obj->base.size < aligned_height * mode_cmd->pitches[0]) return -EINVAL; diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 76b3c2043954..b9598ba6901c 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -879,7 +879,8 @@ void intel_frontbuffer_flip(struct drm_device *dev, } int intel_fb_align_height(struct drm_device *dev, int height, - unsigned int tiling); + uint32_t pixel_format, + uint64_t fb_format_modifier); void intel_fb_obj_flush(struct drm_i915_gem_object *obj, bool retire); diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c index 3001a8674611..234a699b8219 100644 --- a/drivers/gpu/drm/i915/intel_fbdev.c +++ b/drivers/gpu/drm/i915/intel_fbdev.c @@ -594,7 +594,8 @@ static bool intel_fbdev_init_bios(struct drm_device *dev, cur_size = intel_crtc->config->base.adjusted_mode.crtc_vdisplay; cur_size = intel_fb_align_height(dev, cur_size, - plane_config->tiling); + fb->base.pixel_format, + fb->base.modifier[0]); cur_size *= fb->base.pitches[0]; DRM_DEBUG_KMS("pipe %c area: %dx%d, bpp: %d, size: %d\n", pipe_name(intel_crtc->pipe), -- GitLab From 30af77c4c80f98c72b27cb497aa660ef9474e6cf Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 10 Feb 2015 17:16:11 +0000 Subject: [PATCH 00197/11651] drm/i915: Use fb format modifiers in skylake_update_primary_plane Just a little demo really. We probably need to introduce skl specific functions for a lot of the format validation stuff, or at least helpers. Specifically I think intel_framebuffer_init and intel_fb_align_height must be adjusted to have an i915_ and a skl_ variant. And only shared code should be converted to fb modifiers, platform code (like the plane config readout can keep on using old tiling_mode defines to avoid some churn). Cc: Tvrtko Ursulin Reviewed-by: Tvrtko Ursulin Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index a2bb905c2372..a954263663a9 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2779,11 +2779,11 @@ static void skylake_update_primary_plane(struct drm_crtc *crtc, * The stride is either expressed as a multiple of 64 bytes chunks for * linear buffers or in number of tiles for tiled buffers. */ - switch (obj->tiling_mode) { - case I915_TILING_NONE: + switch (fb->modifier[0]) { + case DRM_FORMAT_MOD_NONE: stride = fb->pitches[0] >> 6; break; - case I915_TILING_X: + case I915_FORMAT_MOD_X_TILED: plane_ctl |= PLANE_CTL_TILED_X; stride = fb->pitches[0] >> 9; break; -- GitLab From ba343e029e028a1a7e93c11969789ac70d609f9d Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Tue, 10 Feb 2015 17:16:12 +0000 Subject: [PATCH 00198/11651] drm/i915/skl: CS flips are not supported with execlists And skl only works in execlist mode, not in legacy ring submission. Therefore remove dead code. Signed-off-by: Tvrtko Ursulin Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 72 ++-------------------------- 1 file changed, 4 insertions(+), 68 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index a954263663a9..4b01876b760f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -9631,69 +9631,6 @@ static int intel_queue_mmio_flip(struct drm_device *dev, return 0; } -static int intel_gen9_queue_flip(struct drm_device *dev, - struct drm_crtc *crtc, - struct drm_framebuffer *fb, - struct drm_i915_gem_object *obj, - struct intel_engine_cs *ring, - uint32_t flags) -{ - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - uint32_t plane = 0, stride; - int ret; - - switch(intel_crtc->pipe) { - case PIPE_A: - plane = MI_DISPLAY_FLIP_SKL_PLANE_1_A; - break; - case PIPE_B: - plane = MI_DISPLAY_FLIP_SKL_PLANE_1_B; - break; - case PIPE_C: - plane = MI_DISPLAY_FLIP_SKL_PLANE_1_C; - break; - default: - WARN_ONCE(1, "unknown plane in flip command\n"); - return -ENODEV; - } - - switch (obj->tiling_mode) { - case I915_TILING_NONE: - stride = fb->pitches[0] >> 6; - break; - case I915_TILING_X: - stride = fb->pitches[0] >> 9; - break; - default: - WARN_ONCE(1, "unknown tiling in flip command\n"); - return -ENODEV; - } - - ret = intel_ring_begin(ring, 10); - if (ret) - return ret; - - intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1)); - intel_ring_emit(ring, DERRMR); - intel_ring_emit(ring, ~(DERRMR_PIPEA_PRI_FLIP_DONE | - DERRMR_PIPEB_PRI_FLIP_DONE | - DERRMR_PIPEC_PRI_FLIP_DONE)); - intel_ring_emit(ring, MI_STORE_REGISTER_MEM_GEN8(1) | - MI_SRM_LRM_GLOBAL_GTT); - intel_ring_emit(ring, DERRMR); - intel_ring_emit(ring, ring->scratch.gtt_offset + 256); - intel_ring_emit(ring, 0); - - intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | plane); - intel_ring_emit(ring, stride << 6 | obj->tiling_mode); - intel_ring_emit(ring, intel_crtc->unpin_work->gtt_offset); - - intel_mark_page_flip_active(intel_crtc); - __intel_ring_advance(ring); - - return 0; -} - static int intel_default_queue_flip(struct drm_device *dev, struct drm_crtc *crtc, struct drm_framebuffer *fb, @@ -12993,9 +12930,6 @@ static void intel_init_display(struct drm_device *dev) valleyview_modeset_global_resources; } - /* Default just returns -ENODEV to indicate unsupported */ - dev_priv->display.queue_flip = intel_default_queue_flip; - switch (INTEL_INFO(dev)->gen) { case 2: dev_priv->display.queue_flip = intel_gen2_queue_flip; @@ -13018,8 +12952,10 @@ static void intel_init_display(struct drm_device *dev) dev_priv->display.queue_flip = intel_gen7_queue_flip; break; case 9: - dev_priv->display.queue_flip = intel_gen9_queue_flip; - break; + /* Drop through - unsupported since execlist only. */ + default: + /* Default just returns -ENODEV to indicate unsupported */ + dev_priv->display.queue_flip = intel_default_queue_flip; } intel_panel_init_backlight_funcs(dev); -- GitLab From 66ebf56714ed0b475afc5fb91c7e7230cf86c2a6 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Tue, 10 Feb 2015 17:16:13 +0000 Subject: [PATCH 00199/11651] drm/i915/skl: Use fb modifiers for sprites While at it just outright remove the tiling check in intel_check_sprite_plane because it's impossible: We only allow untiled and X-tiled. This essentially reverts commit 94c6419ed8f45e6682d766672b9ceb54867d3d2d Author: Damien Lespiau Date: Mon Oct 29 15:14:51 2012 +0000 drm/i915: Error out when trying to set a y-tiled as a sprite Signed-off-by: Tvrtko Ursulin [danvet: Drop the hunk in check_sprite, it's impossible.] Cc: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_sprite.c | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 5afc89e00a2a..f2d408dd7c15 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -245,11 +245,11 @@ skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc, BUG(); } - switch (obj->tiling_mode) { - case I915_TILING_NONE: + switch (fb->modifier[0]) { + case DRM_FORMAT_MOD_NONE: stride = fb->pitches[0] >> 6; break; - case I915_TILING_X: + case I915_FORMAT_MOD_X_TILED: plane_ctl |= PLANE_CTL_TILED_X; stride = fb->pitches[0] >> 9; break; @@ -1076,7 +1076,6 @@ intel_check_sprite_plane(struct drm_plane *plane, struct intel_crtc *intel_crtc = to_intel_crtc(state->base.crtc); struct intel_plane *intel_plane = to_intel_plane(plane); struct drm_framebuffer *fb = state->base.fb; - struct drm_i915_gem_object *obj = intel_fb_obj(fb); int crtc_x, crtc_y; unsigned int crtc_w, crtc_h; uint32_t src_x, src_y, src_w, src_h; @@ -1106,16 +1105,6 @@ intel_check_sprite_plane(struct drm_plane *plane, return -EINVAL; } - /* Sprite planes can be linear or x-tiled surfaces */ - switch (obj->tiling_mode) { - case I915_TILING_NONE: - case I915_TILING_X: - break; - default: - DRM_DEBUG_KMS("Unsupported tiling mode\n"); - return -EINVAL; - } - /* * FIXME the following code does a bunch of fuzzy adjustments to the * coordinates and sizes. We probably need some way to decide whether -- GitLab From 6a418fcd84d655e97333627c4247a318e99b0ecf Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Tue, 10 Feb 2015 17:16:14 +0000 Subject: [PATCH 00200/11651] drm/i915: Use fb modifiers in intel_check_cursor_plane Also drop the mutex since with universal planes there is always a proper framebuffer around which wraps the underlying bo. Which means tiling is locked down. This was different in the old code which directly took gem handles. The looking though was always cargo-cult since races where not prevented in any way. v2: Unconditionally enforce untiled, because cursors are always untiled. The check for physical or gtt cursor is irrelevant. Also clarify the commit message a bit Signed-off-by: Tvrtko Ursulin (v1) Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 4b01876b760f..ddf890767461 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -12173,13 +12173,10 @@ intel_check_cursor_plane(struct drm_plane *plane, if (fb == crtc->cursor->fb) return 0; - /* we only need to pin inside GTT if cursor is non-phy */ - mutex_lock(&dev->struct_mutex); - if (!INTEL_INFO(dev)->cursor_needs_physical && obj->tiling_mode) { + if (fb->modifier[0] != DRM_FORMAT_MOD_NONE) { DRM_DEBUG_KMS("cursor cannot be tiled\n"); ret = -EINVAL; } - mutex_unlock(&dev->struct_mutex); finish: if (intel_crtc->active) { -- GitLab From 7b911adc924e0ca817ce6454ca3df922dc5d47fa Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Tue, 10 Feb 2015 17:16:15 +0000 Subject: [PATCH 00201/11651] drm/i915: Use fb modifiers in intel_pin_and_fence_fb_obj And at the same time replace BUG() with a warning and handle it gracefuly. Signed-off-by: Tvrtko Ursulin Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index ddf890767461..e0e9348442e7 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2215,8 +2215,8 @@ intel_pin_and_fence_fb_obj(struct drm_plane *plane, WARN_ON(!mutex_is_locked(&dev->struct_mutex)); - switch (obj->tiling_mode) { - case I915_TILING_NONE: + switch (fb->modifier[0]) { + case DRM_FORMAT_MOD_NONE: if (INTEL_INFO(dev)->gen >= 9) alignment = 256 * 1024; else if (IS_BROADWATER(dev) || IS_CRESTLINE(dev)) @@ -2226,7 +2226,7 @@ intel_pin_and_fence_fb_obj(struct drm_plane *plane, else alignment = 64 * 1024; break; - case I915_TILING_X: + case I915_FORMAT_MOD_X_TILED: if (INTEL_INFO(dev)->gen >= 9) alignment = 256 * 1024; else { @@ -2234,11 +2234,12 @@ intel_pin_and_fence_fb_obj(struct drm_plane *plane, alignment = 0; } break; - case I915_TILING_Y: + case I915_FORMAT_MOD_Y_TILED: WARN(1, "Y tiled bo slipped through, driver bug!\n"); return -EINVAL; default: - BUG(); + MISSING_CASE(fb->modifier[0]); + return -EINVAL; } /* Note that the w/a also requires 64 PTE of padding following the -- GitLab From 25bab385a0f8e76a32a5550d696f6a17540041c5 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Tue, 10 Feb 2015 17:16:16 +0000 Subject: [PATCH 00202/11651] drm/i915: Announce support for framebuffer modifiers Let the DRM core know we can handle it. v2: Change to boolean true. (Daniel Vetter) Signed-off-by: Tvrtko Ursulin Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e0e9348442e7..d08f8eeaf225 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -13169,6 +13169,8 @@ void intel_modeset_init(struct drm_device *dev) dev->mode_config.preferred_depth = 24; dev->mode_config.prefer_shadow = 1; + dev->mode_config.allow_fb_modifiers = true; + dev->mode_config.funcs = &intel_mode_funcs; intel_init_quirks(dev); -- GitLab From 5baa22c59f4e841eb45f8d1299043fb58370e48b Mon Sep 17 00:00:00 2001 From: Zhi Wang Date: Tue, 10 Feb 2015 17:11:36 +0800 Subject: [PATCH 00203/11651] drm/i915: Introduce bit definitions of CTXT_SR_CTRL register. This patch introduces 2 bit definitions of context save/restore control register. Signed-off-by: Zhi Wang Suggested-by: Dave Gordon Cc: Dave Gordon Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_lrc.c | 3 ++- drivers/gpu/drm/i915/intel_lrc.h | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 091555f34731..c4db49ef4d19 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1666,7 +1666,8 @@ populate_lr_context(struct intel_context *ctx, struct drm_i915_gem_object *ctx_o reg_state[CTX_LRI_HEADER_0] |= MI_LRI_FORCE_POSTED; reg_state[CTX_CONTEXT_CONTROL] = RING_CONTEXT_CONTROL(ring); reg_state[CTX_CONTEXT_CONTROL+1] = - _MASKED_BIT_ENABLE((1<<3) | MI_RESTORE_INHIBIT); + _MASKED_BIT_ENABLE(CTX_CTRL_INHIBIT_SYN_CTX_SWITCH | + CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT); reg_state[CTX_RING_HEAD] = RING_HEAD(ring->mmio_base); reg_state[CTX_RING_HEAD+1] = 0; reg_state[CTX_RING_TAIL] = RING_TAIL(ring->mmio_base); diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h index 6f2d7da594f6..ced191f73b0e 100644 --- a/drivers/gpu/drm/i915/intel_lrc.h +++ b/drivers/gpu/drm/i915/intel_lrc.h @@ -30,6 +30,8 @@ #define RING_ELSP(ring) ((ring)->mmio_base+0x230) #define RING_EXECLIST_STATUS(ring) ((ring)->mmio_base+0x234) #define RING_CONTEXT_CONTROL(ring) ((ring)->mmio_base+0x244) +#define CTX_CTRL_INHIBIT_SYN_CTX_SWITCH (1 << 3) +#define CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT (1 << 0) #define RING_CONTEXT_STATUS_BUF(ring) ((ring)->mmio_base+0x370) #define RING_CONTEXT_STATUS_PTR(ring) ((ring)->mmio_base+0x3a0) -- GitLab From cf9d2890da19d9544d655554da907049e8226d14 Mon Sep 17 00:00:00 2001 From: Yu Zhang Date: Tue, 10 Feb 2015 19:05:47 +0800 Subject: [PATCH 00204/11651] drm/i915: Introduce a PV INFO page structure for Intel GVT-g. Introduce a PV INFO structure, to facilitate the Intel GVT-g technology, which is a GPU virtualization solution with mediated pass-through. This page contains the shared information between i915 driver and the host emulator. For now, this structure utilizes an area of 4K bytes on HSW GPU's unused MMIO space. Future hardware will have the reserved window architecturally defined, and layout of the page will be added in future BSpec. The i915 driver load routine detects if it is running in a VM by reading the contents of this PV INFO page. Thereafter a flag, vgpu.active is set, and intel_vgpu_active() is used by checking this flag to conclude if GPU is virtualized with Intel GVT-g. By now, intel_vgpu_active() will return true, only when the driver is running as a guest in the Intel GVT-g enhanced environment on HSW platform. v2: take Chris' comments: - call the i915_check_vgpu() in intel_uncore_init() - sanitize i915_check_vgpu() by adding BUILD_BUG_ON() and debug info take Daniel's comments: - put the definition of PV INFO into a new header - i915_vgt_if.h other changes: - access mmio regs by readq/readw in i915_check_vgpu() v3: take Daniel's comments: - move the i915/vgt interfaces into a new i915_vgpu.c - update makefile - add kerneldoc to functions which are non-static - add a DOC: section describing some of the high-level design - update drm docbook other changes: - rename i915_vgt_if.h to i915_vgpu.h v4: take Tvrtko's comments: - fix a typo in commit message - add debug message when vgt version mismatches - rename low_gmadr/high_gmadr to mappable/non-mappable in PV INFO structure Signed-off-by: Yu Zhang Signed-off-by: Jike Song Signed-off-by: Eddie Dong Reviewed-by: Tvrtko Ursulin Signed-off-by: Daniel Vetter --- Documentation/DocBook/drm.tmpl | 5 ++ drivers/gpu/drm/i915/Makefile | 3 + drivers/gpu/drm/i915/i915_drv.h | 10 ++++ drivers/gpu/drm/i915/i915_vgpu.c | 86 +++++++++++++++++++++++++++++ drivers/gpu/drm/i915/i915_vgpu.h | 85 ++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_uncore.c | 3 + 6 files changed, 192 insertions(+) create mode 100644 drivers/gpu/drm/i915/i915_vgpu.c create mode 100644 drivers/gpu/drm/i915/i915_vgpu.h diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 03f1985a4bd1..249f0c9ede40 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -3979,6 +3979,11 @@ int num_ioctls; !Fdrivers/gpu/drm/i915/i915_irq.c intel_runtime_pm_disable_interrupts !Fdrivers/gpu/drm/i915/i915_irq.c intel_runtime_pm_enable_interrupts + + Intel GVT-g Guest Support(vGPU) +!Pdrivers/gpu/drm/i915/i915_vgpu.c Intel GVT-g guest support +!Idrivers/gpu/drm/i915/i915_vgpu.c + Display Hardware Handling diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index f01922591679..f025e7fae253 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -83,6 +83,9 @@ i915-y += dvo_ch7017.o \ intel_sdvo.o \ intel_tv.o +# virtual gpu code +i915-y += i915_vgpu.o + # legacy horrors i915-y += i915_dma.o \ i915_ums.o diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 99b25928df2f..23ae26c42352 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1641,6 +1641,10 @@ struct i915_workarounds { u32 count; }; +struct i915_virtual_gpu { + bool active; +}; + struct drm_i915_private { struct drm_device *dev; struct kmem_cache *slab; @@ -1653,6 +1657,8 @@ struct drm_i915_private { struct intel_uncore uncore; + struct i915_virtual_gpu vgpu; + struct intel_gmbus gmbus[GMBUS_NUM_PORTS]; @@ -2585,6 +2591,10 @@ void intel_uncore_forcewake_get(struct drm_i915_private *dev_priv, void intel_uncore_forcewake_put(struct drm_i915_private *dev_priv, enum forcewake_domains domains); void assert_forcewakes_inactive(struct drm_i915_private *dev_priv); +static inline bool intel_vgpu_active(struct drm_device *dev) +{ + return to_i915(dev)->vgpu.active; +} void i915_enable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe, diff --git a/drivers/gpu/drm/i915/i915_vgpu.c b/drivers/gpu/drm/i915/i915_vgpu.c new file mode 100644 index 000000000000..995a6003ed78 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_vgpu.c @@ -0,0 +1,86 @@ +/* + * Copyright(c) 2011-2015 Intel Corporation. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "intel_drv.h" +#include "i915_vgpu.h" + +/** + * DOC: Intel GVT-g guest support + * + * Intel GVT-g is a graphics virtualization technology which shares the + * GPU among multiple virtual machines on a time-sharing basis. Each + * virtual machine is presented a virtual GPU (vGPU), which has equivalent + * features as the underlying physical GPU (pGPU), so i915 driver can run + * seamlessly in a virtual machine. This file provides vGPU specific + * optimizations when running in a virtual machine, to reduce the complexity + * of vGPU emulation and to improve the overall performance. + * + * A primary function introduced here is so-called "address space ballooning" + * technique. Intel GVT-g partitions global graphics memory among multiple VMs, + * so each VM can directly access a portion of the memory without hypervisor's + * intervention, e.g. filling textures or queuing commands. However with the + * partitioning an unmodified i915 driver would assume a smaller graphics + * memory starting from address ZERO, then requires vGPU emulation module to + * translate the graphics address between 'guest view' and 'host view', for + * all registers and command opcodes which contain a graphics memory address. + * To reduce the complexity, Intel GVT-g introduces "address space ballooning", + * by telling the exact partitioning knowledge to each guest i915 driver, which + * then reserves and prevents non-allocated portions from allocation. Thus vGPU + * emulation module only needs to scan and validate graphics addresses without + * complexity of address translation. + * + */ + +/** + * i915_check_vgpu - detect virtual GPU + * @dev: drm device * + * + * This function is called at the initialization stage, to detect whether + * running on a vGPU. + */ +void i915_check_vgpu(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = to_i915(dev); + uint64_t magic; + uint32_t version; + + BUILD_BUG_ON(sizeof(struct vgt_if) != VGT_PVINFO_SIZE); + + if (!IS_HASWELL(dev)) + return; + + magic = readq(dev_priv->regs + vgtif_reg(magic)); + if (magic != VGT_MAGIC) + return; + + version = INTEL_VGT_IF_VERSION_ENCODE( + readw(dev_priv->regs + vgtif_reg(version_major)), + readw(dev_priv->regs + vgtif_reg(version_minor))); + if (version != INTEL_VGT_IF_VERSION) { + DRM_INFO("VGT interface version mismatch!\n"); + return; + } + + dev_priv->vgpu.active = true; + DRM_INFO("Virtual GPU for Intel GVT-g detected.\n"); +} diff --git a/drivers/gpu/drm/i915/i915_vgpu.h b/drivers/gpu/drm/i915/i915_vgpu.h new file mode 100644 index 000000000000..aa72e146d6c8 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_vgpu.h @@ -0,0 +1,85 @@ +/* + * Copyright(c) 2011-2015 Intel Corporation. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef _I915_VGPU_H_ +#define _I915_VGPU_H_ + +/* The MMIO offset of the shared info between guest and host emulator */ +#define VGT_PVINFO_PAGE 0x78000 +#define VGT_PVINFO_SIZE 0x1000 + +/* + * The following structure pages are defined in GEN MMIO space + * for virtualization. (One page for now) + */ +#define VGT_MAGIC 0x4776544776544776 /* 'vGTvGTvG' */ +#define VGT_VERSION_MAJOR 1 +#define VGT_VERSION_MINOR 0 + +#define INTEL_VGT_IF_VERSION_ENCODE(major, minor) ((major) << 16 | (minor)) +#define INTEL_VGT_IF_VERSION \ + INTEL_VGT_IF_VERSION_ENCODE(VGT_VERSION_MAJOR, VGT_VERSION_MINOR) + +struct vgt_if { + uint64_t magic; /* VGT_MAGIC */ + uint16_t version_major; + uint16_t version_minor; + uint32_t vgt_id; /* ID of vGT instance */ + uint32_t rsv1[12]; /* pad to offset 0x40 */ + /* + * Data structure to describe the balooning info of resources. + * Each VM can only have one portion of continuous area for now. + * (May support scattered resource in future) + * (starting from offset 0x40) + */ + struct { + /* Aperture register balooning */ + struct { + uint32_t base; + uint32_t size; + } mappable_gmadr; /* aperture */ + /* GMADR register balooning */ + struct { + uint32_t base; + uint32_t size; + } nonmappable_gmadr; /* non aperture */ + /* allowed fence registers */ + uint32_t fence_num; + uint32_t rsv2[3]; + } avail_rs; /* available/assigned resource */ + uint32_t rsv3[0x200 - 24]; /* pad to half page */ + /* + * The bottom half page is for response from Gfx driver to hypervisor. + * Set to reserved fields temporarily by now. + */ + uint32_t rsv4; + uint32_t display_ready; /* ready for display owner switch */ + uint32_t rsv5[0x200 - 2]; /* pad to one page */ +} __packed; + +#define vgtif_reg(x) \ + (VGT_PVINFO_PAGE + (long)&((struct vgt_if *)NULL)->x) + +extern void i915_check_vgpu(struct drm_device *dev); + +#endif /* _I915_VGPU_H_ */ diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 76b60a3538b2..b381c16b97e1 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -23,6 +23,7 @@ #include "i915_drv.h" #include "intel_drv.h" +#include "i915_vgpu.h" #include @@ -1075,6 +1076,8 @@ void intel_uncore_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; + i915_check_vgpu(dev); + intel_uncore_ellc_detect(dev); intel_uncore_fw_domains_init(dev); __intel_uncore_early_sanitize(dev, false); -- GitLab From 5dda8fa356587832e5373498d8b973d66735762d Mon Sep 17 00:00:00 2001 From: Yu Zhang Date: Tue, 10 Feb 2015 19:05:48 +0800 Subject: [PATCH 00205/11651] drm/i915: Adds graphic address space ballooning logic With Intel GVT-g, the global graphic memory space is partitioned by multiple vGPU instances in different VMs. The ballooning code is called in i915_gem_setup_global_gtt(), utilizing the drm mm allocator APIs to mark the graphic address space which are partitioned out to other vGPUs as reserved. With ballooning, host side does not need to translate a grahpic address from guest view to host view. By now, current implementation only support the static ballooning, but in the future, with more cooperation from guest driver, the same interfaces can be extended to grow/shrink the guest graphic memory dynamically. v2: take Chris and Daniel's comments: - no guard page between different VMs - use drm_mm_reserve_node() to do the reservation for ballooning, instead of the previous drm_mm_insert_node_in_range_generic() v3: take Daniel's comments: - move ballooning functions into i915_vgpu.c - add kerneldoc to ballooning functions v4: take Tvrtko's comments: - more accurate comments and commit message Signed-off-by: Yu Zhang Signed-off-by: Jike Song Signed-off-by: Zhi Wang Signed-off-by: Eddie Dong Reviewed-by: Tvrtko Ursulin Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem_gtt.c | 17 ++- drivers/gpu/drm/i915/i915_vgpu.c | 178 ++++++++++++++++++++++++++++ drivers/gpu/drm/i915/i915_vgpu.h | 2 + 3 files changed, 194 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index b48b586dc287..057f905b25b0 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -27,6 +27,7 @@ #include #include #include "i915_drv.h" +#include "i915_vgpu.h" #include "i915_trace.h" #include "intel_drv.h" @@ -1756,6 +1757,16 @@ static int i915_gem_setup_global_gtt(struct drm_device *dev, /* Subtract the guard page ... */ drm_mm_init(&ggtt_vm->mm, start, end - start - PAGE_SIZE); + + dev_priv->gtt.base.start = start; + dev_priv->gtt.base.total = end - start; + + if (intel_vgpu_active(dev)) { + ret = intel_vgt_balloon(dev); + if (ret) + return ret; + } + if (!HAS_LLC(dev)) dev_priv->gtt.base.mm.color_adjust = i915_gtt_color_adjust; @@ -1775,9 +1786,6 @@ static int i915_gem_setup_global_gtt(struct drm_device *dev, vma->bound |= GLOBAL_BIND; } - dev_priv->gtt.base.start = start; - dev_priv->gtt.base.total = end - start; - /* Clear any non-preallocated blocks */ drm_mm_for_each_hole(entry, &ggtt_vm->mm, hole_start, hole_end) { DRM_DEBUG_KMS("clearing unused GTT space: [%lx, %lx]\n", @@ -1829,6 +1837,9 @@ void i915_global_gtt_cleanup(struct drm_device *dev) } if (drm_mm_initialized(&vm->mm)) { + if (intel_vgpu_active(dev)) + intel_vgt_deballoon(); + drm_mm_takedown(&vm->mm); list_del(&vm->global_link); } diff --git a/drivers/gpu/drm/i915/i915_vgpu.c b/drivers/gpu/drm/i915/i915_vgpu.c index 995a6003ed78..5eee75bff170 100644 --- a/drivers/gpu/drm/i915/i915_vgpu.c +++ b/drivers/gpu/drm/i915/i915_vgpu.c @@ -84,3 +84,181 @@ void i915_check_vgpu(struct drm_device *dev) dev_priv->vgpu.active = true; DRM_INFO("Virtual GPU for Intel GVT-g detected.\n"); } + +struct _balloon_info_ { + /* + * There are up to 2 regions per mappable/unmappable graphic + * memory that might be ballooned. Here, index 0/1 is for mappable + * graphic memory, 2/3 for unmappable graphic memory. + */ + struct drm_mm_node space[4]; +}; + +static struct _balloon_info_ bl_info; + +/** + * intel_vgt_deballoon - deballoon reserved graphics address trunks + * + * This function is called to deallocate the ballooned-out graphic memory, when + * driver is unloaded or when ballooning fails. + */ +void intel_vgt_deballoon(void) +{ + int i; + + DRM_DEBUG("VGT deballoon.\n"); + + for (i = 0; i < 4; i++) { + if (bl_info.space[i].allocated) + drm_mm_remove_node(&bl_info.space[i]); + } + + memset(&bl_info, 0, sizeof(bl_info)); +} + +static int vgt_balloon_space(struct drm_mm *mm, + struct drm_mm_node *node, + unsigned long start, unsigned long end) +{ + unsigned long size = end - start; + + if (start == end) + return -EINVAL; + + DRM_INFO("balloon space: range [ 0x%lx - 0x%lx ] %lu KiB.\n", + start, end, size / 1024); + + node->start = start; + node->size = size; + + return drm_mm_reserve_node(mm, node); +} + +/** + * intel_vgt_balloon - balloon out reserved graphics address trunks + * @dev: drm device + * + * This function is called at the initialization stage, to balloon out the + * graphic address space allocated to other vGPUs, by marking these spaces as + * reserved. The ballooning related knowledge(starting address and size of + * the mappable/unmappable graphic memory) is described in the vgt_if structure + * in a reserved mmio range. + * + * To give an example, the drawing below depicts one typical scenario after + * ballooning. Here the vGPU1 has 2 pieces of graphic address spaces ballooned + * out each for the mappable and the non-mappable part. From the vGPU1 point of + * view, the total size is the same as the physical one, with the start address + * of its graphic space being zero. Yet there are some portions ballooned out( + * the shadow part, which are marked as reserved by drm allocator). From the + * host point of view, the graphic address space is partitioned by multiple + * vGPUs in different VMs. + * + * vGPU1 view Host view + * 0 ------> +-----------+ +-----------+ + * ^ |///////////| | vGPU3 | + * | |///////////| +-----------+ + * | |///////////| | vGPU2 | + * | +-----------+ +-----------+ + * mappable GM | available | ==> | vGPU1 | + * | +-----------+ +-----------+ + * | |///////////| | | + * v |///////////| | Host | + * +=======+===========+ +===========+ + * ^ |///////////| | vGPU3 | + * | |///////////| +-----------+ + * | |///////////| | vGPU2 | + * | +-----------+ +-----------+ + * unmappable GM | available | ==> | vGPU1 | + * | +-----------+ +-----------+ + * | |///////////| | | + * | |///////////| | Host | + * v |///////////| | | + * total GM size ------> +-----------+ +-----------+ + * + * Returns: + * zero on success, non-zero if configuration invalid or ballooning failed + */ +int intel_vgt_balloon(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = to_i915(dev); + struct i915_address_space *ggtt_vm = &dev_priv->gtt.base; + unsigned long ggtt_vm_end = ggtt_vm->start + ggtt_vm->total; + + unsigned long mappable_base, mappable_size, mappable_end; + unsigned long unmappable_base, unmappable_size, unmappable_end; + int ret; + + mappable_base = I915_READ(vgtif_reg(avail_rs.mappable_gmadr.base)); + mappable_size = I915_READ(vgtif_reg(avail_rs.mappable_gmadr.size)); + unmappable_base = I915_READ(vgtif_reg(avail_rs.nonmappable_gmadr.base)); + unmappable_size = I915_READ(vgtif_reg(avail_rs.nonmappable_gmadr.size)); + + mappable_end = mappable_base + mappable_size; + unmappable_end = unmappable_base + unmappable_size; + + DRM_INFO("VGT ballooning configuration:\n"); + DRM_INFO("Mappable graphic memory: base 0x%lx size %ldKiB\n", + mappable_base, mappable_size / 1024); + DRM_INFO("Unmappable graphic memory: base 0x%lx size %ldKiB\n", + unmappable_base, unmappable_size / 1024); + + if (mappable_base < ggtt_vm->start || + mappable_end > dev_priv->gtt.mappable_end || + unmappable_base < dev_priv->gtt.mappable_end || + unmappable_end > ggtt_vm_end) { + DRM_ERROR("Invalid ballooning configuration!\n"); + return -EINVAL; + } + + /* Unmappable graphic memory ballooning */ + if (unmappable_base > dev_priv->gtt.mappable_end) { + ret = vgt_balloon_space(&ggtt_vm->mm, + &bl_info.space[2], + dev_priv->gtt.mappable_end, + unmappable_base); + + if (ret) + goto err; + } + + /* + * No need to partition out the last physical page, + * because it is reserved to the guard page. + */ + if (unmappable_end < ggtt_vm_end - PAGE_SIZE) { + ret = vgt_balloon_space(&ggtt_vm->mm, + &bl_info.space[3], + unmappable_end, + ggtt_vm_end - PAGE_SIZE); + if (ret) + goto err; + } + + /* Mappable graphic memory ballooning */ + if (mappable_base > ggtt_vm->start) { + ret = vgt_balloon_space(&ggtt_vm->mm, + &bl_info.space[0], + ggtt_vm->start, mappable_base); + + if (ret) + goto err; + } + + if (mappable_end < dev_priv->gtt.mappable_end) { + ret = vgt_balloon_space(&ggtt_vm->mm, + &bl_info.space[1], + mappable_end, + dev_priv->gtt.mappable_end); + + if (ret) + goto err; + } + + DRM_INFO("VGT balloon successfully\n"); + return 0; + +err: + DRM_ERROR("VGT balloon fail\n"); + intel_vgt_deballoon(); + return ret; +} diff --git a/drivers/gpu/drm/i915/i915_vgpu.h b/drivers/gpu/drm/i915/i915_vgpu.h index aa72e146d6c8..3ed01a7ac48e 100644 --- a/drivers/gpu/drm/i915/i915_vgpu.h +++ b/drivers/gpu/drm/i915/i915_vgpu.h @@ -81,5 +81,7 @@ struct vgt_if { (VGT_PVINFO_PAGE + (long)&((struct vgt_if *)NULL)->x) extern void i915_check_vgpu(struct drm_device *dev); +extern int intel_vgt_balloon(struct drm_device *dev); +extern void intel_vgt_deballoon(void); #endif /* _I915_VGPU_H_ */ -- GitLab From eb82289a1f2373917aae02ff41a247741040f16b Mon Sep 17 00:00:00 2001 From: Yu Zhang Date: Tue, 10 Feb 2015 19:05:49 +0800 Subject: [PATCH 00206/11651] drm/i915: Partition the fence registers for vGPU in i915 driver With Intel GVT-g, the fence registers are partitioned by multiple vGPU instances in different VMs. Routine i915_gem_load() is modified to reset the num_fence_regs, when the driver detects it's running in a VM. Accesses to the fence registers from vGPU will be trapped and remapped by the host side. And the allocated fence number is provided in PV INFO page structure. By now, the value of fence number is fixed, but in the future we can relax this limitation, to allocate the fence registers dynamically from host side. Signed-off-by: Yu Zhang Signed-off-by: Jike Song Signed-off-by: Eddie Dong Reviewed-by: Tvrtko Ursulin Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 36f1093e3c63..323706cefedf 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -29,6 +29,7 @@ #include #include #include "i915_drv.h" +#include "i915_vgpu.h" #include "i915_trace.h" #include "intel_drv.h" #include @@ -4987,6 +4988,10 @@ i915_gem_load(struct drm_device *dev) else dev_priv->num_fence_regs = 8; + if (intel_vgpu_active(dev)) + dev_priv->num_fence_regs = + I915_READ(vgtif_reg(avail_rs.fence_num)); + /* Initialize fence registers to zero */ INIT_LIST_HEAD(&dev_priv->mm.fence_list); i915_gem_restore_fences(dev); -- GitLab From bd49234b6aa37fd32069e506c6997171afd326be Mon Sep 17 00:00:00 2001 From: Yu Zhang Date: Tue, 10 Feb 2015 19:05:50 +0800 Subject: [PATCH 00207/11651] drm/i915: Disable framebuffer compression for i915 driver in VM Framebuffer compression is disabled when driver detects it's running in a Intel GVT-g enlightened VM, because FBC is not emulated and there is no stolen memory for a vGPU. v2: take Chris' comments: - move the code into intel_update_fbc() v4: take Tvrtko's comments: - rebase the code into intel_fbc_update() Signed-off-by: Yu Zhang Signed-off-by: Jike Song Signed-off-by: Zhiyuan Lv Reviewed-by: Tvrtko Ursulin Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_fbc.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index 7341e87221ae..ee65731baaf7 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -505,6 +505,10 @@ void intel_fbc_update(struct drm_device *dev) if (!HAS_FBC(dev)) return; + /* disable framebuffer compression in vGPU */ + if (intel_vgpu_active(dev)) + i915.enable_fbc = 0; + if (i915.enable_fbc < 0) { if (set_no_fbc_reason(dev_priv, FBC_CHIP_DEFAULT)) DRM_DEBUG_KMS("disabled per chip default\n"); -- GitLab From e21fd552ff068da4bcb1a0108e2933db52685f2c Mon Sep 17 00:00:00 2001 From: Yu Zhang Date: Tue, 10 Feb 2015 19:05:51 +0800 Subject: [PATCH 00208/11651] drm/i915: Add the display switch logic for vGPU in i915 driver Display switch logic is added to notify the host side that current vGPU have a valid surface to show. It does so by writing the display_ready field in PV INFO page, and then will be handled in the host side. This is useful to avoid trickiness when the VM's framebuffer is being accessed in the middle of VM modesetting, e.g. compositing the framebuffer in the host side. v2: - move the notification code outside the 'else' in load sequence - remove the notification code in intel_crtc_set_config() v4: - code rebase, no need to define another dev_priv - use #define instead of enum for display readiness Signed-off-by: Yu Zhang Signed-off-by: Jike Song Signed-off-by: Zhiyuan Lv Reviewed-by: Tvrtko Ursulin Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_dma.c | 8 ++++++++ drivers/gpu/drm/i915/i915_vgpu.h | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 1a46787129e7..5804aa5f9df0 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -36,6 +36,7 @@ #include "intel_drv.h" #include #include "i915_drv.h" +#include "i915_vgpu.h" #include "i915_trace.h" #include #include @@ -842,6 +843,13 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) } } + /* + * Notify a valid surface after modesetting, + * when running inside a VM. + */ + if (intel_vgpu_active(dev)) + I915_WRITE(vgtif_reg(display_ready), VGT_DRV_DISPLAY_READY); + i915_setup_sysfs(dev); if (INTEL_INFO(dev)->num_pipes) { diff --git a/drivers/gpu/drm/i915/i915_vgpu.h b/drivers/gpu/drm/i915/i915_vgpu.h index 3ed01a7ac48e..0db9ccf32605 100644 --- a/drivers/gpu/drm/i915/i915_vgpu.h +++ b/drivers/gpu/drm/i915/i915_vgpu.h @@ -80,6 +80,10 @@ struct vgt_if { #define vgtif_reg(x) \ (VGT_PVINFO_PAGE + (long)&((struct vgt_if *)NULL)->x) +/* vGPU display status to be used by the host side */ +#define VGT_DRV_DISPLAY_NOT_READY 0 +#define VGT_DRV_DISPLAY_READY 1 /* ready for display switch */ + extern void i915_check_vgpu(struct drm_device *dev); extern int intel_vgt_balloon(struct drm_device *dev); extern void intel_vgt_deballoon(void); -- GitLab From f61018b1fe00238407724ea7a502003c3f71d9a0 Mon Sep 17 00:00:00 2001 From: Yu Zhang Date: Tue, 10 Feb 2015 19:05:52 +0800 Subject: [PATCH 00209/11651] drm/i915: Disable power management for i915 driver in VM With Intel GVT-g, GPU power management is controlled by host driver, so there is no need to provide virtualized GPU PM support. In the future it might be useful to gather VM input for freq boost, but now let's disable it simply. v2: take Chris' comments: - do not special case this to gen6+ Signed-off-by: Yu Zhang Signed-off-by: Jike Song Reviewed-by: Tvrtko Ursulin Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index a3b979deeeb1..9b9433f1e1c7 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -5623,6 +5623,10 @@ void intel_enable_gt_powersave(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; + /* Powersaving is controlled by the host when inside a VM */ + if (intel_vgpu_active(dev)) + return; + if (IS_IRONLAKE_M(dev)) { mutex_lock(&dev->struct_mutex); ironlake_enable_drps(dev); -- GitLab From 3be0bf5acca61daa9800219088b0b95712ced520 Mon Sep 17 00:00:00 2001 From: Yu Zhang Date: Tue, 10 Feb 2015 19:05:53 +0800 Subject: [PATCH 00210/11651] drm/i915: Create vGPU specific MMIO operations to reduce traps In the virtualized environment, forcewake operations are not necessary for the driver, because mmio accesses will be trapped and emulated by the host side, and real forcewake operations are also done in the host. New mmio access handlers are added to directly call the __raw_i915_read/write, therefore will reduce many traps and increase the overall performance for drivers running in the VM with Intel GVT-g enhancement. v2: take Chris' comments: - register the mmio hooks in intel_uncore_init() v3: take Daniel's comments: - use macros to assign mmio write functions for vGPU v4: take Tvrtko's comments: - also use mmio hooks for read operations Signed-off-by: Yu Zhang Signed-off-by: Jike Song Signed-off-by: Kevin Tian k Reviewed-by: Tvrtko Ursulin Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_uncore.c | 31 +++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index b381c16b97e1..db864dff810e 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -640,6 +640,14 @@ static inline void __force_wake_get(struct drm_i915_private *dev_priv, dev_priv->uncore.funcs.force_wake_get(dev_priv, fw_domains); } +#define __vgpu_read(x) \ +static u##x \ +vgpu_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \ + GEN6_READ_HEADER(x); \ + val = __raw_i915_read##x(dev_priv, reg); \ + GEN6_READ_FOOTER; \ +} + #define __gen6_read(x) \ static u##x \ gen6_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \ @@ -703,6 +711,10 @@ gen9_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \ GEN6_READ_FOOTER; \ } +__vgpu_read(8) +__vgpu_read(16) +__vgpu_read(32) +__vgpu_read(64) __gen9_read(8) __gen9_read(16) __gen9_read(32) @@ -724,6 +736,7 @@ __gen6_read(64) #undef __chv_read #undef __vlv_read #undef __gen6_read +#undef __vgpu_read #undef GEN6_READ_FOOTER #undef GEN6_READ_HEADER @@ -807,6 +820,14 @@ hsw_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) GEN6_WRITE_FOOTER; \ } +#define __vgpu_write(x) \ +static void vgpu_write##x(struct drm_i915_private *dev_priv, \ + off_t reg, u##x val, bool trace) { \ + GEN6_WRITE_HEADER; \ + __raw_i915_write##x(dev_priv, reg, val); \ + GEN6_WRITE_FOOTER; \ +} + static const u32 gen8_shadowed_regs[] = { FORCEWAKE_MT, GEN6_RPNSWREQ, @@ -924,12 +945,17 @@ __gen6_write(8) __gen6_write(16) __gen6_write(32) __gen6_write(64) +__vgpu_write(8) +__vgpu_write(16) +__vgpu_write(32) +__vgpu_write(64) #undef __gen9_write #undef __chv_write #undef __gen8_write #undef __hsw_write #undef __gen6_write +#undef __vgpu_write #undef GEN6_WRITE_FOOTER #undef GEN6_WRITE_HEADER @@ -1126,6 +1152,11 @@ void intel_uncore_init(struct drm_device *dev) break; } + if (intel_vgpu_active(dev)) { + ASSIGN_WRITE_MMIO_VFUNCS(vgpu); + ASSIGN_READ_MMIO_VFUNCS(vgpu); + } + i915_check_and_clear_faults(dev); } #undef ASSIGN_WRITE_MMIO_VFUNCS -- GitLab From 71ba2d6432040352e174f5366fb5e5ac3b908e50 Mon Sep 17 00:00:00 2001 From: Yu Zhang Date: Tue, 10 Feb 2015 19:05:54 +0800 Subject: [PATCH 00211/11651] drm/i915: Support alias ppgtt in VM if ppgtt is enabled The current Intel GVT-g only supports alias ppgtt. And the emulation is done in the host by first trapping PP_DIR_BASE mmio accesses. Updating PP_DIR_BASE by using instructions such as MI_LOAD_REGISTER_IMM are hard to detect and are not supported in current code. Therefore this patch also adds a new callback routine - vgpu_mm_switch() to set the PP_DIR_BASE by mmio writes. v2: take Chris' comments: - move the code into sanitize_enable_ppgtt() v4: take Tvrtko's comments: - fix the parenthesis alignment warning Signed-off-by: Yu Zhang Signed-off-by: Jike Song Reviewed-by: Tvrtko Ursulin Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem_gtt.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 057f905b25b0..e54b2a0ca921 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -104,6 +104,9 @@ static int sanitize_enable_ppgtt(struct drm_device *dev, int enable_ppgtt) has_aliasing_ppgtt = INTEL_INFO(dev)->gen >= 6; has_full_ppgtt = INTEL_INFO(dev)->gen >= 7; + if (intel_vgpu_active(dev)) + has_full_ppgtt = false; /* emulation is too hard */ + /* * We don't allow disabling PPGTT for gen9+ as it's a requirement for * execlists, the sole mechanism available to submit work. @@ -798,6 +801,16 @@ static int hsw_mm_switch(struct i915_hw_ppgtt *ppgtt, return 0; } +static int vgpu_mm_switch(struct i915_hw_ppgtt *ppgtt, + struct intel_engine_cs *ring) +{ + struct drm_i915_private *dev_priv = to_i915(ppgtt->base.dev); + + I915_WRITE(RING_PP_DIR_DCLV(ring), PP_DIR_DCLV_2G); + I915_WRITE(RING_PP_DIR_BASE(ring), get_pd_offset(ppgtt)); + return 0; +} + static int gen7_mm_switch(struct i915_hw_ppgtt *ppgtt, struct intel_engine_cs *ring) { @@ -1127,6 +1140,9 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt) } else BUG(); + if (intel_vgpu_active(dev)) + ppgtt->switch_mm = vgpu_mm_switch; + ret = gen6_ppgtt_alloc(ppgtt); if (ret) return ret; -- GitLab From a2f8aeb328484769404453678dbbd7989c8029d1 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Tue, 10 Feb 2015 19:32:16 +0000 Subject: [PATCH 00212/11651] drm/i915: Garbage collect orphaned prototypes There have been quite a bit of development lately, leaving behing lonely protypes. Time to bid them farewell. Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 4 ---- drivers/gpu/drm/i915/intel_drv.h | 9 --------- 2 files changed, 13 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 23ae26c42352..891463fe949b 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2507,8 +2507,6 @@ extern int i915_max_ioctl; extern int i915_suspend_legacy(struct drm_device *dev, pm_message_t state); extern int i915_resume_legacy(struct drm_device *dev); -extern int i915_master_create(struct drm_device *dev, struct drm_master *master); -extern void i915_master_destroy(struct drm_device *dev, struct drm_master *master); /* i915_params.c */ struct i915_params { @@ -3213,8 +3211,6 @@ int i915_reg_read_ioctl(struct drm_device *dev, void *data, int i915_get_reset_stats_ioctl(struct drm_device *dev, void *data, struct drm_file *file); -void intel_notify_mmio_flip(struct intel_engine_cs *ring); - /* overlay */ extern struct intel_overlay_error_state *intel_overlay_capture_error_state(struct drm_device *dev); extern void intel_overlay_print_error_state(struct drm_i915_error_state_buf *e, diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index b9598ba6901c..b83ffdb1533d 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1039,12 +1039,6 @@ void intel_dp_hot_plug(struct intel_encoder *intel_encoder); void vlv_power_sequencer_reset(struct drm_i915_private *dev_priv); uint32_t intel_dp_pack_aux(const uint8_t *src, int src_bytes); void intel_dp_unpack_aux(uint32_t src, uint8_t *dst, int dst_bytes); -int intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, - struct drm_framebuffer *fb, int crtc_x, int crtc_y, - unsigned int crtc_w, unsigned int crtc_h, - uint32_t src_x, uint32_t src_y, - uint32_t src_w, uint32_t src_h); -int intel_disable_plane(struct drm_plane *plane); void intel_plane_destroy(struct drm_plane *plane); void intel_edp_drrs_enable(struct intel_dp *intel_dp); void intel_edp_drrs_disable(struct intel_dp *intel_dp); @@ -1233,9 +1227,6 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob); int intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane); void intel_flush_primary_plane(struct drm_i915_private *dev_priv, enum plane plane); -int intel_plane_set_property(struct drm_plane *plane, - struct drm_property *prop, - uint64_t val); int intel_plane_restore(struct drm_plane *plane); int intel_sprite_set_colorkey(struct drm_device *dev, void *data, struct drm_file *file_priv); -- GitLab From af75f2691870c575030bbd42adf17457afbe7242 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Tue, 10 Feb 2015 19:32:17 +0000 Subject: [PATCH 00213/11651] drm/i915: Make intel_ring_setup_status_page() static This function is only used in intel_ringbuffer.c, so restrict it to that file. The function was moved around to avoid a forward declaration and group it with its user. Signed-off-by: Damien Lespiau [danvet: Squash in fixup from Wu Fengguang.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_ringbuffer.c | 124 ++++++++++++------------ drivers/gpu/drm/i915/intel_ringbuffer.h | 1 - 2 files changed, 62 insertions(+), 63 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index d62681748b87..9ebc11e6bb49 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -502,6 +502,68 @@ static void ring_setup_phys_status_page(struct intel_engine_cs *ring) I915_WRITE(HWS_PGA, addr); } +static void intel_ring_setup_status_page(struct intel_engine_cs *ring) +{ + struct drm_device *dev = ring->dev; + struct drm_i915_private *dev_priv = ring->dev->dev_private; + u32 mmio = 0; + + /* The ring status page addresses are no longer next to the rest of + * the ring registers as of gen7. + */ + if (IS_GEN7(dev)) { + switch (ring->id) { + case RCS: + mmio = RENDER_HWS_PGA_GEN7; + break; + case BCS: + mmio = BLT_HWS_PGA_GEN7; + break; + /* + * VCS2 actually doesn't exist on Gen7. Only shut up + * gcc switch check warning + */ + case VCS2: + case VCS: + mmio = BSD_HWS_PGA_GEN7; + break; + case VECS: + mmio = VEBOX_HWS_PGA_GEN7; + break; + } + } else if (IS_GEN6(ring->dev)) { + mmio = RING_HWS_PGA_GEN6(ring->mmio_base); + } else { + /* XXX: gen8 returns to sanity */ + mmio = RING_HWS_PGA(ring->mmio_base); + } + + I915_WRITE(mmio, (u32)ring->status_page.gfx_addr); + POSTING_READ(mmio); + + /* + * Flush the TLB for this page + * + * FIXME: These two bits have disappeared on gen8, so a question + * arises: do we still need this and if so how should we go about + * invalidating the TLB? + */ + if (INTEL_INFO(dev)->gen >= 6 && INTEL_INFO(dev)->gen < 8) { + u32 reg = RING_INSTPM(ring->mmio_base); + + /* ring should be idle before issuing a sync flush*/ + WARN_ON((I915_READ_MODE(ring) & MODE_IDLE) == 0); + + I915_WRITE(reg, + _MASKED_BIT_ENABLE(INSTPM_TLB_INVALIDATE | + INSTPM_SYNC_FLUSH)); + if (wait_for((I915_READ(reg) & INSTPM_SYNC_FLUSH) == 0, + 1000)) + DRM_ERROR("%s: wait for SyncFlush to complete for TLB invalidation timed out\n", + ring->name); + } +} + static bool stop_ring(struct intel_engine_cs *ring) { struct drm_i915_private *dev_priv = to_i915(ring->dev); @@ -1438,68 +1500,6 @@ i8xx_ring_put_irq(struct intel_engine_cs *ring) spin_unlock_irqrestore(&dev_priv->irq_lock, flags); } -void intel_ring_setup_status_page(struct intel_engine_cs *ring) -{ - struct drm_device *dev = ring->dev; - struct drm_i915_private *dev_priv = ring->dev->dev_private; - u32 mmio = 0; - - /* The ring status page addresses are no longer next to the rest of - * the ring registers as of gen7. - */ - if (IS_GEN7(dev)) { - switch (ring->id) { - case RCS: - mmio = RENDER_HWS_PGA_GEN7; - break; - case BCS: - mmio = BLT_HWS_PGA_GEN7; - break; - /* - * VCS2 actually doesn't exist on Gen7. Only shut up - * gcc switch check warning - */ - case VCS2: - case VCS: - mmio = BSD_HWS_PGA_GEN7; - break; - case VECS: - mmio = VEBOX_HWS_PGA_GEN7; - break; - } - } else if (IS_GEN6(ring->dev)) { - mmio = RING_HWS_PGA_GEN6(ring->mmio_base); - } else { - /* XXX: gen8 returns to sanity */ - mmio = RING_HWS_PGA(ring->mmio_base); - } - - I915_WRITE(mmio, (u32)ring->status_page.gfx_addr); - POSTING_READ(mmio); - - /* - * Flush the TLB for this page - * - * FIXME: These two bits have disappeared on gen8, so a question - * arises: do we still need this and if so how should we go about - * invalidating the TLB? - */ - if (INTEL_INFO(dev)->gen >= 6 && INTEL_INFO(dev)->gen < 8) { - u32 reg = RING_INSTPM(ring->mmio_base); - - /* ring should be idle before issuing a sync flush*/ - WARN_ON((I915_READ_MODE(ring) & MODE_IDLE) == 0); - - I915_WRITE(reg, - _MASKED_BIT_ENABLE(INSTPM_TLB_INVALIDATE | - INSTPM_SYNC_FLUSH)); - if (wait_for((I915_READ(reg) & INSTPM_SYNC_FLUSH) == 0, - 1000)) - DRM_ERROR("%s: wait for SyncFlush to complete for TLB invalidation timed out\n", - ring->name); - } -} - static int bsd_ring_flush(struct intel_engine_cs *ring, u32 invalidate_domains, diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 714f3fdd57d2..b6c484fe7a59 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -425,7 +425,6 @@ int intel_init_blt_ring_buffer(struct drm_device *dev); int intel_init_vebox_ring_buffer(struct drm_device *dev); u64 intel_ring_get_active_head(struct intel_engine_cs *ring); -void intel_ring_setup_status_page(struct intel_engine_cs *ring); int init_workarounds_ring(struct intel_engine_cs *ring); -- GitLab From a01c7162ca1116dc95c5363e6d77078a61797fc5 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Tue, 10 Feb 2015 19:32:18 +0000 Subject: [PATCH 00214/11651] drm/i915: Remove intel_dsi_cmd.h This header has been unusued since: commit 063c86f60ad4064b2cf62041bee8c6389e180b76 Author: Jani Nikula Date: Fri Jan 16 14:27:27 2015 +0200 drm/i915/dsi: remove intel_dsi_cmd.c and the unused functions therein Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dsi_cmd.h | 39 ---------------------------- 1 file changed, 39 deletions(-) delete mode 100644 drivers/gpu/drm/i915/intel_dsi_cmd.h diff --git a/drivers/gpu/drm/i915/intel_dsi_cmd.h b/drivers/gpu/drm/i915/intel_dsi_cmd.h deleted file mode 100644 index 886779030f1a..000000000000 --- a/drivers/gpu/drm/i915/intel_dsi_cmd.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright © 2013 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Author: Jani Nikula - */ - -#ifndef _INTEL_DSI_DSI_H -#define _INTEL_DSI_DSI_H - -#include -#include -#include + + Internal Structure of Kernel Crypto API + + + The kernel crypto API has an internal structure where a cipher + implementation may use many layers and indirections. This section + shall help to clarify how the kernel crypto API uses + various components to implement the complete cipher. + + + + The following subsections explain the internal structure based + on existing cipher implementations. The first section addresses + the most complex scenario where all other scenarios form a logical + subset. + + + Generic AEAD Cipher Structure + + + The following ASCII art decomposes the kernel crypto API layers + when using the AEAD cipher with the automated IV generation. The + shown example is used by the IPSEC layer. + + + + For other use cases of AEAD ciphers, the ASCII art applies as + well, but the caller may not use the GIVCIPHER interface. In + this case, the caller must generate the IV. + + + + The depicted example decomposes the AEAD cipher of GCM(AES) based + on the generic C implementations (gcm.c, aes-generic.c, ctr.c, + ghash-generic.c, seqiv.c). The generic implementation serves as an + example showing the complete logic of the kernel crypto API. + + + + It is possible that some streamlined cipher implementations (like + AES-NI) provide implementations merging aspects which in the view + of the kernel crypto API cannot be decomposed into layers any more. + In case of the AES-NI implementation, the CTR mode, the GHASH + implementation and the AES cipher are all merged into one cipher + implementation registered with the kernel crypto API. In this case, + the concept described by the following ASCII art applies too. However, + the decomposition of GCM into the individual sub-components + by the kernel crypto API is not done any more. + + + + Each block in the following ASCII art is an independent cipher + instance obtained from the kernel crypto API. Each block + is accessed by the caller or by other blocks using the API functions + defined by the kernel crypto API for the cipher implementation type. + + + + The blocks below indicate the cipher type as well as the specific + logic implemented in the cipher. + + + + The ASCII art picture also indicates the call structure, i.e. who + calls which component. The arrows point to the invoked block + where the caller uses the API applicable to the cipher type + specified for the block. + + + + + + + + The following call sequence is applicable when the IPSEC layer + triggers an encryption operation with the esp_output function. During + configuration, the administrator set up the use of rfc4106(gcm(aes)) as + the cipher for ESP. The following call sequence is now depicted in the + ASCII art above: + + + + + + esp_output() invokes crypto_aead_givencrypt() to trigger an encryption + operation of the GIVCIPHER implementation. + + + + In case of GCM, the SEQIV implementation is registered as GIVCIPHER + in crypto_rfc4106_alloc(). + + + + The SEQIV performs its operation to generate an IV where the core + function is seqiv_geniv(). + + + + + + Now, SEQIV uses the AEAD API function calls to invoke the associated + AEAD cipher. In our case, during the instantiation of SEQIV, the + cipher handle for GCM is provided to SEQIV. This means that SEQIV + invokes AEAD cipher operations with the GCM cipher handle. + + + + During instantiation of the GCM handle, the CTR(AES) and GHASH + ciphers are instantiated. The cipher handles for CTR(AES) and GHASH + are retained for later use. + + + + The GCM implementation is responsible to invoke the CTR mode AES and + the GHASH cipher in the right manner to implement the GCM + specification. + + + + + + The GCM AEAD cipher type implementation now invokes the ABLKCIPHER API + with the instantiated CTR(AES) cipher handle. + + + + During instantiation of the CTR(AES) cipher, the CIPHER type + implementation of AES is instantiated. The cipher handle for AES is + retained. + + + + That means that the ABLKCIPHER implementation of CTR(AES) only + implements the CTR block chaining mode. After performing the block + chaining operation, the CIPHER implementation of AES is invoked. + + + + + + The ABLKCIPHER of CTR(AES) now invokes the CIPHER API with the AES + cipher handle to encrypt one block. + + + + + + The GCM AEAD implementation also invokes the GHASH cipher + implementation via the AHASH API. + + + + + + When the IPSEC layer triggers the esp_input() function, the same call + sequence is followed with the only difference that the operation starts + with step (2). + + + + Generic Block Cipher Structure + + Generic block ciphers follow the same concept as depicted with the ASCII + art picture above. + + + + For example, CBC(AES) is implemented with cbc.c, and aes-generic.c. The + ASCII art picture above applies as well with the difference that only + step (4) is used and the ABLKCIPHER block chaining mode is CBC. + + + + Generic Keyed Message Digest Structure + + Keyed message digest implementations again follow the same concept as + depicted in the ASCII art picture above. + + + + For example, HMAC(SHA256) is implemented with hmac.c and + sha256_generic.c. The following ASCII art illustrates the + implementation: + + + + + + + + The following call sequence is applicable when a caller triggers + an HMAC operation: + + + + + + The AHASH API functions are invoked by the caller. The HMAC + implementation performs its operation as needed. + + + + During initialization of the HMAC cipher, the SHASH cipher type of + SHA256 is instantiated. The cipher handle for the SHA256 instance is + retained. + + + + At one time, the HMAC implementation requires a SHA256 operation + where the SHA256 cipher handle is used. + + + + + + The HMAC instance now invokes the SHASH API with the SHA256 + cipher handle to calculate the message digest. + + + + + Developing Cipher Algorithms -- GitLab From 400c40cf78da00c16e561a3a253ca272455c42ef Mon Sep 17 00:00:00 2001 From: Stephan Mueller Date: Sat, 28 Feb 2015 20:50:00 +0100 Subject: [PATCH 02490/11651] crypto: algif - add AEAD support This patch adds the AEAD support for AF_ALG. The implementation is based on algif_skcipher, but contains heavy modifications to streamline the interface for AEAD uses. To use AEAD, the user space consumer has to use the salg_type named "aead". The AEAD implementation includes some overhead to calculate the size of the ciphertext, because the AEAD implementation of the kernel crypto API makes implied assumption on the location of the authentication tag. When performing an encryption, the tag will be added to the created ciphertext (note, the tag is placed adjacent to the ciphertext). For decryption, the caller must hand in the ciphertext with the tag appended to the ciphertext. Therefore, the selection of the used memory needs to add/subtract the tag size from the source/destination buffers depending on the encryption type. The code is provided with comments explaining when and how that operation is performed. A fully working example using all aspects of AEAD is provided at http://www.chronox.de/libkcapi.html Signed-off-by: Stephan Mueller Signed-off-by: Herbert Xu --- crypto/algif_aead.c | 666 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 666 insertions(+) create mode 100644 crypto/algif_aead.c diff --git a/crypto/algif_aead.c b/crypto/algif_aead.c new file mode 100644 index 000000000000..527d27b023ab --- /dev/null +++ b/crypto/algif_aead.c @@ -0,0 +1,666 @@ +/* + * algif_aead: User-space interface for AEAD algorithms + * + * Copyright (C) 2014, Stephan Mueller + * + * This file provides the user-space API for AEAD ciphers. + * + * This file is derived from algif_skcipher.c. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct aead_sg_list { + unsigned int cur; + struct scatterlist sg[ALG_MAX_PAGES]; +}; + +struct aead_ctx { + struct aead_sg_list tsgl; + /* + * RSGL_MAX_ENTRIES is an artificial limit where user space at maximum + * can cause the kernel to allocate RSGL_MAX_ENTRIES * ALG_MAX_PAGES + * bytes + */ +#define RSGL_MAX_ENTRIES ALG_MAX_PAGES + struct af_alg_sgl rsgl[RSGL_MAX_ENTRIES]; + + void *iv; + + struct af_alg_completion completion; + + unsigned long used; + + unsigned int len; + bool more; + bool merge; + bool enc; + + size_t aead_assoclen; + struct aead_request aead_req; +}; + +static inline int aead_sndbuf(struct sock *sk) +{ + struct alg_sock *ask = alg_sk(sk); + struct aead_ctx *ctx = ask->private; + + return max_t(int, max_t(int, sk->sk_sndbuf & PAGE_MASK, PAGE_SIZE) - + ctx->used, 0); +} + +static inline bool aead_writable(struct sock *sk) +{ + return PAGE_SIZE <= aead_sndbuf(sk); +} + +static inline bool aead_sufficient_data(struct aead_ctx *ctx) +{ + unsigned as = crypto_aead_authsize(crypto_aead_reqtfm(&ctx->aead_req)); + + return (ctx->used >= (ctx->aead_assoclen + (ctx->enc ? 0 : as))); +} + +static void aead_put_sgl(struct sock *sk) +{ + struct alg_sock *ask = alg_sk(sk); + struct aead_ctx *ctx = ask->private; + struct aead_sg_list *sgl = &ctx->tsgl; + struct scatterlist *sg = sgl->sg; + unsigned int i; + + for (i = 0; i < sgl->cur; i++) { + if (!sg_page(sg + i)) + continue; + + put_page(sg_page(sg + i)); + sg_assign_page(sg + i, NULL); + } + sgl->cur = 0; + ctx->used = 0; + ctx->more = 0; + ctx->merge = 0; +} + +static void aead_wmem_wakeup(struct sock *sk) +{ + struct socket_wq *wq; + + if (!aead_writable(sk)) + return; + + rcu_read_lock(); + wq = rcu_dereference(sk->sk_wq); + if (wq_has_sleeper(wq)) + wake_up_interruptible_sync_poll(&wq->wait, POLLIN | + POLLRDNORM | + POLLRDBAND); + sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_IN); + rcu_read_unlock(); +} + +static int aead_wait_for_data(struct sock *sk, unsigned flags) +{ + struct alg_sock *ask = alg_sk(sk); + struct aead_ctx *ctx = ask->private; + long timeout; + DEFINE_WAIT(wait); + int err = -ERESTARTSYS; + + if (flags & MSG_DONTWAIT) + return -EAGAIN; + + set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); + + for (;;) { + if (signal_pending(current)) + break; + prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); + timeout = MAX_SCHEDULE_TIMEOUT; + if (sk_wait_event(sk, &timeout, !ctx->more)) { + err = 0; + break; + } + } + finish_wait(sk_sleep(sk), &wait); + + clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); + + return err; +} + +static void aead_data_wakeup(struct sock *sk) +{ + struct alg_sock *ask = alg_sk(sk); + struct aead_ctx *ctx = ask->private; + struct socket_wq *wq; + + if (ctx->more) + return; + if (!ctx->used) + return; + + rcu_read_lock(); + wq = rcu_dereference(sk->sk_wq); + if (wq_has_sleeper(wq)) + wake_up_interruptible_sync_poll(&wq->wait, POLLOUT | + POLLRDNORM | + POLLRDBAND); + sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT); + rcu_read_unlock(); +} + +static int aead_sendmsg(struct kiocb *unused, struct socket *sock, + struct msghdr *msg, size_t size) +{ + struct sock *sk = sock->sk; + struct alg_sock *ask = alg_sk(sk); + struct aead_ctx *ctx = ask->private; + unsigned ivsize = + crypto_aead_ivsize(crypto_aead_reqtfm(&ctx->aead_req)); + struct aead_sg_list *sgl = &ctx->tsgl; + struct af_alg_control con = {}; + long copied = 0; + bool enc = 0; + bool init = 0; + int err = -EINVAL; + + if (msg->msg_controllen) { + err = af_alg_cmsg_send(msg, &con); + if (err) + return err; + + init = 1; + switch (con.op) { + case ALG_OP_ENCRYPT: + enc = 1; + break; + case ALG_OP_DECRYPT: + enc = 0; + break; + default: + return -EINVAL; + } + + if (con.iv && con.iv->ivlen != ivsize) + return -EINVAL; + } + + lock_sock(sk); + if (!ctx->more && ctx->used) + goto unlock; + + if (init) { + ctx->enc = enc; + if (con.iv) + memcpy(ctx->iv, con.iv->iv, ivsize); + + ctx->aead_assoclen = con.aead_assoclen; + } + + while (size) { + unsigned long len = size; + struct scatterlist *sg = NULL; + + /* use the existing memory in an allocated page */ + if (ctx->merge) { + sg = sgl->sg + sgl->cur - 1; + len = min_t(unsigned long, len, + PAGE_SIZE - sg->offset - sg->length); + err = memcpy_from_msg(page_address(sg_page(sg)) + + sg->offset + sg->length, + msg, len); + if (err) + goto unlock; + + sg->length += len; + ctx->merge = (sg->offset + sg->length) & + (PAGE_SIZE - 1); + + ctx->used += len; + copied += len; + size -= len; + continue; + } + + if (!aead_writable(sk)) { + /* user space sent too much data */ + aead_put_sgl(sk); + err = -EMSGSIZE; + goto unlock; + } + + /* allocate a new page */ + len = min_t(unsigned long, size, aead_sndbuf(sk)); + while (len) { + int plen = 0; + + if (sgl->cur >= ALG_MAX_PAGES) { + aead_put_sgl(sk); + err = -E2BIG; + goto unlock; + } + + sg = sgl->sg + sgl->cur; + plen = min_t(int, len, PAGE_SIZE); + + sg_assign_page(sg, alloc_page(GFP_KERNEL)); + err = -ENOMEM; + if (!sg_page(sg)) + goto unlock; + + err = memcpy_from_msg(page_address(sg_page(sg)), + msg, plen); + if (err) { + __free_page(sg_page(sg)); + sg_assign_page(sg, NULL); + goto unlock; + } + + sg->offset = 0; + sg->length = plen; + len -= plen; + ctx->used += plen; + copied += plen; + sgl->cur++; + size -= plen; + ctx->merge = plen & (PAGE_SIZE - 1); + } + } + + err = 0; + + ctx->more = msg->msg_flags & MSG_MORE; + if (!ctx->more && !aead_sufficient_data(ctx)) { + aead_put_sgl(sk); + err = -EMSGSIZE; + } + +unlock: + aead_data_wakeup(sk); + release_sock(sk); + + return err ?: copied; +} + +static ssize_t aead_sendpage(struct socket *sock, struct page *page, + int offset, size_t size, int flags) +{ + struct sock *sk = sock->sk; + struct alg_sock *ask = alg_sk(sk); + struct aead_ctx *ctx = ask->private; + struct aead_sg_list *sgl = &ctx->tsgl; + int err = -EINVAL; + + if (flags & MSG_SENDPAGE_NOTLAST) + flags |= MSG_MORE; + + if (sgl->cur >= ALG_MAX_PAGES) + return -E2BIG; + + lock_sock(sk); + if (!ctx->more && ctx->used) + goto unlock; + + if (!size) + goto done; + + if (!aead_writable(sk)) { + /* user space sent too much data */ + aead_put_sgl(sk); + err = -EMSGSIZE; + goto unlock; + } + + ctx->merge = 0; + + get_page(page); + sg_set_page(sgl->sg + sgl->cur, page, size, offset); + sgl->cur++; + ctx->used += size; + + err = 0; + +done: + ctx->more = flags & MSG_MORE; + if (!ctx->more && !aead_sufficient_data(ctx)) { + aead_put_sgl(sk); + err = -EMSGSIZE; + } + +unlock: + aead_data_wakeup(sk); + release_sock(sk); + + return err ?: size; +} + +static int aead_recvmsg(struct kiocb *unused, struct socket *sock, + struct msghdr *msg, size_t ignored, int flags) +{ + struct sock *sk = sock->sk; + struct alg_sock *ask = alg_sk(sk); + struct aead_ctx *ctx = ask->private; + unsigned bs = crypto_aead_blocksize(crypto_aead_reqtfm(&ctx->aead_req)); + unsigned as = crypto_aead_authsize(crypto_aead_reqtfm(&ctx->aead_req)); + struct aead_sg_list *sgl = &ctx->tsgl; + struct scatterlist *sg = NULL; + struct scatterlist assoc[ALG_MAX_PAGES]; + size_t assoclen = 0; + unsigned int i = 0; + int err = -EINVAL; + unsigned long used = 0; + size_t outlen = 0; + size_t usedpages = 0; + unsigned int cnt = 0; + + /* Limit number of IOV blocks to be accessed below */ + if (msg->msg_iter.nr_segs > RSGL_MAX_ENTRIES) + return -ENOMSG; + + lock_sock(sk); + + /* + * AEAD memory structure: For encryption, the tag is appended to the + * ciphertext which implies that the memory allocated for the ciphertext + * must be increased by the tag length. For decryption, the tag + * is expected to be concatenated to the ciphertext. The plaintext + * therefore has a memory size of the ciphertext minus the tag length. + * + * The memory structure for cipher operation has the following + * structure: + * AEAD encryption input: assoc data || plaintext + * AEAD encryption output: cipherntext || auth tag + * AEAD decryption input: assoc data || ciphertext || auth tag + * AEAD decryption output: plaintext + */ + + if (ctx->more) { + err = aead_wait_for_data(sk, flags); + if (err) + goto unlock; + } + + used = ctx->used; + + /* + * Make sure sufficient data is present -- note, the same check is + * is also present in sendmsg/sendpage. The checks in sendpage/sendmsg + * shall provide an information to the data sender that something is + * wrong, but they are irrelevant to maintain the kernel integrity. + * We need this check here too in case user space decides to not honor + * the error message in sendmsg/sendpage and still call recvmsg. This + * check here protects the kernel integrity. + */ + if (!aead_sufficient_data(ctx)) + goto unlock; + + /* + * The cipher operation input data is reduced by the associated data + * length as this data is processed separately later on. + */ + used -= ctx->aead_assoclen; + + if (ctx->enc) { + /* round up output buffer to multiple of block size */ + outlen = ((used + bs - 1) / bs * bs); + /* add the size needed for the auth tag to be created */ + outlen += as; + } else { + /* output data size is input without the authentication tag */ + outlen = used - as; + /* round up output buffer to multiple of block size */ + outlen = ((outlen + bs - 1) / bs * bs); + } + + /* convert iovecs of output buffers into scatterlists */ + while (iov_iter_count(&msg->msg_iter)) { + size_t seglen = min_t(size_t, iov_iter_count(&msg->msg_iter), + (outlen - usedpages)); + + /* make one iovec available as scatterlist */ + err = af_alg_make_sg(&ctx->rsgl[cnt], &msg->msg_iter, + seglen); + if (err < 0) + goto unlock; + usedpages += err; + /* chain the new scatterlist with initial list */ + if (cnt) + scatterwalk_crypto_chain(ctx->rsgl[0].sg, + ctx->rsgl[cnt].sg, 1, + sg_nents(ctx->rsgl[cnt-1].sg)); + /* we do not need more iovecs as we have sufficient memory */ + if (outlen <= usedpages) + break; + iov_iter_advance(&msg->msg_iter, err); + cnt++; + } + + err = -EINVAL; + /* ensure output buffer is sufficiently large */ + if (usedpages < outlen) + goto unlock; + + sg_init_table(assoc, ALG_MAX_PAGES); + assoclen = ctx->aead_assoclen; + /* + * Split scatterlist into two: first part becomes AD, second part + * is plaintext / ciphertext. The first part is assigned to assoc + * scatterlist. When this loop finishes, sg points to the start of the + * plaintext / ciphertext. + */ + for (i = 0; i < ctx->tsgl.cur; i++) { + sg = sgl->sg + i; + if (sg->length <= assoclen) { + /* AD is larger than one page */ + sg_set_page(assoc + i, sg_page(sg), + sg->length, sg->offset); + assoclen -= sg->length; + if (i >= ctx->tsgl.cur) + goto unlock; + } else if (!assoclen) { + /* current page is to start of plaintext / ciphertext */ + if (i) + /* AD terminates at page boundary */ + sg_mark_end(assoc + i - 1); + else + /* AD size is zero */ + sg_mark_end(assoc); + break; + } else { + /* AD does not terminate at page boundary */ + sg_set_page(assoc + i, sg_page(sg), + assoclen, sg->offset); + sg_mark_end(assoc + i); + /* plaintext / ciphertext starts after AD */ + sg->length -= assoclen; + sg->offset += assoclen; + break; + } + } + + aead_request_set_assoc(&ctx->aead_req, assoc, ctx->aead_assoclen); + aead_request_set_crypt(&ctx->aead_req, sg, ctx->rsgl[0].sg, used, + ctx->iv); + + err = af_alg_wait_for_completion(ctx->enc ? + crypto_aead_encrypt(&ctx->aead_req) : + crypto_aead_decrypt(&ctx->aead_req), + &ctx->completion); + + if (err) { + /* EBADMSG implies a valid cipher operation took place */ + if (err == -EBADMSG) + aead_put_sgl(sk); + goto unlock; + } + + aead_put_sgl(sk); + + err = 0; + +unlock: + for (i = 0; i < cnt; i++) + af_alg_free_sg(&ctx->rsgl[i]); + + aead_wmem_wakeup(sk); + release_sock(sk); + + return err ? err : outlen; +} + +static unsigned int aead_poll(struct file *file, struct socket *sock, + poll_table *wait) +{ + struct sock *sk = sock->sk; + struct alg_sock *ask = alg_sk(sk); + struct aead_ctx *ctx = ask->private; + unsigned int mask; + + sock_poll_wait(file, sk_sleep(sk), wait); + mask = 0; + + if (!ctx->more) + mask |= POLLIN | POLLRDNORM; + + if (aead_writable(sk)) + mask |= POLLOUT | POLLWRNORM | POLLWRBAND; + + return mask; +} + +static struct proto_ops algif_aead_ops = { + .family = PF_ALG, + + .connect = sock_no_connect, + .socketpair = sock_no_socketpair, + .getname = sock_no_getname, + .ioctl = sock_no_ioctl, + .listen = sock_no_listen, + .shutdown = sock_no_shutdown, + .getsockopt = sock_no_getsockopt, + .mmap = sock_no_mmap, + .bind = sock_no_bind, + .accept = sock_no_accept, + .setsockopt = sock_no_setsockopt, + + .release = af_alg_release, + .sendmsg = aead_sendmsg, + .sendpage = aead_sendpage, + .recvmsg = aead_recvmsg, + .poll = aead_poll, +}; + +static void *aead_bind(const char *name, u32 type, u32 mask) +{ + return crypto_alloc_aead(name, type, mask); +} + +static void aead_release(void *private) +{ + crypto_free_aead(private); +} + +static int aead_setauthsize(void *private, unsigned int authsize) +{ + return crypto_aead_setauthsize(private, authsize); +} + +static int aead_setkey(void *private, const u8 *key, unsigned int keylen) +{ + return crypto_aead_setkey(private, key, keylen); +} + +static void aead_sock_destruct(struct sock *sk) +{ + struct alg_sock *ask = alg_sk(sk); + struct aead_ctx *ctx = ask->private; + unsigned int ivlen = crypto_aead_ivsize( + crypto_aead_reqtfm(&ctx->aead_req)); + + aead_put_sgl(sk); + sock_kzfree_s(sk, ctx->iv, ivlen); + sock_kfree_s(sk, ctx, ctx->len); + af_alg_release_parent(sk); +} + +static int aead_accept_parent(void *private, struct sock *sk) +{ + struct aead_ctx *ctx; + struct alg_sock *ask = alg_sk(sk); + unsigned int len = sizeof(*ctx) + crypto_aead_reqsize(private); + unsigned int ivlen = crypto_aead_ivsize(private); + + ctx = sock_kmalloc(sk, len, GFP_KERNEL); + if (!ctx) + return -ENOMEM; + memset(ctx, 0, len); + + ctx->iv = sock_kmalloc(sk, ivlen, GFP_KERNEL); + if (!ctx->iv) { + sock_kfree_s(sk, ctx, len); + return -ENOMEM; + } + memset(ctx->iv, 0, ivlen); + + ctx->len = len; + ctx->used = 0; + ctx->more = 0; + ctx->merge = 0; + ctx->enc = 0; + ctx->tsgl.cur = 0; + ctx->aead_assoclen = 0; + af_alg_init_completion(&ctx->completion); + sg_init_table(ctx->tsgl.sg, ALG_MAX_PAGES); + + ask->private = ctx; + + aead_request_set_tfm(&ctx->aead_req, private); + aead_request_set_callback(&ctx->aead_req, CRYPTO_TFM_REQ_MAY_BACKLOG, + af_alg_complete, &ctx->completion); + + sk->sk_destruct = aead_sock_destruct; + + return 0; +} + +static const struct af_alg_type algif_type_aead = { + .bind = aead_bind, + .release = aead_release, + .setkey = aead_setkey, + .setauthsize = aead_setauthsize, + .accept = aead_accept_parent, + .ops = &algif_aead_ops, + .name = "aead", + .owner = THIS_MODULE +}; + +static int __init algif_aead_init(void) +{ + return af_alg_register_type(&algif_type_aead); +} + +static void __exit algif_aead_exit(void) +{ + int err = af_alg_unregister_type(&algif_type_aead); + BUG_ON(err); +} + +module_init(algif_aead_init); +module_exit(algif_aead_exit); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Stephan Mueller "); +MODULE_DESCRIPTION("AEAD kernel crypto API user space interface"); -- GitLab From 44cac4fce9b820c37a8792df52a0e4ce33201949 Mon Sep 17 00:00:00 2001 From: Stephan Mueller Date: Sat, 28 Feb 2015 20:50:40 +0100 Subject: [PATCH 02491/11651] crypto: algif - enable AEAD interface compilation Enable compilation of the AEAD AF_ALG support and provide a Kconfig option to compile the AEAD AF_ALG support. Signed-off-by: Stephan Mueller Signed-off-by: Herbert Xu --- crypto/Kconfig | 9 +++++++++ crypto/Makefile | 1 + 2 files changed, 10 insertions(+) diff --git a/crypto/Kconfig b/crypto/Kconfig index 67275b7f176d..e74cecadef70 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -1552,6 +1552,15 @@ config CRYPTO_USER_API_RNG This option enables the user-spaces interface for random number generator algorithms. +config CRYPTO_USER_API_AEAD + tristate "User-space interface for AEAD cipher algorithms" + depends on NET + select CRYPTO_AEAD + select CRYPTO_USER_API + help + This option enables the user-spaces interface for AEAD + cipher algorithms. + config CRYPTO_HASH_INFO bool diff --git a/crypto/Makefile b/crypto/Makefile index ba19465f9ad3..97b7d3ac87e7 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -100,6 +100,7 @@ obj-$(CONFIG_CRYPTO_USER_API) += af_alg.o obj-$(CONFIG_CRYPTO_USER_API_HASH) += algif_hash.o obj-$(CONFIG_CRYPTO_USER_API_SKCIPHER) += algif_skcipher.o obj-$(CONFIG_CRYPTO_USER_API_RNG) += algif_rng.o +obj-$(CONFIG_CRYPTO_USER_API_AEAD) += algif_aead.o # # generic algorithms and the async_tx api -- GitLab From be208356762c3609dc05d0f187be87fd60d8d32e Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Sat, 28 Feb 2015 20:40:10 +0000 Subject: [PATCH 02492/11651] crypto: atmel - fix typo in dev_err error message Fix typo, "intialization" -> "initialization" Signed-off-by: Colin Ian King Signed-off-by: Herbert Xu --- drivers/crypto/atmel-aes.c | 2 +- drivers/crypto/atmel-sha.c | 2 +- drivers/crypto/atmel-tdes.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/crypto/atmel-aes.c b/drivers/crypto/atmel-aes.c index 6597aac9905d..2e875aaeaed7 100644 --- a/drivers/crypto/atmel-aes.c +++ b/drivers/crypto/atmel-aes.c @@ -1374,7 +1374,7 @@ static int atmel_aes_probe(struct platform_device *pdev) /* Initializing the clock */ aes_dd->iclk = clk_get(&pdev->dev, "aes_clk"); if (IS_ERR(aes_dd->iclk)) { - dev_err(dev, "clock intialization failed.\n"); + dev_err(dev, "clock initialization failed.\n"); err = PTR_ERR(aes_dd->iclk); goto clk_err; } diff --git a/drivers/crypto/atmel-sha.c b/drivers/crypto/atmel-sha.c index 34db04addc18..325d6b66c27c 100644 --- a/drivers/crypto/atmel-sha.c +++ b/drivers/crypto/atmel-sha.c @@ -1385,7 +1385,7 @@ static int atmel_sha_probe(struct platform_device *pdev) /* Initializing the clock */ sha_dd->iclk = clk_get(&pdev->dev, "sha_clk"); if (IS_ERR(sha_dd->iclk)) { - dev_err(dev, "clock intialization failed.\n"); + dev_err(dev, "clock initialization failed.\n"); err = PTR_ERR(sha_dd->iclk); goto clk_err; } diff --git a/drivers/crypto/atmel-tdes.c b/drivers/crypto/atmel-tdes.c index 258772d9b22f..8495b8959d0b 100644 --- a/drivers/crypto/atmel-tdes.c +++ b/drivers/crypto/atmel-tdes.c @@ -1408,7 +1408,7 @@ static int atmel_tdes_probe(struct platform_device *pdev) /* Initializing the clock */ tdes_dd->iclk = clk_get(&pdev->dev, "tdes_clk"); if (IS_ERR(tdes_dd->iclk)) { - dev_err(dev, "clock intialization failed.\n"); + dev_err(dev, "clock initialization failed.\n"); err = PTR_ERR(tdes_dd->iclk); goto clk_err; } -- GitLab From 209232d02586bc9b69ce028d22ae2512910f9e7f Mon Sep 17 00:00:00 2001 From: Markus Stockhausen Date: Sun, 1 Mar 2015 19:30:35 +0100 Subject: [PATCH 02493/11651] crypto: powerpc/md5 - assembler This is the assembler code for the MD5 implementation. Handling of algorithm constants has been slightly changed to reduce register usage and make better use of cores with multiple ALUs. Thus they are stored as delta values. Signed-off-by: Markus Stockhausen Signed-off-by: Herbert Xu --- arch/powerpc/crypto/md5-asm.S | 243 ++++++++++++++++++++++++++++++++++ 1 file changed, 243 insertions(+) create mode 100644 arch/powerpc/crypto/md5-asm.S diff --git a/arch/powerpc/crypto/md5-asm.S b/arch/powerpc/crypto/md5-asm.S new file mode 100644 index 000000000000..10cdf5bceebb --- /dev/null +++ b/arch/powerpc/crypto/md5-asm.S @@ -0,0 +1,243 @@ +/* + * Fast MD5 implementation for PPC + * + * Copyright (c) 2015 Markus Stockhausen + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + */ +#include +#include + +#define rHP r3 +#define rWP r4 + +#define rH0 r0 +#define rH1 r6 +#define rH2 r7 +#define rH3 r5 + +#define rW00 r8 +#define rW01 r9 +#define rW02 r10 +#define rW03 r11 +#define rW04 r12 +#define rW05 r14 +#define rW06 r15 +#define rW07 r16 +#define rW08 r17 +#define rW09 r18 +#define rW10 r19 +#define rW11 r20 +#define rW12 r21 +#define rW13 r22 +#define rW14 r23 +#define rW15 r24 + +#define rT0 r25 +#define rT1 r26 + +#define INITIALIZE \ + PPC_STLU r1,-INT_FRAME_SIZE(r1); \ + SAVE_8GPRS(14, r1); /* push registers onto stack */ \ + SAVE_4GPRS(22, r1); \ + SAVE_GPR(26, r1) + +#define FINALIZE \ + REST_8GPRS(14, r1); /* pop registers from stack */ \ + REST_4GPRS(22, r1); \ + REST_GPR(26, r1); \ + addi r1,r1,INT_FRAME_SIZE; + +#ifdef __BIG_ENDIAN__ +#define LOAD_DATA(reg, off) \ + lwbrx reg,0,rWP; /* load data */ +#define INC_PTR \ + addi rWP,rWP,4; /* increment per word */ +#define NEXT_BLOCK /* nothing to do */ +#else +#define LOAD_DATA(reg, off) \ + lwz reg,off(rWP); /* load data */ +#define INC_PTR /* nothing to do */ +#define NEXT_BLOCK \ + addi rWP,rWP,64; /* increment per block */ +#endif + +#define R_00_15(a, b, c, d, w0, w1, p, q, off, k0h, k0l, k1h, k1l) \ + LOAD_DATA(w0, off) /* W */ \ + and rT0,b,c; /* 1: f = b and c */ \ + INC_PTR /* ptr++ */ \ + andc rT1,d,b; /* 1: f' = ~b and d */ \ + LOAD_DATA(w1, off+4) /* W */ \ + or rT0,rT0,rT1; /* 1: f = f or f' */ \ + addi w0,w0,k0l; /* 1: wk = w + k */ \ + add a,a,rT0; /* 1: a = a + f */ \ + addis w0,w0,k0h; /* 1: wk = w + k' */ \ + addis w1,w1,k1h; /* 2: wk = w + k */ \ + add a,a,w0; /* 1: a = a + wk */ \ + addi w1,w1,k1l; /* 2: wk = w + k' */ \ + rotrwi a,a,p; /* 1: a = a rotl x */ \ + add d,d,w1; /* 2: a = a + wk */ \ + add a,a,b; /* 1: a = a + b */ \ + and rT0,a,b; /* 2: f = b and c */ \ + andc rT1,c,a; /* 2: f' = ~b and d */ \ + or rT0,rT0,rT1; /* 2: f = f or f' */ \ + add d,d,rT0; /* 2: a = a + f */ \ + INC_PTR /* ptr++ */ \ + rotrwi d,d,q; /* 2: a = a rotl x */ \ + add d,d,a; /* 2: a = a + b */ + +#define R_16_31(a, b, c, d, w0, w1, p, q, k0h, k0l, k1h, k1l) \ + andc rT0,c,d; /* 1: f = c and ~d */ \ + and rT1,b,d; /* 1: f' = b and d */ \ + addi w0,w0,k0l; /* 1: wk = w + k */ \ + or rT0,rT0,rT1; /* 1: f = f or f' */ \ + addis w0,w0,k0h; /* 1: wk = w + k' */ \ + add a,a,rT0; /* 1: a = a + f */ \ + addi w1,w1,k1l; /* 2: wk = w + k */ \ + add a,a,w0; /* 1: a = a + wk */ \ + addis w1,w1,k1h; /* 2: wk = w + k' */ \ + andc rT0,b,c; /* 2: f = c and ~d */ \ + rotrwi a,a,p; /* 1: a = a rotl x */ \ + add a,a,b; /* 1: a = a + b */ \ + add d,d,w1; /* 2: a = a + wk */ \ + and rT1,a,c; /* 2: f' = b and d */ \ + or rT0,rT0,rT1; /* 2: f = f or f' */ \ + add d,d,rT0; /* 2: a = a + f */ \ + rotrwi d,d,q; /* 2: a = a rotl x */ \ + add d,d,a; /* 2: a = a +b */ + +#define R_32_47(a, b, c, d, w0, w1, p, q, k0h, k0l, k1h, k1l) \ + xor rT0,b,c; /* 1: f' = b xor c */ \ + addi w0,w0,k0l; /* 1: wk = w + k */ \ + xor rT1,rT0,d; /* 1: f = f xor f' */ \ + addis w0,w0,k0h; /* 1: wk = w + k' */ \ + add a,a,rT1; /* 1: a = a + f */ \ + addi w1,w1,k1l; /* 2: wk = w + k */ \ + add a,a,w0; /* 1: a = a + wk */ \ + addis w1,w1,k1h; /* 2: wk = w + k' */ \ + rotrwi a,a,p; /* 1: a = a rotl x */ \ + add d,d,w1; /* 2: a = a + wk */ \ + add a,a,b; /* 1: a = a + b */ \ + xor rT1,rT0,a; /* 2: f = b xor f' */ \ + add d,d,rT1; /* 2: a = a + f */ \ + rotrwi d,d,q; /* 2: a = a rotl x */ \ + add d,d,a; /* 2: a = a + b */ + +#define R_48_63(a, b, c, d, w0, w1, p, q, k0h, k0l, k1h, k1l) \ + addi w0,w0,k0l; /* 1: w = w + k */ \ + orc rT0,b,d; /* 1: f = b or ~d */ \ + addis w0,w0,k0h; /* 1: w = w + k' */ \ + xor rT0,rT0,c; /* 1: f = f xor c */ \ + add a,a,w0; /* 1: a = a + wk */ \ + addi w1,w1,k1l; /* 2: w = w + k */ \ + add a,a,rT0; /* 1: a = a + f */ \ + addis w1,w1,k1h; /* 2: w = w + k' */ \ + rotrwi a,a,p; /* 1: a = a rotl x */ \ + add a,a,b; /* 1: a = a + b */ \ + orc rT0,a,c; /* 2: f = b or ~d */ \ + add d,d,w1; /* 2: a = a + wk */ \ + xor rT0,rT0,b; /* 2: f = f xor c */ \ + add d,d,rT0; /* 2: a = a + f */ \ + rotrwi d,d,q; /* 2: a = a rotl x */ \ + add d,d,a; /* 2: a = a + b */ + +_GLOBAL(ppc_md5_transform) + INITIALIZE + + mtctr r5 + lwz rH0,0(rHP) + lwz rH1,4(rHP) + lwz rH2,8(rHP) + lwz rH3,12(rHP) + +ppc_md5_main: + R_00_15(rH0, rH1, rH2, rH3, rW00, rW01, 25, 20, 0, + 0xd76b, -23432, 0xe8c8, -18602) + R_00_15(rH2, rH3, rH0, rH1, rW02, rW03, 15, 10, 8, + 0x2420, 0x70db, 0xc1be, -12562) + R_00_15(rH0, rH1, rH2, rH3, rW04, rW05, 25, 20, 16, + 0xf57c, 0x0faf, 0x4788, -14806) + R_00_15(rH2, rH3, rH0, rH1, rW06, rW07, 15, 10, 24, + 0xa830, 0x4613, 0xfd47, -27391) + R_00_15(rH0, rH1, rH2, rH3, rW08, rW09, 25, 20, 32, + 0x6981, -26408, 0x8b45, -2129) + R_00_15(rH2, rH3, rH0, rH1, rW10, rW11, 15, 10, 40, + 0xffff, 0x5bb1, 0x895d, -10306) + R_00_15(rH0, rH1, rH2, rH3, rW12, rW13, 25, 20, 48, + 0x6b90, 0x1122, 0xfd98, 0x7193) + R_00_15(rH2, rH3, rH0, rH1, rW14, rW15, 15, 10, 56, + 0xa679, 0x438e, 0x49b4, 0x0821) + + R_16_31(rH0, rH1, rH2, rH3, rW01, rW06, 27, 23, + 0x0d56, 0x6e0c, 0x1810, 0x6d2d) + R_16_31(rH2, rH3, rH0, rH1, rW11, rW00, 18, 12, + 0x9d02, -32109, 0x124c, 0x2332) + R_16_31(rH0, rH1, rH2, rH3, rW05, rW10, 27, 23, + 0x8ea7, 0x4a33, 0x0245, -18270) + R_16_31(rH2, rH3, rH0, rH1, rW15, rW04, 18, 12, + 0x8eee, -8608, 0xf258, -5095) + R_16_31(rH0, rH1, rH2, rH3, rW09, rW14, 27, 23, + 0x969d, -10697, 0x1cbe, -15288) + R_16_31(rH2, rH3, rH0, rH1, rW03, rW08, 18, 12, + 0x3317, 0x3e99, 0xdbd9, 0x7c15) + R_16_31(rH0, rH1, rH2, rH3, rW13, rW02, 27, 23, + 0xac4b, 0x7772, 0xd8cf, 0x331d) + R_16_31(rH2, rH3, rH0, rH1, rW07, rW12, 18, 12, + 0x6a28, 0x6dd8, 0x219a, 0x3b68) + + R_32_47(rH0, rH1, rH2, rH3, rW05, rW08, 28, 21, + 0x29cb, 0x28e5, 0x4218, -7788) + R_32_47(rH2, rH3, rH0, rH1, rW11, rW14, 16, 9, + 0x473f, 0x06d1, 0x3aae, 0x3036) + R_32_47(rH0, rH1, rH2, rH3, rW01, rW04, 28, 21, + 0xaea1, -15134, 0x640b, -11295) + R_32_47(rH2, rH3, rH0, rH1, rW07, rW10, 16, 9, + 0x8f4c, 0x4887, 0xbc7c, -22499) + R_32_47(rH0, rH1, rH2, rH3, rW13, rW00, 28, 21, + 0x7eb8, -27199, 0x00ea, 0x6050) + R_32_47(rH2, rH3, rH0, rH1, rW03, rW06, 16, 9, + 0xe01a, 0x22fe, 0x4447, 0x69c5) + R_32_47(rH0, rH1, rH2, rH3, rW09, rW12, 28, 21, + 0xb7f3, 0x0253, 0x59b1, 0x4d5b) + R_32_47(rH2, rH3, rH0, rH1, rW15, rW02, 16, 9, + 0x4701, -27017, 0xc7bd, -19859) + + R_48_63(rH0, rH1, rH2, rH3, rW00, rW07, 26, 22, + 0x0988, -1462, 0x4c70, -19401) + R_48_63(rH2, rH3, rH0, rH1, rW14, rW05, 17, 11, + 0xadaf, -5221, 0xfc99, 0x66f7) + R_48_63(rH0, rH1, rH2, rH3, rW12, rW03, 26, 22, + 0x7e80, -16418, 0xba1e, -25587) + R_48_63(rH2, rH3, rH0, rH1, rW10, rW01, 17, 11, + 0x4130, 0x380d, 0xe0c5, 0x738d) + lwz rW00,0(rHP) + R_48_63(rH0, rH1, rH2, rH3, rW08, rW15, 26, 22, + 0xe837, -30770, 0xde8a, 0x69e8) + lwz rW14,4(rHP) + R_48_63(rH2, rH3, rH0, rH1, rW06, rW13, 17, 11, + 0x9e79, 0x260f, 0x256d, -27941) + lwz rW12,8(rHP) + R_48_63(rH0, rH1, rH2, rH3, rW04, rW11, 26, 22, + 0xab75, -20775, 0x4f9e, -28397) + lwz rW10,12(rHP) + R_48_63(rH2, rH3, rH0, rH1, rW02, rW09, 17, 11, + 0x662b, 0x7c56, 0x11b2, 0x0358) + + add rH0,rH0,rW00 + stw rH0,0(rHP) + add rH1,rH1,rW14 + stw rH1,4(rHP) + add rH2,rH2,rW12 + stw rH2,8(rHP) + add rH3,rH3,rW10 + stw rH3,12(rHP) + NEXT_BLOCK + + bdnz ppc_md5_main + + FINALIZE + blr -- GitLab From e90508d3b0866c29146535576931356aba072a86 Mon Sep 17 00:00:00 2001 From: Markus Stockhausen Date: Sun, 1 Mar 2015 19:30:41 +0100 Subject: [PATCH 02494/11651] crypto: powerpc/md5 - glue Glue code for crypto infrastructure. Call the assembler code where required. Take a little care about small input data. Kick out early for input chunks < 64 bytes and replace memset for context cleanup with simple loop. Signed-off-by: Markus Stockhausen Signed-off-by: Herbert Xu --- arch/powerpc/crypto/md5_glue.c | 165 +++++++++++++++++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 arch/powerpc/crypto/md5_glue.c diff --git a/arch/powerpc/crypto/md5_glue.c b/arch/powerpc/crypto/md5_glue.c new file mode 100644 index 000000000000..452fb4dc575f --- /dev/null +++ b/arch/powerpc/crypto/md5_glue.c @@ -0,0 +1,165 @@ +/* + * Glue code for MD5 implementation for PPC assembler + * + * Based on generic implementation. + * + * Copyright (c) 2015 Markus Stockhausen + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +extern void ppc_md5_transform(u32 *state, const u8 *src, u32 blocks); + +static inline void ppc_md5_clear_context(struct md5_state *sctx) +{ + int count = sizeof(struct md5_state) >> 2; + u32 *ptr = (u32 *)sctx; + + /* make sure we can clear the fast way */ + BUILD_BUG_ON(sizeof(struct md5_state) % 4); + do { *ptr++ = 0; } while (--count); +} + +static int ppc_md5_init(struct shash_desc *desc) +{ + struct md5_state *sctx = shash_desc_ctx(desc); + + sctx->hash[0] = 0x67452301; + sctx->hash[1] = 0xefcdab89; + sctx->hash[2] = 0x98badcfe; + sctx->hash[3] = 0x10325476; + sctx->byte_count = 0; + + return 0; +} + +static int ppc_md5_update(struct shash_desc *desc, const u8 *data, + unsigned int len) +{ + struct md5_state *sctx = shash_desc_ctx(desc); + const unsigned int offset = sctx->byte_count & 0x3f; + unsigned int avail = 64 - offset; + const u8 *src = data; + + sctx->byte_count += len; + + if (avail > len) { + memcpy((char *)sctx->block + offset, src, len); + return 0; + } + + if (offset) { + memcpy((char *)sctx->block + offset, src, avail); + ppc_md5_transform(sctx->hash, (const u8 *)sctx->block, 1); + len -= avail; + src += avail; + } + + if (len > 63) { + ppc_md5_transform(sctx->hash, src, len >> 6); + src += len & ~0x3f; + len &= 0x3f; + } + + memcpy((char *)sctx->block, src, len); + return 0; +} + +static int ppc_md5_final(struct shash_desc *desc, u8 *out) +{ + struct md5_state *sctx = shash_desc_ctx(desc); + const unsigned int offset = sctx->byte_count & 0x3f; + const u8 *src = (const u8 *)sctx->block; + u8 *p = (u8 *)src + offset; + int padlen = 55 - offset; + __le64 *pbits = (__le64 *)((char *)sctx->block + 56); + __le32 *dst = (__le32 *)out; + + *p++ = 0x80; + + if (padlen < 0) { + memset(p, 0x00, padlen + sizeof (u64)); + ppc_md5_transform(sctx->hash, src, 1); + p = (char *)sctx->block; + padlen = 56; + } + + memset(p, 0, padlen); + *pbits = cpu_to_le64(sctx->byte_count << 3); + ppc_md5_transform(sctx->hash, src, 1); + + dst[0] = cpu_to_le32(sctx->hash[0]); + dst[1] = cpu_to_le32(sctx->hash[1]); + dst[2] = cpu_to_le32(sctx->hash[2]); + dst[3] = cpu_to_le32(sctx->hash[3]); + + ppc_md5_clear_context(sctx); + return 0; +} + +static int ppc_md5_export(struct shash_desc *desc, void *out) +{ + struct md5_state *sctx = shash_desc_ctx(desc); + + memcpy(out, sctx, sizeof(*sctx)); + return 0; +} + +static int ppc_md5_import(struct shash_desc *desc, const void *in) +{ + struct md5_state *sctx = shash_desc_ctx(desc); + + memcpy(sctx, in, sizeof(*sctx)); + return 0; +} + +static struct shash_alg alg = { + .digestsize = MD5_DIGEST_SIZE, + .init = ppc_md5_init, + .update = ppc_md5_update, + .final = ppc_md5_final, + .export = ppc_md5_export, + .import = ppc_md5_import, + .descsize = sizeof(struct md5_state), + .statesize = sizeof(struct md5_state), + .base = { + .cra_name = "md5", + .cra_driver_name= "md5-ppc", + .cra_priority = 200, + .cra_flags = CRYPTO_ALG_TYPE_SHASH, + .cra_blocksize = MD5_HMAC_BLOCK_SIZE, + .cra_module = THIS_MODULE, + } +}; + +static int __init ppc_md5_mod_init(void) +{ + return crypto_register_shash(&alg); +} + +static void __exit ppc_md5_mod_fini(void) +{ + crypto_unregister_shash(&alg); +} + +module_init(ppc_md5_mod_init); +module_exit(ppc_md5_mod_fini); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("MD5 Secure Hash Algorithm, PPC assembler"); + +MODULE_ALIAS_CRYPTO("md5"); +MODULE_ALIAS_CRYPTO("md5-ppc"); -- GitLab From e8e5995372ac3fc63995915dcb351f38a3560018 Mon Sep 17 00:00:00 2001 From: Markus Stockhausen Date: Sun, 1 Mar 2015 19:30:46 +0100 Subject: [PATCH 02495/11651] crypto: powerpc/md5 - kernel config Integrate the module into the kernel config tree. Signed-off-by: Markus Stockhausen Signed-off-by: Herbert Xu --- arch/powerpc/crypto/Makefile | 2 ++ crypto/Kconfig | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/arch/powerpc/crypto/Makefile b/arch/powerpc/crypto/Makefile index d400bf9e43c6..c6b25cba3a0c 100644 --- a/arch/powerpc/crypto/Makefile +++ b/arch/powerpc/crypto/Makefile @@ -5,11 +5,13 @@ # obj-$(CONFIG_CRYPTO_AES_PPC_SPE) += aes-ppc-spe.o +obj-$(CONFIG_CRYPTO_MD5_PPC) += md5-ppc.o obj-$(CONFIG_CRYPTO_SHA1_PPC) += sha1-powerpc.o obj-$(CONFIG_CRYPTO_SHA1_PPC_SPE) += sha1-ppc-spe.o obj-$(CONFIG_CRYPTO_SHA256_PPC_SPE) += sha256-ppc-spe.o aes-ppc-spe-y := aes-spe-core.o aes-spe-keys.o aes-tab-4k.o aes-spe-modes.o aes_spe_glue.o +md5-ppc-y := md5-asm.o md5_glue.o sha1-powerpc-y := sha1-powerpc-asm.o sha1.o sha1-ppc-spe-y := sha1-spe-asm.o sha1_spe_glue.o sha256-ppc-spe-y := sha256-spe-asm.o sha256_spe_glue.o diff --git a/crypto/Kconfig b/crypto/Kconfig index e74cecadef70..6918aff74f4d 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -436,6 +436,14 @@ config CRYPTO_MD5_OCTEON MD5 message digest algorithm (RFC1321) implemented using OCTEON crypto instructions, when available. +config CRYPTO_MD5_PPC + tristate "MD5 digest algorithm (PPC)" + depends on PPC + select CRYPTO_HASH + help + MD5 message digest algorithm (RFC1321) implemented + in PPC assembler. + config CRYPTO_MD5_SPARC64 tristate "MD5 digest algorithm (SPARC64)" depends on SPARC64 -- GitLab From 04bcbfcf7e28ba502383a8e19d99960ab8e347c8 Mon Sep 17 00:00:00 2001 From: Stephan Mueller Date: Sun, 1 Mar 2015 20:39:17 +0100 Subject: [PATCH 02496/11651] crypto: drbg - use single block cipher API The CTR DRBG only encrypts one single block at a time. Thus, use the single block crypto API to avoid additional overhead from the block chaining modes. With the patch, the speed of the DRBG increases between 30% and 40%. The DRBG still passes the CTR DRBG CAVS test. Signed-off-by: Stephan Mueller Signed-off-by: Herbert Xu --- crypto/drbg.c | 39 ++++++++++++++++----------------------- 1 file changed, 16 insertions(+), 23 deletions(-) diff --git a/crypto/drbg.c b/crypto/drbg.c index d8ff16e5c322..c14274ac8d61 100644 --- a/crypto/drbg.c +++ b/crypto/drbg.c @@ -119,19 +119,19 @@ static const struct drbg_core drbg_cores[] = { .statelen = 32, /* 256 bits as defined in 10.2.1 */ .blocklen_bytes = 16, .cra_name = "ctr_aes128", - .backend_cra_name = "ecb(aes)", + .backend_cra_name = "aes", }, { .flags = DRBG_CTR | DRBG_STRENGTH192, .statelen = 40, /* 320 bits as defined in 10.2.1 */ .blocklen_bytes = 16, .cra_name = "ctr_aes192", - .backend_cra_name = "ecb(aes)", + .backend_cra_name = "aes", }, { .flags = DRBG_CTR | DRBG_STRENGTH256, .statelen = 48, /* 384 bits as defined in 10.2.1 */ .blocklen_bytes = 16, .cra_name = "ctr_aes256", - .backend_cra_name = "ecb(aes)", + .backend_cra_name = "aes", }, #endif /* CONFIG_CRYPTO_DRBG_CTR */ #ifdef CONFIG_CRYPTO_DRBG_HASH @@ -1644,24 +1644,24 @@ static int drbg_kcapi_hash(struct drbg_state *drbg, const unsigned char *key, static int drbg_init_sym_kernel(struct drbg_state *drbg) { int ret = 0; - struct crypto_blkcipher *tfm; + struct crypto_cipher *tfm; - tfm = crypto_alloc_blkcipher(drbg->core->backend_cra_name, 0, 0); + tfm = crypto_alloc_cipher(drbg->core->backend_cra_name, 0, 0); if (IS_ERR(tfm)) { pr_info("DRBG: could not allocate cipher TFM handle\n"); return PTR_ERR(tfm); } - BUG_ON(drbg_blocklen(drbg) != crypto_blkcipher_blocksize(tfm)); + BUG_ON(drbg_blocklen(drbg) != crypto_cipher_blocksize(tfm)); drbg->priv_data = tfm; return ret; } static int drbg_fini_sym_kernel(struct drbg_state *drbg) { - struct crypto_blkcipher *tfm = - (struct crypto_blkcipher *)drbg->priv_data; + struct crypto_cipher *tfm = + (struct crypto_cipher *)drbg->priv_data; if (tfm) - crypto_free_blkcipher(tfm); + crypto_free_cipher(tfm); drbg->priv_data = NULL; return 0; } @@ -1669,21 +1669,14 @@ static int drbg_fini_sym_kernel(struct drbg_state *drbg) static int drbg_kcapi_sym(struct drbg_state *drbg, const unsigned char *key, unsigned char *outval, const struct drbg_string *in) { - int ret = 0; - struct scatterlist sg_in, sg_out; - struct blkcipher_desc desc; - struct crypto_blkcipher *tfm = - (struct crypto_blkcipher *)drbg->priv_data; - - desc.tfm = tfm; - desc.flags = 0; - crypto_blkcipher_setkey(tfm, key, (drbg_keylen(drbg))); - /* there is only component in *in */ - sg_init_one(&sg_in, in->buf, in->len); - sg_init_one(&sg_out, outval, drbg_blocklen(drbg)); - ret = crypto_blkcipher_encrypt(&desc, &sg_out, &sg_in, in->len); + struct crypto_cipher *tfm = + (struct crypto_cipher *)drbg->priv_data; - return ret; + crypto_cipher_setkey(tfm, key, (drbg_keylen(drbg))); + /* there is only component in *in */ + BUG_ON(in->len < drbg_blocklen(drbg)); + crypto_cipher_encrypt_one(tfm, outval, in->buf); + return 0; } #endif /* CONFIG_CRYPTO_DRBG_CTR */ -- GitLab From 37821da088d090d8e152f3f8cc072948fa544e5a Mon Sep 17 00:00:00 2001 From: Stephan Mueller Date: Sun, 1 Mar 2015 20:40:17 +0100 Subject: [PATCH 02497/11651] crypto: drbg - remove superflowous memsets The DRBG code contains memset(0) calls to initialize a varaible that are not necessary as the variable is always overwritten by the processing. This patch increases the CTR and Hash DRBGs by about 5%. Signed-off-by: Stephan Mueller Signed-off-by: Herbert Xu --- crypto/drbg.c | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/crypto/drbg.c b/crypto/drbg.c index c14274ac8d61..56c1d7ec3d9e 100644 --- a/crypto/drbg.c +++ b/crypto/drbg.c @@ -308,9 +308,6 @@ static int drbg_ctr_bcc(struct drbg_state *drbg, drbg_string_fill(&data, out, drbg_blocklen(drbg)); - /* 10.4.3 step 1 */ - memset(out, 0, drbg_blocklen(drbg)); - /* 10.4.3 step 2 / 4 */ list_for_each_entry(curr, in, list) { const unsigned char *pos = curr->buf; @@ -406,7 +403,6 @@ static int drbg_ctr_df(struct drbg_state *drbg, memset(pad, 0, drbg_blocklen(drbg)); memset(iv, 0, drbg_blocklen(drbg)); - memset(temp, 0, drbg_statelen(drbg)); /* 10.4.2 step 1 is implicit as we work byte-wise */ @@ -523,7 +519,6 @@ static int drbg_ctr_update(struct drbg_state *drbg, struct list_head *seed, unsigned int len = 0; struct drbg_string cipherin; - memset(temp, 0, drbg_statelen(drbg) + drbg_blocklen(drbg)); if (3 > reseed) memset(df_data, 0, drbg_statelen(drbg)); @@ -585,8 +580,6 @@ static int drbg_ctr_generate(struct drbg_state *drbg, int ret = 0; struct drbg_string data; - memset(drbg->scratchpad, 0, drbg_blocklen(drbg)); - /* 10.2.1.5.2 step 2 */ if (addtl && !list_empty(addtl)) { ret = drbg_ctr_update(drbg, addtl, 2); @@ -761,7 +754,6 @@ static struct drbg_state_ops drbg_hmac_ops = { .generate = drbg_hmac_generate, .crypto_init = drbg_init_hash_kernel, .crypto_fini = drbg_fini_hash_kernel, - }; #endif /* CONFIG_CRYPTO_DRBG_HMAC */ @@ -838,8 +830,6 @@ static int drbg_hash_df(struct drbg_state *drbg, unsigned char *tmp = drbg->scratchpad + drbg_statelen(drbg); struct drbg_string data; - memset(tmp, 0, drbg_blocklen(drbg)); - /* 10.4.1 step 3 */ input[0] = 1; drbg_cpu_to_be32((outlen * 8), &input[1]); @@ -879,7 +869,6 @@ static int drbg_hash_update(struct drbg_state *drbg, struct list_head *seed, unsigned char *V = drbg->scratchpad; unsigned char prefix = DRBG_PREFIX1; - memset(drbg->scratchpad, 0, drbg_statelen(drbg)); if (!seed) return -EINVAL; @@ -921,9 +910,6 @@ static int drbg_hash_process_addtl(struct drbg_state *drbg, LIST_HEAD(datalist); unsigned char prefix = DRBG_PREFIX2; - /* this is value w as per documentation */ - memset(drbg->scratchpad, 0, drbg_blocklen(drbg)); - /* 10.1.1.4 step 2 */ if (!addtl || list_empty(addtl)) return 0; @@ -959,9 +945,6 @@ static int drbg_hash_hashgen(struct drbg_state *drbg, struct drbg_string data; LIST_HEAD(datalist); - memset(src, 0, drbg_statelen(drbg)); - memset(dst, 0, drbg_blocklen(drbg)); - /* 10.1.1.4 step hashgen 2 */ memcpy(src, drbg->V, drbg_statelen(drbg)); @@ -1018,7 +1001,6 @@ static int drbg_hash_generate(struct drbg_state *drbg, len = drbg_hash_hashgen(drbg, buf, buflen); /* this is the value H as documented in 10.1.1.4 */ - memset(drbg->scratchpad, 0, drbg_blocklen(drbg)); /* 10.1.1.4 step 4 */ drbg_string_fill(&data1, &prefix, 1); list_add_tail(&data1.list, &datalist); -- GitLab From 86044c8c14b618b11558d3cba96aa0548c81274d Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Thu, 26 Feb 2015 13:53:47 +0100 Subject: [PATCH 02498/11651] KVM: s390/cpacf: Fix kernel bug under z/VM Under z/VM PQAP might trigger an operation exception if no crypto cards are defined via APVIRTUAL or APDEDICATED. [ 386.098666] Kernel BUG at 0000000000135c56 [verbose debug info unavailable] [ 386.098693] illegal operation: 0001 ilc:2 [#1] SMP [...] [ 386.098751] Krnl PSW : 0704c00180000000 0000000000135c56 (kvm_s390_apxa_installed+0x46/0x98) [...] [ 386.098804] [<000000000013627c>] kvm_arch_init_vm+0x29c/0x358 [ 386.098806] [<000000000012d008>] kvm_dev_ioctl+0xc0/0x460 [ 386.098809] [<00000000002c639a>] do_vfs_ioctl+0x332/0x508 [ 386.098811] [<00000000002c660e>] SyS_ioctl+0x9e/0xb0 [ 386.098814] [<000000000070476a>] system_call+0xd6/0x258 [ 386.098815] [<000003fffc7400a2>] 0x3fffc7400a2 Lets add an extable entry and provide a zeroed config in that case. Reported-by: Stefan Zimmermann Signed-off-by: Christian Borntraeger Reviewed-by: Thomas Huth Tested-by: Stefan Zimmermann --- arch/s390/kvm/kvm-s390.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index b4d2030c22eb..18965f91d39e 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -778,15 +778,18 @@ long kvm_arch_vm_ioctl(struct file *filp, static int kvm_s390_query_ap_config(u8 *config) { u32 fcn_code = 0x04000000UL; - u32 cc; + u32 cc = 0; + memset(config, 0, 128); asm volatile( "lgr 0,%1\n" "lgr 2,%2\n" ".long 0xb2af0000\n" /* PQAP(QCI) */ - "ipm %0\n" + "0: ipm %0\n" "srl %0,28\n" - : "=r" (cc) + "1:\n" + EX_TABLE(0b, 1b) + : "+r" (cc) : "r" (fcn_code), "r" (config) : "cc", "0", "2", "memory" ); -- GitLab From a009d692086b95c38a1047df7c7abae98630e009 Mon Sep 17 00:00:00 2001 From: Jonas Andersson Date: Fri, 30 Jan 2015 12:25:10 +0100 Subject: [PATCH 02499/11651] ARM: at91/dt: at91sam9260: fix usart pinctrl Corrected pins used by usart3. Signed-off-by: Jonas Andersson Acked-by: Alexandre Belloni Signed-off-by: Nicolas Ferre --- arch/arm/boot/dts/at91sam9260.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/at91sam9260.dtsi b/arch/arm/boot/dts/at91sam9260.dtsi index fff0ee69aab4..affeebe620f6 100644 --- a/arch/arm/boot/dts/at91sam9260.dtsi +++ b/arch/arm/boot/dts/at91sam9260.dtsi @@ -494,12 +494,12 @@ pinctrl_usart3_rts: usart3_rts-0 { atmel,pins = - ; /* PC8 periph B */ + ; }; pinctrl_usart3_cts: usart3_cts-0 { atmel,pins = - ; /* PC10 periph B */ + ; }; }; -- GitLab From a8eef13a83e70c5fcb5ae32fb6845e03cf8ed619 Mon Sep 17 00:00:00 2001 From: Anthony Harivel Date: Thu, 5 Feb 2015 22:59:36 +0100 Subject: [PATCH 02500/11651] ARM: at91/defconfig: remove CONFIG_SYSFS_DEPRECATED Recent distributions and userspace tools after 2009/2010 depend on the existence of /sys/class/block/, and will not work with this option enabled. Signed-off-by: Anthony Harivel Signed-off-by: Nicolas Ferre --- arch/arm/configs/sama5_defconfig | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/arm/configs/sama5_defconfig b/arch/arm/configs/sama5_defconfig index 41d856effe6c..510c747c65b4 100644 --- a/arch/arm/configs/sama5_defconfig +++ b/arch/arm/configs/sama5_defconfig @@ -3,8 +3,6 @@ CONFIG_SYSVIPC=y CONFIG_IRQ_DOMAIN_DEBUG=y CONFIG_LOG_BUF_SHIFT=14 -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y CONFIG_BLK_DEV_INITRD=y CONFIG_EMBEDDED=y CONFIG_SLAB=y -- GitLab From efff4b1a5a701236c384eaec1fc5a8826e10e071 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 5 Jan 2015 12:53:02 +0100 Subject: [PATCH 02501/11651] ARM: at91/defconfig: add at91rm9200 ethernet support There is now only one defconfig for the at91rm9200 and at91sam9. Add ethernet support for the at91rm9200. Signed-off-by: Alexandre Belloni Signed-off-by: Nicolas Ferre --- arch/arm/configs/at91_dt_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/configs/at91_dt_defconfig b/arch/arm/configs/at91_dt_defconfig index f2670f638e97..811e72bbe642 100644 --- a/arch/arm/configs/at91_dt_defconfig +++ b/arch/arm/configs/at91_dt_defconfig @@ -70,6 +70,7 @@ CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y # CONFIG_SCSI_LOWLEVEL is not set CONFIG_NETDEVICES=y +CONFIG_ARM_AT91_ETHER=y CONFIG_MACB=y # CONFIG_NET_VENDOR_BROADCOM is not set CONFIG_DM9000=y -- GitLab From 94422ee880afc4af050bac172ea39af8e2130034 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Thu, 26 Feb 2015 12:12:40 +0100 Subject: [PATCH 02502/11651] KVM: s390: fix in memory copy of facility lists The facility lists were not fully copied. Signed-off-by: Michael Mueller Signed-off-by: Christian Borntraeger --- arch/s390/kvm/kvm-s390.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 18965f91d39e..76894c8db4d7 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -579,7 +579,7 @@ static int kvm_s390_get_machine(struct kvm *kvm, struct kvm_device_attr *attr) memcpy(&mach->fac_mask, kvm_s390_fac_list_mask, kvm_s390_fac_list_mask_size() * sizeof(u64)); memcpy((unsigned long *)&mach->fac_list, S390_lowcore.stfle_fac_list, - S390_ARCH_FAC_LIST_SIZE_U64); + S390_ARCH_FAC_LIST_SIZE_BYTE); if (copy_to_user((void __user *)attr->addr, mach, sizeof(*mach))) ret = -EFAULT; kfree(mach); @@ -903,7 +903,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) goto out_nofac; memcpy(kvm->arch.model.fac->kvm, S390_lowcore.stfle_fac_list, - S390_ARCH_FAC_LIST_SIZE_U64); + S390_ARCH_FAC_LIST_SIZE_BYTE); /* * If this KVM host runs *not* in a LPAR, relax the facility bits -- GitLab From 981467c930bdfa4be59acbbc9f3a80eb9e3167a8 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Tue, 24 Feb 2015 13:51:04 +0100 Subject: [PATCH 02503/11651] KVM: s390: include guest facilities in kvm facility test Most facility related decisions in KVM have to take into account: - the facilities offered by the underlying run container (LPAR/VM) - the facilities supported by the KVM code itself - the facilities requested by a guest VM This patch adds the KVM driver requested facilities to the test routine. It additionally renames struct s390_model_fac to kvm_s390_fac and its field names to be more meaningful. The semantics of the facilities stored in the KVM architecture structure is changed. The address arch.model.fac->list now points to the guest facility list and arch.model.fac->mask points to the KVM facility mask. This patch fixes the behaviour of KVM for some facilities for guests that ignore the guest visible facility bits, e.g. guests could use transactional memory intructions on hosts supporting them even if the chosen cpu model would not offer them. The userspace interface is not affected by this change. Signed-off-by: Michael Mueller Signed-off-by: Christian Borntraeger --- arch/s390/include/asm/kvm_host.h | 12 ++++++------ arch/s390/kvm/kvm-s390.c | 30 ++++++++++++++++-------------- arch/s390/kvm/kvm-s390.h | 3 ++- arch/s390/kvm/priv.c | 2 +- 4 files changed, 25 insertions(+), 22 deletions(-) diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h index d84559e31f32..f407bbf5ee94 100644 --- a/arch/s390/include/asm/kvm_host.h +++ b/arch/s390/include/asm/kvm_host.h @@ -515,15 +515,15 @@ struct s390_io_adapter { #define S390_ARCH_FAC_MASK_SIZE_U64 \ (S390_ARCH_FAC_MASK_SIZE_BYTE / sizeof(u64)) -struct s390_model_fac { - /* facilities used in SIE context */ - __u64 sie[S390_ARCH_FAC_LIST_SIZE_U64]; - /* subset enabled by kvm */ - __u64 kvm[S390_ARCH_FAC_LIST_SIZE_U64]; +struct kvm_s390_fac { + /* facility list requested by guest */ + __u64 list[S390_ARCH_FAC_LIST_SIZE_U64]; + /* facility mask supported by kvm & hosting machine */ + __u64 mask[S390_ARCH_FAC_LIST_SIZE_U64]; }; struct kvm_s390_cpu_model { - struct s390_model_fac *fac; + struct kvm_s390_fac *fac; struct cpuid cpu_id; unsigned short ibc; }; diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 76894c8db4d7..5a02be4628f1 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -522,7 +522,7 @@ static int kvm_s390_set_processor(struct kvm *kvm, struct kvm_device_attr *attr) memcpy(&kvm->arch.model.cpu_id, &proc->cpuid, sizeof(struct cpuid)); kvm->arch.model.ibc = proc->ibc; - memcpy(kvm->arch.model.fac->kvm, proc->fac_list, + memcpy(kvm->arch.model.fac->list, proc->fac_list, S390_ARCH_FAC_LIST_SIZE_BYTE); } else ret = -EFAULT; @@ -556,7 +556,7 @@ static int kvm_s390_get_processor(struct kvm *kvm, struct kvm_device_attr *attr) } memcpy(&proc->cpuid, &kvm->arch.model.cpu_id, sizeof(struct cpuid)); proc->ibc = kvm->arch.model.ibc; - memcpy(&proc->fac_list, kvm->arch.model.fac->kvm, S390_ARCH_FAC_LIST_SIZE_BYTE); + memcpy(&proc->fac_list, kvm->arch.model.fac->list, S390_ARCH_FAC_LIST_SIZE_BYTE); if (copy_to_user((void __user *)attr->addr, proc, sizeof(*proc))) ret = -EFAULT; kfree(proc); @@ -576,8 +576,8 @@ static int kvm_s390_get_machine(struct kvm *kvm, struct kvm_device_attr *attr) } get_cpu_id((struct cpuid *) &mach->cpuid); mach->ibc = sclp_get_ibc(); - memcpy(&mach->fac_mask, kvm_s390_fac_list_mask, - kvm_s390_fac_list_mask_size() * sizeof(u64)); + memcpy(&mach->fac_mask, kvm->arch.model.fac->mask, + S390_ARCH_FAC_LIST_SIZE_BYTE); memcpy((unsigned long *)&mach->fac_list, S390_lowcore.stfle_fac_list, S390_ARCH_FAC_LIST_SIZE_BYTE); if (copy_to_user((void __user *)attr->addr, mach, sizeof(*mach))) @@ -893,16 +893,16 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) /* * The architectural maximum amount of facilities is 16 kbit. To store * this amount, 2 kbyte of memory is required. Thus we need a full - * page to hold the active copy (arch.model.fac->sie) and the current - * facilities set (arch.model.fac->kvm). Its address size has to be + * page to hold the guest facility list (arch.model.fac->list) and the + * facility mask (arch.model.fac->mask). Its address size has to be * 31 bits and word aligned. */ kvm->arch.model.fac = - (struct s390_model_fac *) get_zeroed_page(GFP_KERNEL | GFP_DMA); + (struct kvm_s390_fac *) get_zeroed_page(GFP_KERNEL | GFP_DMA); if (!kvm->arch.model.fac) goto out_nofac; - memcpy(kvm->arch.model.fac->kvm, S390_lowcore.stfle_fac_list, + memcpy(kvm->arch.model.fac->mask, S390_lowcore.stfle_fac_list, S390_ARCH_FAC_LIST_SIZE_BYTE); /* @@ -914,7 +914,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) */ if (!MACHINE_IS_LPAR) for (i = 0; i < kvm_s390_fac_list_mask_size(); i++) - kvm_s390_fac_list_mask[i] &= kvm->arch.model.fac->kvm[i]; + kvm_s390_fac_list_mask[i] &= kvm->arch.model.fac->mask[i]; /* * Apply the kvm facility mask to limit the kvm supported/tolerated @@ -922,11 +922,15 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) */ for (i = 0; i < S390_ARCH_FAC_LIST_SIZE_U64; i++) { if (i < kvm_s390_fac_list_mask_size()) - kvm->arch.model.fac->kvm[i] &= kvm_s390_fac_list_mask[i]; + kvm->arch.model.fac->mask[i] &= kvm_s390_fac_list_mask[i]; else - kvm->arch.model.fac->kvm[i] = 0UL; + kvm->arch.model.fac->mask[i] = 0UL; } + /* Populate the facility list initially. */ + memcpy(kvm->arch.model.fac->list, kvm->arch.model.fac->mask, + S390_ARCH_FAC_LIST_SIZE_BYTE); + kvm_s390_get_cpu_id(&kvm->arch.model.cpu_id); kvm->arch.model.ibc = sclp_get_ibc() & 0x0fff; @@ -1172,8 +1176,6 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) mutex_lock(&vcpu->kvm->lock); vcpu->arch.cpu_id = vcpu->kvm->arch.model.cpu_id; - memcpy(vcpu->kvm->arch.model.fac->sie, vcpu->kvm->arch.model.fac->kvm, - S390_ARCH_FAC_LIST_SIZE_BYTE); vcpu->arch.sie_block->ibc = vcpu->kvm->arch.model.ibc; mutex_unlock(&vcpu->kvm->lock); @@ -1219,7 +1221,7 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, vcpu->arch.sie_block->scaol = (__u32)(__u64)kvm->arch.sca; set_bit(63 - id, (unsigned long *) &kvm->arch.sca->mcn); } - vcpu->arch.sie_block->fac = (int) (long) kvm->arch.model.fac->sie; + vcpu->arch.sie_block->fac = (int) (long) kvm->arch.model.fac->list; spin_lock_init(&vcpu->arch.local_int.lock); vcpu->arch.local_int.float_int = &kvm->arch.float_int; diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h index 985c2114d7ef..c34109aa552d 100644 --- a/arch/s390/kvm/kvm-s390.h +++ b/arch/s390/kvm/kvm-s390.h @@ -128,7 +128,8 @@ static inline void kvm_s390_set_psw_cc(struct kvm_vcpu *vcpu, unsigned long cc) /* test availability of facility in a kvm intance */ static inline int test_kvm_facility(struct kvm *kvm, unsigned long nr) { - return __test_facility(nr, kvm->arch.model.fac->kvm); + return __test_facility(nr, kvm->arch.model.fac->mask) && + __test_facility(nr, kvm->arch.model.fac->list); } /* are cpu states controlled by user space */ diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c index bdd9b5b17e03..351116939ea2 100644 --- a/arch/s390/kvm/priv.c +++ b/arch/s390/kvm/priv.c @@ -348,7 +348,7 @@ static int handle_stfl(struct kvm_vcpu *vcpu) * We need to shift the lower 32 facility bits (bit 0-31) from a u64 * into a u32 memory representation. They will remain bits 0-31. */ - fac = *vcpu->kvm->arch.model.fac->sie >> 32; + fac = *vcpu->kvm->arch.model.fac->list >> 32; rc = write_guest_lc(vcpu, offsetof(struct _lowcore, stfl_fac_list), &fac, sizeof(fac)); if (rc) -- GitLab From fb5bf93f84c277546473be35543ed7890f6e6742 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Fri, 27 Feb 2015 14:25:10 +0100 Subject: [PATCH 02504/11651] KVM: s390: non-LPAR case obsolete during facilities mask init With patch "include guest facilities in kvm facility test" it is no longer necessary to have special handling for the non-LPAR case. Signed-off-by: Michael Mueller Signed-off-by: Christian Borntraeger --- arch/s390/kvm/kvm-s390.c | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 5a02be4628f1..f6579cfde2df 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -902,24 +902,9 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) if (!kvm->arch.model.fac) goto out_nofac; + /* Populate the facility mask initially. */ memcpy(kvm->arch.model.fac->mask, S390_lowcore.stfle_fac_list, S390_ARCH_FAC_LIST_SIZE_BYTE); - - /* - * If this KVM host runs *not* in a LPAR, relax the facility bits - * of the kvm facility mask by all missing facilities. This will allow - * to determine the right CPU model by means of the remaining facilities. - * Live guest migration must prohibit the migration of KVMs running in - * a LPAR to non LPAR hosts. - */ - if (!MACHINE_IS_LPAR) - for (i = 0; i < kvm_s390_fac_list_mask_size(); i++) - kvm_s390_fac_list_mask[i] &= kvm->arch.model.fac->mask[i]; - - /* - * Apply the kvm facility mask to limit the kvm supported/tolerated - * facility list. - */ for (i = 0; i < S390_ARCH_FAC_LIST_SIZE_U64; i++) { if (i < kvm_s390_fac_list_mask_size()) kvm->arch.model.fac->mask[i] &= kvm_s390_fac_list_mask[i]; -- GitLab From ef7c67257c9a0765bd1a53f83fd63d55a0f7b224 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sun, 1 Mar 2015 09:10:06 +0200 Subject: [PATCH 02505/11651] mac80211: don't do driver suspend with auth/assoc in progress Drivers can't really be expected to suspend properly while auth or assoc is in progress since then they don't have any state they could keep with WoWLAN, nor can they actually finish the authentication or association. In fact, keeping this can cause subtle issues with drivers like iwlwifi that refuse WoWLAN if not associated, but have trouble figuring out what's going on in the middle of association. In any case, regardless of possible driver issues in this area, it doesn't make sense for mac80211 to try to WoWLAN-suspend in the middle of such operations, so stop them before. Signed-off-by: Johannes Berg --- net/mac80211/pm.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c index ca405b6b686d..bd185f38def1 100644 --- a/net/mac80211/pm.c +++ b/net/mac80211/pm.c @@ -61,7 +61,24 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) local->wowlan = wowlan && local->open_count; if (local->wowlan) { - int err = drv_suspend(local, wowlan); + int err; + + /* Drivers don't expect to suspend while some operations like + * authenticating or associating are in progress. It doesn't + * make sense anyway to accept that, since the authentication + * or association would never finish since the driver can't do + * that on its own. + * Thus, clean up in-progress auth/assoc first. + */ + list_for_each_entry(sdata, &local->interfaces, list) { + if (!ieee80211_sdata_running(sdata)) + continue; + if (sdata->vif.type != NL80211_IFTYPE_STATION) + continue; + ieee80211_mgd_quiesce(sdata); + } + + err = drv_suspend(local, wowlan); if (err < 0) { local->quiescing = false; local->wowlan = false; -- GitLab From 8bb6f4b9c50eef838931e0e667f1a451f34a76ae Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Sun, 1 Mar 2015 09:10:07 +0200 Subject: [PATCH 02506/11651] mac80211: remove useless double check for open_count in __ieee80211_suspend() We check local->open_count at the top of the __ieee80211_suspend(), so there's no need to check for it again. open_count is protected by the rtnl, so there's no chance for it to have change between the two calls. Signed-off-by: Luciano Coelho Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- net/mac80211/pm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c index bd185f38def1..46ffe3ad7c46 100644 --- a/net/mac80211/pm.c +++ b/net/mac80211/pm.c @@ -59,7 +59,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) cancel_work_sync(&local->dynamic_ps_enable_work); del_timer_sync(&local->dynamic_ps_timer); - local->wowlan = wowlan && local->open_count; + local->wowlan = wowlan; if (local->wowlan) { int err; -- GitLab From 23e370989c3fe6b9b2062d9d511feda800434de3 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sun, 1 Mar 2015 09:10:08 +0200 Subject: [PATCH 02507/11651] mac80211: start queues if driver rejected wowlan If the driver rejects WoWLAN, restart the queues before returning to cfg80211. cfg80211 will return to mac80211, but not before it disconnects all interfaces. If we don't start the queues, any of the packets needed for disconnecting won't be transmitted, which is strange. Fix that. Signed-off-by: Johannes Berg --- net/mac80211/pm.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c index 46ffe3ad7c46..ac6ad6238e3a 100644 --- a/net/mac80211/pm.c +++ b/net/mac80211/pm.c @@ -97,6 +97,13 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) return err; } else if (err > 0) { WARN_ON(err != 1); + /* cfg80211 will call back into mac80211 to disconnect + * all interfaces, allow that to proceed properly + */ + ieee80211_wake_queues_by_reason(hw, + IEEE80211_MAX_QUEUE_MAP, + IEEE80211_QUEUE_STOP_REASON_SUSPEND, + false); return err; } else { goto suspend; -- GitLab From ae2e9fba85f69e0b53b1ef15e3011ce09ac1b9f2 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Sun, 1 Mar 2015 09:10:09 +0200 Subject: [PATCH 02508/11651] mac80211: allow TDLS setup code to take wdev lock TDLS off-channel can be allowed in channels marked with GO_CONCURRENT, provided the device is connected to an AP on the same UNII. When relaxing the NO-IR requirements for TDLS, we might hit flows in cfg80211_reg_can_beacon that acquire the wdev lock. Take some measures to allow this during TDLS setup. Acquire the RCU read lock later in the flow that invokes cfg80211_reg_can_beacon. Avoid taking local->mtx when preparing the setup packet to avoid circular deadlocks with mac80211 code that is invoked with wdev-mtx held. Signed-off-by: Arik Nemtsov Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- net/mac80211/tdls.c | 41 ++++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/net/mac80211/tdls.c b/net/mac80211/tdls.c index 5bcd542e4933..bc7e4049896f 100644 --- a/net/mac80211/tdls.c +++ b/net/mac80211/tdls.c @@ -287,17 +287,6 @@ ieee80211_tdls_add_setup_start_ies(struct ieee80211_sub_if_data *sdata, size_t offset = 0, noffset; u8 *pos; - rcu_read_lock(); - - /* we should have the peer STA if we're already responding */ - if (action_code == WLAN_TDLS_SETUP_RESPONSE) { - sta = sta_info_get(sdata, peer); - if (WARN_ON_ONCE(!sta)) { - rcu_read_unlock(); - return; - } - } - ieee80211_add_srates_ie(sdata, skb, false, band); ieee80211_add_ext_srates_ie(sdata, skb, false, band); ieee80211_tdls_add_supp_channels(sdata, skb); @@ -350,6 +339,17 @@ ieee80211_tdls_add_setup_start_ies(struct ieee80211_sub_if_data *sdata, offset = noffset; } + rcu_read_lock(); + + /* we should have the peer STA if we're already responding */ + if (action_code == WLAN_TDLS_SETUP_RESPONSE) { + sta = sta_info_get(sdata, peer); + if (WARN_ON_ONCE(!sta)) { + rcu_read_unlock(); + return; + } + } + /* * with TDLS we can switch channels, and HT-caps are not necessarily * the same on all bands. The specification limits the setup to a @@ -983,7 +983,7 @@ ieee80211_tdls_mgmt_setup(struct wiphy *wiphy, struct net_device *dev, if (!is_zero_ether_addr(sdata->u.mgd.tdls_peer) && !ether_addr_equal(sdata->u.mgd.tdls_peer, peer)) { ret = -EBUSY; - goto exit; + goto out_unlock; } /* @@ -998,27 +998,34 @@ ieee80211_tdls_mgmt_setup(struct wiphy *wiphy, struct net_device *dev, if (!sta_info_get(sdata, peer)) { rcu_read_unlock(); ret = -ENOLINK; - goto exit; + goto out_unlock; } rcu_read_unlock(); } ieee80211_flush_queues(local, sdata, false); + memcpy(sdata->u.mgd.tdls_peer, peer, ETH_ALEN); + mutex_unlock(&local->mtx); + /* we cannot take the mutex while preparing the setup packet */ ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer, action_code, dialog_token, status_code, peer_capability, initiator, extra_ies, extra_ies_len, 0, NULL); - if (ret < 0) - goto exit; + if (ret < 0) { + mutex_lock(&local->mtx); + eth_zero_addr(sdata->u.mgd.tdls_peer); + mutex_unlock(&local->mtx); + return ret; + } - memcpy(sdata->u.mgd.tdls_peer, peer, ETH_ALEN); ieee80211_queue_delayed_work(&sdata->local->hw, &sdata->u.mgd.tdls_peer_del_work, TDLS_PEER_SETUP_TIMEOUT); + return 0; -exit: +out_unlock: mutex_unlock(&local->mtx); return ret; } -- GitLab From 0b4e11074a933937ee75be371d32bf91a0051419 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Sun, 1 Mar 2015 09:10:10 +0200 Subject: [PATCH 02509/11651] mac80211: remove duplicate check for quiescing when queueing work In ieee80211_queue_work() we check if we're quiescing or suspended, so it's not necessary to check for quiescing before calling this function. Remove duplicate checks. Signed-off-by: Luciano Coelho Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- net/mac80211/mlme.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index c5f3bd6ac99e..bc2975e91272 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1621,9 +1621,6 @@ void ieee80211_dynamic_ps_timer(unsigned long data) { struct ieee80211_local *local = (void *) data; - if (local->quiescing || local->suspended) - return; - ieee80211_queue_work(&local->hw, &local->dynamic_ps_enable_work); } @@ -3899,12 +3896,8 @@ static void ieee80211_sta_bcn_mon_timer(unsigned long data) { struct ieee80211_sub_if_data *sdata = (struct ieee80211_sub_if_data *) data; - struct ieee80211_local *local = sdata->local; struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; - if (local->quiescing) - return; - if (sdata->vif.csa_active && !ifmgd->csa_waiting_bcn) return; @@ -3920,9 +3913,6 @@ static void ieee80211_sta_conn_mon_timer(unsigned long data) struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; struct ieee80211_local *local = sdata->local; - if (local->quiescing) - return; - if (sdata->vif.csa_active && !ifmgd->csa_waiting_bcn) return; -- GitLab From 88724a81b4ac2a755bf9c532cdbee08a52803852 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sun, 1 Mar 2015 09:10:12 +0200 Subject: [PATCH 02510/11651] mac80211: check and dequeue skb in ieee80211_tx_prepare_skb() The ieee80211_tx_prepare_skb() function currently entirely ignores the fact that the SKB that is passed in might be split into more than one due to fragmentation and doesn't check the list of skbs that the TX handlers may create. In case this happens, it would leak them. Fix this and also don't leave the skb next/prev pointers dangling pointing to the on-stack sk_buff_head. Reported-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- net/mac80211/tx.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index a23a84e93e80..7e7de811e6ad 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -1420,6 +1420,7 @@ bool ieee80211_tx_prepare_skb(struct ieee80211_hw *hw, struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ieee80211_tx_data tx; + struct sk_buff *skb2; if (ieee80211_tx_prepare(sdata, &tx, skb) == TX_DROP) return false; @@ -1438,6 +1439,14 @@ bool ieee80211_tx_prepare_skb(struct ieee80211_hw *hw, *sta = NULL; } + /* this function isn't suitable for fragmented data frames */ + skb2 = __skb_dequeue(&tx.skbs); + if (WARN_ON(skb2 != skb || !skb_queue_empty(&tx.skbs))) { + ieee80211_free_txskb(hw, skb2); + ieee80211_purge_tx_queue(hw, &tx.skbs); + return false; + } + return true; } EXPORT_SYMBOL(ieee80211_tx_prepare_skb); -- GitLab From 98fc43864af9e74116eec81c290db048cded15d8 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sun, 1 Mar 2015 09:10:13 +0200 Subject: [PATCH 02511/11651] nl80211: prohibit mixing 'any' and regular wowlan triggers If the device supports waking up on 'any' signal - i.e. it continues operating as usual and wakes up the host on pretty much anything that happens, then it makes no sense to also configure the more restricted WoWLAN mode where the device operates more autonomously but also in a more restricted fashion. Currently only cw2100 supports both 'any' and other triggers, but it seems to be broken as it doesn't configure anything to the device, so we can't currently get into a situation where both even can correctly be configured. This is about to change (Intel devices are going to support both and have different behaviour depending on configuration) so make sure the conflicting modes cannot be configured. (It seems that cw2100 advertises 'any' and 'disconnect' as a means of saying that's what it will always do, but that isn't really the way this API was meant to be used nor does it actually mean anything as 'any' always implies 'disconnect' already, and the driver doesn't change device configuration in any way depending on the settings.) Signed-off-by: Johannes Berg --- include/uapi/linux/nl80211.h | 2 ++ net/wireless/nl80211.c | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index 90c5aeb3cca7..37e7f39441e5 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -3708,6 +3708,8 @@ struct nl80211_pattern_support { * @NL80211_WOWLAN_TRIG_ANY: wake up on any activity, do not really put * the chip into a special state -- works best with chips that have * support for low-power operation already (flag) + * Note that this mode is incompatible with all of the others, if + * any others are even supported by the device. * @NL80211_WOWLAN_TRIG_DISCONNECT: wake up on disconnect, the way disconnect * is detected is implementation-specific (flag) * @NL80211_WOWLAN_TRIG_MAGIC_PKT: wake up on magic packet (6x 0xff, followed diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 01874628ae00..07cef3d7653e 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -9105,6 +9105,7 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info) const struct wiphy_wowlan_support *wowlan = rdev->wiphy.wowlan; int err, i; bool prev_enabled = rdev->wiphy.wowlan_config; + bool regular = false; if (!wowlan) return -EOPNOTSUPP; @@ -9132,12 +9133,14 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info) if (!(wowlan->flags & WIPHY_WOWLAN_DISCONNECT)) return -EINVAL; new_triggers.disconnect = true; + regular = true; } if (tb[NL80211_WOWLAN_TRIG_MAGIC_PKT]) { if (!(wowlan->flags & WIPHY_WOWLAN_MAGIC_PKT)) return -EINVAL; new_triggers.magic_pkt = true; + regular = true; } if (tb[NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED]) @@ -9147,24 +9150,28 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info) if (!(wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE)) return -EINVAL; new_triggers.gtk_rekey_failure = true; + regular = true; } if (tb[NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST]) { if (!(wowlan->flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ)) return -EINVAL; new_triggers.eap_identity_req = true; + regular = true; } if (tb[NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE]) { if (!(wowlan->flags & WIPHY_WOWLAN_4WAY_HANDSHAKE)) return -EINVAL; new_triggers.four_way_handshake = true; + regular = true; } if (tb[NL80211_WOWLAN_TRIG_RFKILL_RELEASE]) { if (!(wowlan->flags & WIPHY_WOWLAN_RFKILL_RELEASE)) return -EINVAL; new_triggers.rfkill_release = true; + regular = true; } if (tb[NL80211_WOWLAN_TRIG_PKT_PATTERN]) { @@ -9173,6 +9180,8 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info) int rem, pat_len, mask_len, pkt_offset; struct nlattr *pat_tb[NUM_NL80211_PKTPAT]; + regular = true; + nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN], rem) n_patterns++; @@ -9234,6 +9243,7 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info) } if (tb[NL80211_WOWLAN_TRIG_TCP_CONNECTION]) { + regular = true; err = nl80211_parse_wowlan_tcp( rdev, tb[NL80211_WOWLAN_TRIG_TCP_CONNECTION], &new_triggers); @@ -9242,6 +9252,7 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info) } if (tb[NL80211_WOWLAN_TRIG_NET_DETECT]) { + regular = true; err = nl80211_parse_wowlan_nd( rdev, wowlan, tb[NL80211_WOWLAN_TRIG_NET_DETECT], &new_triggers); @@ -9249,6 +9260,17 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info) goto error; } + /* The 'any' trigger means the device continues operating more or less + * as in its normal operation mode and wakes up the host on most of the + * normal interrupts (like packet RX, ...) + * It therefore makes little sense to combine with the more constrained + * wakeup trigger modes. + */ + if (new_triggers.any && regular) { + err = -EINVAL; + goto error; + } + ntrig = kmemdup(&new_triggers, sizeof(new_triggers), GFP_KERNEL); if (!ntrig) { err = -ENOMEM; -- GitLab From 3384d757d41521a3dee274ed2802bcd285ed8e62 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Sun, 1 Mar 2015 09:10:15 +0200 Subject: [PATCH 02512/11651] mac80211: allow iterating inactive interfaces Sometimes the driver might want to modify private data in interfaces that are down. One possible use-case is cleaning up interface state after HW recovery. Some interfaces that were up before the recovery took place might be down now, but they might still be "dirty". Introduce a new iterate_interfaces() API and a new ACTIVE iterator flag. This way the internal implementation of the both active and inactive APIs remains the same. Signed-off-by: Arik Nemtsov Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- include/net/mac80211.h | 35 ++++++++++++++++++++++++++++++----- net/mac80211/util.c | 29 ++++++++++++++++------------- 2 files changed, 46 insertions(+), 18 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 3a029f0e303d..d1d6fbc13b1c 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -4346,12 +4346,32 @@ void ieee80211_sched_scan_stopped(struct ieee80211_hw *hw); * haven't been re-added to the driver yet. * @IEEE80211_IFACE_ITER_RESUME_ALL: During resume, iterate over all * interfaces, even if they haven't been re-added to the driver yet. + * @IEEE80211_IFACE_ITER_ACTIVE: Iterate only active interfaces (netdev is up). */ enum ieee80211_interface_iteration_flags { IEEE80211_IFACE_ITER_NORMAL = 0, IEEE80211_IFACE_ITER_RESUME_ALL = BIT(0), + IEEE80211_IFACE_ITER_ACTIVE = BIT(1), }; +/** + * ieee80211_iterate_interfaces - iterate interfaces + * + * This function iterates over the interfaces associated with a given + * hardware and calls the callback for them. This includes active as well as + * inactive interfaces. This function allows the iterator function to sleep. + * Will iterate over a new interface during add_interface(). + * + * @hw: the hardware struct of which the interfaces should be iterated over + * @iter_flags: iteration flags, see &enum ieee80211_interface_iteration_flags + * @iterator: the iterator function to call + * @data: first argument of the iterator function + */ +void ieee80211_iterate_interfaces(struct ieee80211_hw *hw, u32 iter_flags, + void (*iterator)(void *data, u8 *mac, + struct ieee80211_vif *vif), + void *data); + /** * ieee80211_iterate_active_interfaces - iterate active interfaces * @@ -4367,11 +4387,16 @@ enum ieee80211_interface_iteration_flags { * @iterator: the iterator function to call * @data: first argument of the iterator function */ -void ieee80211_iterate_active_interfaces(struct ieee80211_hw *hw, - u32 iter_flags, - void (*iterator)(void *data, u8 *mac, - struct ieee80211_vif *vif), - void *data); +static inline void +ieee80211_iterate_active_interfaces(struct ieee80211_hw *hw, u32 iter_flags, + void (*iterator)(void *data, u8 *mac, + struct ieee80211_vif *vif), + void *data) +{ + ieee80211_iterate_interfaces(hw, + iter_flags | IEEE80211_IFACE_ITER_ACTIVE, + iterator, data); +} /** * ieee80211_iterate_active_interfaces_atomic - iterate active interfaces diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 327886748a1d..37d85d36dd2c 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -625,13 +625,14 @@ void ieee80211_wake_vif_queues(struct ieee80211_local *local, reason, true); } -static void __iterate_active_interfaces(struct ieee80211_local *local, - u32 iter_flags, - void (*iterator)(void *data, u8 *mac, - struct ieee80211_vif *vif), - void *data) +static void __iterate_interfaces(struct ieee80211_local *local, + u32 iter_flags, + void (*iterator)(void *data, u8 *mac, + struct ieee80211_vif *vif), + void *data) { struct ieee80211_sub_if_data *sdata; + bool active_only = iter_flags & IEEE80211_IFACE_ITER_ACTIVE; list_for_each_entry_rcu(sdata, &local->interfaces, list) { switch (sdata->vif.type) { @@ -645,9 +646,9 @@ static void __iterate_active_interfaces(struct ieee80211_local *local, break; } if (!(iter_flags & IEEE80211_IFACE_ITER_RESUME_ALL) && - !(sdata->flags & IEEE80211_SDATA_IN_DRIVER)) + active_only && !(sdata->flags & IEEE80211_SDATA_IN_DRIVER)) continue; - if (ieee80211_sdata_running(sdata)) + if (ieee80211_sdata_running(sdata) || !active_only) iterator(data, sdata->vif.addr, &sdata->vif); } @@ -656,12 +657,12 @@ static void __iterate_active_interfaces(struct ieee80211_local *local, lockdep_is_held(&local->iflist_mtx) || lockdep_rtnl_is_held()); if (sdata && - (iter_flags & IEEE80211_IFACE_ITER_RESUME_ALL || + (iter_flags & IEEE80211_IFACE_ITER_RESUME_ALL || !active_only || sdata->flags & IEEE80211_SDATA_IN_DRIVER)) iterator(data, sdata->vif.addr, &sdata->vif); } -void ieee80211_iterate_active_interfaces( +void ieee80211_iterate_interfaces( struct ieee80211_hw *hw, u32 iter_flags, void (*iterator)(void *data, u8 *mac, struct ieee80211_vif *vif), @@ -670,10 +671,10 @@ void ieee80211_iterate_active_interfaces( struct ieee80211_local *local = hw_to_local(hw); mutex_lock(&local->iflist_mtx); - __iterate_active_interfaces(local, iter_flags, iterator, data); + __iterate_interfaces(local, iter_flags, iterator, data); mutex_unlock(&local->iflist_mtx); } -EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces); +EXPORT_SYMBOL_GPL(ieee80211_iterate_interfaces); void ieee80211_iterate_active_interfaces_atomic( struct ieee80211_hw *hw, u32 iter_flags, @@ -684,7 +685,8 @@ void ieee80211_iterate_active_interfaces_atomic( struct ieee80211_local *local = hw_to_local(hw); rcu_read_lock(); - __iterate_active_interfaces(local, iter_flags, iterator, data); + __iterate_interfaces(local, iter_flags | IEEE80211_IFACE_ITER_ACTIVE, + iterator, data); rcu_read_unlock(); } EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic); @@ -699,7 +701,8 @@ void ieee80211_iterate_active_interfaces_rtnl( ASSERT_RTNL(); - __iterate_active_interfaces(local, iter_flags, iterator, data); + __iterate_interfaces(local, iter_flags | IEEE80211_IFACE_ITER_ACTIVE, + iterator, data); } EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_rtnl); -- GitLab From 64a8cef41a8ce694b59ec75ae52688f58925693c Mon Sep 17 00:00:00 2001 From: SenthilKumar Jegadeesan Date: Mon, 2 Mar 2015 13:29:40 +0530 Subject: [PATCH 02513/11651] mac80211: provide station PMF configuration to driver Some device drivers offload part of aggregation including AddBA/DelBA negotiations to firmware. In such scenario, the PMF configuration of the station needs to be provided to driver to enable encryption of AddBA/DelBA action frames. Signed-off-by: SenthilKumar Jegadeesan [fix commit log, documentation] Signed-off-by: Johannes Berg --- include/net/mac80211.h | 2 ++ net/mac80211/cfg.c | 1 + net/mac80211/mlme.c | 6 +++++- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index d1d6fbc13b1c..a7756e45465e 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -1491,6 +1491,7 @@ struct ieee80211_sta_rates { * @tdls: indicates whether the STA is a TDLS peer * @tdls_initiator: indicates the STA is an initiator of the TDLS link. Only * valid if the STA is a TDLS peer in the first place. + * @mfp: indicates whether the STA uses management frame protection or not. */ struct ieee80211_sta { u32 supp_rates[IEEE80211_NUM_BANDS]; @@ -1507,6 +1508,7 @@ struct ieee80211_sta { struct ieee80211_sta_rates __rcu *rates; bool tdls; bool tdls_initiator; + bool mfp; /* must be last */ u8 drv_priv[0] __aligned(sizeof(void *)); diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 06557e4f9588..94889def2ef5 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1068,6 +1068,7 @@ static int sta_apply_parameters(struct ieee80211_local *local, sta->sta.wme = set & BIT(NL80211_STA_FLAG_WME); if (mask & BIT(NL80211_STA_FLAG_MFP)) { + sta->sta.mfp = !!(set & BIT(NL80211_STA_FLAG_MFP)); if (set & BIT(NL80211_STA_FLAG_MFP)) set_sta_flag(sta, WLAN_STA_MFP); else diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index bc2975e91272..539d6a976cbf 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -2966,8 +2966,12 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, rate_control_rate_init(sta); - if (ifmgd->flags & IEEE80211_STA_MFP_ENABLED) + if (ifmgd->flags & IEEE80211_STA_MFP_ENABLED) { set_sta_flag(sta, WLAN_STA_MFP); + sta->sta.mfp = true; + } else { + sta->sta.mfp = false; + } sta->sta.wme = elems.wmm_param; -- GitLab From cc57ac536a88604824aca1d3c874fd5252f1e867 Mon Sep 17 00:00:00 2001 From: Nicholas Mc Guire Date: Mon, 2 Mar 2015 04:54:13 -0500 Subject: [PATCH 02514/11651] mesh_plink: use msecs_to_jiffies for proper time conversion This is primarily an API consolidation and should make things more readable it replaces var * HZ / 1000 by msecs_to_jiffies(var) which also handles corner cases correctly. There is a change of behavior as e.g. for HZ 100, t * HZ / 1000 will return 0 for t < 10 but msecs_to_jiffies will return at least 1 always. Signed-off-by: Nicholas Mc Guire Signed-off-by: Johannes Berg --- net/mac80211/mesh_plink.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index b488e1859b18..4eefd5df5b05 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c @@ -17,7 +17,7 @@ #define PLINK_GET_PLID(p) (p + 4) #define mod_plink_timer(s, t) (mod_timer(&s->plink_timer, \ - jiffies + HZ * t / 1000)) + jiffies + msecs_to_jiffies(t))) enum plink_event { PLINK_UNDEFINED, @@ -623,7 +623,7 @@ static void mesh_plink_timer(unsigned long data) static inline void mesh_plink_timer_set(struct sta_info *sta, int timeout) { - sta->plink_timer.expires = jiffies + (HZ * timeout / 1000); + sta->plink_timer.expires = jiffies + msecs_to_jiffies(timeout); sta->plink_timer.data = (unsigned long) sta; sta->plink_timer.function = mesh_plink_timer; sta->plink_timeout = timeout; -- GitLab From 0df2f6c11813a3e522f72f6998b00ae8e17dd4df Mon Sep 17 00:00:00 2001 From: Nicholas Mc Guire Date: Mon, 2 Mar 2015 04:54:14 -0500 Subject: [PATCH 02515/11651] mesh_plink: fixup type of timeout to match usage timeout was being passed as int but assigned from u32/u16 values and used as unsigned type. This is really only for better readability. Signed-off-by: Nicholas Mc Guire Signed-off-by: Johannes Berg --- net/mac80211/mesh_plink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index 4eefd5df5b05..8465c055a371 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c @@ -621,7 +621,7 @@ static void mesh_plink_timer(unsigned long data) sta->llid, sta->plid, reason); } -static inline void mesh_plink_timer_set(struct sta_info *sta, int timeout) +static inline void mesh_plink_timer_set(struct sta_info *sta, u32 timeout) { sta->plink_timer.expires = jiffies + msecs_to_jiffies(timeout); sta->plink_timer.data = (unsigned long) sta; -- GitLab From 560676282e19a9cb99378547530aca3d085eb99f Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 3 Mar 2015 22:09:05 +0100 Subject: [PATCH 02516/11651] mac80211_hwsim: fix beacon timers Jouni reported that certain combinations of hwsim test cases failed, and we found that beaconing was erroneously enabled too early on any channel switch, which lead to the BI of 2000 TU from the first test case to leak into the second one, which then didn't beacon properly. To fix this, set data->beacon_int to zero when all stop beaconing so that beaconing cannot be started (which was intended as 'restarted') elsewhere. Additionally, Jouni found that due to this 'restart' and the beacon interval handling station interfaces would also have a needlessly running beacon timer all the time, of course not doing anything. To also fix the latter case only use the beacon interval when it's actually needed, i.e. when beaconing gets enabled. Reported-by: Jouni Malinen Tested-by: Jouni Malinen Signed-off-by: Johannes Berg --- drivers/net/wireless/mac80211_hwsim.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 32bd2f02c164..941925991476 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -1595,21 +1595,16 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw, vp->aid = info->aid; } - if (changed & BSS_CHANGED_BEACON_INT) { - wiphy_debug(hw->wiphy, " BCNINT: %d\n", info->beacon_int); - data->beacon_int = info->beacon_int * 1024; - } - if (changed & BSS_CHANGED_BEACON_ENABLED) { - wiphy_debug(hw->wiphy, " BCN EN: %d\n", info->enable_beacon); + wiphy_debug(hw->wiphy, " BCN EN: %d (BI=%u)\n", + info->enable_beacon, info->beacon_int); vp->bcn_en = info->enable_beacon; if (data->started && !hrtimer_is_queued(&data->beacon_timer.timer) && info->enable_beacon) { u64 tsf, until_tbtt; u32 bcn_int; - if (WARN_ON(!data->beacon_int)) - data->beacon_int = 1000 * 1024; + data->beacon_int = info->beacon_int * 1024; tsf = mac80211_hwsim_get_tsf(hw, vif); bcn_int = data->beacon_int; until_tbtt = bcn_int - do_div(tsf, bcn_int); @@ -1623,8 +1618,10 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw, mac80211_hwsim_bcn_en_iter, &count); wiphy_debug(hw->wiphy, " beaconing vifs remaining: %u", count); - if (count == 0) + if (count == 0) { tasklet_hrtimer_cancel(&data->beacon_timer); + data->beacon_int = 0; + } } } -- GitLab From f625d4601759f1cf1fd3ae58abeb0e203b8993b1 Mon Sep 17 00:00:00 2001 From: Benoit Parrot Date: Mon, 2 Feb 2015 11:44:44 -0600 Subject: [PATCH 02517/11651] gpio: add GPIO hogging mechanism Based on Boris Brezillion's work this is a reworked patch of his initial GPIO hogging mechanism. This patch provides a way to initially configure specific GPIO when the GPIO controller is probed. The actual DT scanning to collect the GPIO specific data is performed as part of gpiochip_add(). The purpose of this is to allow specific GPIOs to be configured without any driver specific code. This is particularly useful because board design are getting increasingly complex and given SoC pins can now have more than 10 mux values, a lot of connections are now dependent on external IO muxes to switch various modes. Specific drivers should not necessarily need to be aware of what accounts to a specific board implementation. This board level "description" should be best kept as part of the dts file. Signed-off-by: Benoit Parrot Reviewed-by: Alexandre Courbot Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib-of.c | 111 ++++++++++++++++++++++++++++++++++ drivers/gpio/gpiolib.c | 124 ++++++++++++++++++++++++++++++++------ drivers/gpio/gpiolib.h | 3 + 3 files changed, 219 insertions(+), 19 deletions(-) diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index 8cad8e400b44..468d76ac1e84 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "gpiolib.h" @@ -116,6 +117,114 @@ int of_get_named_gpio_flags(struct device_node *np, const char *list_name, } EXPORT_SYMBOL(of_get_named_gpio_flags); +/** + * of_get_gpio_hog() - Get a GPIO hog descriptor, names and flags for GPIO API + * @np: device node to get GPIO from + * @name: GPIO line name + * @lflags: gpio_lookup_flags - returned from of_find_gpio() or + * of_get_gpio_hog() + * @dflags: gpiod_flags - optional GPIO initialization flags + * + * Returns GPIO descriptor to use with Linux GPIO API, or one of the errno + * value on the error condition. + */ +static struct gpio_desc *of_get_gpio_hog(struct device_node *np, + const char **name, + enum gpio_lookup_flags *lflags, + enum gpiod_flags *dflags) +{ + struct device_node *chip_np; + enum of_gpio_flags xlate_flags; + struct gpio_desc *desc; + struct gg_data gg_data = { + .flags = &xlate_flags, + }; + u32 tmp; + int i, ret; + + chip_np = np->parent; + if (!chip_np) + return ERR_PTR(-EINVAL); + + xlate_flags = 0; + *lflags = 0; + *dflags = 0; + + ret = of_property_read_u32(chip_np, "#gpio-cells", &tmp); + if (ret) + return ERR_PTR(ret); + + if (tmp > MAX_PHANDLE_ARGS) + return ERR_PTR(-EINVAL); + + gg_data.gpiospec.args_count = tmp; + gg_data.gpiospec.np = chip_np; + for (i = 0; i < tmp; i++) { + ret = of_property_read_u32_index(np, "gpios", i, + &gg_data.gpiospec.args[i]); + if (ret) + return ERR_PTR(ret); + } + + gpiochip_find(&gg_data, of_gpiochip_find_and_xlate); + if (!gg_data.out_gpio) { + if (np->parent == np) + return ERR_PTR(-ENXIO); + else + return ERR_PTR(-EINVAL); + } + + if (xlate_flags & OF_GPIO_ACTIVE_LOW) + *lflags |= GPIO_ACTIVE_LOW; + + if (of_property_read_bool(np, "input")) + *dflags |= GPIOD_IN; + else if (of_property_read_bool(np, "output-low")) + *dflags |= GPIOD_OUT_LOW; + else if (of_property_read_bool(np, "output-high")) + *dflags |= GPIOD_OUT_HIGH; + else { + pr_warn("GPIO line %d (%s): no hogging state specified, bailing out\n", + desc_to_gpio(gg_data.out_gpio), np->name); + return ERR_PTR(-EINVAL); + } + + if (name && of_property_read_string(np, "line-name", name)) + *name = np->name; + + desc = gg_data.out_gpio; + + return desc; +} + +/** + * of_gpiochip_scan_hogs - Scan gpio-controller and apply GPIO hog as requested + * @chip: gpio chip to act on + * + * This is only used by of_gpiochip_add to request/set GPIO initial + * configuration. + */ +static void of_gpiochip_scan_hogs(struct gpio_chip *chip) +{ + struct gpio_desc *desc = NULL; + struct device_node *np; + const char *name; + enum gpio_lookup_flags lflags; + enum gpiod_flags dflags; + + for_each_child_of_node(chip->of_node, np) { + if (!of_property_read_bool(np, "gpio-hog")) + continue; + + desc = of_get_gpio_hog(np, &name, &lflags, &dflags); + if (IS_ERR(desc)) + continue; + + if (gpiod_hog(desc, name, lflags, dflags)) + continue; + } +} + /** * of_gpio_simple_xlate - translate gpio_spec to the GPIO number and flags * @gc: pointer to the gpio_chip structure @@ -325,6 +434,8 @@ void of_gpiochip_add(struct gpio_chip *chip) of_gpiochip_add_pin_range(chip); of_node_get(chip->of_node); + + of_gpiochip_scan_hogs(chip); } void of_gpiochip_remove(struct gpio_chip *chip) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 1ca9295b2c10..15837263dbb3 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -315,6 +315,7 @@ EXPORT_SYMBOL_GPL(gpiochip_add); /* Forward-declaration */ static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip); +static void gpiochip_free_hogs(struct gpio_chip *chip); /** * gpiochip_remove() - unregister a gpio_chip @@ -333,6 +334,7 @@ void gpiochip_remove(struct gpio_chip *chip) acpi_gpiochip_remove(chip); gpiochip_remove_pin_ranges(chip); + gpiochip_free_hogs(chip); of_gpiochip_remove(chip); spin_lock_irqsave(&gpio_lock, flags); @@ -866,6 +868,7 @@ static bool __gpiod_free(struct gpio_desc *desc) clear_bit(FLAG_REQUESTED, &desc->flags); clear_bit(FLAG_OPEN_DRAIN, &desc->flags); clear_bit(FLAG_OPEN_SOURCE, &desc->flags); + clear_bit(FLAG_IS_HOGGED, &desc->flags); ret = true; } @@ -1840,6 +1843,47 @@ struct gpio_desc *__must_check __gpiod_get_optional(struct device *dev, } EXPORT_SYMBOL_GPL(__gpiod_get_optional); + +/** + * gpiod_configure_flags - helper function to configure a given GPIO + * @desc: gpio whose value will be assigned + * @con_id: function within the GPIO consumer + * @lflags: gpio_lookup_flags - returned from of_find_gpio() or + * of_get_gpio_hog() + * @dflags: gpiod_flags - optional GPIO initialization flags + * + * Return 0 on success, -ENOENT if no GPIO has been assigned to the + * requested function and/or index, or another IS_ERR() code if an error + * occurred while trying to acquire the GPIO. + */ +static int gpiod_configure_flags(struct gpio_desc *desc, const char *con_id, + unsigned long lflags, enum gpiod_flags dflags) +{ + int status; + + if (lflags & GPIO_ACTIVE_LOW) + set_bit(FLAG_ACTIVE_LOW, &desc->flags); + if (lflags & GPIO_OPEN_DRAIN) + set_bit(FLAG_OPEN_DRAIN, &desc->flags); + if (lflags & GPIO_OPEN_SOURCE) + set_bit(FLAG_OPEN_SOURCE, &desc->flags); + + /* No particular flag request, return here... */ + if (!(dflags & GPIOD_FLAGS_BIT_DIR_SET)) { + pr_debug("no flags found for %s\n", con_id); + return 0; + } + + /* Process flags */ + if (dflags & GPIOD_FLAGS_BIT_DIR_OUT) + status = gpiod_direction_output(desc, + dflags & GPIOD_FLAGS_BIT_DIR_VAL); + else + status = gpiod_direction_input(desc); + + return status; +} + /** * gpiod_get_index - obtain a GPIO from a multi-index GPIO function * @dev: GPIO consumer, can be NULL for system-global GPIOs @@ -1889,28 +1933,10 @@ struct gpio_desc *__must_check __gpiod_get_index(struct device *dev, } status = gpiod_request(desc, con_id); - if (status < 0) return ERR_PTR(status); - if (lookupflags & GPIO_ACTIVE_LOW) - set_bit(FLAG_ACTIVE_LOW, &desc->flags); - if (lookupflags & GPIO_OPEN_DRAIN) - set_bit(FLAG_OPEN_DRAIN, &desc->flags); - if (lookupflags & GPIO_OPEN_SOURCE) - set_bit(FLAG_OPEN_SOURCE, &desc->flags); - - /* No particular flag request, return here... */ - if (!(flags & GPIOD_FLAGS_BIT_DIR_SET)) - return desc; - - /* Process flags */ - if (flags & GPIOD_FLAGS_BIT_DIR_OUT) - status = gpiod_direction_output(desc, - flags & GPIOD_FLAGS_BIT_DIR_VAL); - else - status = gpiod_direction_input(desc); - + status = gpiod_configure_flags(desc, con_id, lookupflags, flags); if (status < 0) { dev_dbg(dev, "setup of GPIO %s failed\n", con_id); gpiod_put(desc); @@ -2005,6 +2031,66 @@ struct gpio_desc *__must_check __gpiod_get_index_optional(struct device *dev, } EXPORT_SYMBOL_GPL(__gpiod_get_index_optional); +/** + * gpiod_hog - Hog the specified GPIO desc given the provided flags + * @desc: gpio whose value will be assigned + * @name: gpio line name + * @lflags: gpio_lookup_flags - returned from of_find_gpio() or + * of_get_gpio_hog() + * @dflags: gpiod_flags - optional GPIO initialization flags + */ +int gpiod_hog(struct gpio_desc *desc, const char *name, + unsigned long lflags, enum gpiod_flags dflags) +{ + struct gpio_chip *chip; + struct gpio_desc *local_desc; + int hwnum; + int status; + + chip = gpiod_to_chip(desc); + hwnum = gpio_chip_hwgpio(desc); + + local_desc = gpiochip_request_own_desc(chip, hwnum, name); + if (IS_ERR(local_desc)) { + pr_debug("requesting own GPIO %s failed\n", name); + return PTR_ERR(local_desc); + } + + status = gpiod_configure_flags(desc, name, lflags, dflags); + if (status < 0) { + pr_debug("setup of GPIO %s failed\n", name); + gpiochip_free_own_desc(desc); + return status; + } + + /* Mark GPIO as hogged so it can be identified and removed later */ + set_bit(FLAG_IS_HOGGED, &desc->flags); + + pr_info("GPIO line %d (%s) hogged as %s%s\n", + desc_to_gpio(desc), name, + (dflags&GPIOD_FLAGS_BIT_DIR_OUT) ? "output" : "input", + (dflags&GPIOD_FLAGS_BIT_DIR_OUT) ? + (dflags&GPIOD_FLAGS_BIT_DIR_VAL) ? "/high" : "/low":""); + + return 0; +} + +/** + * gpiochip_free_hogs - Scan gpio-controller chip and release GPIO hog + * @chip: gpio chip to act on + * + * This is only used by of_gpiochip_remove to free hogged gpios + */ +static void gpiochip_free_hogs(struct gpio_chip *chip) +{ + int id; + + for (id = 0; id < chip->ngpio; id++) { + if (test_bit(FLAG_IS_HOGGED, &chip->desc[id].flags)) + gpiochip_free_own_desc(&chip->desc[id]); + } +} + /** * gpiod_put - dispose of a GPIO descriptor * @desc: GPIO descriptor to dispose of diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h index 550a5eafbd38..cadba26c45a6 100644 --- a/drivers/gpio/gpiolib.h +++ b/drivers/gpio/gpiolib.h @@ -78,6 +78,7 @@ struct gpio_desc { #define FLAG_OPEN_SOURCE 8 /* Gpio is open source type */ #define FLAG_USED_AS_IRQ 9 /* GPIO is connected to an IRQ */ #define FLAG_SYSFS_DIR 10 /* show sysfs direction attribute */ +#define FLAG_IS_HOGGED 11 /* GPIO is hogged */ #define ID_SHIFT 16 /* add new flags before this one */ @@ -89,6 +90,8 @@ struct gpio_desc { int gpiod_request(struct gpio_desc *desc, const char *label); void gpiod_free(struct gpio_desc *desc); +int gpiod_hog(struct gpio_desc *desc, const char *name, + unsigned long lflags, enum gpiod_flags dflags); /* * Return the GPIO number of the passed descriptor relative to its chip -- GitLab From 6b516a1093006a39368dd11a5396be5bb00c99df Mon Sep 17 00:00:00 2001 From: Benoit Parrot Date: Mon, 2 Feb 2015 11:44:45 -0600 Subject: [PATCH 02518/11651] gpio: Document GPIO hogging mechanism Add GPIO hogging documentation to gpio.txt Signed-off-by: Benoit Parrot Reviewed-by: Alexandre Courbot Signed-off-by: Linus Walleij --- .../devicetree/bindings/gpio/gpio.txt | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/Documentation/devicetree/bindings/gpio/gpio.txt b/Documentation/devicetree/bindings/gpio/gpio.txt index f7a158d85862..5788d5cf1252 100644 --- a/Documentation/devicetree/bindings/gpio/gpio.txt +++ b/Documentation/devicetree/bindings/gpio/gpio.txt @@ -116,6 +116,29 @@ Every GPIO controller node must contain both an empty "gpio-controller" property, and a #gpio-cells integer property, which indicates the number of cells in a gpio-specifier. +The GPIO chip may contain GPIO hog definitions. GPIO hogging is a mechanism +providing automatic GPIO request and configuration as part of the +gpio-controller's driver probe function. + +Each GPIO hog definition is represented as a child node of the GPIO controller. +Required properties: +- gpio-hog: A property specifying that this child node represent a GPIO hog. +- gpios: Store the GPIO information (id, flags, ...). Shall contain the + number of cells specified in its parent node (GPIO controller + node). +Only one of the following properties scanned in the order shown below. +This means that when multiple properties are present they will be searched +in the order presented below and the first match is taken as the intended +configuration. +- input: A property specifying to set the GPIO direction as input. +- output-low A property specifying to set the GPIO direction as output with + the value low. +- output-high A property specifying to set the GPIO direction as output with + the value high. + +Optional properties: +- line-name: The GPIO label name. If not present the node name is used. + Example of two SOC GPIO banks defined as gpio-controller nodes: qe_pio_a: gpio-controller@1400 { @@ -123,6 +146,13 @@ Example of two SOC GPIO banks defined as gpio-controller nodes: reg = <0x1400 0x18>; gpio-controller; #gpio-cells = <2>; + + line_b { + gpio-hog; + gpios = <6 0>; + output-low; + line-name = "foo-bar-gpio"; + }; }; qe_pio_e: gpio-controller@1460 { -- GitLab From 566084007d3672aebd82a27b448095be67fb208f Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 18 Jan 2015 14:26:50 +0100 Subject: [PATCH 02519/11651] dts: Documentation: AT91 Watchdog, explain what atmel,idle-halt property really do atmel,idle-halt property should be used with care, it actually makes the watchdog not counting when the CPU is in idle state, therefore the watchdog reset time depends on mean CPU usage and will not reset at all of the CPU stop working while it is in idle state, which is probably not what you want. Signed-off-by: Sylvain Rochet Acked-by: Boris Brezillon Signed-off-by: Nicolas Ferre --- Documentation/devicetree/bindings/watchdog/atmel-wdt.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Documentation/devicetree/bindings/watchdog/atmel-wdt.txt b/Documentation/devicetree/bindings/watchdog/atmel-wdt.txt index f90e294d7631..a4d869744f59 100644 --- a/Documentation/devicetree/bindings/watchdog/atmel-wdt.txt +++ b/Documentation/devicetree/bindings/watchdog/atmel-wdt.txt @@ -26,6 +26,11 @@ Optional properties: - atmel,disable : Should be present if you want to disable the watchdog. - atmel,idle-halt : Should be present if you want to stop the watchdog when entering idle state. + CAUTION: This property should be used with care, it actually makes the + watchdog not counting when the CPU is in idle state, therefore the + watchdog reset time depends on mean CPU usage and will not reset at all + if the CPU stop working while it is in idle state, which is probably + not what you want. - atmel,dbg-halt : Should be present if you want to stop the watchdog when entering debug state. -- GitLab From 2141102e045e622cac176891cb66c5bf08e439f5 Mon Sep 17 00:00:00 2001 From: Michel Marti Date: Tue, 23 Dec 2014 12:41:43 +0100 Subject: [PATCH 02520/11651] ARM: at91/dt: keep watchdog running in idle mode Since turning on idle-halt in commit fe46aa679f12 (ARM: at91/dt: add sam9 watchdog default options to SoCs), SoCs compatible with at91sam9260-wdt no longer reboot if the watchdog times out while the CPU is in idle state. Removing the 'idle-halt' flag that was set by default fixes this. Signed-off-by: Michel Marti Acked-by: Boris Brezillon Acked-by: Sylvain Rochet [nicolas.ferre@atmel.com: rework the commit message] Signed-off-by: Nicolas Ferre --- arch/arm/boot/dts/at91sam9260.dtsi | 1 - arch/arm/boot/dts/at91sam9263.dtsi | 1 - arch/arm/boot/dts/at91sam9g45.dtsi | 1 - arch/arm/boot/dts/at91sam9n12.dtsi | 1 - arch/arm/boot/dts/at91sam9x5.dtsi | 1 - arch/arm/boot/dts/sama5d3.dtsi | 1 - 6 files changed, 6 deletions(-) diff --git a/arch/arm/boot/dts/at91sam9260.dtsi b/arch/arm/boot/dts/at91sam9260.dtsi index affeebe620f6..ac2c5dd03663 100644 --- a/arch/arm/boot/dts/at91sam9260.dtsi +++ b/arch/arm/boot/dts/at91sam9260.dtsi @@ -976,7 +976,6 @@ atmel,watchdog-type = "hardware"; atmel,reset-type = "all"; atmel,dbg-halt; - atmel,idle-halt; status = "disabled"; }; diff --git a/arch/arm/boot/dts/at91sam9263.dtsi b/arch/arm/boot/dts/at91sam9263.dtsi index c6583d8d0114..088219d1c8ce 100644 --- a/arch/arm/boot/dts/at91sam9263.dtsi +++ b/arch/arm/boot/dts/at91sam9263.dtsi @@ -905,7 +905,6 @@ atmel,watchdog-type = "hardware"; atmel,reset-type = "all"; atmel,dbg-halt; - atmel,idle-halt; status = "disabled"; }; diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi index ee80aa9c0759..119893181189 100644 --- a/arch/arm/boot/dts/at91sam9g45.dtsi +++ b/arch/arm/boot/dts/at91sam9g45.dtsi @@ -1116,7 +1116,6 @@ atmel,watchdog-type = "hardware"; atmel,reset-type = "all"; atmel,dbg-halt; - atmel,idle-halt; status = "disabled"; }; diff --git a/arch/arm/boot/dts/at91sam9n12.dtsi b/arch/arm/boot/dts/at91sam9n12.dtsi index c2666a7cb5b1..0c53a375ba99 100644 --- a/arch/arm/boot/dts/at91sam9n12.dtsi +++ b/arch/arm/boot/dts/at91sam9n12.dtsi @@ -894,7 +894,6 @@ atmel,watchdog-type = "hardware"; atmel,reset-type = "all"; atmel,dbg-halt; - atmel,idle-halt; status = "disabled"; }; diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi index 818dabdd8c0e..e77c9bb5485d 100644 --- a/arch/arm/boot/dts/at91sam9x5.dtsi +++ b/arch/arm/boot/dts/at91sam9x5.dtsi @@ -1130,7 +1130,6 @@ atmel,watchdog-type = "hardware"; atmel,reset-type = "all"; atmel,dbg-halt; - atmel,idle-halt; status = "disabled"; }; diff --git a/arch/arm/boot/dts/sama5d3.dtsi b/arch/arm/boot/dts/sama5d3.dtsi index 261311bdf65b..e30fee2edd55 100644 --- a/arch/arm/boot/dts/sama5d3.dtsi +++ b/arch/arm/boot/dts/sama5d3.dtsi @@ -1248,7 +1248,6 @@ atmel,watchdog-type = "hardware"; atmel,reset-type = "all"; atmel,dbg-halt; - atmel,idle-halt; status = "disabled"; }; -- GitLab From 1a6ab46fa9c2bc9399694b4856ab7ea19c036485 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Wed, 4 Mar 2015 10:56:13 +0900 Subject: [PATCH 02521/11651] ALSA: Fix spelling typo in Documentation/DocBook/alsa-driver-api.xml This patch fix spelling typo found in alsa-driver-api.xml. It is because this file is generated from comments in source files, I have to fix source files. Signed-off-by: Masanari Iida Signed-off-by: Takashi Iwai --- include/sound/compress_driver.h | 4 ++-- include/sound/control.h | 2 +- include/sound/soc.h | 2 +- include/uapi/sound/compress_offload.h | 2 +- sound/core/pcm_dmaengine.c | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/include/sound/compress_driver.h b/include/sound/compress_driver.h index f48089d364c5..fa1d05512c09 100644 --- a/include/sound/compress_driver.h +++ b/include/sound/compress_driver.h @@ -70,7 +70,7 @@ struct snd_compr_runtime { * @device: device pointer * @direction: stream direction, playback/recording * @metadata_set: metadata set flag, true when set - * @next_track: has userspace signall next track transistion, true when set + * @next_track: has userspace signal next track transition, true when set * @private_data: pointer to DSP private data */ struct snd_compr_stream { @@ -95,7 +95,7 @@ struct snd_compr_stream { * and the stream properties * @get_params: retrieve the codec parameters, mandatory * @set_metadata: Set the metadata values for a stream - * @get_metadata: retreives the requested metadata values from stream + * @get_metadata: retrieves the requested metadata values from stream * @trigger: Trigger operations like start, pause, resume, drain, stop. * This callback is mandatory * @pointer: Retrieve current h/w pointer information. Mandatory diff --git a/include/sound/control.h b/include/sound/control.h index 75f3054023f7..95aad6d3fd1a 100644 --- a/include/sound/control.h +++ b/include/sound/control.h @@ -227,7 +227,7 @@ snd_ctl_add_slave(struct snd_kcontrol *master, struct snd_kcontrol *slave) * Add a virtual slave control to the given master. * Unlike snd_ctl_add_slave(), the element added via this function * is supposed to have volatile values, and get callback is called - * at each time quried from the master. + * at each time queried from the master. * * When the control peeks the hardware values directly and the value * can be changed by other means than the put callback of the element, diff --git a/include/sound/soc.h b/include/sound/soc.h index 0d1ade195628..cf0bb156d6da 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -1469,7 +1469,7 @@ static inline struct snd_soc_codec *snd_soc_kcontrol_codec( } /** - * snd_soc_kcontrol_platform() - Returns the platform that registerd the control + * snd_soc_kcontrol_platform() - Returns the platform that registered the control * @kcontrol: The control for which to get the platform * * Note: This function will only work correctly if the control has been diff --git a/include/uapi/sound/compress_offload.h b/include/uapi/sound/compress_offload.h index 22ed8cb7800b..e00d8cbfc628 100644 --- a/include/uapi/sound/compress_offload.h +++ b/include/uapi/sound/compress_offload.h @@ -75,7 +75,7 @@ struct snd_compr_tstamp { /** * struct snd_compr_avail - avail descriptor * @avail: Number of bytes available in ring buffer for writing/reading - * @tstamp: timestamp infomation + * @tstamp: timestamp information */ struct snd_compr_avail { __u64 avail; diff --git a/sound/core/pcm_dmaengine.c b/sound/core/pcm_dmaengine.c index 6542c4083594..fba365a78390 100644 --- a/sound/core/pcm_dmaengine.c +++ b/sound/core/pcm_dmaengine.c @@ -289,7 +289,7 @@ EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_request_channel); * * The function should usually be called from the pcm open callback. Note that * this function will use private_data field of the substream's runtime. So it - * is not availabe to your pcm driver implementation. + * is not available to your pcm driver implementation. */ int snd_dmaengine_pcm_open(struct snd_pcm_substream *substream, struct dma_chan *chan) @@ -328,7 +328,7 @@ EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_open); * This function will request a DMA channel using the passed filter function and * data. The function should usually be called from the pcm open callback. Note * that this function will use private_data field of the substream's runtime. So - * it is not availabe to your pcm driver implementation. + * it is not available to your pcm driver implementation. */ int snd_dmaengine_pcm_open_request_chan(struct snd_pcm_substream *substream, dma_filter_fn filter_fn, void *filter_data) -- GitLab From cb0c3f5f1b888fa0283c2581c91bb10728ac1b22 Mon Sep 17 00:00:00 2001 From: Tony K Nadackal Date: Wed, 17 Dec 2014 04:21:21 -0300 Subject: [PATCH 02522/11651] [media] s5p-jpeg: Initialize cb and cr to zero To avoid garbage value written into image base address planes, initialize cb and cr of structure s5p_jpeg_addr to zero. Signed-off-by: Tony K Nadackal Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-jpeg/jpeg-core.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c index 12f7452edce3..a92ff4249d10 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-core.c +++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c @@ -1845,6 +1845,9 @@ static void exynos4_jpeg_set_img_addr(struct s5p_jpeg_ctx *ctx) struct s5p_jpeg_addr jpeg_addr; u32 pix_size, padding_bytes = 0; + jpeg_addr.cb = 0; + jpeg_addr.cr = 0; + pix_size = ctx->cap_q.w * ctx->cap_q.h; if (ctx->mode == S5P_JPEG_ENCODE) { -- GitLab From 940f700dfbe91d37a56ebd26e0a7a681d387326a Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 20 Feb 2015 13:52:01 +0300 Subject: [PATCH 02523/11651] iommu/amd: Small cleanup in mn_release() "pasid_state->device_state" and "dev_state" are the same, but it's nicer to use dev_state consistently. Signed-off-by: Dan Carpenter Signed-off-by: Joerg Roedel --- drivers/iommu/amd_iommu_v2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iommu/amd_iommu_v2.c b/drivers/iommu/amd_iommu_v2.c index 6d5a5c44453b..a1cbba9056fd 100644 --- a/drivers/iommu/amd_iommu_v2.c +++ b/drivers/iommu/amd_iommu_v2.c @@ -417,7 +417,7 @@ static void mn_release(struct mmu_notifier *mn, struct mm_struct *mm) dev_state = pasid_state->device_state; run_inv_ctx_cb = !pasid_state->invalid; - if (run_inv_ctx_cb && pasid_state->device_state->inv_ctx_cb) + if (run_inv_ctx_cb && dev_state->inv_ctx_cb) dev_state->inv_ctx_cb(dev_state->pdev, pasid_state->pasid); unbind_pasid(pasid_state); -- GitLab From 3987c98461e3886031a563679cf22e73ba900b5a Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 29 Jan 2015 13:13:08 -0300 Subject: [PATCH 02524/11651] [media] s5p-tv: hdmi needs I2C support Building the s5p-tv HDMI support when CONFIG_I2C is disabled gives us this build error: s5p-tv/hdmi_drv.c: In function 'hdmi_probe': s5p-tv/hdmi_drv.c:947:2: error: implicit declaration of function 'i2c_get_adapter' [-Werror=implicit-function-declaration] adapter = i2c_get_adapter(pdata->hdmiphy_bus); ^ This patch changes the Kconfig description to include I2C as a dependency for this driver, so it cannot be configured incorrectly. Signed-off-by: Arnd Bergmann Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-tv/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/platform/s5p-tv/Kconfig b/drivers/media/platform/s5p-tv/Kconfig index 5a1835dd65e8..697aaed42486 100644 --- a/drivers/media/platform/s5p-tv/Kconfig +++ b/drivers/media/platform/s5p-tv/Kconfig @@ -20,6 +20,7 @@ if VIDEO_SAMSUNG_S5P_TV config VIDEO_SAMSUNG_S5P_HDMI tristate "Samsung HDMI Driver" depends on VIDEO_V4L2 + depends on I2C depends on VIDEO_SAMSUNG_S5P_TV select VIDEO_SAMSUNG_S5P_HDMIPHY help -- GitLab From f7cbd688f039a3adefc9210226b7edf5bd8fd6cd Mon Sep 17 00:00:00 2001 From: Jacek Anaszewski Date: Wed, 25 Feb 2015 08:53:49 -0300 Subject: [PATCH 02525/11651] [media] s5p-jpeg: exynos3250: fix erroneous reset procedure The first while loop in the function exynos3250_jpeg_reset had no chance to be executed because the reg variable was initialized to 0. Initialize reg variable to 1 to fix the issue. Signed-off-by: Jacek Anaszewski Reported-by: Andrzej Pietrasiewicz Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-jpeg/jpeg-hw-exynos3250.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos3250.c b/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos3250.c index e8c2cad93962..0974b9a7a584 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos3250.c +++ b/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos3250.c @@ -20,7 +20,7 @@ void exynos3250_jpeg_reset(void __iomem *regs) { - u32 reg = 0; + u32 reg = 1; int count = 1000; writel(1, regs + EXYNOS3250_SW_RESET); -- GitLab From 41f03a00536ebb3d72c051f9e7efe2d4ab76ebc8 Mon Sep 17 00:00:00 2001 From: Kamil Debski Date: Tue, 3 Mar 2015 11:32:58 -0300 Subject: [PATCH 02526/11651] [media] s5p-mfc: Fix NULL pointer dereference caused by not set q->lock The patch "media: s5p-mfc: use vb2_ops_wait_prepare/finish helper" (654a731be1a0b6f606f3f3d12b50db08f2ae3c3) introduced a kernel panic. The q->lock was set for just one queue, the other was not set thus causing a NULL pointer dereference. Reported-by: Marek Szyprowski Signed-off-by: Kamil Debski Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-mfc/s5p_mfc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c index 8e44a59d8ec2..98374e8bad3e 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c @@ -833,6 +833,7 @@ static int s5p_mfc_open(struct file *file) q->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; q->io_modes = VB2_MMAP; q->drv_priv = &ctx->fh; + q->lock = &dev->mfc_mutex; if (vdev == dev->vfd_dec) { q->io_modes = VB2_MMAP; q->ops = get_dec_queue_ops(); -- GitLab From db2cf865c75792f2e52596bf3e94e9a98272becf Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Wed, 4 Feb 2015 19:30:23 +0100 Subject: [PATCH 02527/11651] ath10k: delete unnecessary checks before the function call "release_firmware" The release_firmware() function tests whether its argument is NULL and then returns immediately. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/core.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index 310e12bc078a..c0e454bb6a8d 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c @@ -436,16 +436,16 @@ static int ath10k_download_fw(struct ath10k *ar, enum ath10k_firmware_mode mode) static void ath10k_core_free_firmware_files(struct ath10k *ar) { - if (ar->board && !IS_ERR(ar->board)) + if (!IS_ERR(ar->board)) release_firmware(ar->board); - if (ar->otp && !IS_ERR(ar->otp)) + if (!IS_ERR(ar->otp)) release_firmware(ar->otp); - if (ar->firmware && !IS_ERR(ar->firmware)) + if (!IS_ERR(ar->firmware)) release_firmware(ar->firmware); - if (ar->cal_file && !IS_ERR(ar->cal_file)) + if (!IS_ERR(ar->cal_file)) release_firmware(ar->cal_file); ar->board = NULL; -- GitLab From 6383864053cc456aa82847cd910257deaa34eb5a Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Mon, 9 Feb 2015 15:04:55 +0100 Subject: [PATCH 02528/11651] ath10k: workaround corrupted htt rx events qca6174 WLAN.RM.2.0-00073 firmware uses full rx reordering offload and delivers Rx via a new HTT event. The event however is incorrectly generated in firmware and becomes overly long (with trailing garbage). This was hitting defined CE buffer limit that was programmed to the device and caused device to crash upon busier Rx traffic. Increasing the CE buffer limit for HTT Rx pipe to 2KBytes seems to be enough to workaround this problem. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/pci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index e6972b09333e..7681237fe298 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c @@ -104,7 +104,7 @@ static const struct ce_attr host_ce_config_wlan[] = { { .flags = CE_ATTR_FLAGS, .src_nentries = 0, - .src_sz_max = 512, + .src_sz_max = 2048, .dest_nentries = 512, }, @@ -174,7 +174,7 @@ static const struct ce_pipe_config target_ce_config_wlan[] = { .pipenum = __cpu_to_le32(1), .pipedir = __cpu_to_le32(PIPEDIR_IN), .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(512), + .nbytes_max = __cpu_to_le32(2048), .flags = __cpu_to_le32(CE_ATTR_FLAGS), .reserved = __cpu_to_le32(0), }, -- GitLab From c8c60cfd18e1ddf8f1b9ef76a49d7d1b08ea7a2d Mon Sep 17 00:00:00 2001 From: Marek Puzyniak Date: Tue, 10 Feb 2015 12:38:15 +0100 Subject: [PATCH 02529/11651] ath10k: fix wmm params per vdev During wmm tests changing wmm parameters did not change anything. This was because of mismatch in WMM params per vdev command. WMM params per vdev uses different command structure than wmm params per pdev command. Patch concerns qca6174. Signed-off-by: Marek Puzyniak Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/wmi-tlv.c | 15 +++++---------- drivers/net/wireless/ath/ath10k/wmi-tlv.h | 6 ++++++ 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c index f34baa0c9e87..ee0c5f602e29 100644 --- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c +++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c @@ -1710,14 +1710,12 @@ ath10k_wmi_tlv_op_gen_vdev_wmm_conf(struct ath10k *ar, u32 vdev_id, const struct wmi_wmm_params_all_arg *arg) { struct wmi_tlv_vdev_set_wmm_cmd *cmd; - struct wmi_wmm_params *wmm; struct wmi_tlv *tlv; struct sk_buff *skb; size_t len; void *ptr; - len = (sizeof(*tlv) + sizeof(*cmd)) + - (4 * (sizeof(*tlv) + sizeof(*wmm))); + len = sizeof(*tlv) + sizeof(*cmd); skb = ath10k_wmi_alloc_skb(ar, len); if (!skb) return ERR_PTR(-ENOMEM); @@ -1729,13 +1727,10 @@ ath10k_wmi_tlv_op_gen_vdev_wmm_conf(struct ath10k *ar, u32 vdev_id, cmd = (void *)tlv->value; cmd->vdev_id = __cpu_to_le32(vdev_id); - ptr += sizeof(*tlv); - ptr += sizeof(*cmd); - - ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_be); - ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_bk); - ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_vi); - ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_vo); + ath10k_wmi_set_wmm_param(&cmd->vdev_wmm_params[0].params, &arg->ac_be); + ath10k_wmi_set_wmm_param(&cmd->vdev_wmm_params[1].params, &arg->ac_bk); + ath10k_wmi_set_wmm_param(&cmd->vdev_wmm_params[2].params, &arg->ac_vi); + ath10k_wmi_set_wmm_param(&cmd->vdev_wmm_params[3].params, &arg->ac_vo); ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev wmm conf\n"); return skb; diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.h b/drivers/net/wireless/ath/ath10k/wmi-tlv.h index d7a31e15910d..a6c8280cc4b1 100644 --- a/drivers/net/wireless/ath/ath10k/wmi-tlv.h +++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.h @@ -1302,8 +1302,14 @@ struct wmi_tlv_pdev_set_wmm_cmd { __le32 dg_type; /* no idea.. */ } __packed; +struct wmi_tlv_vdev_wmm_params { + __le32 dummy; + struct wmi_wmm_params params; +} __packed; + struct wmi_tlv_vdev_set_wmm_cmd { __le32 vdev_id; + struct wmi_tlv_vdev_wmm_params vdev_wmm_params[4]; } __packed; struct wmi_tlv_phyerr_ev { -- GitLab From cde72ccfdd5920abb0413d16240c1551de3bd13a Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 3 Mar 2015 14:28:51 +0100 Subject: [PATCH 02530/11651] regulator: Fix regression due to NULL constraints check The commit [39f802d6b6d9: 'regulator: Build sysfs entries with static attribute groups'] converted the sysfs entry creation to static attribute groups, but this resulted in a regression due to the NULL check of rdev->constraints. At the point where the device is registered, rdev->constraints isn't set, so the attributes depending on it are missing. We may fix it by shuffling the code order in regulator_register(), but a quicker fix is to just remove this NULL check. rdev->constraints is in anyway always set to non-NULL in set_machine_constraints(), thus the check there is basically superfluous. Fixes: 39f802d6b6d9 ('regulator: Build sysfs entries with static attribute groups') Signed-off-by: Takashi Iwai Reportded-by: Steve Twiss Tested-by: Steve Twiss Signed-off-by: Mark Brown --- drivers/regulator/core.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index b899947d839d..1245dca79009 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -3444,13 +3444,6 @@ static umode_t regulator_attr_is_visible(struct kobject *kobj, if (attr == &dev_attr_requested_microamps.attr) return rdev->desc->type == REGULATOR_CURRENT ? mode : 0; - /* all the other attributes exist to support constraints; - * don't show them if there are no constraints, or if the - * relevant supporting methods are missing. - */ - if (!rdev->constraints) - return 0; - /* constraints need specific supporting methods */ if (attr == &dev_attr_min_microvolts.attr || attr == &dev_attr_max_microvolts.attr) -- GitLab From e921eea8e7d4457f424bc3f821cb836e35b91f88 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Tue, 3 Mar 2015 12:05:00 +0100 Subject: [PATCH 02531/11651] dmaengine: Remove memset leftovers Commit 48a9db462d99 ("drivers/dma: remove unused support for MEMSET operations") removed support for the memset operation in dmaengine, but left the fill_aligned field that was supposed to set the buffer alignment for the memset operations. Remove that field too. Signed-off-by: Maxime Ripard Signed-off-by: Vinod Koul --- include/linux/dmaengine.h | 8 -------- 1 file changed, 8 deletions(-) diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index b6997a0cb528..db0104b0da4d 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -574,7 +574,6 @@ struct dma_tx_state { * @copy_align: alignment shift for memcpy operations * @xor_align: alignment shift for xor operations * @pq_align: alignment shift for pq operations - * @fill_align: alignment shift for memset operations * @dev_id: unique device ID * @dev: struct device reference for dma mapping api * @src_addr_widths: bit mask of src addr widths the device supports @@ -625,7 +624,6 @@ struct dma_device { u8 copy_align; u8 xor_align; u8 pq_align; - u8 fill_align; #define DMA_HAS_PQ_CONTINUE (1 << 15) int dev_id; @@ -826,12 +824,6 @@ static inline bool is_dma_pq_aligned(struct dma_device *dev, size_t off1, return dmaengine_check_align(dev->pq_align, off1, off2, len); } -static inline bool is_dma_fill_aligned(struct dma_device *dev, size_t off1, - size_t off2, size_t len) -{ - return dmaengine_check_align(dev->fill_align, off1, off2, len); -} - static inline void dma_set_maxpq(struct dma_device *dma, int maxpq, int has_pq_continue) { -- GitLab From 1eed601a5b02a1f0bbabd155aeea7879fc3708eb Mon Sep 17 00:00:00 2001 From: Qiao Zhou Date: Tue, 3 Mar 2015 09:16:08 +0800 Subject: [PATCH 02532/11651] dma: mmp-tdma: refine dma disable and dma-pos update Below are the refinements. 1. Set DMA abort bit when disabling dma channel. This will clear the remaining data in dma FIFO, to fix channel-swap issue. 2. Read DMA HW pointer when updating DMA status. Previously dma position is calculated by adding one period size in dma interrupt. This is inaccurate/insufficient for some high-quality audio APP. Since interrupt bottom half handler has variable schedule delay, it causes big error when calculating sample delay. Read the actual HW pointer and feedback can improve the accuracy. 3. Do some minor code clean. Signed-off-by: Qiao Zhou Signed-off-by: Vinod Koul --- drivers/dma/mmp_tdma.c | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/drivers/dma/mmp_tdma.c b/drivers/dma/mmp_tdma.c index 70c2fa9963cd..b6f4e1fc9c78 100644 --- a/drivers/dma/mmp_tdma.c +++ b/drivers/dma/mmp_tdma.c @@ -110,7 +110,7 @@ struct mmp_tdma_chan { struct tasklet_struct tasklet; struct mmp_tdma_desc *desc_arr; - phys_addr_t desc_arr_phys; + dma_addr_t desc_arr_phys; int desc_num; enum dma_transfer_direction dir; dma_addr_t dev_addr; @@ -166,9 +166,12 @@ static void mmp_tdma_enable_chan(struct mmp_tdma_chan *tdmac) static int mmp_tdma_disable_chan(struct dma_chan *chan) { struct mmp_tdma_chan *tdmac = to_mmp_tdma_chan(chan); + u32 tdcr; - writel(readl(tdmac->reg_base + TDCR) & ~TDCR_CHANEN, - tdmac->reg_base + TDCR); + tdcr = readl(tdmac->reg_base + TDCR); + tdcr |= TDCR_ABR; + tdcr &= ~TDCR_CHANEN; + writel(tdcr, tdmac->reg_base + TDCR); tdmac->status = DMA_COMPLETE; @@ -296,12 +299,27 @@ static int mmp_tdma_clear_chan_irq(struct mmp_tdma_chan *tdmac) return -EAGAIN; } +static size_t mmp_tdma_get_pos(struct mmp_tdma_chan *tdmac) +{ + size_t reg; + + if (tdmac->idx == 0) { + reg = __raw_readl(tdmac->reg_base + TDSAR); + reg -= tdmac->desc_arr[0].src_addr; + } else if (tdmac->idx == 1) { + reg = __raw_readl(tdmac->reg_base + TDDAR); + reg -= tdmac->desc_arr[0].dst_addr; + } else + return -EINVAL; + + return reg; +} + static irqreturn_t mmp_tdma_chan_handler(int irq, void *dev_id) { struct mmp_tdma_chan *tdmac = dev_id; if (mmp_tdma_clear_chan_irq(tdmac) == 0) { - tdmac->pos = (tdmac->pos + tdmac->period_len) % tdmac->buf_len; tasklet_schedule(&tdmac->tasklet); return IRQ_HANDLED; } else @@ -343,7 +361,7 @@ static void mmp_tdma_free_descriptor(struct mmp_tdma_chan *tdmac) int size = tdmac->desc_num * sizeof(struct mmp_tdma_desc); gpool = tdmac->pool; - if (tdmac->desc_arr) + if (gpool && tdmac->desc_arr) gen_pool_free(gpool, (unsigned long)tdmac->desc_arr, size); tdmac->desc_arr = NULL; @@ -499,6 +517,7 @@ static enum dma_status mmp_tdma_tx_status(struct dma_chan *chan, { struct mmp_tdma_chan *tdmac = to_mmp_tdma_chan(chan); + tdmac->pos = mmp_tdma_get_pos(tdmac); dma_set_tx_state(txstate, chan->completed_cookie, chan->cookie, tdmac->buf_len - tdmac->pos); @@ -610,7 +629,7 @@ static int mmp_tdma_probe(struct platform_device *pdev) int i, ret; int irq = 0, irq_num = 0; int chan_num = TDMA_CHANNEL_NUM; - struct gen_pool *pool; + struct gen_pool *pool = NULL; of_id = of_match_device(mmp_tdma_dt_ids, &pdev->dev); if (of_id) -- GitLab From a39294bdf4b03803156c771968a6e2ba6ebb505b Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 5 Feb 2015 16:49:08 +0100 Subject: [PATCH 02533/11651] gpio: pcf857x: Switch to use gpiolib irqchip helpers Switch the PCF857x GPIO driver to use the gpiolib irqchip helpers. This driver uses a nested threaded interrupt, hence handle_nested_irq() and gpiochip_set_chained_irqchip() must be used. Note that this removes the checks added in commit 21fd3cd1874a2ac8 ("gpio: pcf857x: call the gpio user handler iff gpio_to_irq is done"), as the interrupt mappings are no longer created on-demand by the driver, but by gpiochip_irqchip_add() during initialization. Signed-off-by: Geert Uytterhoeven Signed-off-by: Linus Walleij --- drivers/gpio/Kconfig | 1 + drivers/gpio/gpio-pcf857x.c | 121 ++++++++---------------------------- 2 files changed, 28 insertions(+), 94 deletions(-) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 09bc70b3875b..249845a47624 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -604,6 +604,7 @@ config GPIO_PCA953X_IRQ config GPIO_PCF857X tristate "PCF857x, PCA{85,96}7x, and MAX732[89] I2C GPIO expanders" depends on I2C + select GPIOLIB_IRQCHIP select IRQ_DOMAIN help Say yes here to provide access to most "quasi-bidirectional" I2C diff --git a/drivers/gpio/gpio-pcf857x.c b/drivers/gpio/gpio-pcf857x.c index 236708ad0a5b..126c93732101 100644 --- a/drivers/gpio/gpio-pcf857x.c +++ b/drivers/gpio/gpio-pcf857x.c @@ -88,11 +88,9 @@ struct pcf857x { struct gpio_chip chip; struct i2c_client *client; struct mutex lock; /* protect 'out' */ - struct irq_domain *irq_domain; /* for irq demux */ spinlock_t slock; /* protect irq demux */ unsigned out; /* software latch */ unsigned status; /* current status */ - unsigned irq_mapped; /* mapped gpio irqs */ int (*write)(struct i2c_client *client, unsigned data); int (*read)(struct i2c_client *client); @@ -182,18 +180,6 @@ static void pcf857x_set(struct gpio_chip *chip, unsigned offset, int value) /*-------------------------------------------------------------------------*/ -static int pcf857x_to_irq(struct gpio_chip *chip, unsigned offset) -{ - struct pcf857x *gpio = container_of(chip, struct pcf857x, chip); - int ret; - - ret = irq_create_mapping(gpio->irq_domain, offset); - if (ret > 0) - gpio->irq_mapped |= (1 << offset); - - return ret; -} - static irqreturn_t pcf857x_irq(int irq, void *data) { struct pcf857x *gpio = data; @@ -208,9 +194,9 @@ static irqreturn_t pcf857x_irq(int irq, void *data) * interrupt source, just to avoid bad irqs */ - change = ((gpio->status ^ status) & gpio->irq_mapped); + change = (gpio->status ^ status); for_each_set_bit(i, &change, gpio->chip.ngpio) - generic_handle_irq(irq_find_mapping(gpio->irq_domain, i)); + handle_nested_irq(irq_find_mapping(gpio->chip.irqdomain, i)); gpio->status = status; spin_unlock_irqrestore(&gpio->slock, flags); @@ -218,66 +204,6 @@ static irqreturn_t pcf857x_irq(int irq, void *data) return IRQ_HANDLED; } -static int pcf857x_irq_domain_map(struct irq_domain *domain, unsigned int irq, - irq_hw_number_t hw) -{ - struct pcf857x *gpio = domain->host_data; - - irq_set_chip_and_handler(irq, - &dummy_irq_chip, - handle_level_irq); -#ifdef CONFIG_ARM - set_irq_flags(irq, IRQF_VALID); -#else - irq_set_noprobe(irq); -#endif - gpio->irq_mapped |= (1 << hw); - - return 0; -} - -static struct irq_domain_ops pcf857x_irq_domain_ops = { - .map = pcf857x_irq_domain_map, -}; - -static void pcf857x_irq_domain_cleanup(struct pcf857x *gpio) -{ - if (gpio->irq_domain) - irq_domain_remove(gpio->irq_domain); - -} - -static int pcf857x_irq_domain_init(struct pcf857x *gpio, - struct i2c_client *client) -{ - int status; - - gpio->irq_domain = irq_domain_add_linear(client->dev.of_node, - gpio->chip.ngpio, - &pcf857x_irq_domain_ops, - gpio); - if (!gpio->irq_domain) - goto fail; - - /* enable real irq */ - status = devm_request_threaded_irq(&client->dev, client->irq, - NULL, pcf857x_irq, IRQF_ONESHOT | - IRQF_TRIGGER_FALLING | IRQF_SHARED, - dev_name(&client->dev), gpio); - - if (status) - goto fail; - - /* enable gpio_to_irq() */ - gpio->chip.to_irq = pcf857x_to_irq; - - return 0; - -fail: - pcf857x_irq_domain_cleanup(gpio); - return -EINVAL; -} - /*-------------------------------------------------------------------------*/ static int pcf857x_probe(struct i2c_client *client, @@ -314,15 +240,6 @@ static int pcf857x_probe(struct i2c_client *client, gpio->chip.direction_output = pcf857x_output; gpio->chip.ngpio = id->driver_data; - /* enable gpio_to_irq() if platform has settings */ - if (client->irq) { - status = pcf857x_irq_domain_init(gpio, client); - if (status < 0) { - dev_err(&client->dev, "irq_domain init failed\n"); - goto fail_irq_domain; - } - } - /* NOTE: the OnSemi jlc1562b is also largely compatible with * these parts, notably for output. It has a low-resolution * DAC instead of pin change IRQs; and its inputs can be the @@ -398,6 +315,26 @@ static int pcf857x_probe(struct i2c_client *client, if (status < 0) goto fail; + /* Enable irqchip if we have an interrupt */ + if (client->irq) { + status = gpiochip_irqchip_add(&gpio->chip, &dummy_irq_chip, 0, + handle_level_irq, IRQ_TYPE_NONE); + if (status) { + dev_err(&client->dev, "cannot add irqchip\n"); + goto fail_irq; + } + + status = devm_request_threaded_irq(&client->dev, client->irq, + NULL, pcf857x_irq, IRQF_ONESHOT | + IRQF_TRIGGER_FALLING | IRQF_SHARED, + dev_name(&client->dev), gpio); + if (status) + goto fail_irq; + + gpiochip_set_chained_irqchip(&gpio->chip, &dummy_irq_chip, + client->irq, NULL); + } + /* Let platform code set up the GPIOs and their users. * Now is the first time anyone could use them. */ @@ -413,13 +350,12 @@ static int pcf857x_probe(struct i2c_client *client, return 0; -fail: - if (client->irq) - pcf857x_irq_domain_cleanup(gpio); +fail_irq: + gpiochip_remove(&gpio->chip); -fail_irq_domain: - dev_dbg(&client->dev, "probe error %d for '%s'\n", - status, client->name); +fail: + dev_dbg(&client->dev, "probe error %d for '%s'\n", status, + client->name); return status; } @@ -441,9 +377,6 @@ static int pcf857x_remove(struct i2c_client *client) } } - if (client->irq) - pcf857x_irq_domain_cleanup(gpio); - gpiochip_remove(&gpio->chip); return status; } -- GitLab From b80eef95beb04760629822fa130aeed54cdfafca Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 5 Feb 2015 16:49:09 +0100 Subject: [PATCH 02534/11651] gpio: pcf857x: Propagate wake-up setting to parent irq controller The pcf857x GPIO and interrupt controller uses dummy_irq_chip, which does not implement irq_chip.irq_set_wake() and does not set IRQCHIP_SKIP_SET_WAKE. This causes two s2ram issues if wake-up is enabled for the pcf857x GPIO pins: 1. During resume from s2ram, the following warning is printed: WARNING: CPU: 0 PID: 1046 at kernel/irq/manage.c:537 irq_set_irq_wake+0x9c/0xf8() Unbalanced IRQ 113 wake disable 2. Wake-up through the pcf857x GPIO pins may fail, as the parent interrupt controller may be suspended. Migrate the pcf857x GPIO and interrupt controller from dummy_irq_chip to its own irq_chip. This irq chip implements irq_chip.irq_set_wake() to propagate its wake-up setting to the parent interrupt controller. This fixes wake-up through gpio-keys on sh73a0/kzm9g, where the pcf857x interrupt is cascaded to irq-renesas-intc-irqpin, and the latter must not be suspended when wake-up is enabled. Signed-off-by: Geert Uytterhoeven Signed-off-by: Linus Walleij --- drivers/gpio/gpio-pcf857x.c | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/drivers/gpio/gpio-pcf857x.c b/drivers/gpio/gpio-pcf857x.c index 126c93732101..945f0cda8529 100644 --- a/drivers/gpio/gpio-pcf857x.c +++ b/drivers/gpio/gpio-pcf857x.c @@ -204,6 +204,36 @@ static irqreturn_t pcf857x_irq(int irq, void *data) return IRQ_HANDLED; } +/* + * NOP functions + */ +static void noop(struct irq_data *data) { } + +static unsigned int noop_ret(struct irq_data *data) +{ + return 0; +} + +static int pcf857x_irq_set_wake(struct irq_data *data, unsigned int on) +{ + struct pcf857x *gpio = irq_data_get_irq_chip_data(data); + + irq_set_irq_wake(gpio->client->irq, on); + return 0; +} + +static struct irq_chip pcf857x_irq_chip = { + .name = "pcf857x", + .irq_startup = noop_ret, + .irq_shutdown = noop, + .irq_enable = noop, + .irq_disable = noop, + .irq_ack = noop, + .irq_mask = noop, + .irq_unmask = noop, + .irq_set_wake = pcf857x_irq_set_wake, +}; + /*-------------------------------------------------------------------------*/ static int pcf857x_probe(struct i2c_client *client, @@ -317,8 +347,9 @@ static int pcf857x_probe(struct i2c_client *client, /* Enable irqchip if we have an interrupt */ if (client->irq) { - status = gpiochip_irqchip_add(&gpio->chip, &dummy_irq_chip, 0, - handle_level_irq, IRQ_TYPE_NONE); + status = gpiochip_irqchip_add(&gpio->chip, &pcf857x_irq_chip, + 0, handle_level_irq, + IRQ_TYPE_NONE); if (status) { dev_err(&client->dev, "cannot add irqchip\n"); goto fail_irq; @@ -331,7 +362,7 @@ static int pcf857x_probe(struct i2c_client *client, if (status) goto fail_irq; - gpiochip_set_chained_irqchip(&gpio->chip, &dummy_irq_chip, + gpiochip_set_chained_irqchip(&gpio->chip, &pcf857x_irq_chip, client->irq, NULL); } -- GitLab From ee086577abe7f7ccf5f64a33479a36e22710b7d0 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Fri, 6 Feb 2015 16:57:53 +0100 Subject: [PATCH 02535/11651] pinctrl: mvebu: add pinctrl driver for Marvell Armada 39x This commit adds a new pinctrl driver for the Marvell Armada 39x family of processors, which hooks into the existing infrastructure to support pin-muxing on Marvell EBU processors. Two variants of the Armada 39x are supported: 88F6920 (Armada 390) and 88F6928 (Armada 398), which have a few differences in the available functions for certain pins. Signed-off-by: Thomas Petazzoni Signed-off-by: Linus Walleij --- drivers/pinctrl/mvebu/Kconfig | 4 + drivers/pinctrl/mvebu/Makefile | 1 + drivers/pinctrl/mvebu/pinctrl-armada-39x.c | 432 +++++++++++++++++++++ 3 files changed, 437 insertions(+) create mode 100644 drivers/pinctrl/mvebu/pinctrl-armada-39x.c diff --git a/drivers/pinctrl/mvebu/Kconfig b/drivers/pinctrl/mvebu/Kconfig index d6dd8358a6f6..170602407c0d 100644 --- a/drivers/pinctrl/mvebu/Kconfig +++ b/drivers/pinctrl/mvebu/Kconfig @@ -26,6 +26,10 @@ config PINCTRL_ARMADA_38X bool select PINCTRL_MVEBU +config PINCTRL_ARMADA_39X + bool + select PINCTRL_MVEBU + config PINCTRL_ARMADA_XP bool select PINCTRL_MVEBU diff --git a/drivers/pinctrl/mvebu/Makefile b/drivers/pinctrl/mvebu/Makefile index a0818e96374b..554d8af14eeb 100644 --- a/drivers/pinctrl/mvebu/Makefile +++ b/drivers/pinctrl/mvebu/Makefile @@ -4,5 +4,6 @@ obj-$(CONFIG_PINCTRL_KIRKWOOD) += pinctrl-kirkwood.o obj-$(CONFIG_PINCTRL_ARMADA_370) += pinctrl-armada-370.o obj-$(CONFIG_PINCTRL_ARMADA_375) += pinctrl-armada-375.o obj-$(CONFIG_PINCTRL_ARMADA_38X) += pinctrl-armada-38x.o +obj-$(CONFIG_PINCTRL_ARMADA_39X) += pinctrl-armada-39x.o obj-$(CONFIG_PINCTRL_ARMADA_XP) += pinctrl-armada-xp.o obj-$(CONFIG_PINCTRL_ORION) += pinctrl-orion.o diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-39x.c b/drivers/pinctrl/mvebu/pinctrl-armada-39x.c new file mode 100644 index 000000000000..5963411988a2 --- /dev/null +++ b/drivers/pinctrl/mvebu/pinctrl-armada-39x.c @@ -0,0 +1,432 @@ +/* + * Marvell Armada 39x pinctrl driver based on mvebu pinctrl core + * + * Copyright (C) 2015 Marvell + * + * Thomas Petazzoni + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pinctrl-mvebu.h" + +static void __iomem *mpp_base; + +static int armada_39x_mpp_ctrl_get(unsigned pid, unsigned long *config) +{ + return default_mpp_ctrl_get(mpp_base, pid, config); +} + +static int armada_39x_mpp_ctrl_set(unsigned pid, unsigned long config) +{ + return default_mpp_ctrl_set(mpp_base, pid, config); +} + +enum { + V_88F6920 = BIT(0), + V_88F6928 = BIT(1), + V_88F6920_PLUS = (V_88F6920 | V_88F6928), +}; + +static struct mvebu_mpp_mode armada_39x_mpp_modes[] = { + MPP_MODE(0, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(1, "ua0", "rxd", V_88F6920_PLUS)), + MPP_MODE(1, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(1, "ua0", "txd", V_88F6920_PLUS)), + MPP_MODE(2, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(1, "i2c0", "sck", V_88F6920_PLUS)), + MPP_MODE(3, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(1, "i2c0", "sda", V_88F6920_PLUS)), + MPP_MODE(4, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(2, "ua1", "txd", V_88F6920_PLUS), + MPP_VAR_FUNCTION(3, "ua0", "rts", V_88F6920_PLUS), + MPP_VAR_FUNCTION(7, "smi", "mdc", V_88F6920_PLUS)), + MPP_MODE(5, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(2, "ua1", "rxd", V_88F6920_PLUS), + MPP_VAR_FUNCTION(3, "ua0", "cts", V_88F6920_PLUS), + MPP_VAR_FUNCTION(7, "smi", "mdio", V_88F6920_PLUS)), + MPP_MODE(6, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(5, "dev", "cs3", V_88F6920_PLUS), + MPP_VAR_FUNCTION(7, "xsmi", "mdio", V_88F6920_PLUS)), + MPP_MODE(7, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(5, "dev", "ad9", V_88F6920_PLUS), + MPP_VAR_FUNCTION(7, "xsmi", "mdc", V_88F6920_PLUS)), + MPP_MODE(8, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(5, "dev", "ad10", V_88F6920_PLUS), + MPP_VAR_FUNCTION(7, "ptp", "trig", V_88F6920_PLUS)), + MPP_MODE(9, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(5, "dev", "ad11", V_88F6920_PLUS), + MPP_VAR_FUNCTION(7, "ptp", "clk", V_88F6920_PLUS)), + MPP_MODE(10, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(5, "dev", "ad12", V_88F6920_PLUS), + MPP_VAR_FUNCTION(7, "ptp", "event", V_88F6920_PLUS)), + MPP_MODE(11, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(5, "dev", "ad13", V_88F6920_PLUS), + MPP_VAR_FUNCTION(7, "led", "clk", V_88F6920_PLUS)), + MPP_MODE(12, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(2, "pcie0", "rstout", V_88F6920_PLUS), + MPP_VAR_FUNCTION(5, "dev", "ad14", V_88F6920_PLUS), + MPP_VAR_FUNCTION(7, "led", "stb", V_88F6920_PLUS)), + MPP_MODE(13, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(5, "dev", "ad15", V_88F6920_PLUS), + MPP_VAR_FUNCTION(7, "led", "data", V_88F6920_PLUS)), + MPP_MODE(14, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(3, "m", "vtt", V_88F6920_PLUS), + MPP_VAR_FUNCTION(5, "dev", "wen1", V_88F6920_PLUS), + MPP_VAR_FUNCTION(7, "ua1", "txd", V_88F6920_PLUS)), + MPP_MODE(15, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(3, "pcie0", "rstout", V_88F6920_PLUS), + MPP_VAR_FUNCTION(4, "spi0", "mosi", V_88F6920_PLUS), + MPP_VAR_FUNCTION(7, "i2c1", "sck", V_88F6920_PLUS)), + MPP_MODE(16, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(3, "m", "decc", V_88F6920_PLUS), + MPP_VAR_FUNCTION(4, "spi0", "miso", V_88F6920_PLUS), + MPP_VAR_FUNCTION(7, "i2c1", "sda", V_88F6920_PLUS)), + MPP_MODE(17, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(3, "ua1", "rxd", V_88F6920_PLUS), + MPP_VAR_FUNCTION(4, "spi0", "sck", V_88F6920_PLUS), + MPP_VAR_FUNCTION(7, "smi", "mdio", V_88F6920_PLUS)), + MPP_MODE(18, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(3, "ua1", "txd", V_88F6920_PLUS), + MPP_VAR_FUNCTION(4, "spi0", "cs0", V_88F6920_PLUS), + MPP_VAR_FUNCTION(7, "i2c2", "sck", V_88F6920_PLUS)), + MPP_MODE(19, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(4, "sata1", "present", V_88F6928), + MPP_VAR_FUNCTION(5, "ua0", "cts", V_88F6920_PLUS), + MPP_VAR_FUNCTION(6, "ua1", "rxd", V_88F6920_PLUS), + MPP_VAR_FUNCTION(7, "i2c2", "sda", V_88F6920_PLUS)), + MPP_MODE(20, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(4, "sata0", "present", V_88F6928), + MPP_VAR_FUNCTION(5, "ua0", "rts", V_88F6920_PLUS), + MPP_VAR_FUNCTION(6, "ua1", "txd", V_88F6920_PLUS), + MPP_VAR_FUNCTION(7, "smi", "mdc", V_88F6920_PLUS)), + MPP_MODE(21, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(1, "spi0", "cs1", V_88F6920_PLUS), + MPP_VAR_FUNCTION(3, "sata0", "present", V_88F6928), + MPP_VAR_FUNCTION(4, "sd", "cmd", V_88F6920_PLUS), + MPP_VAR_FUNCTION(5, "dev", "bootcs", V_88F6920_PLUS), + MPP_VAR_FUNCTION(8, "ge", "rxd0", V_88F6920_PLUS)), + MPP_MODE(22, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(1, "spi0", "mosi", V_88F6920_PLUS), + MPP_VAR_FUNCTION(5, "dev", "ad0", V_88F6920_PLUS)), + MPP_MODE(23, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(1, "spi0", "sck", V_88F6920_PLUS), + MPP_VAR_FUNCTION(5, "dev", "ad2", V_88F6920_PLUS)), + MPP_MODE(24, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(1, "spi0", "miso", V_88F6920_PLUS), + MPP_VAR_FUNCTION(2, "ua0", "cts", V_88F6920_PLUS), + MPP_VAR_FUNCTION(3, "ua1", "rxd", V_88F6920_PLUS), + MPP_VAR_FUNCTION(4, "sd", "d4", V_88F6920_PLUS), + MPP_VAR_FUNCTION(5, "dev", "readyn", V_88F6920_PLUS)), + MPP_MODE(25, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(1, "spi0", "cs0", V_88F6920_PLUS), + MPP_VAR_FUNCTION(2, "ua0", "rts", V_88F6920_PLUS), + MPP_VAR_FUNCTION(3, "ua1", "txd", V_88F6920_PLUS), + MPP_VAR_FUNCTION(4, "sd", "d5", V_88F6920_PLUS), + MPP_VAR_FUNCTION(5, "dev", "cs0", V_88F6920_PLUS)), + MPP_MODE(26, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(1, "spi0", "cs2", V_88F6920_PLUS), + MPP_VAR_FUNCTION(3, "i2c1", "sck", V_88F6920_PLUS), + MPP_VAR_FUNCTION(4, "sd", "d6", V_88F6920_PLUS), + MPP_VAR_FUNCTION(5, "dev", "cs1", V_88F6920_PLUS)), + MPP_MODE(27, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(1, "spi0", "cs3", V_88F6920_PLUS), + MPP_VAR_FUNCTION(3, "i2c1", "sda", V_88F6920_PLUS), + MPP_VAR_FUNCTION(4, "sd", "d7", V_88F6920_PLUS), + MPP_VAR_FUNCTION(5, "dev", "cs2", V_88F6920_PLUS), + MPP_VAR_FUNCTION(8, "ge", "txclkout", V_88F6920_PLUS)), + MPP_MODE(28, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(4, "sd", "clk", V_88F6920_PLUS), + MPP_VAR_FUNCTION(5, "dev", "ad5", V_88F6920_PLUS), + MPP_VAR_FUNCTION(8, "ge", "txd0", V_88F6920_PLUS)), + MPP_MODE(29, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(5, "dev", "ale0", V_88F6920_PLUS), + MPP_VAR_FUNCTION(8, "ge", "txd1", V_88F6920_PLUS)), + MPP_MODE(30, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(5, "dev", "oen", V_88F6920_PLUS), + MPP_VAR_FUNCTION(8, "ge", "txd2", V_88F6920_PLUS)), + MPP_MODE(31, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(5, "dev", "ale1", V_88F6920_PLUS), + MPP_VAR_FUNCTION(8, "ge", "txd3", V_88F6920_PLUS)), + MPP_MODE(32, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(5, "dev", "wen0", V_88F6920_PLUS), + MPP_VAR_FUNCTION(8, "ge", "txctl", V_88F6920_PLUS)), + MPP_MODE(33, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(1, "m", "decc", V_88F6920_PLUS), + MPP_VAR_FUNCTION(5, "dev", "ad3", V_88F6920_PLUS)), + MPP_MODE(34, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(5, "dev", "ad1", V_88F6920_PLUS)), + MPP_MODE(35, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(1, "ref", "clk", V_88F6920_PLUS), + MPP_VAR_FUNCTION(5, "dev", "a1", V_88F6920_PLUS)), + MPP_MODE(36, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(5, "dev", "a0", V_88F6920_PLUS)), + MPP_MODE(37, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(4, "sd", "d3", V_88F6920_PLUS), + MPP_VAR_FUNCTION(5, "dev", "ad8", V_88F6920_PLUS), + MPP_VAR_FUNCTION(8, "ge", "rxclk", V_88F6920_PLUS)), + MPP_MODE(38, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(3, "ref", "clk", V_88F6920_PLUS), + MPP_VAR_FUNCTION(4, "sd", "d0", V_88F6920_PLUS), + MPP_VAR_FUNCTION(5, "dev", "ad4", V_88F6920_PLUS), + MPP_VAR_FUNCTION(8, "ge", "rxd1", V_88F6920_PLUS)), + MPP_MODE(39, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(1, "i2c1", "sck", V_88F6920_PLUS), + MPP_VAR_FUNCTION(3, "ua0", "cts", V_88F6920_PLUS), + MPP_VAR_FUNCTION(4, "sd", "d1", V_88F6920_PLUS), + MPP_VAR_FUNCTION(5, "dev", "a2", V_88F6920_PLUS), + MPP_VAR_FUNCTION(8, "ge", "rxd2", V_88F6920_PLUS)), + MPP_MODE(40, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(1, "i2c1", "sda", V_88F6920_PLUS), + MPP_VAR_FUNCTION(3, "ua0", "rts", V_88F6920_PLUS), + MPP_VAR_FUNCTION(4, "sd", "d2", V_88F6920_PLUS), + MPP_VAR_FUNCTION(5, "dev", "ad6", V_88F6920_PLUS), + MPP_VAR_FUNCTION(8, "ge", "rxd3", V_88F6920_PLUS)), + MPP_MODE(41, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(1, "ua1", "rxd", V_88F6920_PLUS), + MPP_VAR_FUNCTION(3, "ua0", "cts", V_88F6920_PLUS), + MPP_VAR_FUNCTION(4, "spi1", "cs3", V_88F6920_PLUS), + MPP_VAR_FUNCTION(5, "dev", "burstn", V_88F6920_PLUS), + MPP_VAR_FUNCTION(6, "nd", "rbn0", V_88F6920_PLUS), + MPP_VAR_FUNCTION(8, "ge", "rxctl", V_88F6920_PLUS)), + MPP_MODE(42, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(1, "ua1", "txd", V_88F6920_PLUS), + MPP_VAR_FUNCTION(3, "ua0", "rts", V_88F6920_PLUS), + MPP_VAR_FUNCTION(5, "dev", "ad7", V_88F6920_PLUS)), + MPP_MODE(43, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(1, "pcie0", "clkreq", V_88F6920_PLUS), + MPP_VAR_FUNCTION(2, "m", "vtt", V_88F6920_PLUS), + MPP_VAR_FUNCTION(3, "m", "decc", V_88F6920_PLUS), + MPP_VAR_FUNCTION(4, "spi1", "cs2", V_88F6920_PLUS), + MPP_VAR_FUNCTION(5, "dev", "clkout", V_88F6920_PLUS), + MPP_VAR_FUNCTION(6, "nd", "rbn1", V_88F6920_PLUS)), + MPP_MODE(44, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(1, "sata0", "present", V_88F6928), + MPP_VAR_FUNCTION(2, "sata1", "present", V_88F6928), + MPP_VAR_FUNCTION(7, "led", "clk", V_88F6920_PLUS)), + MPP_MODE(45, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(1, "ref", "clk", V_88F6920_PLUS), + MPP_VAR_FUNCTION(2, "pcie0", "rstout", V_88F6920_PLUS), + MPP_VAR_FUNCTION(6, "ua1", "rxd", V_88F6920_PLUS)), + MPP_MODE(46, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(1, "ref", "clk", V_88F6920_PLUS), + MPP_VAR_FUNCTION(2, "pcie0", "rstout", V_88F6920_PLUS), + MPP_VAR_FUNCTION(6, "ua1", "txd", V_88F6920_PLUS), + MPP_VAR_FUNCTION(7, "led", "stb", V_88F6920_PLUS)), + MPP_MODE(47, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(1, "sata0", "present", V_88F6928), + MPP_VAR_FUNCTION(2, "sata1", "present", V_88F6928), + MPP_VAR_FUNCTION(7, "led", "data", V_88F6920_PLUS)), + MPP_MODE(48, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(1, "sata0", "present", V_88F6928), + MPP_VAR_FUNCTION(2, "m", "vtt", V_88F6920_PLUS), + MPP_VAR_FUNCTION(3, "tdm", "pclk", V_88F6928), + MPP_VAR_FUNCTION(4, "audio", "mclk", V_88F6928), + MPP_VAR_FUNCTION(5, "sd", "d4", V_88F6920_PLUS), + MPP_VAR_FUNCTION(6, "pcie0", "clkreq", V_88F6920_PLUS), + MPP_VAR_FUNCTION(7, "ua1", "txd", V_88F6920_PLUS)), + MPP_MODE(49, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(3, "tdm", "fsync", V_88F6928), + MPP_VAR_FUNCTION(4, "audio", "lrclk", V_88F6928), + MPP_VAR_FUNCTION(5, "sd", "d5", V_88F6920_PLUS), + MPP_VAR_FUNCTION(7, "ua2", "rxd", V_88F6920_PLUS)), + MPP_MODE(50, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(1, "pcie0", "rstout", V_88F6920_PLUS), + MPP_VAR_FUNCTION(3, "tdm", "drx", V_88F6928), + MPP_VAR_FUNCTION(4, "audio", "extclk", V_88F6928), + MPP_VAR_FUNCTION(5, "sd", "cmd", V_88F6920_PLUS), + MPP_VAR_FUNCTION(7, "ua2", "rxd", V_88F6920_PLUS)), + MPP_MODE(51, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(3, "tdm", "dtx", V_88F6928), + MPP_VAR_FUNCTION(4, "audio", "sdo", V_88F6928), + MPP_VAR_FUNCTION(5, "m", "decc", V_88F6920_PLUS), + MPP_VAR_FUNCTION(7, "ua2", "txd", V_88F6920_PLUS)), + MPP_MODE(52, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(1, "pcie0", "rstout", V_88F6920_PLUS), + MPP_VAR_FUNCTION(3, "tdm", "intn", V_88F6928), + MPP_VAR_FUNCTION(4, "audio", "sdi", V_88F6928), + MPP_VAR_FUNCTION(5, "sd", "d6", V_88F6920_PLUS), + MPP_VAR_FUNCTION(7, "i2c3", "sck", V_88F6920_PLUS)), + MPP_MODE(53, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(1, "sata1", "present", V_88F6928), + MPP_VAR_FUNCTION(2, "sata0", "present", V_88F6928), + MPP_VAR_FUNCTION(3, "tdm", "rstn", V_88F6928), + MPP_VAR_FUNCTION(4, "audio", "bclk", V_88F6928), + MPP_VAR_FUNCTION(5, "sd", "d7", V_88F6920_PLUS), + MPP_VAR_FUNCTION(7, "i2c3", "sda", V_88F6920_PLUS)), + MPP_MODE(54, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(1, "sata0", "present", V_88F6928), + MPP_VAR_FUNCTION(2, "sata1", "present", V_88F6928), + MPP_VAR_FUNCTION(3, "pcie0", "rstout", V_88F6920_PLUS), + MPP_VAR_FUNCTION(5, "sd", "d3", V_88F6920_PLUS), + MPP_VAR_FUNCTION(7, "ua3", "txd", V_88F6920_PLUS)), + MPP_MODE(55, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(1, "ua1", "cts", V_88F6920_PLUS), + MPP_VAR_FUNCTION(4, "spi1", "cs1", V_88F6920_PLUS), + MPP_VAR_FUNCTION(5, "sd", "d0", V_88F6920_PLUS), + MPP_VAR_FUNCTION(6, "ua1", "rxd", V_88F6920_PLUS), + MPP_VAR_FUNCTION(7, "ua3", "rxd", V_88F6920_PLUS)), + MPP_MODE(56, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(1, "ua1", "rts", V_88F6920_PLUS), + MPP_VAR_FUNCTION(3, "m", "decc", V_88F6920_PLUS), + MPP_VAR_FUNCTION(4, "spi1", "mosi", V_88F6920_PLUS), + MPP_VAR_FUNCTION(6, "ua1", "txd", V_88F6920_PLUS)), + MPP_MODE(57, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(4, "spi1", "sck", V_88F6920_PLUS), + MPP_VAR_FUNCTION(5, "sd", "clk", V_88F6920_PLUS), + MPP_VAR_FUNCTION(6, "ua1", "txd", V_88F6920_PLUS)), + MPP_MODE(58, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(2, "i2c1", "sck", V_88F6920_PLUS), + MPP_VAR_FUNCTION(3, "pcie2", "clkreq", V_88F6920_PLUS), + MPP_VAR_FUNCTION(4, "spi1", "miso", V_88F6920_PLUS), + MPP_VAR_FUNCTION(5, "sd", "d1", V_88F6920_PLUS), + MPP_VAR_FUNCTION(6, "ua1", "rxd", V_88F6920_PLUS)), + MPP_MODE(59, + MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6920_PLUS), + MPP_VAR_FUNCTION(1, "pcie0", "rstout", V_88F6920_PLUS), + MPP_VAR_FUNCTION(2, "i2c1", "sda", V_88F6920_PLUS), + MPP_VAR_FUNCTION(4, "spi1", "cs0", V_88F6920_PLUS), + MPP_VAR_FUNCTION(5, "sd", "d2", V_88F6920_PLUS)), +}; + +static struct mvebu_pinctrl_soc_info armada_39x_pinctrl_info; + +static struct of_device_id armada_39x_pinctrl_of_match[] = { + { + .compatible = "marvell,mv88f6920-pinctrl", + .data = (void *) V_88F6920, + }, + { + .compatible = "marvell,mv88f6928-pinctrl", + .data = (void *) V_88F6928, + }, + { }, +}; + +static struct mvebu_mpp_ctrl armada_39x_mpp_controls[] = { + MPP_FUNC_CTRL(0, 59, NULL, armada_39x_mpp_ctrl), +}; + +static struct pinctrl_gpio_range armada_39x_mpp_gpio_ranges[] = { + MPP_GPIO_RANGE(0, 0, 0, 32), + MPP_GPIO_RANGE(1, 32, 32, 27), +}; + +static int armada_39x_pinctrl_probe(struct platform_device *pdev) +{ + struct mvebu_pinctrl_soc_info *soc = &armada_39x_pinctrl_info; + const struct of_device_id *match = + of_match_device(armada_39x_pinctrl_of_match, &pdev->dev); + struct resource *res; + + if (!match) + return -ENODEV; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + mpp_base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(mpp_base)) + return PTR_ERR(mpp_base); + + soc->variant = (unsigned) match->data & 0xff; + soc->controls = armada_39x_mpp_controls; + soc->ncontrols = ARRAY_SIZE(armada_39x_mpp_controls); + soc->gpioranges = armada_39x_mpp_gpio_ranges; + soc->ngpioranges = ARRAY_SIZE(armada_39x_mpp_gpio_ranges); + soc->modes = armada_39x_mpp_modes; + soc->nmodes = armada_39x_mpp_controls[0].npins; + + pdev->dev.platform_data = soc; + + return mvebu_pinctrl_probe(pdev); +} + +static int armada_39x_pinctrl_remove(struct platform_device *pdev) +{ + return mvebu_pinctrl_remove(pdev); +} + +static struct platform_driver armada_39x_pinctrl_driver = { + .driver = { + .name = "armada-39x-pinctrl", + .of_match_table = of_match_ptr(armada_39x_pinctrl_of_match), + }, + .probe = armada_39x_pinctrl_probe, + .remove = armada_39x_pinctrl_remove, +}; + +module_platform_driver(armada_39x_pinctrl_driver); + +MODULE_AUTHOR("Thomas Petazzoni "); +MODULE_DESCRIPTION("Marvell Armada 39x pinctrl driver"); +MODULE_LICENSE("GPL v2"); -- GitLab From 1feb57a245a4910b03202a814ffc51a900bd4aca Mon Sep 17 00:00:00 2001 From: Olliver Schinagl Date: Wed, 21 Jan 2015 22:33:46 +0100 Subject: [PATCH 02536/11651] gpio: add parameter to allow the use named gpios The gpio binding document says that new code should always use named gpios. Patch 40b73183 added support to parse a list of gpios from child nodes, but does not make it possible to use named gpios. This patch adds the con_id property and implements it is done in gpiolib.c, where the old-style of using unnamed gpios still works. Signed-off-by: Olliver Schinagl Acked-by: Bryan Wu Acked-by: Dmitry Torokhov Reviewed-by: Alexandre Courbot Signed-off-by: Linus Walleij --- drivers/gpio/devres.c | 18 +++++++++++++++++- drivers/input/keyboard/gpio_keys_polled.c | 2 +- drivers/leds/leds-gpio.c | 2 +- include/linux/gpio/consumer.h | 1 + 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/drivers/gpio/devres.c b/drivers/gpio/devres.c index 13dbd3dfc33a..12c2082f968e 100644 --- a/drivers/gpio/devres.c +++ b/drivers/gpio/devres.c @@ -111,23 +111,39 @@ EXPORT_SYMBOL(__devm_gpiod_get_index); /** * devm_get_gpiod_from_child - get a GPIO descriptor from a device's child node * @dev: GPIO consumer + * @con_id: function within the GPIO consumer * @child: firmware node (child of @dev) * * GPIO descriptors returned from this function are automatically disposed on * driver detach. */ struct gpio_desc *devm_get_gpiod_from_child(struct device *dev, + const char *con_id, struct fwnode_handle *child) { + static const char const *suffixes[] = { "gpios", "gpio" }; + char prop_name[32]; /* 32 is max size of property name */ struct gpio_desc **dr; struct gpio_desc *desc; + unsigned int i; dr = devres_alloc(devm_gpiod_release, sizeof(struct gpio_desc *), GFP_KERNEL); if (!dr) return ERR_PTR(-ENOMEM); - desc = fwnode_get_named_gpiod(child, "gpios"); + for (i = 0; i < ARRAY_SIZE(suffixes); i++) { + if (con_id) + snprintf(prop_name, sizeof(prop_name), "%s-%s", + con_id, suffixes[i]); + else + snprintf(prop_name, sizeof(prop_name), "%s", + suffixes[i]); + + desc = fwnode_get_named_gpiod(child, prop_name); + if (!IS_ERR(desc) || (PTR_ERR(desc) == -EPROBE_DEFER)) + break; + } if (IS_ERR(desc)) { devres_free(dr); return desc; diff --git a/drivers/input/keyboard/gpio_keys_polled.c b/drivers/input/keyboard/gpio_keys_polled.c index 90df4df58b07..097d7216d98e 100644 --- a/drivers/input/keyboard/gpio_keys_polled.c +++ b/drivers/input/keyboard/gpio_keys_polled.c @@ -125,7 +125,7 @@ static struct gpio_keys_platform_data *gpio_keys_polled_get_devtree_pdata(struct device_for_each_child_node(dev, child) { struct gpio_desc *desc; - desc = devm_get_gpiod_from_child(dev, child); + desc = devm_get_gpiod_from_child(dev, NULL, child); if (IS_ERR(desc)) { error = PTR_ERR(desc); if (error != -EPROBE_DEFER) diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c index d26af0a79a90..15eb3f86f670 100644 --- a/drivers/leds/leds-gpio.c +++ b/drivers/leds/leds-gpio.c @@ -184,7 +184,7 @@ static struct gpio_leds_priv *gpio_leds_create(struct platform_device *pdev) struct gpio_led led = {}; const char *state = NULL; - led.gpiod = devm_get_gpiod_from_child(dev, child); + led.gpiod = devm_get_gpiod_from_child(dev, NULL, child); if (IS_ERR(led.gpiod)) { fwnode_handle_put(child); ret = PTR_ERR(led.gpiod); diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h index 45afc2dee560..ed20759229eb 100644 --- a/include/linux/gpio/consumer.h +++ b/include/linux/gpio/consumer.h @@ -110,6 +110,7 @@ struct fwnode_handle; struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, const char *propname); struct gpio_desc *devm_get_gpiod_from_child(struct device *dev, + const char *con_id, struct fwnode_handle *child); #else /* CONFIG_GPIOLIB */ -- GitLab From 21647f73835efdd0cc71b899668a8848ad9bd8cf Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 24 Feb 2015 19:52:47 +0800 Subject: [PATCH 02537/11651] phy: miphy28lp: Avoid calling of_get_child_count() multiple times Currently, of_get_child_count() is called in each iteration of the for loop in miphy28lp_xlate(). This patch stores the return value of of_get_child_count() in miphy_dev->nphys and call of_get_child_count() once in miphy28lp_probe(). Signed-off-by: Axel Lin Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/phy-miphy28lp.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/phy/phy-miphy28lp.c b/drivers/phy/phy-miphy28lp.c index 9b2848e6115d..d44493230d0c 100644 --- a/drivers/phy/phy-miphy28lp.c +++ b/drivers/phy/phy-miphy28lp.c @@ -228,6 +228,7 @@ struct miphy28lp_dev { struct regmap *regmap; struct mutex miphy_mutex; struct miphy28lp_phy **phys; + int nphys; }; struct miphy_initval { @@ -1116,7 +1117,7 @@ static struct phy *miphy28lp_xlate(struct device *dev, return ERR_PTR(-EINVAL); } - for (index = 0; index < of_get_child_count(dev->of_node); index++) + for (index = 0; index < miphy_dev->nphys; index++) if (phynode == miphy_dev->phys[index]->phy->dev.of_node) { miphy_phy = miphy_dev->phys[index]; break; @@ -1200,15 +1201,15 @@ static int miphy28lp_probe(struct platform_device *pdev) struct miphy28lp_dev *miphy_dev; struct phy_provider *provider; struct phy *phy; - int chancount, port = 0; - int ret; + int ret, port = 0; miphy_dev = devm_kzalloc(&pdev->dev, sizeof(*miphy_dev), GFP_KERNEL); if (!miphy_dev) return -ENOMEM; - chancount = of_get_child_count(np); - miphy_dev->phys = devm_kzalloc(&pdev->dev, sizeof(phy) * chancount, + miphy_dev->nphys = of_get_child_count(np); + miphy_dev->phys = devm_kzalloc(&pdev->dev, + sizeof(phy) * miphy_dev->nphys, GFP_KERNEL); if (!miphy_dev->phys) return -ENOMEM; -- GitLab From 5bd568f5d2c95dbfeda4425c0d355093e29ae7f2 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 24 Feb 2015 19:53:45 +0800 Subject: [PATCH 02538/11651] phy: miphy365x: Avoid calling of_get_child_count() multiple times Currently, of_get_child_count() is called in each iteration of the for loop in miphy365x_xlate(). This patch stores the return value of of_get_child_count() in miphy_dev->nphys and call of_get_child_count() once in miphy365x_probe(). Signed-off-by: Axel Lin Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/phy-miphy365x.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/phy/phy-miphy365x.c b/drivers/phy/phy-miphy365x.c index 6c80154e8bff..61177a6c465a 100644 --- a/drivers/phy/phy-miphy365x.c +++ b/drivers/phy/phy-miphy365x.c @@ -150,6 +150,7 @@ struct miphy365x_dev { struct regmap *regmap; struct mutex miphy_mutex; struct miphy365x_phy **phys; + int nphys; }; /* @@ -485,7 +486,7 @@ static struct phy *miphy365x_xlate(struct device *dev, return ERR_PTR(-EINVAL); } - for (index = 0; index < of_get_child_count(dev->of_node); index++) + for (index = 0; index < miphy_dev->nphys; index++) if (phynode == miphy_dev->phys[index]->phy->dev.of_node) { miphy_phy = miphy_dev->phys[index]; break; @@ -541,15 +542,15 @@ static int miphy365x_probe(struct platform_device *pdev) struct miphy365x_dev *miphy_dev; struct phy_provider *provider; struct phy *phy; - int chancount, port = 0; - int ret; + int ret, port = 0; miphy_dev = devm_kzalloc(&pdev->dev, sizeof(*miphy_dev), GFP_KERNEL); if (!miphy_dev) return -ENOMEM; - chancount = of_get_child_count(np); - miphy_dev->phys = devm_kzalloc(&pdev->dev, sizeof(phy) * chancount, + miphy_dev->nphys = of_get_child_count(np); + miphy_dev->phys = devm_kzalloc(&pdev->dev, + sizeof(phy) * miphy_dev->nphys, GFP_KERNEL); if (!miphy_dev->phys) return -ENOMEM; -- GitLab From 7a83b145b5891f445009b341361e2e458bd13d2b Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 26 Feb 2015 07:24:49 +0800 Subject: [PATCH 02539/11651] phy: armada375-usb2: Set drvdata for phy and use it At the context we have pointer to struct phy, it's useful to call phy_get_drvdata() to get the address of cluster_phy. This has slightly better readability than calling dev_get_drvdata(phy->dev.parent). Signed-off-by: Axel Lin Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/phy-armada375-usb2.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/phy/phy-armada375-usb2.c b/drivers/phy/phy-armada375-usb2.c index 7c99ca256f05..8ccc3952c13d 100644 --- a/drivers/phy/phy-armada375-usb2.c +++ b/drivers/phy/phy-armada375-usb2.c @@ -37,7 +37,7 @@ static int armada375_usb_phy_init(struct phy *phy) struct armada375_cluster_phy *cluster_phy; u32 reg; - cluster_phy = dev_get_drvdata(phy->dev.parent); + cluster_phy = phy_get_drvdata(phy); if (!cluster_phy) return -ENODEV; @@ -131,6 +131,7 @@ static int armada375_usb_phy_probe(struct platform_device *pdev) cluster_phy->reg = usb_cluster_base; dev_set_drvdata(dev, cluster_phy); + phy_set_drvdata(phy, cluster_phy); phy_provider = devm_of_phy_provider_register(&pdev->dev, armada375_usb_phy_xlate); -- GitLab From 991e45f8f8ff079a04caa710be417e8e713e092c Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 25 Feb 2015 22:10:53 +0800 Subject: [PATCH 02540/11651] phy: xgene: Remove duplicate code to set ctx->dev Set it once is enough and it's done after devm_kzalloc(). Signed-off-by: Axel Lin Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/phy-xgene.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/phy/phy-xgene.c b/drivers/phy/phy-xgene.c index 29214a36ea28..2263cd010032 100644 --- a/drivers/phy/phy-xgene.c +++ b/drivers/phy/phy-xgene.c @@ -1704,7 +1704,6 @@ static int xgene_phy_probe(struct platform_device *pdev) for (i = 0; i < MAX_LANE; i++) ctx->sata_param.speed[i] = 2; /* Default to Gen3 */ - ctx->dev = &pdev->dev; platform_set_drvdata(pdev, ctx); ctx->phy = devm_phy_create(ctx->dev, NULL, &xgene_phy_ops); -- GitLab From 235b633eb513f8471b9f23635345ede6e49371ab Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 25 Feb 2015 22:12:53 +0800 Subject: [PATCH 02541/11651] phy: miphy28lp: Add missing .owner field in miphy28lp_ops Add missing .owner field in miphy28lp_ops, which is used for refcounting. Signed-off-by: Axel Lin Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/phy-miphy28lp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/phy/phy-miphy28lp.c b/drivers/phy/phy-miphy28lp.c index d44493230d0c..4fe1755e3aa8 100644 --- a/drivers/phy/phy-miphy28lp.c +++ b/drivers/phy/phy-miphy28lp.c @@ -1139,6 +1139,7 @@ static struct phy *miphy28lp_xlate(struct device *dev, static struct phy_ops miphy28lp_ops = { .init = miphy28lp_init, + .owner = THIS_MODULE, }; static int miphy28lp_probe_resets(struct device_node *node, -- GitLab From cfd565d1e102941ec61b2a33c3c474961300a6fb Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 26 Feb 2015 11:48:08 +0800 Subject: [PATCH 02542/11651] phy: exynos-mipi-video: Fixup the test for state->regmap syscon_regmap_lookup_by_phandle() returns ERR_PTR on error. Thus don't use null test against state->regmap. Signed-off-by: Axel Lin Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/phy-exynos-mipi-video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/phy/phy-exynos-mipi-video.c b/drivers/phy/phy-exynos-mipi-video.c index f017b2f2a54e..d19649328d05 100644 --- a/drivers/phy/phy-exynos-mipi-video.c +++ b/drivers/phy/phy-exynos-mipi-video.c @@ -59,7 +59,7 @@ static int __set_phy_state(struct exynos_mipi_video_phy *state, else reset = EXYNOS4_MIPI_PHY_SRESETN; - if (state->regmap) { + if (!IS_ERR(state->regmap)) { mutex_lock(&state->mutex); regmap_read(state->regmap, offset, &val); if (on) -- GitLab From 63f1789ec71677dd285d43d6c79ca44808f16945 Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Wed, 4 Mar 2015 16:47:11 +0800 Subject: [PATCH 02543/11651] x86/PCI/ACPI: Ignore resources consumed by host bridge itself When parsing resources for PCI host bridge, we should ignore resources consumed by host bridge itself and only report window resources available to child PCI busses. Fixes: 593669c2ac0f (x86/PCI/ACPI: Use common ACPI resource interfaces ...) Signed-off-by: Jiang Liu Signed-off-by: Rafael J. Wysocki --- arch/x86/pci/acpi.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index 6ac273832f28..e4695985f9de 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c @@ -331,7 +331,7 @@ static void probe_pci_root_info(struct pci_root_info *info, struct list_head *list) { int ret; - struct resource_entry *entry; + struct resource_entry *entry, *tmp; sprintf(info->name, "PCI Bus %04x:%02x", domain, busnum); info->bridge = device; @@ -345,8 +345,13 @@ static void probe_pci_root_info(struct pci_root_info *info, dev_dbg(&device->dev, "no IO and memory resources present in _CRS\n"); else - resource_list_for_each_entry(entry, list) - entry->res->name = info->name; + resource_list_for_each_entry_safe(entry, tmp, list) { + if ((entry->res->flags & IORESOURCE_WINDOW) == 0 || + (entry->res->flags & IORESOURCE_DISABLED)) + resource_list_destroy_entry(entry); + else + entry->res->name = info->name; + } } struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root) -- GitLab From aa714d286f2ea5fae3ca8c75acd03d8694fb657e Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Wed, 4 Mar 2015 16:47:12 +0800 Subject: [PATCH 02544/11651] x86/PCI/ACPI: Relax ACPI resource descriptor checks to work around BIOS bugs Some BIOSes report incorrect length for ACPI address space descriptors, so relax the checks to avoid regressions. This issue has appeared several times as: 3162b6f0c5e1 ("PNPACPI: truncate _CRS windows with _LEN > _MAX - _MIN + 1") d558b483d5a7 ("x86/PCI: truncate _CRS windows with _LEN > _MAX - _MIN + 1") f238b414a74a ("PNPACPI: compute Address Space length rather than using _LEN") 48728e077480 ("x86/PCI: compute Address Space length rather than using _LEN") Please refer to https://bugzilla.kernel.org/show_bug.cgi?id=94221 for more details and example malformed ACPI resource descriptors. Link: https://bugzilla.kernel.org/show_bug.cgi?id=94221 Fixes: 593669c2ac0f (x86/PCI/ACPI: Use common ACPI resource interfaces ...) Signed-off-by: Jiang Liu Tested-by: Dave Airlie Tested-by: Prakash Punnoor Signed-off-by: Rafael J. Wysocki --- drivers/acpi/resource.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c index c723668e3e27..5589a6e2a023 100644 --- a/drivers/acpi/resource.c +++ b/drivers/acpi/resource.c @@ -42,8 +42,10 @@ static bool acpi_dev_resource_len_valid(u64 start, u64 end, u64 len, bool io) * CHECKME: len might be required to check versus a minimum * length as well. 1 for io is fine, but for memory it does * not make any sense at all. + * Note: some BIOSes report incorrect length for ACPI address space + * descriptor, so remove check of 'reslen == len' to avoid regression. */ - if (len && reslen && reslen == len && start <= end) + if (len && reslen && start <= end) return true; pr_debug("ACPI: invalid or unassigned resource %s [%016llx - %016llx] length [%016llx]\n", -- GitLab From 5877b4f4677b66f92b5ed94491d69680d6eac4dc Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 4 Mar 2015 12:56:20 +0100 Subject: [PATCH 02545/11651] cpufreq: ppc: Add missing #include If CONFIG_SMP=n, does not include , causing: drivers/cpufreq/ppc-corenet-cpufreq.c: In function 'corenet_cpufreq_cpu_init': drivers/cpufreq/ppc-corenet-cpufreq.c:173:3: error: implicit declaration of function 'get_hard_smp_processor_id' [-Werror=implicit-function-declaration] Signed-off-by: Geert Uytterhoeven Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/ppc-corenet-cpufreq.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/cpufreq/ppc-corenet-cpufreq.c b/drivers/cpufreq/ppc-corenet-cpufreq.c index bee5df7794d3..7cb4b766cf94 100644 --- a/drivers/cpufreq/ppc-corenet-cpufreq.c +++ b/drivers/cpufreq/ppc-corenet-cpufreq.c @@ -22,6 +22,8 @@ #include #include +#include /* for get_hard_smp_processor_id() in UP configs */ + /** * struct cpu_data - per CPU data struct * @parent: the parent node of cpu clock -- GitLab From 66a5ca4b2c62c44692316f27b0fa39a037cce295 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Mon, 2 Mar 2015 11:24:28 -0800 Subject: [PATCH 02546/11651] PM / Domains: cleanup: rename gpd -> genpd in debugfs interface To keep consisitency with the rest of the file, use 'genpd' as the name of the 'struct generic_pm_domain' pointer instead of 'gpd'. This is just a rename, no functional changes. Signed-off-by: Kevin Hilman Acked-by: Pavel Machek Reviewed-by: Ulf Hansson Signed-off-by: Rafael J. Wysocki --- drivers/base/power/domain.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index ba4abbe4693c..45937f88e77c 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -2242,7 +2242,7 @@ static void rtpm_status_str(struct seq_file *s, struct device *dev) } static int pm_genpd_summary_one(struct seq_file *s, - struct generic_pm_domain *gpd) + struct generic_pm_domain *genpd) { static const char * const status_lookup[] = { [GPD_STATE_ACTIVE] = "on", @@ -2256,26 +2256,26 @@ static int pm_genpd_summary_one(struct seq_file *s, struct gpd_link *link; int ret; - ret = mutex_lock_interruptible(&gpd->lock); + ret = mutex_lock_interruptible(&genpd->lock); if (ret) return -ERESTARTSYS; - if (WARN_ON(gpd->status >= ARRAY_SIZE(status_lookup))) + if (WARN_ON(genpd->status >= ARRAY_SIZE(status_lookup))) goto exit; - seq_printf(s, "%-30s %-15s ", gpd->name, status_lookup[gpd->status]); + seq_printf(s, "%-30s %-15s ", genpd->name, status_lookup[genpd->status]); /* * Modifications on the list require holding locks on both * master and slave, so we are safe. - * Also gpd->name is immutable. + * Also genpd->name is immutable. */ - list_for_each_entry(link, &gpd->master_links, master_node) { + list_for_each_entry(link, &genpd->master_links, master_node) { seq_printf(s, "%s", link->slave->name); - if (!list_is_last(&link->master_node, &gpd->master_links)) + if (!list_is_last(&link->master_node, &genpd->master_links)) seq_puts(s, ", "); } - list_for_each_entry(pm_data, &gpd->dev_list, list_node) { + list_for_each_entry(pm_data, &genpd->dev_list, list_node) { kobj_path = kobject_get_path(&pm_data->dev->kobj, GFP_KERNEL); if (kobj_path == NULL) continue; @@ -2287,14 +2287,14 @@ static int pm_genpd_summary_one(struct seq_file *s, seq_puts(s, "\n"); exit: - mutex_unlock(&gpd->lock); + mutex_unlock(&genpd->lock); return 0; } static int pm_genpd_summary_show(struct seq_file *s, void *data) { - struct generic_pm_domain *gpd; + struct generic_pm_domain *genpd; int ret = 0; seq_puts(s, " domain status slaves\n"); @@ -2305,8 +2305,8 @@ static int pm_genpd_summary_show(struct seq_file *s, void *data) if (ret) return -ERESTARTSYS; - list_for_each_entry(gpd, &gpd_list, gpd_list_node) { - ret = pm_genpd_summary_one(s, gpd); + list_for_each_entry(genpd, &gpd_list, gpd_list_node) { + ret = pm_genpd_summary_one(s, genpd); if (ret) break; } -- GitLab From 1a1b9d2571fb521985616573bfa6bdb5f80c8b32 Mon Sep 17 00:00:00 2001 From: Sebastian Hesselbarth Date: Tue, 17 Feb 2015 19:52:07 +0100 Subject: [PATCH 02547/11651] ARM: dts: dove: Add some more common pinctrl settings This add common pinctrl settings for pcie[01]_clkreq, spi1, i2c[23], and internal i2c mux. These settings have either one or two options only, so put them into the SoC dtsi instead of repeating them on board level. Signed-off-by: Sebastian Hesselbarth Acked-by: Gregory CLEMENT Signed-off-by: Gregory CLEMENT --- arch/arm/boot/dts/dove.dtsi | 52 +++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/arch/arm/boot/dts/dove.dtsi b/arch/arm/boot/dts/dove.dtsi index 81209bd9525a..9ad829523a13 100644 --- a/arch/arm/boot/dts/dove.dtsi +++ b/arch/arm/boot/dts/dove.dtsi @@ -451,6 +451,11 @@ marvell,function = "gpio"; }; + pmx_pcie1_clkreq: pmx-pcie1-clkreq { + marvell,pins = "mpp9"; + marvell,function = "pex1"; + }; + pmx_gpio_10: pmx-gpio-10 { marvell,pins = "mpp10"; marvell,function = "gpio"; @@ -461,6 +466,11 @@ marvell,function = "gpio"; }; + pmx_pcie0_clkreq: pmx-pcie0-clkreq { + marvell,pins = "mpp11"; + marvell,function = "pex0"; + }; + pmx_gpio_12: pmx-gpio-12 { marvell,pins = "mpp12"; marvell,function = "gpio"; @@ -566,6 +576,18 @@ marvell,function = "gpio"; }; + pmx_spi1_4_7: pmx-spi1-4-7 { + marvell,pins = "mpp4", "mpp5", + "mpp6", "mpp7"; + marvell,function = "spi1"; + }; + + pmx_spi1_20_23: pmx-spi1-20-23 { + marvell,pins = "mpp20", "mpp21", + "mpp22", "mpp23"; + marvell,function = "spi1"; + }; + pmx_uart1: pmx-uart1 { marvell,pins = "mpp_uart1"; marvell,function = "uart1"; @@ -585,6 +607,36 @@ marvell,pins = "mpp_nand"; marvell,function = "gpo"; }; + + pmx_i2c1: pmx-i2c1 { + marvell,pins = "mpp17", "mpp19"; + marvell,function = "twsi"; + }; + + pmx_i2c2: pmx-i2c2 { + marvell,pins = "mpp_audio1"; + marvell,function = "twsi"; + }; + + pmx_ssp_i2c2: pmx-ssp-i2c2 { + marvell,pins = "mpp_audio1"; + marvell,function = "ssp/twsi"; + }; + + pmx_i2cmux_0: pmx-i2cmux-0 { + marvell,pins = "twsi"; + marvell,function = "twsi-opt1"; + }; + + pmx_i2cmux_1: pmx-i2cmux-1 { + marvell,pins = "twsi"; + marvell,function = "twsi-opt2"; + }; + + pmx_i2cmux_2: pmx-i2cmux-2 { + marvell,pins = "twsi"; + marvell,function = "twsi-opt3"; + }; }; core_clk: core-clocks@d0214 { -- GitLab From 1d7b0839941c6ee883c001716611949448f20a79 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Thu, 26 Feb 2015 10:51:17 +0100 Subject: [PATCH 02548/11651] ARM: mvebu: Fix MPIC unit address The unit-address is supposed to be equal the first reg address, which is not the case for the MPIC, that uses the mbus-controller one. Fix this. Signed-off-by: Maxime Ripard Acked-by: Gregory CLEMENT Signed-off-by: Gregory CLEMENT --- arch/arm/boot/dts/armada-38x.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/armada-38x.dtsi b/arch/arm/boot/dts/armada-38x.dtsi index cb30fb82a046..a7f2c7b2529c 100644 --- a/arch/arm/boot/dts/armada-38x.dtsi +++ b/arch/arm/boot/dts/armada-38x.dtsi @@ -368,7 +368,7 @@ reg = <0x20000 0x100>, <0x20180 0x20>; }; - mpic: interrupt-controller@20000 { + mpic: interrupt-controller@20a00 { compatible = "marvell,mpic"; reg = <0x20a00 0x2d0>, <0x21070 0x58>; #interrupt-cells = <1>; -- GitLab From ef34481712067205ca3a9ca52c8484550702b4e2 Mon Sep 17 00:00:00 2001 From: Simon Guinot Date: Wed, 25 Feb 2015 19:00:19 +0100 Subject: [PATCH 02549/11651] ARM: Kirkwood: enable GPIO fan alarm support for 2Big Network v2 On the LaCie 2Big Network v2 (net2big_v2) board, the fan alarm is not wired to the I2C fan controller but to a separe GPIO. This GPIO can be controlled by using the gpio-fan driver. This patch adds the gpio-fan alarm description in the net2big_v2 DTS. Signed-off-by: Simon Guinot Signed-off-by: Gregory CLEMENT --- arch/arm/boot/dts/kirkwood-net2big.dts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm/boot/dts/kirkwood-net2big.dts b/arch/arm/boot/dts/kirkwood-net2big.dts index 53dc37a3b687..13a44773b6df 100644 --- a/arch/arm/boot/dts/kirkwood-net2big.dts +++ b/arch/arm/boot/dts/kirkwood-net2big.dts @@ -27,6 +27,11 @@ device_type = "memory"; reg = <0x00000000 0x10000000>; }; + + fan { + compatible = "gpio-fan"; + alarm-gpios = <&gpio0 25 GPIO_ACTIVE_LOW>; + }; }; ®ulators { -- GitLab From 924361249de339123e15d78c1d95dd450a6e3f03 Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Sat, 28 Feb 2015 21:20:48 +0100 Subject: [PATCH 02550/11651] ARM: ARMADA XP: WRT1900AC: Add support for the Ethernet switch Add a DSA section to the DT blob representing the Ethernet switch. Signed-off-by: Andrew Lunn Signed-off-by: Gregory CLEMENT --- arch/arm/boot/dts/armada-xp-linksys-mamba.dts | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts index 485a6eb86910..a2cf2154dcdb 100644 --- a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts +++ b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts @@ -327,6 +327,51 @@ gpio-fan,speed-map = <0 0 4500 1>; }; + + dsa@0 { + compatible = "marvell,dsa"; + #address-cells = <2>; + #size-cells = <0>; + + dsa,ethernet = <ð0>; + dsa,mii-bus = <&mdio>; + + switch@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x0 0>; /* MDIO address 0, switch 0 in tree */ + + port@0 { + reg = <0>; + label = "lan4"; + }; + + port@1 { + reg = <1>; + label = "lan3"; + }; + + port@2 { + reg = <2>; + label = "lan2"; + }; + + port@3 { + reg = <3>; + label = "lan1"; + }; + + port@4 { + reg = <4>; + label = "internet"; + }; + + port@5 { + reg = <5>; + label = "cpu"; + }; + }; + }; }; &pinctrl { -- GitLab From 2a2dbd8b411028151a8adb09db3395a95769b4bb Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Tue, 3 Mar 2015 11:16:45 +0100 Subject: [PATCH 02551/11651] ARM: mvebu: a385-db-ap: Enable the NAND The Armada 385 Access Point Development Board has a 1GB NAND SLC chip from Micron as its main storage. Enable it. Signed-off-by: Maxime Ripard Signed-off-by: Gregory CLEMENT --- arch/arm/boot/dts/armada-385-db-ap.dts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/arch/arm/boot/dts/armada-385-db-ap.dts b/arch/arm/boot/dts/armada-385-db-ap.dts index 57b9119fb3e0..9e33f7d7276b 100644 --- a/arch/arm/boot/dts/armada-385-db-ap.dts +++ b/arch/arm/boot/dts/armada-385-db-ap.dts @@ -150,6 +150,19 @@ phy = <&phy0>; phy-mode = "rgmii-id"; }; + + nfc: flash@d0000 { + status = "okay"; + #address-cells = <1>; + #size-cells = <1>; + + num-cs = <1>; + nand-ecc-strength = <4>; + nand-ecc-step-size = <512>; + marvell,nand-keep-config; + marvell,nand-enable-arbiter; + nand-on-flash-bbt; + }; }; pcie-controller { -- GitLab From 0a987fb0069e83be32bb21e07d335d2a3d7e7f5e Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Fri, 13 Feb 2015 13:30:15 +0100 Subject: [PATCH 02552/11651] ath10k: workaround qca6174 sta powersave issue qca6184 WLAN.RM.2.0-00073 has a bug in sta powersave state machine and requires peer param to be poked to enable the powersave. Calling this unconditionally should be safe for other chips/firmwares. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/mac.c | 12 ++++++++++++ drivers/net/wireless/ath/ath10k/wmi.h | 3 ++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index f9c1507478ea..943e8909ea82 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -1922,6 +1922,18 @@ static void ath10k_bss_assoc(struct ieee80211_hw *hw, } arvif->is_up = true; + + /* Workaround: Some firmware revisions (tested with qca6174 + * WLAN.RM.2.0-00073) have buggy powersave state machine and must be + * poked with peer param command. + */ + ret = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, arvif->bssid, + WMI_PEER_DUMMY_VAR, 1); + if (ret) { + ath10k_warn(ar, "failed to poke peer %pM param for ps workaround on vdev %i: %d\n", + arvif->bssid, arvif->vdev_id, ret); + return; + } } static void ath10k_bss_disassoc(struct ieee80211_hw *hw, diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h index 28c1822af6cf..adf935bf0580 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.h +++ b/drivers/net/wireless/ath/ath10k/wmi.h @@ -4445,7 +4445,8 @@ enum wmi_peer_param { WMI_PEER_AUTHORIZE = 0x3, WMI_PEER_CHAN_WIDTH = 0x4, WMI_PEER_NSS = 0x5, - WMI_PEER_USE_4ADDR = 0x6 + WMI_PEER_USE_4ADDR = 0x6, + WMI_PEER_DUMMY_VAR = 0xff, /* dummy parameter for STA PS workaround */ }; struct wmi_peer_set_param_cmd { -- GitLab From cffb41f3eeaae77c0c747f671a2809a790d1413f Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Fri, 13 Feb 2015 13:30:16 +0100 Subject: [PATCH 02553/11651] ath10k: disable multi-vif ps by default Not all firmware revisions have a proper multi-interface client powersaving implementation, e.g. qca6174 WLAN.RM.2.0-00073. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/core.h | 7 ++++++ drivers/net/wireless/ath/ath10k/mac.c | 31 ++++++++++++++++++++++++-- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index 7cba7815be96..f65310c3ba5f 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -308,6 +308,7 @@ struct ath10k_vif { bool is_started; bool is_up; bool spectral_enabled; + bool ps; u32 aid; u8 bssid[ETH_ALEN]; @@ -433,6 +434,12 @@ enum ath10k_fw_features { */ ATH10K_FW_FEATURE_WMI_10_2 = 4, + /* Some firmware revisions lack proper multi-interface client powersave + * implementation. Enabling PS could result in connection drops, + * traffic stalls, etc. + */ + ATH10K_FW_FEATURE_MULTI_VIF_PS_SUPPORT = 5, + /* keep last */ ATH10K_FW_FEATURE_COUNT, }; diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 943e8909ea82..51838ed26eab 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -1251,6 +1251,20 @@ static int ath10k_mac_vif_recalc_ps_poll_count(struct ath10k_vif *arvif) return 0; } +static int ath10k_mac_ps_vif_count(struct ath10k *ar) +{ + struct ath10k_vif *arvif; + int num = 0; + + lockdep_assert_held(&ar->conf_mutex); + + list_for_each_entry(arvif, &ar->arvifs, list) + if (arvif->ps) + num++; + + return num; +} + static int ath10k_mac_vif_setup_ps(struct ath10k_vif *arvif) { struct ath10k *ar = arvif->ar; @@ -1260,13 +1274,24 @@ static int ath10k_mac_vif_setup_ps(struct ath10k_vif *arvif) enum wmi_sta_ps_mode psmode; int ret; int ps_timeout; + bool enable_ps; lockdep_assert_held(&arvif->ar->conf_mutex); if (arvif->vif->type != NL80211_IFTYPE_STATION) return 0; - if (vif->bss_conf.ps) { + enable_ps = arvif->ps; + + if (enable_ps && ath10k_mac_ps_vif_count(ar) > 1 && + !test_bit(ATH10K_FW_FEATURE_MULTI_VIF_PS_SUPPORT, + ar->fw_features)) { + ath10k_warn(ar, "refusing to enable ps on vdev %i: not supported by fw\n", + arvif->vdev_id); + enable_ps = false; + } + + if (enable_ps) { psmode = WMI_STA_PS_MODE_ENABLED; param = WMI_STA_PS_PARAM_INACTIVITY_TIME; @@ -3650,7 +3675,9 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw, } if (changed & BSS_CHANGED_PS) { - ret = ath10k_mac_vif_setup_ps(arvif); + arvif->ps = vif->bss_conf.ps; + + ret = ath10k_config_ps(ar); if (ret) ath10k_warn(ar, "failed to setup ps on vdev %i: %d\n", arvif->vdev_id, ret); -- GitLab From bc2d7a58b9a48e4c1f35fadb30223ca87c59d50f Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Tue, 3 Mar 2015 15:40:56 +0100 Subject: [PATCH 02554/11651] ARM: mvebu: add __initconst specifiers on DT_MACHINE_START dt_compat tables As suggested by Stephen Boyd, this commit adds the __initconst specifier to the dt_compat table declarations used by the DT_MACHINE_START structures in mach-mvebu land. Signed-off-by: Thomas Petazzoni Acked-by: Gregory CLEMENT Signed-off-by: Gregory CLEMENT --- arch/arm/mach-mvebu/board-v7.c | 6 +++--- arch/arm/mach-mvebu/dove.c | 2 +- arch/arm/mach-mvebu/kirkwood.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/arm/mach-mvebu/board-v7.c b/arch/arm/mach-mvebu/board-v7.c index 89a139ed7d5b..31b66f26e029 100644 --- a/arch/arm/mach-mvebu/board-v7.c +++ b/arch/arm/mach-mvebu/board-v7.c @@ -184,7 +184,7 @@ static void __init mvebu_dt_init(void) of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); } -static const char * const armada_370_xp_dt_compat[] = { +static const char * const armada_370_xp_dt_compat[] __initconst = { "marvell,armada-370-xp", NULL, }; @@ -205,7 +205,7 @@ DT_MACHINE_START(ARMADA_370_XP_DT, "Marvell Armada 370/XP (Device Tree)") .dt_compat = armada_370_xp_dt_compat, MACHINE_END -static const char * const armada_375_dt_compat[] = { +static const char * const armada_375_dt_compat[] __initconst = { "marvell,armada375", NULL, }; @@ -219,7 +219,7 @@ DT_MACHINE_START(ARMADA_375_DT, "Marvell Armada 375 (Device Tree)") .dt_compat = armada_375_dt_compat, MACHINE_END -static const char * const armada_38x_dt_compat[] = { +static const char * const armada_38x_dt_compat[] __initconst = { "marvell,armada380", "marvell,armada385", NULL, diff --git a/arch/arm/mach-mvebu/dove.c b/arch/arm/mach-mvebu/dove.c index b50464ec1130..5a1741500a30 100644 --- a/arch/arm/mach-mvebu/dove.c +++ b/arch/arm/mach-mvebu/dove.c @@ -27,7 +27,7 @@ static void __init dove_init(void) of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); } -static const char * const dove_dt_compat[] = { +static const char * const dove_dt_compat[] __initconst = { "marvell,dove", NULL }; diff --git a/arch/arm/mach-mvebu/kirkwood.c b/arch/arm/mach-mvebu/kirkwood.c index 6b5310828eb2..925f75f54268 100644 --- a/arch/arm/mach-mvebu/kirkwood.c +++ b/arch/arm/mach-mvebu/kirkwood.c @@ -186,7 +186,7 @@ static void __init kirkwood_dt_init(void) of_platform_populate(NULL, of_default_bus_match_table, auxdata, NULL); } -static const char * const kirkwood_dt_board_compat[] = { +static const char * const kirkwood_dt_board_compat[] __initconst = { "marvell,kirkwood", NULL }; -- GitLab From a165c3b63b6f24fdc47c270db5f8b1a48b69c1b6 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Tue, 3 Mar 2015 15:40:57 +0100 Subject: [PATCH 02555/11651] ARM: mvebu: fix usb@ unit address on Armada 38x to match register address On Marvell Armada 38x, the USB2 controller registers are at 0x58000, so the corresponding Device Tree node should have a unit address of 58000, and not 50000. We were using 50000 due to an incorrect copy/pastebin of Armada 370/XP code. Signed-off-by: Thomas Petazzoni Acked-by: Gregory CLEMENT Signed-off-by: Gregory CLEMENT --- arch/arm/boot/dts/armada-388-db.dts | 2 +- arch/arm/boot/dts/armada-388-gp.dts | 2 +- arch/arm/boot/dts/armada-38x.dtsi | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/boot/dts/armada-388-db.dts b/arch/arm/boot/dts/armada-388-db.dts index 16512efcd32c..af6c74e5e7d6 100644 --- a/arch/arm/boot/dts/armada-388-db.dts +++ b/arch/arm/boot/dts/armada-388-db.dts @@ -99,7 +99,7 @@ phy-mode = "rgmii-id"; }; - usb@50000 { + usb@58000 { status = "ok"; }; diff --git a/arch/arm/boot/dts/armada-388-gp.dts b/arch/arm/boot/dts/armada-388-gp.dts index 590b383db323..3ff05739ac48 100644 --- a/arch/arm/boot/dts/armada-388-gp.dts +++ b/arch/arm/boot/dts/armada-388-gp.dts @@ -135,7 +135,7 @@ }; /* CON4 */ - usb@50000 { + usb@58000 { vcc-supply = <®_usb2_0_vbus>; status = "okay"; }; diff --git a/arch/arm/boot/dts/armada-38x.dtsi b/arch/arm/boot/dts/armada-38x.dtsi index a7f2c7b2529c..1db118bf7a7a 100644 --- a/arch/arm/boot/dts/armada-38x.dtsi +++ b/arch/arm/boot/dts/armada-38x.dtsi @@ -435,7 +435,7 @@ status = "disabled"; }; - usb@50000 { + usb@58000 { compatible = "marvell,orion-ehci"; reg = <0x58000 0x500>; interrupts = ; -- GitLab From 8a48dccb8350ad6c1f91b9f8306e555cd38b25e8 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Tue, 3 Mar 2015 15:40:58 +0100 Subject: [PATCH 02556/11651] ARM: mvebu: add missing UART labels on Armada 38x The Armada 38x had a label for UART0, but not UART1. This commit fixes that. Signed-off-by: Thomas Petazzoni Acked-by: Gregory CLEMENT Signed-off-by: Gregory CLEMENT --- arch/arm/boot/dts/armada-38x.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/armada-38x.dtsi b/arch/arm/boot/dts/armada-38x.dtsi index 1db118bf7a7a..2fedfc7d775d 100644 --- a/arch/arm/boot/dts/armada-38x.dtsi +++ b/arch/arm/boot/dts/armada-38x.dtsi @@ -216,7 +216,7 @@ status = "disabled"; }; - serial@12100 { + uart1: serial@12100 { compatible = "snps,dw-apb-uart"; reg = <0x12100 0x100>; reg-shift = <2>; -- GitLab From 43e58e90f8f9c69a453b9889f66e4562eb99b32b Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Tue, 3 Mar 2015 15:40:59 +0100 Subject: [PATCH 02557/11651] ARM: mvebu: add UART labels to Armada 375 This commit adds the standard uart0 and uart1 DT labels to the Device Tree description of the Marvell Armada 375 SoC. Signed-off-by: Thomas Petazzoni Signed-off-by: Gregory CLEMENT --- arch/arm/boot/dts/armada-375.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/armada-375.dtsi b/arch/arm/boot/dts/armada-375.dtsi index ba3c57e0af72..6307e80516dd 100644 --- a/arch/arm/boot/dts/armada-375.dtsi +++ b/arch/arm/boot/dts/armada-375.dtsi @@ -276,7 +276,7 @@ status = "disabled"; }; - serial@12000 { + uart0: serial@12000 { compatible = "snps,dw-apb-uart"; reg = <0x12000 0x100>; reg-shift = <2>; @@ -286,7 +286,7 @@ status = "disabled"; }; - serial@12100 { + uart1: serial@12100 { compatible = "snps,dw-apb-uart"; reg = <0x12100 0x100>; reg-shift = <2>; -- GitLab From 9574b2fb1cf7f6bab48714f5cf9e5382b8ca1685 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Tue, 3 Mar 2015 15:41:00 +0100 Subject: [PATCH 02558/11651] ARM: mvebu: remove aliases for Ethernet devices on Armada 370/375/38x/XP Having aliases for Ethernet devices is useless, since the networking subsystem unfortunately doesn't care about aliases to name network interfaces. Note that the 'aliases' nodes in armada-370-xp.dtsi and armada-xp.dtsi become empty, but that we keep it as is since a followup patch will re-add some aliases to it. Signed-off-by: Thomas Petazzoni Signed-off-by: Gregory CLEMENT --- arch/arm/boot/dts/armada-370-xp.dtsi | 2 -- arch/arm/boot/dts/armada-375.dtsi | 2 -- arch/arm/boot/dts/armada-38x.dtsi | 3 --- arch/arm/boot/dts/armada-xp-mv78260.dtsi | 1 - arch/arm/boot/dts/armada-xp-mv78460.dtsi | 1 - arch/arm/boot/dts/armada-xp.dtsi | 1 - 6 files changed, 10 deletions(-) diff --git a/arch/arm/boot/dts/armada-370-xp.dtsi b/arch/arm/boot/dts/armada-370-xp.dtsi index 8a322ad57e5f..d36b1e58b5b7 100644 --- a/arch/arm/boot/dts/armada-370-xp.dtsi +++ b/arch/arm/boot/dts/armada-370-xp.dtsi @@ -59,8 +59,6 @@ compatible = "marvell,armada-370-xp"; aliases { - eth0 = ð0; - eth1 = ð1; }; cpus { diff --git a/arch/arm/boot/dts/armada-375.dtsi b/arch/arm/boot/dts/armada-375.dtsi index 6307e80516dd..0d02251ede2f 100644 --- a/arch/arm/boot/dts/armada-375.dtsi +++ b/arch/arm/boot/dts/armada-375.dtsi @@ -60,8 +60,6 @@ gpio0 = &gpio0; gpio1 = &gpio1; gpio2 = &gpio2; - ethernet0 = ð0; - ethernet1 = ð1; }; clocks { diff --git a/arch/arm/boot/dts/armada-38x.dtsi b/arch/arm/boot/dts/armada-38x.dtsi index 2fedfc7d775d..f74bb01edb1b 100644 --- a/arch/arm/boot/dts/armada-38x.dtsi +++ b/arch/arm/boot/dts/armada-38x.dtsi @@ -59,9 +59,6 @@ aliases { gpio0 = &gpio0; gpio1 = &gpio1; - ethernet0 = ð0; - ethernet1 = ð1; - ethernet2 = ð2; }; soc { diff --git a/arch/arm/boot/dts/armada-xp-mv78260.dtsi b/arch/arm/boot/dts/armada-xp-mv78260.dtsi index 4a7cbed79b07..8479fdc9e9c2 100644 --- a/arch/arm/boot/dts/armada-xp-mv78260.dtsi +++ b/arch/arm/boot/dts/armada-xp-mv78260.dtsi @@ -57,7 +57,6 @@ gpio0 = &gpio0; gpio1 = &gpio1; gpio2 = &gpio2; - eth3 = ð3; }; cpus { diff --git a/arch/arm/boot/dts/armada-xp-mv78460.dtsi b/arch/arm/boot/dts/armada-xp-mv78460.dtsi index 36ce63a96cc9..661d54c81580 100644 --- a/arch/arm/boot/dts/armada-xp-mv78460.dtsi +++ b/arch/arm/boot/dts/armada-xp-mv78460.dtsi @@ -57,7 +57,6 @@ gpio0 = &gpio0; gpio1 = &gpio1; gpio2 = &gpio2; - eth3 = ð3; }; diff --git a/arch/arm/boot/dts/armada-xp.dtsi b/arch/arm/boot/dts/armada-xp.dtsi index 82917236a2fb..975ae64ead9e 100644 --- a/arch/arm/boot/dts/armada-xp.dtsi +++ b/arch/arm/boot/dts/armada-xp.dtsi @@ -57,7 +57,6 @@ compatible = "marvell,armadaxp", "marvell,armada-370-xp"; aliases { - eth2 = ð2; }; soc { -- GitLab From bf6acf1657ab906531549d3e8fbe9027d90e4c86 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Tue, 3 Mar 2015 15:41:01 +0100 Subject: [PATCH 02559/11651] ARM: mvebu: add serial port aliases on Armada 370/375/38x/XP This commit adds 'serialX' aliases for the various serial ports on Armada 370, 375, 38x and XP platforms. It will allow the usage of the stdout-path property. Signed-off-by: Thomas Petazzoni Signed-off-by: Gregory CLEMENT --- arch/arm/boot/dts/armada-370-xp.dtsi | 2 ++ arch/arm/boot/dts/armada-375.dtsi | 2 ++ arch/arm/boot/dts/armada-38x.dtsi | 2 ++ arch/arm/boot/dts/armada-xp.dtsi | 2 ++ 4 files changed, 8 insertions(+) diff --git a/arch/arm/boot/dts/armada-370-xp.dtsi b/arch/arm/boot/dts/armada-370-xp.dtsi index d36b1e58b5b7..1058cf6898fd 100644 --- a/arch/arm/boot/dts/armada-370-xp.dtsi +++ b/arch/arm/boot/dts/armada-370-xp.dtsi @@ -59,6 +59,8 @@ compatible = "marvell,armada-370-xp"; aliases { + serial0 = &uart0; + serial1 = &uart1; }; cpus { diff --git a/arch/arm/boot/dts/armada-375.dtsi b/arch/arm/boot/dts/armada-375.dtsi index 0d02251ede2f..64206939bde5 100644 --- a/arch/arm/boot/dts/armada-375.dtsi +++ b/arch/arm/boot/dts/armada-375.dtsi @@ -60,6 +60,8 @@ gpio0 = &gpio0; gpio1 = &gpio1; gpio2 = &gpio2; + serial0 = &uart0; + serial1 = &uart1; }; clocks { diff --git a/arch/arm/boot/dts/armada-38x.dtsi b/arch/arm/boot/dts/armada-38x.dtsi index f74bb01edb1b..1a2dc370792f 100644 --- a/arch/arm/boot/dts/armada-38x.dtsi +++ b/arch/arm/boot/dts/armada-38x.dtsi @@ -59,6 +59,8 @@ aliases { gpio0 = &gpio0; gpio1 = &gpio1; + serial0 = &uart0; + serial1 = &uart1; }; soc { diff --git a/arch/arm/boot/dts/armada-xp.dtsi b/arch/arm/boot/dts/armada-xp.dtsi index 975ae64ead9e..bbabee5dd9b5 100644 --- a/arch/arm/boot/dts/armada-xp.dtsi +++ b/arch/arm/boot/dts/armada-xp.dtsi @@ -57,6 +57,8 @@ compatible = "marvell,armadaxp", "marvell,armada-370-xp"; aliases { + serial2 = &uart2; + serial3 = &uart3; }; soc { -- GitLab From 9552203cb08b9802e17f19bd5c786d6a2281a04a Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Tue, 3 Mar 2015 15:41:02 +0100 Subject: [PATCH 02560/11651] ARM: mvebu: use stdout-path in all armada-*.dts This commit adds the stdout-path property in /chosen for all Armada boards that were not yet carrying this property, and gets rid of /chosen/bootargs which becomes unneeded: earlyprintk should not be used by default, and the console= parameter is replaced by the /chosen/stdout-path property. Signed-off-by: Thomas Petazzoni Signed-off-by: Gregory CLEMENT --- arch/arm/boot/dts/armada-370-db.dts | 2 +- arch/arm/boot/dts/armada-370-mirabox.dts | 2 +- arch/arm/boot/dts/armada-370-netgear-rn102.dts | 2 +- arch/arm/boot/dts/armada-370-netgear-rn104.dts | 2 +- arch/arm/boot/dts/armada-370-rd.dts | 2 +- arch/arm/boot/dts/armada-370-synology-ds213j.dts | 3 +-- arch/arm/boot/dts/armada-375-db.dts | 2 +- arch/arm/boot/dts/armada-385-db-ap.dts | 3 +-- arch/arm/boot/dts/armada-388-db.dts | 2 +- arch/arm/boot/dts/armada-388-gp.dts | 3 +-- arch/arm/boot/dts/armada-388-rd.dts | 2 +- arch/arm/boot/dts/armada-xp-axpwifiap.dts | 2 +- arch/arm/boot/dts/armada-xp-db.dts | 2 +- arch/arm/boot/dts/armada-xp-gp.dts | 2 +- arch/arm/boot/dts/armada-xp-lenovo-ix4-300d.dts | 3 +-- arch/arm/boot/dts/armada-xp-matrix.dts | 2 +- arch/arm/boot/dts/armada-xp-netgear-rn2120.dts | 2 +- arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts | 2 +- arch/arm/boot/dts/armada-xp-synology-ds414.dts | 3 +-- 19 files changed, 19 insertions(+), 24 deletions(-) diff --git a/arch/arm/boot/dts/armada-370-db.dts b/arch/arm/boot/dts/armada-370-db.dts index e993c46bd472..485ecf856fae 100644 --- a/arch/arm/boot/dts/armada-370-db.dts +++ b/arch/arm/boot/dts/armada-370-db.dts @@ -55,7 +55,7 @@ compatible = "marvell,a370-db", "marvell,armada370", "marvell,armada-370-xp"; chosen { - bootargs = "console=ttyS0,115200 earlyprintk"; + stdout-path = "serial0:115200n8"; }; memory { diff --git a/arch/arm/boot/dts/armada-370-mirabox.dts b/arch/arm/boot/dts/armada-370-mirabox.dts index b10ceb488efe..0f40d5da28c3 100644 --- a/arch/arm/boot/dts/armada-370-mirabox.dts +++ b/arch/arm/boot/dts/armada-370-mirabox.dts @@ -51,7 +51,7 @@ compatible = "globalscale,mirabox", "marvell,armada370", "marvell,armada-370-xp"; chosen { - bootargs = "console=ttyS0,115200 earlyprintk"; + stdout-path = "serial0:115200n8"; }; memory { diff --git a/arch/arm/boot/dts/armada-370-netgear-rn102.dts b/arch/arm/boot/dts/armada-370-netgear-rn102.dts index 3f8cc3845a5e..a31207860f34 100644 --- a/arch/arm/boot/dts/armada-370-netgear-rn102.dts +++ b/arch/arm/boot/dts/armada-370-netgear-rn102.dts @@ -53,7 +53,7 @@ compatible = "netgear,readynas-102", "marvell,armada370", "marvell,armada-370-xp"; chosen { - bootargs = "console=ttyS0,115200 earlyprintk"; + stdout-path = "serial0:115200n8"; }; memory { diff --git a/arch/arm/boot/dts/armada-370-netgear-rn104.dts b/arch/arm/boot/dts/armada-370-netgear-rn104.dts index 99eb8a014ac6..00540f292979 100644 --- a/arch/arm/boot/dts/armada-370-netgear-rn104.dts +++ b/arch/arm/boot/dts/armada-370-netgear-rn104.dts @@ -53,7 +53,7 @@ compatible = "netgear,readynas-104", "marvell,armada370", "marvell,armada-370-xp"; chosen { - bootargs = "console=ttyS0,115200 earlyprintk"; + stdout-path = "serial0:115200n8"; }; memory { diff --git a/arch/arm/boot/dts/armada-370-rd.dts b/arch/arm/boot/dts/armada-370-rd.dts index 6ae36a38beb2..19475e68b8e9 100644 --- a/arch/arm/boot/dts/armada-370-rd.dts +++ b/arch/arm/boot/dts/armada-370-rd.dts @@ -64,7 +64,7 @@ compatible = "marvell,a370-rd", "marvell,armada370", "marvell,armada-370-xp"; chosen { - bootargs = "console=ttyS0,115200 earlyprintk"; + stdout-path = "serial0:115200n8"; }; memory { diff --git a/arch/arm/boot/dts/armada-370-synology-ds213j.dts b/arch/arm/boot/dts/armada-370-synology-ds213j.dts index 59f74e66963f..b42b767763aa 100644 --- a/arch/arm/boot/dts/armada-370-synology-ds213j.dts +++ b/arch/arm/boot/dts/armada-370-synology-ds213j.dts @@ -67,8 +67,7 @@ "marvell,armada-370-xp"; chosen { - bootargs = "console=ttyS0,115200 earlyprintk"; - stdout-path = &uart0; + stdout-path = "serial0:115200n8"; }; memory { diff --git a/arch/arm/boot/dts/armada-375-db.dts b/arch/arm/boot/dts/armada-375-db.dts index 0440891425c0..4eabc9c21f8d 100644 --- a/arch/arm/boot/dts/armada-375-db.dts +++ b/arch/arm/boot/dts/armada-375-db.dts @@ -55,7 +55,7 @@ compatible = "marvell,a375-db", "marvell,armada375"; chosen { - bootargs = "console=ttyS0,115200 earlyprintk"; + stdout-path = "serial0:115200n8"; }; memory { diff --git a/arch/arm/boot/dts/armada-385-db-ap.dts b/arch/arm/boot/dts/armada-385-db-ap.dts index 9e33f7d7276b..d6b0f7db9624 100644 --- a/arch/arm/boot/dts/armada-385-db-ap.dts +++ b/arch/arm/boot/dts/armada-385-db-ap.dts @@ -49,8 +49,7 @@ compatible = "marvell,a385-db-ap", "marvell,armada385", "marvell,armada38x"; chosen { - bootargs = "console=ttyS0,115200"; - stdout-path = &uart1; + stdout-path = "serial1:115200n8"; }; memory { diff --git a/arch/arm/boot/dts/armada-388-db.dts b/arch/arm/boot/dts/armada-388-db.dts index af6c74e5e7d6..51d1623de53e 100644 --- a/arch/arm/boot/dts/armada-388-db.dts +++ b/arch/arm/boot/dts/armada-388-db.dts @@ -54,7 +54,7 @@ "marvell,armada385", "marvell,armada380"; chosen { - bootargs = "console=ttyS0,115200 earlyprintk"; + stdout-path = "serial0:115200n8"; }; memory { diff --git a/arch/arm/boot/dts/armada-388-gp.dts b/arch/arm/boot/dts/armada-388-gp.dts index 3ff05739ac48..78514ab0b47a 100644 --- a/arch/arm/boot/dts/armada-388-gp.dts +++ b/arch/arm/boot/dts/armada-388-gp.dts @@ -48,8 +48,7 @@ compatible = "marvell,a385-gp", "marvell,armada388", "marvell,armada380"; chosen { - bootargs = "console=ttyS0,115200"; - stdout-path = &uart0; + stdout-path = "serial0:115200n8"; }; memory { diff --git a/arch/arm/boot/dts/armada-388-rd.dts b/arch/arm/boot/dts/armada-388-rd.dts index 1ecf511288c9..1dc6e2341cc2 100644 --- a/arch/arm/boot/dts/armada-388-rd.dts +++ b/arch/arm/boot/dts/armada-388-rd.dts @@ -55,7 +55,7 @@ "marvell,armada385","marvell,armada380"; chosen { - bootargs = "console=ttyS0,115200 earlyprintk"; + stdout-path = "serial0:115200n8"; }; memory { diff --git a/arch/arm/boot/dts/armada-xp-axpwifiap.dts b/arch/arm/boot/dts/armada-xp-axpwifiap.dts index c1fbab243609..dfd782b44e50 100644 --- a/arch/arm/boot/dts/armada-xp-axpwifiap.dts +++ b/arch/arm/boot/dts/armada-xp-axpwifiap.dts @@ -59,7 +59,7 @@ compatible = "marvell,rd-axpwifiap", "marvell,armadaxp-mv78230", "marvell,armadaxp", "marvell,armada-370-xp"; chosen { - bootargs = "console=ttyS0,115200 earlyprintk"; + stdout-path = "serial0:115200n8"; }; memory { diff --git a/arch/arm/boot/dts/armada-xp-db.dts b/arch/arm/boot/dts/armada-xp-db.dts index 48bdafe17526..103782407618 100644 --- a/arch/arm/boot/dts/armada-xp-db.dts +++ b/arch/arm/boot/dts/armada-xp-db.dts @@ -64,7 +64,7 @@ compatible = "marvell,axp-db", "marvell,armadaxp-mv78460", "marvell,armadaxp", "marvell,armada-370-xp"; chosen { - bootargs = "console=ttyS0,115200 earlyprintk"; + stdout-path = "serial0:115200n8"; }; memory { diff --git a/arch/arm/boot/dts/armada-xp-gp.dts b/arch/arm/boot/dts/armada-xp-gp.dts index 206aebba01be..565227eacf06 100644 --- a/arch/arm/boot/dts/armada-xp-gp.dts +++ b/arch/arm/boot/dts/armada-xp-gp.dts @@ -65,7 +65,7 @@ compatible = "marvell,axp-gp", "marvell,armadaxp-mv78460", "marvell,armadaxp", "marvell,armada-370-xp"; chosen { - bootargs = "console=ttyS0,115200 earlyprintk"; + stdout-path = "serial0:115200n8"; }; memory { diff --git a/arch/arm/boot/dts/armada-xp-lenovo-ix4-300d.dts b/arch/arm/boot/dts/armada-xp-lenovo-ix4-300d.dts index 5fb3c8b687cf..06a6a6c1fdf7 100644 --- a/arch/arm/boot/dts/armada-xp-lenovo-ix4-300d.dts +++ b/arch/arm/boot/dts/armada-xp-lenovo-ix4-300d.dts @@ -54,8 +54,7 @@ "marvell,armadaxp", "marvell,armada-370-xp"; chosen { - bootargs = "console=ttyS0,115200 earlyprintk"; - stdout-path = &uart0; + stdout-path = "serial0:115200n8"; }; memory { diff --git a/arch/arm/boot/dts/armada-xp-matrix.dts b/arch/arm/boot/dts/armada-xp-matrix.dts index 56f958eb1ede..f894bc83e957 100644 --- a/arch/arm/boot/dts/armada-xp-matrix.dts +++ b/arch/arm/boot/dts/armada-xp-matrix.dts @@ -52,7 +52,7 @@ compatible = "marvell,axp-matrix", "marvell,armadaxp-mv78460", "marvell,armadaxp", "marvell,armada-370-xp"; chosen { - bootargs = "console=ttyS0,115200 earlyprintk"; + stdout-path = "serial0:115200n8"; }; memory { diff --git a/arch/arm/boot/dts/armada-xp-netgear-rn2120.dts b/arch/arm/boot/dts/armada-xp-netgear-rn2120.dts index 99cb9a8401b4..1516fc2627f9 100644 --- a/arch/arm/boot/dts/armada-xp-netgear-rn2120.dts +++ b/arch/arm/boot/dts/armada-xp-netgear-rn2120.dts @@ -53,7 +53,7 @@ compatible = "netgear,readynas-2120", "marvell,armadaxp-mv78230", "marvell,armadaxp", "marvell,armada-370-xp"; chosen { - bootargs = "console=ttyS0,115200 earlyprintk"; + stdout-path = "serial0:115200n8"; }; memory { diff --git a/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts b/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts index 0c76d9f05fd0..e3b08fb959e5 100644 --- a/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts +++ b/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts @@ -54,7 +54,7 @@ compatible = "plathome,openblocks-ax3-4", "marvell,armadaxp-mv78260", "marvell,armadaxp", "marvell,armada-370-xp"; chosen { - bootargs = "console=ttyS0,115200 earlyprintk"; + stdout-path = "serial0:115200n8"; }; memory { diff --git a/arch/arm/boot/dts/armada-xp-synology-ds414.dts b/arch/arm/boot/dts/armada-xp-synology-ds414.dts index e9fb225169aa..6063428fa6a0 100644 --- a/arch/arm/boot/dts/armada-xp-synology-ds414.dts +++ b/arch/arm/boot/dts/armada-xp-synology-ds414.dts @@ -67,8 +67,7 @@ "marvell,armadaxp", "marvell,armada-370-xp"; chosen { - bootargs = "console=ttyS0,115200 earlyprintk"; - stdout-path = &uart0; + stdout-path = "serial0:115200n8"; }; memory { -- GitLab From 24c2573bdb9203259a822a4e3ed90795b273d3ab Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Tue, 3 Mar 2015 15:41:03 +0100 Subject: [PATCH 02561/11651] ARM: mvebu: fix unit address of MPIC nodes The Device Tree nodes describing the MPIC nodes on Armada 370, 375, 38x and XP had a unit address that did not match the first reg property, as suggested by the ePAPR. This commit fixes that. [gregory.clement@free-electrons.com: removed the armada-38x part, as it was already applied by a previous patch] Signed-off-by: Thomas Petazzoni Signed-off-by: Gregory CLEMENT --- arch/arm/boot/dts/armada-370-xp.dtsi | 2 +- arch/arm/boot/dts/armada-370.dtsi | 2 +- arch/arm/boot/dts/armada-375.dtsi | 2 +- arch/arm/boot/dts/armada-xp.dtsi | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/boot/dts/armada-370-xp.dtsi b/arch/arm/boot/dts/armada-370-xp.dtsi index 1058cf6898fd..7b3393e264f8 100644 --- a/arch/arm/boot/dts/armada-370-xp.dtsi +++ b/arch/arm/boot/dts/armada-370-xp.dtsi @@ -223,7 +223,7 @@ <0x20250 0x8>; }; - mpic: interrupt-controller@20000 { + mpic: interrupt-controller@20a00 { compatible = "marvell,mpic"; #interrupt-cells = <1>; #size-cells = <1>; diff --git a/arch/arm/boot/dts/armada-370.dtsi b/arch/arm/boot/dts/armada-370.dtsi index 27397f151def..50f259b20f94 100644 --- a/arch/arm/boot/dts/armada-370.dtsi +++ b/arch/arm/boot/dts/armada-370.dtsi @@ -232,7 +232,7 @@ reg = <0x18330 0x4>; }; - interrupt-controller@20000 { + interrupt-controller@20a00 { reg = <0x20a00 0x1d0>, <0x21870 0x58>; }; diff --git a/arch/arm/boot/dts/armada-375.dtsi b/arch/arm/boot/dts/armada-375.dtsi index 64206939bde5..c6fedf2bfe3d 100644 --- a/arch/arm/boot/dts/armada-375.dtsi +++ b/arch/arm/boot/dts/armada-375.dtsi @@ -394,7 +394,7 @@ reg = <0x20000 0x100>, <0x20180 0x20>; }; - mpic: interrupt-controller@20000 { + mpic: interrupt-controller@20a00 { compatible = "marvell,mpic"; reg = <0x20a00 0x2d0>, <0x21070 0x58>; #interrupt-cells = <1>; diff --git a/arch/arm/boot/dts/armada-xp.dtsi b/arch/arm/boot/dts/armada-xp.dtsi index bbabee5dd9b5..ff47345e19ed 100644 --- a/arch/arm/boot/dts/armada-xp.dtsi +++ b/arch/arm/boot/dts/armada-xp.dtsi @@ -154,7 +154,7 @@ clocks = <&coreclk 1>; }; - interrupt-controller@20000 { + interrupt-controller@20a00 { reg = <0x20a00 0x2d0>, <0x21070 0x58>; }; -- GitLab From 6e17cb12881ba8d5e456b89f072dc6b70048af36 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 1 Mar 2015 10:41:37 +0000 Subject: [PATCH 02562/11651] ACPI / video: Load the module even if ACPI is disabled i915.ko depends upon the acpi/video.ko module and so refuses to load if ACPI is disabled at runtime if for example the BIOS is broken beyond repair. acpi/video provides an optional service for i915.ko and so we should just allow the modules to load, but do no nothing in order to let the machines boot correctly. Reported-by: Bill Augur Signed-off-by: Chris Wilson Cc: Daniel Vetter Cc: Jani Nikula Cc: All applicable Acked-by: Aaron Lu [ rjw: Fixed up the new comment in acpi_video_init() ] Signed-off-by: Rafael J. Wysocki --- drivers/acpi/video.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index debd30917010..5f98ac69729a 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -2176,6 +2176,17 @@ EXPORT_SYMBOL(acpi_video_unregister_backlight); static int __init acpi_video_init(void) { + /* + * Let the module load even if ACPI is disabled (e.g. due to + * a broken BIOS) so that i915.ko can still be loaded on such + * old systems without an AcpiOpRegion. + * + * acpi_video_register() will report -ENODEV later as well due + * to acpi_disabled when i915.ko tries to register itself afterwards. + */ + if (acpi_disabled) + return 0; + dmi_check_system(video_dmi_table); if (intel_opregion_present()) -- GitLab From 28d634038d8fed8d25b92f21b728318a79c0be00 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 1 Mar 2015 10:41:38 +0000 Subject: [PATCH 02563/11651] ACPI / video: Propagate the error code for acpi_video_register Report the actual error code from acpi_bus_register_driver(), it may help future debugging (typically ENODEV as previously reported, but the unusual cases are where it may help most). Signed-off-by: Chris Wilson Acked-by: Aaron Lu Signed-off-by: Rafael J. Wysocki --- drivers/acpi/video.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 5f98ac69729a..26eb70c8f518 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -2110,7 +2110,8 @@ static int __init intel_opregion_present(void) int acpi_video_register(void) { - int result = 0; + int ret; + if (register_count) { /* * if the function of acpi_video_register is already called, @@ -2122,9 +2123,9 @@ int acpi_video_register(void) mutex_init(&video_list_lock); INIT_LIST_HEAD(&video_bus_head); - result = acpi_bus_register_driver(&acpi_video_bus); - if (result < 0) - return -ENODEV; + ret = acpi_bus_register_driver(&acpi_video_bus); + if (ret) + return ret; /* * When the acpi_video_bus is loaded successfully, increase -- GitLab From 074fa7e76cfff4cd1a60753ee4596510f1b87183 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Wed, 4 Mar 2015 15:10:55 +0100 Subject: [PATCH 02564/11651] microblaze: Coding style cleanup No function change. Signed-off-by: Michal Simek --- arch/microblaze/kernel/entry.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/microblaze/kernel/entry.S b/arch/microblaze/kernel/entry.S index 0536bc021cc6..5dcb0e1a41c4 100644 --- a/arch/microblaze/kernel/entry.S +++ b/arch/microblaze/kernel/entry.S @@ -349,7 +349,7 @@ C_ENTRY(_user_exception): * should return. [note that MAKE_SYS_CALL uses label 1] */ /* See if the system call number is valid */ addi r11, r12, -__NR_syscalls; - bgei r11,5f; + bgei r11, 5f; /* Figure out which function to use for this system call. */ /* Note Microblaze barrel shift is optional, so don't rely on it */ add r12, r12, r12; /* convert num -> ptr */ @@ -411,7 +411,7 @@ C_ENTRY(ret_from_trap): bri 1b /* Maybe handle a signal */ -5: +5: andi r11, r19, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME; beqi r11, 4f; /* Signals to handle, handle them */ -- GitLab From c2219eda547813c0c50dba90d9e989ae36cc3ab8 Mon Sep 17 00:00:00 2001 From: Jamie Garside Date: Mon, 23 Feb 2015 15:35:35 +0000 Subject: [PATCH 02565/11651] microblaze: Fix syscall error recovery for invalid syscall IDs This patch fixes two bugs in the Microblaze syscall trap handler when an invalid syscall ID is used. First, the range check on line 351 only checks for syscall IDs greater than __NR_syscalls. A negative syscall ID (either passed to `syscall()` or as returned by `do_syscall_trace_enter()` on error) will still satisfy this test and cause the Linux kernel to access an invalid memory location and cause a kernel oops. This has been fixed by also checking for r12 < 0. Secondly, the current error recovery at line 378 returns using the wrong register (r15 instead of r14) and does not restore the previous stack state. This has been fixed by invoking `ret_from_trap` on error, setting r3 to `-ENOSYS`, similar to what would happen when calling a valid syscall. Signed-off-by: Jamie Garside Signed-off-by: Michal Simek --- arch/microblaze/kernel/entry.S | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/microblaze/kernel/entry.S b/arch/microblaze/kernel/entry.S index 5dcb0e1a41c4..ef548510b951 100644 --- a/arch/microblaze/kernel/entry.S +++ b/arch/microblaze/kernel/entry.S @@ -348,6 +348,7 @@ C_ENTRY(_user_exception): * The LP register should point to the location where the called function * should return. [note that MAKE_SYS_CALL uses label 1] */ /* See if the system call number is valid */ + blti r12, 5f addi r11, r12, -__NR_syscalls; bgei r11, 5f; /* Figure out which function to use for this system call. */ @@ -375,7 +376,7 @@ C_ENTRY(_user_exception): /* The syscall number is invalid, return an error. */ 5: - rtsd r15, 8; /* looks like a normal subroutine return */ + braid ret_from_trap addi r3, r0, -ENOSYS; /* Entry point used to return from a syscall/trap */ -- GitLab From 9baf96886780c3ec137350da3c6418c825b2dd0a Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Tue, 3 Mar 2015 15:41:05 +0100 Subject: [PATCH 02566/11651] devicetree: bindings: update DT bindings for Marvell EBU clock support With the introduction of the Marvell Armada 39x SoC, the DT bindings for Marvell EBU clocks need to be extended. This commit include the corresponding update to the Device Tree bindings documentation. Signed-off-by: Thomas Petazzoni Signed-off-by: Gregory CLEMENT --- .../bindings/clock/mvebu-core-clock.txt | 9 +++++++++ .../bindings/clock/mvebu-gated-clock.txt | 15 ++++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/clock/mvebu-core-clock.txt b/Documentation/devicetree/bindings/clock/mvebu-core-clock.txt index dc5ea5b22da9..670c2af3e931 100644 --- a/Documentation/devicetree/bindings/clock/mvebu-core-clock.txt +++ b/Documentation/devicetree/bindings/clock/mvebu-core-clock.txt @@ -23,6 +23,14 @@ The following is a list of provided IDs and clock names on Armada 380/385: 2 = l2clk (L2 Cache clock) 3 = ddrclk (DDR clock) +The following is a list of provided IDs and clock names on Armada 39x: + 0 = tclk (Internal Bus clock) + 1 = cpuclk (CPU clock) + 2 = nbclk (Coherent Fabric clock) + 3 = hclk (SDRAM Controller Internal Clock) + 4 = dclk (SDRAM Interface Clock) + 5 = refclk (Reference Clock) + The following is a list of provided IDs and clock names on Kirkwood and Dove: 0 = tclk (Internal Bus clock) 1 = cpuclk (CPU0 clock) @@ -39,6 +47,7 @@ Required properties: "marvell,armada-370-core-clock" - For Armada 370 SoC core clocks "marvell,armada-375-core-clock" - For Armada 375 SoC core clocks "marvell,armada-380-core-clock" - For Armada 380/385 SoC core clocks + "marvell,armada-390-core-clock" - For Armada 39x SoC core clocks "marvell,armada-xp-core-clock" - For Armada XP SoC core clocks "marvell,dove-core-clock" - for Dove SoC core clocks "marvell,kirkwood-core-clock" - for Kirkwood SoC (except mv88f6180) diff --git a/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt b/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt index 76477be742b2..31c7c0c1ce8f 100644 --- a/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt +++ b/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt @@ -1,6 +1,6 @@ * Gated Clock bindings for Marvell EBU SoCs -Marvell Armada 370/375/380/385/XP, Dove and Kirkwood allow some +Marvell Armada 370/375/380/385/39x/XP, Dove and Kirkwood allow some peripheral clocks to be gated to save some power. The clock consumer should specify the desired clock by having the clock ID in its "clocks" phandle cell. The clock ID is directly mapped to the @@ -77,6 +77,18 @@ ID Clock Peripheral 28 xor1 XOR 1 30 sata1 SATA 1 +The following is a list of provided IDs for Armada 39x: +ID Clock Peripheral +----------------------------------- +5 pex1 PCIe 1 +6 pex2 PCIe 2 +7 pex3 PCIe 3 +8 pex0 PCIe 0 +9 usb3h0 USB3 Host 0 +17 sdio SDIO +22 xor0 XOR 0 +28 xor1 XOR 1 + The following is a list of provided IDs for Armada XP: ID Clock Peripheral ----------------------------------- @@ -152,6 +164,7 @@ Required properties: "marvell,armada-370-gating-clock" - for Armada 370 SoC clock gating "marvell,armada-375-gating-clock" - for Armada 375 SoC clock gating "marvell,armada-380-gating-clock" - for Armada 380/385 SoC clock gating + "marvell,armada-390-gating-clock" - for Armada 39x SoC clock gating "marvell,armada-xp-gating-clock" - for Armada XP SoC clock gating "marvell,dove-gating-clock" - for Dove SoC clock gating "marvell,kirkwood-gating-clock" - for Kirkwood SoC clock gating -- GitLab From 42b5f40610fd222a9e7100f5b77582940bfdcbde Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Tue, 3 Mar 2015 15:41:08 +0100 Subject: [PATCH 02567/11651] clk: mvebu: extend common code to allow an optional refclk The Armada 39x, contrary to its predecessor, has a configurable reference clock frequency, of either 25 Mhz, or 40 Mhz. For the previous SoCs, it was fixed to 25 Mhz and described directly as such in the Device Tree. For Armada 39x, we need to read certain registers to know whether the frequency is 25 or 40 Mhz. Therefore, this commit extends the common mvebu clock code to allow the SoC-specific code to say it wants to register a reference clock, by giving a non-NULL ->get_refclk_freq() function pointer in its coreclk_soc_desc structure. Signed-off-by: Thomas Petazzoni Signed-off-by: Gregory CLEMENT --- drivers/clk/mvebu/common.c | 17 +++++++++++++++++ drivers/clk/mvebu/common.h | 1 + 2 files changed, 18 insertions(+) diff --git a/drivers/clk/mvebu/common.c b/drivers/clk/mvebu/common.c index 0d4d1216f2dd..15b370ff3748 100644 --- a/drivers/clk/mvebu/common.c +++ b/drivers/clk/mvebu/common.c @@ -121,6 +121,11 @@ void __init mvebu_coreclk_setup(struct device_node *np, /* Allocate struct for TCLK, cpu clk, and core ratio clocks */ clk_data.clk_num = 2 + desc->num_ratios; + + /* One more clock for the optional refclk */ + if (desc->get_refclk_freq) + clk_data.clk_num += 1; + clk_data.clks = kzalloc(clk_data.clk_num * sizeof(struct clk *), GFP_KERNEL); if (WARN_ON(!clk_data.clks)) { @@ -162,6 +167,18 @@ void __init mvebu_coreclk_setup(struct device_node *np, WARN_ON(IS_ERR(clk_data.clks[2+n])); }; + /* Register optional refclk */ + if (desc->get_refclk_freq) { + const char *name = "refclk"; + of_property_read_string_index(np, "clock-output-names", + 2 + desc->num_ratios, &name); + rate = desc->get_refclk_freq(base); + clk_data.clks[2 + desc->num_ratios] = + clk_register_fixed_rate(NULL, name, NULL, + CLK_IS_ROOT, rate); + WARN_ON(IS_ERR(clk_data.clks[2 + desc->num_ratios])); + } + /* SAR register isn't needed anymore */ iounmap(base); diff --git a/drivers/clk/mvebu/common.h b/drivers/clk/mvebu/common.h index 783b5631a453..f0de6c8a494a 100644 --- a/drivers/clk/mvebu/common.h +++ b/drivers/clk/mvebu/common.h @@ -30,6 +30,7 @@ struct coreclk_soc_desc { u32 (*get_tclk_freq)(void __iomem *sar); u32 (*get_cpu_freq)(void __iomem *sar); void (*get_clk_ratio)(void __iomem *sar, int id, int *mult, int *div); + u32 (*get_refclk_freq)(void __iomem *sar); bool (*is_sscg_enabled)(void __iomem *sar); u32 (*fix_sscg_deviation)(u32 system_clk); const struct coreclk_ratio *ratios; -- GitLab From 8da6f3c1662a74a39b5ebc773ee27a949b5d7658 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Tue, 3 Mar 2015 15:41:09 +0100 Subject: [PATCH 02568/11651] clk: mvebu: add Marvell Armada 39x driver This commit adds a new clock driver for the Marvell Armada 39x family of processors. This driver is fairly similar to the ones already used on other Marvell EBU processors, with the following main differences: * Different set of ratios * Different set of core clocks * Configurable reference clock in frequency Signed-off-by: Thomas Petazzoni Signed-off-by: Gregory CLEMENT --- drivers/clk/mvebu/Kconfig | 4 + drivers/clk/mvebu/Makefile | 1 + drivers/clk/mvebu/armada-39x.c | 156 +++++++++++++++++++++++++++++++++ 3 files changed, 161 insertions(+) create mode 100644 drivers/clk/mvebu/armada-39x.c diff --git a/drivers/clk/mvebu/Kconfig b/drivers/clk/mvebu/Kconfig index 3b34dba9178d..27696255486d 100644 --- a/drivers/clk/mvebu/Kconfig +++ b/drivers/clk/mvebu/Kconfig @@ -21,6 +21,10 @@ config ARMADA_38X_CLK bool select MVEBU_CLK_COMMON +config ARMADA_39X_CLK + bool + select MVEBU_CLK_COMMON + config ARMADA_XP_CLK bool select MVEBU_CLK_COMMON diff --git a/drivers/clk/mvebu/Makefile b/drivers/clk/mvebu/Makefile index a9a56fc01901..645ac7ea3565 100644 --- a/drivers/clk/mvebu/Makefile +++ b/drivers/clk/mvebu/Makefile @@ -5,6 +5,7 @@ obj-$(CONFIG_MVEBU_CLK_COREDIV) += clk-corediv.o obj-$(CONFIG_ARMADA_370_CLK) += armada-370.o obj-$(CONFIG_ARMADA_375_CLK) += armada-375.o obj-$(CONFIG_ARMADA_38X_CLK) += armada-38x.o +obj-$(CONFIG_ARMADA_39X_CLK) += armada-39x.o obj-$(CONFIG_ARMADA_XP_CLK) += armada-xp.o obj-$(CONFIG_DOVE_CLK) += dove.o obj-$(CONFIG_KIRKWOOD_CLK) += kirkwood.o diff --git a/drivers/clk/mvebu/armada-39x.c b/drivers/clk/mvebu/armada-39x.c new file mode 100644 index 000000000000..efb974df9822 --- /dev/null +++ b/drivers/clk/mvebu/armada-39x.c @@ -0,0 +1,156 @@ +/* + * Marvell Armada 39x SoC clocks + * + * Copyright (C) 2015 Marvell + * + * Gregory CLEMENT + * Sebastian Hesselbarth + * Andrew Lunn + * Thomas Petazzoni + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include "common.h" + +/* + * SARL[14:10] : Ratios between CPU, NBCLK, HCLK and DCLK. + * + * SARL[15] : TCLK frequency + * 0 = 250 MHz + * 1 = 200 MHz + * + * SARH[0] : Reference clock frequency + * 0 = 25 Mhz + * 1 = 40 Mhz + */ + +#define SARL 0 +#define SARL_A390_TCLK_FREQ_OPT 15 +#define SARL_A390_TCLK_FREQ_OPT_MASK 0x1 +#define SARL_A390_CPU_DDR_L2_FREQ_OPT 10 +#define SARL_A390_CPU_DDR_L2_FREQ_OPT_MASK 0x1F +#define SARH 4 +#define SARH_A390_REFCLK_FREQ BIT(0) + +static const u32 armada_39x_tclk_frequencies[] __initconst = { + 250000000, + 200000000, +}; + +static u32 __init armada_39x_get_tclk_freq(void __iomem *sar) +{ + u8 tclk_freq_select; + + tclk_freq_select = ((readl(sar + SARL) >> SARL_A390_TCLK_FREQ_OPT) & + SARL_A390_TCLK_FREQ_OPT_MASK); + return armada_39x_tclk_frequencies[tclk_freq_select]; +} + +static const u32 armada_39x_cpu_frequencies[] __initconst = { + [0x0] = 666 * 1000 * 1000, + [0x2] = 800 * 1000 * 1000, + [0x3] = 800 * 1000 * 1000, + [0x4] = 1066 * 1000 * 1000, + [0x5] = 1066 * 1000 * 1000, + [0x6] = 1200 * 1000 * 1000, + [0x8] = 1332 * 1000 * 1000, + [0xB] = 1600 * 1000 * 1000, + [0xC] = 1600 * 1000 * 1000, + [0x12] = 1800 * 1000 * 1000, + [0x1E] = 1800 * 1000 * 1000, +}; + +static u32 __init armada_39x_get_cpu_freq(void __iomem *sar) +{ + u8 cpu_freq_select; + + cpu_freq_select = ((readl(sar + SARL) >> SARL_A390_CPU_DDR_L2_FREQ_OPT) & + SARL_A390_CPU_DDR_L2_FREQ_OPT_MASK); + if (cpu_freq_select >= ARRAY_SIZE(armada_39x_cpu_frequencies)) { + pr_err("Selected CPU frequency (%d) unsupported\n", + cpu_freq_select); + return 0; + } + + return armada_39x_cpu_frequencies[cpu_freq_select]; +} + +enum { A390_CPU_TO_NBCLK, A390_CPU_TO_HCLK, A390_CPU_TO_DCLK }; + +static const struct coreclk_ratio armada_39x_coreclk_ratios[] __initconst = { + { .id = A390_CPU_TO_NBCLK, .name = "nbclk" }, + { .id = A390_CPU_TO_HCLK, .name = "hclk" }, + { .id = A390_CPU_TO_DCLK, .name = "dclk" }, +}; + +static void __init armada_39x_get_clk_ratio( + void __iomem *sar, int id, int *mult, int *div) +{ + switch (id) { + case A390_CPU_TO_NBCLK: + *mult = 1; + *div = 2; + break; + case A390_CPU_TO_HCLK: + *mult = 1; + *div = 4; + break; + case A390_CPU_TO_DCLK: + *mult = 1; + *div = 2; + break; + } +} + +static u32 __init armada_39x_refclk_ratio(void __iomem *sar) +{ + if (readl(sar + SARH) & SARH_A390_REFCLK_FREQ) + return 40 * 1000 * 1000; + else + return 25 * 1000 * 1000; +} + +static const struct coreclk_soc_desc armada_39x_coreclks = { + .get_tclk_freq = armada_39x_get_tclk_freq, + .get_cpu_freq = armada_39x_get_cpu_freq, + .get_clk_ratio = armada_39x_get_clk_ratio, + .get_refclk_freq = armada_39x_refclk_ratio, + .ratios = armada_39x_coreclk_ratios, + .num_ratios = ARRAY_SIZE(armada_39x_coreclk_ratios), +}; + +static void __init armada_39x_coreclk_init(struct device_node *np) +{ + mvebu_coreclk_setup(np, &armada_39x_coreclks); +} +CLK_OF_DECLARE(armada_39x_core_clk, "marvell,armada-390-core-clock", + armada_39x_coreclk_init); + +/* + * Clock Gating Control + */ +static const struct clk_gating_soc_desc armada_39x_gating_desc[] __initconst = { + { "pex1", NULL, 5 }, + { "pex2", NULL, 6 }, + { "pex3", NULL, 7 }, + { "pex0", NULL, 8 }, + { "usb3h0", NULL, 9 }, + { "sdio", NULL, 17 }, + { "xor0", NULL, 22 }, + { "xor1", NULL, 28 }, + { } +}; + +static void __init armada_39x_clk_gating_init(struct device_node *np) +{ + mvebu_clk_gating_setup(np, armada_39x_gating_desc); +} +CLK_OF_DECLARE(armada_39x_clk_gating, "marvell,armada-390-gating-clock", + armada_39x_clk_gating_init); -- GitLab From e9d119a1faa5bb386953283748999dc970bc255d Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Tue, 3 Mar 2015 15:41:04 +0100 Subject: [PATCH 02569/11651] devicetree: bindings: add DT binding for the Marvell Armada 39x SoC family The Marvell Armada 39x is a family of two SoCs: the Armada 390 and the Armada 398, with a slightly different number of interfaces. This commit introduces the Device Tree binding that documents the top-level compatible strings for Armada 39x based platforms. Signed-off-by: Thomas Petazzoni Acked-by: Gregory CLEMENT Signed-off-by: Gregory CLEMENT --- .../devicetree/bindings/arm/armada-39x.txt | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 Documentation/devicetree/bindings/arm/armada-39x.txt diff --git a/Documentation/devicetree/bindings/arm/armada-39x.txt b/Documentation/devicetree/bindings/arm/armada-39x.txt new file mode 100644 index 000000000000..53d4ff9ea8ad --- /dev/null +++ b/Documentation/devicetree/bindings/arm/armada-39x.txt @@ -0,0 +1,20 @@ +Marvell Armada 39x Platforms Device Tree Bindings +------------------------------------------------- + +Boards with a SoC of the Marvell Armada 39x family shall have the +following property: + +Required root node property: + + - compatible: must contain "marvell,armada390" + +In addition, boards using the Marvell Armada 398 SoC shall have the +following property before the previous one: + +Required root node property: + +compatible: must contain "marvell,armada398" + +Example: + +compatible = "marvell,a398-db", "marvell,armada398", "marvell,armada390"; -- GitLab From 007fa9467f8f5607bb36b4a2bf31316a7e5b06ff Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Tue, 3 Mar 2015 15:41:07 +0100 Subject: [PATCH 02570/11651] devicetree: bindings: add new SMP enable method for Marvell Armada 39x This commit updates the ARM CPUs Device Tree binding to document a new enable method of Marvell Armada 39x processors. Signed-off-by: Thomas Petazzoni Signed-off-by: Gregory CLEMENT --- Documentation/devicetree/bindings/arm/cpus.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/arm/cpus.txt b/Documentation/devicetree/bindings/arm/cpus.txt index 8b9e0a95de31..6aa331d11c5e 100644 --- a/Documentation/devicetree/bindings/arm/cpus.txt +++ b/Documentation/devicetree/bindings/arm/cpus.txt @@ -192,6 +192,7 @@ nodes to be present and contain the properties described below. "brcm,brahma-b15" "marvell,armada-375-smp" "marvell,armada-380-smp" + "marvell,armada-390-smp" "marvell,armada-xp-smp" "qcom,gcc-msm8660" "qcom,kpss-acc-v1" -- GitLab From 242ede0bdd2bc6fb2057ddc98cce90043008127f Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Tue, 3 Mar 2015 15:41:11 +0100 Subject: [PATCH 02571/11651] ARM: mvebu: add core support for Armada 39x This commit adds the core support for Armada 39x, which is quite simple: - a new Kconfig option which selects the appropriate clock and pinctrl drivers as well as other common features (GIC, L2 cache, SMP, etc.) - a new DT_MACHINE_START which references the top-level compatible strings supported for the Marvell Armada 39x. - a new SMP enable-method. The mechanism to enable CPUs for Armada 39x appears to be the same as Armada 38x. However, we do not want to use marvell,armada-380-smp in the Device Tree, in the case of the discovery of a subtle difference in the future, which would require changing the Device Tree. And the enable-method isn't a compatible string: you can't specify several values and expect a fallback on the second string if the first one isn't supported. Therefore, we simply declare the SMP enable method "marvell,armada-390-smp" as doing the same thing as the "marvell,armada-380-smp" one. Signed-off-by: Thomas Petazzoni Signed-off-by: Gregory CLEMENT --- arch/arm/mach-mvebu/Kconfig | 14 ++++++++++++++ arch/arm/mach-mvebu/board-v7.c | 14 ++++++++++++++ arch/arm/mach-mvebu/platsmp-a9.c | 2 ++ 3 files changed, 30 insertions(+) diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig index c1e4567a5ab3..97473168d6b6 100644 --- a/arch/arm/mach-mvebu/Kconfig +++ b/arch/arm/mach-mvebu/Kconfig @@ -64,6 +64,20 @@ config MACH_ARMADA_38X Say 'Y' here if you want your kernel to support boards based on the Marvell Armada 380/385 SoC with device tree. +config MACH_ARMADA_39X + bool "Marvell Armada 39x boards" if ARCH_MULTI_V7 + select ARM_GIC + select ARMADA_39X_CLK + select CACHE_L2X0 + select HAVE_ARM_SCU + select HAVE_ARM_TWD if SMP + select HAVE_SMP + select MACH_MVEBU_V7 + select PINCTRL_ARMADA_39X + help + Say 'Y' here if you want your kernel to support boards based + on the Marvell Armada 39x SoC with device tree. + config MACH_ARMADA_XP bool "Marvell Armada XP boards" if ARCH_MULTI_V7 select ARMADA_XP_CLK diff --git a/arch/arm/mach-mvebu/board-v7.c b/arch/arm/mach-mvebu/board-v7.c index 89a139ed7d5b..db8d15f9ad57 100644 --- a/arch/arm/mach-mvebu/board-v7.c +++ b/arch/arm/mach-mvebu/board-v7.c @@ -232,3 +232,17 @@ DT_MACHINE_START(ARMADA_38X_DT, "Marvell Armada 380/385 (Device Tree)") .restart = mvebu_restart, .dt_compat = armada_38x_dt_compat, MACHINE_END + +static const char * const armada_39x_dt_compat[] __initconst = { + "marvell,armada390", + "marvell,armada398", + NULL, +}; + +DT_MACHINE_START(ARMADA_39X_DT, "Marvell Armada 39x (Device Tree)") + .l2c_aux_val = 0, + .l2c_aux_mask = ~0, + .init_irq = mvebu_init_irq, + .restart = mvebu_restart, + .dt_compat = armada_39x_dt_compat, +MACHINE_END diff --git a/arch/arm/mach-mvebu/platsmp-a9.c b/arch/arm/mach-mvebu/platsmp-a9.c index 2ec1a42b4321..df0a9cc5da59 100644 --- a/arch/arm/mach-mvebu/platsmp-a9.c +++ b/arch/arm/mach-mvebu/platsmp-a9.c @@ -110,3 +110,5 @@ CPU_METHOD_OF_DECLARE(mvebu_armada_375_smp, "marvell,armada-375-smp", &mvebu_cortex_a9_smp_ops); CPU_METHOD_OF_DECLARE(mvebu_armada_380_smp, "marvell,armada-380-smp", &armada_38x_smp_ops); +CPU_METHOD_OF_DECLARE(mvebu_armada_390_smp, "marvell,armada-390-smp", + &armada_38x_smp_ops); -- GitLab From 0d9ab18e337609b010800ac493c588b0a24c2dd2 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Tue, 3 Mar 2015 15:41:13 +0100 Subject: [PATCH 02572/11651] Documentation: arm: update supported Marvell EBU processors Now that we support Armada 39x, let's add this family of SoC to the Marvell documentation, and a reference to a link with more details about those processors. Unfortunately, no datasheet is publicly available at this time. Signed-off-by: Thomas Petazzoni Signed-off-by: Gregory CLEMENT --- Documentation/arm/Marvell/README | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Documentation/arm/Marvell/README b/Documentation/arm/Marvell/README index 17453794fca5..18a775d10172 100644 --- a/Documentation/arm/Marvell/README +++ b/Documentation/arm/Marvell/README @@ -96,6 +96,11 @@ EBU Armada family 88F6820 88F6828 + Armada 390/398 Flavors: + 88F6920 + 88F6928 + Product infos: http://www.marvell.com/embedded-processors/armada-39x/ + Armada XP Flavors: MV78230 MV78260 -- GitLab From 538da83ddbeaa422a48e9bd0a12a0bc246c567f4 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Tue, 3 Mar 2015 15:41:12 +0100 Subject: [PATCH 02573/11651] ARM: mvebu: add Device Tree files for Armada 39x SoC and board This commit adds the Device Tree files for the Armada 39x family of processors, as well as one Armada 398 Development Board. Like for other Marvell EBU families, a common armada-39x.dtsi contains the description of the common features of all Armada 39x SoCs, while armada-390.dtsi and armada-398.dtsi respectively describe the specificities of those SoCs. Finally, an armada-398-db.dts file is added to describe the Armada 398 Development Board itself. So far, the following features are supported: * SMP: dual Cortex-A9 * Basic ARM IPs: SCU, timer, GIC, L2 cache * Basic Marvell IPs: pin-muxing, clocks, system controller, MBus controller, MPIC interrupt controller, timer, CPU reset for SMP, PMSU. * I2C * SPI * SDHCI * XOR * NAND * UART * PCIe Additional features will be supported in the future. Signed-off-by: Thomas Petazzoni Signed-off-by: Gregory CLEMENT --- arch/arm/boot/dts/Makefile | 2 + arch/arm/boot/dts/armada-390.dtsi | 57 ++++ arch/arm/boot/dts/armada-398-db.dts | 153 +++++++++ arch/arm/boot/dts/armada-398.dtsi | 60 ++++ arch/arm/boot/dts/armada-39x.dtsi | 508 ++++++++++++++++++++++++++++ 5 files changed, 780 insertions(+) create mode 100644 arch/arm/boot/dts/armada-390.dtsi create mode 100644 arch/arm/boot/dts/armada-398-db.dts create mode 100644 arch/arm/boot/dts/armada-398.dtsi create mode 100644 arch/arm/boot/dts/armada-39x.dtsi diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index 0d9710b3c6bb..b9c3f8c8ca27 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -624,6 +624,8 @@ dtb-$(CONFIG_MACH_ARMADA_38X) += \ armada-388-db.dtb \ armada-388-gp.dtb \ armada-388-rd.dtb +dtb-$(CONFIG_MACH_ARMADA_39X) += \ + armada-398-db.dtb dtb-$(CONFIG_MACH_ARMADA_XP) += \ armada-xp-axpwifiap.dtb \ armada-xp-db.dtb \ diff --git a/arch/arm/boot/dts/armada-390.dtsi b/arch/arm/boot/dts/armada-390.dtsi new file mode 100644 index 000000000000..094e39c66039 --- /dev/null +++ b/arch/arm/boot/dts/armada-390.dtsi @@ -0,0 +1,57 @@ +/* + * Device Tree Include file for Marvell Armada 390 SoC. + * + * Copyright (C) 2015 Marvell + * + * Thomas Petazzoni + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file 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. + * + * Or, alternatively + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "armada-39x.dtsi" + +/ { + soc { + internal-regs { + pinctrl@18000 { + compatible = "marvell,mv88f6920-pinctrl"; + reg = <0x18000 0x20>; + }; + }; +}; diff --git a/arch/arm/boot/dts/armada-398-db.dts b/arch/arm/boot/dts/armada-398-db.dts new file mode 100644 index 000000000000..bbf83756c43c --- /dev/null +++ b/arch/arm/boot/dts/armada-398-db.dts @@ -0,0 +1,153 @@ +/* + * Device Tree Include file for Marvell Armada 398 Development Board + * + * Copyright (C) 2015 Marvell + * + * Thomas Petazzoni + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file 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. + * + * Or, alternatively + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +#include "armada-398.dtsi" + +/ { + model = "Marvell Armada 398 Development Board"; + compatible = "marvell,a398-db", "marvell,armada398", "marvell,armada390"; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + memory { + device_type = "memory"; + reg = <0x00000000 0x80000000>; /* 2 GB */ + }; + + soc { + ranges = ; + + internal-regs { + spi@10680 { + status = "okay"; + pinctrl-0 = <&spi1_pins>; + pinctrl-names = "default"; + + spi-flash@0 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "n25q128a13"; + reg = <0>; + spi-max-frequency = <108000000>; + + partition@0 { + label = "U-Boot"; + reg = <0 0x400000>; + }; + + partition@400000 { + label = "Filesystem"; + reg = <0x400000 0x1000000>; + }; + }; + }; + + i2c@11000 { + pinctrl-0 = <&i2c0_pins>; + pinctrl-names = "default"; + status = "okay"; + clock-frequency = <100000>; + }; + + serial@12000 { + pinctrl-0 = <&uart0_pins>; + pinctrl-names = "default"; + status = "okay"; + }; + + serial@12100 { + pinctrl-0 = <&uart1_pins>; + pinctrl-names = "default"; + status = "okay"; + }; + + flash@d0000 { + status = "okay"; + pinctrl-0 = <&nand_pins>; + pinctrl-names = "default"; + num-cs = <1>; + marvell,nand-keep-config; + marvell,nand-enable-arbiter; + nand-on-flash-bbt; + nand-ecc-strength = <8>; + nand-ecc-step-size = <512>; + + partition@0 { + label = "U-Boot"; + reg = <0 0x800000>; + }; + partition@800000 { + label = "Linux"; + reg = <0x800000 0x800000>; + }; + partition@1000000 { + label = "Filesystem"; + reg = <0x1000000 0x3f000000>; + }; + }; + }; + + pcie-controller { + status = "okay"; + + pcie@1,0 { + status = "okay"; + }; + + pcie@2,0 { + status = "okay"; + }; + + pcie@3,0 { + status = "okay"; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/armada-398.dtsi b/arch/arm/boot/dts/armada-398.dtsi new file mode 100644 index 000000000000..fdc25914e3a3 --- /dev/null +++ b/arch/arm/boot/dts/armada-398.dtsi @@ -0,0 +1,60 @@ +/* + * Device Tree Include file for Marvell Armada 398 SoC. + * + * Copyright (C) 2015 Marvell + * + * Thomas Petazzoni + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file 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. + * + * Or, alternatively + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "armada-39x.dtsi" + +/ { + compatible = "marvell,armada398", "marvell,armada390"; + + soc { + internal-regs { + pinctrl@18000 { + compatible = "marvell,mv88f6928-pinctrl"; + reg = <0x18000 0x20>; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/armada-39x.dtsi b/arch/arm/boot/dts/armada-39x.dtsi new file mode 100644 index 000000000000..0e85fc15ceda --- /dev/null +++ b/arch/arm/boot/dts/armada-39x.dtsi @@ -0,0 +1,508 @@ +/* + * Device Tree Include file for Marvell Armada 39x family of SoCs. + * + * Copyright (C) 2015 Marvell + * + * Thomas Petazzoni + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file 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. + * + * Or, alternatively + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "skeleton.dtsi" +#include +#include + +#define MBUS_ID(target,attributes) (((target) << 24) | ((attributes) << 16)) + +/ { + model = "Marvell Armada 39x family SoC"; + compatible = "marvell,armada390"; + + aliases { + serial0 = &uart0; + serial1 = &uart1; + serial2 = &uart2; + serial3 = &uart3; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + enable-method = "marvell,armada-390-smp"; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a9"; + reg = <0>; + }; + cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a9"; + reg = <1>; + }; + }; + + soc { + compatible = "marvell,armada390-mbus", "marvell,armadaxp-mbus", + "simple-bus"; + #address-cells = <2>; + #size-cells = <1>; + controller = <&mbusc>; + interrupt-parent = <&gic>; + pcie-mem-aperture = <0xe0000000 0x8000000>; + pcie-io-aperture = <0xe8000000 0x100000>; + + bootrom { + compatible = "marvell,bootrom"; + reg = ; + }; + + internal-regs { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 MBUS_ID(0xf0, 0x01) 0 0x100000>; + + L2: cache-controller@8000 { + compatible = "arm,pl310-cache"; + reg = <0x8000 0x1000>; + cache-unified; + cache-level = <2>; + }; + + scu@c000 { + compatible = "arm,cortex-a9-scu"; + reg = <0xc000 0x100>; + }; + + timer@c600 { + compatible = "arm,cortex-a9-twd-timer"; + reg = <0xc600 0x20>; + interrupts = ; + clocks = <&coreclk 2>; + }; + + gic: interrupt-controller@d000 { + compatible = "arm,cortex-a9-gic"; + #interrupt-cells = <3>; + #size-cells = <0>; + interrupt-controller; + reg = <0xd000 0x1000>, + <0xc100 0x100>; + }; + + spi0: spi@10600 { + compatible = "marvell,orion-spi"; + reg = <0x10600 0x50>; + #address-cells = <1>; + #size-cells = <0>; + cell-index = <0>; + interrupts = ; + clocks = <&coreclk 0>; + status = "disabled"; + }; + + spi1: spi@10680 { + compatible = "marvell,orion-spi"; + reg = <0x10680 0x50>; + #address-cells = <1>; + #size-cells = <0>; + cell-index = <1>; + interrupts = ; + clocks = <&coreclk 0>; + status = "disabled"; + }; + + i2c0: i2c@11000 { + compatible = "marvell,mv64xxx-i2c"; + reg = <0x11000 0x20>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = ; + timeout-ms = <1000>; + clocks = <&coreclk 0>; + status = "disabled"; + }; + + i2c1: i2c@11100 { + compatible = "marvell,mv64xxx-i2c"; + reg = <0x11100 0x20>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = ; + timeout-ms = <1000>; + clocks = <&coreclk 0>; + status = "disabled"; + }; + + i2c2: i2c@11200 { + compatible = "marvell,mv64xxx-i2c"; + reg = <0x11200 0x20>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = ; + timeout-ms = <1000>; + clocks = <&coreclk 0>; + status = "disabled"; + }; + + i2c3: i2c@11300 { + compatible = "marvell,mv64xxx-i2c"; + reg = <0x11300 0x20>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = ; + timeout-ms = <1000>; + clocks = <&coreclk 0>; + status = "disabled"; + }; + + uart0: serial@12000 { + compatible = "snps,dw-apb-uart"; + reg = <0x12000 0x100>; + reg-shift = <2>; + interrupts = ; + reg-io-width = <1>; + clocks = <&coreclk 0>; + status = "disabled"; + }; + + uart1: serial@12100 { + compatible = "snps,dw-apb-uart"; + reg = <0x12100 0x100>; + reg-shift = <2>; + interrupts = ; + reg-io-width = <1>; + clocks = <&coreclk 0>; + status = "disabled"; + }; + + uart2: serial@12200 { + compatible = "snps,dw-apb-uart"; + reg = <0x12200 0x100>; + reg-shift = <2>; + interrupts = ; + reg-io-width = <1>; + clocks = <&coreclk 0>; + status = "disabled"; + }; + + uart3: serial@12300 { + compatible = "snps,dw-apb-uart"; + reg = <0x12300 0x100>; + reg-shift = <2>; + interrupts = ; + reg-io-width = <1>; + clocks = <&coreclk 0>; + status = "disabled"; + }; + + pinctrl@18000 { + i2c0_pins: i2c0-pins { + marvell,pins = "mpp2", "mpp3"; + marvell,function = "i2c0"; + }; + + uart0_pins: uart0-pins { + marvell,pins = "mpp0", "mpp1"; + marvell,function = "ua0"; + }; + + uart1_pins: uart1-pins { + marvell,pins = "mpp19", "mpp20"; + marvell,function = "ua1"; + }; + + spi1_pins: spi1-pins { + marvell,pins = "mpp56", "mpp57", "mpp58", "mpp59"; + marvell,function = "spi1"; + }; + + nand_pins: nand-pins { + marvell,pins = "mpp22", "mpp34", "mpp23", "mpp33", + "mpp38", "mpp28", "mpp40", "mpp42", + "mpp35", "mpp36", "mpp25", "mpp30", + "mpp32"; + marvell,function = "dev"; + }; + }; + + system-controller@18200 { + compatible = "marvell,armada-390-system-controller", + "marvell,armada-370-xp-system-controller"; + reg = <0x18200 0x100>; + }; + + gateclk: clock-gating-control@18220 { + compatible = "marvell,armada-390-gating-clock"; + reg = <0x18220 0x4>; + clocks = <&coreclk 0>; + #clock-cells = <1>; + }; + + coreclk: mvebu-sar@18600 { + compatible = "marvell,armada-390-core-clock"; + reg = <0x18600 0x04>; + #clock-cells = <1>; + }; + + mbusc: mbus-controller@20000 { + compatible = "marvell,mbus-controller"; + reg = <0x20000 0x100>, <0x20180 0x20>, <0x20250 0x8>; + }; + + mpic: interrupt-controller@20a00 { + compatible = "marvell,mpic"; + reg = <0x20a00 0x2d0>, <0x21070 0x58>; + #interrupt-cells = <1>; + #size-cells = <1>; + interrupt-controller; + msi-controller; + interrupts = ; + }; + + timer@20300 { + compatible = "marvell,armada-380-timer", + "marvell,armada-xp-timer"; + reg = <0x20300 0x30>, <0x21040 0x30>; + interrupts-extended = <&gic GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>, + <&gic GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>, + <&gic GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>, + <&gic GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>, + <&mpic 5>, + <&mpic 6>; + clocks = <&coreclk 2>, <&coreclk 5>; + clock-names = "nbclk", "fixed"; + }; + + cpurst@20800 { + compatible = "marvell,armada-370-cpu-reset"; + reg = <0x20800 0x10>; + }; + + pmsu@22000 { + compatible = "marvell,armada-390-pmsu", + "marvell,armada-380-pmsu"; + reg = <0x22000 0x1000>; + }; + + xor@60800 { + compatible = "marvell,orion-xor"; + reg = <0x60800 0x100 + 0x60a00 0x100>; + clocks = <&gateclk 22>; + status = "okay"; + + xor00 { + interrupts = ; + dmacap,memcpy; + dmacap,xor; + }; + xor01 { + interrupts = ; + dmacap,memcpy; + dmacap,xor; + dmacap,memset; + }; + }; + + xor@60900 { + compatible = "marvell,orion-xor"; + reg = <0x60900 0x100 + 0x60b00 0x100>; + clocks = <&gateclk 28>; + status = "okay"; + + xor10 { + interrupts = ; + dmacap,memcpy; + dmacap,xor; + }; + xor11 { + interrupts = ; + dmacap,memcpy; + dmacap,xor; + dmacap,memset; + }; + }; + + flash@d0000 { + compatible = "marvell,armada370-nand"; + reg = <0xd0000 0x54>; + #address-cells = <1>; + #size-cells = <1>; + interrupts = ; + clocks = <&coredivclk 0>; + status = "disabled"; + }; + + sdhci@d8000 { + compatible = "marvell,armada-380-sdhci"; + reg = <0xd8000 0x1000>, <0xdc000 0x100>; + interrupts = ; + clocks = <&gateclk 17>; + mrvl,clk-delay-cycles = <0x1F>; + status = "disabled"; + }; + + coredivclk: clock@e4250 { + compatible = "marvell,armada-390-corediv-clock", + "marvell,armada-380-corediv-clock"; + reg = <0xe4250 0xc>; + #clock-cells = <1>; + clocks = <&mainpll>; + clock-output-names = "nand"; + }; + }; + + pcie-controller { + compatible = "marvell,armada-370-pcie"; + status = "disabled"; + device_type = "pci"; + + #address-cells = <3>; + #size-cells = <2>; + + msi-parent = <&mpic>; + bus-range = <0x00 0xff>; + + ranges = + <0x82000000 0 0x80000 MBUS_ID(0xf0, 0x01) 0x80000 0 0x00002000 + 0x82000000 0 0x40000 MBUS_ID(0xf0, 0x01) 0x40000 0 0x00002000 + 0x82000000 0 0x44000 MBUS_ID(0xf0, 0x01) 0x44000 0 0x00002000 + 0x82000000 0 0x48000 MBUS_ID(0xf0, 0x01) 0x48000 0 0x00002000 + 0x82000000 0x1 0 MBUS_ID(0x08, 0xe8) 0 1 0 /* Port 0 MEM */ + 0x81000000 0x1 0 MBUS_ID(0x08, 0xe0) 0 1 0 /* Port 0 IO */ + 0x82000000 0x2 0 MBUS_ID(0x04, 0xe8) 0 1 0 /* Port 1 MEM */ + 0x81000000 0x2 0 MBUS_ID(0x04, 0xe0) 0 1 0 /* Port 1 IO */ + 0x82000000 0x3 0 MBUS_ID(0x04, 0xd8) 0 1 0 /* Port 2 MEM */ + 0x81000000 0x3 0 MBUS_ID(0x04, 0xd0) 0 1 0 /* Port 2 IO */ + 0x82000000 0x4 0 MBUS_ID(0x04, 0xb8) 0 1 0 /* Port 3 MEM */ + 0x81000000 0x4 0 MBUS_ID(0x04, 0xb0) 0 1 0 /* Port 3 IO */>; + + /* + * This port can be either x4 or x1. When + * configured in x4 by the bootloader, then + * pcie@4,0 is not available. + */ + pcie@1,0 { + device_type = "pci"; + assigned-addresses = <0x82000800 0 0x80000 0 0x2000>; + reg = <0x0800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0 + 0x81000000 0 0 0x81000000 0x1 0 1 0>; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &gic GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>; + marvell,pcie-port = <0>; + marvell,pcie-lane = <0>; + clocks = <&gateclk 8>; + status = "disabled"; + }; + + /* x1 port */ + pcie@2,0 { + device_type = "pci"; + assigned-addresses = <0x82000800 0 0x40000 0 0x2000>; + reg = <0x1000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0 + 0x81000000 0 0 0x81000000 0x2 0 1 0>; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &gic GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>; + marvell,pcie-port = <1>; + marvell,pcie-lane = <0>; + clocks = <&gateclk 5>; + status = "disabled"; + }; + + /* x1 port */ + pcie@3,0 { + device_type = "pci"; + assigned-addresses = <0x82000800 0 0x44000 0 0x2000>; + reg = <0x1800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges = <0x82000000 0 0 0x82000000 0x3 0 1 0 + 0x81000000 0 0 0x81000000 0x3 0 1 0>; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &gic GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>; + marvell,pcie-port = <2>; + marvell,pcie-lane = <0>; + clocks = <&gateclk 6>; + status = "disabled"; + }; + + /* + * x1 port only available when pcie@1,0 is + * configured as a x1 port + */ + pcie@4,0 { + device_type = "pci"; + assigned-addresses = <0x82000800 0 0x48000 0 0x2000>; + reg = <0x2000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges = <0x82000000 0 0 0x82000000 0x4 0 1 0 + 0x81000000 0 0 0x81000000 0x4 0 1 0>; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &gic GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>; + marvell,pcie-port = <3>; + marvell,pcie-lane = <0>; + clocks = <&gateclk 7>; + status = "disabled"; + }; + }; + }; + + clocks { + /* 2 GHz fixed main PLL */ + mainpll: mainpll { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <2000000000>; + }; + }; +}; -- GitLab From f224b572dcc86017d793c047c92c8479f5a6ae14 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Tue, 3 Mar 2015 15:41:14 +0100 Subject: [PATCH 02574/11651] ARM: mvebu: enable Armada 39x in mvebu_v7_defconfig Following the introduction of the Marvell Armada 39x support, let's enabled it by default in mvebu_v7_defconfig. Signed-off-by: Thomas Petazzoni Signed-off-by: Gregory CLEMENT --- arch/arm/configs/mvebu_v7_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/configs/mvebu_v7_defconfig b/arch/arm/configs/mvebu_v7_defconfig index 73673e95f23c..bb262f0880fd 100644 --- a/arch/arm/configs/mvebu_v7_defconfig +++ b/arch/arm/configs/mvebu_v7_defconfig @@ -12,6 +12,7 @@ CONFIG_ARCH_MVEBU=y CONFIG_MACH_ARMADA_370=y CONFIG_MACH_ARMADA_375=y CONFIG_MACH_ARMADA_38X=y +CONFIG_MACH_ARMADA_39X=y CONFIG_MACH_ARMADA_XP=y CONFIG_MACH_DOVE=y CONFIG_PCI=y -- GitLab From 4a8fe4e1811c96ad0ad9f4083f2fe4fb43b2988d Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Wed, 4 Mar 2015 09:56:02 -0500 Subject: [PATCH 02575/11651] seq_buf: Fix seq_buf_vprintf() truncation In seq_buf_vprintf(), vsnprintf() is used to copy the format into the buffer remaining in the seq_buf structure. The return of vsnprintf() is the amount of characters written to the buffer excluding the '\0', unless the line was truncated! If the line copied does not fit, it is truncated, and a '\0' is added to the end of the buffer. But in this case, '\0' is included in the length of the line written. To know if the buffer had overflowed, the return length will be the same as the length of the buffer passed in. The check in seq_buf_vprintf() only checked if the length returned from vsnprintf() would fit in the buffer, as the seq_buf_vprintf() is only to be an all or nothing command. It either writes all the string into the seq_buf, or none of it. If the string is truncated, the pointers inside the seq_buf must be reset to what they were when the function was called. This is not the case. On overflow, it copies only part of the string. The fix is to change the overflow check to see if the length returned from vsnprintf() is less than the length remaining in the seq_buf buffer, and not if it is less than or equal to as it currently does. Then seq_buf_vprintf() will know if the write from vsnpritnf() was truncated or not. Cc: stable@vger.kernel.org Signed-off-by: Steven Rostedt --- lib/seq_buf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/seq_buf.c b/lib/seq_buf.c index 88c0854bd752..0c92583b7b7e 100644 --- a/lib/seq_buf.c +++ b/lib/seq_buf.c @@ -61,7 +61,7 @@ int seq_buf_vprintf(struct seq_buf *s, const char *fmt, va_list args) if (s->len < s->size) { len = vsnprintf(s->buffer + s->len, s->size - s->len, fmt, args); - if (seq_buf_can_fit(s, len)) { + if (s->len + len < s->size) { s->len += len; return 0; } -- GitLab From 0a240339a8deeb13a19043389bba4285a6c0592e Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Wed, 19 Nov 2014 00:42:09 +0100 Subject: [PATCH 02576/11651] quota: Make VFS quotas use new interface for getting quota info Create new internal interface for getting information about quota which contains everything needed for both VFS quotas and XFS quotas. Make VFS use this and hook it up to Q_GETINFO. Reviewed-by: Christoph Hellwig Signed-off-by: Jan Kara --- fs/ext3/super.c | 2 +- fs/ext4/super.c | 2 +- fs/quota/dquot.c | 41 ++++++++++++++++++++++++++-------------- fs/quota/quota.c | 25 ++++++++++++++++++++---- fs/reiserfs/super.c | 2 +- include/linux/quota.h | 33 +++++++++++++++++++++++++++++++- include/linux/quotaops.h | 2 +- 7 files changed, 84 insertions(+), 23 deletions(-) diff --git a/fs/ext3/super.c b/fs/ext3/super.c index d4dbf3c259b3..f037b4b27300 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c @@ -789,7 +789,7 @@ static const struct quotactl_ops ext3_qctl_operations = { .quota_on = ext3_quota_on, .quota_off = dquot_quota_off, .quota_sync = dquot_quota_sync, - .get_info = dquot_get_dqinfo, + .get_state = dquot_get_state, .set_info = dquot_set_dqinfo, .get_dqblk = dquot_get_dqblk, .set_dqblk = dquot_set_dqblk diff --git a/fs/ext4/super.c b/fs/ext4/super.c index e061e66c8280..d348c7d29d80 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1076,7 +1076,7 @@ static const struct quotactl_ops ext4_qctl_operations = { .quota_on = ext4_quota_on, .quota_off = ext4_quota_off, .quota_sync = dquot_quota_sync, - .get_info = dquot_get_dqinfo, + .get_state = dquot_get_state, .set_info = dquot_set_dqinfo, .get_dqblk = dquot_get_dqblk, .set_dqblk = dquot_set_dqblk diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index 0ccd4ba3a246..cf4edd87e854 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c @@ -2614,26 +2614,39 @@ out: EXPORT_SYMBOL(dquot_set_dqblk); /* Generic routine for getting common part of quota file information */ -int dquot_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) +int dquot_get_state(struct super_block *sb, struct qc_state *state) { struct mem_dqinfo *mi; + struct qc_type_state *tstate; + struct quota_info *dqopt = sb_dqopt(sb); + int type; mutex_lock(&sb_dqopt(sb)->dqonoff_mutex); - if (!sb_has_quota_active(sb, type)) { - mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); - return -ESRCH; + memset(state, 0, sizeof(*state)); + for (type = 0; type < MAXQUOTAS; type++) { + if (!sb_has_quota_active(sb, type)) + continue; + tstate = state->s_state + type; + mi = sb_dqopt(sb)->info + type; + tstate->flags = QCI_ACCT_ENABLED; + spin_lock(&dq_data_lock); + if (mi->dqi_flags & DQF_SYS_FILE) + tstate->flags |= QCI_SYSFILE; + if (mi->dqi_flags & DQF_ROOT_SQUASH) + tstate->flags |= QCI_ROOT_SQUASH; + if (sb_has_quota_limits_enabled(sb, type)) + tstate->flags |= QCI_LIMITS_ENFORCED; + tstate->spc_timelimit = mi->dqi_bgrace; + tstate->ino_timelimit = mi->dqi_igrace; + tstate->ino = dqopt->files[type]->i_ino; + tstate->blocks = dqopt->files[type]->i_blocks; + tstate->nextents = 1; /* We don't know... */ + spin_unlock(&dq_data_lock); } - mi = sb_dqopt(sb)->info + type; - spin_lock(&dq_data_lock); - ii->dqi_bgrace = mi->dqi_bgrace; - ii->dqi_igrace = mi->dqi_igrace; - ii->dqi_flags = mi->dqi_flags & DQF_GETINFO_MASK; - ii->dqi_valid = IIF_ALL; - spin_unlock(&dq_data_lock); mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); return 0; } -EXPORT_SYMBOL(dquot_get_dqinfo); +EXPORT_SYMBOL(dquot_get_state); /* Generic routine for setting common part of quota file information */ int dquot_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) @@ -2677,7 +2690,7 @@ const struct quotactl_ops dquot_quotactl_ops = { .quota_on = dquot_quota_on, .quota_off = dquot_quota_off, .quota_sync = dquot_quota_sync, - .get_info = dquot_get_dqinfo, + .get_state = dquot_get_state, .set_info = dquot_set_dqinfo, .get_dqblk = dquot_get_dqblk, .set_dqblk = dquot_set_dqblk @@ -2688,7 +2701,7 @@ const struct quotactl_ops dquot_quotactl_sysfile_ops = { .quota_enable = dquot_quota_enable, .quota_disable = dquot_quota_disable, .quota_sync = dquot_quota_sync, - .get_info = dquot_get_dqinfo, + .get_state = dquot_get_state, .set_info = dquot_set_dqinfo, .get_dqblk = dquot_get_dqblk, .set_dqblk = dquot_set_dqblk diff --git a/fs/quota/quota.c b/fs/quota/quota.c index d14a799c7785..00d50fca1005 100644 --- a/fs/quota/quota.c +++ b/fs/quota/quota.c @@ -118,13 +118,30 @@ static int quota_getfmt(struct super_block *sb, int type, void __user *addr) static int quota_getinfo(struct super_block *sb, int type, void __user *addr) { - struct if_dqinfo info; + struct qc_state state; + struct qc_type_state *tstate; + struct if_dqinfo uinfo; int ret; - if (!sb->s_qcop->get_info) + /* This checks whether qc_state has enough entries... */ + BUILD_BUG_ON(MAXQUOTAS > XQM_MAXQUOTAS); + if (!sb->s_qcop->get_state) return -ENOSYS; - ret = sb->s_qcop->get_info(sb, type, &info); - if (!ret && copy_to_user(addr, &info, sizeof(info))) + ret = sb->s_qcop->get_state(sb, &state); + if (ret) + return ret; + tstate = state.s_state + type; + if (!(tstate->flags & QCI_ACCT_ENABLED)) + return -ESRCH; + memset(&uinfo, 0, sizeof(uinfo)); + uinfo.dqi_bgrace = tstate->spc_timelimit; + uinfo.dqi_igrace = tstate->ino_timelimit; + if (tstate->flags & QCI_SYSFILE) + uinfo.dqi_flags |= DQF_SYS_FILE; + if (tstate->flags & QCI_ROOT_SQUASH) + uinfo.dqi_flags |= DQF_ROOT_SQUASH; + uinfo.dqi_valid = IIF_ALL; + if (!ret && copy_to_user(addr, &uinfo, sizeof(uinfo))) return -EFAULT; return ret; } diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 71fbbe3e2dab..68b5f182984e 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -805,7 +805,7 @@ static const struct quotactl_ops reiserfs_qctl_operations = { .quota_on = reiserfs_quota_on, .quota_off = dquot_quota_off, .quota_sync = dquot_quota_sync, - .get_info = dquot_get_dqinfo, + .get_state = dquot_get_state, .set_info = dquot_set_dqinfo, .get_dqblk = dquot_get_dqblk, .set_dqblk = dquot_set_dqblk, diff --git a/include/linux/quota.h b/include/linux/quota.h index d534e8ed308a..6ecac0f3b2ca 100644 --- a/include/linux/quota.h +++ b/include/linux/quota.h @@ -366,6 +366,37 @@ struct qc_dqblk { #define QC_RT_SPACE (1<<14) #define QC_ACCT_MASK (QC_SPACE | QC_INO_COUNT | QC_RT_SPACE) +#define QCI_SYSFILE (1 << 0) /* Quota file is hidden from userspace */ +#define QCI_ROOT_SQUASH (1 << 1) /* Root squash turned on */ +#define QCI_ACCT_ENABLED (1 << 2) /* Quota accounting enabled */ +#define QCI_LIMITS_ENFORCED (1 << 3) /* Quota limits enforced */ + +/* Structures for communicating via ->get_state */ +struct qc_type_state { + unsigned int flags; /* Flags QCI_* */ + unsigned int spc_timelimit; /* Time after which space softlimit is + * enforced */ + unsigned int ino_timelimit; /* Ditto for inode softlimit */ + unsigned int rt_spc_timelimit; /* Ditto for real-time space */ + unsigned int spc_warnlimit; /* Limit for number of space warnings */ + unsigned int ino_warnlimit; /* Ditto for inodes */ + unsigned int rt_spc_warnlimit; /* Ditto for real-time space */ + unsigned long long ino; /* Inode number of quota file */ + blkcnt_t blocks; /* Number of 512-byte blocks in the file */ + blkcnt_t nextents; /* Number of extents in the file */ +}; + +struct qc_state { + unsigned int s_incoredqs; /* Number of dquots in core */ + /* + * Per quota type information. The array should really have + * max(MAXQUOTAS, XQM_MAXQUOTAS) entries. BUILD_BUG_ON in + * quota_getinfo() makes sure XQM_MAXQUOTAS is large enough. Once VFS + * supports project quotas, this can be changed to MAXQUOTAS + */ + struct qc_type_state s_state[XQM_MAXQUOTAS]; +}; + /* Operations handling requests from userspace */ struct quotactl_ops { int (*quota_on)(struct super_block *, int, int, struct path *); @@ -373,10 +404,10 @@ struct quotactl_ops { int (*quota_enable)(struct super_block *, unsigned int); int (*quota_disable)(struct super_block *, unsigned int); int (*quota_sync)(struct super_block *, int); - int (*get_info)(struct super_block *, int, struct if_dqinfo *); int (*set_info)(struct super_block *, int, struct if_dqinfo *); int (*get_dqblk)(struct super_block *, struct kqid, struct qc_dqblk *); int (*set_dqblk)(struct super_block *, struct kqid, struct qc_dqblk *); + int (*get_state)(struct super_block *, struct qc_state *); int (*get_xstate)(struct super_block *, struct fs_quota_stat *); int (*get_xstatev)(struct super_block *, struct fs_quota_statv *); int (*rm_xquota)(struct super_block *, unsigned int); diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h index df73258cca47..6509a29523e2 100644 --- a/include/linux/quotaops.h +++ b/include/linux/quotaops.h @@ -95,7 +95,7 @@ int dquot_quota_on_mount(struct super_block *sb, char *qf_name, int dquot_quota_off(struct super_block *sb, int type); int dquot_writeback_dquots(struct super_block *sb, int type); int dquot_quota_sync(struct super_block *sb, int type); -int dquot_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii); +int dquot_get_state(struct super_block *sb, struct qc_state *state); int dquot_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii); int dquot_get_dqblk(struct super_block *sb, struct kqid id, struct qc_dqblk *di); -- GitLab From bc230e4a2326e30476092ed967fced0e43667c82 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Wed, 19 Nov 2014 16:17:45 +0100 Subject: [PATCH 02577/11651] quota: Wire up Q_GETXSTATE and Q_GETXSTATV calls to work with ->get_state Add appropriate conversion functions so that filesystems supporting ->get_state() method can be queried using Q_GETXSTATE and Q_GETXSTATV calls. Reviewed-by: Christoph Hellwig Signed-off-by: Jan Kara --- fs/quota/quota.c | 138 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 134 insertions(+), 4 deletions(-) diff --git a/fs/quota/quota.c b/fs/quota/quota.c index 00d50fca1005..83939ff4c444 100644 --- a/fs/quota/quota.c +++ b/fs/quota/quota.c @@ -269,25 +269,152 @@ static int quota_disable(struct super_block *sb, void __user *addr) return sb->s_qcop->quota_disable(sb, flags); } +static int quota_state_to_flags(struct qc_state *state) +{ + int flags = 0; + + if (state->s_state[USRQUOTA].flags & QCI_ACCT_ENABLED) + flags |= FS_QUOTA_UDQ_ACCT; + if (state->s_state[USRQUOTA].flags & QCI_LIMITS_ENFORCED) + flags |= FS_QUOTA_UDQ_ENFD; + if (state->s_state[GRPQUOTA].flags & QCI_ACCT_ENABLED) + flags |= FS_QUOTA_GDQ_ACCT; + if (state->s_state[GRPQUOTA].flags & QCI_LIMITS_ENFORCED) + flags |= FS_QUOTA_GDQ_ENFD; + if (state->s_state[PRJQUOTA].flags & QCI_ACCT_ENABLED) + flags |= FS_QUOTA_PDQ_ACCT; + if (state->s_state[PRJQUOTA].flags & QCI_LIMITS_ENFORCED) + flags |= FS_QUOTA_PDQ_ENFD; + return flags; +} + +static int quota_getstate(struct super_block *sb, struct fs_quota_stat *fqs) +{ + int type; + struct qc_state state; + int ret; + + ret = sb->s_qcop->get_state(sb, &state); + if (ret < 0) + return ret; + + memset(fqs, 0, sizeof(*fqs)); + fqs->qs_version = FS_QSTAT_VERSION; + fqs->qs_flags = quota_state_to_flags(&state); + /* No quota enabled? */ + if (!fqs->qs_flags) + return -ENOSYS; + fqs->qs_incoredqs = state.s_incoredqs; + /* + * GETXSTATE quotactl has space for just one set of time limits so + * report them for the first enabled quota type + */ + for (type = 0; type < XQM_MAXQUOTAS; type++) + if (state.s_state[type].flags & QCI_ACCT_ENABLED) + break; + BUG_ON(type == XQM_MAXQUOTAS); + fqs->qs_btimelimit = state.s_state[type].spc_timelimit; + fqs->qs_itimelimit = state.s_state[type].ino_timelimit; + fqs->qs_rtbtimelimit = state.s_state[type].rt_spc_timelimit; + fqs->qs_bwarnlimit = state.s_state[type].spc_warnlimit; + fqs->qs_iwarnlimit = state.s_state[type].ino_warnlimit; + if (state.s_state[USRQUOTA].flags & QCI_ACCT_ENABLED) { + fqs->qs_uquota.qfs_ino = state.s_state[USRQUOTA].ino; + fqs->qs_uquota.qfs_nblks = state.s_state[USRQUOTA].blocks; + fqs->qs_uquota.qfs_nextents = state.s_state[USRQUOTA].nextents; + } + if (state.s_state[GRPQUOTA].flags & QCI_ACCT_ENABLED) { + fqs->qs_gquota.qfs_ino = state.s_state[GRPQUOTA].ino; + fqs->qs_gquota.qfs_nblks = state.s_state[GRPQUOTA].blocks; + fqs->qs_gquota.qfs_nextents = state.s_state[GRPQUOTA].nextents; + } + if (state.s_state[PRJQUOTA].flags & QCI_ACCT_ENABLED) { + /* + * Q_XGETQSTAT doesn't have room for both group and project + * quotas. So, allow the project quota values to be copied out + * only if there is no group quota information available. + */ + if (!(state.s_state[GRPQUOTA].flags & QCI_ACCT_ENABLED)) { + fqs->qs_gquota.qfs_ino = state.s_state[PRJQUOTA].ino; + fqs->qs_gquota.qfs_nblks = + state.s_state[PRJQUOTA].blocks; + fqs->qs_gquota.qfs_nextents = + state.s_state[PRJQUOTA].nextents; + } + } + return 0; +} + static int quota_getxstate(struct super_block *sb, void __user *addr) { struct fs_quota_stat fqs; int ret; - if (!sb->s_qcop->get_xstate) + if (!sb->s_qcop->get_xstate && !sb->s_qcop->get_state) return -ENOSYS; - ret = sb->s_qcop->get_xstate(sb, &fqs); + if (sb->s_qcop->get_state) + ret = quota_getstate(sb, &fqs); + else + ret = sb->s_qcop->get_xstate(sb, &fqs); if (!ret && copy_to_user(addr, &fqs, sizeof(fqs))) return -EFAULT; return ret; } +static int quota_getstatev(struct super_block *sb, struct fs_quota_statv *fqs) +{ + int type; + struct qc_state state; + int ret; + + ret = sb->s_qcop->get_state(sb, &state); + if (ret < 0) + return ret; + + memset(fqs, 0, sizeof(*fqs)); + fqs->qs_version = FS_QSTAT_VERSION; + fqs->qs_flags = quota_state_to_flags(&state); + /* No quota enabled? */ + if (!fqs->qs_flags) + return -ENOSYS; + fqs->qs_incoredqs = state.s_incoredqs; + /* + * GETXSTATV quotactl has space for just one set of time limits so + * report them for the first enabled quota type + */ + for (type = 0; type < XQM_MAXQUOTAS; type++) + if (state.s_state[type].flags & QCI_ACCT_ENABLED) + break; + BUG_ON(type == XQM_MAXQUOTAS); + fqs->qs_btimelimit = state.s_state[type].spc_timelimit; + fqs->qs_itimelimit = state.s_state[type].ino_timelimit; + fqs->qs_rtbtimelimit = state.s_state[type].rt_spc_timelimit; + fqs->qs_bwarnlimit = state.s_state[type].spc_warnlimit; + fqs->qs_iwarnlimit = state.s_state[type].ino_warnlimit; + if (state.s_state[USRQUOTA].flags & QCI_ACCT_ENABLED) { + fqs->qs_uquota.qfs_ino = state.s_state[USRQUOTA].ino; + fqs->qs_uquota.qfs_nblks = state.s_state[USRQUOTA].blocks; + fqs->qs_uquota.qfs_nextents = state.s_state[USRQUOTA].nextents; + } + if (state.s_state[GRPQUOTA].flags & QCI_ACCT_ENABLED) { + fqs->qs_gquota.qfs_ino = state.s_state[GRPQUOTA].ino; + fqs->qs_gquota.qfs_nblks = state.s_state[GRPQUOTA].blocks; + fqs->qs_gquota.qfs_nextents = state.s_state[GRPQUOTA].nextents; + } + if (state.s_state[PRJQUOTA].flags & QCI_ACCT_ENABLED) { + fqs->qs_pquota.qfs_ino = state.s_state[PRJQUOTA].ino; + fqs->qs_pquota.qfs_nblks = state.s_state[PRJQUOTA].blocks; + fqs->qs_pquota.qfs_nextents = state.s_state[PRJQUOTA].nextents; + } + return 0; +} + static int quota_getxstatev(struct super_block *sb, void __user *addr) { struct fs_quota_statv fqs; int ret; - if (!sb->s_qcop->get_xstatev) + if (!sb->s_qcop->get_xstatev && !sb->s_qcop->get_state) return -ENOSYS; memset(&fqs, 0, sizeof(fqs)); @@ -301,7 +428,10 @@ static int quota_getxstatev(struct super_block *sb, void __user *addr) default: return -EINVAL; } - ret = sb->s_qcop->get_xstatev(sb, &fqs); + if (sb->s_qcop->get_state) + ret = quota_getstatev(sb, &fqs); + else + ret = sb->s_qcop->get_xstatev(sb, &fqs); if (!ret && copy_to_user(addr, &fqs, sizeof(fqs))) return -EFAULT; return ret; -- GitLab From 5d3684c2823bcf14a14bc7117c56c592f27815b9 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Wed, 19 Nov 2014 12:03:59 +0100 Subject: [PATCH 02578/11651] xfs: Convert to using ->get_state callback Convert xfs to use ->get_state callback instead of ->get_xstate and ->get_xstatev. Reviewed-by: Christoph Hellwig Signed-off-by: Jan Kara --- fs/xfs/xfs_qm.h | 4 - fs/xfs/xfs_qm_syscalls.c | 176 --------------------------------------- fs/xfs/xfs_quotaops.c | 96 +++++++++++++++------ 3 files changed, 71 insertions(+), 205 deletions(-) diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h index 0d4d3590cf85..996a04064894 100644 --- a/fs/xfs/xfs_qm.h +++ b/fs/xfs/xfs_qm.h @@ -168,10 +168,6 @@ extern int xfs_qm_scall_getquota(struct xfs_mount *, xfs_dqid_t, uint, struct qc_dqblk *); extern int xfs_qm_scall_setqlim(struct xfs_mount *, xfs_dqid_t, uint, struct qc_dqblk *); -extern int xfs_qm_scall_getqstat(struct xfs_mount *, - struct fs_quota_stat *); -extern int xfs_qm_scall_getqstatv(struct xfs_mount *, - struct fs_quota_statv *); extern int xfs_qm_scall_quotaon(struct xfs_mount *, uint); extern int xfs_qm_scall_quotaoff(struct xfs_mount *, uint); diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c index 9b965db45800..9a25c9275fb3 100644 --- a/fs/xfs/xfs_qm_syscalls.c +++ b/fs/xfs/xfs_qm_syscalls.c @@ -38,7 +38,6 @@ STATIC int xfs_qm_log_quotaoff(xfs_mount_t *, xfs_qoff_logitem_t **, uint); STATIC int xfs_qm_log_quotaoff_end(xfs_mount_t *, xfs_qoff_logitem_t *, uint); -STATIC uint xfs_qm_export_flags(uint); /* * Turn off quota accounting and/or enforcement for all udquots and/or @@ -389,159 +388,6 @@ xfs_qm_scall_quotaon( return 0; } - -/* - * Return quota status information, such as uquota-off, enforcements, etc. - * for Q_XGETQSTAT command. - */ -int -xfs_qm_scall_getqstat( - struct xfs_mount *mp, - struct fs_quota_stat *out) -{ - struct xfs_quotainfo *q = mp->m_quotainfo; - struct xfs_inode *uip = NULL; - struct xfs_inode *gip = NULL; - struct xfs_inode *pip = NULL; - bool tempuqip = false; - bool tempgqip = false; - bool temppqip = false; - - memset(out, 0, sizeof(fs_quota_stat_t)); - - out->qs_version = FS_QSTAT_VERSION; - out->qs_flags = (__uint16_t) xfs_qm_export_flags(mp->m_qflags & - (XFS_ALL_QUOTA_ACCT| - XFS_ALL_QUOTA_ENFD)); - uip = q->qi_uquotaip; - gip = q->qi_gquotaip; - pip = q->qi_pquotaip; - if (!uip && mp->m_sb.sb_uquotino != NULLFSINO) { - if (xfs_iget(mp, NULL, mp->m_sb.sb_uquotino, - 0, 0, &uip) == 0) - tempuqip = true; - } - if (!gip && mp->m_sb.sb_gquotino != NULLFSINO) { - if (xfs_iget(mp, NULL, mp->m_sb.sb_gquotino, - 0, 0, &gip) == 0) - tempgqip = true; - } - /* - * Q_XGETQSTAT doesn't have room for both group and project quotas. - * So, allow the project quota values to be copied out only if - * there is no group quota information available. - */ - if (!gip) { - if (!pip && mp->m_sb.sb_pquotino != NULLFSINO) { - if (xfs_iget(mp, NULL, mp->m_sb.sb_pquotino, - 0, 0, &pip) == 0) - temppqip = true; - } - } else - pip = NULL; - if (uip) { - out->qs_uquota.qfs_ino = mp->m_sb.sb_uquotino; - out->qs_uquota.qfs_nblks = uip->i_d.di_nblocks; - out->qs_uquota.qfs_nextents = uip->i_d.di_nextents; - if (tempuqip) - IRELE(uip); - } - - if (gip) { - out->qs_gquota.qfs_ino = mp->m_sb.sb_gquotino; - out->qs_gquota.qfs_nblks = gip->i_d.di_nblocks; - out->qs_gquota.qfs_nextents = gip->i_d.di_nextents; - if (tempgqip) - IRELE(gip); - } - if (pip) { - out->qs_gquota.qfs_ino = mp->m_sb.sb_gquotino; - out->qs_gquota.qfs_nblks = pip->i_d.di_nblocks; - out->qs_gquota.qfs_nextents = pip->i_d.di_nextents; - if (temppqip) - IRELE(pip); - } - out->qs_incoredqs = q->qi_dquots; - out->qs_btimelimit = q->qi_btimelimit; - out->qs_itimelimit = q->qi_itimelimit; - out->qs_rtbtimelimit = q->qi_rtbtimelimit; - out->qs_bwarnlimit = q->qi_bwarnlimit; - out->qs_iwarnlimit = q->qi_iwarnlimit; - - return 0; -} - -/* - * Return quota status information, such as uquota-off, enforcements, etc. - * for Q_XGETQSTATV command, to support separate project quota field. - */ -int -xfs_qm_scall_getqstatv( - struct xfs_mount *mp, - struct fs_quota_statv *out) -{ - struct xfs_quotainfo *q = mp->m_quotainfo; - struct xfs_inode *uip = NULL; - struct xfs_inode *gip = NULL; - struct xfs_inode *pip = NULL; - bool tempuqip = false; - bool tempgqip = false; - bool temppqip = false; - - out->qs_flags = (__uint16_t) xfs_qm_export_flags(mp->m_qflags & - (XFS_ALL_QUOTA_ACCT| - XFS_ALL_QUOTA_ENFD)); - out->qs_uquota.qfs_ino = mp->m_sb.sb_uquotino; - out->qs_gquota.qfs_ino = mp->m_sb.sb_gquotino; - out->qs_pquota.qfs_ino = mp->m_sb.sb_pquotino; - - uip = q->qi_uquotaip; - gip = q->qi_gquotaip; - pip = q->qi_pquotaip; - if (!uip && mp->m_sb.sb_uquotino != NULLFSINO) { - if (xfs_iget(mp, NULL, mp->m_sb.sb_uquotino, - 0, 0, &uip) == 0) - tempuqip = true; - } - if (!gip && mp->m_sb.sb_gquotino != NULLFSINO) { - if (xfs_iget(mp, NULL, mp->m_sb.sb_gquotino, - 0, 0, &gip) == 0) - tempgqip = true; - } - if (!pip && mp->m_sb.sb_pquotino != NULLFSINO) { - if (xfs_iget(mp, NULL, mp->m_sb.sb_pquotino, - 0, 0, &pip) == 0) - temppqip = true; - } - if (uip) { - out->qs_uquota.qfs_nblks = uip->i_d.di_nblocks; - out->qs_uquota.qfs_nextents = uip->i_d.di_nextents; - if (tempuqip) - IRELE(uip); - } - - if (gip) { - out->qs_gquota.qfs_nblks = gip->i_d.di_nblocks; - out->qs_gquota.qfs_nextents = gip->i_d.di_nextents; - if (tempgqip) - IRELE(gip); - } - if (pip) { - out->qs_pquota.qfs_nblks = pip->i_d.di_nblocks; - out->qs_pquota.qfs_nextents = pip->i_d.di_nextents; - if (temppqip) - IRELE(pip); - } - out->qs_incoredqs = q->qi_dquots; - out->qs_btimelimit = q->qi_btimelimit; - out->qs_itimelimit = q->qi_itimelimit; - out->qs_rtbtimelimit = q->qi_rtbtimelimit; - out->qs_bwarnlimit = q->qi_bwarnlimit; - out->qs_iwarnlimit = q->qi_iwarnlimit; - - return 0; -} - #define XFS_QC_MASK \ (QC_LIMIT_MASK | QC_TIMER_MASK | QC_WARNS_MASK) @@ -873,28 +719,6 @@ out_put: return error; } -STATIC uint -xfs_qm_export_flags( - uint flags) -{ - uint uflags; - - uflags = 0; - if (flags & XFS_UQUOTA_ACCT) - uflags |= FS_QUOTA_UDQ_ACCT; - if (flags & XFS_GQUOTA_ACCT) - uflags |= FS_QUOTA_GDQ_ACCT; - if (flags & XFS_PQUOTA_ACCT) - uflags |= FS_QUOTA_PDQ_ACCT; - if (flags & XFS_UQUOTA_ENFD) - uflags |= FS_QUOTA_UDQ_ENFD; - if (flags & XFS_GQUOTA_ENFD) - uflags |= FS_QUOTA_GDQ_ENFD; - if (flags & XFS_PQUOTA_ENFD) - uflags |= FS_QUOTA_PDQ_ENFD; - return uflags; -} - STATIC int xfs_dqrele_inode( diff --git a/fs/xfs/xfs_quotaops.c b/fs/xfs/xfs_quotaops.c index 6923905ab33d..5775acb0589b 100644 --- a/fs/xfs/xfs_quotaops.c +++ b/fs/xfs/xfs_quotaops.c @@ -23,45 +23,92 @@ #include "xfs_inode.h" #include "xfs_quota.h" #include "xfs_trans.h" +#include "xfs_trace.h" +#include "xfs_icache.h" #include "xfs_qm.h" #include -STATIC int -xfs_quota_type(int type) +static void +xfs_qm_fill_state( + struct qc_type_state *tstate, + struct xfs_mount *mp, + struct xfs_inode *ip, + xfs_ino_t ino) { - switch (type) { - case USRQUOTA: - return XFS_DQ_USER; - case GRPQUOTA: - return XFS_DQ_GROUP; - default: - return XFS_DQ_PROJ; + struct xfs_quotainfo *q = mp->m_quotainfo; + bool tempqip = false; + + tstate->ino = ino; + if (!ip && ino == NULLFSINO) + return; + if (!ip) { + if (xfs_iget(mp, NULL, ino, 0, 0, &ip)) + return; + tempqip = true; } + tstate->flags |= QCI_SYSFILE; + tstate->blocks = ip->i_d.di_nblocks; + tstate->nextents = ip->i_d.di_nextents; + tstate->spc_timelimit = q->qi_btimelimit; + tstate->ino_timelimit = q->qi_itimelimit; + tstate->rt_spc_timelimit = q->qi_rtbtimelimit; + tstate->spc_warnlimit = q->qi_bwarnlimit; + tstate->ino_warnlimit = q->qi_iwarnlimit; + tstate->rt_spc_warnlimit = q->qi_rtbwarnlimit; + if (tempqip) + IRELE(ip); } -STATIC int -xfs_fs_get_xstate( +/* + * Return quota status information, such as enforcements, quota file inode + * numbers etc. + */ +static int +xfs_fs_get_quota_state( struct super_block *sb, - struct fs_quota_stat *fqs) + struct qc_state *state) { - struct xfs_mount *mp = XFS_M(sb); + struct xfs_mount *mp = XFS_M(sb); + struct xfs_quotainfo *q = mp->m_quotainfo; + memset(state, 0, sizeof(*state)); if (!XFS_IS_QUOTA_RUNNING(mp)) - return -ENOSYS; - return xfs_qm_scall_getqstat(mp, fqs); + return 0; + state->s_incoredqs = q->qi_dquots; + if (XFS_IS_UQUOTA_RUNNING(mp)) + state->s_state[USRQUOTA].flags |= QCI_ACCT_ENABLED; + if (XFS_IS_UQUOTA_ENFORCED(mp)) + state->s_state[USRQUOTA].flags |= QCI_LIMITS_ENFORCED; + if (XFS_IS_GQUOTA_RUNNING(mp)) + state->s_state[GRPQUOTA].flags |= QCI_ACCT_ENABLED; + if (XFS_IS_GQUOTA_ENFORCED(mp)) + state->s_state[GRPQUOTA].flags |= QCI_LIMITS_ENFORCED; + if (XFS_IS_PQUOTA_RUNNING(mp)) + state->s_state[PRJQUOTA].flags |= QCI_ACCT_ENABLED; + if (XFS_IS_PQUOTA_ENFORCED(mp)) + state->s_state[PRJQUOTA].flags |= QCI_LIMITS_ENFORCED; + + xfs_qm_fill_state(&state->s_state[USRQUOTA], mp, q->qi_uquotaip, + mp->m_sb.sb_uquotino); + xfs_qm_fill_state(&state->s_state[GRPQUOTA], mp, q->qi_gquotaip, + mp->m_sb.sb_gquotino); + xfs_qm_fill_state(&state->s_state[PRJQUOTA], mp, q->qi_pquotaip, + mp->m_sb.sb_pquotino); + return 0; } STATIC int -xfs_fs_get_xstatev( - struct super_block *sb, - struct fs_quota_statv *fqs) +xfs_quota_type(int type) { - struct xfs_mount *mp = XFS_M(sb); - - if (!XFS_IS_QUOTA_RUNNING(mp)) - return -ENOSYS; - return xfs_qm_scall_getqstatv(mp, fqs); + switch (type) { + case USRQUOTA: + return XFS_DQ_USER; + case GRPQUOTA: + return XFS_DQ_GROUP; + default: + return XFS_DQ_PROJ; + } } static unsigned int @@ -178,8 +225,7 @@ xfs_fs_set_dqblk( } const struct quotactl_ops xfs_quotactl_operations = { - .get_xstatev = xfs_fs_get_xstatev, - .get_xstate = xfs_fs_get_xstate, + .get_state = xfs_fs_get_quota_state, .quota_enable = xfs_quota_enable, .quota_disable = xfs_quota_disable, .rm_xquota = xfs_fs_rm_xquota, -- GitLab From e54b2e2d723f138df35de0bf1f8262da116ca6fa Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Wed, 19 Nov 2014 16:41:07 +0100 Subject: [PATCH 02579/11651] gfs2: Convert to using ->get_state callback Convert gfs2 to use ->get_state callback instead of ->get_xstate. Acked-by: Bob Peterson Signed-off-by: Jan Kara --- fs/gfs2/quota.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c index 3aa17d4d1cfc..fa54cbf4c866 100644 --- a/fs/gfs2/quota.c +++ b/fs/gfs2/quota.c @@ -1468,32 +1468,34 @@ int gfs2_quotad(void *data) return 0; } -static int gfs2_quota_get_xstate(struct super_block *sb, - struct fs_quota_stat *fqs) +static int gfs2_quota_get_state(struct super_block *sb, struct qc_state *state) { struct gfs2_sbd *sdp = sb->s_fs_info; - memset(fqs, 0, sizeof(struct fs_quota_stat)); - fqs->qs_version = FS_QSTAT_VERSION; + memset(state, 0, sizeof(*state)); switch (sdp->sd_args.ar_quota) { case GFS2_QUOTA_ON: - fqs->qs_flags |= (FS_QUOTA_UDQ_ENFD | FS_QUOTA_GDQ_ENFD); + state->s_state[USRQUOTA].flags |= QCI_LIMITS_ENFORCED; + state->s_state[GRPQUOTA].flags |= QCI_LIMITS_ENFORCED; /*FALLTHRU*/ case GFS2_QUOTA_ACCOUNT: - fqs->qs_flags |= (FS_QUOTA_UDQ_ACCT | FS_QUOTA_GDQ_ACCT); + state->s_state[USRQUOTA].flags |= QCI_ACCT_ENABLED | + QCI_SYSFILE; + state->s_state[GRPQUOTA].flags |= QCI_ACCT_ENABLED | + QCI_SYSFILE; break; case GFS2_QUOTA_OFF: break; } - if (sdp->sd_quota_inode) { - fqs->qs_uquota.qfs_ino = GFS2_I(sdp->sd_quota_inode)->i_no_addr; - fqs->qs_uquota.qfs_nblks = sdp->sd_quota_inode->i_blocks; + state->s_state[USRQUOTA].ino = + GFS2_I(sdp->sd_quota_inode)->i_no_addr; + state->s_state[USRQUOTA].blocks = sdp->sd_quota_inode->i_blocks; } - fqs->qs_uquota.qfs_nextents = 1; /* unsupported */ - fqs->qs_gquota = fqs->qs_uquota; /* its the same inode in both cases */ - fqs->qs_incoredqs = list_lru_count(&gfs2_qd_lru); + state->s_state[USRQUOTA].nextents = 1; /* unsupported */ + state->s_state[GRPQUOTA] = state->s_state[USRQUOTA]; + state->s_incoredqs = list_lru_count(&gfs2_qd_lru); return 0; } @@ -1638,7 +1640,7 @@ out_put: const struct quotactl_ops gfs2_quotactl_ops = { .quota_sync = gfs2_quota_sync, - .get_xstate = gfs2_quota_get_xstate, + .get_state = gfs2_quota_get_state, .get_dqblk = gfs2_get_dqblk, .set_dqblk = gfs2_set_dqblk, }; -- GitLab From 59b6ba699043e0f55d4057cf2ae79d9c1171bc58 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Wed, 19 Nov 2014 16:44:58 +0100 Subject: [PATCH 02580/11651] quota: Remove ->get_xstate and ->get_xstatev callbacks These callbacks are now unused. Remove them. Reviewed-by: Christoph Hellwig Signed-off-by: Jan Kara --- fs/quota/quota.c | 14 ++++---------- include/linux/quota.h | 2 -- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/fs/quota/quota.c b/fs/quota/quota.c index 83939ff4c444..20d11cd21247 100644 --- a/fs/quota/quota.c +++ b/fs/quota/quota.c @@ -350,12 +350,9 @@ static int quota_getxstate(struct super_block *sb, void __user *addr) struct fs_quota_stat fqs; int ret; - if (!sb->s_qcop->get_xstate && !sb->s_qcop->get_state) + if (!sb->s_qcop->get_state) return -ENOSYS; - if (sb->s_qcop->get_state) - ret = quota_getstate(sb, &fqs); - else - ret = sb->s_qcop->get_xstate(sb, &fqs); + ret = quota_getstate(sb, &fqs); if (!ret && copy_to_user(addr, &fqs, sizeof(fqs))) return -EFAULT; return ret; @@ -414,7 +411,7 @@ static int quota_getxstatev(struct super_block *sb, void __user *addr) struct fs_quota_statv fqs; int ret; - if (!sb->s_qcop->get_xstatev && !sb->s_qcop->get_state) + if (!sb->s_qcop->get_state) return -ENOSYS; memset(&fqs, 0, sizeof(fqs)); @@ -428,10 +425,7 @@ static int quota_getxstatev(struct super_block *sb, void __user *addr) default: return -EINVAL; } - if (sb->s_qcop->get_state) - ret = quota_getstatev(sb, &fqs); - else - ret = sb->s_qcop->get_xstatev(sb, &fqs); + ret = quota_getstatev(sb, &fqs); if (!ret && copy_to_user(addr, &fqs, sizeof(fqs))) return -EFAULT; return ret; diff --git a/include/linux/quota.h b/include/linux/quota.h index 6ecac0f3b2ca..a07f2ed25284 100644 --- a/include/linux/quota.h +++ b/include/linux/quota.h @@ -408,8 +408,6 @@ struct quotactl_ops { int (*get_dqblk)(struct super_block *, struct kqid, struct qc_dqblk *); int (*set_dqblk)(struct super_block *, struct kqid, struct qc_dqblk *); int (*get_state)(struct super_block *, struct qc_state *); - int (*get_xstate)(struct super_block *, struct fs_quota_stat *); - int (*get_xstatev)(struct super_block *, struct fs_quota_statv *); int (*rm_xquota)(struct super_block *, unsigned int); }; -- GitLab From 5eacb2ac029161d94969a511e0adf7dca28cda1f Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Tue, 16 Dec 2014 12:03:51 +0100 Subject: [PATCH 02581/11651] quota: Make ->set_info use structure with neccesary info to VFS and XFS Change ->set_info to take new qc_info structure which contains all the necessary information both for XFS and VFS. Convert Q_SETINFO handler to use this structure. Signed-off-by: Jan Kara --- fs/quota/dquot.c | 27 ++++++++++++++++----------- fs/quota/quota.c | 21 ++++++++++++++++++++- include/linux/quota.h | 21 +++++++++++++++++++-- include/linux/quotaops.h | 2 +- 4 files changed, 56 insertions(+), 15 deletions(-) diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index cf4edd87e854..f37b74eab807 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c @@ -2649,33 +2649,38 @@ int dquot_get_state(struct super_block *sb, struct qc_state *state) EXPORT_SYMBOL(dquot_get_state); /* Generic routine for setting common part of quota file information */ -int dquot_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) +int dquot_set_dqinfo(struct super_block *sb, int type, struct qc_info *ii) { struct mem_dqinfo *mi; int err = 0; + if ((ii->i_fieldmask & QC_WARNS_MASK) || + (ii->i_fieldmask & QC_RT_SPC_TIMER)) + return -EINVAL; mutex_lock(&sb_dqopt(sb)->dqonoff_mutex); if (!sb_has_quota_active(sb, type)) { err = -ESRCH; goto out; } mi = sb_dqopt(sb)->info + type; - if (ii->dqi_valid & IIF_FLAGS) { - if (ii->dqi_flags & ~DQF_SETINFO_MASK || - (ii->dqi_flags & DQF_ROOT_SQUASH && + if (ii->i_fieldmask & QC_FLAGS) { + if ((ii->i_flags & QCI_ROOT_SQUASH && mi->dqi_format->qf_fmt_id != QFMT_VFS_OLD)) { err = -EINVAL; goto out; } } spin_lock(&dq_data_lock); - if (ii->dqi_valid & IIF_BGRACE) - mi->dqi_bgrace = ii->dqi_bgrace; - if (ii->dqi_valid & IIF_IGRACE) - mi->dqi_igrace = ii->dqi_igrace; - if (ii->dqi_valid & IIF_FLAGS) - mi->dqi_flags = (mi->dqi_flags & ~DQF_SETINFO_MASK) | - (ii->dqi_flags & DQF_SETINFO_MASK); + if (ii->i_fieldmask & QC_SPC_TIMER) + mi->dqi_bgrace = ii->i_spc_timelimit; + if (ii->i_fieldmask & QC_INO_TIMER) + mi->dqi_igrace = ii->i_ino_timelimit; + if (ii->i_fieldmask & QC_FLAGS) { + if (ii->i_flags & QCI_ROOT_SQUASH) + mi->dqi_flags |= DQF_ROOT_SQUASH; + else + mi->dqi_flags &= ~DQF_ROOT_SQUASH; + } spin_unlock(&dq_data_lock); mark_info_dirty(sb, type); /* Force write to disk */ diff --git a/fs/quota/quota.c b/fs/quota/quota.c index 20d11cd21247..741d5a178268 100644 --- a/fs/quota/quota.c +++ b/fs/quota/quota.c @@ -149,12 +149,31 @@ static int quota_getinfo(struct super_block *sb, int type, void __user *addr) static int quota_setinfo(struct super_block *sb, int type, void __user *addr) { struct if_dqinfo info; + struct qc_info qinfo; if (copy_from_user(&info, addr, sizeof(info))) return -EFAULT; if (!sb->s_qcop->set_info) return -ENOSYS; - return sb->s_qcop->set_info(sb, type, &info); + if (info.dqi_valid & ~(IIF_FLAGS | IIF_BGRACE | IIF_IGRACE)) + return -EINVAL; + memset(&qinfo, 0, sizeof(qinfo)); + if (info.dqi_valid & IIF_FLAGS) { + if (info.dqi_flags & ~DQF_SETINFO_MASK) + return -EINVAL; + if (info.dqi_flags & DQF_ROOT_SQUASH) + qinfo.i_flags |= QCI_ROOT_SQUASH; + qinfo.i_fieldmask |= QC_FLAGS; + } + if (info.dqi_valid & IIF_BGRACE) { + qinfo.i_spc_timelimit = info.dqi_bgrace; + qinfo.i_fieldmask |= QC_SPC_TIMER; + } + if (info.dqi_valid & IIF_IGRACE) { + qinfo.i_ino_timelimit = info.dqi_igrace; + qinfo.i_fieldmask |= QC_INO_TIMER; + } + return sb->s_qcop->set_info(sb, type, &qinfo); } static inline qsize_t qbtos(qsize_t blocks) diff --git a/include/linux/quota.h b/include/linux/quota.h index a07f2ed25284..3d521199a0bd 100644 --- a/include/linux/quota.h +++ b/include/linux/quota.h @@ -344,7 +344,10 @@ struct qc_dqblk { int d_rt_spc_warns; /* # warnings issued wrt RT space */ }; -/* Field specifiers for ->set_dqblk() in struct qc_dqblk */ +/* + * Field specifiers for ->set_dqblk() in struct qc_dqblk and also for + * ->set_info() in struct qc_info + */ #define QC_INO_SOFT (1<<0) #define QC_INO_HARD (1<<1) #define QC_SPC_SOFT (1<<2) @@ -365,6 +368,7 @@ struct qc_dqblk { #define QC_INO_COUNT (1<<13) #define QC_RT_SPACE (1<<14) #define QC_ACCT_MASK (QC_SPACE | QC_INO_COUNT | QC_RT_SPACE) +#define QC_FLAGS (1<<15) #define QCI_SYSFILE (1 << 0) /* Quota file is hidden from userspace */ #define QCI_ROOT_SQUASH (1 << 1) /* Root squash turned on */ @@ -397,6 +401,19 @@ struct qc_state { struct qc_type_state s_state[XQM_MAXQUOTAS]; }; +/* Structure for communicating via ->set_info */ +struct qc_info { + int i_fieldmask; /* mask of fields to change in ->set_info() */ + unsigned int i_flags; /* Flags QCI_* */ + unsigned int i_spc_timelimit; /* Time after which space softlimit is + * enforced */ + unsigned int i_ino_timelimit; /* Ditto for inode softlimit */ + unsigned int i_rt_spc_timelimit;/* Ditto for real-time space */ + unsigned int i_spc_warnlimit; /* Limit for number of space warnings */ + unsigned int i_ino_warnlimit; /* Limit for number of inode warnings */ + unsigned int i_rt_spc_warnlimit; /* Ditto for real-time space */ +}; + /* Operations handling requests from userspace */ struct quotactl_ops { int (*quota_on)(struct super_block *, int, int, struct path *); @@ -404,7 +421,7 @@ struct quotactl_ops { int (*quota_enable)(struct super_block *, unsigned int); int (*quota_disable)(struct super_block *, unsigned int); int (*quota_sync)(struct super_block *, int); - int (*set_info)(struct super_block *, int, struct if_dqinfo *); + int (*set_info)(struct super_block *, int, struct qc_info *); int (*get_dqblk)(struct super_block *, struct kqid, struct qc_dqblk *); int (*set_dqblk)(struct super_block *, struct kqid, struct qc_dqblk *); int (*get_state)(struct super_block *, struct qc_state *); diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h index 6509a29523e2..9f4b07ba9e8c 100644 --- a/include/linux/quotaops.h +++ b/include/linux/quotaops.h @@ -96,7 +96,7 @@ int dquot_quota_off(struct super_block *sb, int type); int dquot_writeback_dquots(struct super_block *sb, int type); int dquot_quota_sync(struct super_block *sb, int type); int dquot_get_state(struct super_block *sb, struct qc_state *state); -int dquot_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii); +int dquot_set_dqinfo(struct super_block *sb, int type, struct qc_info *ii); int dquot_get_dqblk(struct super_block *sb, struct kqid id, struct qc_dqblk *di); int dquot_set_dqblk(struct super_block *sb, struct kqid id, -- GitLab From c14cad9eed11343014f73aae4a77278239b201b8 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Tue, 16 Dec 2014 13:07:45 +0100 Subject: [PATCH 02582/11651] xfs: Add support for Q_SETINFO Add support to XFS so that time limits can be set through Q_SETINFO quotactl. Reviewed-by: Christoph Hellwig Signed-off-by: Jan Kara --- fs/xfs/xfs_quotaops.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/fs/xfs/xfs_quotaops.c b/fs/xfs/xfs_quotaops.c index 5775acb0589b..7795e0d01382 100644 --- a/fs/xfs/xfs_quotaops.c +++ b/fs/xfs/xfs_quotaops.c @@ -111,6 +111,42 @@ xfs_quota_type(int type) } } +#define XFS_QC_SETINFO_MASK (QC_TIMER_MASK | QC_WARNS_MASK) + +/* + * Adjust quota timers & warnings + */ +static int +xfs_fs_set_info( + struct super_block *sb, + int type, + struct qc_info *info) +{ + struct xfs_mount *mp = XFS_M(sb); + struct qc_dqblk newlim; + + if (sb->s_flags & MS_RDONLY) + return -EROFS; + if (!XFS_IS_QUOTA_RUNNING(mp)) + return -ENOSYS; + if (!XFS_IS_QUOTA_ON(mp)) + return -ESRCH; + if (info->i_fieldmask & ~XFS_QC_SETINFO_MASK) + return -EINVAL; + if ((info->i_fieldmask & XFS_QC_SETINFO_MASK) == 0) + return 0; + + newlim.d_fieldmask = info->i_fieldmask; + newlim.d_spc_timer = info->i_spc_timelimit; + newlim.d_ino_timer = info->i_ino_timelimit; + newlim.d_rt_spc_timer = info->i_rt_spc_timelimit; + newlim.d_ino_warns = info->i_ino_warnlimit; + newlim.d_spc_warns = info->i_spc_warnlimit; + newlim.d_rt_spc_warns = info->i_rt_spc_warnlimit; + + return xfs_qm_scall_setqlim(mp, 0, xfs_quota_type(type), &newlim); +} + static unsigned int xfs_quota_flags(unsigned int uflags) { @@ -226,6 +262,7 @@ xfs_fs_set_dqblk( const struct quotactl_ops xfs_quotactl_operations = { .get_state = xfs_fs_get_quota_state, + .set_info = xfs_fs_set_info, .quota_enable = xfs_quota_enable, .quota_disable = xfs_quota_disable, .rm_xquota = xfs_fs_rm_xquota, -- GitLab From c39fb53b48c851b185c22548153581d78f2acc11 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Tue, 16 Dec 2014 16:12:27 +0100 Subject: [PATCH 02583/11651] quota: Hook up Q_XSETQLIM for id 0 to ->set_info Setting timers or warning counts for id 0 via Q_XSETQLIM is used to actually set time limits and warning limits for all users. Hook up ->set_info to this so that VFS quota time limits get set the same way as XFS ones. When doing this Q_XSETQLIM for XFS is effectively split into two independent transactions - one for setting timers and warning limits and one for setting space and inode limits. Although this is inefficient, it is rare enough that it does not matter. Reviewed-by: Christoph Hellwig Signed-off-by: Jan Kara --- fs/quota/quota.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/fs/quota/quota.c b/fs/quota/quota.c index 741d5a178268..86ded7375c21 100644 --- a/fs/quota/quota.c +++ b/fs/quota/quota.c @@ -517,6 +517,30 @@ static void copy_from_xfs_dqblk(struct qc_dqblk *dst, struct fs_disk_quota *src) dst->d_fieldmask |= QC_RT_SPACE; } +static void copy_qcinfo_from_xfs_dqblk(struct qc_info *dst, + struct fs_disk_quota *src) +{ + memset(dst, 0, sizeof(*dst)); + dst->i_spc_timelimit = src->d_btimer; + dst->i_ino_timelimit = src->d_itimer; + dst->i_rt_spc_timelimit = src->d_rtbtimer; + dst->i_ino_warnlimit = src->d_iwarns; + dst->i_spc_warnlimit = src->d_bwarns; + dst->i_rt_spc_warnlimit = src->d_rtbwarns; + if (src->d_fieldmask & FS_DQ_BWARNS) + dst->i_fieldmask |= QC_SPC_WARNS; + if (src->d_fieldmask & FS_DQ_IWARNS) + dst->i_fieldmask |= QC_INO_WARNS; + if (src->d_fieldmask & FS_DQ_RTBWARNS) + dst->i_fieldmask |= QC_RT_SPC_WARNS; + if (src->d_fieldmask & FS_DQ_BTIMER) + dst->i_fieldmask |= QC_SPC_TIMER; + if (src->d_fieldmask & FS_DQ_ITIMER) + dst->i_fieldmask |= QC_INO_TIMER; + if (src->d_fieldmask & FS_DQ_RTBTIMER) + dst->i_fieldmask |= QC_RT_SPC_TIMER; +} + static int quota_setxquota(struct super_block *sb, int type, qid_t id, void __user *addr) { @@ -531,6 +555,21 @@ static int quota_setxquota(struct super_block *sb, int type, qid_t id, qid = make_kqid(current_user_ns(), type, id); if (!qid_valid(qid)) return -EINVAL; + /* Are we actually setting timer / warning limits for all users? */ + if (from_kqid(&init_user_ns, qid) == 0 && + fdq.d_fieldmask & (FS_DQ_WARNS_MASK | FS_DQ_TIMER_MASK)) { + struct qc_info qinfo; + int ret; + + if (!sb->s_qcop->set_info) + return -EINVAL; + copy_qcinfo_from_xfs_dqblk(&qinfo, &fdq); + ret = sb->s_qcop->set_info(sb, type, &qinfo); + if (ret) + return ret; + /* These are already done */ + fdq.d_fieldmask &= ~(FS_DQ_WARNS_MASK | FS_DQ_TIMER_MASK); + } copy_from_xfs_dqblk(&qdq, &fdq); return sb->s_qcop->set_dqblk(sb, qid, &qdq); } -- GitLab From 33350e6b1833b15cf9c9c4c84d8534ad68b0c7b8 Mon Sep 17 00:00:00 2001 From: Ashwin Chaugule Date: Tue, 27 Jan 2015 16:03:57 -0500 Subject: [PATCH 02584/11651] Mailbox: Restructure and simplify PCC mailbox code Previously the PCC driver depended on the client side to map the communication space base address. This region was was then used in the PCC driver and the client side. The client side used this region to read and write its data and the PCC driver used it to only write the PCC command. Removing this split simplifies the PCC driver a lot. This patch moves all communication region read/writes to the client side. The PCC clients can now drive the PCC mailbox controller via the mbox_client_txdone() method. Signed-off-by: Ashwin Chaugule --- drivers/mailbox/pcc.c | 122 +++++++++++++----------------------------- 1 file changed, 37 insertions(+), 85 deletions(-) diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c index 977c814cdf6f..7e91d68a3ac3 100644 --- a/drivers/mailbox/pcc.c +++ b/drivers/mailbox/pcc.c @@ -20,10 +20,35 @@ * shared memory regions as defined in the PCC table entries. The PCC * specification supports a Doorbell mechanism for the PCC clients * to notify the platform about new data. This Doorbell information - * is also specified in each PCC table entry. See pcc_send_data() - * and pcc_tx_done() for basic mode of operation. + * is also specified in each PCC table entry. * - * For more details about PCC, please see the ACPI specification from + * Typical high level flow of operation is: + * + * PCC Reads: + * * Client tries to acquire a channel lock. + * * After it is acquired it writes READ cmd in communication region cmd + * address. + * * Client issues mbox_send_message() which rings the PCC doorbell + * for its PCC channel. + * * If command completes, then client has control over channel and + * it can proceed with its reads. + * * Client releases lock. + * + * PCC Writes: + * * Client tries to acquire channel lock. + * * Client writes to its communication region after it acquires a + * channel lock. + * * Client writes WRITE cmd in communication region cmd address. + * * Client issues mbox_send_message() which rings the PCC doorbell + * for its PCC channel. + * * If command completes, then writes have succeded and it can release + * the channel lock. + * + * There is a Nominal latency defined for each channel which indicates + * how long to wait until a command completes. If command is not complete + * the client needs to retry or assume failure. + * + * For more details about PCC, please see the ACPI specification from * http://www.uefi.org/ACPIv5.1 Section 14. * * This file implements PCC as a Mailbox controller and allows for PCC @@ -42,8 +67,6 @@ #include "mailbox.h" #define MAX_PCC_SUBSPACES 256 -#define PCCS_SS_SIG_MAGIC 0x50434300 -#define PCC_CMD_COMPLETE 0x1 static struct mbox_chan *pcc_mbox_channels; @@ -70,23 +93,6 @@ static struct mbox_chan *get_pcc_channel(int id) return pcc_chan; } -/** - * get_subspace_id - Given a Mailbox channel, find out the - * PCC subspace id. - * @chan: Pointer to Mailbox Channel from which we want - * the index. - * Return: Errno if not found, else positive index number. - */ -static int get_subspace_id(struct mbox_chan *chan) -{ - unsigned int id = chan - pcc_mbox_channels; - - if (id < 0 || id > pcc_mbox_ctrl.num_chans) - return -ENOENT; - - return id; -} - /** * pcc_mbox_request_channel - PCC clients call this function to * request a pointer to their PCC subspace, from which they @@ -117,7 +123,7 @@ struct mbox_chan *pcc_mbox_request_channel(struct mbox_client *cl, chan = get_pcc_channel(subspace_id); if (!chan || chan->cl) { - dev_err(dev, "%s: PCC mailbox not free\n", __func__); + dev_err(dev, "Channel not found for idx: %d\n", subspace_id); return ERR_PTR(-EBUSY); } @@ -161,81 +167,30 @@ void pcc_mbox_free_channel(struct mbox_chan *chan) EXPORT_SYMBOL_GPL(pcc_mbox_free_channel); /** - * pcc_tx_done - Callback from Mailbox controller code to - * check if PCC message transmission completed. - * @chan: Pointer to Mailbox channel on which previous - * transmission occurred. - * - * Return: TRUE if succeeded. - */ -static bool pcc_tx_done(struct mbox_chan *chan) -{ - struct acpi_pcct_hw_reduced *pcct_ss = chan->con_priv; - struct acpi_pcct_shared_memory *generic_comm_base = - (struct acpi_pcct_shared_memory *) pcct_ss->base_address; - u16 cmd_delay = pcct_ss->latency; - unsigned int retries = 0; - - /* Try a few times while waiting for platform to consume */ - while (!(readw_relaxed(&generic_comm_base->status) - & PCC_CMD_COMPLETE)) { - - if (retries++ < 5) - udelay(cmd_delay); - else { - /* - * If the remote is dead, this will cause the Mbox - * controller to timeout after mbox client.tx_tout - * msecs. - */ - pr_err("PCC platform did not respond.\n"); - return false; - } - } - return true; -} - -/** - * pcc_send_data - Called from Mailbox Controller code to finally - * transmit data over channel. + * pcc_send_data - Called from Mailbox Controller code. Used + * here only to ring the channel doorbell. The PCC client + * specific read/write is done in the client driver in + * order to maintain atomicity over PCC channel once + * OS has control over it. See above for flow of operations. * @chan: Pointer to Mailbox channel over which to send data. - * @data: Actual data to be written over channel. + * @data: Client specific data written over channel. Used here + * only for debug after PCC transaction completes. * * Return: Err if something failed else 0 for success. */ static int pcc_send_data(struct mbox_chan *chan, void *data) { struct acpi_pcct_hw_reduced *pcct_ss = chan->con_priv; - struct acpi_pcct_shared_memory *generic_comm_base = - (struct acpi_pcct_shared_memory *) pcct_ss->base_address; struct acpi_generic_address doorbell; u64 doorbell_preserve; u64 doorbell_val; u64 doorbell_write; - u16 cmd = *(u16 *) data; - u16 ss_idx = -1; - - ss_idx = get_subspace_id(chan); - - if (ss_idx < 0) { - pr_err("Invalid Subspace ID from PCC client\n"); - return -EINVAL; - } doorbell = pcct_ss->doorbell_register; doorbell_preserve = pcct_ss->preserve_mask; doorbell_write = pcct_ss->write_mask; - /* Write to the shared comm region. */ - writew(cmd, &generic_comm_base->command); - - /* Write Subspace MAGIC value so platform can identify destination. */ - writel((PCCS_SS_SIG_MAGIC | ss_idx), &generic_comm_base->signature); - - /* Flip CMD COMPLETE bit */ - writew(0, &generic_comm_base->status); - - /* Sync notification from OSPM to Platform. */ + /* Sync notification from OS to Platform. */ acpi_read(&doorbell_val, &doorbell); acpi_write((doorbell_val & doorbell_preserve) | doorbell_write, &doorbell); @@ -245,7 +200,6 @@ static int pcc_send_data(struct mbox_chan *chan, void *data) static struct mbox_chan_ops pcc_chan_ops = { .send_data = pcc_send_data, - .last_tx_done = pcc_tx_done, }; /** @@ -351,8 +305,6 @@ static int pcc_mbox_probe(struct platform_device *pdev) pcc_mbox_ctrl.chans = pcc_mbox_channels; pcc_mbox_ctrl.ops = &pcc_chan_ops; - pcc_mbox_ctrl.txdone_poll = true; - pcc_mbox_ctrl.txpoll_period = 10; pcc_mbox_ctrl.dev = &pdev->dev; pr_info("Registering PCC driver as Mailbox controller\n"); -- GitLab From 8b28c93fe5a55873ce22b7126e84eb59290f8603 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 4 Mar 2015 15:37:01 +0100 Subject: [PATCH 02585/11651] ALSA: usb-audio: Check Marantz/Denon USB DACs in a single place There are three places doing the same check. Let's make them together. Signed-off-by: Takashi Iwai --- sound/usb/quirks.c | 40 +++++++++++++++++----------------------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index 753a47de8459..353532b8aee4 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -1120,17 +1120,24 @@ bool snd_usb_get_sample_rate_quirk(struct snd_usb_audio *chip) /* Marantz/Denon USB DACs need a vendor cmd to switch * between PCM and native DSD mode */ +static bool is_marantz_denon_dac(unsigned int id) +{ + switch (id) { + case USB_ID(0x154e, 0x1003): /* Denon DA-300USB */ + case USB_ID(0x154e, 0x3005): /* Marantz HD-DAC1 */ + case USB_ID(0x154e, 0x3006): /* Marantz SA-14S1 */ + return true; + } + return false; +} + int snd_usb_select_mode_quirk(struct snd_usb_substream *subs, struct audioformat *fmt) { struct usb_device *dev = subs->dev; int err; - switch (subs->stream->chip->usb_id) { - case USB_ID(0x154e, 0x1003): /* Denon DA-300USB */ - case USB_ID(0x154e, 0x3005): /* Marantz HD-DAC1 */ - case USB_ID(0x154e, 0x3006): /* Marantz SA-14S1 */ - + if (is_marantz_denon_dac(subs->stream->chip->usb_id)) { /* First switch to alt set 0, otherwise the mode switch cmd * will not be accepted by the DAC */ @@ -1203,17 +1210,10 @@ void snd_usb_ctl_msg_quirk(struct usb_device *dev, unsigned int pipe, /* Marantz/Denon devices with USB DAC functionality need a delay * after each class compliant request */ - if ((le16_to_cpu(dev->descriptor.idVendor) == 0x154e) && - (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS) { - - switch (le16_to_cpu(dev->descriptor.idProduct)) { - case 0x1003: /* Denon DA300-USB */ - case 0x3005: /* Marantz HD-DAC1 */ - case 0x3006: /* Marantz SA-14S1 */ - mdelay(20); - break; - } - } + if (is_marantz_denon_dac(USB_ID(le16_to_cpu(dev->descriptor.idVendor), + le16_to_cpu(dev->descriptor.idProduct))) + && (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS) + mdelay(20); /* Zoom R16/24 needs a tiny delay here, otherwise requests like * get/set frequency return as failed despite actually succeeding. @@ -1268,15 +1268,9 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip, } /* Denon/Marantz devices with USB DAC functionality */ - switch (chip->usb_id) { - case USB_ID(0x154e, 0x1003): /* Denon DA300-USB */ - case USB_ID(0x154e, 0x3005): /* Marantz HD-DAC1 */ - case USB_ID(0x154e, 0x3006): /* Marantz SA-14S1 */ + if (is_marantz_denon_dac(chip->usb_id)) { if (fp->altsetting == 2) return SNDRV_PCM_FMTBIT_DSD_U32_BE; - break; - default: - break; } return 0; -- GitLab From 7d70e15480c0450d2bfafaad338a32e884fc215e Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 4 Mar 2015 10:37:43 -0500 Subject: [PATCH 02586/11651] writeback: add missing INITIAL_JIFFIES init in global_update_bandwidth() global_update_bandwidth() uses static variable update_time as the timestamp for the last update but forgets to initialize it to INITIALIZE_JIFFIES. This means that global_dirty_limit will be 5 mins into the future on 32bit and some large amount jiffies into the past on 64bit. This isn't critical as the only effect is that global_dirty_limit won't be updated for the first 5 mins after booting on 32bit machines, especially given the auxiliary nature of global_dirty_limit's role - protecting against global dirty threshold's sudden dips; however, it does lead to unintended suboptimal behavior. Fix it. Fixes: c42843f2f0bb ("writeback: introduce smoothed global dirty limit") Signed-off-by: Tejun Heo Acked-by: Jan Kara Cc: Wu Fengguang Cc: Jens Axboe Cc: stable@vger.kernel.org Signed-off-by: Jens Axboe --- mm/page-writeback.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/page-writeback.c b/mm/page-writeback.c index 45e187b2d971..b4fd980a93eb 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c @@ -922,7 +922,7 @@ static void global_update_bandwidth(unsigned long thresh, unsigned long now) { static DEFINE_SPINLOCK(dirty_lock); - static unsigned long update_time; + static unsigned long update_time = INITIAL_JIFFIES; /* * check locklessly first to optimize away locking for the most time -- GitLab From 5bcd3b6f639c277ed7fa71f2f8ed6fb072615011 Mon Sep 17 00:00:00 2001 From: Konstantin Khlebnikov Date: Thu, 12 Feb 2015 12:36:37 +0300 Subject: [PATCH 02587/11651] quota: optimize i_dquot access Remove redundant calls of i_dquot(), keep pointer in local variable. add/remove: 0/0 grow/shrink: 3/7 up/down: 40/-278 (-238) function old new delta __dquot_free_space 734 750 +16 __dquot_alloc_space 484 500 +16 dquot_free_inode 324 332 +8 dquot_drop 82 69 -13 vfs_load_quota_inode 1357 1341 -16 dquot_reclaim_space_nodirty 348 316 -32 dquot_disable 1980 1944 -36 dquot_claim_space_nodirty 354 314 -40 __dquot_drop 125 83 -42 __dquot_initialize 522 423 -99 Signed-off-by: Konstantin Khlebnikov Signed-off-by: Jan Kara --- fs/quota/dquot.c | 63 ++++++++++++++++++++++++++++++------------------ 1 file changed, 39 insertions(+), 24 deletions(-) diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index 0ccd4ba3a246..2112ed33de41 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c @@ -900,14 +900,17 @@ static inline struct dquot **i_dquot(struct inode *inode) static int dqinit_needed(struct inode *inode, int type) { + struct dquot * const *dquots; int cnt; if (IS_NOQUOTA(inode)) return 0; + + dquots = i_dquot(inode); if (type != -1) - return !i_dquot(inode)[type]; + return !dquots[type]; for (cnt = 0; cnt < MAXQUOTAS; cnt++) - if (!i_dquot(inode)[cnt]) + if (!dquots[cnt]) return 1; return 0; } @@ -970,12 +973,13 @@ static void add_dquot_ref(struct super_block *sb, int type) static void remove_inode_dquot_ref(struct inode *inode, int type, struct list_head *tofree_head) { - struct dquot *dquot = i_dquot(inode)[type]; + struct dquot **dquots = i_dquot(inode); + struct dquot *dquot = dquots[type]; - i_dquot(inode)[type] = NULL; if (!dquot) return; + dquots[type] = NULL; if (list_empty(&dquot->dq_free)) { /* * The inode still has reference to dquot so it can't be in the @@ -1389,13 +1393,15 @@ static int dquot_active(const struct inode *inode) static void __dquot_initialize(struct inode *inode, int type) { int cnt, init_needed = 0; - struct dquot *got[MAXQUOTAS]; + struct dquot **dquots, *got[MAXQUOTAS]; struct super_block *sb = inode->i_sb; qsize_t rsv; if (!dquot_active(inode)) return; + dquots = i_dquot(inode); + /* First get references to structures we might need. */ for (cnt = 0; cnt < MAXQUOTAS; cnt++) { struct kqid qid; @@ -1407,7 +1413,7 @@ static void __dquot_initialize(struct inode *inode, int type) * we check it without locking here to avoid unnecessary * dqget()/dqput() calls. */ - if (i_dquot(inode)[cnt]) + if (dquots[cnt]) continue; init_needed = 1; @@ -1438,8 +1444,8 @@ static void __dquot_initialize(struct inode *inode, int type) /* We could race with quotaon or dqget() could have failed */ if (!got[cnt]) continue; - if (!i_dquot(inode)[cnt]) { - i_dquot(inode)[cnt] = got[cnt]; + if (!dquots[cnt]) { + dquots[cnt] = got[cnt]; got[cnt] = NULL; /* * Make quota reservation system happy if someone @@ -1447,7 +1453,7 @@ static void __dquot_initialize(struct inode *inode, int type) */ rsv = inode_get_rsv_space(inode); if (unlikely(rsv)) - dquot_resv_space(i_dquot(inode)[cnt], rsv); + dquot_resv_space(dquots[cnt], rsv); } } out_err: @@ -1473,12 +1479,13 @@ EXPORT_SYMBOL(dquot_initialize); static void __dquot_drop(struct inode *inode) { int cnt; + struct dquot **dquots = i_dquot(inode); struct dquot *put[MAXQUOTAS]; spin_lock(&dq_data_lock); for (cnt = 0; cnt < MAXQUOTAS; cnt++) { - put[cnt] = i_dquot(inode)[cnt]; - i_dquot(inode)[cnt] = NULL; + put[cnt] = dquots[cnt]; + dquots[cnt] = NULL; } spin_unlock(&dq_data_lock); dqput_all(put); @@ -1486,6 +1493,7 @@ static void __dquot_drop(struct inode *inode) void dquot_drop(struct inode *inode) { + struct dquot * const *dquots; int cnt; if (IS_NOQUOTA(inode)) @@ -1498,8 +1506,9 @@ void dquot_drop(struct inode *inode) * must assure that nobody can come after the DQUOT_DROP and * add quota pointers back anyway. */ + dquots = i_dquot(inode); for (cnt = 0; cnt < MAXQUOTAS; cnt++) { - if (i_dquot(inode)[cnt]) + if (dquots[cnt]) break; } @@ -1600,8 +1609,8 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags) { int cnt, ret = 0, index; struct dquot_warn warn[MAXQUOTAS]; - struct dquot **dquots = i_dquot(inode); int reserve = flags & DQUOT_SPACE_RESERVE; + struct dquot **dquots; if (!dquot_active(inode)) { inode_incr_space(inode, number, reserve); @@ -1611,6 +1620,7 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags) for (cnt = 0; cnt < MAXQUOTAS; cnt++) warn[cnt].w_type = QUOTA_NL_NOWARN; + dquots = i_dquot(inode); index = srcu_read_lock(&dquot_srcu); spin_lock(&dq_data_lock); for (cnt = 0; cnt < MAXQUOTAS; cnt++) { @@ -1652,13 +1662,14 @@ int dquot_alloc_inode(struct inode *inode) { int cnt, ret = 0, index; struct dquot_warn warn[MAXQUOTAS]; - struct dquot * const *dquots = i_dquot(inode); + struct dquot * const *dquots; if (!dquot_active(inode)) return 0; for (cnt = 0; cnt < MAXQUOTAS; cnt++) warn[cnt].w_type = QUOTA_NL_NOWARN; + dquots = i_dquot(inode); index = srcu_read_lock(&dquot_srcu); spin_lock(&dq_data_lock); for (cnt = 0; cnt < MAXQUOTAS; cnt++) { @@ -1690,6 +1701,7 @@ EXPORT_SYMBOL(dquot_alloc_inode); */ int dquot_claim_space_nodirty(struct inode *inode, qsize_t number) { + struct dquot **dquots; int cnt, index; if (!dquot_active(inode)) { @@ -1697,18 +1709,18 @@ int dquot_claim_space_nodirty(struct inode *inode, qsize_t number) return 0; } + dquots = i_dquot(inode); index = srcu_read_lock(&dquot_srcu); spin_lock(&dq_data_lock); /* Claim reserved quotas to allocated quotas */ for (cnt = 0; cnt < MAXQUOTAS; cnt++) { - if (i_dquot(inode)[cnt]) - dquot_claim_reserved_space(i_dquot(inode)[cnt], - number); + if (dquots[cnt]) + dquot_claim_reserved_space(dquots[cnt], number); } /* Update inode bytes */ inode_claim_rsv_space(inode, number); spin_unlock(&dq_data_lock); - mark_all_dquot_dirty(i_dquot(inode)); + mark_all_dquot_dirty(dquots); srcu_read_unlock(&dquot_srcu, index); return 0; } @@ -1719,6 +1731,7 @@ EXPORT_SYMBOL(dquot_claim_space_nodirty); */ void dquot_reclaim_space_nodirty(struct inode *inode, qsize_t number) { + struct dquot **dquots; int cnt, index; if (!dquot_active(inode)) { @@ -1726,18 +1739,18 @@ void dquot_reclaim_space_nodirty(struct inode *inode, qsize_t number) return; } + dquots = i_dquot(inode); index = srcu_read_lock(&dquot_srcu); spin_lock(&dq_data_lock); /* Claim reserved quotas to allocated quotas */ for (cnt = 0; cnt < MAXQUOTAS; cnt++) { - if (i_dquot(inode)[cnt]) - dquot_reclaim_reserved_space(i_dquot(inode)[cnt], - number); + if (dquots[cnt]) + dquot_reclaim_reserved_space(dquots[cnt], number); } /* Update inode bytes */ inode_reclaim_rsv_space(inode, number); spin_unlock(&dq_data_lock); - mark_all_dquot_dirty(i_dquot(inode)); + mark_all_dquot_dirty(dquots); srcu_read_unlock(&dquot_srcu, index); return; } @@ -1750,7 +1763,7 @@ void __dquot_free_space(struct inode *inode, qsize_t number, int flags) { unsigned int cnt; struct dquot_warn warn[MAXQUOTAS]; - struct dquot **dquots = i_dquot(inode); + struct dquot **dquots; int reserve = flags & DQUOT_SPACE_RESERVE, index; if (!dquot_active(inode)) { @@ -1758,6 +1771,7 @@ void __dquot_free_space(struct inode *inode, qsize_t number, int flags) return; } + dquots = i_dquot(inode); index = srcu_read_lock(&dquot_srcu); spin_lock(&dq_data_lock); for (cnt = 0; cnt < MAXQUOTAS; cnt++) { @@ -1793,12 +1807,13 @@ void dquot_free_inode(struct inode *inode) { unsigned int cnt; struct dquot_warn warn[MAXQUOTAS]; - struct dquot * const *dquots = i_dquot(inode); + struct dquot * const *dquots; int index; if (!dquot_active(inode)) return; + dquots = i_dquot(inode); index = srcu_read_lock(&dquot_srcu); spin_lock(&dq_data_lock); for (cnt = 0; cnt < MAXQUOTAS; cnt++) { -- GitLab From 69a25ee217ba8c93a6d4c6671d9208c0155c0485 Mon Sep 17 00:00:00 2001 From: Konstantin Khlebnikov Date: Thu, 12 Feb 2015 12:36:49 +0300 Subject: [PATCH 02588/11651] quota: paranoia: check quota tree root Root level in quota tree must be already allocated otherwise this block could be used for something else. Signed-off-by: Konstantin Khlebnikov Signed-off-by: Jan Kara --- fs/quota/quota_tree.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/fs/quota/quota_tree.c b/fs/quota/quota_tree.c index d65877fbe8f4..58efb83dec1c 100644 --- a/fs/quota/quota_tree.c +++ b/fs/quota/quota_tree.c @@ -349,6 +349,13 @@ static inline int dq_insert_tree(struct qtree_mem_dqinfo *info, struct dquot *dquot) { int tmp = QT_TREEOFF; + +#ifdef __QUOTA_QT_PARANOIA + if (info->dqi_blocks <= QT_TREEOFF) { + quota_error(dquot->dq_sb, "Quota tree root isn't allocated!"); + return -EIO; + } +#endif return do_insert_tree(info, dquot, &tmp, 0); } -- GitLab From 781970240a56d1c15a9b8ee37d28987b8182f060 Mon Sep 17 00:00:00 2001 From: Konstantin Khlebnikov Date: Thu, 12 Feb 2015 19:08:16 +0300 Subject: [PATCH 02589/11651] quota: reorder flags in quota state Flags in struct quota_state keep flags for each quota type and some common flags. This patch reorders typed flags: Before: 0 USRQUOTA DQUOT_USAGE_ENABLED 1 USRQUOTA DQUOT_LIMITS_ENABLED 2 USRQUOTA DQUOT_SUSPENDED 3 GRPQUOTA DQUOT_USAGE_ENABLED 4 GRPQUOTA DQUOT_LIMITS_ENABLED 5 GRPQUOTA DQUOT_SUSPENDED 6 DQUOT_QUOTA_SYS_FILE 7 DQUOT_NEGATIVE_USAGE After: 0 USRQUOTA DQUOT_USAGE_ENABLED 1 GRPQUOTA DQUOT_USAGE_ENABLED 2 USRQUOTA DQUOT_LIMITS_ENABLED 3 GRPQUOTA DQUOT_LIMITS_ENABLED 4 USRQUOTA DQUOT_SUSPENDED 5 GRPQUOTA DQUOT_SUSPENDED 6 DQUOT_QUOTA_SYS_FILE 7 DQUOT_NEGATIVE_USAGE Now we can get bitmap of all enabled/suspended quota types without loop. For example suspended: (flags / DQUOT_SUSPENDED) & ((1 << MAXQUOTAS) - 1). add/remove: 0/1 grow/shrink: 3/11 up/down: 56/-215 (-159) function old new delta __dquot_initialize 423 447 +24 dquot_transfer 181 197 +16 dquot_alloc_inode 286 302 +16 dquot_reclaim_space_nodirty 316 313 -3 dquot_claim_space_nodirty 314 311 -3 dquot_resume 286 281 -5 dquot_free_inode 332 324 -8 __dquot_alloc_space 500 492 -8 dquot_disable 1944 1929 -15 dquot_quota_enable 252 236 -16 __dquot_free_space 750 734 -16 dquot_writeback_dquots 625 608 -17 __dquot_transfer 1186 1154 -32 dquot_quota_sync 299 261 -38 dquot_active.isra 54 - -54 Signed-off-by: Konstantin Khlebnikov Signed-off-by: Jan Kara --- include/linux/quota.h | 32 +++++++++++++++++++++++++------- include/linux/quotaops.h | 10 ++-------- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/include/linux/quota.h b/include/linux/quota.h index d534e8ed308a..a3374dc3a91b 100644 --- a/include/linux/quota.h +++ b/include/linux/quota.h @@ -389,7 +389,19 @@ struct quota_format_type { struct quota_format_type *qf_next; }; -/* Quota state flags - they actually come in two flavors - for users and groups */ +/** + * Quota state flags - they actually come in two flavors - for users and groups. + * + * Actual typed flags layout: + * USRQUOTA GRPQUOTA + * DQUOT_USAGE_ENABLED 0x0001 0x0002 + * DQUOT_LIMITS_ENABLED 0x0004 0x0008 + * DQUOT_SUSPENDED 0x0010 0x0020 + * + * Following bits are used for non-typed flags: + * DQUOT_QUOTA_SYS_FILE 0x0040 + * DQUOT_NEGATIVE_USAGE 0x0080 + */ enum { _DQUOT_USAGE_ENABLED = 0, /* Track disk usage for users */ _DQUOT_LIMITS_ENABLED, /* Enforce quota limits for users */ @@ -398,9 +410,9 @@ enum { * memory to turn them on */ _DQUOT_STATE_FLAGS }; -#define DQUOT_USAGE_ENABLED (1 << _DQUOT_USAGE_ENABLED) -#define DQUOT_LIMITS_ENABLED (1 << _DQUOT_LIMITS_ENABLED) -#define DQUOT_SUSPENDED (1 << _DQUOT_SUSPENDED) +#define DQUOT_USAGE_ENABLED (1 << _DQUOT_USAGE_ENABLED * MAXQUOTAS) +#define DQUOT_LIMITS_ENABLED (1 << _DQUOT_LIMITS_ENABLED * MAXQUOTAS) +#define DQUOT_SUSPENDED (1 << _DQUOT_SUSPENDED * MAXQUOTAS) #define DQUOT_STATE_FLAGS (DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED | \ DQUOT_SUSPENDED) /* Other quota flags */ @@ -414,15 +426,21 @@ enum { */ #define DQUOT_NEGATIVE_USAGE (1 << (DQUOT_STATE_LAST + 1)) /* Allow negative quota usage */ - static inline unsigned int dquot_state_flag(unsigned int flags, int type) { - return flags << _DQUOT_STATE_FLAGS * type; + return flags << type; } static inline unsigned int dquot_generic_flag(unsigned int flags, int type) { - return (flags >> _DQUOT_STATE_FLAGS * type) & DQUOT_STATE_FLAGS; + return (flags >> type) & DQUOT_STATE_FLAGS; +} + +/* Bitmap of quota types where flag is set in flags */ +static __always_inline unsigned dquot_state_types(unsigned flags, unsigned flag) +{ + BUILD_BUG_ON_NOT_POWER_OF_2(flag); + return (flags / flag) & ((1 << MAXQUOTAS) - 1); } #ifdef CONFIG_QUOTA_NETLINK_INTERFACE diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h index df73258cca47..8778ec4775eb 100644 --- a/include/linux/quotaops.h +++ b/include/linux/quotaops.h @@ -134,10 +134,7 @@ static inline bool sb_has_quota_suspended(struct super_block *sb, int type) static inline unsigned sb_any_quota_suspended(struct super_block *sb) { - unsigned type, tmsk = 0; - for (type = 0; type < MAXQUOTAS; type++) - tmsk |= sb_has_quota_suspended(sb, type) << type; - return tmsk; + return dquot_state_types(sb_dqopt(sb)->flags, DQUOT_SUSPENDED); } /* Does kernel know about any quota information for given sb + type? */ @@ -149,10 +146,7 @@ static inline bool sb_has_quota_loaded(struct super_block *sb, int type) static inline unsigned sb_any_quota_loaded(struct super_block *sb) { - unsigned type, tmsk = 0; - for (type = 0; type < MAXQUOTAS; type++) - tmsk |= sb_has_quota_loaded(sb, type) << type; - return tmsk; + return dquot_state_types(sb_dqopt(sb)->flags, DQUOT_USAGE_ENABLED); } static inline bool sb_has_quota_active(struct super_block *sb, int type) -- GitLab From 7e08da50cf706151f324349f9235ebd311226997 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Wed, 4 Mar 2015 14:42:02 +0100 Subject: [PATCH 02590/11651] quota: Fix maximum quota limit settings Currently quota format that supports 64-bit usage sets maximum quota limit as 2^64-1. However quota core code uses signed numbers to track usage and even limits themselves are stored in long long. Checking of maximum allowable limits worked by luck until commit 14bf61ffe6ac (quota: Switch ->get_dqblk() and ->set_dqblk() to use bytes as space units) because variable we compared with was unsigned. After that commit the type we compared against changed to signed and thus checks for maximum limits with the newest VFS quota format started to refuse any non-negative value. Later the problem was inadvertedly fixed by commit b10a08194c2b (quota: Store maximum space limit in bytes) because we started to compare against unsigned type as well. Fix possible future problems of this kind by setting maximum limits to 2^63-1 to avoid overflow issues. Reported-by: Carlos Carvalho Signed-off-by: Jan Kara --- fs/quota/quota_v2.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/fs/quota/quota_v2.c b/fs/quota/quota_v2.c index 9cb10d7197f7..2aa012a68e90 100644 --- a/fs/quota/quota_v2.c +++ b/fs/quota/quota_v2.c @@ -117,12 +117,16 @@ static int v2_read_file_info(struct super_block *sb, int type) qinfo = info->dqi_priv; if (version == 0) { /* limits are stored as unsigned 32-bit data */ - info->dqi_max_spc_limit = 0xffffffffULL << QUOTABLOCK_BITS; + info->dqi_max_spc_limit = 0xffffffffLL << QUOTABLOCK_BITS; info->dqi_max_ino_limit = 0xffffffff; } else { - /* used space is stored as unsigned 64-bit value in bytes */ - info->dqi_max_spc_limit = 0xffffffffffffffffULL; /* 2^64-1 */ - info->dqi_max_ino_limit = 0xffffffffffffffffULL; + /* + * Used space is stored as unsigned 64-bit value in bytes but + * quota core supports only signed 64-bit values so use that + * as a limit + */ + info->dqi_max_spc_limit = 0x7fffffffffffffffLL; /* 2^63-1 */ + info->dqi_max_ino_limit = 0x7fffffffffffffffLL; } info->dqi_bgrace = le32_to_cpu(dinfo.dqi_bgrace); info->dqi_igrace = le32_to_cpu(dinfo.dqi_igrace); -- GitLab From bbb2d8a890733256d12b2c796eadaf54e70e9af5 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Wed, 4 Mar 2015 11:24:55 -0500 Subject: [PATCH 02591/11651] HID: Kconfig: add USB_HID dependency to UC-LOGIC In commit 08177f4 (HID: uclogic: merge hid-huion driver in hid-uclogic) HID_HUION depends explicitely on USB_HID because it contained quite some USB-isms. Now that hid-uclogic is the new home of Huion tablets, we need to also add the dependency on USB_HID to this driver. Reported-by: Jiri Kosina Reported-by: kbuild test robot Signed-off-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 8a55fd7f1fe3..60c34ccebe61 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -306,7 +306,7 @@ config HID_KYE config HID_UCLOGIC tristate "UC-Logic" - depends on HID + depends on USB_HID ---help--- Support for UC-Logic and Huion tablets. -- GitLab From b43baf694fde30dc2db2386c347324d1a013f3d1 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Wed, 4 Mar 2015 18:41:34 +0200 Subject: [PATCH 02592/11651] mei: free me client references on host init Fx fixes leak introduced by: commit b7d885145538 ("mei: revamp me clients list handling") Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/client.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index 98a5363e1e8a..b6fec4d15307 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -668,14 +668,17 @@ void mei_host_client_init(struct work_struct *work) me_cl = mei_me_cl_by_uuid(dev, &mei_amthif_guid); if (me_cl) mei_amthif_host_init(dev); + mei_me_cl_put(me_cl); me_cl = mei_me_cl_by_uuid(dev, &mei_wd_guid); if (me_cl) mei_wd_host_init(dev); + mei_me_cl_put(me_cl); me_cl = mei_me_cl_by_uuid(dev, &mei_nfc_guid); if (me_cl) mei_nfc_host_init(dev); + mei_me_cl_put(me_cl); dev->dev_state = MEI_DEV_ENABLED; -- GitLab From d2b5851d8583e690eeb5ac8dfff5da92e1f1468f Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Wed, 4 Mar 2015 18:41:35 +0200 Subject: [PATCH 02593/11651] mei: trace: fix missing include to linux/device.h Fix warning (discovered using randconfig) drivers/misc/mei/mei-trace.h:30:24: warning: 'struct device' declared inside parameter list TP_PROTO(const struct device *dev, const char *reg, u32 offs, u32 val), Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/mei-trace.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/misc/mei/mei-trace.h b/drivers/misc/mei/mei-trace.h index d5c38d15cdd9..5f4e1a17360b 100644 --- a/drivers/misc/mei/mei-trace.h +++ b/drivers/misc/mei/mei-trace.h @@ -21,6 +21,8 @@ #include #include +#include + #undef TRACE_SYSTEM #define TRACE_SYSTEM mei -- GitLab From 4ceba98d3fe204c59e5f63c4d834b45dcfe789f0 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 4 Mar 2015 15:29:17 +0100 Subject: [PATCH 02594/11651] regmap: Skip read-only registers in regcache_sync() regcache_sync() spews warnings when a value was cached for a read-only register as it tries to write all registers no matter whether they are writable or not. This patch adds regmap_wrtieable() checks for avoiding it in regcache_sync_block_single() and regcache_block_raw(). Signed-off-by: Takashi Iwai Signed-off-by: Mark Brown --- drivers/base/regmap/regcache.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c index f373c35f9e1d..da84f544c544 100644 --- a/drivers/base/regmap/regcache.c +++ b/drivers/base/regmap/regcache.c @@ -608,7 +608,8 @@ static int regcache_sync_block_single(struct regmap *map, void *block, for (i = start; i < end; i++) { regtmp = block_base + (i * map->reg_stride); - if (!regcache_reg_present(cache_present, i)) + if (!regcache_reg_present(cache_present, i) || + !regmap_writeable(map, regtmp)) continue; val = regcache_get_val(map, block, i); @@ -677,7 +678,8 @@ static int regcache_sync_block_raw(struct regmap *map, void *block, for (i = start; i < end; i++) { regtmp = block_base + (i * map->reg_stride); - if (!regcache_reg_present(cache_present, i)) { + if (!regcache_reg_present(cache_present, i) || + !regmap_writeable(map, regtmp)) { ret = regcache_sync_block_raw_flush(map, &data, base, regtmp); if (ret != 0) -- GitLab From c472b93990e02c31f02322ddf0fdd9d571169310 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 4 Mar 2015 10:33:16 +0100 Subject: [PATCH 02595/11651] ASoC: sn95031: Pass CODEC to sn95031_jack_detection() The sn95031 driver currently gets the CODEC implicitly from the jack that is passed to sn95031_jack_detection(). But the codec field is going to be removed from the snd_soc_jack struct, so refactor things to pass the CODEC explicitly. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/sn95031.c | 14 ++++++++------ sound/soc/codecs/sn95031.h | 3 ++- sound/soc/intel/mfld_machine.c | 13 +++++++------ 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/sound/soc/codecs/sn95031.c b/sound/soc/codecs/sn95031.c index 47b257e41809..1e5d2643c286 100644 --- a/sound/soc/codecs/sn95031.c +++ b/sound/soc/codecs/sn95031.c @@ -783,19 +783,21 @@ static inline void sn95031_enable_jack_btn(struct snd_soc_codec *codec) snd_soc_write(codec, SN95031_BTNCTRL2, 0x01); } -static int sn95031_get_headset_state(struct snd_soc_jack *mfld_jack) +static int sn95031_get_headset_state(struct snd_soc_codec *codec, + struct snd_soc_jack *mfld_jack) { - int micbias = sn95031_get_mic_bias(mfld_jack->codec); + int micbias = sn95031_get_mic_bias(codec); int jack_type = snd_soc_jack_get_type(mfld_jack, micbias); pr_debug("jack type detected = %d\n", jack_type); if (jack_type == SND_JACK_HEADSET) - sn95031_enable_jack_btn(mfld_jack->codec); + sn95031_enable_jack_btn(codec); return jack_type; } -void sn95031_jack_detection(struct mfld_jack_data *jack_data) +void sn95031_jack_detection(struct snd_soc_codec *codec, + struct mfld_jack_data *jack_data) { unsigned int status; unsigned int mask = SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_HEADSET; @@ -809,11 +811,11 @@ void sn95031_jack_detection(struct mfld_jack_data *jack_data) status = SND_JACK_HEADSET | SND_JACK_BTN_1; } else if (jack_data->intr_id & 0x4) { pr_debug("headset or headphones inserted\n"); - status = sn95031_get_headset_state(jack_data->mfld_jack); + status = sn95031_get_headset_state(codec, jack_data->mfld_jack); } else if (jack_data->intr_id & 0x8) { pr_debug("headset or headphones removed\n"); status = 0; - sn95031_disable_jack_btn(jack_data->mfld_jack->codec); + sn95031_disable_jack_btn(codec); } else { pr_err("unidentified interrupt\n"); return; diff --git a/sound/soc/codecs/sn95031.h b/sound/soc/codecs/sn95031.h index 20376d234fb8..7651fe4e6a45 100644 --- a/sound/soc/codecs/sn95031.h +++ b/sound/soc/codecs/sn95031.h @@ -127,6 +127,7 @@ struct mfld_jack_data { struct snd_soc_jack *mfld_jack; }; -extern void sn95031_jack_detection(struct mfld_jack_data *jack_data); +extern void sn95031_jack_detection(struct snd_soc_codec *codec, + struct mfld_jack_data *jack_data); #endif diff --git a/sound/soc/intel/mfld_machine.c b/sound/soc/intel/mfld_machine.c index 90b7a57713a0..d22b44db824e 100644 --- a/sound/soc/intel/mfld_machine.c +++ b/sound/soc/intel/mfld_machine.c @@ -228,10 +228,13 @@ static void mfld_jack_check(unsigned int intr_status) { struct mfld_jack_data jack_data; + if (!mfld_codec) + return; + jack_data.mfld_jack = &mfld_jack; jack_data.intr_id = intr_status; - sn95031_jack_detection(&jack_data); + sn95031_jack_detection(mfld_codec, &jack_data); /* TODO: add american headset detection post gpiolib support */ } @@ -240,8 +243,6 @@ static int mfld_init(struct snd_soc_pcm_runtime *runtime) struct snd_soc_dapm_context *dapm = &runtime->card->dapm; int ret_val; - mfld_codec = runtime->codec; - /* default is earpiece pin, userspace sets it explcitly */ snd_soc_dapm_disable_pin(dapm, "Headphones"); /* default is lineout NC, userspace sets it explcitly */ @@ -254,7 +255,7 @@ static int mfld_init(struct snd_soc_pcm_runtime *runtime) snd_soc_dapm_disable_pin(dapm, "LINEINR"); /* Headset and button jack detection */ - ret_val = snd_soc_jack_new(mfld_codec, "Intel(R) MID Audio Jack", + ret_val = snd_soc_jack_new(runtime->codec, "Intel(R) MID Audio Jack", SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1, &mfld_jack); if (ret_val) { @@ -275,6 +276,8 @@ static int mfld_init(struct snd_soc_pcm_runtime *runtime) return ret_val; } + mfld_codec = runtime->codec; + /* we want to check if anything is inserted at boot, * so send a fake event to codec and it will read adc * to find if anything is there or not */ @@ -359,8 +362,6 @@ static irqreturn_t snd_mfld_jack_detection(int irq, void *data) { struct mfld_mc_private *mc_drv_ctx = (struct mfld_mc_private *) data; - if (mfld_jack.codec == NULL) - return IRQ_HANDLED; mfld_jack_check(mc_drv_ctx->interrupt_status); return IRQ_HANDLED; -- GitLab From 970939964c26db4643f58d4e84487821962e0b65 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 4 Mar 2015 10:33:17 +0100 Subject: [PATCH 02596/11651] ASoC: Allow to register jacks at the card level Jacks are typically card level elements, but are currently registered with a CODEC. When it was originally introduced snd_soc_jack_new() took a snd_soc_card as its parameter, but at that time DAPM was only implemented at the CODEC level and there was only one CODEC per card. This made it clear which CODEC to use for the jack DAPM operations. But the multi-component patchset added support for having multiple CODECs per card and with it the API was updated to register jacks with a specific CODEC instance instead. Subsequently DAPM support at the card level has been introduced, but the snd_soc_jack_new() API has so remained unchanged. This leaves us with the issue that the DAPM pins that are managed by the jack detection logic usually are part of the card DAPM context but are accessed through a CODEC DAPM context. Currently this works fine, but might break in the future if we take a more hierarchical approach to DAPM contexts. Furthermore with componentization progressing systems that do not register a snd_soc_codec might appear, while these system may still want to able to register a jack. This patch addresses these issues by adding a new function called snd_soc_card_jack_new() that can be used to register jacks with the card rather than a CODEC. This new function is mostly identical to snd_soc_jack_new() except that it additionally allows to directly specify the DAPM pins associated with the jack. This was done since most users of snd_soc_jack_new() typically call snd_soc_jack_add_pins() right after it, which is not necessary with the new API and allows to reduce the amount of boiler plate code. The old snd_soc_jack_new() is re-implemented as a wrapper around snd_soc_card_jack_new(). Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- include/sound/soc.h | 28 +++++++++++++++++++++++++--- sound/soc/soc-jack.c | 42 ++++++++++++++++++++++++++---------------- 2 files changed, 51 insertions(+), 19 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index 0d1ade195628..99d9ce272209 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -450,8 +450,10 @@ int soc_dai_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *dai); /* Jack reporting */ -int snd_soc_jack_new(struct snd_soc_codec *codec, const char *id, int type, - struct snd_soc_jack *jack); +int snd_soc_card_jack_new(struct snd_soc_card *card, const char *id, int type, + struct snd_soc_jack *jack, struct snd_soc_jack_pin *pins, + unsigned int num_pins); + void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask); int snd_soc_jack_add_pins(struct snd_soc_jack *jack, int count, struct snd_soc_jack_pin *pins); @@ -659,7 +661,7 @@ struct snd_soc_jack_gpio { struct snd_soc_jack { struct mutex mutex; struct snd_jack *jack; - struct snd_soc_codec *codec; + struct snd_soc_card *card; struct list_head pins; int status; struct blocking_notifier_head notifier; @@ -1482,6 +1484,26 @@ static inline struct snd_soc_platform *snd_soc_kcontrol_platform( return snd_soc_component_to_platform(snd_soc_kcontrol_component(kcontrol)); } +/** + * snd_soc_jack_new - Create a new jack + * @codec: ASoC CODEC + * @id: an identifying string for this jack + * @type: a bitmask of enum snd_jack_type values that can be detected by + * this jack + * @jack: structure to use for the jack + * + * Creates a new jack object. + * + * Returns zero if successful, or a negative error code on failure. + * On success jack will be initialised. + */ +static inline int snd_soc_jack_new(struct snd_soc_codec *codec, const char *id, + int type, struct snd_soc_jack *jack) +{ + return snd_soc_card_jack_new(codec->component.card, id, type, jack, + NULL, 0); +} + int snd_soc_util_init(void); void snd_soc_util_exit(void); diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c index 4380dcc064a5..9f60c25c4568 100644 --- a/sound/soc/soc-jack.c +++ b/sound/soc/soc-jack.c @@ -22,30 +22,42 @@ #include /** - * snd_soc_jack_new - Create a new jack - * @codec: ASoC codec + * snd_soc_card_jack_new - Create a new jack + * @card: ASoC card * @id: an identifying string for this jack * @type: a bitmask of enum snd_jack_type values that can be detected by * this jack * @jack: structure to use for the jack + * @pins: Array of jack pins to be added to the jack or NULL + * @num_pins: Number of elements in the @pins array * * Creates a new jack object. * * Returns zero if successful, or a negative error code on failure. * On success jack will be initialised. */ -int snd_soc_jack_new(struct snd_soc_codec *codec, const char *id, int type, - struct snd_soc_jack *jack) +int snd_soc_card_jack_new(struct snd_soc_card *card, const char *id, int type, + struct snd_soc_jack *jack, struct snd_soc_jack_pin *pins, + unsigned int num_pins) { + int ret; + mutex_init(&jack->mutex); - jack->codec = codec; + jack->card = card; INIT_LIST_HEAD(&jack->pins); INIT_LIST_HEAD(&jack->jack_zones); BLOCKING_INIT_NOTIFIER_HEAD(&jack->notifier); - return snd_jack_new(codec->component.card->snd_card, id, type, &jack->jack); + ret = snd_jack_new(card->snd_card, id, type, &jack->jack); + if (ret) + return ret; + + if (num_pins) + return snd_soc_jack_add_pins(jack, num_pins, pins); + + return 0; } -EXPORT_SYMBOL_GPL(snd_soc_jack_new); +EXPORT_SYMBOL_GPL(snd_soc_card_jack_new); /** * snd_soc_jack_report - Report the current status for a jack @@ -63,7 +75,6 @@ EXPORT_SYMBOL_GPL(snd_soc_jack_new); */ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask) { - struct snd_soc_codec *codec; struct snd_soc_dapm_context *dapm; struct snd_soc_jack_pin *pin; unsigned int sync = 0; @@ -74,8 +85,7 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask) if (!jack) return; - codec = jack->codec; - dapm = &codec->dapm; + dapm = &jack->card->dapm; mutex_lock(&jack->mutex); @@ -175,12 +185,12 @@ int snd_soc_jack_add_pins(struct snd_soc_jack *jack, int count, for (i = 0; i < count; i++) { if (!pins[i].pin) { - dev_err(jack->codec->dev, "ASoC: No name for pin %d\n", + dev_err(jack->card->dev, "ASoC: No name for pin %d\n", i); return -EINVAL; } if (!pins[i].mask) { - dev_err(jack->codec->dev, "ASoC: No mask for pin %d" + dev_err(jack->card->dev, "ASoC: No mask for pin %d" " (%s)\n", i, pins[i].pin); return -EINVAL; } @@ -260,7 +270,7 @@ static void snd_soc_jack_gpio_detect(struct snd_soc_jack_gpio *gpio) static irqreturn_t gpio_handler(int irq, void *data) { struct snd_soc_jack_gpio *gpio = data; - struct device *dev = gpio->jack->codec->component.card->dev; + struct device *dev = gpio->jack->card->dev; trace_snd_soc_jack_irq(gpio->name); @@ -299,7 +309,7 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count, for (i = 0; i < count; i++) { if (!gpios[i].name) { - dev_err(jack->codec->dev, + dev_err(jack->card->dev, "ASoC: No name for gpio at index %d\n", i); ret = -EINVAL; goto undo; @@ -320,7 +330,7 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count, } else { /* legacy GPIO number */ if (!gpio_is_valid(gpios[i].gpio)) { - dev_err(jack->codec->dev, + dev_err(jack->card->dev, "ASoC: Invalid gpio %d\n", gpios[i].gpio); ret = -EINVAL; @@ -350,7 +360,7 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count, if (gpios[i].wake) { ret = irq_set_irq_wake(gpiod_to_irq(gpios[i].desc), 1); if (ret != 0) - dev_err(jack->codec->dev, + dev_err(jack->card->dev, "ASoC: Failed to mark GPIO at index %d as wake source: %d\n", i, ret); } -- GitLab From 386669fcec85a16cb81cd19236abe76abe0f1fc1 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 4 Mar 2015 10:33:18 +0100 Subject: [PATCH 02597/11651] ASoC: simple-card: Register jacks at the card level The jacks are card level elements so use snd_soc_card_jack_new() instead of snd_soc_jack_new() to register them. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/generic/simple-card.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index f7c6734bd5da..b8ee47b7ba9c 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c @@ -176,11 +176,11 @@ static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd) return ret; if (gpio_is_valid(priv->gpio_hp_det)) { - snd_soc_jack_new(codec->codec, "Headphones", SND_JACK_HEADPHONE, - &simple_card_hp_jack); - snd_soc_jack_add_pins(&simple_card_hp_jack, - ARRAY_SIZE(simple_card_hp_jack_pins), - simple_card_hp_jack_pins); + snd_soc_card_jack_new(rtd->card, "Headphones", + SND_JACK_HEADPHONE, + &simple_card_hp_jack, + simple_card_hp_jack_pins, + ARRAY_SIZE(simple_card_hp_jack_pins)); simple_card_hp_jack_gpio.gpio = priv->gpio_hp_det; simple_card_hp_jack_gpio.invert = priv->gpio_hp_det_invert; @@ -189,11 +189,11 @@ static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd) } if (gpio_is_valid(priv->gpio_mic_det)) { - snd_soc_jack_new(codec->codec, "Mic Jack", SND_JACK_MICROPHONE, - &simple_card_mic_jack); - snd_soc_jack_add_pins(&simple_card_mic_jack, - ARRAY_SIZE(simple_card_mic_jack_pins), - simple_card_mic_jack_pins); + snd_soc_card_jack_new(rtd->card, "Mic Jack", + SND_JACK_MICROPHONE, + &simple_card_mic_jack, + simple_card_mic_jack_pins, + ARRAY_SIZE(simple_card_mic_jack_pins)); simple_card_mic_jack_gpio.gpio = priv->gpio_mic_det; simple_card_mic_jack_gpio.invert = priv->gpio_mic_det_invert; snd_soc_jack_add_gpios(&simple_card_mic_jack, 1, -- GitLab From 27cb64b474516421001932d966ca3184795d4e29 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 4 Mar 2015 10:33:19 +0100 Subject: [PATCH 02598/11651] ASoC: imx-es8328: Register jacks at the card level The jacks are card level elements so use snd_soc_card_jack_new() instead of snd_soc_jack_new() to register them. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/fsl/imx-es8328.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/fsl/imx-es8328.c b/sound/soc/fsl/imx-es8328.c index f8cf10e16ce9..20e7400e2611 100644 --- a/sound/soc/fsl/imx-es8328.c +++ b/sound/soc/fsl/imx-es8328.c @@ -53,9 +53,9 @@ static int imx_es8328_dai_init(struct snd_soc_pcm_runtime *rtd) /* Headphone jack detection */ if (gpio_is_valid(data->jack_gpio)) { - ret = snd_soc_jack_new(rtd->codec, "Headphone", - SND_JACK_HEADPHONE | SND_JACK_BTN_0, - &headset_jack); + ret = snd_soc_card_jack_new(rtd->card, "Headphone", + SND_JACK_HEADPHONE | SND_JACK_BTN_0, + &headset_jack, NULL, 0); if (ret) return ret; -- GitLab From 47ec96d4ca7e4a7b9b8b115a10d59e89f794ef95 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 4 Mar 2015 10:33:20 +0100 Subject: [PATCH 02599/11651] ASoC: wm1133-ev: Register jacks at the card level The jacks are card level elements so use snd_soc_card_jack_new() instead of snd_soc_jack_new() to register them. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/fsl/wm1133-ev1.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/sound/soc/fsl/wm1133-ev1.c b/sound/soc/fsl/wm1133-ev1.c index a958937ab405..0653aa83c927 100644 --- a/sound/soc/fsl/wm1133-ev1.c +++ b/sound/soc/fsl/wm1133-ev1.c @@ -205,16 +205,14 @@ static int wm1133_ev1_init(struct snd_soc_pcm_runtime *rtd) struct snd_soc_dapm_context *dapm = &codec->dapm; /* Headphone jack detection */ - snd_soc_jack_new(codec, "Headphone", SND_JACK_HEADPHONE, &hp_jack); - snd_soc_jack_add_pins(&hp_jack, ARRAY_SIZE(hp_jack_pins), - hp_jack_pins); + snd_soc_card_jack_new(rtd->card, "Headphone", SND_JACK_HEADPHONE, + &hp_jack, hp_jack_pins, ARRAY_SIZE(hp_jack_pins)); wm8350_hp_jack_detect(codec, WM8350_JDR, &hp_jack, SND_JACK_HEADPHONE); /* Microphone jack detection */ - snd_soc_jack_new(codec, "Microphone", - SND_JACK_MICROPHONE | SND_JACK_BTN_0, &mic_jack); - snd_soc_jack_add_pins(&mic_jack, ARRAY_SIZE(mic_jack_pins), - mic_jack_pins); + snd_soc_card_jack_new(rtd->card, "Microphone", + SND_JACK_MICROPHONE | SND_JACK_BTN_0, &mic_jack, + mic_jack_pins, ARRAY_SIZE(mic_jack_pins)); wm8350_mic_jack_detect(codec, &mic_jack, SND_JACK_MICROPHONE, SND_JACK_BTN_0); -- GitLab From 85c85e5d6d579a5ff8b5471c4e753946eedbf788 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 4 Mar 2015 10:33:21 +0100 Subject: [PATCH 02600/11651] ASoC: broadwell: Register jacks at the card level The jacks are card level elements so use snd_soc_card_jack_new() instead of snd_soc_jack_new() to register them. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/intel/broadwell.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/sound/soc/intel/broadwell.c b/sound/soc/intel/broadwell.c index 9cf7d01479ad..9effa3da982f 100644 --- a/sound/soc/intel/broadwell.c +++ b/sound/soc/intel/broadwell.c @@ -80,15 +80,9 @@ static int broadwell_rt286_codec_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; int ret = 0; - ret = snd_soc_jack_new(codec, "Headset", - SND_JACK_HEADSET | SND_JACK_BTN_0, &broadwell_headset); - - if (ret) - return ret; - - ret = snd_soc_jack_add_pins(&broadwell_headset, - ARRAY_SIZE(broadwell_headset_pins), - broadwell_headset_pins); + ret = snd_soc_card_jack_new(rtd->card, "Headset", + SND_JACK_HEADSET | SND_JACK_BTN_0, &broadwell_headset, + broadwell_headset_pins, ARRAY_SIZE(broadwell_headset_pins)); if (ret) return ret; -- GitLab From e0f7dd9d88f4c151aeca45d290e171d907249888 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 4 Mar 2015 10:33:22 +0100 Subject: [PATCH 02601/11651] ASoC: byt-max98090: Register jacks at the card level The jacks are card level elements so use snd_soc_card_jack_new() instead of snd_soc_jack_new() to register them. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/intel/byt-max98090.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/sound/soc/intel/byt-max98090.c b/sound/soc/intel/byt-max98090.c index 9832afe7d22c..d8b1f038da1c 100644 --- a/sound/soc/intel/byt-max98090.c +++ b/sound/soc/intel/byt-max98090.c @@ -84,7 +84,6 @@ static struct snd_soc_jack_gpio hs_jack_gpios[] = { static int byt_max98090_init(struct snd_soc_pcm_runtime *runtime) { int ret; - struct snd_soc_codec *codec = runtime->codec; struct snd_soc_card *card = runtime->card; struct byt_max98090_private *drv = snd_soc_card_get_drvdata(card); struct snd_soc_jack *jack = &drv->jack; @@ -100,13 +99,9 @@ static int byt_max98090_init(struct snd_soc_pcm_runtime *runtime) } /* Enable jack detection */ - ret = snd_soc_jack_new(codec, "Headset", - SND_JACK_LINEOUT | SND_JACK_HEADSET, jack); - if (ret) - return ret; - - ret = snd_soc_jack_add_pins(jack, ARRAY_SIZE(hs_jack_pins), - hs_jack_pins); + ret = snd_soc_card_jack_new(runtime->card, "Headset", + SND_JACK_LINEOUT | SND_JACK_HEADSET, jack, + hs_jack_pins, ARRAY_SIZE(hs_jack_pins)); if (ret) return ret; -- GitLab From fb1edb4b68a829619bcd50a0c23c557000d0d638 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 4 Mar 2015 10:33:23 +0100 Subject: [PATCH 02602/11651] ASoC: cht_bsw_rt5645: Register jacks at the card level The jacks are card level elements so use snd_soc_card_jack_new() instead of snd_soc_jack_new() to register them. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/intel/cht_bsw_rt5645.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sound/soc/intel/cht_bsw_rt5645.c b/sound/soc/intel/cht_bsw_rt5645.c index bd29617a9ab9..0bfca2192ca0 100644 --- a/sound/soc/intel/cht_bsw_rt5645.c +++ b/sound/soc/intel/cht_bsw_rt5645.c @@ -169,17 +169,17 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime) return ret; } - ret = snd_soc_jack_new(codec, "Headphone Jack", - SND_JACK_HEADPHONE, - &ctx->hp_jack); + ret = snd_soc_card_jack_new(runtime->card, "Headphone Jack", + SND_JACK_HEADPHONE, &ctx->hp_jack, + NULL, 0); if (ret) { dev_err(runtime->dev, "HP jack creation failed %d\n", ret); return ret; } - ret = snd_soc_jack_new(codec, "Mic Jack", - SND_JACK_MICROPHONE, - &ctx->mic_jack); + ret = snd_soc_card_jack_new(runtime->card, "Mic Jack", + SND_JACK_MICROPHONE, &ctx->mic_jack, + NULL, 0); if (ret) { dev_err(runtime->dev, "Mic jack creation failed %d\n", ret); return ret; -- GitLab From af13cbc1a288d3921f1af739da84371e6c53aea3 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 4 Mar 2015 10:33:24 +0100 Subject: [PATCH 02603/11651] ASoC: mfld_machine: Register jacks at the card level The jacks are card level elements so use snd_soc_card_jack_new() instead of snd_soc_jack_new() to register them. Signed-off-by: Lars-Peter Clausen Acked-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/intel/mfld_machine.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/sound/soc/intel/mfld_machine.c b/sound/soc/intel/mfld_machine.c index d22b44db824e..49c09a0add79 100644 --- a/sound/soc/intel/mfld_machine.c +++ b/sound/soc/intel/mfld_machine.c @@ -255,20 +255,15 @@ static int mfld_init(struct snd_soc_pcm_runtime *runtime) snd_soc_dapm_disable_pin(dapm, "LINEINR"); /* Headset and button jack detection */ - ret_val = snd_soc_jack_new(runtime->codec, "Intel(R) MID Audio Jack", - SND_JACK_HEADSET | SND_JACK_BTN_0 | - SND_JACK_BTN_1, &mfld_jack); + ret_val = snd_soc_card_jack_new(runtime->card, + "Intel(R) MID Audio Jack", SND_JACK_HEADSET | + SND_JACK_BTN_0 | SND_JACK_BTN_1, &mfld_jack, + mfld_jack_pins, ARRAY_SIZE(mfld_jack_pins)); if (ret_val) { pr_err("jack creation failed\n"); return ret_val; } - ret_val = snd_soc_jack_add_pins(&mfld_jack, - ARRAY_SIZE(mfld_jack_pins), mfld_jack_pins); - if (ret_val) { - pr_err("adding jack pins failed\n"); - return ret_val; - } ret_val = snd_soc_jack_add_zones(&mfld_jack, ARRAY_SIZE(mfld_zones), mfld_zones); if (ret_val) { -- GitLab From df8c66189dd42f719c75800a526bdc901f300f41 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 4 Mar 2015 10:33:25 +0100 Subject: [PATCH 02604/11651] ASoC: ams-deltea: Register jacks at the card level The jacks are card level elements so use snd_soc_card_jack_new() instead of snd_soc_jack_new() to register them. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/omap/ams-delta.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/omap/ams-delta.c index 706613077c15..16cc95fa4573 100644 --- a/sound/soc/omap/ams-delta.c +++ b/sound/soc/omap/ams-delta.c @@ -479,8 +479,8 @@ static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd) /* Add hook switch - can be used to control the codec from userspace * even if line discipline fails */ - ret = snd_soc_jack_new(rtd->codec, "hook_switch", - SND_JACK_HEADSET, &ams_delta_hook_switch); + ret = snd_soc_card_jack_new(card, "hook_switch", SND_JACK_HEADSET, + &ams_delta_hook_switch, NULL, 0); if (ret) dev_warn(card->dev, "Failed to allocate resources for hook switch, " -- GitLab From 25649592cfa6c210c9f86670472b864782c8d677 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 4 Mar 2015 10:33:26 +0100 Subject: [PATCH 02605/11651] ASoC: omap-abe-twl6040: Register jacks at the card level The jacks are card level elements so use snd_soc_card_jack_new() instead of snd_soc_jack_new() to register them. Signed-off-by: Lars-Peter Clausen Acked-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/omap/omap-abe-twl6040.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sound/soc/omap/omap-abe-twl6040.c b/sound/soc/omap/omap-abe-twl6040.c index b9c65f1ad5a8..0843a68f277c 100644 --- a/sound/soc/omap/omap-abe-twl6040.c +++ b/sound/soc/omap/omap-abe-twl6040.c @@ -182,17 +182,17 @@ static int omap_abe_twl6040_init(struct snd_soc_pcm_runtime *rtd) /* Headset jack detection only if it is supported */ if (priv->jack_detection) { - ret = snd_soc_jack_new(codec, "Headset Jack", - SND_JACK_HEADSET, &hs_jack); + ret = snd_soc_card_jack_new(rtd->card, "Headset Jack", + SND_JACK_HEADSET, &hs_jack, + hs_jack_pins, + ARRAY_SIZE(hs_jack_pins)); if (ret) return ret; - ret = snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins), - hs_jack_pins); twl6040_hs_jack_detect(codec, &hs_jack, SND_JACK_HEADSET); } - return ret; + return 0; } static const struct snd_soc_dapm_route dmic_audio_map[] = { -- GitLab From da21cf6d65283680247da74c3d03f7e5cdfb40d1 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 4 Mar 2015 10:33:27 +0100 Subject: [PATCH 02606/11651] ASoC: omap-twl4030: Register jacks at the card level The jacks are card level elements so use snd_soc_card_jack_new() instead of snd_soc_jack_new() to register them. Signed-off-by: Lars-Peter Clausen Acked-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/omap/omap-twl4030.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/sound/soc/omap/omap-twl4030.c b/sound/soc/omap/omap-twl4030.c index fb1f6bb87cd4..3673ada43bfb 100644 --- a/sound/soc/omap/omap-twl4030.c +++ b/sound/soc/omap/omap-twl4030.c @@ -170,14 +170,10 @@ static int omap_twl4030_init(struct snd_soc_pcm_runtime *rtd) if (priv->jack_detect > 0) { hs_jack_gpios[0].gpio = priv->jack_detect; - ret = snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET, - &priv->hs_jack); - if (ret) - return ret; - - ret = snd_soc_jack_add_pins(&priv->hs_jack, - ARRAY_SIZE(hs_jack_pins), - hs_jack_pins); + ret = snd_soc_card_jack_new(rtd->card, "Headset Jack", + SND_JACK_HEADSET, &priv->hs_jack, + hs_jack_pins, + ARRAY_SIZE(hs_jack_pins)); if (ret) return ret; -- GitLab From 753d45e6b886c93a2a8a88eddaca345643a87f4e Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 4 Mar 2015 10:33:28 +0100 Subject: [PATCH 02607/11651] ASoC: rx51: Register jacks at the card level The jacks are card level elements so use snd_soc_card_jack_new() instead of snd_soc_jack_new() to register them. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/omap/rx51.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c index 7f299357c2d2..c2ddf0fbfa28 100644 --- a/sound/soc/omap/rx51.c +++ b/sound/soc/omap/rx51.c @@ -311,9 +311,9 @@ static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd) } /* AV jack detection */ - err = snd_soc_jack_new(codec, "AV Jack", - SND_JACK_HEADSET | SND_JACK_VIDEOOUT, - &rx51_av_jack); + err = snd_soc_card_jack_new(rtd->card, "AV Jack", + SND_JACK_HEADSET | SND_JACK_VIDEOOUT, + &rx51_av_jack, NULL, 0); if (err) { dev_err(card->dev, "Failed to add AV Jack\n"); return err; -- GitLab From f7a4433b498384f0e300c51b654910f3e03b5ca6 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 4 Mar 2015 10:33:29 +0100 Subject: [PATCH 02608/11651] ASoC: hx4700: Register jacks at the card level The jacks are card level elements so use snd_soc_card_jack_new() instead of snd_soc_jack_new() to register them. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/pxa/hx4700.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/sound/soc/pxa/hx4700.c b/sound/soc/pxa/hx4700.c index 73eb5ddf9753..9f8be7cd567e 100644 --- a/sound/soc/pxa/hx4700.c +++ b/sound/soc/pxa/hx4700.c @@ -126,17 +126,12 @@ static const struct snd_soc_dapm_route hx4700_audio_map[] = { */ static int hx4700_ak4641_init(struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_codec *codec = rtd->codec; int err; /* Jack detection API stuff */ - err = snd_soc_jack_new(codec, "Headphone Jack", - SND_JACK_HEADPHONE, &hs_jack); - if (err) - return err; - - err = snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pin), - hs_jack_pin); + err = snd_soc_card_jack_new(rtd->card, "Headphone Jack", + SND_JACK_HEADPHONE, &hs_jack, hs_jack_pin, + ARRAY_SIZE(hs_jack_pin)); if (err) return err; -- GitLab From bc1e2e06a07ad4c0c021165b34fa8259bdf4d8c6 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 4 Mar 2015 10:33:30 +0100 Subject: [PATCH 02609/11651] ASoC: palm27x: Register jacks at the card level The jacks are card level elements so use snd_soc_card_jack_new() instead of snd_soc_jack_new() to register them. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/pxa/palm27x.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/sound/soc/pxa/palm27x.c b/sound/soc/pxa/palm27x.c index 910336c5ebeb..c20bbc042425 100644 --- a/sound/soc/pxa/palm27x.c +++ b/sound/soc/pxa/palm27x.c @@ -75,17 +75,12 @@ static struct snd_soc_card palm27x_asoc; static int palm27x_ac97_init(struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_codec *codec = rtd->codec; int err; /* Jack detection API stuff */ - err = snd_soc_jack_new(codec, "Headphone Jack", - SND_JACK_HEADPHONE, &hs_jack); - if (err) - return err; - - err = snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins), - hs_jack_pins); + err = snd_soc_card_jack_new(rtd->card, "Headphone Jack", + SND_JACK_HEADPHONE, &hs_jack, hs_jack_pins, + ARRAY_SIZE(hs_jack_pins)); if (err) return err; -- GitLab From 3b14125bc553a0fe091a5d43a22be41cdc43b156 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 4 Mar 2015 10:33:31 +0100 Subject: [PATCH 02610/11651] ASoC: ttc-dkb: Register jacks at the card level The jacks are card level elements so use snd_soc_card_jack_new() instead of snd_soc_jack_new() to register them. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/pxa/ttc-dkb.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/sound/soc/pxa/ttc-dkb.c b/sound/soc/pxa/ttc-dkb.c index 5001dbb9b257..1753c7d9e760 100644 --- a/sound/soc/pxa/ttc-dkb.c +++ b/sound/soc/pxa/ttc-dkb.c @@ -78,15 +78,12 @@ static int ttc_pm860x_init(struct snd_soc_pcm_runtime *rtd) struct snd_soc_codec *codec = rtd->codec; /* Headset jack detection */ - snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE - | SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2, - &hs_jack); - snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins), - hs_jack_pins); - snd_soc_jack_new(codec, "Microphone Jack", SND_JACK_MICROPHONE, - &mic_jack); - snd_soc_jack_add_pins(&mic_jack, ARRAY_SIZE(mic_jack_pins), - mic_jack_pins); + snd_soc_card_jack_new(rtd->card, "Headphone Jack", SND_JACK_HEADPHONE | + SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2, + &hs_jack, hs_jack_pins, ARRAY_SIZE(hs_jack_pins)); + snd_soc_card_jack_new(rtd->card, "Microphone Jack", SND_JACK_MICROPHONE, + &mic_jack, mic_jack_pins, + ARRAY_SIZE(mic_jack_pins)); /* headphone, microphone detection & headset short detection */ pm860x_hs_jack_detect(codec, &hs_jack, SND_JACK_HEADPHONE, -- GitLab From d30d141f9cb7eb9fb3f03af11146dc0d2b393ff2 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 4 Mar 2015 10:33:32 +0100 Subject: [PATCH 02611/11651] ASoC: z2: Register jacks at the card level The jacks are card level elements so use snd_soc_card_jack_new() instead of snd_soc_jack_new() to register them. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/pxa/z2.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/sound/soc/pxa/z2.c b/sound/soc/pxa/z2.c index 76ccb172d0a7..bcbfbe8303f7 100644 --- a/sound/soc/pxa/z2.c +++ b/sound/soc/pxa/z2.c @@ -143,13 +143,9 @@ static int z2_wm8750_init(struct snd_soc_pcm_runtime *rtd) snd_soc_dapm_disable_pin(dapm, "MONO1"); /* Jack detection API stuff */ - ret = snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET, - &hs_jack); - if (ret) - goto err; - - ret = snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins), - hs_jack_pins); + ret = snd_soc_card_jack_new(rtd->card, "Headset Jack", SND_JACK_HEADSET, + &hs_jack, hs_jack_pins, + ARRAY_SIZE(hs_jack_pins)); if (ret) goto err; -- GitLab From dfe11f282c61808f7140d9dd741f7e54cf97cda6 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 4 Mar 2015 10:33:33 +0100 Subject: [PATCH 02612/11651] ASoC: h1980_uda1380: Register jacks at the card level The jacks are card level elements so use snd_soc_card_jack_new() instead of snd_soc_jack_new() to register them. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/samsung/h1940_uda1380.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/sound/soc/samsung/h1940_uda1380.c b/sound/soc/samsung/h1940_uda1380.c index 59b044255b78..c72e9fb26658 100644 --- a/sound/soc/samsung/h1940_uda1380.c +++ b/sound/soc/samsung/h1940_uda1380.c @@ -162,13 +162,8 @@ static struct platform_device *s3c24xx_snd_device; static int h1940_uda1380_init(struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_codec *codec = rtd->codec; - - snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE, - &hp_jack); - - snd_soc_jack_add_pins(&hp_jack, ARRAY_SIZE(hp_jack_pins), - hp_jack_pins); + snd_soc_card_jack_new(rtd->card, "Headphone Jack", SND_JACK_HEADPHONE, + &hp_jack, hp_jack_pins, ARRAY_SIZE(hp_jack_pins)); snd_soc_jack_add_gpios(&hp_jack, ARRAY_SIZE(hp_jack_gpios), hp_jack_gpios); -- GitLab From 39ec5109d6089e1acd04b51b9df5349f5b8a7f5c Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 4 Mar 2015 10:33:34 +0100 Subject: [PATCH 02613/11651] ASoC: littlemill: Register jacks at the card level The jacks are card level elements so use snd_soc_card_jack_new() instead of snd_soc_jack_new() to register them. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/samsung/littlemill.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sound/soc/samsung/littlemill.c b/sound/soc/samsung/littlemill.c index 141519c21e21..31a820eb0ac3 100644 --- a/sound/soc/samsung/littlemill.c +++ b/sound/soc/samsung/littlemill.c @@ -260,12 +260,12 @@ static int littlemill_late_probe(struct snd_soc_card *card) if (ret < 0) return ret; - ret = snd_soc_jack_new(codec, "Headset", - SND_JACK_HEADSET | SND_JACK_MECHANICAL | - SND_JACK_BTN_0 | SND_JACK_BTN_1 | - SND_JACK_BTN_2 | SND_JACK_BTN_3 | - SND_JACK_BTN_4 | SND_JACK_BTN_5, - &littlemill_headset); + ret = snd_soc_card_jack_new(card, "Headset", + SND_JACK_HEADSET | SND_JACK_MECHANICAL | + SND_JACK_BTN_0 | SND_JACK_BTN_1 | + SND_JACK_BTN_2 | SND_JACK_BTN_3 | + SND_JACK_BTN_4 | SND_JACK_BTN_5, + &littlemill_headset, NULL, 0); if (ret) return ret; -- GitLab From f97e0eacf2b5d9c1a470e53df60519d555ac5a75 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 4 Mar 2015 10:33:35 +0100 Subject: [PATCH 02614/11651] ASoC: lowland: Register jacks at the card level The jacks are card level elements so use snd_soc_card_jack_new() instead of snd_soc_jack_new() to register them. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/samsung/lowland.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/sound/soc/samsung/lowland.c b/sound/soc/samsung/lowland.c index 243dea7ba38f..5f156093101e 100644 --- a/sound/soc/samsung/lowland.c +++ b/sound/soc/samsung/lowland.c @@ -56,16 +56,10 @@ static int lowland_wm5100_init(struct snd_soc_pcm_runtime *rtd) return ret; } - ret = snd_soc_jack_new(codec, "Headset", - SND_JACK_LINEOUT | SND_JACK_HEADSET | - SND_JACK_BTN_0, - &lowland_headset); - if (ret) - return ret; - - ret = snd_soc_jack_add_pins(&lowland_headset, - ARRAY_SIZE(lowland_headset_pins), - lowland_headset_pins); + ret = snd_soc_card_jack_new(rtd->card, "Headset", SND_JACK_LINEOUT | + SND_JACK_HEADSET | SND_JACK_BTN_0, + &lowland_headset, lowland_headset_pins, + ARRAY_SIZE(lowland_headset_pins)); if (ret) return ret; -- GitLab From e9c9a723eea5102fa6adedf454e02fff6201a3c3 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 4 Mar 2015 10:33:36 +0100 Subject: [PATCH 02615/11651] ASoC: rx1950_uda1380: Register jacks at the card level The jacks are card level elements so use snd_soc_card_jack_new() instead of snd_soc_jack_new() to register them. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/samsung/rx1950_uda1380.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/sound/soc/samsung/rx1950_uda1380.c b/sound/soc/samsung/rx1950_uda1380.c index 873f2cb4bebe..35e37c457f1f 100644 --- a/sound/soc/samsung/rx1950_uda1380.c +++ b/sound/soc/samsung/rx1950_uda1380.c @@ -211,13 +211,8 @@ static int rx1950_hw_params(struct snd_pcm_substream *substream, static int rx1950_uda1380_init(struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_codec *codec = rtd->codec; - - snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE, - &hp_jack); - - snd_soc_jack_add_pins(&hp_jack, ARRAY_SIZE(hp_jack_pins), - hp_jack_pins); + snd_soc_card_jack_new(rtd->card, "Headphone Jack", SND_JACK_HEADPHONE, + &hp_jack, hp_jack_pins, ARRAY_SIZE(hp_jack_pins)); snd_soc_jack_add_gpios(&hp_jack, ARRAY_SIZE(hp_jack_gpios), hp_jack_gpios); -- GitLab From 55b2ed2d9dd8c611837f34ca29df881eb0a1de8d Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 4 Mar 2015 10:33:37 +0100 Subject: [PATCH 02616/11651] ASoC: smartq: Register jacks at the card level The jacks are card level elements so use snd_soc_card_jack_new() instead of snd_soc_jack_new() to register them. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/samsung/smartq_wm8987.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/sound/soc/samsung/smartq_wm8987.c b/sound/soc/samsung/smartq_wm8987.c index 8291d2a5f152..dfbe2db1c407 100644 --- a/sound/soc/samsung/smartq_wm8987.c +++ b/sound/soc/samsung/smartq_wm8987.c @@ -151,13 +151,10 @@ static int smartq_wm8987_init(struct snd_soc_pcm_runtime *rtd) snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); /* Headphone jack detection */ - err = snd_soc_jack_new(codec, "Headphone Jack", - SND_JACK_HEADPHONE, &smartq_jack); - if (err) - return err; - - err = snd_soc_jack_add_pins(&smartq_jack, ARRAY_SIZE(smartq_jack_pins), - smartq_jack_pins); + err = snd_soc_card_jack_new(rtd->card, "Headphone Jack", + SND_JACK_HEADPHONE, &smartq_jack, + smartq_jack_pins, + ARRAY_SIZE(smartq_jack_pins)); if (err) return err; -- GitLab From 663976ad478b50664353fdf19a5a3dcad3cb4e22 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 4 Mar 2015 10:33:38 +0100 Subject: [PATCH 02617/11651] ASoC: speyside: Register jacks at the card level The jacks are card level elements so use snd_soc_card_jack_new() instead of snd_soc_jack_new() to register them. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/samsung/speyside.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/sound/soc/samsung/speyside.c b/sound/soc/samsung/speyside.c index 5ec7c52282f2..2dcb988bdff2 100644 --- a/sound/soc/samsung/speyside.c +++ b/sound/soc/samsung/speyside.c @@ -153,16 +153,10 @@ static int speyside_wm8996_init(struct snd_soc_pcm_runtime *rtd) pr_err("Failed to request HP_SEL GPIO: %d\n", ret); gpio_direction_output(WM8996_HPSEL_GPIO, speyside_jack_polarity); - ret = snd_soc_jack_new(codec, "Headset", - SND_JACK_LINEOUT | SND_JACK_HEADSET | - SND_JACK_BTN_0, - &speyside_headset); - if (ret) - return ret; - - ret = snd_soc_jack_add_pins(&speyside_headset, - ARRAY_SIZE(speyside_headset_pins), - speyside_headset_pins); + ret = snd_soc_card_jack_new(rtd->card, "Headset", SND_JACK_LINEOUT | + SND_JACK_HEADSET | SND_JACK_BTN_0, + &speyside_headset, speyside_headset_pins, + ARRAY_SIZE(speyside_headset_pins)); if (ret) return ret; -- GitLab From 3fd94f37da000a2b562a3f4e6c553b7ab1ad9e19 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 4 Mar 2015 10:33:39 +0100 Subject: [PATCH 02618/11651] ASoC: tobermory: Register jacks at the card level The jacks are card level elements so use snd_soc_card_jack_new() instead of snd_soc_jack_new() to register them. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/samsung/tobermory.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/sound/soc/samsung/tobermory.c b/sound/soc/samsung/tobermory.c index 9c80506527c4..85ccfb7188cb 100644 --- a/sound/soc/samsung/tobermory.c +++ b/sound/soc/samsung/tobermory.c @@ -179,15 +179,10 @@ static int tobermory_late_probe(struct snd_soc_card *card) if (ret < 0) return ret; - ret = snd_soc_jack_new(codec, "Headset", - SND_JACK_HEADSET | SND_JACK_BTN_0, - &tobermory_headset); - if (ret) - return ret; - - ret = snd_soc_jack_add_pins(&tobermory_headset, - ARRAY_SIZE(tobermory_headset_pins), - tobermory_headset_pins); + ret = snd_soc_card_jack_new(card, "Headset", SND_JACK_HEADSET | + SND_JACK_BTN_0, &tobermory_headset, + tobermory_headset_pins, + ARRAY_SIZE(tobermory_headset_pins)); if (ret) return ret; -- GitLab From 12cc6d1dca4d3a9e929090cb0cf9ef452f414518 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 4 Mar 2015 10:33:40 +0100 Subject: [PATCH 02619/11651] ASoC: tegra_alc5632: Register jacks at the card level The jacks are card level elements so use snd_soc_card_jack_new() instead of snd_soc_jack_new() to register them. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/tegra/tegra_alc5632.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/sound/soc/tegra/tegra_alc5632.c b/sound/soc/tegra/tegra_alc5632.c index 769aca2fc5f5..6dcd06a966c7 100644 --- a/sound/soc/tegra/tegra_alc5632.c +++ b/sound/soc/tegra/tegra_alc5632.c @@ -106,11 +106,10 @@ static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd) struct snd_soc_dapm_context *dapm = &codec->dapm; struct tegra_alc5632 *machine = snd_soc_card_get_drvdata(rtd->card); - snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET, - &tegra_alc5632_hs_jack); - snd_soc_jack_add_pins(&tegra_alc5632_hs_jack, - ARRAY_SIZE(tegra_alc5632_hs_jack_pins), - tegra_alc5632_hs_jack_pins); + snd_soc_card_jack_new(rtd->card, "Headset Jack", SND_JACK_HEADSET, + &tegra_alc5632_hs_jack, + tegra_alc5632_hs_jack_pins, + ARRAY_SIZE(tegra_alc5632_hs_jack_pins)); if (gpio_is_valid(machine->gpio_hp_det)) { tegra_alc5632_hp_jack_gpio.gpio = machine->gpio_hp_det; -- GitLab From d020e77c61b8a9d563d205cfcec7e71090d1377d Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 4 Mar 2015 10:33:41 +0100 Subject: [PATCH 02620/11651] ASoC: tegra_max98090: Register jacks at the card level The jacks are card level elements so use snd_soc_card_jack_new() instead of snd_soc_jack_new() to register them. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/tegra/tegra_max98090.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/sound/soc/tegra/tegra_max98090.c b/sound/soc/tegra/tegra_max98090.c index af3fb997b752..6760f0ebc133 100644 --- a/sound/soc/tegra/tegra_max98090.c +++ b/sound/soc/tegra/tegra_max98090.c @@ -141,16 +141,14 @@ static const struct snd_kcontrol_new tegra_max98090_controls[] = { static int tegra_max98090_asoc_init(struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_codec *codec = codec_dai->codec; struct tegra_max98090 *machine = snd_soc_card_get_drvdata(rtd->card); if (gpio_is_valid(machine->gpio_hp_det)) { - snd_soc_jack_new(codec, "Headphones", SND_JACK_HEADPHONE, - &tegra_max98090_hp_jack); - snd_soc_jack_add_pins(&tegra_max98090_hp_jack, - ARRAY_SIZE(tegra_max98090_hp_jack_pins), - tegra_max98090_hp_jack_pins); + snd_soc_card_jack_new(rtd->card, "Headphones", + SND_JACK_HEADPHONE, + &tegra_max98090_hp_jack, + tegra_max98090_hp_jack_pins, + ARRAY_SIZE(tegra_max98090_hp_jack_pins)); tegra_max98090_hp_jack_gpio.gpio = machine->gpio_hp_det; snd_soc_jack_add_gpios(&tegra_max98090_hp_jack, @@ -159,11 +157,11 @@ static int tegra_max98090_asoc_init(struct snd_soc_pcm_runtime *rtd) } if (gpio_is_valid(machine->gpio_mic_det)) { - snd_soc_jack_new(codec, "Mic Jack", SND_JACK_MICROPHONE, - &tegra_max98090_mic_jack); - snd_soc_jack_add_pins(&tegra_max98090_mic_jack, - ARRAY_SIZE(tegra_max98090_mic_jack_pins), - tegra_max98090_mic_jack_pins); + snd_soc_card_jack_new(rtd->card, "Mic Jack", + SND_JACK_MICROPHONE, + &tegra_max98090_mic_jack, + tegra_max98090_mic_jack_pins, + ARRAY_SIZE(tegra_max98090_mic_jack_pins)); tegra_max98090_mic_jack_gpio.gpio = machine->gpio_mic_det; snd_soc_jack_add_gpios(&tegra_max98090_mic_jack, -- GitLab From 00eafe3b1b191c9b2611b74c03e1b573ae257b1e Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 4 Mar 2015 10:33:42 +0100 Subject: [PATCH 02621/11651] ASoC: tegra_rt5640: Register jacks at the card level The jacks are card level elements so use snd_soc_card_jack_new() instead of snd_soc_jack_new() to register them. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/tegra/tegra_rt5640.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/sound/soc/tegra/tegra_rt5640.c b/sound/soc/tegra/tegra_rt5640.c index ed759a3076b8..773daecaa5e8 100644 --- a/sound/soc/tegra/tegra_rt5640.c +++ b/sound/soc/tegra/tegra_rt5640.c @@ -108,15 +108,11 @@ static const struct snd_kcontrol_new tegra_rt5640_controls[] = { static int tegra_rt5640_asoc_init(struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_codec *codec = codec_dai->codec; struct tegra_rt5640 *machine = snd_soc_card_get_drvdata(rtd->card); - snd_soc_jack_new(codec, "Headphones", SND_JACK_HEADPHONE, - &tegra_rt5640_hp_jack); - snd_soc_jack_add_pins(&tegra_rt5640_hp_jack, - ARRAY_SIZE(tegra_rt5640_hp_jack_pins), - tegra_rt5640_hp_jack_pins); + snd_soc_card_jack_new(rtd->card, "Headphones", SND_JACK_HEADPHONE, + &tegra_rt5640_hp_jack, tegra_rt5640_hp_jack_pins, + ARRAY_SIZE(tegra_rt5640_hp_jack_pins)); if (gpio_is_valid(machine->gpio_hp_det)) { tegra_rt5640_hp_jack_gpio.gpio = machine->gpio_hp_det; -- GitLab From 783b1e7948010ded40eba784b558d86d72ae2ef4 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 4 Mar 2015 10:33:43 +0100 Subject: [PATCH 02622/11651] ASoC: tegra_rt5677: Register jacks at the card level The jacks are card level elements so use snd_soc_card_jack_new() instead of snd_soc_jack_new() to register them. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/tegra/tegra_rt5677.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/sound/soc/tegra/tegra_rt5677.c b/sound/soc/tegra/tegra_rt5677.c index e4cf978a6e3a..68d8b67e79c1 100644 --- a/sound/soc/tegra/tegra_rt5677.c +++ b/sound/soc/tegra/tegra_rt5677.c @@ -146,10 +146,9 @@ static int tegra_rt5677_asoc_init(struct snd_soc_pcm_runtime *rtd) struct snd_soc_dapm_context *dapm = &codec->dapm; struct tegra_rt5677 *machine = snd_soc_card_get_drvdata(rtd->card); - snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE, - &tegra_rt5677_hp_jack); - snd_soc_jack_add_pins(&tegra_rt5677_hp_jack, 1, - &tegra_rt5677_hp_jack_pins); + snd_soc_card_jack_new(rtd->card, "Headphone Jack", SND_JACK_HEADPHONE, + &tegra_rt5677_hp_jack, + &tegra_rt5677_hp_jack_pins, 1); if (gpio_is_valid(machine->gpio_hp_det)) { tegra_rt5677_hp_jack_gpio.gpio = machine->gpio_hp_det; @@ -158,10 +157,9 @@ static int tegra_rt5677_asoc_init(struct snd_soc_pcm_runtime *rtd) } - snd_soc_jack_new(codec, "Mic Jack", SND_JACK_MICROPHONE, - &tegra_rt5677_mic_jack); - snd_soc_jack_add_pins(&tegra_rt5677_mic_jack, 1, - &tegra_rt5677_mic_jack_pins); + snd_soc_card_jack_new(rtd->card, "Mic Jack", SND_JACK_MICROPHONE, + &tegra_rt5677_mic_jack, + &tegra_rt5677_mic_jack_pins, 1); if (gpio_is_valid(machine->gpio_mic_present)) { tegra_rt5677_mic_jack_gpio.gpio = machine->gpio_mic_present; -- GitLab From 7ba8cbb2f0fd9ff232fa19159e2646bf64135126 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 4 Mar 2015 10:33:44 +0100 Subject: [PATCH 02623/11651] ASoC: tegra_wm8903: Register jacks at the card level The jacks are card level elements so use snd_soc_card_jack_new() instead of snd_soc_jack_new() to register them. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/tegra/tegra_wm8903.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c index e52420dae2b4..4a95b70f0cf0 100644 --- a/sound/soc/tegra/tegra_wm8903.c +++ b/sound/soc/tegra/tegra_wm8903.c @@ -177,21 +177,19 @@ static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd) if (gpio_is_valid(machine->gpio_hp_det)) { tegra_wm8903_hp_jack_gpio.gpio = machine->gpio_hp_det; - snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE, - &tegra_wm8903_hp_jack); - snd_soc_jack_add_pins(&tegra_wm8903_hp_jack, - ARRAY_SIZE(tegra_wm8903_hp_jack_pins), - tegra_wm8903_hp_jack_pins); + snd_soc_card_jack_new(rtd->card, "Headphone Jack", + SND_JACK_HEADPHONE, &tegra_wm8903_hp_jack, + tegra_wm8903_hp_jack_pins, + ARRAY_SIZE(tegra_wm8903_hp_jack_pins)); snd_soc_jack_add_gpios(&tegra_wm8903_hp_jack, 1, &tegra_wm8903_hp_jack_gpio); } - snd_soc_jack_new(codec, "Mic Jack", SND_JACK_MICROPHONE, - &tegra_wm8903_mic_jack); - snd_soc_jack_add_pins(&tegra_wm8903_mic_jack, - ARRAY_SIZE(tegra_wm8903_mic_jack_pins), - tegra_wm8903_mic_jack_pins); + snd_soc_card_jack_new(rtd->card, "Mic Jack", SND_JACK_MICROPHONE, + &tegra_wm8903_mic_jack, + tegra_wm8903_mic_jack_pins, + ARRAY_SIZE(tegra_wm8903_mic_jack_pins)); wm8903_mic_detect(codec, &tegra_wm8903_mic_jack, SND_JACK_MICROPHONE, 0); -- GitLab From 77c71765ef78f87dd901fcb4c751908e835a3b2e Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 4 Mar 2015 10:33:45 +0100 Subject: [PATCH 02624/11651] ASoC: Remove snd_soc_jack_new() There are no users of snd_soc_jack_new() left and new users should use snd_soc_card_jack_new() instead. So remove the function. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- include/sound/soc.h | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index 99d9ce272209..40b3ee96f317 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -1484,26 +1484,6 @@ static inline struct snd_soc_platform *snd_soc_kcontrol_platform( return snd_soc_component_to_platform(snd_soc_kcontrol_component(kcontrol)); } -/** - * snd_soc_jack_new - Create a new jack - * @codec: ASoC CODEC - * @id: an identifying string for this jack - * @type: a bitmask of enum snd_jack_type values that can be detected by - * this jack - * @jack: structure to use for the jack - * - * Creates a new jack object. - * - * Returns zero if successful, or a negative error code on failure. - * On success jack will be initialised. - */ -static inline int snd_soc_jack_new(struct snd_soc_codec *codec, const char *id, - int type, struct snd_soc_jack *jack) -{ - return snd_soc_card_jack_new(codec->component.card, id, type, jack, - NULL, 0); -} - int snd_soc_util_init(void); void snd_soc_util_exit(void); -- GitLab From d51199a83a2cf82a291d19ee852c44caa511427d Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 3 Mar 2015 13:38:14 +0200 Subject: [PATCH 02625/11651] ASoC: omap-pcm: Correct dma mask DMA_BIT_MASK of 64 is not valid dma address mask for OMAPs, it should be set to 32. The 64 was introduced by commit (in 2009): a152ff24b978 ASoC: OMAP: Make DMA 64 aligned But the dma_mask and coherent_dma_mask can not be used to specify alignment. Fixes: a152ff24b978 (ASoC: OMAP: Make DMA 64 aligned) Reported-by: Grygorii Strashko Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- sound/soc/omap/omap-pcm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c index f4b05bc23e4b..1343ecbf0bd5 100644 --- a/sound/soc/omap/omap-pcm.c +++ b/sound/soc/omap/omap-pcm.c @@ -201,7 +201,7 @@ static int omap_pcm_new(struct snd_soc_pcm_runtime *rtd) struct snd_pcm *pcm = rtd->pcm; int ret; - ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(64)); + ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(32)); if (ret) return ret; -- GitLab From 4c03a5ebc7f75e98b32591d1d2c6758c811dcbef Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 3 Mar 2015 16:45:17 +0200 Subject: [PATCH 02626/11651] ASoC: davinci: Select SND_EDMA_SOC when SND_DAVINCI_SOC is enabled edma-pcm going to replace davinci-pcm as platform driver for daVinci platform. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/davinci/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/davinci/Kconfig b/sound/soc/davinci/Kconfig index 2b81ca418d2a..eae4e229f341 100644 --- a/sound/soc/davinci/Kconfig +++ b/sound/soc/davinci/Kconfig @@ -1,10 +1,11 @@ config SND_DAVINCI_SOC tristate "SoC Audio for TI DAVINCI" depends on ARCH_DAVINCI + select SND_EDMA_SOC config SND_EDMA_SOC tristate "SoC Audio for Texas Instruments chips using eDMA (AM33XX/43XX)" - depends on SOC_AM33XX || SOC_AM43XX + depends on SOC_AM33XX || SOC_AM43XX || ARCH_DAVINCI select SND_SOC_GENERIC_DMAENGINE_PCM help Say Y or M here if you want audio support for TI SoC which uses eDMA. -- GitLab From 257ade78b6019cf1570c1239894a7a6a549768e1 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 3 Mar 2015 16:45:18 +0200 Subject: [PATCH 02627/11651] ASoC: davinci-i2s: Convert to use edma-pcm The edma-pcm can replace the old davinci-pcm as platform driver. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/davinci/davinci-i2s.c | 67 +++++++++++++-------------------- 1 file changed, 26 insertions(+), 41 deletions(-) diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c index 15fb28fc8e1b..56cb4d95637d 100644 --- a/sound/soc/davinci/davinci-i2s.c +++ b/sound/soc/davinci/davinci-i2s.c @@ -23,8 +23,9 @@ #include #include #include +#include -#include "davinci-pcm.h" +#include "edma-pcm.h" #include "davinci-i2s.h" @@ -122,7 +123,8 @@ static const unsigned char double_fmt[SNDRV_PCM_FORMAT_S32_LE + 1] = { struct davinci_mcbsp_dev { struct device *dev; - struct davinci_pcm_dma_params dma_params[2]; + struct snd_dmaengine_dai_dma_data dma_data[2]; + int dma_request[2]; void __iomem *base; #define MOD_DSP_A 0 #define MOD_DSP_B 1 @@ -419,8 +421,6 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(dai); - struct davinci_pcm_dma_params *dma_params = - &dev->dma_params[substream->stream]; struct snd_interval *i = NULL; int mcbsp_word_length, master; unsigned int rcr, xcr, srgr, clk_div, freq, framesize; @@ -532,8 +532,6 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream, return -EINVAL; } } - dma_params->acnt = dma_params->data_type = data_type[fmt]; - dma_params->fifo_level = 0; mcbsp_word_length = asp_word_length[fmt]; switch (master) { @@ -600,15 +598,6 @@ static int davinci_i2s_trigger(struct snd_pcm_substream *substream, int cmd, return ret; } -static int davinci_i2s_startup(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(dai); - - snd_soc_dai_set_dma_data(dai, substream, dev->dma_params); - return 0; -} - static void davinci_i2s_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { @@ -620,7 +609,6 @@ static void davinci_i2s_shutdown(struct snd_pcm_substream *substream, #define DAVINCI_I2S_RATES SNDRV_PCM_RATE_8000_96000 static const struct snd_soc_dai_ops davinci_i2s_dai_ops = { - .startup = davinci_i2s_startup, .shutdown = davinci_i2s_shutdown, .prepare = davinci_i2s_prepare, .trigger = davinci_i2s_trigger, @@ -630,7 +618,18 @@ static const struct snd_soc_dai_ops davinci_i2s_dai_ops = { }; +static int davinci_i2s_dai_probe(struct snd_soc_dai *dai) +{ + struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(dai); + + dai->playback_dma_data = &dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK]; + dai->capture_dma_data = &dev->dma_data[SNDRV_PCM_STREAM_CAPTURE]; + + return 0; +} + static struct snd_soc_dai_driver davinci_i2s_dai = { + .probe = davinci_i2s_dai_probe, .playback = { .channels_min = 2, .channels_max = 2, @@ -651,11 +650,9 @@ static const struct snd_soc_component_driver davinci_i2s_component = { static int davinci_i2s_probe(struct platform_device *pdev) { - struct snd_platform_data *pdata = pdev->dev.platform_data; struct davinci_mcbsp_dev *dev; struct resource *mem, *ioarea, *res; - enum dma_event_q asp_chan_q = EVENTQ_0; - enum dma_event_q ram_chan_q = EVENTQ_1; + int *dma; int ret; mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -676,22 +673,6 @@ static int davinci_i2s_probe(struct platform_device *pdev) GFP_KERNEL); if (!dev) return -ENOMEM; - if (pdata) { - dev->enable_channel_combine = pdata->enable_channel_combine; - dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].sram_size = - pdata->sram_size_playback; - dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].sram_size = - pdata->sram_size_capture; - dev->clk_input_pin = pdata->clk_input_pin; - dev->i2s_accurate_sck = pdata->i2s_accurate_sck; - asp_chan_q = pdata->asp_chan_q; - ram_chan_q = pdata->ram_chan_q; - } - - dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].asp_chan_q = asp_chan_q; - dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].ram_chan_q = ram_chan_q; - dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].asp_chan_q = asp_chan_q; - dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].ram_chan_q = ram_chan_q; dev->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(dev->clk)) @@ -705,10 +686,10 @@ static int davinci_i2s_probe(struct platform_device *pdev) goto err_release_clk; } - dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].dma_addr = + dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr = (dma_addr_t)(mem->start + DAVINCI_MCBSP_DXR_REG); - dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].dma_addr = + dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].addr = (dma_addr_t)(mem->start + DAVINCI_MCBSP_DRR_REG); /* first TX, then RX */ @@ -718,7 +699,9 @@ static int davinci_i2s_probe(struct platform_device *pdev) ret = -ENXIO; goto err_release_clk; } - dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].channel = res->start; + dma = &dev->dma_request[SNDRV_PCM_STREAM_PLAYBACK]; + *dma = res->start; + dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].filter_data = dma; res = platform_get_resource(pdev, IORESOURCE_DMA, 1); if (!res) { @@ -726,9 +709,11 @@ static int davinci_i2s_probe(struct platform_device *pdev) ret = -ENXIO; goto err_release_clk; } - dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].channel = res->start; - dev->dev = &pdev->dev; + dma = &dev->dma_request[SNDRV_PCM_STREAM_CAPTURE]; + *dma = res->start; + dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].filter_data = dma; + dev->dev = &pdev->dev; dev_set_drvdata(&pdev->dev, dev); ret = snd_soc_register_component(&pdev->dev, &davinci_i2s_component, @@ -736,7 +721,7 @@ static int davinci_i2s_probe(struct platform_device *pdev) if (ret != 0) goto err_release_clk; - ret = davinci_soc_platform_register(&pdev->dev); + ret = edma_pcm_platform_register(&pdev->dev); if (ret) { dev_err(&pdev->dev, "register PCM failed: %d\n", ret); goto err_unregister_component; -- GitLab From 62731d33c41d95914a0a796f319924e22e7ea411 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 3 Mar 2015 16:45:19 +0200 Subject: [PATCH 02628/11651] ASoC: davinci-vcif: Convert to use edma-pcm The edma-pcm can replace the old davinci-pcm as platform driver. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/davinci/davinci-vcif.c | 55 ++++++++++++++------------------ 1 file changed, 24 insertions(+), 31 deletions(-) diff --git a/sound/soc/davinci/davinci-vcif.c b/sound/soc/davinci/davinci-vcif.c index 5bee04279ebe..fabd05f24aeb 100644 --- a/sound/soc/davinci/davinci-vcif.c +++ b/sound/soc/davinci/davinci-vcif.c @@ -33,8 +33,9 @@ #include #include #include +#include -#include "davinci-pcm.h" +#include "edma-pcm.h" #include "davinci-i2s.h" #define MOD_REG_BIT(val, mask, set) do { \ @@ -47,7 +48,8 @@ struct davinci_vcif_dev { struct davinci_vc *davinci_vc; - struct davinci_pcm_dma_params dma_params[2]; + struct snd_dmaengine_dai_dma_data dma_data[2]; + int dma_request[2]; }; static void davinci_vcif_start(struct snd_pcm_substream *substream) @@ -93,8 +95,6 @@ static int davinci_vcif_hw_params(struct snd_pcm_substream *substream, { struct davinci_vcif_dev *davinci_vcif_dev = snd_soc_dai_get_drvdata(dai); struct davinci_vc *davinci_vc = davinci_vcif_dev->davinci_vc; - struct davinci_pcm_dma_params *dma_params = - &davinci_vcif_dev->dma_params[substream->stream]; u32 w; /* Restart the codec before setup */ @@ -113,16 +113,12 @@ static int davinci_vcif_hw_params(struct snd_pcm_substream *substream, /* Determine xfer data type */ switch (params_format(params)) { case SNDRV_PCM_FORMAT_U8: - dma_params->data_type = 0; - MOD_REG_BIT(w, DAVINCI_VC_CTRL_RD_BITS_8 | DAVINCI_VC_CTRL_RD_UNSIGNED | DAVINCI_VC_CTRL_WD_BITS_8 | DAVINCI_VC_CTRL_WD_UNSIGNED, 1); break; case SNDRV_PCM_FORMAT_S8: - dma_params->data_type = 1; - MOD_REG_BIT(w, DAVINCI_VC_CTRL_RD_BITS_8 | DAVINCI_VC_CTRL_WD_BITS_8, 1); @@ -130,8 +126,6 @@ static int davinci_vcif_hw_params(struct snd_pcm_substream *substream, DAVINCI_VC_CTRL_WD_UNSIGNED, 0); break; case SNDRV_PCM_FORMAT_S16_LE: - dma_params->data_type = 2; - MOD_REG_BIT(w, DAVINCI_VC_CTRL_RD_BITS_8 | DAVINCI_VC_CTRL_RD_UNSIGNED | DAVINCI_VC_CTRL_WD_BITS_8 | @@ -142,8 +136,6 @@ static int davinci_vcif_hw_params(struct snd_pcm_substream *substream, return -EINVAL; } - dma_params->acnt = dma_params->data_type; - writel(w, davinci_vc->base + DAVINCI_VC_CTRL); return 0; @@ -172,24 +164,25 @@ static int davinci_vcif_trigger(struct snd_pcm_substream *substream, int cmd, return ret; } -static int davinci_vcif_startup(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct davinci_vcif_dev *dev = snd_soc_dai_get_drvdata(dai); - - snd_soc_dai_set_dma_data(dai, substream, dev->dma_params); - return 0; -} - #define DAVINCI_VCIF_RATES SNDRV_PCM_RATE_8000_48000 static const struct snd_soc_dai_ops davinci_vcif_dai_ops = { - .startup = davinci_vcif_startup, .trigger = davinci_vcif_trigger, .hw_params = davinci_vcif_hw_params, }; +static int davinci_vcif_dai_probe(struct snd_soc_dai *dai) +{ + struct davinci_vcif_dev *dev = snd_soc_dai_get_drvdata(dai); + + dai->playback_dma_data = &dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK]; + dai->capture_dma_data = &dev->dma_data[SNDRV_PCM_STREAM_CAPTURE]; + + return 0; +} + static struct snd_soc_dai_driver davinci_vcif_dai = { + .probe = davinci_vcif_dai_probe, .playback = { .channels_min = 1, .channels_max = 2, @@ -225,16 +218,16 @@ static int davinci_vcif_probe(struct platform_device *pdev) /* DMA tx params */ davinci_vcif_dev->davinci_vc = davinci_vc; - davinci_vcif_dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].channel = - davinci_vc->davinci_vcif.dma_tx_channel; - davinci_vcif_dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].dma_addr = - davinci_vc->davinci_vcif.dma_tx_addr; + davinci_vcif_dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].filter_data = + &davinci_vc->davinci_vcif.dma_tx_channel; + davinci_vcif_dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr = + davinci_vc->davinci_vcif.dma_tx_addr; /* DMA rx params */ - davinci_vcif_dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].channel = - davinci_vc->davinci_vcif.dma_rx_channel; - davinci_vcif_dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].dma_addr = - davinci_vc->davinci_vcif.dma_rx_addr; + davinci_vcif_dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].filter_data = + &davinci_vc->davinci_vcif.dma_rx_channel; + davinci_vcif_dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].addr = + davinci_vc->davinci_vcif.dma_rx_addr; dev_set_drvdata(&pdev->dev, davinci_vcif_dev); @@ -245,7 +238,7 @@ static int davinci_vcif_probe(struct platform_device *pdev) return ret; } - ret = davinci_soc_platform_register(&pdev->dev); + ret = edma_pcm_platform_register(&pdev->dev); if (ret) { dev_err(&pdev->dev, "register PCM failed: %d\n", ret); snd_soc_unregister_component(&pdev->dev); -- GitLab From 9759e7ef53138c5ab46ea516ad08977eb5770393 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 3 Mar 2015 16:45:20 +0200 Subject: [PATCH 02629/11651] ASoC: davinci-mcasp: Deprecate the use of davinci-pcm in favor of edma-pcm The edma-pcm performs as good as the old davinci-pcm and it's use does not require the 'ping-pong' mode of davinci-pcm, which was introduced to overcome under/over flow issues when using davinci-pcm. Keep the SND_DAVINCI_SOC config option to select the SND_EDMA_SOC to avoid regression in audio support. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/davinci/Kconfig | 15 +++--- sound/soc/davinci/davinci-mcasp.c | 87 +++++++------------------------ 2 files changed, 27 insertions(+), 75 deletions(-) diff --git a/sound/soc/davinci/Kconfig b/sound/soc/davinci/Kconfig index eae4e229f341..3736d9aabc56 100644 --- a/sound/soc/davinci/Kconfig +++ b/sound/soc/davinci/Kconfig @@ -1,15 +1,16 @@ config SND_DAVINCI_SOC - tristate "SoC Audio for TI DAVINCI" + tristate depends on ARCH_DAVINCI select SND_EDMA_SOC config SND_EDMA_SOC - tristate "SoC Audio for Texas Instruments chips using eDMA (AM33XX/43XX)" + tristate "SoC Audio for Texas Instruments chips using eDMA" depends on SOC_AM33XX || SOC_AM43XX || ARCH_DAVINCI select SND_SOC_GENERIC_DMAENGINE_PCM help Say Y or M here if you want audio support for TI SoC which uses eDMA. The following line of SoCs are supported by this platform driver: + - daVinci devices - AM335x - AM437x/AM438x @@ -18,7 +19,7 @@ config SND_DAVINCI_SOC_I2S config SND_DAVINCI_SOC_MCASP tristate "Multichannel Audio Serial Port (McASP) support" - depends on SND_DAVINCI_SOC || SND_OMAP_SOC || SND_EDMA_SOC + depends on SND_OMAP_SOC || SND_EDMA_SOC help Say Y or M here if you want to have support for McASP IP found in various Texas Instruments SoCs like: @@ -46,7 +47,7 @@ config SND_AM33XX_SOC_EVM config SND_DAVINCI_SOC_EVM tristate "SoC Audio support for DaVinci DM6446, DM355 or DM365 EVM" - depends on SND_DAVINCI_SOC && I2C + depends on SND_EDMA_SOC && I2C depends on MACH_DAVINCI_EVM || MACH_DAVINCI_DM355_EVM || MACH_DAVINCI_DM365_EVM select SND_DAVINCI_SOC_GENERIC_EVM help @@ -74,7 +75,7 @@ endchoice config SND_DM6467_SOC_EVM tristate "SoC Audio support for DaVinci DM6467 EVM" - depends on SND_DAVINCI_SOC && MACH_DAVINCI_DM6467_EVM && I2C + depends on SND_EDMA_SOC && MACH_DAVINCI_DM6467_EVM && I2C select SND_DAVINCI_SOC_GENERIC_EVM select SND_SOC_SPDIF @@ -83,7 +84,7 @@ config SND_DM6467_SOC_EVM config SND_DA830_SOC_EVM tristate "SoC Audio support for DA830/OMAP-L137 EVM" - depends on SND_DAVINCI_SOC && MACH_DAVINCI_DA830_EVM && I2C + depends on SND_EDMA_SOC && MACH_DAVINCI_DA830_EVM && I2C select SND_DAVINCI_SOC_GENERIC_EVM help @@ -92,7 +93,7 @@ config SND_DA830_SOC_EVM config SND_DA850_SOC_EVM tristate "SoC Audio support for DA850/OMAP-L138 EVM" - depends on SND_DAVINCI_SOC && MACH_DAVINCI_DA850_EVM && I2C + depends on SND_EDMA_SOC && MACH_DAVINCI_DA850_EVM && I2C select SND_DAVINCI_SOC_GENERIC_EVM help Say Y if you want to add support for SoC audio on TI diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 031c1fb44ae7..0c882995a357 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -36,7 +37,6 @@ #include #include -#include "davinci-pcm.h" #include "edma-pcm.h" #include "davinci-mcasp.h" @@ -65,7 +65,6 @@ struct davinci_mcasp_context { }; struct davinci_mcasp { - struct davinci_pcm_dma_params dma_params[2]; struct snd_dmaengine_dai_dma_data dma_data[2]; void __iomem *base; u32 fifo_base; @@ -82,6 +81,7 @@ struct davinci_mcasp { u16 bclk_lrclk_ratio; int streams; u32 irq_request[2]; + int dma_request[2]; int sysclk_freq; bool bclk_master; @@ -643,7 +643,6 @@ static int davinci_config_channel_size(struct davinci_mcasp *mcasp, static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream, int period_words, int channels) { - struct davinci_pcm_dma_params *dma_params = &mcasp->dma_params[stream]; struct snd_dmaengine_dai_dma_data *dma_data = &mcasp->dma_data[stream]; int i; u8 tx_ser = 0; @@ -711,10 +710,8 @@ static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream, * For example if three serializers are enabled the DMA * need to transfer three words per DMA request. */ - dma_params->fifo_level = active_serializers; dma_data->maxburst = active_serializers; } else { - dma_params->fifo_level = 0; dma_data->maxburst = 0; } return 0; @@ -746,7 +743,6 @@ static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream, /* Configure the burst size for platform drivers */ if (numevt == 1) numevt = 0; - dma_params->fifo_level = numevt; dma_data->maxburst = numevt; return 0; @@ -872,8 +868,6 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *cpu_dai) { struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai); - struct davinci_pcm_dma_params *dma_params = - &mcasp->dma_params[substream->stream]; int word_length; int channels = params_channels(params); int period_size = params_period_size(params); @@ -914,31 +908,26 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, switch (params_format(params)) { case SNDRV_PCM_FORMAT_U8: case SNDRV_PCM_FORMAT_S8: - dma_params->data_type = 1; word_length = 8; break; case SNDRV_PCM_FORMAT_U16_LE: case SNDRV_PCM_FORMAT_S16_LE: - dma_params->data_type = 2; word_length = 16; break; case SNDRV_PCM_FORMAT_U24_3LE: case SNDRV_PCM_FORMAT_S24_3LE: - dma_params->data_type = 3; word_length = 24; break; case SNDRV_PCM_FORMAT_U24_LE: case SNDRV_PCM_FORMAT_S24_LE: - dma_params->data_type = 4; word_length = 24; break; case SNDRV_PCM_FORMAT_U32_LE: case SNDRV_PCM_FORMAT_S32_LE: - dma_params->data_type = 4; word_length = 32; break; @@ -947,11 +936,6 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, return -EINVAL; } - if (mcasp->version == MCASP_VERSION_2 && !dma_params->fifo_level) - dma_params->acnt = 4; - else - dma_params->acnt = dma_params->data_type; - davinci_config_channel_size(mcasp, word_length); if (mcasp->op_mode == DAVINCI_MCASP_IIS_MODE) @@ -1055,17 +1039,8 @@ static int davinci_mcasp_dai_probe(struct snd_soc_dai *dai) { struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai); - if (mcasp->version >= MCASP_VERSION_3) { - /* Using dmaengine PCM */ - dai->playback_dma_data = - &mcasp->dma_data[SNDRV_PCM_STREAM_PLAYBACK]; - dai->capture_dma_data = - &mcasp->dma_data[SNDRV_PCM_STREAM_CAPTURE]; - } else { - /* Using davinci-pcm */ - dai->playback_dma_data = mcasp->dma_params; - dai->capture_dma_data = mcasp->dma_params; - } + dai->playback_dma_data = &mcasp->dma_data[SNDRV_PCM_STREAM_PLAYBACK]; + dai->capture_dma_data = &mcasp->dma_data[SNDRV_PCM_STREAM_CAPTURE]; return 0; } @@ -1184,28 +1159,24 @@ static const struct snd_soc_component_driver davinci_mcasp_component = { static struct davinci_mcasp_pdata dm646x_mcasp_pdata = { .tx_dma_offset = 0x400, .rx_dma_offset = 0x400, - .asp_chan_q = EVENTQ_0, .version = MCASP_VERSION_1, }; static struct davinci_mcasp_pdata da830_mcasp_pdata = { .tx_dma_offset = 0x2000, .rx_dma_offset = 0x2000, - .asp_chan_q = EVENTQ_0, .version = MCASP_VERSION_2, }; static struct davinci_mcasp_pdata am33xx_mcasp_pdata = { .tx_dma_offset = 0, .rx_dma_offset = 0, - .asp_chan_q = EVENTQ_0, .version = MCASP_VERSION_3, }; static struct davinci_mcasp_pdata dra7_mcasp_pdata = { .tx_dma_offset = 0x200, .rx_dma_offset = 0x284, - .asp_chan_q = EVENTQ_0, .version = MCASP_VERSION_4, }; @@ -1382,12 +1353,12 @@ nodata: static int davinci_mcasp_probe(struct platform_device *pdev) { - struct davinci_pcm_dma_params *dma_params; struct snd_dmaengine_dai_dma_data *dma_data; struct resource *mem, *ioarea, *res, *dat; struct davinci_mcasp_pdata *pdata; struct davinci_mcasp *mcasp; char *irq_name; + int *dma; int irq; int ret; @@ -1521,59 +1492,45 @@ static int davinci_mcasp_probe(struct platform_device *pdev) if (dat) mcasp->dat_port = true; - dma_params = &mcasp->dma_params[SNDRV_PCM_STREAM_PLAYBACK]; dma_data = &mcasp->dma_data[SNDRV_PCM_STREAM_PLAYBACK]; - dma_params->asp_chan_q = pdata->asp_chan_q; - dma_params->ram_chan_q = pdata->ram_chan_q; - dma_params->sram_pool = pdata->sram_pool; - dma_params->sram_size = pdata->sram_size_playback; if (dat) - dma_params->dma_addr = dat->start; + dma_data->addr = dat->start; else - dma_params->dma_addr = mem->start + pdata->tx_dma_offset; - - /* Unconditional dmaengine stuff */ - dma_data->addr = dma_params->dma_addr; + dma_data->addr = mem->start + pdata->tx_dma_offset; + dma = &mcasp->dma_request[SNDRV_PCM_STREAM_PLAYBACK]; res = platform_get_resource(pdev, IORESOURCE_DMA, 0); if (res) - dma_params->channel = res->start; + *dma = res->start; else - dma_params->channel = pdata->tx_dma_channel; + *dma = pdata->tx_dma_channel; /* dmaengine filter data for DT and non-DT boot */ if (pdev->dev.of_node) dma_data->filter_data = "tx"; else - dma_data->filter_data = &dma_params->channel; + dma_data->filter_data = dma; /* RX is not valid in DIT mode */ if (mcasp->op_mode != DAVINCI_MCASP_DIT_MODE) { - dma_params = &mcasp->dma_params[SNDRV_PCM_STREAM_CAPTURE]; dma_data = &mcasp->dma_data[SNDRV_PCM_STREAM_CAPTURE]; - dma_params->asp_chan_q = pdata->asp_chan_q; - dma_params->ram_chan_q = pdata->ram_chan_q; - dma_params->sram_pool = pdata->sram_pool; - dma_params->sram_size = pdata->sram_size_capture; if (dat) - dma_params->dma_addr = dat->start; + dma_data->addr = dat->start; else - dma_params->dma_addr = mem->start + pdata->rx_dma_offset; - - /* Unconditional dmaengine stuff */ - dma_data->addr = dma_params->dma_addr; + dma_data->addr = mem->start + pdata->rx_dma_offset; + dma = &mcasp->dma_request[SNDRV_PCM_STREAM_CAPTURE]; res = platform_get_resource(pdev, IORESOURCE_DMA, 1); if (res) - dma_params->channel = res->start; + *dma = res->start; else - dma_params->channel = pdata->rx_dma_channel; + *dma = pdata->rx_dma_channel; /* dmaengine filter data for DT and non-DT boot */ if (pdev->dev.of_node) dma_data->filter_data = "rx"; else - dma_data->filter_data = &dma_params->channel; + dma_data->filter_data = dma; } if (mcasp->version < MCASP_VERSION_3) { @@ -1596,17 +1553,11 @@ static int davinci_mcasp_probe(struct platform_device *pdev) goto err; switch (mcasp->version) { -#if IS_BUILTIN(CONFIG_SND_DAVINCI_SOC) || \ - (IS_MODULE(CONFIG_SND_DAVINCI_SOC_MCASP) && \ - IS_MODULE(CONFIG_SND_DAVINCI_SOC)) - case MCASP_VERSION_1: - case MCASP_VERSION_2: - ret = davinci_soc_platform_register(&pdev->dev); - break; -#endif #if IS_BUILTIN(CONFIG_SND_EDMA_SOC) || \ (IS_MODULE(CONFIG_SND_DAVINCI_SOC_MCASP) && \ IS_MODULE(CONFIG_SND_EDMA_SOC)) + case MCASP_VERSION_1: + case MCASP_VERSION_2: case MCASP_VERSION_3: ret = edma_pcm_platform_register(&pdev->dev); break; -- GitLab From 4da4608c91308d0d15dd022074724446c15710dc Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 3 Mar 2015 16:45:21 +0200 Subject: [PATCH 02630/11651] ASoC: davinci: Remove unused davinci-pcm platform driver All DAI drivers has been converted to use edma-pcm instead of davinci-pcm and the driver can be removed from the tree. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/davinci/Makefile | 2 - sound/soc/davinci/davinci-pcm.c | 861 -------------------------------- sound/soc/davinci/davinci-pcm.h | 41 -- 3 files changed, 904 deletions(-) delete mode 100644 sound/soc/davinci/davinci-pcm.c delete mode 100644 sound/soc/davinci/davinci-pcm.h diff --git a/sound/soc/davinci/Makefile b/sound/soc/davinci/Makefile index 09bf2ba92d38..f883933c1a19 100644 --- a/sound/soc/davinci/Makefile +++ b/sound/soc/davinci/Makefile @@ -1,11 +1,9 @@ # DAVINCI Platform Support -snd-soc-davinci-objs := davinci-pcm.o snd-soc-edma-objs := edma-pcm.o snd-soc-davinci-i2s-objs := davinci-i2s.o snd-soc-davinci-mcasp-objs:= davinci-mcasp.o snd-soc-davinci-vcif-objs:= davinci-vcif.o -obj-$(CONFIG_SND_DAVINCI_SOC) += snd-soc-davinci.o obj-$(CONFIG_SND_EDMA_SOC) += snd-soc-edma.o obj-$(CONFIG_SND_DAVINCI_SOC_I2S) += snd-soc-davinci-i2s.o obj-$(CONFIG_SND_DAVINCI_SOC_MCASP) += snd-soc-davinci-mcasp.o diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c deleted file mode 100644 index 7809e9d935fc..000000000000 --- a/sound/soc/davinci/davinci-pcm.c +++ /dev/null @@ -1,861 +0,0 @@ -/* - * ALSA PCM interface for the TI DAVINCI processor - * - * Author: Vladimir Barinov, - * Copyright: (C) 2007 MontaVista Software, Inc., - * added SRAM ping/pong (C) 2008 Troy Kisky - * - * 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 -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include "davinci-pcm.h" - -#ifdef DEBUG -static void print_buf_info(int slot, char *name) -{ - struct edmacc_param p; - if (slot < 0) - return; - edma_read_slot(slot, &p); - printk(KERN_DEBUG "%s: 0x%x, opt=%x, src=%x, a_b_cnt=%x dst=%x\n", - name, slot, p.opt, p.src, p.a_b_cnt, p.dst); - printk(KERN_DEBUG " src_dst_bidx=%x link_bcntrld=%x src_dst_cidx=%x ccnt=%x\n", - p.src_dst_bidx, p.link_bcntrld, p.src_dst_cidx, p.ccnt); -} -#else -static void print_buf_info(int slot, char *name) -{ -} -#endif - -static struct snd_pcm_hardware pcm_hardware_playback = { - .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME| - SNDRV_PCM_INFO_BATCH), - .buffer_bytes_max = 128 * 1024, - .period_bytes_min = 32, - .period_bytes_max = 8 * 1024, - .periods_min = 16, - .periods_max = 255, - .fifo_size = 0, -}; - -static struct snd_pcm_hardware pcm_hardware_capture = { - .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_PAUSE | - SNDRV_PCM_INFO_BATCH), - .buffer_bytes_max = 128 * 1024, - .period_bytes_min = 32, - .period_bytes_max = 8 * 1024, - .periods_min = 16, - .periods_max = 255, - .fifo_size = 0, -}; - -/* - * How ping/pong works.... - * - * Playback: - * ram_params - copys 2*ping_size from start of SDRAM to iram, - * links to ram_link2 - * ram_link2 - copys rest of SDRAM to iram in ping_size units, - * links to ram_link - * ram_link - copys entire SDRAM to iram in ping_size uints, - * links to self - * - * asp_params - same as asp_link[0] - * asp_link[0] - copys from lower half of iram to asp port - * links to asp_link[1], triggers iram copy event on completion - * asp_link[1] - copys from upper half of iram to asp port - * links to asp_link[0], triggers iram copy event on completion - * triggers interrupt only needed to let upper SOC levels update position - * in stream on completion - * - * When playback is started: - * ram_params started - * asp_params started - * - * Capture: - * ram_params - same as ram_link, - * links to ram_link - * ram_link - same as playback - * links to self - * - * asp_params - same as playback - * asp_link[0] - same as playback - * asp_link[1] - same as playback - * - * When capture is started: - * asp_params started - */ -struct davinci_runtime_data { - spinlock_t lock; - int period; /* current DMA period */ - int asp_channel; /* Master DMA channel */ - int asp_link[2]; /* asp parameter link channel, ping/pong */ - struct davinci_pcm_dma_params *params; /* DMA params */ - int ram_channel; - int ram_link; - int ram_link2; - struct edmacc_param asp_params; - struct edmacc_param ram_params; -}; - -static void davinci_pcm_period_elapsed(struct snd_pcm_substream *substream) -{ - struct davinci_runtime_data *prtd = substream->runtime->private_data; - struct snd_pcm_runtime *runtime = substream->runtime; - - prtd->period++; - if (unlikely(prtd->period >= runtime->periods)) - prtd->period = 0; -} - -static void davinci_pcm_period_reset(struct snd_pcm_substream *substream) -{ - struct davinci_runtime_data *prtd = substream->runtime->private_data; - - prtd->period = 0; -} -/* - * Not used with ping/pong - */ -static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream) -{ - struct davinci_runtime_data *prtd = substream->runtime->private_data; - struct snd_pcm_runtime *runtime = substream->runtime; - unsigned int period_size; - unsigned int dma_offset; - dma_addr_t dma_pos; - dma_addr_t src, dst; - unsigned short src_bidx, dst_bidx; - unsigned short src_cidx, dst_cidx; - unsigned int data_type; - unsigned short acnt; - unsigned int count; - unsigned int fifo_level; - - period_size = snd_pcm_lib_period_bytes(substream); - dma_offset = prtd->period * period_size; - dma_pos = runtime->dma_addr + dma_offset; - fifo_level = prtd->params->fifo_level; - - pr_debug("davinci_pcm: audio_set_dma_params_play channel = %d " - "dma_ptr = %x period_size=%x\n", prtd->asp_link[0], dma_pos, - period_size); - - data_type = prtd->params->data_type; - count = period_size / data_type; - if (fifo_level) - count /= fifo_level; - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - src = dma_pos; - dst = prtd->params->dma_addr; - src_bidx = data_type; - dst_bidx = 4; - src_cidx = data_type * fifo_level; - dst_cidx = 0; - } else { - src = prtd->params->dma_addr; - dst = dma_pos; - src_bidx = 0; - dst_bidx = data_type; - src_cidx = 0; - dst_cidx = data_type * fifo_level; - } - - acnt = prtd->params->acnt; - edma_set_src(prtd->asp_link[0], src, INCR, W8BIT); - edma_set_dest(prtd->asp_link[0], dst, INCR, W8BIT); - - edma_set_src_index(prtd->asp_link[0], src_bidx, src_cidx); - edma_set_dest_index(prtd->asp_link[0], dst_bidx, dst_cidx); - - if (!fifo_level) - edma_set_transfer_params(prtd->asp_link[0], acnt, count, 1, 0, - ASYNC); - else - edma_set_transfer_params(prtd->asp_link[0], acnt, - fifo_level, - count, fifo_level, - ABSYNC); -} - -static void davinci_pcm_dma_irq(unsigned link, u16 ch_status, void *data) -{ - struct snd_pcm_substream *substream = data; - struct davinci_runtime_data *prtd = substream->runtime->private_data; - - print_buf_info(prtd->ram_channel, "i ram_channel"); - pr_debug("davinci_pcm: link=%d, status=0x%x\n", link, ch_status); - - if (unlikely(ch_status != EDMA_DMA_COMPLETE)) - return; - - if (snd_pcm_running(substream)) { - spin_lock(&prtd->lock); - if (prtd->ram_channel < 0) { - /* No ping/pong must fix up link dma data*/ - davinci_pcm_enqueue_dma(substream); - } - davinci_pcm_period_elapsed(substream); - spin_unlock(&prtd->lock); - snd_pcm_period_elapsed(substream); - } -} - -#ifdef CONFIG_GENERIC_ALLOCATOR -static int allocate_sram(struct snd_pcm_substream *substream, - struct gen_pool *sram_pool, unsigned size, - struct snd_pcm_hardware *ppcm) -{ - struct snd_dma_buffer *buf = &substream->dma_buffer; - struct snd_dma_buffer *iram_dma = NULL; - dma_addr_t iram_phys = 0; - void *iram_virt = NULL; - - if (buf->private_data || !size) - return 0; - - ppcm->period_bytes_max = size; - iram_virt = gen_pool_dma_alloc(sram_pool, size, &iram_phys); - if (!iram_virt) - goto exit1; - iram_dma = kzalloc(sizeof(*iram_dma), GFP_KERNEL); - if (!iram_dma) - goto exit2; - iram_dma->area = iram_virt; - iram_dma->addr = iram_phys; - memset(iram_dma->area, 0, size); - iram_dma->bytes = size; - buf->private_data = iram_dma; - return 0; -exit2: - if (iram_virt) - gen_pool_free(sram_pool, (unsigned)iram_virt, size); -exit1: - return -ENOMEM; -} - -static void davinci_free_sram(struct snd_pcm_substream *substream, - struct snd_dma_buffer *iram_dma) -{ - struct davinci_runtime_data *prtd = substream->runtime->private_data; - struct gen_pool *sram_pool = prtd->params->sram_pool; - - gen_pool_free(sram_pool, (unsigned) iram_dma->area, iram_dma->bytes); -} -#else -static int allocate_sram(struct snd_pcm_substream *substream, - struct gen_pool *sram_pool, unsigned size, - struct snd_pcm_hardware *ppcm) -{ - return 0; -} - -static void davinci_free_sram(struct snd_pcm_substream *substream, - struct snd_dma_buffer *iram_dma) -{ -} -#endif - -/* - * Only used with ping/pong. - * This is called after runtime->dma_addr, period_bytes and data_type are valid - */ -static int ping_pong_dma_setup(struct snd_pcm_substream *substream) -{ - unsigned short ram_src_cidx, ram_dst_cidx; - struct snd_pcm_runtime *runtime = substream->runtime; - struct davinci_runtime_data *prtd = runtime->private_data; - struct snd_dma_buffer *iram_dma = - (struct snd_dma_buffer *)substream->dma_buffer.private_data; - struct davinci_pcm_dma_params *params = prtd->params; - unsigned int data_type = params->data_type; - unsigned int acnt = params->acnt; - /* divide by 2 for ping/pong */ - unsigned int ping_size = snd_pcm_lib_period_bytes(substream) >> 1; - unsigned int fifo_level = prtd->params->fifo_level; - unsigned int count; - if ((data_type == 0) || (data_type > 4)) { - printk(KERN_ERR "%s: data_type=%i\n", __func__, data_type); - return -EINVAL; - } - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - dma_addr_t asp_src_pong = iram_dma->addr + ping_size; - ram_src_cidx = ping_size; - ram_dst_cidx = -ping_size; - edma_set_src(prtd->asp_link[1], asp_src_pong, INCR, W8BIT); - - edma_set_src_index(prtd->asp_link[0], data_type, - data_type * fifo_level); - edma_set_src_index(prtd->asp_link[1], data_type, - data_type * fifo_level); - - edma_set_src(prtd->ram_link, runtime->dma_addr, INCR, W32BIT); - } else { - dma_addr_t asp_dst_pong = iram_dma->addr + ping_size; - ram_src_cidx = -ping_size; - ram_dst_cidx = ping_size; - edma_set_dest(prtd->asp_link[1], asp_dst_pong, INCR, W8BIT); - - edma_set_dest_index(prtd->asp_link[0], data_type, - data_type * fifo_level); - edma_set_dest_index(prtd->asp_link[1], data_type, - data_type * fifo_level); - - edma_set_dest(prtd->ram_link, runtime->dma_addr, INCR, W32BIT); - } - - if (!fifo_level) { - count = ping_size / data_type; - edma_set_transfer_params(prtd->asp_link[0], acnt, count, - 1, 0, ASYNC); - edma_set_transfer_params(prtd->asp_link[1], acnt, count, - 1, 0, ASYNC); - } else { - count = ping_size / (data_type * fifo_level); - edma_set_transfer_params(prtd->asp_link[0], acnt, fifo_level, - count, fifo_level, ABSYNC); - edma_set_transfer_params(prtd->asp_link[1], acnt, fifo_level, - count, fifo_level, ABSYNC); - } - - edma_set_src_index(prtd->ram_link, ping_size, ram_src_cidx); - edma_set_dest_index(prtd->ram_link, ping_size, ram_dst_cidx); - edma_set_transfer_params(prtd->ram_link, ping_size, 2, - runtime->periods, 2, ASYNC); - - /* init master params */ - edma_read_slot(prtd->asp_link[0], &prtd->asp_params); - edma_read_slot(prtd->ram_link, &prtd->ram_params); - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - struct edmacc_param p_ram; - /* Copy entire iram buffer before playback started */ - prtd->ram_params.a_b_cnt = (1 << 16) | (ping_size << 1); - /* 0 dst_bidx */ - prtd->ram_params.src_dst_bidx = (ping_size << 1); - /* 0 dst_cidx */ - prtd->ram_params.src_dst_cidx = (ping_size << 1); - prtd->ram_params.ccnt = 1; - - /* Skip 1st period */ - edma_read_slot(prtd->ram_link, &p_ram); - p_ram.src += (ping_size << 1); - p_ram.ccnt -= 1; - edma_write_slot(prtd->ram_link2, &p_ram); - /* - * When 1st started, ram -> iram dma channel will fill the - * entire iram. Then, whenever a ping/pong asp buffer finishes, - * 1/2 iram will be filled. - */ - prtd->ram_params.link_bcntrld = - EDMA_CHAN_SLOT(prtd->ram_link2) << 5; - } - return 0; -} - -/* 1 asp tx or rx channel using 2 parameter channels - * 1 ram to/from iram channel using 1 parameter channel - * - * Playback - * ram copy channel kicks off first, - * 1st ram copy of entire iram buffer completion kicks off asp channel - * asp tcc always kicks off ram copy of 1/2 iram buffer - * - * Record - * asp channel starts, tcc kicks off ram copy - */ -static int request_ping_pong(struct snd_pcm_substream *substream, - struct davinci_runtime_data *prtd, - struct snd_dma_buffer *iram_dma) -{ - dma_addr_t asp_src_ping; - dma_addr_t asp_dst_ping; - int ret; - struct davinci_pcm_dma_params *params = prtd->params; - - /* Request ram master channel */ - ret = prtd->ram_channel = edma_alloc_channel(EDMA_CHANNEL_ANY, - davinci_pcm_dma_irq, substream, - prtd->params->ram_chan_q); - if (ret < 0) - goto exit1; - - /* Request ram link channel */ - ret = prtd->ram_link = edma_alloc_slot( - EDMA_CTLR(prtd->ram_channel), EDMA_SLOT_ANY); - if (ret < 0) - goto exit2; - - ret = prtd->asp_link[1] = edma_alloc_slot( - EDMA_CTLR(prtd->asp_channel), EDMA_SLOT_ANY); - if (ret < 0) - goto exit3; - - prtd->ram_link2 = -1; - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - ret = prtd->ram_link2 = edma_alloc_slot( - EDMA_CTLR(prtd->ram_channel), EDMA_SLOT_ANY); - if (ret < 0) - goto exit4; - } - /* circle ping-pong buffers */ - edma_link(prtd->asp_link[0], prtd->asp_link[1]); - edma_link(prtd->asp_link[1], prtd->asp_link[0]); - /* circle ram buffers */ - edma_link(prtd->ram_link, prtd->ram_link); - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - asp_src_ping = iram_dma->addr; - asp_dst_ping = params->dma_addr; /* fifo */ - } else { - asp_src_ping = params->dma_addr; /* fifo */ - asp_dst_ping = iram_dma->addr; - } - /* ping */ - edma_set_src(prtd->asp_link[0], asp_src_ping, INCR, W16BIT); - edma_set_dest(prtd->asp_link[0], asp_dst_ping, INCR, W16BIT); - edma_set_src_index(prtd->asp_link[0], 0, 0); - edma_set_dest_index(prtd->asp_link[0], 0, 0); - - edma_read_slot(prtd->asp_link[0], &prtd->asp_params); - prtd->asp_params.opt &= ~(TCCMODE | EDMA_TCC(0x3f) | TCINTEN); - prtd->asp_params.opt |= TCCHEN | - EDMA_TCC(prtd->ram_channel & 0x3f); - edma_write_slot(prtd->asp_link[0], &prtd->asp_params); - - /* pong */ - edma_set_src(prtd->asp_link[1], asp_src_ping, INCR, W16BIT); - edma_set_dest(prtd->asp_link[1], asp_dst_ping, INCR, W16BIT); - edma_set_src_index(prtd->asp_link[1], 0, 0); - edma_set_dest_index(prtd->asp_link[1], 0, 0); - - edma_read_slot(prtd->asp_link[1], &prtd->asp_params); - prtd->asp_params.opt &= ~(TCCMODE | EDMA_TCC(0x3f)); - /* interrupt after every pong completion */ - prtd->asp_params.opt |= TCINTEN | TCCHEN | - EDMA_TCC(prtd->ram_channel & 0x3f); - edma_write_slot(prtd->asp_link[1], &prtd->asp_params); - - /* ram */ - edma_set_src(prtd->ram_link, iram_dma->addr, INCR, W32BIT); - edma_set_dest(prtd->ram_link, iram_dma->addr, INCR, W32BIT); - pr_debug("%s: audio dma channels/slots in use for ram:%u %u %u," - "for asp:%u %u %u\n", __func__, - prtd->ram_channel, prtd->ram_link, prtd->ram_link2, - prtd->asp_channel, prtd->asp_link[0], - prtd->asp_link[1]); - return 0; -exit4: - edma_free_channel(prtd->asp_link[1]); - prtd->asp_link[1] = -1; -exit3: - edma_free_channel(prtd->ram_link); - prtd->ram_link = -1; -exit2: - edma_free_channel(prtd->ram_channel); - prtd->ram_channel = -1; -exit1: - return ret; -} - -static int davinci_pcm_dma_request(struct snd_pcm_substream *substream) -{ - struct snd_dma_buffer *iram_dma; - struct davinci_runtime_data *prtd = substream->runtime->private_data; - struct davinci_pcm_dma_params *params = prtd->params; - int ret; - - if (!params) - return -ENODEV; - - /* Request asp master DMA channel */ - ret = prtd->asp_channel = edma_alloc_channel(params->channel, - davinci_pcm_dma_irq, substream, - prtd->params->asp_chan_q); - if (ret < 0) - goto exit1; - - /* Request asp link channels */ - ret = prtd->asp_link[0] = edma_alloc_slot( - EDMA_CTLR(prtd->asp_channel), EDMA_SLOT_ANY); - if (ret < 0) - goto exit2; - - iram_dma = (struct snd_dma_buffer *)substream->dma_buffer.private_data; - if (iram_dma) { - if (request_ping_pong(substream, prtd, iram_dma) == 0) - return 0; - printk(KERN_WARNING "%s: dma channel allocation failed," - "not using sram\n", __func__); - } - - /* Issue transfer completion IRQ when the channel completes a - * transfer, then always reload from the same slot (by a kind - * of loopback link). The completion IRQ handler will update - * the reload slot with a new buffer. - * - * REVISIT save p_ram here after setting up everything except - * the buffer and its length (ccnt) ... use it as a template - * so davinci_pcm_enqueue_dma() takes less time in IRQ. - */ - edma_read_slot(prtd->asp_link[0], &prtd->asp_params); - prtd->asp_params.opt |= TCINTEN | - EDMA_TCC(EDMA_CHAN_SLOT(prtd->asp_channel)); - prtd->asp_params.link_bcntrld = EDMA_CHAN_SLOT(prtd->asp_link[0]) << 5; - edma_write_slot(prtd->asp_link[0], &prtd->asp_params); - return 0; -exit2: - edma_free_channel(prtd->asp_channel); - prtd->asp_channel = -1; -exit1: - return ret; -} - -static int davinci_pcm_trigger(struct snd_pcm_substream *substream, int cmd) -{ - struct davinci_runtime_data *prtd = substream->runtime->private_data; - int ret = 0; - - spin_lock(&prtd->lock); - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - edma_start(prtd->asp_channel); - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && - prtd->ram_channel >= 0) { - /* copy 1st iram buffer */ - edma_start(prtd->ram_channel); - } - break; - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - edma_resume(prtd->asp_channel); - break; - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - edma_pause(prtd->asp_channel); - break; - default: - ret = -EINVAL; - break; - } - - spin_unlock(&prtd->lock); - - return ret; -} - -static int davinci_pcm_prepare(struct snd_pcm_substream *substream) -{ - struct davinci_runtime_data *prtd = substream->runtime->private_data; - - davinci_pcm_period_reset(substream); - if (prtd->ram_channel >= 0) { - int ret = ping_pong_dma_setup(substream); - if (ret < 0) - return ret; - - edma_write_slot(prtd->ram_channel, &prtd->ram_params); - edma_write_slot(prtd->asp_channel, &prtd->asp_params); - - print_buf_info(prtd->ram_channel, "ram_channel"); - print_buf_info(prtd->ram_link, "ram_link"); - print_buf_info(prtd->ram_link2, "ram_link2"); - print_buf_info(prtd->asp_channel, "asp_channel"); - print_buf_info(prtd->asp_link[0], "asp_link[0]"); - print_buf_info(prtd->asp_link[1], "asp_link[1]"); - - /* - * There is a phase offset of 2 periods between the position - * used by dma setup and the position reported in the pointer - * function. - * - * The phase offset, when not using ping-pong buffers, is due to - * the two consecutive calls to davinci_pcm_enqueue_dma() below. - * - * Whereas here, with ping-pong buffers, the phase is due to - * there being an entire buffer transfer complete before the - * first dma completion event triggers davinci_pcm_dma_irq(). - */ - davinci_pcm_period_elapsed(substream); - davinci_pcm_period_elapsed(substream); - - return 0; - } - davinci_pcm_enqueue_dma(substream); - davinci_pcm_period_elapsed(substream); - - /* Copy self-linked parameter RAM entry into master channel */ - edma_read_slot(prtd->asp_link[0], &prtd->asp_params); - edma_write_slot(prtd->asp_channel, &prtd->asp_params); - davinci_pcm_enqueue_dma(substream); - davinci_pcm_period_elapsed(substream); - - return 0; -} - -static snd_pcm_uframes_t -davinci_pcm_pointer(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct davinci_runtime_data *prtd = runtime->private_data; - unsigned int offset; - int asp_count; - unsigned int period_size = snd_pcm_lib_period_bytes(substream); - - /* - * There is a phase offset of 2 periods between the position used by dma - * setup and the position reported in the pointer function. Either +2 in - * the dma setup or -2 here in the pointer function (with wrapping, - * both) accounts for this offset -- choose the latter since it makes - * the first-time setup clearer. - */ - spin_lock(&prtd->lock); - asp_count = prtd->period - 2; - spin_unlock(&prtd->lock); - - if (asp_count < 0) - asp_count += runtime->periods; - asp_count *= period_size; - - offset = bytes_to_frames(runtime, asp_count); - if (offset >= runtime->buffer_size) - offset = 0; - - return offset; -} - -static int davinci_pcm_open(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct davinci_runtime_data *prtd; - struct snd_pcm_hardware *ppcm; - int ret = 0; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct davinci_pcm_dma_params *pa; - struct davinci_pcm_dma_params *params; - - pa = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); - if (!pa) - return -ENODEV; - params = &pa[substream->stream]; - - ppcm = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? - &pcm_hardware_playback : &pcm_hardware_capture; - allocate_sram(substream, params->sram_pool, params->sram_size, ppcm); - snd_soc_set_runtime_hwparams(substream, ppcm); - /* ensure that buffer size is a multiple of period size */ - ret = snd_pcm_hw_constraint_integer(runtime, - SNDRV_PCM_HW_PARAM_PERIODS); - if (ret < 0) - return ret; - - prtd = kzalloc(sizeof(struct davinci_runtime_data), GFP_KERNEL); - if (prtd == NULL) - return -ENOMEM; - - spin_lock_init(&prtd->lock); - prtd->params = params; - prtd->asp_channel = -1; - prtd->asp_link[0] = prtd->asp_link[1] = -1; - prtd->ram_channel = -1; - prtd->ram_link = -1; - prtd->ram_link2 = -1; - - runtime->private_data = prtd; - - ret = davinci_pcm_dma_request(substream); - if (ret) { - printk(KERN_ERR "davinci_pcm: Failed to get dma channels\n"); - kfree(prtd); - } - - return ret; -} - -static int davinci_pcm_close(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct davinci_runtime_data *prtd = runtime->private_data; - - if (prtd->ram_channel >= 0) - edma_stop(prtd->ram_channel); - if (prtd->asp_channel >= 0) - edma_stop(prtd->asp_channel); - if (prtd->asp_link[0] >= 0) - edma_unlink(prtd->asp_link[0]); - if (prtd->asp_link[1] >= 0) - edma_unlink(prtd->asp_link[1]); - if (prtd->ram_link >= 0) - edma_unlink(prtd->ram_link); - - if (prtd->asp_link[0] >= 0) - edma_free_slot(prtd->asp_link[0]); - if (prtd->asp_link[1] >= 0) - edma_free_slot(prtd->asp_link[1]); - if (prtd->asp_channel >= 0) - edma_free_channel(prtd->asp_channel); - if (prtd->ram_link >= 0) - edma_free_slot(prtd->ram_link); - if (prtd->ram_link2 >= 0) - edma_free_slot(prtd->ram_link2); - if (prtd->ram_channel >= 0) - edma_free_channel(prtd->ram_channel); - - kfree(prtd); - - return 0; -} - -static int davinci_pcm_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *hw_params) -{ - return snd_pcm_lib_malloc_pages(substream, - params_buffer_bytes(hw_params)); -} - -static int davinci_pcm_hw_free(struct snd_pcm_substream *substream) -{ - return snd_pcm_lib_free_pages(substream); -} - -static int davinci_pcm_mmap(struct snd_pcm_substream *substream, - struct vm_area_struct *vma) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - - return dma_mmap_writecombine(substream->pcm->card->dev, vma, - runtime->dma_area, - runtime->dma_addr, - runtime->dma_bytes); -} - -static struct snd_pcm_ops davinci_pcm_ops = { - .open = davinci_pcm_open, - .close = davinci_pcm_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = davinci_pcm_hw_params, - .hw_free = davinci_pcm_hw_free, - .prepare = davinci_pcm_prepare, - .trigger = davinci_pcm_trigger, - .pointer = davinci_pcm_pointer, - .mmap = davinci_pcm_mmap, -}; - -static int davinci_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream, - size_t size) -{ - struct snd_pcm_substream *substream = pcm->streams[stream].substream; - struct snd_dma_buffer *buf = &substream->dma_buffer; - - buf->dev.type = SNDRV_DMA_TYPE_DEV; - buf->dev.dev = pcm->card->dev; - buf->private_data = NULL; - buf->area = dma_alloc_writecombine(pcm->card->dev, size, - &buf->addr, GFP_KERNEL); - - pr_debug("davinci_pcm: preallocate_dma_buffer: area=%p, addr=%p, " - "size=%d\n", (void *) buf->area, (void *) buf->addr, size); - - if (!buf->area) - return -ENOMEM; - - buf->bytes = size; - return 0; -} - -static void davinci_pcm_free(struct snd_pcm *pcm) -{ - struct snd_pcm_substream *substream; - struct snd_dma_buffer *buf; - int stream; - - for (stream = 0; stream < 2; stream++) { - struct snd_dma_buffer *iram_dma; - substream = pcm->streams[stream].substream; - if (!substream) - continue; - - buf = &substream->dma_buffer; - if (!buf->area) - continue; - - dma_free_writecombine(pcm->card->dev, buf->bytes, - buf->area, buf->addr); - buf->area = NULL; - iram_dma = buf->private_data; - if (iram_dma) { - davinci_free_sram(substream, iram_dma); - kfree(iram_dma); - } - } -} - -static int davinci_pcm_new(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_card *card = rtd->card->snd_card; - struct snd_pcm *pcm = rtd->pcm; - int ret; - - ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(32)); - if (ret) - return ret; - - if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { - ret = davinci_pcm_preallocate_dma_buffer(pcm, - SNDRV_PCM_STREAM_PLAYBACK, - pcm_hardware_playback.buffer_bytes_max); - if (ret) - return ret; - } - - if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { - ret = davinci_pcm_preallocate_dma_buffer(pcm, - SNDRV_PCM_STREAM_CAPTURE, - pcm_hardware_capture.buffer_bytes_max); - if (ret) - return ret; - } - - return 0; -} - -static struct snd_soc_platform_driver davinci_soc_platform = { - .ops = &davinci_pcm_ops, - .pcm_new = davinci_pcm_new, - .pcm_free = davinci_pcm_free, -}; - -int davinci_soc_platform_register(struct device *dev) -{ - return devm_snd_soc_register_platform(dev, &davinci_soc_platform); -} -EXPORT_SYMBOL_GPL(davinci_soc_platform_register); - -MODULE_AUTHOR("Vladimir Barinov"); -MODULE_DESCRIPTION("TI DAVINCI PCM DMA module"); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/davinci/davinci-pcm.h b/sound/soc/davinci/davinci-pcm.h deleted file mode 100644 index 0fe2346a9aa2..000000000000 --- a/sound/soc/davinci/davinci-pcm.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * ALSA PCM interface for the TI DAVINCI processor - * - * Author: Vladimir Barinov, - * Copyright: (C) 2007 MontaVista Software, Inc., - * - * 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. - */ - -#ifndef _DAVINCI_PCM_H -#define _DAVINCI_PCM_H - -#include -#include -#include - -struct davinci_pcm_dma_params { - int channel; /* sync dma channel ID */ - unsigned short acnt; - dma_addr_t dma_addr; /* device physical address for DMA */ - unsigned sram_size; - struct gen_pool *sram_pool; /* SRAM gen_pool for ping pong */ - enum dma_event_q asp_chan_q; /* event queue number for ASP channel */ - enum dma_event_q ram_chan_q; /* event queue number for RAM channel */ - unsigned char data_type; /* xfer data type */ - unsigned char convert_mono_stereo; - unsigned int fifo_level; -}; - -#if IS_ENABLED(CONFIG_SND_DAVINCI_SOC) -int davinci_soc_platform_register(struct device *dev); -#else -static inline int davinci_soc_platform_register(struct device *dev) -{ - return 0; -} -#endif /* CONFIG_SND_DAVINCI_SOC */ - -#endif -- GitLab From 6742e15cf92a8dc3065843a627952ed518e08267 Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Tue, 3 Mar 2015 13:28:53 +0200 Subject: [PATCH 02631/11651] ASoC: omap-pcm: Allow only formats with 1, 2, and 4 byte physical size sDMA support only transfer elements with 1, 2, and 4 byte physical size. Initialize the pcm driver accordingly. Signed-off-by: Jyri Sarha Acked-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/omap/omap-pcm.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c index f4b05bc23e4b..e49ee2383a88 100644 --- a/sound/soc/omap/omap-pcm.c +++ b/sound/soc/omap/omap-pcm.c @@ -39,7 +39,7 @@ #define pcm_omap1510() 0 #endif -static const struct snd_pcm_hardware omap_pcm_hardware = { +static struct snd_pcm_hardware omap_pcm_hardware = { .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_INTERLEAVED | @@ -53,6 +53,24 @@ static const struct snd_pcm_hardware omap_pcm_hardware = { .buffer_bytes_max = 128 * 1024, }; +/* sDMA supports only 1, 2, and 4 byte transfer elements. */ +static void omap_pcm_limit_supported_formats(void) +{ + int i; + + for (i = 0; i < SNDRV_PCM_FORMAT_LAST; i++) { + switch (snd_pcm_format_physical_width(i)) { + case 8: + case 16: + case 32: + omap_pcm_hardware.formats |= (1LL << i); + break; + default: + break; + } + } +} + /* this may get called several times by oss emulation */ static int omap_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) @@ -235,6 +253,7 @@ static struct snd_soc_platform_driver omap_soc_platform = { int omap_pcm_platform_register(struct device *dev) { + omap_pcm_limit_supported_formats(); return devm_snd_soc_register_platform(dev, &omap_soc_platform); } EXPORT_SYMBOL_GPL(omap_pcm_platform_register); -- GitLab From 2bf9eba14340a53776a742f2c8a0bfbd9c86d259 Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Tue, 3 Mar 2015 18:31:29 +0800 Subject: [PATCH 02632/11651] ASoC: rt5670: Fix the speaker mono output issue We need to set left/right control for the speaker amp to get stereo output on speaker. Signed-off-by: Bard Liao Signed-off-by: Mark Brown --- sound/soc/codecs/rt5670.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c index 0632b7458a53..592f961b5de5 100644 --- a/sound/soc/codecs/rt5670.c +++ b/sound/soc/codecs/rt5670.c @@ -2700,6 +2700,12 @@ static int rt5670_i2c_probe(struct i2c_client *i2c, regmap_write(rt5670->regmap, RT5670_RESET, 0); + regmap_read(rt5670->regmap, RT5670_VENDOR_ID, &val); + if (val >= 4) + regmap_write(rt5670->regmap, RT5670_GPIO_CTRL3, 0x0980); + else + regmap_write(rt5670->regmap, RT5670_GPIO_CTRL3, 0x0d00); + ret = regmap_register_patch(rt5670->regmap, init_list, ARRAY_SIZE(init_list)); if (ret != 0) -- GitLab From 7f9acb109318ddf8bf5139804b065f137cbf8b47 Mon Sep 17 00:00:00 2001 From: Josh Wu Date: Thu, 12 Feb 2015 16:06:23 +0800 Subject: [PATCH 02633/11651] ARM: at91: at91sam9x5/dts: add ISI dt support, include isi node, pinctrls Add a new file: at91sam9x5_isi.dtsi, which includes ISI node and pinctrls. Signed-off-by: Josh Wu Acked-by: Boris Brezillon Signed-off-by: Nicolas Ferre --- arch/arm/boot/dts/at91sam9g25.dtsi | 1 + arch/arm/boot/dts/at91sam9x5_isi.dtsi | 46 +++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/arch/arm/boot/dts/at91sam9g25.dtsi b/arch/arm/boot/dts/at91sam9g25.dtsi index 17b879990914..a7da0dd0c98f 100644 --- a/arch/arm/boot/dts/at91sam9g25.dtsi +++ b/arch/arm/boot/dts/at91sam9g25.dtsi @@ -7,6 +7,7 @@ */ #include "at91sam9x5.dtsi" +#include "at91sam9x5_isi.dtsi" #include "at91sam9x5_usart3.dtsi" #include "at91sam9x5_macb0.dtsi" diff --git a/arch/arm/boot/dts/at91sam9x5_isi.dtsi b/arch/arm/boot/dts/at91sam9x5_isi.dtsi index 98bc877a68ef..8fc45ca4dcb5 100644 --- a/arch/arm/boot/dts/at91sam9x5_isi.dtsi +++ b/arch/arm/boot/dts/at91sam9x5_isi.dtsi @@ -13,6 +13,37 @@ / { ahb { apb { + pinctrl@fffff400 { + isi { + pinctrl_isi_data_0_7: isi-0-data-0-7 { + atmel,pins = + ; /* ISI_VSYNC, conflicts with LCDDAT13 */ + }; + + pinctrl_isi_data_8_9: isi-0-data-8-9 { + atmel,pins = + ; /* ISI_D9, conflicts with LCDDAT9 */ + }; + + pinctrl_isi_data_10_11: isi-0-data-10-11 { + atmel,pins = + ; /* ISI_D11, conflicts with LCDDAT11 */ + }; + }; + }; + pmc: pmc@fffffc00 { periphck { isi_clk: isi_clk { @@ -21,6 +52,21 @@ }; }; }; + + isi: isi@f8048000 { + compatible = "atmel,at91sam9g45-isi"; + reg = <0xf8048000 0x4000>; + interrupts = <25 IRQ_TYPE_LEVEL_HIGH 5>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_isi_data_0_7>; + clocks = <&isi_clk>; + clock-names = "isi_clk"; + status = "disabled"; + port { + #address-cells = <1>; + #size-cells = <0>; + }; + }; }; }; }; -- GitLab From 436ea603c3779699f50ee0ff61c4d733496c2560 Mon Sep 17 00:00:00 2001 From: Josh Wu Date: Thu, 12 Feb 2015 16:06:24 +0800 Subject: [PATCH 02634/11651] ARM: at91: at91sam9x5ek/dts: add ov2640 support Add the camera sensor ov2640 dt support. And connect sensor to isi node as well. Signed-off-by: Josh Wu Acked-by: Boris Brezillon Signed-off-by: Nicolas Ferre --- arch/arm/boot/dts/at91sam9x5ek.dtsi | 48 +++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/arch/arm/boot/dts/at91sam9x5ek.dtsi b/arch/arm/boot/dts/at91sam9x5ek.dtsi index bd16bd360272..cc83a37a7311 100644 --- a/arch/arm/boot/dts/at91sam9x5ek.dtsi +++ b/arch/arm/boot/dts/at91sam9x5ek.dtsi @@ -59,6 +59,16 @@ status = "okay"; }; + isi: isi@f8048000 { + status = "disabled"; + port { + isi_0: endpoint@0 { + remote-endpoint = <&ov2640_0>; + bus-width = <8>; + }; + }; + }; + i2c0: i2c@f8010000 { status = "okay"; @@ -66,9 +76,47 @@ compatible = "wm8731"; reg = <0x1a>; }; + + ov2640: camera@0x30 { + compatible = "ovti,ov2640"; + reg = <0x30>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pck0_as_isi_mck &pinctrl_sensor_power &pinctrl_sensor_reset>; + resetb-gpios = <&pioA 7 GPIO_ACTIVE_LOW>; + pwdn-gpios = <&pioA 13 GPIO_ACTIVE_HIGH>; + clocks = <&pck0>; + clock-names = "xvclk"; + assigned-clocks = <&pck0>; + assigned-clock-rates = <25000000>; + status = "disabled"; + + port { + ov2640_0: endpoint { + remote-endpoint = <&isi_0>; + bus-width = <8>; + }; + }; + }; }; pinctrl@fffff400 { + camera_sensor { + pinctrl_pck0_as_isi_mck: pck0_as_isi_mck-0 { + atmel,pins = + ; /* ISI_MCK */ + }; + + pinctrl_sensor_power: sensor_power-0 { + atmel,pins = + ; + }; + + pinctrl_sensor_reset: sensor_reset-0 { + atmel,pins = + ; + }; + }; + mmc0 { pinctrl_board_mmc0: mmc0-board { atmel,pins = -- GitLab From 3978d6b05ff39821890f0322782322f242350c1f Mon Sep 17 00:00:00 2001 From: Josh Wu Date: Thu, 12 Feb 2015 16:06:25 +0800 Subject: [PATCH 02635/11651] ARM: at91: at91sam9g25ek/dts: enable ISI and ov2640 Enable ISI and ov2640 for at91sam9g25ek board. Meantime, we need to disable the mmc1 and spi0 as they have pin conflict with ISI. Signed-off-by: Josh Wu Acked-by: Boris Brezillon Signed-off-by: Nicolas Ferre --- arch/arm/boot/dts/at91sam9g25ek.dts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/arch/arm/boot/dts/at91sam9g25ek.dts b/arch/arm/boot/dts/at91sam9g25ek.dts index 1e4c49c584d3..707fd4ea58f5 100644 --- a/arch/arm/boot/dts/at91sam9g25ek.dts +++ b/arch/arm/boot/dts/at91sam9g25ek.dts @@ -16,10 +16,28 @@ ahb { apb { + spi0: spi@f0000000 { + status = "disabled"; + }; + + mmc1: mmc@f000c000 { + status = "disabled"; + }; + + i2c0: i2c@f8010000 { + ov2640: camera@0x30 { + status = "okay"; + }; + }; + macb0: ethernet@f802c000 { phy-mode = "rmii"; status = "okay"; }; + + isi: isi@f8048000 { + status = "okay"; + }; }; }; }; -- GitLab From 13f7ad3dc6dbb09ae232647058f18dedd69fce47 Mon Sep 17 00:00:00 2001 From: Bo Shen Date: Tue, 10 Feb 2015 09:55:34 +0800 Subject: [PATCH 02636/11651] ARM: at91/dt: at91sam9n12: add udp device node Add usb device node for at91sam9n12. Signed-off-by: Bo Shen Signed-off-by: Nicolas Ferre --- arch/arm/boot/dts/at91sam9n12.dtsi | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/arm/boot/dts/at91sam9n12.dtsi b/arch/arm/boot/dts/at91sam9n12.dtsi index 0c53a375ba99..9648430d78e6 100644 --- a/arch/arm/boot/dts/at91sam9n12.dtsi +++ b/arch/arm/boot/dts/at91sam9n12.dtsi @@ -912,6 +912,15 @@ clocks = <&pwm_clk>; status = "disabled"; }; + + usb1: gadget@f803c000 { + compatible = "atmel,at91sam9260-udc"; + reg = <0xf803c000 0x4000>; + interrupts = <23 IRQ_TYPE_LEVEL_HIGH 2>; + clocks = <&udphs_clk>, <&udpck>; + clock-names = "pclk", "hclk"; + status = "disabled"; + }; }; nand0: nand@40000000 { -- GitLab From cf05ea713144fe08d1207846fb592ff0985040c6 Mon Sep 17 00:00:00 2001 From: Bo Shen Date: Tue, 10 Feb 2015 09:55:35 +0800 Subject: [PATCH 02637/11651] ARM: at91/dt: at91sam9n12ek: enable udp Enable usb device port on at91sam9n12ek board. Signed-off-by: Bo Shen Signed-off-by: Nicolas Ferre --- arch/arm/boot/dts/at91sam9n12ek.dts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/arch/arm/boot/dts/at91sam9n12ek.dts b/arch/arm/boot/dts/at91sam9n12ek.dts index 9575c0d895c9..6123109f14ff 100644 --- a/arch/arm/boot/dts/at91sam9n12ek.dts +++ b/arch/arm/boot/dts/at91sam9n12ek.dts @@ -108,6 +108,13 @@ ; }; }; + + usb1 { + pinctrl_usb1_vbus_sense: usb1_vbus_sense { + atmel,pins = + ; /* PB16 gpio usb vbus sense, no pull up and deglitch */ + }; + }; }; spi0: spi@f0000000 { @@ -120,6 +127,13 @@ }; }; + usb1: gadget@f803c000 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb1_vbus_sense>; + atmel,vbus-gpio = <&pioB 16 GPIO_ACTIVE_HIGH>; + status = "okay"; + }; + watchdog@fffffe40 { status = "okay"; }; -- GitLab From 8dafaa1f28e9113c19ead7d7e118669aace538af Mon Sep 17 00:00:00 2001 From: Nicolas Ferre Date: Wed, 4 Mar 2015 17:56:03 +0100 Subject: [PATCH 02638/11651] ARM: at91/dt/trivial: correct file headers for SAMA5D3 SoC peripherals File name had at91 prefix, which is not the case anymore for SAMA5D3. AT91SAM9x5 was mentioned instead of SAMA5D3 SoC. Signed-off-by: Nicolas Ferre --- arch/arm/boot/dts/sama5d3_can.dtsi | 2 +- arch/arm/boot/dts/sama5d3_emac.dtsi | 2 +- arch/arm/boot/dts/sama5d3_gmac.dtsi | 2 +- arch/arm/boot/dts/sama5d3_lcd.dtsi | 2 +- arch/arm/boot/dts/sama5d3_mci2.dtsi | 2 +- arch/arm/boot/dts/sama5d3_tcb1.dtsi | 2 +- arch/arm/boot/dts/sama5d3_uart.dtsi | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/arm/boot/dts/sama5d3_can.dtsi b/arch/arm/boot/dts/sama5d3_can.dtsi index eaf41451ad0c..c5a3772741bf 100644 --- a/arch/arm/boot/dts/sama5d3_can.dtsi +++ b/arch/arm/boot/dts/sama5d3_can.dtsi @@ -1,5 +1,5 @@ /* - * at91sama5d3_can.dtsi - Device Tree Include file for AT91SAM9x5 SoC with + * sama5d3_can.dtsi - Device Tree Include file for SAMA5D3 SoC with * CAN support * * Copyright (C) 2013 Boris BREZILLON diff --git a/arch/arm/boot/dts/sama5d3_emac.dtsi b/arch/arm/boot/dts/sama5d3_emac.dtsi index fe2af9276312..ca4094d8d0fc 100644 --- a/arch/arm/boot/dts/sama5d3_emac.dtsi +++ b/arch/arm/boot/dts/sama5d3_emac.dtsi @@ -1,5 +1,5 @@ /* - * at91sama5d3_emac.dtsi - Device Tree Include file for AT91SAM9x5 SoC with + * sama5d3_emac.dtsi - Device Tree Include file for SAMA5D3 SoC with * Ethernet. * * Copyright (C) 2013 Boris BREZILLON diff --git a/arch/arm/boot/dts/sama5d3_gmac.dtsi b/arch/arm/boot/dts/sama5d3_gmac.dtsi index de5ed59fb446..23f225fbb756 100644 --- a/arch/arm/boot/dts/sama5d3_gmac.dtsi +++ b/arch/arm/boot/dts/sama5d3_gmac.dtsi @@ -1,5 +1,5 @@ /* - * at91sama5d3_gmac.dtsi - Device Tree Include file for AT91SAM9x5 SoC with + * sama5d3_gmac.dtsi - Device Tree Include file for SAMA5D3 SoC with * Gigabit Ethernet. * * Copyright (C) 2013 Boris BREZILLON diff --git a/arch/arm/boot/dts/sama5d3_lcd.dtsi b/arch/arm/boot/dts/sama5d3_lcd.dtsi index 85d302701565..8aeff6c122aa 100644 --- a/arch/arm/boot/dts/sama5d3_lcd.dtsi +++ b/arch/arm/boot/dts/sama5d3_lcd.dtsi @@ -1,5 +1,5 @@ /* - * at91sama5d3_lcd.dtsi - Device Tree Include file for AT91SAM9x5 SoC with + * sama5d3_lcd.dtsi - Device Tree Include file for SAMA5D3 SoC with * LCD support * * Copyright (C) 2013 Boris BREZILLON diff --git a/arch/arm/boot/dts/sama5d3_mci2.dtsi b/arch/arm/boot/dts/sama5d3_mci2.dtsi index 1b02208ea6ff..026b252f09b3 100644 --- a/arch/arm/boot/dts/sama5d3_mci2.dtsi +++ b/arch/arm/boot/dts/sama5d3_mci2.dtsi @@ -1,5 +1,5 @@ /* - * at91sama5d3_mci2.dtsi - Device Tree Include file for AT91SAM9x5 SoC with + * sama5d3_mci2.dtsi - Device Tree Include file for SAMA5D3 SoC with * 3 MMC ports * * Copyright (C) 2013 Boris BREZILLON diff --git a/arch/arm/boot/dts/sama5d3_tcb1.dtsi b/arch/arm/boot/dts/sama5d3_tcb1.dtsi index 02848453ca0c..f7fa58fe09f1 100644 --- a/arch/arm/boot/dts/sama5d3_tcb1.dtsi +++ b/arch/arm/boot/dts/sama5d3_tcb1.dtsi @@ -1,5 +1,5 @@ /* - * at91sama5d3_tcb1.dtsi - Device Tree Include file for AT91SAM9x5 SoC with + * sama5d3_tcb1.dtsi - Device Tree Include file for SAMA5D3 SoC with * 2 TC blocks. * * Copyright (C) 2013 Boris BREZILLON diff --git a/arch/arm/boot/dts/sama5d3_uart.dtsi b/arch/arm/boot/dts/sama5d3_uart.dtsi index 7a8d4c6115f7..2511d748867b 100644 --- a/arch/arm/boot/dts/sama5d3_uart.dtsi +++ b/arch/arm/boot/dts/sama5d3_uart.dtsi @@ -1,5 +1,5 @@ /* - * at91sama5d3_uart.dtsi - Device Tree Include file for AT91SAM9x5 SoC with + * sama5d3_uart.dtsi - Device Tree Include file for SAMA5D3 SoC with * UART support * * Copyright (C) 2013 Boris BREZILLON -- GitLab From 6d39bb019f5ac1e48d8bdc4e88cef290a14058a5 Mon Sep 17 00:00:00 2001 From: Wenyou Yang Date: Wed, 13 Aug 2014 12:58:21 +0800 Subject: [PATCH 02639/11651] ARM: at91/dt: at91-sama5d3_xplained: add gpio-key pinctrl property Signed-off-by: Wenyou Yang Signed-off-by: Nicolas Ferre --- arch/arm/boot/dts/at91-sama5d3_xplained.dts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/arm/boot/dts/at91-sama5d3_xplained.dts b/arch/arm/boot/dts/at91-sama5d3_xplained.dts index fec1fca2ad66..225c63d003d1 100644 --- a/arch/arm/boot/dts/at91-sama5d3_xplained.dts +++ b/arch/arm/boot/dts/at91-sama5d3_xplained.dts @@ -188,6 +188,11 @@ ; }; + pinctrl_key_gpio: key_gpio_0 { + atmel,pins = + ; + }; + pinctrl_mmc0_cd: mmc0_cd { atmel,pins = ; @@ -276,6 +281,9 @@ gpio_keys { compatible = "gpio-keys"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_key_gpio>; + bp3 { label = "PB_USER"; gpios = <&pioE 29 GPIO_ACTIVE_LOW>; -- GitLab From 4f74a4a642eb48e6638fb709039638881f6cf9ed Mon Sep 17 00:00:00 2001 From: Nicolas Ferre Date: Wed, 4 Mar 2015 18:31:03 +0100 Subject: [PATCH 02640/11651] ARM: at91/dt: gpio-keys: address-cells and size-cells properties are not needed Gpio-keys nodes are not using the "reg" property in their sub nodes. So, there is no need to define #address-cells and #size-cells properties in gpio-keys nodes: we remove them in these new boards. Signed-off-by: Nicolas Ferre --- arch/arm/boot/dts/at91-sama5d4ek.dts | 2 -- arch/arm/boot/dts/sama5d35ek.dts | 2 -- 2 files changed, 4 deletions(-) diff --git a/arch/arm/boot/dts/at91-sama5d4ek.dts b/arch/arm/boot/dts/at91-sama5d4ek.dts index 9198b719d0ef..61f537a68ee8 100644 --- a/arch/arm/boot/dts/at91-sama5d4ek.dts +++ b/arch/arm/boot/dts/at91-sama5d4ek.dts @@ -244,8 +244,6 @@ gpio_keys { compatible = "gpio-keys"; - #address-cells = <1>; - #size-cells = <0>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_key_gpio>; diff --git a/arch/arm/boot/dts/sama5d35ek.dts b/arch/arm/boot/dts/sama5d35ek.dts index 9089c7c6cea8..d9a9aca1ccfd 100644 --- a/arch/arm/boot/dts/sama5d35ek.dts +++ b/arch/arm/boot/dts/sama5d35ek.dts @@ -44,8 +44,6 @@ gpio_keys { compatible = "gpio-keys"; - #address-cells = <1>; - #size-cells = <0>; pb_user1 { label = "pb_user1"; -- GitLab From 4cc7cdf35c5f8022fde2d5046a79b52967e390f5 Mon Sep 17 00:00:00 2001 From: Philip Attfield Date: Fri, 6 Feb 2015 14:52:56 +0100 Subject: [PATCH 02641/11651] ARM: at91/dt: add i2c1 declaration to sama5d4 Add alias, node declaration and pinctrl for i2c1 (aka: twi1). Signed-off-by: Philip Attfield Signed-off-by: Nicolas Ferre --- arch/arm/boot/dts/sama5d4.dtsi | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/arch/arm/boot/dts/sama5d4.dtsi b/arch/arm/boot/dts/sama5d4.dtsi index 97d5b9759c07..2f4cf5af2405 100644 --- a/arch/arm/boot/dts/sama5d4.dtsi +++ b/arch/arm/boot/dts/sama5d4.dtsi @@ -67,6 +67,7 @@ tcb0 = &tcb0; tcb1 = &tcb1; i2c0 = &i2c0; + i2c1 = &i2c1; i2c2 = &i2c2; }; cpus { @@ -839,6 +840,25 @@ status = "disabled"; }; + i2c1: i2c@f8018000 { + compatible = "atmel,at91sam9x5-i2c"; + reg = <0xf8018000 0x4000>; + interrupts = <33 IRQ_TYPE_LEVEL_HIGH 6>; + dmas = <&dma1 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)) + AT91_XDMAC_DT_PERID(4)>, + <&dma1 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)) + AT91_XDMAC_DT_PERID(5)>; + dma-names = "tx", "rx"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c1>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&twi1_clk>; + status = "disabled"; + }; + tcb0: timer@f801c000 { compatible = "atmel,at91sam9x5-tcb"; reg = <0xf801c000 0x100>; @@ -1190,6 +1210,14 @@ }; }; + i2c1 { + pinctrl_i2c1: i2c1-0 { + atmel,pins = + ; /* TWCK1, conflicts with UART0 TX and DIBN */ + }; + }; + i2c2 { pinctrl_i2c2: i2c2-0 { atmel,pins = -- GitLab From 1bc54652767637d1be3515129777b83abc997fcc Mon Sep 17 00:00:00 2001 From: Josh Wu Date: Mon, 9 Feb 2015 17:40:20 +0800 Subject: [PATCH 02642/11651] ARM: at91/dt: sama5d4ek: add leds in DT node Add the leds DT node in the dts file. In the leds, d10 is set as heartbeat led. Signed-off-by: Josh Wu Signed-off-by: Nicolas Ferre --- arch/arm/boot/dts/at91-sama5d4ek.dts | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/arch/arm/boot/dts/at91-sama5d4ek.dts b/arch/arm/boot/dts/at91-sama5d4ek.dts index 61f537a68ee8..fbd1ed22bb3e 100644 --- a/arch/arm/boot/dts/at91-sama5d4ek.dts +++ b/arch/arm/boot/dts/at91-sama5d4ek.dts @@ -255,4 +255,26 @@ gpio-key,wakeup; }; }; + + leds { + compatible = "gpio-leds"; + status = "okay"; + + d8 { + label = "d8"; + /* PE28, conflicts with usart4 rts pin */ + gpios = <&pioE 28 GPIO_ACTIVE_LOW>; + }; + + d9 { + label = "d9"; + gpios = <&pioE 9 GPIO_ACTIVE_HIGH>; + }; + + d10 { + label = "d10"; + gpios = <&pioE 8 GPIO_ACTIVE_LOW>; + linux,default-trigger = "heartbeat"; + }; + }; }; -- GitLab From 9917defd8c3928eb89729d1457d9bc438263a3a1 Mon Sep 17 00:00:00 2001 From: Josh Wu Date: Wed, 4 Mar 2015 10:51:47 +0800 Subject: [PATCH 02643/11651] ARM: at91/dt: sama5d4: add #{address, size}_cells properties for macb0 macb0 DT node can have phy child nodes, so add the #{address, size}_cells for macb0 node. Signed-off-by: Josh Wu Signed-off-by: Nicolas Ferre --- arch/arm/boot/dts/sama5d4.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/boot/dts/sama5d4.dtsi b/arch/arm/boot/dts/sama5d4.dtsi index 2f4cf5af2405..f6f2af3d3e84 100644 --- a/arch/arm/boot/dts/sama5d4.dtsi +++ b/arch/arm/boot/dts/sama5d4.dtsi @@ -873,6 +873,8 @@ interrupts = <54 IRQ_TYPE_LEVEL_HIGH 3>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_macb0_rmii>; + #address-cells = <1>; + #size-cells = <0>; clocks = <&macb0_clk>, <&macb0_clk>; clock-names = "hclk", "pclk"; status = "disabled"; -- GitLab From 38153a017896f3a23fa8b4eb41241a8681fc8d6b Mon Sep 17 00:00:00 2001 From: Josh Wu Date: Wed, 4 Mar 2015 10:51:48 +0800 Subject: [PATCH 02644/11651] ARM: at91/dt: sama5d4: add dts for sama5d4 xplained board Add at91 sama5d4 xplained board support. Signed-off-by: Josh Wu Signed-off-by: Nicolas Ferre --- arch/arm/boot/dts/Makefile | 1 + arch/arm/boot/dts/at91-sama5d4_xplained.dts | 237 ++++++++++++++++++++ 2 files changed, 238 insertions(+) create mode 100644 arch/arm/boot/dts/at91-sama5d4_xplained.dts diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index a1c776b8dcec..0fc67d7aac0d 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -42,6 +42,7 @@ dtb-$(CONFIG_SOC_SAM_V7) += \ sama5d34ek.dtb \ sama5d35ek.dtb \ sama5d36ek.dtb \ + at91-sama5d4_xplained.dtb \ at91-sama5d4ek.dtb dtb-$(CONFIG_ARCH_ATLAS6) += \ atlas6-evb.dtb diff --git a/arch/arm/boot/dts/at91-sama5d4_xplained.dts b/arch/arm/boot/dts/at91-sama5d4_xplained.dts new file mode 100644 index 000000000000..772dc98cdb33 --- /dev/null +++ b/arch/arm/boot/dts/at91-sama5d4_xplained.dts @@ -0,0 +1,237 @@ +/* + * at91-sama5d4_xplained.dts - Device Tree file for SAMA5D4 Xplained board + * + * Copyright (C) 2015 Atmel, + * 2015 Josh Wu + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file 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. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +/dts-v1/; +#include "sama5d4.dtsi" + +/ { + model = "Atmel SAMA5D4 Xplained"; + compatible = "atmel,sama5d4-xplained", "atmel,sama5d4", "atmel,sama5"; + + chosen { + bootargs = "console=ttyS0,115200 ignore_loglevel earlyprintk"; + }; + + memory { + reg = <0x20000000 0x20000000>; + }; + + clocks { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + main_clock: clock@0 { + compatible = "atmel,osc", "fixed-clock"; + clock-frequency = <12000000>; + }; + + slow_xtal { + clock-frequency = <32768>; + }; + + main_xtal { + clock-frequency = <12000000>; + }; + }; + + ahb { + apb { + spi0: spi@f8010000 { + cs-gpios = <&pioC 3 0>, <0>, <0>, <0>; + status = "okay"; + m25p80@0 { + compatible = "atmel,at25df321a"; + spi-max-frequency = <50000000>; + reg = <0>; + }; + }; + + macb0: ethernet@f8020000 { + phy-mode = "rmii"; + status = "okay"; + + phy0: ethernet-phy@1 { + interrupt-parent = <&pioE>; + interrupts = <1 IRQ_TYPE_EDGE_FALLING>; + reg = <1>; + }; + }; + + mmc1: mmc@fc000000 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_mmc1_clk_cmd_dat0 &pinctrl_mmc1_dat1_3 &pinctrl_mmc1_cd>; + status = "okay"; + slot@0 { + reg = <0>; + bus-width = <4>; + cd-gpios = <&pioE 3 0>; + }; + }; + + usart3: serial@fc00c000 { + status = "okay"; + }; + + usart4: serial@fc010000 { + status = "okay"; + }; + + adc0: adc@fc034000 { + atmel,adc-vref = <3300>; + status = "okay"; + }; + + watchdog@fc068640 { + status = "okay"; + }; + + pinctrl@fc06a000 { + board { + pinctrl_mmc1_cd: mmc1_cd { + atmel,pins = + ; + }; + pinctrl_usba_vbus: usba_vbus { + atmel,pins = + ; + }; + pinctrl_key_gpio: key_gpio_0 { + atmel,pins = + ; + }; + }; + }; + }; + + usb0: gadget@00400000 { + atmel,vbus-gpio = <&pioE 31 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usba_vbus>; + status = "okay"; + }; + + usb1: ohci@00500000 { + num-ports = <3>; + atmel,vbus-gpio = <0 + &pioE 11 GPIO_ACTIVE_HIGH + &pioE 14 GPIO_ACTIVE_HIGH + >; + status = "okay"; + }; + + usb2: ehci@00600000 { + status = "okay"; + }; + + nand0: nand@80000000 { + nand-bus-width = <8>; + nand-ecc-mode = "hw"; + nand-on-flash-bbt; + atmel,has-pmecc; + status = "okay"; + + at91bootstrap@0 { + label = "at91bootstrap"; + reg = <0x0 0x40000>; + }; + + bootloader@40000 { + label = "bootloader"; + reg = <0x40000 0x80000>; + }; + + bootloaderenv@c0000 { + label = "bootloader env"; + reg = <0xc0000 0xc0000>; + }; + + dtb@180000 { + label = "device tree"; + reg = <0x180000 0x80000>; + }; + + kernel@200000 { + label = "kernel"; + reg = <0x200000 0x600000>; + }; + + rootfs@800000 { + label = "rootfs"; + reg = <0x800000 0x0f800000>; + }; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_key_gpio>; + + pb_user1 { + label = "pb_user1"; + gpios = <&pioE 8 GPIO_ACTIVE_HIGH>; + linux,code = <0x100>; + gpio-key,wakeup; + }; + }; + + leds { + compatible = "gpio-leds"; + status = "okay"; + + d8 { + label = "d8"; + gpios = <&pioD 30 GPIO_ACTIVE_HIGH>; + status = "disabled"; + }; + + d10 { + label = "d10"; + gpios = <&pioE 15 GPIO_ACTIVE_LOW>; + linux,default-trigger = "heartbeat"; + }; + }; +}; -- GitLab From df99d08ccd1db44bba746fea31de8e7bfb08c6d6 Mon Sep 17 00:00:00 2001 From: Nicolas Ferre Date: Thu, 26 Feb 2015 16:05:14 +0100 Subject: [PATCH 02645/11651] ARM: at91/dt: sama5d4 xplained: add i2c0 Add i2c0 aka twi0 on sama5d4 xplained board. Signed-off-by: Nicolas Ferre --- arch/arm/boot/dts/at91-sama5d4_xplained.dts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm/boot/dts/at91-sama5d4_xplained.dts b/arch/arm/boot/dts/at91-sama5d4_xplained.dts index 772dc98cdb33..c740e1a2a3a5 100644 --- a/arch/arm/boot/dts/at91-sama5d4_xplained.dts +++ b/arch/arm/boot/dts/at91-sama5d4_xplained.dts @@ -88,6 +88,10 @@ }; }; + i2c0: i2c@f8014000 { + status = "okay"; + }; + macb0: ethernet@f8020000 { phy-mode = "rmii"; status = "okay"; -- GitLab From 0697edd7b7c57b533f286e2101699af9ec59564d Mon Sep 17 00:00:00 2001 From: Bo Shen Date: Mon, 2 Feb 2015 14:51:44 +0800 Subject: [PATCH 02646/11651] ARM: at91: dt: sama5d4: add ssc nodes Add SSC 0 and 1 nodes. Signed-off-by: Bo Shen Signed-off-by: Nicolas Ferre --- arch/arm/boot/dts/sama5d4.dtsi | 70 ++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/arch/arm/boot/dts/sama5d4.dtsi b/arch/arm/boot/dts/sama5d4.dtsi index f6f2af3d3e84..5661b90b0b2b 100644 --- a/arch/arm/boot/dts/sama5d4.dtsi +++ b/arch/arm/boot/dts/sama5d4.dtsi @@ -64,6 +64,8 @@ gpio2 = &pioC; gpio3 = &pioD; gpio4 = &pioE; + ssc0 = &ssc0; + ssc1 = &ssc1; tcb0 = &tcb0; tcb1 = &tcb1; i2c0 = &i2c0; @@ -801,6 +803,24 @@ clock-names = "mci_clk"; }; + ssc0: ssc@f8008000 { + compatible = "atmel,at91sam9g45-ssc"; + reg = <0xf8008000 0x4000>; + interrupts = <48 IRQ_TYPE_LEVEL_HIGH 0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ssc0_tx &pinctrl_ssc0_rx>; + dmas = <&dma1 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(26))>, + <&dma1 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(27))>; + dma-names = "tx", "rx"; + clocks = <&ssc0_clk>; + clock-names = "pclk"; + status = "disabled"; + }; + spi0: spi@f8010000 { #address-cells = <1>; #size-cells = <0>; @@ -975,6 +995,24 @@ status = "disabled"; }; + ssc1: ssc@fc014000 { + compatible = "atmel,at91sam9g45-ssc"; + reg = <0xfc014000 0x4000>; + interrupts = <49 IRQ_TYPE_LEVEL_HIGH 0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ssc1_tx &pinctrl_ssc1_rx>; + dmas = <&dma1 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(28))>, + <&dma1 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(29))>; + dma-names = "tx", "rx"; + clocks = <&ssc1_clk>; + clock-names = "pclk"; + status = "disabled"; + }; + tcb1: timer@fc020000 { compatible = "atmel,at91sam9x5-tcb"; reg = <0xfc020000 0x100>; @@ -1311,6 +1349,38 @@ }; }; + ssc0 { + pinctrl_ssc0_tx: ssc0_tx { + atmel,pins = + ; /* TD0 */ + }; + + pinctrl_ssc0_rx: ssc0_rx { + atmel,pins = + ; /* RD0 */ + }; + }; + + ssc1 { + pinctrl_ssc1_tx: ssc1_tx { + atmel,pins = + ; /* TD1 */ + }; + + pinctrl_ssc1_rx: ssc1_rx { + atmel,pins = + ; /* RD1 */ + }; + }; + usart2 { pinctrl_usart2: usart2-0 { atmel,pins = -- GitLab From 06981c51f82464f946cea6843fd17cacfd4c59a6 Mon Sep 17 00:00:00 2001 From: Bo Shen Date: Mon, 2 Feb 2015 14:51:45 +0800 Subject: [PATCH 02647/11651] ARM: at91: dt: sama5d4ek: enable ssc0 Enable SSC0 node, which will be used for audio. Signed-off-by: Bo Shen Signed-off-by: Nicolas Ferre --- arch/arm/boot/dts/at91-sama5d4ek.dts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm/boot/dts/at91-sama5d4ek.dts b/arch/arm/boot/dts/at91-sama5d4ek.dts index fbd1ed22bb3e..e8e20164aa31 100644 --- a/arch/arm/boot/dts/at91-sama5d4ek.dts +++ b/arch/arm/boot/dts/at91-sama5d4ek.dts @@ -115,6 +115,10 @@ }; }; + ssc0: ssc@f8008000 { + status = "okay"; + }; + spi0: spi@f8010000 { cs-gpios = <&pioC 3 0>, <0>, <0>, <0>; status = "okay"; -- GitLab From 5afd9451cf6c20e8bbd0dc5713141295a1d8f38c Mon Sep 17 00:00:00 2001 From: Bo Shen Date: Mon, 2 Feb 2015 14:51:46 +0800 Subject: [PATCH 02648/11651] ARM: at91: dt: sama5d4ek: add and enable wm8904 Add wm8904 codec node and enable it. Signed-off-by: Bo Shen Signed-off-by: Nicolas Ferre --- arch/arm/boot/dts/at91-sama5d4ek.dts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm/boot/dts/at91-sama5d4ek.dts b/arch/arm/boot/dts/at91-sama5d4ek.dts index e8e20164aa31..957e66b112c1 100644 --- a/arch/arm/boot/dts/at91-sama5d4ek.dts +++ b/arch/arm/boot/dts/at91-sama5d4ek.dts @@ -131,6 +131,13 @@ i2c0: i2c@f8014000 { status = "okay"; + + wm8904: codec@1a { + compatible = "wlf,wm8904"; + reg = <0x1a>; + clocks = <&pck2>; + clock-names = "mclk"; + }; }; macb0: ethernet@f8020000 { -- GitLab From 15ff964dd45877278aaae20c00ef5977138976c8 Mon Sep 17 00:00:00 2001 From: Bo Shen Date: Mon, 2 Feb 2015 14:51:47 +0800 Subject: [PATCH 02649/11651] ARM: at91: dt: sama5d4ek: enable audio Enable audio support for sama5d4ek board. Signed-off-by: Bo Shen Signed-off-by: Nicolas Ferre --- arch/arm/boot/dts/at91-sama5d4ek.dts | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/arch/arm/boot/dts/at91-sama5d4ek.dts b/arch/arm/boot/dts/at91-sama5d4ek.dts index 957e66b112c1..89ef4a540db5 100644 --- a/arch/arm/boot/dts/at91-sama5d4ek.dts +++ b/arch/arm/boot/dts/at91-sama5d4ek.dts @@ -182,6 +182,10 @@ atmel,pins = ; }; + pinctrl_pck2_as_audio_mck: pck2_as_audio_mck { + atmel,pins = + ; + }; pinctrl_usba_vbus: usba_vbus { atmel,pins = ; @@ -288,4 +292,20 @@ linux,default-trigger = "heartbeat"; }; }; + + sound { + compatible = "atmel,asoc-wm8904"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pck2_as_audio_mck>; + + atmel,model = "wm8904 @ SAMA5D4EK"; + atmel,audio-routing = + "Headphone Jack", "HPOUTL", + "Headphone Jack", "HPOUTR", + "IN1L", "Line In Jack", + "IN1R", "Line In Jack"; + + atmel,ssc-controller = <&ssc0>; + atmel,audio-codec = <&wm8904>; + }; }; -- GitLab From 83906783b7663b9245ea6d668c8af4b4697f463b Mon Sep 17 00:00:00 2001 From: Leilei Zhao Date: Fri, 9 Jan 2015 16:58:57 +0100 Subject: [PATCH 02650/11651] ARM: at91/dt: sama5d4: add aes, sha and tdes nodes Signed-off-by: Leilei Zhao Signed-off-by: Ludovic Desroches Signed-off-by: Nicolas Ferre --- arch/arm/boot/dts/sama5d4.dtsi | 40 ++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/arch/arm/boot/dts/sama5d4.dtsi b/arch/arm/boot/dts/sama5d4.dtsi index 5661b90b0b2b..93dc4e374b64 100644 --- a/arch/arm/boot/dts/sama5d4.dtsi +++ b/arch/arm/boot/dts/sama5d4.dtsi @@ -1068,6 +1068,46 @@ }; }; + aes@fc044000 { + compatible = "atmel,at91sam9g46-aes"; + reg = <0xfc044000 0x100>; + interrupts = <12 IRQ_TYPE_LEVEL_HIGH 0>; + dmas = <&dma0 (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)) + AT91_XDMAC_DT_PERID(41)>, + <&dma0 (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)) + AT91_XDMAC_DT_PERID(40)>; + dma-names = "tx", "rx"; + clocks = <&aes_clk>; + clock-names = "aes_clk"; + status = "disabled"; + }; + + tdes@fc04c000 { + compatible = "atmel,at91sam9g46-tdes"; + reg = <0xfc04c000 0x100>; + interrupts = <14 IRQ_TYPE_LEVEL_HIGH 0>; + dmas = <&dma0 (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)) + AT91_XDMAC_DT_PERID(42)>, + <&dma0 (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)) + AT91_XDMAC_DT_PERID(43)>; + dma-names = "tx", "rx"; + clocks = <&tdes_clk>; + clock-names = "tdes_clk"; + status = "disabled"; + }; + + sha@fc050000 { + compatible = "atmel,at91sam9g46-sha"; + reg = <0xfc050000 0x100>; + interrupts = <15 IRQ_TYPE_LEVEL_HIGH 0>; + dmas = <&dma0 (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)) + AT91_XDMAC_DT_PERID(44)>; + dma-names = "tx"; + clocks = <&sha_clk>; + clock-names = "sha_clk"; + status = "disabled"; + }; + rstc@fc068600 { compatible = "atmel,at91sam9g45-rstc"; reg = <0xfc068600 0x10>; -- GitLab From 0a5c5f84a51450c8772f4212d85262ddb8f75b14 Mon Sep 17 00:00:00 2001 From: Bo Shen Date: Fri, 9 Jan 2015 17:11:05 +0100 Subject: [PATCH 02651/11651] ARM: at91/dt: sama5d4: add pwm0 device node Signed-off-by: Bo Shen Signed-off-by: Nicolas Ferre --- arch/arm/boot/dts/sama5d4.dtsi | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/arm/boot/dts/sama5d4.dtsi b/arch/arm/boot/dts/sama5d4.dtsi index 93dc4e374b64..3041baaa19a1 100644 --- a/arch/arm/boot/dts/sama5d4.dtsi +++ b/arch/arm/boot/dts/sama5d4.dtsi @@ -64,6 +64,7 @@ gpio2 = &pioC; gpio3 = &pioD; gpio4 = &pioE; + pwm0 = &pwm0; ssc0 = &ssc0; ssc1 = &ssc1; tcb0 = &tcb0; @@ -821,6 +822,15 @@ status = "disabled"; }; + pwm0: pwm@f800c000 { + compatible = "atmel,sama5d3-pwm"; + reg = <0xf800c000 0x300>; + interrupts = <43 IRQ_TYPE_LEVEL_HIGH 4>; + #pwm-cells = <3>; + clocks = <&pwm_clk>; + status = "disabled"; + }; + spi0: spi@f8010000 { #address-cells = <1>; #size-cells = <0>; -- GitLab From 35762a624f82dbea7c62177bf3ef0cde0d0f84bc Mon Sep 17 00:00:00 2001 From: Josh Wu Date: Fri, 23 Jan 2015 16:38:03 +0800 Subject: [PATCH 02652/11651] ARM: at91/dt: sama5d4: add ISI dt support Add ISI dt node and pinctrl settings in sama5d4.dtsi. Signed-off-by: Josh Wu [nicolas.ferre@atmel.com: sort nodes in order. remove useless comments] Signed-off-by: Nicolas Ferre --- arch/arm/boot/dts/sama5d4.dtsi | 42 ++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/arch/arm/boot/dts/sama5d4.dtsi b/arch/arm/boot/dts/sama5d4.dtsi index 3041baaa19a1..63eb7a2c08f7 100644 --- a/arch/arm/boot/dts/sama5d4.dtsi +++ b/arch/arm/boot/dts/sama5d4.dtsi @@ -323,6 +323,21 @@ clock-names = "dma_clk"; }; + isi: isi@f0008000 { + compatible = "atmel,at91sam9g45-isi"; + reg = <0xf0008000 0x4000>; + interrupts = <52 IRQ_TYPE_LEVEL_HIGH 5>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_isi_data_0_7>; + clocks = <&isi_clk>; + clock-names = "isi_clk"; + status = "disabled"; + port { + #address-cells = <1>; + #size-cells = <0>; + }; + }; + ramc0: ramc@f0010000 { compatible = "atmel,sama5d3-ddramc"; reg = <0xf0010000 0x200>; @@ -1316,6 +1331,33 @@ }; }; + isi { + pinctrl_isi_data_0_7: isi-0-data-0-7 { + atmel,pins = + ; /* ISI_HSYNC */ + }; + pinctrl_isi_data_8_9: isi-0-data-8-9 { + atmel,pins = + ; /* ISI_D9, conflicts with SPI0_MOSI, PWML2 */ + }; + pinctrl_isi_data_10_11: isi-0-data-10-11 { + atmel,pins = + ; /* ISI_D11, conflicts with SPI0_NPCS0, PWML3 */ + }; + }; + macb0 { pinctrl_macb0_rmii: macb0_rmii-0 { atmel,pins = -- GitLab From 8670c3a55e91cb27a4b4d4d4c4fa35b0149e1abf Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Tue, 3 Mar 2015 20:04:18 +0000 Subject: [PATCH 02653/11651] netfilter: nf_tables: fix transaction race condition A race condition exists in the rule transaction code for rules that get added and removed within the same transaction. The new rule starts out as inactive in the current and active in the next generation and is inserted into the ruleset. When it is deleted, it is additionally set to inactive in the next generation as well. On commit the next generation is begun, then the actions are finalized. For the new rule this would mean clearing out the inactive bit for the previously current, now next generation. However nft_rule_clear() clears out the bits for *both* generations, activating the rule in the current generation, where it should be deactivated due to being deleted. The rule will thus be active until the deletion is finalized, removing the rule from the ruleset. Similarly, when aborting a transaction for the same case, the undo of insertion will remove it from the RCU protected rule list, the deletion will clear out all bits. However until the next RCU synchronization after all operations have been undone, the rule is active on CPUs which can still see the rule on the list. Generally, there may never be any modifications of the current generations' inactive bit since this defeats the entire purpose of atomicity. Change nft_rule_clear() to only touch the next generations bit to fix this. Signed-off-by: Patrick McHardy Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nf_tables_api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index a8c94620f20e..6fb532bf0fdb 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -227,7 +227,7 @@ nft_rule_deactivate_next(struct net *net, struct nft_rule *rule) static inline void nft_rule_clear(struct net *net, struct nft_rule *rule) { - rule->genmask = 0; + rule->genmask &= ~(1 << gencursor_next(net)); } static int -- GitLab From 9889840f5988ecfd43b00c9abb83c1804e21406b Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Tue, 3 Mar 2015 20:04:19 +0000 Subject: [PATCH 02654/11651] netfilter: nf_tables: check for overflow of rule dlen field Check that the space required for the expressions doesn't exceed the size of the dlen field, which would lead to the iterators crashing. Signed-off-by: Patrick McHardy Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nf_tables_api.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 6fb532bf0fdb..7baafd5ab520 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -1968,6 +1968,10 @@ static int nf_tables_newrule(struct sock *nlsk, struct sk_buff *skb, n++; } } + /* Check for overflow of dlen field */ + err = -EFBIG; + if (size >= 1 << 12) + goto err1; if (nla[NFTA_RULE_USERDATA]) ulen = nla_len(nla[NFTA_RULE_USERDATA]); -- GitLab From 86f1ec32318159a24de349f0a38e79b9d2b3131a Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Tue, 3 Mar 2015 20:04:20 +0000 Subject: [PATCH 02655/11651] netfilter: nf_tables: fix userdata length overflow The NFT_USERDATA_MAXLEN is defined to 256, however we only have a u8 to store its size. Introduce a struct nft_userdata which contains a length field and indicate its presence using a single bit in the rule. The length field of struct nft_userdata is also a u8, however we don't store zero sized data, so the actual length is udata->len + 1. Signed-off-by: Patrick McHardy Signed-off-by: Pablo Neira Ayuso --- include/net/netfilter/nf_tables.h | 22 +++++++++++++++++++--- net/netfilter/nf_tables_api.c | 28 +++++++++++++++++++--------- 2 files changed, 38 insertions(+), 12 deletions(-) diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h index 9eaaa7884586..decb9a095ae7 100644 --- a/include/net/netfilter/nf_tables.h +++ b/include/net/netfilter/nf_tables.h @@ -119,6 +119,22 @@ int nft_validate_data_load(const struct nft_ctx *ctx, enum nft_registers reg, const struct nft_data *data, enum nft_data_types type); + +/** + * struct nft_userdata - user defined data associated with an object + * + * @len: length of the data + * @data: content + * + * The presence of user data is indicated in an object specific fashion, + * so a length of zero can't occur and the value "len" indicates data + * of length len + 1. + */ +struct nft_userdata { + u8 len; + unsigned char data[0]; +}; + /** * struct nft_set_elem - generic representation of set elements * @@ -380,7 +396,7 @@ static inline void *nft_expr_priv(const struct nft_expr *expr) * @handle: rule handle * @genmask: generation mask * @dlen: length of expression data - * @ulen: length of user data (used for comments) + * @udata: user data is appended to the rule * @data: expression data */ struct nft_rule { @@ -388,7 +404,7 @@ struct nft_rule { u64 handle:42, genmask:2, dlen:12, - ulen:8; + udata:1; unsigned char data[] __attribute__((aligned(__alignof__(struct nft_expr)))); }; @@ -476,7 +492,7 @@ static inline struct nft_expr *nft_expr_last(const struct nft_rule *rule) return (struct nft_expr *)&rule->data[rule->dlen]; } -static inline void *nft_userdata(const struct nft_rule *rule) +static inline struct nft_userdata *nft_userdata(const struct nft_rule *rule) { return (void *)&rule->data[rule->dlen]; } diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 7baafd5ab520..74e4b876c96e 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -1711,9 +1711,12 @@ static int nf_tables_fill_rule_info(struct sk_buff *skb, struct net *net, } nla_nest_end(skb, list); - if (rule->ulen && - nla_put(skb, NFTA_RULE_USERDATA, rule->ulen, nft_userdata(rule))) - goto nla_put_failure; + if (rule->udata) { + struct nft_userdata *udata = nft_userdata(rule); + if (nla_put(skb, NFTA_RULE_USERDATA, udata->len + 1, + udata->data) < 0) + goto nla_put_failure; + } nlmsg_end(skb, nlh); return 0; @@ -1896,11 +1899,12 @@ static int nf_tables_newrule(struct sock *nlsk, struct sk_buff *skb, struct nft_table *table; struct nft_chain *chain; struct nft_rule *rule, *old_rule = NULL; + struct nft_userdata *udata; struct nft_trans *trans = NULL; struct nft_expr *expr; struct nft_ctx ctx; struct nlattr *tmp; - unsigned int size, i, n, ulen = 0; + unsigned int size, i, n, ulen = 0, usize = 0; int err, rem; bool create; u64 handle, pos_handle; @@ -1973,11 +1977,14 @@ static int nf_tables_newrule(struct sock *nlsk, struct sk_buff *skb, if (size >= 1 << 12) goto err1; - if (nla[NFTA_RULE_USERDATA]) + if (nla[NFTA_RULE_USERDATA]) { ulen = nla_len(nla[NFTA_RULE_USERDATA]); + if (ulen > 0) + usize = sizeof(struct nft_userdata) + ulen; + } err = -ENOMEM; - rule = kzalloc(sizeof(*rule) + size + ulen, GFP_KERNEL); + rule = kzalloc(sizeof(*rule) + size + usize, GFP_KERNEL); if (rule == NULL) goto err1; @@ -1985,10 +1992,13 @@ static int nf_tables_newrule(struct sock *nlsk, struct sk_buff *skb, rule->handle = handle; rule->dlen = size; - rule->ulen = ulen; + rule->udata = ulen ? 1 : 0; - if (ulen) - nla_memcpy(nft_userdata(rule), nla[NFTA_RULE_USERDATA], ulen); + if (ulen) { + udata = nft_userdata(rule); + udata->len = ulen - 1; + nla_memcpy(udata->data, nla[NFTA_RULE_USERDATA], ulen); + } expr = nft_expr_first(rule); for (i = 0; i < n; i++) { -- GitLab From 59900e0a019e7c2bdb7809a03ed5742d311b15b3 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Wed, 4 Mar 2015 17:55:27 +0100 Subject: [PATCH 02656/11651] netfilter: nf_tables: fix error handling of rule replacement In general, if a transaction object is added to the list successfully, we can rely on the abort path to undo what we've done. This allows us to simplify the error handling of the rule replacement path in nf_tables_newrule(). This implicitly fixes an unnecessary removal of the old rule, which needs to be left in place if we fail to replace. Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nf_tables_api.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 74e4b876c96e..6ab777912237 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -2045,12 +2045,6 @@ static int nf_tables_newrule(struct sock *nlsk, struct sk_buff *skb, err3: list_del_rcu(&rule->list); - if (trans) { - list_del_rcu(&nft_trans_rule(trans)->list); - nft_rule_clear(net, nft_trans_rule(trans)); - nft_trans_destroy(trans); - chain->use++; - } err2: nf_tables_rule_destroy(&ctx, rule); err1: -- GitLab From de04261d5ac26c523a9737980d1e4f580f0e48f7 Mon Sep 17 00:00:00 2001 From: Vince Bridgers Date: Wed, 11 Feb 2015 18:34:25 +0000 Subject: [PATCH 02657/11651] ARM: socfpga: Correct SCU virtual mapping in socfpga Correct SCU virtual mapping that was causing this BUG message: "BUG: mapping for 0xfffec000 at 0xfffec000 out of vmalloc space" Signed-off-by: Vince Bridgers Signed-off-by: Dinh Nguyen --- arch/arm/mach-socfpga/core.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-socfpga/core.h b/arch/arm/mach-socfpga/core.h index 483cb467bf65..a0f3b1cd497c 100644 --- a/arch/arm/mach-socfpga/core.h +++ b/arch/arm/mach-socfpga/core.h @@ -45,6 +45,6 @@ extern char secondary_trampoline, secondary_trampoline_end; extern unsigned long socfpga_cpu1start_addr; -#define SOCFPGA_SCU_VIRT_BASE 0xfffec000 +#define SOCFPGA_SCU_VIRT_BASE 0xfee00000 #endif -- GitLab From 78c03c7af89721bd8a4428408a8cc7b53972e4b8 Mon Sep 17 00:00:00 2001 From: Steffen Trumtrar Date: Thu, 19 Feb 2015 12:07:52 +0000 Subject: [PATCH 02658/11651] ARM: socfpga: fix uart DMA binding error socfpga.dtsi is missing the DMA channels for the uart nodes. This will produce the following errors: of_dma_request_slave_channel: dma-names property of node '/soc/serial0@ffc02000' missing or empty ttyS0 - failed to request DMA Provide the correct DMA channels to fix this. Signed-off-by: Steffen Trumtrar Signed-off-by: Dinh Nguyen --- arch/arm/boot/dts/socfpga.dtsi | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm/boot/dts/socfpga.dtsi b/arch/arm/boot/dts/socfpga.dtsi index 252c3d1bda50..9d8760956752 100644 --- a/arch/arm/boot/dts/socfpga.dtsi +++ b/arch/arm/boot/dts/socfpga.dtsi @@ -713,6 +713,9 @@ reg-shift = <2>; reg-io-width = <4>; clocks = <&l4_sp_clk>; + dmas = <&pdma 28>, + <&pdma 29>; + dma-names = "tx", "rx"; }; uart1: serial1@ffc03000 { @@ -722,6 +725,9 @@ reg-shift = <2>; reg-io-width = <4>; clocks = <&l4_sp_clk>; + dmas = <&pdma 30>, + <&pdma 31>; + dma-names = "tx", "rx"; }; rst: rstmgr@ffd05000 { -- GitLab From cee9b8d6b8b7d82bfb34e4700d839aec76519f02 Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 25 Feb 2015 10:24:25 -0600 Subject: [PATCH 02659/11651] ARM: socfpga: make sure socfpga_cpu1start_addr is properly flushed Make sure socfpga_cpu1start_addr is properly flushed from it's cache line so that secondary cpu's can see it. Signed-off-by: Russell King Tested-by: Steffen Trumtrar Signed-off-by: Dinh Nguyen --- arch/arm/mach-socfpga/socfpga.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm/mach-socfpga/socfpga.c b/arch/arm/mach-socfpga/socfpga.c index 383d61e138af..f5e597c207b9 100644 --- a/arch/arm/mach-socfpga/socfpga.c +++ b/arch/arm/mach-socfpga/socfpga.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "core.h" @@ -73,6 +74,10 @@ void __init socfpga_sysmgr_init(void) (u32 *) &socfpga_cpu1start_addr)) pr_err("SMP: Need cpu1-start-addr in device tree.\n"); + /* Ensure that socfpga_cpu1start_addr is visible to other CPUs */ + smp_wmb(); + sync_cache_w(&socfpga_cpu1start_addr); + sys_manager_base_addr = of_iomap(np, 0); np = of_find_compatible_node(NULL, NULL, "altr,rst-mgr"); -- GitLab From ef59c25d1be9539890c03c4915cdd4b868191b6f Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Tue, 3 Mar 2015 13:22:32 +0100 Subject: [PATCH 02660/11651] platform/chrome: cros_ec_dev - fix Unknown escape '%' warning Fix the following sparse warning: drivers/platform/chrome/cros_ec_dev.c:64:45: sparse: Unknown escape '%' Reported-by: Dan Carpenter Signed-off-by: Olof Johansson Reviewed-by: Gwendal Grignou Signed-off-by: Javier Martinez Canillas Signed-off-by: Olof Johansson --- drivers/platform/chrome/cros_ec_dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/platform/chrome/cros_ec_dev.c b/drivers/platform/chrome/cros_ec_dev.c index ce714317a59e..6090d0b2826f 100644 --- a/drivers/platform/chrome/cros_ec_dev.c +++ b/drivers/platform/chrome/cros_ec_dev.c @@ -61,7 +61,7 @@ static int ec_get_version(struct cros_ec_device *ec, char *str, int maxlen) if (resp->current_image >= ARRAY_SIZE(current_image_name)) resp->current_image = 3; /* invalid */ - snprintf(str, maxlen, "%s\n%s\n%s\n\%s\n", CROS_EC_DEV_VERSION, + snprintf(str, maxlen, "%s\n%s\n%s\n%s\n", CROS_EC_DEV_VERSION, resp->version_string_ro, resp->version_string_rw, current_image_name[resp->current_image]); -- GitLab From 377415abab7b49c982475990cd06eef9f33e2ccc Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Tue, 3 Mar 2015 13:22:33 +0100 Subject: [PATCH 02661/11651] platform/chrome: cros_ec_lightbar - fix duplicate const warning Fix the following sparse warning: drivers/platform/chrome/cros_ec_lightbar.c:254:25: sparse: duplicate const Reported-by: Dan Carpenter Signed-off-by: Olof Johansson Reviewed-by: Gwendal Grignou Signed-off-by: Javier Martinez Canillas Signed-off-by: Olof Johansson --- drivers/platform/chrome/cros_ec_lightbar.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/platform/chrome/cros_ec_lightbar.c b/drivers/platform/chrome/cros_ec_lightbar.c index 35fc892e4c95..b4ff47a9069a 100644 --- a/drivers/platform/chrome/cros_ec_lightbar.c +++ b/drivers/platform/chrome/cros_ec_lightbar.c @@ -251,7 +251,7 @@ static ssize_t led_rgb_store(struct device *dev, struct device_attribute *attr, return (ok && i == 0) ? count : -EINVAL; } -static const char const *seqname[] = { +static char const *seqname[] = { "ERROR", "S5", "S3", "S0", "S5S3", "S3S0", "S0S3", "S3S5", "STOP", "RUN", "PULSE", "TEST", "KONAMI", }; -- GitLab From 88999ae23bbd490d14e15e22b4e8650c75e7e90a Mon Sep 17 00:00:00 2001 From: kbuild test robot Date: Fri, 27 Feb 2015 09:09:01 +0800 Subject: [PATCH 02662/11651] platform/chrome: fix platform_no_drv_owner.cocci warnings drivers/platform/chrome/cros_ec_lpc.c:272:3-8: No need to set .owner here. The core will do it. Remove .owner field if calls are used which set it automatically Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci CC: Bill Richardson Signed-off-by: Fengguang Wu Signed-off-by: Olof Johansson --- drivers/platform/chrome/cros_ec_lpc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/platform/chrome/cros_ec_lpc.c b/drivers/platform/chrome/cros_ec_lpc.c index 822fdb36ded9..4bba5ecef9e0 100644 --- a/drivers/platform/chrome/cros_ec_lpc.c +++ b/drivers/platform/chrome/cros_ec_lpc.c @@ -269,7 +269,6 @@ MODULE_DEVICE_TABLE(dmi, cros_ec_lpc_dmi_table); static struct platform_driver cros_ec_lpc_driver = { .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, }, .probe = cros_ec_lpc_probe, .remove = cros_ec_lpc_remove, -- GitLab From 18d0dc24661b42c03074fc89bc89bc0f7c63d2bc Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Fri, 27 Feb 2015 06:37:48 +0100 Subject: [PATCH 02663/11651] platform/chrome: cros_ec_lpc - Include linux/io.h header file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The driver uses the inb() and outb() I/O functions so should include the header file that has these functions definitions. This patch fixes the following error when the header is not explicitly included: drivers/platform/chrome//cros_ec_lpc.c: In function ‘ec_response_timed_out’: drivers/platform/chrome//cros_ec_lpc.c:40:3: error: implicit declaration of function ‘inb’ [-Werror=implicit-function-declaration] drivers/platform/chrome//cros_ec_lpc.c: In function ‘cros_ec_cmd_xfer_lpc’: drivers/platform/chrome//cros_ec_lpc.c:75:3: error: implicit declaration of function ‘outb’ [-Werror=implicit-function-declaration] Signed-off-by: Javier Martinez Canillas Signed-off-by: Olof Johansson --- drivers/platform/chrome/cros_ec_lpc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/platform/chrome/cros_ec_lpc.c b/drivers/platform/chrome/cros_ec_lpc.c index 4bba5ecef9e0..8f9ac4d7bbd0 100644 --- a/drivers/platform/chrome/cros_ec_lpc.c +++ b/drivers/platform/chrome/cros_ec_lpc.c @@ -23,6 +23,7 @@ #include #include +#include #include #include #include -- GitLab From 8ce580932f8ee40903017a6f1408ccfff319a6a5 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Fri, 27 Feb 2015 06:37:49 +0100 Subject: [PATCH 02664/11651] platform/chrome: cros_ec_lpc - Depend on X86 || COMPILE_TEST The ChromeOS EC is connected by LPC only on x86 platforms and no others, so add a dependency describing that. But also build the driver if the COMPILE_TEST option is enabled to have build coverage in other architectures. Signed-off-by: Javier Martinez Canillas [olof: reworded commit message] Signed-off-by: Olof Johansson --- drivers/platform/chrome/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/platform/chrome/Kconfig b/drivers/platform/chrome/Kconfig index d4befbffae85..2a6531a5fde8 100644 --- a/drivers/platform/chrome/Kconfig +++ b/drivers/platform/chrome/Kconfig @@ -49,7 +49,7 @@ config CROS_EC_CHARDEV config CROS_EC_LPC tristate "ChromeOS Embedded Controller (LPC)" - depends on MFD_CROS_EC + depends on MFD_CROS_EC && (X86 || COMPILE_TEST) help If you say Y here, you get support for talking to the ChromeOS EC over an LPC bus. This uses a simple byte-level protocol with a -- GitLab From d55ce8d818a992cef7de014ed1b86108cf3f27a4 Mon Sep 17 00:00:00 2001 From: Andy Yan Date: Sun, 1 Mar 2015 17:28:24 +0800 Subject: [PATCH 02665/11651] dt-bindings: add root compatible property for PopMetal board PopMetal board is a rk3288 based board made by ChipSpark, this add root compatible property for it Signed-off-by: Andy Yan Signed-off-by: Heiko Stuebner --- Documentation/devicetree/bindings/arm/rockchip.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/arm/rockchip.txt b/Documentation/devicetree/bindings/arm/rockchip.txt index 6809e4e51ed2..60d4a1e0a9b5 100644 --- a/Documentation/devicetree/bindings/arm/rockchip.txt +++ b/Documentation/devicetree/bindings/arm/rockchip.txt @@ -22,3 +22,7 @@ Rockchip platforms device tree bindings - compatible = "firefly,firefly-rk3288", "rockchip,rk3288"; or - compatible = "firefly,firefly-rk3288-beta", "rockchip,rk3288"; + +- ChipSPARK PopMetal-RK3288 board: + Required root node properties: + - compatible = "chipspark,popmetal-rk3288", "rockchip,rk3288"; -- GitLab From c38e1328ceadc0b345ddd914c13ac1abfb048209 Mon Sep 17 00:00:00 2001 From: Andy Yan Date: Sun, 1 Mar 2015 17:32:33 +0800 Subject: [PATCH 02666/11651] ARM: dts: add rk3288 PopMetal board PopMetal is a rockchip rk3288 based board made by ChipSpark, which has many interface such as VGA,HDMI,usb,ir,sdcad and lots of sensors such as gyroscope(L3G4200D),accelerometer(mma8452), compass(AK8963C). This patch add a basic support for this board, which make the board boot into a initramfs shell with sdcard,hdmi and all sensors enabled Signed-off-by: Andy Yan Signed-off-by: Heiko Stuebner --- arch/arm/boot/dts/rk3288-popmetal.dts | 447 ++++++++++++++++++++++++++ 1 file changed, 447 insertions(+) create mode 100644 arch/arm/boot/dts/rk3288-popmetal.dts diff --git a/arch/arm/boot/dts/rk3288-popmetal.dts b/arch/arm/boot/dts/rk3288-popmetal.dts new file mode 100644 index 000000000000..d081f0e0da36 --- /dev/null +++ b/arch/arm/boot/dts/rk3288-popmetal.dts @@ -0,0 +1,447 @@ +/* + * Copyright (c) 2014, 2015 Andy Yan + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file 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. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; + +#include "rk3288.dtsi" + +/ { + model = "PopMetal-RK3288"; + compatible = "chipspark,popmetal-rk3288", "rockchip,rk3288"; + + memory{ + reg = <0 0x80000000>; + }; + + ext_gmac: external-gmac-clock { + compatible = "fixed-clock"; + clock-frequency = <125000000>; + clock-output-names = "ext_gmac"; + #clock-cells = <0>; + }; + + gpio-keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + autorepeat; + + pinctrl-names = "default"; + pinctrl-0 = <&pwrbtn>; + + button@0 { + gpios = <&gpio0 5 GPIO_ACTIVE_LOW>; + linux,code = <116>; + label = "GPIO Key Power"; + linux,input-type = <1>; + gpio-key,wakeup = <1>; + debounce-interval = <100>; + }; + }; + + ir: ir-receiver { + compatible = "gpio-ir-receiver"; + gpios = <&gpio0 6 GPIO_ACTIVE_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&ir_int>; + }; + + vcc_sys: vsys-regulator { + compatible = "regulator-fixed"; + regulator-name = "vcc_sys"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + regulator-boot-on; + }; +}; + +&cpu0 { + cpu0-supply = <&vdd_cpu>; +}; + +&emmc { + broken-cd; + bus-width = <8>; + cap-mmc-highspeed; + disable-wp; + non-removable; + num-slots = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_pwr &emmc_bus8>; + status = "okay"; +}; + +&sdmmc { + bus-width = <4>; + cap-mmc-highspeed; + cap-sd-highspeed; + card-detect-delay = <200>; + disable-wp; /* wp not hooked up */ + num-slots = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>; + status = "okay"; +}; + +&gmac { + phy-supply = <&vcc_lan>; + phy-mode = "rgmii"; + clock_in_out = "input"; + snps,reset-gpio = <&gpio4 7 0>; + snps,reset-active-low; + snps,reset-delays-us = <0 10000 1000000>; + assigned-clocks = <&cru SCLK_MAC>; + assigned-clock-parents = <&ext_gmac>; + pinctrl-names = "default"; + pinctrl-0 = <&rgmii_pins>; + tx_delay = <0x30>; + rx_delay = <0x10>; + status = "ok"; +}; + +&hdmi { + ddc-i2c-bus = <&i2c5>; + status = "okay"; +}; + +&i2c0 { + status = "okay"; + clock-frequency = <400000>; + + rk808: pmic@1b { + compatible = "rockchip,rk808"; + reg = <0x1b>; + interrupt-parent = <&gpio0>; + interrupts = <4 IRQ_TYPE_LEVEL_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int &global_pwroff>; + rockchip,system-power-controller; + wakeup-source; + #clock-cells = <1>; + clock-output-names = "xin32k", "rk808-clkout2"; + + vcc1-supply = <&vcc_sys>; + vcc2-supply = <&vcc_sys>; + vcc3-supply = <&vcc_sys>; + vcc4-supply = <&vcc_sys>; + vcc6-supply = <&vcc_sys>; + vcc7-supply = <&vcc_sys>; + vcc8-supply = <&vcc_18>; + vcc9-supply = <&vcc_io>; + vcc10-supply = <&vcc_io>; + vcc11-supply = <&vcc_sys>; + vcc12-supply = <&vcc_io>; + vddio-supply = <&vcc_io>; + + regulators { + vdd_cpu: DCDC_REG1 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <1350000>; + regulator-name = "vdd_arm"; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_gpu: DCDC_REG2 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <1250000>; + regulator-name = "vdd_gpu"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-always-on; + regulator-boot-on; + regulator-name = "vcc_ddr"; + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc_io: DCDC_REG4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc_io"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_lan: LDO_REG1 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc_lan"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vccio_sd: LDO_REG2 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vccio_sd"; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_10: LDO_REG3 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-name = "vdd_10"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + + vcc18_lcd: LDO_REG4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc18_lcd"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + ldo5: LDO_REG5 { + regulator-always-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-name = "ldo5"; + }; + + vdd10_lcd: LDO_REG6 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-name = "vdd10_lcd"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + + vcc_18: LDO_REG7 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc_18"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcca_codec: LDO_REG8 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcca_codec"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_wl: SWITCH_REG1 { + regulator-always-on; + regulator-boot-on; + regulator-name = "vcc_wl"; + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc_lcd: SWITCH_REG2 { + regulator-always-on; + regulator-boot-on; + regulator-name = "vcc_lcd"; + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + }; + }; +}; + +&i2c1 { + status = "okay"; + clock-frequency = <400000>; + + ak8963: ak8963@0d { + compatible = "asahi-kasei,ak8975"; + reg = <0x0d>; + interrupt-parent = <&gpio8>; + interrupts = <1 IRQ_TYPE_EDGE_RISING>; + pinctrl-names = "default"; + pinctrl-0 = <&comp_int>; + }; + + l3g4200d: l3g4200d@68 { + compatible = "st,l3g4200d-gyro"; + st,drdy-int-pin = <2>; + reg = <0x6b>; + }; + + mma8452: mma8452@1d { + compatible = "fsl,mma8452"; + reg = <0x1d>; + interrupt-parent = <&gpio8>; + interrupts = <0 IRQ_TYPE_EDGE_RISING>; + pinctrl-names = "default"; + pinctrl-0 = <&gsensor_int>; + }; +}; + +&i2c2 { + status = "okay"; +}; + +&i2c3 { + status = "okay"; +}; + +&i2c4 { + status = "okay"; +}; + +&i2c5 { + status = "okay"; +}; + +&pinctrl { + ak8963 { + comp_int: comp-int { + rockchip,pins = <8 1 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + buttons { + pwrbtn: pwrbtn { + rockchip,pins = <0 5 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + ir { + ir_int: ir-int { + rockchip,pins = <0 6 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + mma8452 { + gsensor_int: gsensor-int { + rockchip,pins = <8 0 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + pmic { + pmic_int: pmic-int { + rockchip,pins = ; + }; + }; +}; + +&vopb { + status = "okay"; +}; + +&vopb_mmu { + status = "okay"; +}; + +&vopl { + status = "okay"; +}; + +&vopl_mmu { + status = "okay"; +}; + +&uart0 { + status = "okay"; +}; + +&uart1 { + status = "okay"; +}; + +&uart2 { + status = "okay"; +}; + +&uart3 { + status = "okay"; +}; + +&uart4 { + status = "okay"; +}; + +&usbphy { + status = "okay"; +}; -- GitLab From 25b77ad774a88cd7a9a8f63e122d4bda68479267 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 26 Feb 2015 20:33:30 +0000 Subject: [PATCH 02667/11651] sh_eth: Implement multicast statistic based on the RFS8 status bit At least on the R8A7790, RFS8 reflects the RINT8 (multicast) MAC status flag. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/ethernet/renesas/sh_eth.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 736d5d1624a1..8e35ccba6259 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -1500,6 +1500,8 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota) netif_receive_skb(skb); ndev->stats.rx_packets++; ndev->stats.rx_bytes += pkt_len; + if (desc_status & RD_RFS8) + ndev->stats.multicast++; } entry = (++mdp->cur_rx) % mdp->num_rx_ring; rxdesc = &mdp->rx_ring[entry]; -- GitLab From 3365711df024f60d2e1e0ba9b40b6e965ab83bf6 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 26 Feb 2015 20:34:14 +0000 Subject: [PATCH 02668/11651] sh_eth: WARN on access to a register not implemented in a particular chip Currently we may silently read/write a register at offset 0. Change this to WARN and then ignore the write or read-back all-ones. Signed-off-by: Ben Hutchings Acked-by: Sergei Shtylyov Signed-off-by: David S. Miller --- drivers/net/ethernet/renesas/sh_eth.c | 16 +++++++++++++++- drivers/net/ethernet/renesas/sh_eth.h | 14 ++++++++++++-- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 8e35ccba6259..64e72ebdf8c5 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -52,7 +52,12 @@ NETIF_MSG_RX_ERR| \ NETIF_MSG_TX_ERR) +#define SH_ETH_OFFSET_DEFAULTS \ + [0 ... SH_ETH_MAX_REGISTER_OFFSET - 1] = SH_ETH_OFFSET_INVALID + static const u16 sh_eth_offset_gigabit[SH_ETH_MAX_REGISTER_OFFSET] = { + SH_ETH_OFFSET_DEFAULTS, + [EDSR] = 0x0000, [EDMR] = 0x0400, [EDTRR] = 0x0408, @@ -151,6 +156,8 @@ static const u16 sh_eth_offset_gigabit[SH_ETH_MAX_REGISTER_OFFSET] = { }; static const u16 sh_eth_offset_fast_rz[SH_ETH_MAX_REGISTER_OFFSET] = { + SH_ETH_OFFSET_DEFAULTS, + [EDSR] = 0x0000, [EDMR] = 0x0400, [EDTRR] = 0x0408, @@ -210,6 +217,8 @@ static const u16 sh_eth_offset_fast_rz[SH_ETH_MAX_REGISTER_OFFSET] = { }; static const u16 sh_eth_offset_fast_rcar[SH_ETH_MAX_REGISTER_OFFSET] = { + SH_ETH_OFFSET_DEFAULTS, + [ECMR] = 0x0300, [RFLR] = 0x0308, [ECSR] = 0x0310, @@ -256,6 +265,8 @@ static const u16 sh_eth_offset_fast_rcar[SH_ETH_MAX_REGISTER_OFFSET] = { }; static const u16 sh_eth_offset_fast_sh4[SH_ETH_MAX_REGISTER_OFFSET] = { + SH_ETH_OFFSET_DEFAULTS, + [ECMR] = 0x0100, [RFLR] = 0x0108, [ECSR] = 0x0110, @@ -308,6 +319,8 @@ static const u16 sh_eth_offset_fast_sh4[SH_ETH_MAX_REGISTER_OFFSET] = { }; static const u16 sh_eth_offset_fast_sh3_sh2[SH_ETH_MAX_REGISTER_OFFSET] = { + SH_ETH_OFFSET_DEFAULTS, + [EDMR] = 0x0000, [EDTRR] = 0x0004, [EDRRR] = 0x0008, @@ -1544,7 +1557,8 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota) /* If we don't need to check status, don't. -KDU */ if (!(sh_eth_read(ndev, EDRRR) & EDRRR_R)) { /* fix the values for the next receiving if RDE is set */ - if (intr_status & EESR_RDE && mdp->reg_offset[RDFAR] != 0) { + if (intr_status & EESR_RDE && + mdp->reg_offset[RDFAR] != SH_ETH_OFFSET_INVALID) { u32 count = (sh_eth_read(ndev, RDFAR) - sh_eth_read(ndev, RDLAR)) >> 4; diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h index 259d03f353e1..33a360c4fd10 100644 --- a/drivers/net/ethernet/renesas/sh_eth.h +++ b/drivers/net/ethernet/renesas/sh_eth.h @@ -543,19 +543,29 @@ static inline void sh_eth_soft_swap(char *src, int len) #endif } +#define SH_ETH_OFFSET_INVALID ((u16) ~0) + static inline void sh_eth_write(struct net_device *ndev, u32 data, int enum_index) { struct sh_eth_private *mdp = netdev_priv(ndev); + u16 offset = mdp->reg_offset[enum_index]; + + if (WARN_ON(offset == SH_ETH_OFFSET_INVALID)) + return; - iowrite32(data, mdp->addr + mdp->reg_offset[enum_index]); + iowrite32(data, mdp->addr + offset); } static inline u32 sh_eth_read(struct net_device *ndev, int enum_index) { struct sh_eth_private *mdp = netdev_priv(ndev); + u16 offset = mdp->reg_offset[enum_index]; + + if (WARN_ON(offset == SH_ETH_OFFSET_INVALID)) + return ~0U; - return ioread32(mdp->addr + mdp->reg_offset[enum_index]); + return ioread32(mdp->addr + offset); } static inline void *sh_eth_tsu_get_offset(struct sh_eth_private *mdp, -- GitLab From 6b4b4fead3421f00953c8ce89af95ba9a1f39086 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 26 Feb 2015 20:34:35 +0000 Subject: [PATCH 02669/11651] sh_eth: Implement ethtool register dump operations There are many different sets of registers implemented by the different versions of this controller, and we can only expect this to get more complicated in future. Limit how much ethtool needs to know by including an explicit bitmap of which registers are included in the dump, allowing room for future growth in the number of possible registers. As I don't have datasheets for all of these, I've only included registers that are: - defined in all 5 register type arrays, or - used by the driver, or - documented in the datasheet I have Add one new capability flag so we can tell whether the RTRATE register is implemented. Delete the TSU_ADRL0 and TSU_ADR{H,L}31 definitions, as they weren't used and the address table is already assumed to be contiguous. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/ethernet/renesas/sh_eth.c | 197 ++++++++++++++++++++++++-- drivers/net/ethernet/renesas/sh_eth.h | 9 +- 2 files changed, 195 insertions(+), 11 deletions(-) diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 64e72ebdf8c5..5d9e3a77a1eb 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -137,9 +137,6 @@ static const u16 sh_eth_offset_gigabit[SH_ETH_MAX_REGISTER_OFFSET] = { [TSU_POST3] = 0x0078, [TSU_POST4] = 0x007c, [TSU_ADRH0] = 0x0100, - [TSU_ADRL0] = 0x0104, - [TSU_ADRH31] = 0x01f8, - [TSU_ADRL31] = 0x01fc, [TXNLCR0] = 0x0080, [TXALCR0] = 0x0084, @@ -206,9 +203,6 @@ static const u16 sh_eth_offset_fast_rz[SH_ETH_MAX_REGISTER_OFFSET] = { [TSU_ADSBSY] = 0x0060, [TSU_TEN] = 0x0064, [TSU_ADRH0] = 0x0100, - [TSU_ADRL0] = 0x0104, - [TSU_ADRH31] = 0x01f8, - [TSU_ADRL31] = 0x01fc, [TXNLCR0] = 0x0080, [TXALCR0] = 0x0084, @@ -405,8 +399,6 @@ static const u16 sh_eth_offset_fast_sh3_sh2[SH_ETH_MAX_REGISTER_OFFSET] = { [FWALCR1] = 0x00b4, [TSU_ADRH0] = 0x0100, - [TSU_ADRL0] = 0x0104, - [TSU_ADRL31] = 0x01fc, }; static void sh_eth_rcv_snd_disable(struct net_device *ndev); @@ -601,6 +593,7 @@ static struct sh_eth_cpu_data sh7757_data = { .no_ade = 1, .rpadir = 1, .rpadir_value = 2 << 16, + .rtrate = 1, }; #define SH_GIGA_ETH_BASE 0xfee00000UL @@ -1945,6 +1938,192 @@ error_exit: return ret; } +/* If it is ever necessary to increase SH_ETH_REG_DUMP_MAX_REGS, the + * version must be bumped as well. Just adding registers up to that + * limit is fine, as long as the existing register indices don't + * change. + */ +#define SH_ETH_REG_DUMP_VERSION 1 +#define SH_ETH_REG_DUMP_MAX_REGS 256 + +static size_t __sh_eth_get_regs(struct net_device *ndev, u32 *buf) +{ + struct sh_eth_private *mdp = netdev_priv(ndev); + struct sh_eth_cpu_data *cd = mdp->cd; + u32 *valid_map; + size_t len; + + BUILD_BUG_ON(SH_ETH_MAX_REGISTER_OFFSET > SH_ETH_REG_DUMP_MAX_REGS); + + /* Dump starts with a bitmap that tells ethtool which + * registers are defined for this chip. + */ + len = DIV_ROUND_UP(SH_ETH_REG_DUMP_MAX_REGS, 32); + if (buf) { + valid_map = buf; + buf += len; + } else { + valid_map = NULL; + } + + /* Add a register to the dump, if it has a defined offset. + * This automatically skips most undefined registers, but for + * some it is also necessary to check a capability flag in + * struct sh_eth_cpu_data. + */ +#define mark_reg_valid(reg) valid_map[reg / 32] |= 1U << (reg % 32) +#define add_reg_from(reg, read_expr) do { \ + if (mdp->reg_offset[reg] != SH_ETH_OFFSET_INVALID) { \ + if (buf) { \ + mark_reg_valid(reg); \ + *buf++ = read_expr; \ + } \ + ++len; \ + } \ + } while (0) +#define add_reg(reg) add_reg_from(reg, sh_eth_read(ndev, reg)) +#define add_tsu_reg(reg) add_reg_from(reg, sh_eth_tsu_read(mdp, reg)) + + add_reg(EDSR); + add_reg(EDMR); + add_reg(EDTRR); + add_reg(EDRRR); + add_reg(EESR); + add_reg(EESIPR); + add_reg(TDLAR); + add_reg(TDFAR); + add_reg(TDFXR); + add_reg(TDFFR); + add_reg(RDLAR); + add_reg(RDFAR); + add_reg(RDFXR); + add_reg(RDFFR); + add_reg(TRSCER); + add_reg(RMFCR); + add_reg(TFTR); + add_reg(FDR); + add_reg(RMCR); + add_reg(TFUCR); + add_reg(RFOCR); + if (cd->rmiimode) + add_reg(RMIIMODE); + add_reg(FCFTR); + if (cd->rpadir) + add_reg(RPADIR); + if (!cd->no_trimd) + add_reg(TRIMD); + add_reg(ECMR); + add_reg(ECSR); + add_reg(ECSIPR); + add_reg(PIR); + if (!cd->no_psr) + add_reg(PSR); + add_reg(RDMLR); + add_reg(RFLR); + add_reg(IPGR); + if (cd->apr) + add_reg(APR); + if (cd->mpr) + add_reg(MPR); + add_reg(RFCR); + add_reg(RFCF); + if (cd->tpauser) + add_reg(TPAUSER); + add_reg(TPAUSECR); + add_reg(GECMR); + if (cd->bculr) + add_reg(BCULR); + add_reg(MAHR); + add_reg(MALR); + add_reg(TROCR); + add_reg(CDCR); + add_reg(LCCR); + add_reg(CNDCR); + add_reg(CEFCR); + add_reg(FRECR); + add_reg(TSFRCR); + add_reg(TLFRCR); + add_reg(CERCR); + add_reg(CEECR); + add_reg(MAFCR); + if (cd->rtrate) + add_reg(RTRATE); + if (cd->hw_crc) + add_reg(CSMR); + if (cd->select_mii) + add_reg(RMII_MII); + add_reg(ARSTR); + if (cd->tsu) { + add_tsu_reg(TSU_CTRST); + add_tsu_reg(TSU_FWEN0); + add_tsu_reg(TSU_FWEN1); + add_tsu_reg(TSU_FCM); + add_tsu_reg(TSU_BSYSL0); + add_tsu_reg(TSU_BSYSL1); + add_tsu_reg(TSU_PRISL0); + add_tsu_reg(TSU_PRISL1); + add_tsu_reg(TSU_FWSL0); + add_tsu_reg(TSU_FWSL1); + add_tsu_reg(TSU_FWSLC); + add_tsu_reg(TSU_QTAG0); + add_tsu_reg(TSU_QTAG1); + add_tsu_reg(TSU_QTAGM0); + add_tsu_reg(TSU_QTAGM1); + add_tsu_reg(TSU_FWSR); + add_tsu_reg(TSU_FWINMK); + add_tsu_reg(TSU_ADQT0); + add_tsu_reg(TSU_ADQT1); + add_tsu_reg(TSU_VTAG0); + add_tsu_reg(TSU_VTAG1); + add_tsu_reg(TSU_ADSBSY); + add_tsu_reg(TSU_TEN); + add_tsu_reg(TSU_POST1); + add_tsu_reg(TSU_POST2); + add_tsu_reg(TSU_POST3); + add_tsu_reg(TSU_POST4); + if (mdp->reg_offset[TSU_ADRH0] != SH_ETH_OFFSET_INVALID) { + /* This is the start of a table, not just a single + * register. + */ + if (buf) { + unsigned int i; + + mark_reg_valid(TSU_ADRH0); + for (i = 0; i < SH_ETH_TSU_CAM_ENTRIES * 2; i++) + *buf++ = ioread32( + mdp->tsu_addr + + mdp->reg_offset[TSU_ADRH0] + + i * 4); + } + len += SH_ETH_TSU_CAM_ENTRIES * 2; + } + } + +#undef mark_reg_valid +#undef add_reg_from +#undef add_reg +#undef add_tsu_reg + + return len * 4; +} + +static int sh_eth_get_regs_len(struct net_device *ndev) +{ + return __sh_eth_get_regs(ndev, NULL); +} + +static void sh_eth_get_regs(struct net_device *ndev, struct ethtool_regs *regs, + void *buf) +{ + struct sh_eth_private *mdp = netdev_priv(ndev); + + regs->version = SH_ETH_REG_DUMP_VERSION; + + pm_runtime_get_sync(&mdp->pdev->dev); + __sh_eth_get_regs(ndev, buf); + pm_runtime_put_sync(&mdp->pdev->dev); +} + static int sh_eth_nway_reset(struct net_device *ndev) { struct sh_eth_private *mdp = netdev_priv(ndev); @@ -2090,6 +2269,8 @@ static int sh_eth_set_ringparam(struct net_device *ndev, static const struct ethtool_ops sh_eth_ethtool_ops = { .get_settings = sh_eth_get_settings, .set_settings = sh_eth_set_settings, + .get_regs_len = sh_eth_get_regs_len, + .get_regs = sh_eth_get_regs, .nway_reset = sh_eth_nway_reset, .get_msglevel = sh_eth_get_msglevel, .set_msglevel = sh_eth_set_msglevel, diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h index 33a360c4fd10..06dbbe5201cb 100644 --- a/drivers/net/ethernet/renesas/sh_eth.h +++ b/drivers/net/ethernet/renesas/sh_eth.h @@ -32,6 +32,10 @@ #define SH_ETH_TSU_CAM_ENTRIES 32 enum { + /* IMPORTANT: To keep ethtool register dump working, add new + * register names immediately before SH_ETH_MAX_REGISTER_OFFSET. + */ + /* E-DMAC registers */ EDSR = 0, EDMR, @@ -131,9 +135,7 @@ enum { TSU_POST3, TSU_POST4, TSU_ADRH0, - TSU_ADRL0, - TSU_ADRH31, - TSU_ADRL31, + /* TSU_ADR{H,L}{0..31} are assumed to be contiguous */ TXNLCR0, TXALCR0, @@ -491,6 +493,7 @@ struct sh_eth_cpu_data { unsigned select_mii:1; /* EtherC have RMII_MII (MII select register) */ unsigned shift_rd0:1; /* shift Rx descriptor word 0 right by 16 */ unsigned rmiimode:1; /* EtherC has RMIIMODE register */ + unsigned rtrate:1; /* EtherC has RTRATE register */ }; struct sh_eth_private { -- GitLab From e5fd13f476025f416583149313da85f8a3164414 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 26 Feb 2015 20:34:46 +0000 Subject: [PATCH 02670/11651] sh_eth: Optionally log RX and TX status for each completed descriptor Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/ethernet/renesas/sh_eth.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 5d9e3a77a1eb..c92dd173b994 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -1417,6 +1417,9 @@ static int sh_eth_txfree(struct net_device *ndev) break; /* TACT bit must be checked before all the following reads */ rmb(); + netif_info(mdp, tx_done, ndev, + "tx entry %d status 0x%08x\n", + entry, edmac_to_cpu(mdp, txdesc->status)); /* Free the original skb. */ if (mdp->tx_skbuff[entry]) { dma_unmap_single(&ndev->dev, txdesc->addr, @@ -1462,6 +1465,10 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota) if (--boguscnt < 0) break; + netif_info(mdp, rx_status, ndev, + "rx entry %d status 0x%08x len %d\n", + entry, desc_status, pkt_len); + if (!(desc_status & RDFEND)) ndev->stats.rx_length_errors++; -- GitLab From 4398f9c817028b3b654923b3b614ea174cbc2c67 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 26 Feb 2015 20:35:05 +0000 Subject: [PATCH 02671/11651] sh_eth: Mitigate lost statistics updates The statistics registers have write-clear behaviour, which means we will lose any increment between the read and write. Mitigate this by only clearing when we read a non-zero value, so we will never falsely report a total of zero. This also saves time as we only handle error statistics here and they won't often be incremented. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/ethernet/renesas/sh_eth.c | 37 ++++++++++++++++++--------- 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index c92dd173b994..7fb244f565b2 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -2417,6 +2417,22 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev) return NETDEV_TX_OK; } +/* The statistics registers have write-clear behaviour, which means we + * will lose any increment between the read and write. We mitigate + * this by only clearing when we read a non-zero value, so we will + * never falsely report a total of zero. + */ +static void +sh_eth_update_stat(struct net_device *ndev, unsigned long *stat, int reg) +{ + u32 delta = sh_eth_read(ndev, reg); + + if (delta) { + *stat += delta; + sh_eth_write(ndev, 0, reg); + } +} + static struct net_device_stats *sh_eth_get_stats(struct net_device *ndev) { struct sh_eth_private *mdp = netdev_priv(ndev); @@ -2427,21 +2443,18 @@ static struct net_device_stats *sh_eth_get_stats(struct net_device *ndev) if (!mdp->is_opened) return &ndev->stats; - ndev->stats.tx_dropped += sh_eth_read(ndev, TROCR); - sh_eth_write(ndev, 0, TROCR); /* (write clear) */ - ndev->stats.collisions += sh_eth_read(ndev, CDCR); - sh_eth_write(ndev, 0, CDCR); /* (write clear) */ - ndev->stats.tx_carrier_errors += sh_eth_read(ndev, LCCR); - sh_eth_write(ndev, 0, LCCR); /* (write clear) */ + sh_eth_update_stat(ndev, &ndev->stats.tx_dropped, TROCR); + sh_eth_update_stat(ndev, &ndev->stats.collisions, CDCR); + sh_eth_update_stat(ndev, &ndev->stats.tx_carrier_errors, LCCR); if (sh_eth_is_gether(mdp)) { - ndev->stats.tx_carrier_errors += sh_eth_read(ndev, CERCR); - sh_eth_write(ndev, 0, CERCR); /* (write clear) */ - ndev->stats.tx_carrier_errors += sh_eth_read(ndev, CEECR); - sh_eth_write(ndev, 0, CEECR); /* (write clear) */ + sh_eth_update_stat(ndev, &ndev->stats.tx_carrier_errors, + CERCR); + sh_eth_update_stat(ndev, &ndev->stats.tx_carrier_errors, + CEECR); } else { - ndev->stats.tx_carrier_errors += sh_eth_read(ndev, CNDCR); - sh_eth_write(ndev, 0, CNDCR); /* (write clear) */ + sh_eth_update_stat(ndev, &ndev->stats.tx_carrier_errors, + CNDCR); } return &ndev->stats; -- GitLab From 17f480342026e54000731acaa69bf32787ce46cb Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 27 Feb 2015 00:07:55 +0100 Subject: [PATCH 02672/11651] genirq / PM: Add flag for shared NO_SUSPEND interrupt lines It currently is required that all users of NO_SUSPEND interrupt lines pass the IRQF_NO_SUSPEND flag when requesting the IRQ or the WARN_ON_ONCE() in irq_pm_install_action() will trigger. That is done to warn about situations in which unprepared interrupt handlers may be run unnecessarily for suspended devices and may attempt to access those devices by mistake. However, it may cause drivers that have no technical reasons for using IRQF_NO_SUSPEND to set that flag just because they happen to share the interrupt line with something like a timer. Moreover, the generic handling of wakeup interrupts introduced by commit 9ce7a25849e8 (genirq: Simplify wakeup mechanism) only works for IRQs without any NO_SUSPEND users, so the drivers of wakeup devices needing to use shared NO_SUSPEND interrupt lines for signaling system wakeup generally have to detect wakeup in their interrupt handlers. Thus if they happen to share an interrupt line with a NO_SUSPEND user, they also need to request that their interrupt handlers be run after suspend_device_irqs(). In both cases the reason for using IRQF_NO_SUSPEND is not because the driver in question has a genuine need to run its interrupt handler after suspend_device_irqs(), but because it happens to share the line with some other NO_SUSPEND user. Otherwise, the driver would do without IRQF_NO_SUSPEND just fine. To make it possible to specify that condition explicitly, introduce a new IRQ action handler flag for shared IRQs, IRQF_COND_SUSPEND, that, when set, will indicate to the IRQ core that the interrupt user is generally fine with suspending the IRQ, but it also can tolerate handler invocations after suspend_device_irqs() and, in particular, it is capable of detecting system wakeup and triggering it as appropriate from its interrupt handler. That will allow us to work around a problem with a shared timer interrupt line on at91 platforms. Link: http://marc.info/?l=linux-kernel&m=142252777602084&w=2 Link: http://marc.info/?t=142252775300011&r=1&w=2 Link: https://lkml.org/lkml/2014/12/15/552 Reported-by: Boris Brezillon Signed-off-by: Rafael J. Wysocki Acked-by: Peter Zijlstra (Intel) Acked-by: Mark Rutland --- include/linux/interrupt.h | 5 +++++ include/linux/irqdesc.h | 1 + kernel/irq/manage.c | 7 ++++++- kernel/irq/pm.c | 7 ++++++- 4 files changed, 18 insertions(+), 2 deletions(-) diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index 606771c7cac2..2e88580194f0 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -59,6 +59,10 @@ * IRQF_NO_THREAD - Interrupt cannot be threaded * IRQF_EARLY_RESUME - Resume IRQ early during syscore instead of at device * resume time. + * IRQF_COND_SUSPEND - If the IRQ is shared with a NO_SUSPEND user, execute this + * interrupt handler after suspending interrupts. For system + * wakeup devices users need to implement wakeup detection in + * their interrupt handlers. */ #define IRQF_DISABLED 0x00000020 #define IRQF_SHARED 0x00000080 @@ -72,6 +76,7 @@ #define IRQF_FORCE_RESUME 0x00008000 #define IRQF_NO_THREAD 0x00010000 #define IRQF_EARLY_RESUME 0x00020000 +#define IRQF_COND_SUSPEND 0x00040000 #define IRQF_TIMER (__IRQF_TIMER | IRQF_NO_SUSPEND | IRQF_NO_THREAD) diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h index faf433af425e..dd1109fb241e 100644 --- a/include/linux/irqdesc.h +++ b/include/linux/irqdesc.h @@ -78,6 +78,7 @@ struct irq_desc { #ifdef CONFIG_PM_SLEEP unsigned int nr_actions; unsigned int no_suspend_depth; + unsigned int cond_suspend_depth; unsigned int force_resume_depth; #endif #ifdef CONFIG_PROC_FS diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 196a06fbc122..886d09e691d5 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c @@ -1474,8 +1474,13 @@ int request_threaded_irq(unsigned int irq, irq_handler_t handler, * otherwise we'll have trouble later trying to figure out * which interrupt is which (messes up the interrupt freeing * logic etc). + * + * Also IRQF_COND_SUSPEND only makes sense for shared interrupts and + * it cannot be set along with IRQF_NO_SUSPEND. */ - if ((irqflags & IRQF_SHARED) && !dev_id) + if (((irqflags & IRQF_SHARED) && !dev_id) || + (!(irqflags & IRQF_SHARED) && (irqflags & IRQF_COND_SUSPEND)) || + ((irqflags & IRQF_NO_SUSPEND) && (irqflags & IRQF_COND_SUSPEND))) return -EINVAL; desc = irq_to_desc(irq); diff --git a/kernel/irq/pm.c b/kernel/irq/pm.c index 3ca532592704..5204a6d1b985 100644 --- a/kernel/irq/pm.c +++ b/kernel/irq/pm.c @@ -43,9 +43,12 @@ void irq_pm_install_action(struct irq_desc *desc, struct irqaction *action) if (action->flags & IRQF_NO_SUSPEND) desc->no_suspend_depth++; + else if (action->flags & IRQF_COND_SUSPEND) + desc->cond_suspend_depth++; WARN_ON_ONCE(desc->no_suspend_depth && - desc->no_suspend_depth != desc->nr_actions); + (desc->no_suspend_depth + + desc->cond_suspend_depth) != desc->nr_actions); } /* @@ -61,6 +64,8 @@ void irq_pm_remove_action(struct irq_desc *desc, struct irqaction *action) if (action->flags & IRQF_NO_SUSPEND) desc->no_suspend_depth--; + else if (action->flags & IRQF_COND_SUSPEND) + desc->cond_suspend_depth--; } static bool suspend_device_irq(struct irq_desc *desc, int irq) -- GitLab From 8f02d8da969a73133d82edaaa63f6286fba0195a Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Tue, 3 Mar 2015 13:46:44 +0300 Subject: [PATCH 02673/11651] stmmac: check IRQ availability early on probe Currently we're getting IRQs after lots of resources are already allocated: * netdev * clocks * MDIO bus Also HW gets initialized by the time when checking IRQs as well. Now there's a possibility for master interrupt controller to be not probed yet. This will lead to exit from GMAC probe routine with "- EPROBE_DEFER" and so deferred probe will hapen later on. But since we exited the first GMAC probe without release of all allocated resources there could be conflicts on subsequent probes. For example this is what happens for me: --->8--- stmmaceth e0018000.ethernet: no reset control found stmmac - user ID: 0x10, Synopsys ID: 0x37 Ring mode enabled DMA HW capability register supported Normal descriptors RX Checksum Offload Engine supported (type 2) TX Checksum insertion supported Enable RX Mitigation via HW Watchdog Timer libphy: stmmac: probed eth0: PHY ID 20005c7a at 1 IRQ POLL (stmmac-0:01) active platform e0018000.ethernet: Driver stmmaceth requests probe deferral ... ... ... stmmaceth e0018000.ethernet: no reset control found stmmac - user ID: 0x10, Synopsys ID: 0x37 Ring mode enabled DMA HW capability register supported Normal descriptors RX Checksum Offload Engine supported (type 2) TX Checksum insertion supported Enable RX Mitigation via HW Watchdog Timer ------------[ cut here ]------------ WARNING: CPU: 0 PID: 6 at fs/sysfs/dir.c:31 sysfs_warn_dup+0x4e/0x68() sysfs: cannot create duplicate filename '/devices/platform/axs10x_mb/e0018000.ethernet/mdio_bus/stmmac-0' CPU: 0 PID: 6 Comm: kworker/u2:0 Not tainted 4.0.0-rc1-next-20150303+#8 Workqueue: deferwq deferred_probe_work_func Stack Trace: arc_unwind_core+0xb8/0x114 warn_slowpath_common+0x5a/0x8c warn_slowpath_fmt+0x2e/0x38 sysfs_warn_dup+0x4e/0x68 sysfs_create_dir_ns+0x98/0xa0 kobject_add_internal+0x8c/0x2e8 kobject_add+0x4a/0x8c device_add+0xc6/0x448 mdiobus_register+0x6c/0x164 stmmac_mdio_register+0x112/0x264 stmmac_dvr_probe+0x6c0/0x85c stmmac_pltfr_probe+0x2e4/0x50c platform_drv_probe+0x26/0x5c really_probe+0x76/0x1dc bus_for_each_drv+0x42/0x7c device_attach+0x64/0x6c bus_probe_device+0x74/0xa4 deferred_probe_work_func+0x50/0x84 process_one_work+0xf8/0x2cc worker_thread+0x110/0x478 kthread+0x8a/0x9c ret_from_fork+0x14/0x18 ---[ end trace a2dfaa7d630c8be1 ]--- ------------[ cut here ]------------ WARNING: CPU: 0 PID: 6 at lib/kobject.c:240 kobject_add_internal+0x218/0x2e8() kobject_add_internal failed for stmmac-0 with -EEXIST, don't try to register things with the same name in the same di. CPU: 0 PID: 6 Comm: kworker/u2:0 Tainted: G W 4.0.0-rc1-next-20150303+ #8 Workqueue: deferwq deferred_probe_work_func Stack Trace: arc_unwind_core+0xb8/0x114 warn_slowpath_common+0x5a/0x8c warn_slowpath_fmt+0x2e/0x38 kobject_add_internal+0x218/0x2e8 kobject_add+0x4a/0x8c device_add+0xc6/0x448 mdiobus_register+0x6c/0x164 stmmac_mdio_register+0x112/0x264 stmmac_dvr_probe+0x6c0/0x85c stmmac_pltfr_probe+0x2e4/0x50c platform_drv_probe+0x26/0x5c really_probe+0x76/0x1dc bus_for_each_drv+0x42/0x7c device_attach+0x64/0x6c bus_probe_device+0x74/0xa4 deferred_probe_work_func+0x50/0x84 process_one_work+0xf8/0x2cc worker_thread+0x110/0x478 kthread+0x8a/0x9c ret_from_fork+0x14/0x18 ---[ end trace a2dfaa7d630c8be2 ]--- libphy: mii_bus stmmac-0 failed to register : Cannot register as MDIO bus stmmac_pltfr_probe: main driver probe failed stmmaceth: probe of e0018000.ethernet failed with error -22 --->8--- Essential fix is to check for IRQs availability as early as possible and then safely go to deferred probe if IRQs are not there yet. Signed-off-by: Alexey Brodkin Cc: Vineet Gupta Cc: Andy Shevchenko Cc: Giuseppe Cavallaro Cc: Sonic Zhang Cc: David S. Miller Signed-off-by: David S. Miller --- .../ethernet/stmicro/stmmac/stmmac_platform.c | 65 ++++++++++--------- 1 file changed, 36 insertions(+), 29 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c index fb846ebba1d9..f9b42f11950f 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c @@ -272,6 +272,37 @@ static int stmmac_pltfr_probe(struct platform_device *pdev) struct stmmac_priv *priv = NULL; struct plat_stmmacenet_data *plat_dat = NULL; const char *mac = NULL; + int irq, wol_irq, lpi_irq; + + /* Get IRQ information early to have an ability to ask for deferred + * probe if needed before we went too far with resource allocation. + */ + irq = platform_get_irq_byname(pdev, "macirq"); + if (irq < 0) { + if (irq != -EPROBE_DEFER) { + dev_err(dev, + "MAC IRQ configuration information not found\n"); + } + return irq; + } + + /* On some platforms e.g. SPEAr the wake up irq differs from the mac irq + * The external wake up irq can be passed through the platform code + * named as "eth_wake_irq" + * + * In case the wake up interrupt is not passed from the platform + * so the driver will continue to use the mac irq (ndev->irq) + */ + wol_irq = platform_get_irq_byname(pdev, "eth_wake_irq"); + if (wol_irq < 0) { + if (wol_irq == -EPROBE_DEFER) + return -EPROBE_DEFER; + wol_irq = irq; + } + + lpi_irq = platform_get_irq_byname(pdev, "eth_lpi"); + if (lpi_irq == -EPROBE_DEFER) + return -EPROBE_DEFER; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); addr = devm_ioremap_resource(dev, res); @@ -323,39 +354,15 @@ static int stmmac_pltfr_probe(struct platform_device *pdev) return PTR_ERR(priv); } + /* Copy IRQ values to priv structure which is now avaialble */ + priv->dev->irq = irq; + priv->wol_irq = wol_irq; + priv->lpi_irq = lpi_irq; + /* Get MAC address if available (DT) */ if (mac) memcpy(priv->dev->dev_addr, mac, ETH_ALEN); - /* Get the MAC information */ - priv->dev->irq = platform_get_irq_byname(pdev, "macirq"); - if (priv->dev->irq < 0) { - if (priv->dev->irq != -EPROBE_DEFER) { - netdev_err(priv->dev, - "MAC IRQ configuration information not found\n"); - } - return priv->dev->irq; - } - - /* - * On some platforms e.g. SPEAr the wake up irq differs from the mac irq - * The external wake up irq can be passed through the platform code - * named as "eth_wake_irq" - * - * In case the wake up interrupt is not passed from the platform - * so the driver will continue to use the mac irq (ndev->irq) - */ - priv->wol_irq = platform_get_irq_byname(pdev, "eth_wake_irq"); - if (priv->wol_irq < 0) { - if (priv->wol_irq == -EPROBE_DEFER) - return -EPROBE_DEFER; - priv->wol_irq = priv->dev->irq; - } - - priv->lpi_irq = platform_get_irq_byname(pdev, "eth_lpi"); - if (priv->lpi_irq == -EPROBE_DEFER) - return -EPROBE_DEFER; - platform_set_drvdata(pdev, priv->dev); pr_debug("STMMAC platform driver registration completed"); -- GitLab From cd33ccf5fd87e94342b6cf8990e2e1570632c276 Mon Sep 17 00:00:00 2001 From: Nicolas Schichan Date: Tue, 3 Mar 2015 12:45:12 +0100 Subject: [PATCH 02674/11651] bcm63xx_enet: fix poll callback. In case there was some tx buffer reclaimed and not enough rx packets to consume the whole budget, napi_complete would not be called and interrupts would be kept disabled, effectively resulting in the network core never to call the poll callback again and no rx/tx interrupts to be fired either. Fix that by only accounting the rx work done in the poll callback. Signed-off-by: Nicolas Schichan Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bcm63xx_enet.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bcm63xx_enet.c b/drivers/net/ethernet/broadcom/bcm63xx_enet.c index 21206d33b638..a7f2cc3e485e 100644 --- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c +++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c @@ -486,7 +486,7 @@ static int bcm_enet_poll(struct napi_struct *napi, int budget) { struct bcm_enet_priv *priv; struct net_device *dev; - int tx_work_done, rx_work_done; + int rx_work_done; priv = container_of(napi, struct bcm_enet_priv, napi); dev = priv->net_dev; @@ -498,14 +498,14 @@ static int bcm_enet_poll(struct napi_struct *napi, int budget) ENETDMAC_IR, priv->tx_chan); /* reclaim sent skb */ - tx_work_done = bcm_enet_tx_reclaim(dev, 0); + bcm_enet_tx_reclaim(dev, 0); spin_lock(&priv->rx_lock); rx_work_done = bcm_enet_receive_queue(dev, budget); spin_unlock(&priv->rx_lock); - if (rx_work_done >= budget || tx_work_done > 0) { - /* rx/tx queue is not yet empty/clean */ + if (rx_work_done >= budget) { + /* rx queue is not yet empty/clean */ return rx_work_done; } -- GitLab From 9145736d4862145684009d6a72a6e61324a9439e Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Tue, 3 Mar 2015 23:16:16 +0900 Subject: [PATCH 02675/11651] net: ping: Return EAFNOSUPPORT when appropriate. 1. For an IPv4 ping socket, ping_check_bind_addr does not check the family of the socket address that's passed in. Instead, make it behave like inet_bind, which enforces either that the address family is AF_INET, or that the family is AF_UNSPEC and the address is 0.0.0.0. 2. For an IPv6 ping socket, ping_check_bind_addr returns EINVAL if the socket family is not AF_INET6. Return EAFNOSUPPORT instead, for consistency with inet6_bind. 3. Make ping_v4_sendmsg and ping_v6_sendmsg return EAFNOSUPPORT instead of EINVAL if an incorrect socket address structure is passed in. 4. Make IPv6 ping sockets be IPv6-only. The code does not support IPv4, and it cannot easily be made to support IPv4 because the protocol numbers for ICMP and ICMPv6 are different. This makes connect(::ffff:192.0.2.1) fail with EAFNOSUPPORT instead of making the socket unusable. Among other things, this fixes an oops that can be triggered by: int s = socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP); struct sockaddr_in6 sin6 = { .sin6_family = AF_INET6, .sin6_addr = in6addr_any, }; bind(s, (struct sockaddr *) &sin6, sizeof(sin6)); Change-Id: If06ca86d9f1e4593c0d6df174caca3487c57a241 Signed-off-by: Lorenzo Colitti Signed-off-by: David S. Miller --- net/ipv4/ping.c | 12 ++++++++++-- net/ipv6/ping.c | 5 +++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c index e9f66e1cda50..208d5439e59b 100644 --- a/net/ipv4/ping.c +++ b/net/ipv4/ping.c @@ -259,6 +259,9 @@ int ping_init_sock(struct sock *sk) kgid_t low, high; int ret = 0; + if (sk->sk_family == AF_INET6) + sk->sk_ipv6only = 1; + inet_get_ping_group_range_net(net, &low, &high); if (gid_lte(low, group) && gid_lte(group, high)) return 0; @@ -305,6 +308,11 @@ static int ping_check_bind_addr(struct sock *sk, struct inet_sock *isk, if (addr_len < sizeof(*addr)) return -EINVAL; + if (addr->sin_family != AF_INET && + !(addr->sin_family == AF_UNSPEC && + addr->sin_addr.s_addr == htonl(INADDR_ANY))) + return -EAFNOSUPPORT; + pr_debug("ping_check_bind_addr(sk=%p,addr=%pI4,port=%d)\n", sk, &addr->sin_addr.s_addr, ntohs(addr->sin_port)); @@ -330,7 +338,7 @@ static int ping_check_bind_addr(struct sock *sk, struct inet_sock *isk, return -EINVAL; if (addr->sin6_family != AF_INET6) - return -EINVAL; + return -EAFNOSUPPORT; pr_debug("ping_check_bind_addr(sk=%p,addr=%pI6c,port=%d)\n", sk, addr->sin6_addr.s6_addr, ntohs(addr->sin6_port)); @@ -716,7 +724,7 @@ static int ping_v4_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m if (msg->msg_namelen < sizeof(*usin)) return -EINVAL; if (usin->sin_family != AF_INET) - return -EINVAL; + return -EAFNOSUPPORT; daddr = usin->sin_addr.s_addr; /* no remote port */ } else { diff --git a/net/ipv6/ping.c b/net/ipv6/ping.c index bd46f736f61d..a2dfff6ff227 100644 --- a/net/ipv6/ping.c +++ b/net/ipv6/ping.c @@ -102,9 +102,10 @@ int ping_v6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, if (msg->msg_name) { DECLARE_SOCKADDR(struct sockaddr_in6 *, u, msg->msg_name); - if (msg->msg_namelen < sizeof(struct sockaddr_in6) || - u->sin6_family != AF_INET6) { + if (msg->msg_namelen < sizeof(*u)) return -EINVAL; + if (u->sin6_family != AF_INET6) { + return -EAFNOSUPPORT; } if (sk->sk_bound_dev_if && sk->sk_bound_dev_if != u->sin6_scope_id) { -- GitLab From 28811a8c00fe0d899b8a544421f3b4947425d5e8 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 3 Mar 2015 15:43:00 +0100 Subject: [PATCH 02676/11651] net: cadence: Remove Kconfig dependency on ARCH MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove Kconfig dependency and enable driver for all ARCHs. Signed-off-by: Michal Simek Acked-by: Sören Brinkmann Signed-off-by: David S. Miller --- drivers/net/ethernet/cadence/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/cadence/Kconfig b/drivers/net/ethernet/cadence/Kconfig index 321d2ad235d9..739bb0048ebf 100644 --- a/drivers/net/ethernet/cadence/Kconfig +++ b/drivers/net/ethernet/cadence/Kconfig @@ -4,7 +4,7 @@ config NET_CADENCE bool "Cadence devices" - depends on HAS_IOMEM && (ARM || AVR32 || MICROBLAZE || COMPILE_TEST) + depends on HAS_IOMEM default y ---help--- If you have a network (Ethernet) card belonging to this class, say Y. @@ -30,7 +30,7 @@ config ARM_AT91_ETHER config MACB tristate "Cadence MACB/GEM support" - depends on HAS_DMA && (PLATFORM_AT32AP || ARCH_AT91 || ARCH_PICOXCELL || ARCH_ZYNQ || MICROBLAZE || COMPILE_TEST) + depends on HAS_DMA select PHYLIB ---help--- The Cadence MACB ethernet interface is found on many Atmel AT32 and -- GitLab From 955ab7e2adc9446257431d7d7ff509bdd1fe5ef8 Mon Sep 17 00:00:00 2001 From: Iyappan Subramanian Date: Tue, 3 Mar 2015 11:39:39 -0800 Subject: [PATCH 02677/11651] Documentation: dts: Update compatible field description for APM X-Gene Signed-off-by: Iyappan Subramanian Signed-off-by: Keyur Chudgar Tested-by: Mark Langsdorf Signed-off-by: David S. Miller --- Documentation/devicetree/bindings/net/apm-xgene-enet.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/net/apm-xgene-enet.txt b/Documentation/devicetree/bindings/net/apm-xgene-enet.txt index cfcc52705ed8..6151999c5dca 100644 --- a/Documentation/devicetree/bindings/net/apm-xgene-enet.txt +++ b/Documentation/devicetree/bindings/net/apm-xgene-enet.txt @@ -4,7 +4,10 @@ Ethernet nodes are defined to describe on-chip ethernet interfaces in APM X-Gene SoC. Required properties for all the ethernet interfaces: -- compatible: Should be "apm,xgene-enet" +- compatible: Should state binding information from the following list, + - "apm,xgene-enet": RGMII based 1G interface + - "apm,xgene1-sgenet": SGMII based 1G interface + - "apm,xgene1-xgenet": XFI based 10G interface - reg: Address and length of the register set for the device. It contains the information of registers in the same order as described by reg-names - reg-names: Should contain the register set names -- GitLab From 2a91eb72e630e512e87bed746d7db47810773d58 Mon Sep 17 00:00:00 2001 From: Iyappan Subramanian Date: Tue, 3 Mar 2015 11:39:40 -0800 Subject: [PATCH 02678/11651] dtb: change binding name to match with newer firmware DT This patch fixes the backward compatibility of the older driver with the newer firmware by making the binding unique so that the older driver won't recognize the non-supported interfaces. The new bindings are in sync with the newer firmware. Signed-off-by: Iyappan Subramanian Signed-off-by: Keyur Chudgar Tested-by: Mark Langsdorf Signed-off-by: David S. Miller --- arch/arm64/boot/dts/apm/apm-storm.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/apm/apm-storm.dtsi b/arch/arm64/boot/dts/apm/apm-storm.dtsi index f1ad9c2ab2e9..a857794432d6 100644 --- a/arch/arm64/boot/dts/apm/apm-storm.dtsi +++ b/arch/arm64/boot/dts/apm/apm-storm.dtsi @@ -622,7 +622,7 @@ }; sgenet0: ethernet@1f210000 { - compatible = "apm,xgene-enet"; + compatible = "apm,xgene1-sgenet"; status = "disabled"; reg = <0x0 0x1f210000 0x0 0xd100>, <0x0 0x1f200000 0x0 0Xc300>, @@ -636,7 +636,7 @@ }; xgenet: ethernet@1f610000 { - compatible = "apm,xgene-enet"; + compatible = "apm,xgene1-xgenet"; status = "disabled"; reg = <0x0 0x1f610000 0x0 0xd100>, <0x0 0x1f600000 0x0 0Xc300>, -- GitLab From ecadf4e71de079d4050f249547d25b3bd333f89f Mon Sep 17 00:00:00 2001 From: Iyappan Subramanian Date: Tue, 3 Mar 2015 11:39:41 -0800 Subject: [PATCH 02679/11651] drivers: net: xgene: fix new firmware backward compatibility with older driver This patch fixes the backward compatibile of the older driver with the newer firmware by making the binding unique so that the older driver won't recognize the non-supported interfaces. Signed-off-by: Iyappan Subramanian Signed-off-by: Keyur Chudgar Tested-by: Mark Langsdorf Signed-off-by: David S. Miller --- drivers/net/ethernet/apm/xgene/xgene_enet_main.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c index 4de62b210c85..635a83be7e5e 100644 --- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c +++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c @@ -1025,6 +1025,8 @@ static int xgene_enet_remove(struct platform_device *pdev) #ifdef CONFIG_ACPI static const struct acpi_device_id xgene_enet_acpi_match[] = { { "APMC0D05", }, + { "APMC0D30", }, + { "APMC0D31", }, { } }; MODULE_DEVICE_TABLE(acpi, xgene_enet_acpi_match); @@ -1033,6 +1035,8 @@ MODULE_DEVICE_TABLE(acpi, xgene_enet_acpi_match); #ifdef CONFIG_OF static struct of_device_id xgene_enet_of_match[] = { {.compatible = "apm,xgene-enet",}, + {.compatible = "apm,xgene1-sgenet",}, + {.compatible = "apm,xgene1-xgenet",}, {}, }; -- GitLab From 61615cd27e2fdcf698261ba77c7d93f7a7739c65 Mon Sep 17 00:00:00 2001 From: Fugang Duan Date: Wed, 4 Mar 2015 07:52:11 +0800 Subject: [PATCH 02680/11651] net: fec: fix rcv is not last issue when do suspend/resume test When do suspend/resume stress test, some log shows "rcv is not +last". The issue is that enet suspend will disable phy clock, phy link down, after resume back, enet MAC redo initial and ready to tx/rx packet, but phy still is not ready which is doing auto-negotiation. When phy link is not up, don't schdule napi soft irq. [Peter] It has fixed kernel panic after long time suspend/resume test with nfs rootfs. [ 8864.429458] fec 2188000.ethernet eth0: rcv is not +last [ 8864.434799] fec 2188000.ethernet eth0: rcv is not +last [ 8864.440088] fec 2188000.ethernet eth0: rcv is not +last [ 8864.445424] fec 2188000.ethernet eth0: rcv is not +last [ 8864.450782] fec 2188000.ethernet eth0: rcv is not +last [ 8864.456111] Unable to handle kernel NULL pointer dereference at virtual address 00000000 [ 8864.464225] pgd = 80004000 [ 8864.466997] [00000000] *pgd=00000000 [ 8864.470627] Internal error: Oops: 17 [#1] SMP ARM [ 8864.475353] Modules linked in: evbug [ 8864.479006] CPU: 0 PID: 3 Comm: ksoftirqd/0 Not tainted 4.0.0-rc1-00044-g7a2a1d2 #234 [ 8864.486854] Hardware name: Freescale i.MX6 SoloX (Device Tree) [ 8864.492709] task: be069380 ti: be07a000 task.ti: be07a000 [ 8864.498137] PC is at memcpy+0x80/0x330 [ 8864.501919] LR is at gro_pull_from_frag0+0x34/0xa8 [ 8864.506735] pc : [<802bb080>] lr : [<8057c204>] psr: 00000113 [ 8864.506735] sp : be07bbd4 ip : 00000010 fp : be07bc0c [ 8864.518235] r10: 0000000e r9 : 00000000 r8 : 809c7754 [ 8864.523479] r7 : 809c7754 r6 : bb43c040 r5 : bd280cc0 r4 : 00000012 [ 8864.530025] r3 : 00000804 r2 : fffffff2 r1 : 00000000 r0 : bb43b83c [ 8864.536575] Flags: nzcv IRQs on FIQs on Mode SVC_32 ISA ARM Segment kernel [ 8864.543904] Control: 10c5387d Table: bd14c04a DAC: 00000015 [ 8864.549669] Process ksoftirqd/0 (pid: 3, stack limit = 0xbe07a210) [ 8864.555869] Stack: (0xbe07bbd4 to 0xbe07c000) [ 8864.560250] bbc0: bd280cc0 bb43c040 809c7754 [ 8864.568455] bbe0: 809c7754 bb43b83c 00000012 8057c204 00000000 bd280cc0 bd8a0718 00000003 [ 8864.576658] bc00: be07bc5c be07bc10 8057ebf0 8057c1dc 00000000 00000000 8057ecc4 bef59760 [ 8864.584863] bc20: 00000002 bd8a0000 be07bc64 809c7754 00000000 bd8a0718 bd280cc0 bd8a0000 [ 8864.593066] bc40: 00000000 0000001c 00000000 bd8a0000 be07bc74 be07bc60 8057f148 8057eb90 [ 8864.601268] bc60: bf0810a0 00000000 be07bcf4 be07bc78 8044e7b4 8057f12c 00000000 8007df6c [ 8864.609470] bc80: bd8a0718 00000040 00000000 bd280a80 00000002 00000019 bd8a0600 bd8a1214 [ 8864.617672] bca0: bd8a0690 bf0810a0 00000000 00000000 bd8a1000 00000000 00000027 bd280cc0 [ 8864.625874] bcc0: 80062708 800625cc 000943db bd8a0718 00000001 000d1166 00000040 be7c1ec0 [ 8864.634077] bce0: 0000012c be07bd00 be07bd3c be07bcf8 8057fc98 8044e3ac 809c2ec0 3ddff000 [ 8864.642280] bd00: be07bd00 be07bd00 be07bd08 be07bd08 00000000 00000020 809c608c 00000003 [ 8864.650481] bd20: 809c6080 40000001 809c6088 00200100 be07bd84 be07bd40 8002e690 8057fac8 [ 8864.658684] bd40: be07bd64 be07bd50 00000001 04208040 000d1165 0000000a be07bd84 809c0d7c [ 8864.666885] bd60: 00000000 809c6af8 00000000 00000001 be008000 00000000 be07bd9c be07bd88 [ 8864.675087] bd80: 8002eb64 8002e564 00000125 809c0d7c be07bdc4 be07bda0 8006f100 8002eaac [ 8864.683291] bda0: c080e10c be07bde8 809c6c6c c080e100 00000002 00000000 be07bde4 be07bdc8 [ 8864.691492] bdc0: 800087a0 8006f098 806f2934 20000013 ffffffff be07be1c be07be44 be07bde8 [ 8864.699695] bde0: 800133a4 80008784 00000001 00000001 00000000 00000000 be7c1680 00000000 [ 8864.707896] be00: be0cfe00 bd93eb40 00000002 00000000 00000000 be07be44 be07be00 be07be30 [ 8864.716098] be20: 8006278c 806f2934 20000013 ffffffff be069380 be7c1680 be07be7c be07be48 [ 8864.724300] be40: 80049cfc 806f2910 00000001 00000000 80049cb4 00000000 be07be7c be7c1680 [ 8864.732502] be60: be3289c0 be069380 bd23b600 be0cfe00 be07bebc be07be80 806ed614 80049c68 [ 8864.740706] be80: be07a000 0000020a 809c608c 00000003 00000001 8002e858 be07a000 be035740 [ 8864.748907] bea0: 00000000 00000001 809d4598 00000000 be07bed4 be07bec0 806edd0c 806ed440 [ 8864.757110] bec0: be07a000 be07a000 be07bee4 be07bed8 806edd68 806edcf0 be07bef4 be07bee8 [ 8864.765311] bee0: 8002e860 806edd34 be07bf24 be07bef8 800494b0 8002e828 be069380 00000000 [ 8864.773512] bf00: be035780 be035740 8004938c 00000000 00000000 00000000 be07bfac be07bf28 [ 8864.781715] bf20: 80045928 80049398 be07bf44 00000001 00000000 be035740 00000000 00030003 [ 8864.789917] bf40: dead4ead ffffffff ffffffff 80a2716c 80b59b00 00000000 8088c954 be07bf5c [ 8864.798120] bf60: be07bf5c 00000000 00000000 dead4ead ffffffff ffffffff 80a2716c 00000000 [ 8864.806320] bf80: 00000000 8088c954 be07bf88 be07bf88 be035780 8004584c 00000000 00000000 [ 8864.814523] bfa0: 00000000 be07bfb0 8000ed10 80045858 00000000 00000000 00000000 00000000 [ 8864.822723] bfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 [ 8864.830925] bfe0: 00000000 00000000 00000000 00000000 00000013 00000000 5ffbb5f7 f9fcf5e7 [ 8864.839115] Backtrace: [ 8864.841631] [<8057c1d0>] (gro_pull_from_frag0) from [<8057ebf0>] (dev_gro_receive+0x6c/0x3f8) [ 8864.850173] r6:00000003 r5:bd8a0718 r4:bd280cc0 r3:00000000 [ 8864.855958] [<8057eb84>] (dev_gro_receive) from [<8057f148>] (napi_gro_receive+0x28/0xac) [ 8864.864152] r10:bd8a0000 r9:00000000 r8:0000001c r7:00000000 r6:bd8a0000 r5:bd280cc0 [ 8864.872115] r4:bd8a0718 [ 8864.874713] [<8057f120>] (napi_gro_receive) from [<8044e7b4>] (fec_enet_rx_napi+0x414/0xc74) [ 8864.883167] r5:00000000 r4:bf0810a0 [ 8864.886823] [<8044e3a0>] (fec_enet_rx_napi) from [<8057fc98>] (net_rx_action+0x1dc/0x2ec) [ 8864.895016] r10:be07bd00 r9:0000012c r8:be7c1ec0 r7:00000040 r6:000d1166 r5:00000001 [ 8864.902982] r4:bd8a0718 [ 8864.905570] [<8057fabc>] (net_rx_action) from [<8002e690>] (__do_softirq+0x138/0x2c4) [ 8864.913417] r10:00200100 r9:809c6088 r8:40000001 r7:809c6080 r6:00000003 r5:809c608c [ 8864.921382] r4:00000020 [ 8864.923966] [<8002e558>] (__do_softirq) from [<8002eb64>] (irq_exit+0xc4/0x138) [ 8864.931289] r10:00000000 r9:be008000 r8:00000001 r7:00000000 r6:809c6af8 r5:00000000 [ 8864.939252] r4:809c0d7c [ 8864.941841] [<8002eaa0>] (irq_exit) from [<8006f100>] (__handle_domain_irq+0x74/0xe8) [ 8864.949688] r4:809c0d7c r3:00000125 [ 8864.953342] [<8006f08c>] (__handle_domain_irq) from [<800087a0>] (gic_handle_irq+0x28/0x68) [ 8864.961707] r9:00000000 r8:00000002 r7:c080e100 r6:809c6c6c r5:be07bde8 r4:c080e10c [ 8864.969597] [<80008778>] (gic_handle_irq) from [<800133a4>] (__irq_svc+0x44/0x5c) [ 8864.977097] Exception stack(0xbe07bde8 to 0xbe07be30) [ 8864.982173] bde0: 00000001 00000001 00000000 00000000 be7c1680 00000000 [ 8864.990377] be00: be0cfe00 bd93eb40 00000002 00000000 00000000 be07be44 be07be00 be07be30 [ 8864.998573] be20: 8006278c 806f2934 20000013 ffffffff [ 8865.003638] r7:be07be1c r6:ffffffff r5:20000013 r4:806f2934 [ 8865.009447] [<806f2904>] (_raw_spin_unlock_irq) from [<80049cfc>] (finish_task_switch+0xa0/0x160) [ 8865.018334] r4:be7c1680 r3:be069380 [ 8865.021993] [<80049c5c>] (finish_task_switch) from [<806ed614>] (__schedule+0x1e0/0x5dc) [ 8865.030098] r8:be0cfe00 r7:bd23b600 r6:be069380 r5:be3289c0 r4:be7c1680 [ 8865.036942] [<806ed434>] (__schedule) from [<806edd0c>] (preempt_schedule_common+0x28/0x44) [ 8865.045307] r9:00000000 r8:809d4598 r7:00000001 r6:00000000 r5:be035740 r4:be07a000 [ 8865.053197] [<806edce4>] (preempt_schedule_common) from [<806edd68>] (_cond_resched+0x40/0x48) [ 8865.061822] r4:be07a000 r3:be07a000 [ 8865.065472] [<806edd28>] (_cond_resched) from [<8002e860>] (run_ksoftirqd+0x44/0x64) [ 8865.073252] [<8002e81c>] (run_ksoftirqd) from [<800494b0>] (smpboot_thread_fn+0x124/0x190) [ 8865.081550] [<8004938c>] (smpboot_thread_fn) from [<80045928>] (kthread+0xdc/0xf8) [ 8865.089133] r10:00000000 r9:00000000 r8:00000000 r7:8004938c r6:be035740 r5:be035780 [ 8865.097097] r4:00000000 r3:be069380 [ 8865.100752] [<8004584c>] (kthread) from [<8000ed10>] (ret_from_fork+0x14/0x24) [ 8865.107990] r7:00000000 r6:00000000 r5:8004584c r4:be035780 [ 8865.113767] Code: e320f000 e4913004 e4914004 e4915004 (e4916004) [ 8865.120006] ---[ end trace b0a4c6bd499288ca ]--- [ 8865.124697] Kernel panic - not syncing: Fatal exception in interrupt [ 8865.131084] ---[ end Kernel panic - not syncing: Fatal exception in interrupt Cc: [v3.19+] stable@vger.kernel.org Tested-by: Peter Chen Signed-off-by: Peter Chen Signed-off-by: Fugang Duan Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/fec_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index 9bb6220663b2..5ff8fee3850f 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -1597,7 +1597,7 @@ fec_enet_interrupt(int irq, void *dev_id) writel(int_events, fep->hwp + FEC_IEVENT); fec_enet_collect_events(fep, int_events); - if (fep->work_tx || fep->work_rx) { + if ((fep->work_tx || fep->work_rx) && fep->link) { ret = IRQ_HANDLED; if (napi_schedule_prep(&fep->napi)) { -- GitLab From 71bb8bd08ca61c8cd8b07ff13d3cca40b7272769 Mon Sep 17 00:00:00 2001 From: Vasundhara Volam Date: Wed, 4 Mar 2015 00:44:32 -0500 Subject: [PATCH 02681/11651] be2net: avoid creating the non-RSS default RXQ if FW allows to On BE2, BE3 and Skhawk-R chips one non-RSS (called "default") RXQ was needed to receive non-IP traffic. Some FW versions now export a capability called IFACE_FLAGS_DEFQ_RSS where this requirement doesn't hold. On such FWs the driver now does not create the non-RSS default queue. This prevents wasting one RXQ per VF. Signed-off-by: Vasundhara Volam Signed-off-by: Sathya Perla Signed-off-by: David S. Miller --- drivers/net/ethernet/emulex/benet/be.h | 5 +- drivers/net/ethernet/emulex/benet/be_cmds.c | 3 -- drivers/net/ethernet/emulex/benet/be_cmds.h | 5 +- .../net/ethernet/emulex/benet/be_ethtool.c | 2 +- drivers/net/ethernet/emulex/benet/be_main.c | 50 +++++++++++++------ 5 files changed, 41 insertions(+), 24 deletions(-) diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h index fac806a15a61..7e13faba03bd 100644 --- a/drivers/net/ethernet/emulex/benet/be.h +++ b/drivers/net/ethernet/emulex/benet/be.h @@ -488,6 +488,8 @@ struct be_adapter { /* Rx rings */ u16 num_rx_qs; + u16 num_rss_qs; + u16 need_def_rxq; struct be_rx_obj rx_obj[MAX_RX_QS]; u32 big_page_size; /* Compounded page size shared by rx wrbs */ @@ -635,9 +637,8 @@ extern const struct ethtool_ops be_ethtool_ops; for (i = 0, rxo = &adapter->rx_obj[i]; i < adapter->num_rx_qs; \ i++, rxo++) -/* Skip the default non-rss queue (last one)*/ #define for_all_rss_queues(adapter, rxo, i) \ - for (i = 0, rxo = &adapter->rx_obj[i]; i < (adapter->num_rx_qs - 1);\ + for (i = 0, rxo = &adapter->rx_obj[i]; i < adapter->num_rss_qs; \ i++, rxo++) #define for_all_tx_queues(adapter, txo, i) \ diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c index be00695b3be7..e1fa1d4c55d4 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/drivers/net/ethernet/emulex/benet/be_cmds.c @@ -3580,9 +3580,6 @@ static void be_copy_nic_desc(struct be_resources *res, /* Clear flags that driver is not interested in */ res->if_cap_flags = le32_to_cpu(desc->cap_flags) & BE_IF_CAP_FLAGS_WANT; - /* Need 1 RXQ as the default RXQ */ - if (res->max_rss_qs && res->max_rss_qs == res->max_rx_qs) - res->max_rss_qs -= 1; } /* Uses Mbox */ diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h index db761e8e42a3..49514821d0df 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.h +++ b/drivers/net/ethernet/emulex/benet/be_cmds.h @@ -588,14 +588,15 @@ enum be_if_flags { BE_IF_FLAGS_MCAST_PROMISCUOUS = 0x200, BE_IF_FLAGS_PASS_L2_ERRORS = 0x400, BE_IF_FLAGS_PASS_L3L4_ERRORS = 0x800, - BE_IF_FLAGS_MULTICAST = 0x1000 + BE_IF_FLAGS_MULTICAST = 0x1000, + BE_IF_FLAGS_DEFQ_RSS = 0x1000000 }; #define BE_IF_CAP_FLAGS_WANT (BE_IF_FLAGS_RSS | BE_IF_FLAGS_PROMISCUOUS |\ BE_IF_FLAGS_BROADCAST | BE_IF_FLAGS_VLAN_PROMISCUOUS |\ BE_IF_FLAGS_VLAN | BE_IF_FLAGS_MCAST_PROMISCUOUS |\ BE_IF_FLAGS_PASS_L3L4_ERRORS | BE_IF_FLAGS_MULTICAST |\ - BE_IF_FLAGS_UNTAGGED) + BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_DEFQ_RSS) #define BE_IF_FLAGS_ALL_PROMISCUOUS (BE_IF_FLAGS_PROMISCUOUS | \ BE_IF_FLAGS_VLAN_PROMISCUOUS |\ diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c index 4d2de4700769..b765c24625bf 100644 --- a/drivers/net/ethernet/emulex/benet/be_ethtool.c +++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c @@ -1097,7 +1097,7 @@ static int be_set_rss_hash_opts(struct be_adapter *adapter, return status; if (be_multi_rxq(adapter)) { - for (j = 0; j < 128; j += adapter->num_rx_qs - 1) { + for (j = 0; j < 128; j += adapter->num_rss_qs) { for_all_rss_queues(adapter, rxo, i) { if ((j + i) >= 128) break; diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 7eccebc676e2..c4c3a93cac99 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -2454,13 +2454,19 @@ static int be_rx_cqs_create(struct be_adapter *adapter) int rc, i; /* We can create as many RSS rings as there are EQs. */ - adapter->num_rx_qs = adapter->num_evt_qs; + adapter->num_rss_qs = adapter->num_evt_qs; - /* We'll use RSS only if atleast 2 RSS rings are supported. - * When RSS is used, we'll need a default RXQ for non-IP traffic. + /* We'll use RSS only if atleast 2 RSS rings are supported. */ + if (adapter->num_rss_qs <= 1) + adapter->num_rss_qs = 0; + + adapter->num_rx_qs = adapter->num_rss_qs + adapter->need_def_rxq; + + /* When the interface is not capable of RSS rings (and there is no + * need to create a default RXQ) we'll still need one RXQ */ - if (adapter->num_rx_qs > 1) - adapter->num_rx_qs++; + if (adapter->num_rx_qs == 0) + adapter->num_rx_qs = 1; adapter->big_page_size = (1 << get_order(rx_frag_size)) * PAGE_SIZE; for_all_rx_queues(adapter, rxo, i) { @@ -2479,8 +2485,7 @@ static int be_rx_cqs_create(struct be_adapter *adapter) } dev_info(&adapter->pdev->dev, - "created %d RSS queue(s) and 1 default RX queue\n", - adapter->num_rx_qs - 1); + "created %d RX queue(s)\n", adapter->num_rx_qs); return 0; } @@ -3110,12 +3115,14 @@ static int be_rx_qs_create(struct be_adapter *adapter) return rc; } - /* The FW would like the default RXQ to be created first */ - rxo = default_rxo(adapter); - rc = be_cmd_rxq_create(adapter, &rxo->q, rxo->cq.id, rx_frag_size, - adapter->if_handle, false, &rxo->rss_id); - if (rc) - return rc; + if (adapter->need_def_rxq || !adapter->num_rss_qs) { + rxo = default_rxo(adapter); + rc = be_cmd_rxq_create(adapter, &rxo->q, rxo->cq.id, + rx_frag_size, adapter->if_handle, + false, &rxo->rss_id); + if (rc) + return rc; + } for_all_rss_queues(adapter, rxo, i) { rc = be_cmd_rxq_create(adapter, &rxo->q, rxo->cq.id, @@ -3126,8 +3133,7 @@ static int be_rx_qs_create(struct be_adapter *adapter) } if (be_multi_rxq(adapter)) { - for (j = 0; j < RSS_INDIR_TABLE_LEN; - j += adapter->num_rx_qs - 1) { + for (j = 0; j < RSS_INDIR_TABLE_LEN; j += adapter->num_rss_qs) { for_all_rss_queues(adapter, rxo, i) { if ((j + i) >= RSS_INDIR_TABLE_LEN) break; @@ -3439,7 +3445,7 @@ static int be_if_create(struct be_adapter *adapter, u32 *if_handle, en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST | BE_IF_FLAGS_MULTICAST | BE_IF_FLAGS_PASS_L3L4_ERRORS | - BE_IF_FLAGS_RSS; + BE_IF_FLAGS_RSS | BE_IF_FLAGS_DEFQ_RSS; en_flags &= cap_flags; @@ -3649,6 +3655,7 @@ static void BEx_get_resources(struct be_adapter *adapter, res->max_evt_qs = 1; res->if_cap_flags = BE_IF_CAP_FLAGS_WANT; + res->if_cap_flags &= ~BE_IF_FLAGS_DEFQ_RSS; if (!(adapter->function_caps & BE_FUNCTION_CAPS_RSS)) res->if_cap_flags &= ~BE_IF_FLAGS_RSS; } @@ -3731,12 +3738,23 @@ static int be_get_resources(struct be_adapter *adapter) if (status) return status; + /* If a deafault RXQ must be created, we'll use up one RSSQ*/ + if (res.max_rss_qs && res.max_rss_qs == res.max_rx_qs && + !(res.if_cap_flags & BE_IF_FLAGS_DEFQ_RSS)) + res.max_rss_qs -= 1; + /* If RoCE may be enabled stash away half the EQs for RoCE */ if (be_roce_supported(adapter)) res.max_evt_qs /= 2; adapter->res = res; } + /* If FW supports RSS default queue, then skip creating non-RSS + * queue for non-IP traffic. + */ + adapter->need_def_rxq = (be_if_cap_flags(adapter) & + BE_IF_FLAGS_DEFQ_RSS) ? 0 : 1; + dev_info(dev, "Max: txqs %d, rxqs %d, rss %d, eqs %d, vfs %d\n", be_max_txqs(adapter), be_max_rxqs(adapter), be_max_rss(adapter), be_max_eqs(adapter), -- GitLab From f285873841299e027a6159dc3d3af0d0caf578d9 Mon Sep 17 00:00:00 2001 From: Vasundhara Volam Date: Wed, 4 Mar 2015 00:44:33 -0500 Subject: [PATCH 02682/11651] be2net: re-distribute SRIOV resources allowed by FW When SR-IOV is enabled in the adapter, the FW distributes resources evenly across the PF and it's VFs. This is currently done only for some resources. This patch adds support for a new cmd that queries the FW for the list of resources for which the distribution is allowed and distributes them accordingly. Signed-off-by: Vasundhara Volam Signed-off-by: Sathya Perla Signed-off-by: David S. Miller --- drivers/net/ethernet/emulex/benet/be.h | 4 + drivers/net/ethernet/emulex/benet/be_cmds.c | 108 ++++++++++++++------ drivers/net/ethernet/emulex/benet/be_cmds.h | 18 +++- drivers/net/ethernet/emulex/benet/be_main.c | 49 ++++++++- 4 files changed, 141 insertions(+), 38 deletions(-) diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h index 7e13faba03bd..996bbc6a244f 100644 --- a/drivers/net/ethernet/emulex/benet/be.h +++ b/drivers/net/ethernet/emulex/benet/be.h @@ -87,6 +87,7 @@ #define BE3_MAX_EVT_QS 16 #define BE3_SRIOV_MAX_EVT_QS 8 +#define MAX_RSS_IFACES 15 #define MAX_RX_QS 32 #define MAX_EVT_QS 32 #define MAX_TX_QS 32 @@ -411,8 +412,11 @@ struct be_resources { u16 max_tx_qs; u16 max_rss_qs; u16 max_rx_qs; + u16 max_cq_count; u16 max_uc_mac; /* Max UC MACs programmable */ u16 max_vlans; /* Number of vlans supported */ + u16 max_iface_count; + u16 max_mcc_count; u16 max_evt_qs; u32 if_cap_flags; u32 vf_if_cap_flags; /* VF if capability flags */ diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c index e1fa1d4c55d4..1c0e2b00db8d 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/drivers/net/ethernet/emulex/benet/be_cmds.c @@ -3577,6 +3577,9 @@ static void be_copy_nic_desc(struct be_resources *res, res->max_rss_qs = le16_to_cpu(desc->rssq_count); res->max_rx_qs = le16_to_cpu(desc->rq_count); res->max_evt_qs = le16_to_cpu(desc->eq_count); + res->max_cq_count = le16_to_cpu(desc->cq_count); + res->max_iface_count = le16_to_cpu(desc->iface_count); + res->max_mcc_count = le16_to_cpu(desc->mcc_count); /* Clear flags that driver is not interested in */ res->if_cap_flags = le32_to_cpu(desc->cap_flags) & BE_IF_CAP_FLAGS_WANT; @@ -3641,7 +3644,7 @@ err: /* Will use MBOX only if MCCQ has not been created */ int be_cmd_get_profile_config(struct be_adapter *adapter, - struct be_resources *res, u8 domain) + struct be_resources *res, u8 query, u8 domain) { struct be_cmd_resp_get_profile_config *resp; struct be_cmd_req_get_profile_config *req; @@ -3651,7 +3654,7 @@ int be_cmd_get_profile_config(struct be_adapter *adapter, struct be_nic_res_desc *nic; struct be_mcc_wrb wrb = {0}; struct be_dma_mem cmd; - u32 desc_count; + u16 desc_count; int status; memset(&cmd, 0, sizeof(struct be_dma_mem)); @@ -3670,12 +3673,19 @@ int be_cmd_get_profile_config(struct be_adapter *adapter, req->hdr.version = 1; req->type = ACTIVE_PROFILE_TYPE; + /* When QUERY_MODIFIABLE_FIELDS_TYPE bit is set, cmd returns the + * descriptors with all bits set to "1" for the fields which can be + * modified using SET_PROFILE_CONFIG cmd. + */ + if (query == RESOURCE_MODIFIABLE) + req->type |= QUERY_MODIFIABLE_FIELDS_TYPE; + status = be_cmd_notify_wait(adapter, &wrb); if (status) goto err; resp = cmd.va; - desc_count = le32_to_cpu(resp->desc_count); + desc_count = le16_to_cpu(resp->desc_count); pcie = be_get_pcie_desc(adapter->pdev->devfn, resp->func_param, desc_count); @@ -3800,14 +3810,74 @@ int be_cmd_config_qos(struct be_adapter *adapter, u32 max_rate, u16 link_speed, 1, version, domain); } +static void be_fill_vf_res_template(struct be_adapter *adapter, + struct be_resources pool_res, + u16 num_vfs, u16 num_vf_qs, + struct be_nic_res_desc *nic_vft) +{ + u32 vf_if_cap_flags = pool_res.vf_if_cap_flags; + struct be_resources res_mod = {0}; + + /* Resource with fields set to all '1's by GET_PROFILE_CONFIG cmd, + * which are modifiable using SET_PROFILE_CONFIG cmd. + */ + be_cmd_get_profile_config(adapter, &res_mod, RESOURCE_MODIFIABLE, 0); + + /* If RSS IFACE capability flags are modifiable for a VF, set the + * capability flag as valid and set RSS and DEFQ_RSS IFACE flags if + * more than 1 RSSQ is available for a VF. + * Otherwise, provision only 1 queue pair for VF. + */ + if (res_mod.vf_if_cap_flags & BE_IF_FLAGS_RSS) { + nic_vft->flags |= BIT(IF_CAPS_FLAGS_VALID_SHIFT); + if (num_vf_qs > 1) { + vf_if_cap_flags |= BE_IF_FLAGS_RSS; + if (pool_res.if_cap_flags & BE_IF_FLAGS_DEFQ_RSS) + vf_if_cap_flags |= BE_IF_FLAGS_DEFQ_RSS; + } else { + vf_if_cap_flags &= ~(BE_IF_FLAGS_RSS | + BE_IF_FLAGS_DEFQ_RSS); + } + + nic_vft->cap_flags = cpu_to_le32(vf_if_cap_flags); + } else { + num_vf_qs = 1; + } + + nic_vft->rq_count = cpu_to_le16(num_vf_qs); + nic_vft->txq_count = cpu_to_le16(num_vf_qs); + nic_vft->rssq_count = cpu_to_le16(num_vf_qs); + nic_vft->cq_count = cpu_to_le16(pool_res.max_cq_count / + (num_vfs + 1)); + + /* Distribute unicast MACs, VLANs, IFACE count and MCCQ count equally + * among the PF and it's VFs, if the fields are changeable + */ + if (res_mod.max_uc_mac == FIELD_MODIFIABLE) + nic_vft->unicast_mac_count = cpu_to_le16(pool_res.max_uc_mac / + (num_vfs + 1)); + + if (res_mod.max_vlans == FIELD_MODIFIABLE) + nic_vft->vlan_count = cpu_to_le16(pool_res.max_vlans / + (num_vfs + 1)); + + if (res_mod.max_iface_count == FIELD_MODIFIABLE) + nic_vft->iface_count = cpu_to_le16(pool_res.max_iface_count / + (num_vfs + 1)); + + if (res_mod.max_mcc_count == FIELD_MODIFIABLE) + nic_vft->mcc_count = cpu_to_le16(pool_res.max_mcc_count / + (num_vfs + 1)); +} + int be_cmd_set_sriov_config(struct be_adapter *adapter, - struct be_resources res, u16 num_vfs) + struct be_resources pool_res, u16 num_vfs, + u16 num_vf_qs) { struct { struct be_pcie_res_desc pcie; struct be_nic_res_desc nic_vft; } __packed desc; - u16 vf_q_count; if (BEx_chip(adapter) || lancer_chip(adapter)) return 0; @@ -3816,7 +3886,7 @@ int be_cmd_set_sriov_config(struct be_adapter *adapter, be_reset_pcie_desc(&desc.pcie); desc.pcie.hdr.desc_type = PCIE_RESOURCE_DESC_TYPE_V1; desc.pcie.hdr.desc_len = RESOURCE_DESC_SIZE_V1; - desc.pcie.flags = (1 << IMM_SHIFT) | (1 << NOSV_SHIFT); + desc.pcie.flags = BIT(IMM_SHIFT) | BIT(NOSV_SHIFT); desc.pcie.pf_num = adapter->pdev->devfn; desc.pcie.sriov_state = num_vfs ? 1 : 0; desc.pcie.num_vfs = cpu_to_le16(num_vfs); @@ -3825,32 +3895,12 @@ int be_cmd_set_sriov_config(struct be_adapter *adapter, be_reset_nic_desc(&desc.nic_vft); desc.nic_vft.hdr.desc_type = NIC_RESOURCE_DESC_TYPE_V1; desc.nic_vft.hdr.desc_len = RESOURCE_DESC_SIZE_V1; - desc.nic_vft.flags = (1 << VFT_SHIFT) | (1 << IMM_SHIFT) | - (1 << NOSV_SHIFT); + desc.nic_vft.flags = BIT(VFT_SHIFT) | BIT(IMM_SHIFT) | BIT(NOSV_SHIFT); desc.nic_vft.pf_num = adapter->pdev->devfn; desc.nic_vft.vf_num = 0; - if (num_vfs && res.vf_if_cap_flags & BE_IF_FLAGS_RSS) { - /* If number of VFs requested is 8 less than max supported, - * assign 8 queue pairs to the PF and divide the remaining - * resources evenly among the VFs - */ - if (num_vfs < (be_max_vfs(adapter) - 8)) - vf_q_count = (res.max_rss_qs - 8) / num_vfs; - else - vf_q_count = res.max_rss_qs / num_vfs; - - desc.nic_vft.rq_count = cpu_to_le16(vf_q_count); - desc.nic_vft.txq_count = cpu_to_le16(vf_q_count); - desc.nic_vft.rssq_count = cpu_to_le16(vf_q_count - 1); - desc.nic_vft.cq_count = cpu_to_le16(3 * vf_q_count); - } else { - desc.nic_vft.txq_count = cpu_to_le16(1); - desc.nic_vft.rq_count = cpu_to_le16(1); - desc.nic_vft.rssq_count = cpu_to_le16(0); - /* One CQ for each TX, RX and MCCQ */ - desc.nic_vft.cq_count = cpu_to_le16(3); - } + be_fill_vf_res_template(adapter, pool_res, num_vfs, num_vf_qs, + &desc.nic_vft); return be_cmd_set_profile_config(adapter, &desc, 2 * RESOURCE_DESC_SIZE_V1, 2, 1, 0); diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h index 49514821d0df..53e903f37247 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.h +++ b/drivers/net/ethernet/emulex/benet/be_cmds.h @@ -2022,6 +2022,7 @@ struct be_cmd_req_set_ext_fat_caps { #define PORT_RESOURCE_DESC_TYPE_V1 0x55 #define MAX_RESOURCE_DESC 264 +#define IF_CAPS_FLAGS_VALID_SHIFT 0 /* IF caps valid */ #define VFT_SHIFT 3 /* VF template */ #define IMM_SHIFT 6 /* Immediate */ #define NOSV_SHIFT 7 /* No save */ @@ -2132,20 +2133,28 @@ struct be_cmd_resp_get_func_config { u8 func_param[MAX_RESOURCE_DESC * RESOURCE_DESC_SIZE_V1]; }; -#define ACTIVE_PROFILE_TYPE 0x2 +enum { + RESOURCE_LIMITS, + RESOURCE_MODIFIABLE +}; + struct be_cmd_req_get_profile_config { struct be_cmd_req_hdr hdr; u8 rsvd; +#define ACTIVE_PROFILE_TYPE 0x2 +#define QUERY_MODIFIABLE_FIELDS_TYPE BIT(3) u8 type; u16 rsvd1; }; struct be_cmd_resp_get_profile_config { struct be_cmd_resp_hdr hdr; - u32 desc_count; + __le16 desc_count; + u16 rsvd; u8 func_param[MAX_RESOURCE_DESC * RESOURCE_DESC_SIZE_V1]; }; +#define FIELD_MODIFIABLE 0xFFFF struct be_cmd_req_set_profile_config { struct be_cmd_req_hdr hdr; u32 rsvd; @@ -2345,7 +2354,7 @@ int be_cmd_query_port_name(struct be_adapter *adapter); int be_cmd_get_func_config(struct be_adapter *adapter, struct be_resources *res); int be_cmd_get_profile_config(struct be_adapter *adapter, - struct be_resources *res, u8 domain); + struct be_resources *res, u8 query, u8 domain); int be_cmd_get_active_profile(struct be_adapter *adapter, u16 *profile); int be_cmd_get_if_id(struct be_adapter *adapter, struct be_vf_cfg *vf_cfg, int vf_num); @@ -2356,4 +2365,5 @@ int be_cmd_set_logical_link_config(struct be_adapter *adapter, int be_cmd_set_vxlan_port(struct be_adapter *adapter, __be16 port); int be_cmd_manage_iface(struct be_adapter *adapter, u32 iface, u8 op); int be_cmd_set_sriov_config(struct be_adapter *adapter, - struct be_resources res, u16 num_vfs); + struct be_resources res, u16 num_vfs, + u16 num_vf_qs); diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index c4c3a93cac99..20305e1e0ec4 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -3408,8 +3408,39 @@ static void be_disable_vxlan_offloads(struct be_adapter *adapter) } #endif +static u16 be_calculate_vf_qs(struct be_adapter *adapter, u16 num_vfs) +{ + struct be_resources res = adapter->pool_res; + u16 num_vf_qs = 1; + + /* Distribute the queue resources equally among the PF and it's VFs + * Do not distribute queue resources in multi-channel configuration. + */ + if (num_vfs && !be_is_mc(adapter)) { + /* If number of VFs requested is 8 less than max supported, + * assign 8 queue pairs to the PF and divide the remaining + * resources evenly among the VFs + */ + if (num_vfs < (be_max_vfs(adapter) - 8)) + num_vf_qs = (res.max_rss_qs - 8) / num_vfs; + else + num_vf_qs = res.max_rss_qs / num_vfs; + + /* Skyhawk-R chip supports only MAX_RSS_IFACES RSS capable + * interfaces per port. Provide RSS on VFs, only if number + * of VFs requested is less than MAX_RSS_IFACES limit. + */ + if (num_vfs >= MAX_RSS_IFACES) + num_vf_qs = 1; + } + return num_vf_qs; +} + static int be_clear(struct be_adapter *adapter) { + struct pci_dev *pdev = adapter->pdev; + u16 num_vf_qs; + be_cancel_worker(adapter); if (sriov_enabled(adapter)) @@ -3418,9 +3449,13 @@ static int be_clear(struct be_adapter *adapter) /* Re-configure FW to distribute resources evenly across max-supported * number of VFs, only when VFs are not already enabled. */ - if (be_physfn(adapter) && !pci_vfs_assigned(adapter->pdev)) + if (be_physfn(adapter) && !pci_vfs_assigned(pdev)) { + num_vf_qs = be_calculate_vf_qs(adapter, + pci_sriov_get_totalvfs(pdev)); be_cmd_set_sriov_config(adapter, adapter->pool_res, - pci_sriov_get_totalvfs(adapter->pdev)); + pci_sriov_get_totalvfs(pdev), + num_vf_qs); + } #ifdef CONFIG_BE2NET_VXLAN be_disable_vxlan_offloads(adapter); @@ -3469,6 +3504,7 @@ static int be_vfs_if_create(struct be_adapter *adapter) for_all_vfs(adapter, vf_cfg, vf) { if (!BE3_chip(adapter)) { status = be_cmd_get_profile_config(adapter, &res, + RESOURCE_LIMITS, vf + 1); if (!status) cap_flags = res.if_cap_flags; @@ -3635,7 +3671,8 @@ static void BEx_get_resources(struct be_adapter *adapter, /* On a SuperNIC profile, the driver needs to use the * GET_PROFILE_CONFIG cmd to query the per-function TXQ limits */ - be_cmd_get_profile_config(adapter, &super_nic_res, 0); + be_cmd_get_profile_config(adapter, &super_nic_res, + RESOURCE_LIMITS, 0); /* Some old versions of BE3 FW don't report max_tx_qs value */ res->max_tx_qs = super_nic_res.max_tx_qs ? : BE3_MAX_TX_QS; } else { @@ -3680,7 +3717,7 @@ static int be_get_sriov_config(struct be_adapter *adapter) int max_vfs, old_vfs; /* Some old versions of BE3 FW don't report max_vfs value */ - be_cmd_get_profile_config(adapter, &res, 0); + be_cmd_get_profile_config(adapter, &res, RESOURCE_LIMITS, 0); if (BE3_chip(adapter) && !res.max_vfs) { max_vfs = pci_sriov_get_totalvfs(adapter->pdev); @@ -3769,6 +3806,7 @@ static int be_get_resources(struct be_adapter *adapter) static void be_sriov_config(struct be_adapter *adapter) { struct device *dev = &adapter->pdev->dev; + u16 num_vf_qs; int status; status = be_get_sriov_config(adapter); @@ -3787,9 +3825,10 @@ static void be_sriov_config(struct be_adapter *adapter) * Also, this is done by FW in Lancer chip. */ if (be_max_vfs(adapter) && !pci_num_vf(adapter->pdev)) { + num_vf_qs = be_calculate_vf_qs(adapter, adapter->num_vfs); status = be_cmd_set_sriov_config(adapter, adapter->pool_res, - adapter->num_vfs); + adapter->num_vfs, num_vf_qs); if (status) dev_err(dev, "Failed to optimize SR-IOV resources\n"); } -- GitLab From ace40aff3cee8a82c39375761ea65cc748aa1623 Mon Sep 17 00:00:00 2001 From: Vasundhara Volam Date: Wed, 4 Mar 2015 00:44:34 -0500 Subject: [PATCH 02683/11651] be2net: implement .sriov_configure() PCI callback This patch implements the .sriov_configure() PCI method to allow for runtime enabling/disabling of VFs. The module param "num_vfs" is now deprecated. At the time of driver load the PF-pool resources are allocated to the PF. When the user enables VFs, the resources are then re-distributed across PFs and VFs based on the number of VFs enabled. Signed-off-by: Vasundhara Volam Signed-off-by: Sathya Perla Signed-off-by: David S. Miller --- drivers/net/ethernet/emulex/benet/be_cmds.c | 3 - drivers/net/ethernet/emulex/benet/be_main.c | 169 +++++++++++++------- 2 files changed, 107 insertions(+), 65 deletions(-) diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c index 1c0e2b00db8d..75cb4610423b 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/drivers/net/ethernet/emulex/benet/be_cmds.c @@ -3879,9 +3879,6 @@ int be_cmd_set_sriov_config(struct be_adapter *adapter, struct be_nic_res_desc nic_vft; } __packed desc; - if (BEx_chip(adapter) || lancer_chip(adapter)) - return 0; - /* PF PCIE descriptor */ be_reset_pcie_desc(&desc.pcie); desc.pcie.hdr.desc_type = PCIE_RESOURCE_DESC_TYPE_V1; diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 20305e1e0ec4..5652b005947f 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -30,6 +30,9 @@ MODULE_DESCRIPTION(DRV_DESC " " DRV_VER); MODULE_AUTHOR("Emulex Corporation"); MODULE_LICENSE("GPL"); +/* num_vfs module param is obsolete. + * Use sysfs method to enable/disable VFs. + */ static unsigned int num_vfs; module_param(num_vfs, uint, S_IRUGO); MODULE_PARM_DESC(num_vfs, "Number of PCI VFs to initialize"); @@ -3449,7 +3452,8 @@ static int be_clear(struct be_adapter *adapter) /* Re-configure FW to distribute resources evenly across max-supported * number of VFs, only when VFs are not already enabled. */ - if (be_physfn(adapter) && !pci_vfs_assigned(pdev)) { + if (skyhawk_chip(adapter) && be_physfn(adapter) && + !pci_vfs_assigned(pdev)) { num_vf_qs = be_calculate_vf_qs(adapter, pci_sriov_get_totalvfs(pdev)); be_cmd_set_sriov_config(adapter, adapter->pool_res, @@ -3712,13 +3716,12 @@ static void be_setup_init(struct be_adapter *adapter) static int be_get_sriov_config(struct be_adapter *adapter) { - struct device *dev = &adapter->pdev->dev; struct be_resources res = {0}; int max_vfs, old_vfs; - /* Some old versions of BE3 FW don't report max_vfs value */ be_cmd_get_profile_config(adapter, &res, RESOURCE_LIMITS, 0); + /* Some old versions of BE3 FW don't report max_vfs value */ if (BE3_chip(adapter) && !res.max_vfs) { max_vfs = pci_sriov_get_totalvfs(adapter->pdev); res.max_vfs = max_vfs > 0 ? min(MAX_VFS, max_vfs) : 0; @@ -3726,35 +3729,49 @@ static int be_get_sriov_config(struct be_adapter *adapter) adapter->pool_res = res; - if (!be_max_vfs(adapter)) { - if (num_vfs) - dev_warn(dev, "SRIOV is disabled. Ignoring num_vfs\n"); - adapter->num_vfs = 0; - return 0; - } - - pci_sriov_set_totalvfs(adapter->pdev, be_max_vfs(adapter)); - - /* validate num_vfs module param */ + /* If during previous unload of the driver, the VFs were not disabled, + * then we cannot rely on the PF POOL limits for the TotalVFs value. + * Instead use the TotalVFs value stored in the pci-dev struct. + */ old_vfs = pci_num_vf(adapter->pdev); if (old_vfs) { - dev_info(dev, "%d VFs are already enabled\n", old_vfs); - if (old_vfs != num_vfs) - dev_warn(dev, "Ignoring num_vfs=%d setting\n", num_vfs); + dev_info(&adapter->pdev->dev, "%d VFs are already enabled\n", + old_vfs); + + adapter->pool_res.max_vfs = + pci_sriov_get_totalvfs(adapter->pdev); adapter->num_vfs = old_vfs; - } else { - if (num_vfs > be_max_vfs(adapter)) { - dev_info(dev, "Resources unavailable to init %d VFs\n", - num_vfs); - dev_info(dev, "Limiting to %d VFs\n", - be_max_vfs(adapter)); - } - adapter->num_vfs = min_t(u16, num_vfs, be_max_vfs(adapter)); } return 0; } +static void be_alloc_sriov_res(struct be_adapter *adapter) +{ + int old_vfs = pci_num_vf(adapter->pdev); + u16 num_vf_qs; + int status; + + be_get_sriov_config(adapter); + + if (!old_vfs) + pci_sriov_set_totalvfs(adapter->pdev, be_max_vfs(adapter)); + + /* When the HW is in SRIOV capable configuration, the PF-pool + * resources are given to PF during driver load, if there are no + * old VFs. This facility is not available in BE3 FW. + * Also, this is done by FW in Lancer chip. + */ + if (skyhawk_chip(adapter) && be_max_vfs(adapter) && !old_vfs) { + num_vf_qs = be_calculate_vf_qs(adapter, 0); + status = be_cmd_set_sriov_config(adapter, adapter->pool_res, 0, + num_vf_qs); + if (status) + dev_err(&adapter->pdev->dev, + "Failed to optimize SRIOV resources\n"); + } +} + static int be_get_resources(struct be_adapter *adapter) { struct device *dev = &adapter->pdev->dev; @@ -3800,40 +3817,12 @@ static int be_get_resources(struct be_adapter *adapter) be_max_uc(adapter), be_max_mc(adapter), be_max_vlans(adapter)); + /* Sanitize cfg_num_qs based on HW and platform limits */ + adapter->cfg_num_qs = min_t(u16, netif_get_num_default_rss_queues(), + be_max_qs(adapter)); return 0; } -static void be_sriov_config(struct be_adapter *adapter) -{ - struct device *dev = &adapter->pdev->dev; - u16 num_vf_qs; - int status; - - status = be_get_sriov_config(adapter); - if (status) { - dev_err(dev, "Failed to query SR-IOV configuration\n"); - dev_err(dev, "SR-IOV cannot be enabled\n"); - return; - } - - /* When the HW is in SRIOV capable configuration, the PF-pool - * resources are equally distributed across the max-number of - * VFs. The user may request only a subset of the max-vfs to be - * enabled. Based on num_vfs, redistribute the resources across - * num_vfs so that each VF will have access to more number of - * resources. This facility is not available in BE3 FW. - * Also, this is done by FW in Lancer chip. - */ - if (be_max_vfs(adapter) && !pci_num_vf(adapter->pdev)) { - num_vf_qs = be_calculate_vf_qs(adapter, adapter->num_vfs); - status = be_cmd_set_sriov_config(adapter, - adapter->pool_res, - adapter->num_vfs, num_vf_qs); - if (status) - dev_err(dev, "Failed to optimize SR-IOV resources\n"); - } -} - static int be_get_config(struct be_adapter *adapter) { int status, level; @@ -3864,9 +3853,6 @@ static int be_get_config(struct be_adapter *adapter) "Using profile 0x%x\n", profile_id); } - if (!BE2_chip(adapter) && be_physfn(adapter)) - be_sriov_config(adapter); - status = be_get_resources(adapter); if (status) return status; @@ -3876,9 +3862,6 @@ static int be_get_config(struct be_adapter *adapter) if (!adapter->pmac_id) return -ENOMEM; - /* Sanitize cfg_num_qs based on HW and platform limits */ - adapter->cfg_num_qs = min(adapter->cfg_num_qs, be_max_qs(adapter)); - return 0; } @@ -4053,6 +4036,9 @@ static int be_setup(struct be_adapter *adapter) if (!lancer_chip(adapter)) be_cmd_req_native_mode(adapter); + if (!BE2_chip(adapter) && be_physfn(adapter)) + be_alloc_sriov_res(adapter); + status = be_get_config(adapter); if (status) goto err; @@ -5274,7 +5260,6 @@ static int be_drv_init(struct be_adapter *adapter) /* Must be a power of 2 or else MODULO will BUG_ON */ adapter->be_get_temp_freq = 64; - adapter->cfg_num_qs = netif_get_num_default_rss_queues(); return 0; @@ -5598,6 +5583,60 @@ err: dev_err(&adapter->pdev->dev, "EEH resume failed\n"); } +static int be_pci_sriov_configure(struct pci_dev *pdev, int num_vfs) +{ + struct be_adapter *adapter = pci_get_drvdata(pdev); + u16 num_vf_qs; + int status; + + if (!num_vfs) + be_vf_clear(adapter); + + adapter->num_vfs = num_vfs; + + if (adapter->num_vfs == 0 && pci_vfs_assigned(pdev)) { + dev_warn(&pdev->dev, + "Cannot disable VFs while they are assigned\n"); + return -EBUSY; + } + + /* When the HW is in SRIOV capable configuration, the PF-pool resources + * are equally distributed across the max-number of VFs. The user may + * request only a subset of the max-vfs to be enabled. + * Based on num_vfs, redistribute the resources across num_vfs so that + * each VF will have access to more number of resources. + * This facility is not available in BE3 FW. + * Also, this is done by FW in Lancer chip. + */ + if (skyhawk_chip(adapter) && !pci_num_vf(pdev)) { + num_vf_qs = be_calculate_vf_qs(adapter, adapter->num_vfs); + status = be_cmd_set_sriov_config(adapter, adapter->pool_res, + adapter->num_vfs, num_vf_qs); + if (status) + dev_err(&pdev->dev, + "Failed to optimize SR-IOV resources\n"); + } + + status = be_get_resources(adapter); + if (status) + return be_cmd_status(status); + + /* Updating real_num_tx/rx_queues() requires rtnl_lock() */ + rtnl_lock(); + status = be_update_queues(adapter); + rtnl_unlock(); + if (status) + return be_cmd_status(status); + + if (adapter->num_vfs) + status = be_vf_setup(adapter); + + if (!status) + return adapter->num_vfs; + + return 0; +} + static const struct pci_error_handlers be_eeh_handlers = { .error_detected = be_eeh_err_detected, .slot_reset = be_eeh_reset, @@ -5612,6 +5651,7 @@ static struct pci_driver be_driver = { .suspend = be_suspend, .resume = be_pci_resume, .shutdown = be_shutdown, + .sriov_configure = be_pci_sriov_configure, .err_handler = &be_eeh_handlers }; @@ -5625,6 +5665,11 @@ static int __init be_init_module(void) rx_frag_size = 2048; } + if (num_vfs > 0) { + pr_info(DRV_NAME " : Module param num_vfs is obsolete."); + pr_info(DRV_NAME " : Use sysfs method to enable VFs\n"); + } + return pci_register_driver(&be_driver); } module_init(be_init_module); -- GitLab From 9215f437b85da339a7dfe3db6e288637406f88b2 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 4 Mar 2015 08:36:31 +0100 Subject: [PATCH 02684/11651] team: don't traverse port list using rcu in team_set_mac_address Currently the list is traversed using rcu variant. That is not correct since dev_set_mac_address can be called which eventually calls rtmsg_ifinfo_build_skb and there, skb allocation can sleep. So fix this by remove the rcu usage here. Fixes: 3d249d4ca7 "net: introduce ethernet teaming device" Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/team/team.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index f1ee71e22241..7d394846afc2 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -1730,11 +1730,11 @@ static int team_set_mac_address(struct net_device *dev, void *p) if (dev->type == ARPHRD_ETHER && !is_valid_ether_addr(addr->sa_data)) return -EADDRNOTAVAIL; memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); - rcu_read_lock(); - list_for_each_entry_rcu(port, &team->port_list, list) + mutex_lock(&team->lock); + list_for_each_entry(port, &team->port_list, list) if (team->ops.port_change_dev_addr) team->ops.port_change_dev_addr(team, port); - rcu_read_unlock(); + mutex_unlock(&team->lock); return 0; } -- GitLab From 432ec92b299e4bcbb0d9a116789563d53b2798e1 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Mon, 2 Mar 2015 10:18:13 +0100 Subject: [PATCH 02685/11651] PM / wakeup: export pm_system_wakeup symbol Export pm_system_wakeup function to allow irq handlers to deal with system wakeup. This is needed for shared IRQ lines where one of the handler is registered with IRQF_NO_SUSPEND, while the other ones want to configure it as a wakeup source. In this specific case, irq core does not handle the wakeup process and leave the decision to each irq handler. Signed-off-by: Boris Brezillon Reviewed-by: Alexandre Belloni Acked-by: Nicolas Ferre Acked-by: Mark Rutland Signed-off-by: Rafael J. Wysocki --- drivers/base/power/wakeup.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c index c2744b30d5d9..aab7158d2afe 100644 --- a/drivers/base/power/wakeup.c +++ b/drivers/base/power/wakeup.c @@ -730,6 +730,7 @@ void pm_system_wakeup(void) pm_abort_suspend = true; freeze_wake(); } +EXPORT_SYMBOL_GPL(pm_system_wakeup); void pm_wakeup_clear(void) { -- GitLab From 603b1a232604dcd19a28eaddf70eee9fbe3edc88 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Mon, 2 Mar 2015 10:18:14 +0100 Subject: [PATCH 02686/11651] rtc: at91sam9: rework wakeup and interrupt handling The IRQ line used by the RTC device is usually shared with the system timer (PIT) on at91 platforms. Since timers are registering their handlers with IRQF_NO_SUSPEND, we should expect being called in suspended state, and properly wake the system up when this is the case. Set IRQF_COND_SUSPEND flag when registering the IRQ handler to inform irq core that it can safely be called while the system is suspended. Signed-off-by: Boris Brezillon Reviewed-by: Alexandre Belloni Acked-by: Nicolas Ferre Acked-by: Mark Rutland Signed-off-by: Rafael J. Wysocki --- drivers/rtc/rtc-at91sam9.c | 73 +++++++++++++++++++++++++++++++------- 1 file changed, 61 insertions(+), 12 deletions(-) diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c index 2183fd2750ab..5ccaee32df72 100644 --- a/drivers/rtc/rtc-at91sam9.c +++ b/drivers/rtc/rtc-at91sam9.c @@ -23,6 +23,7 @@ #include #include #include +#include #include /* @@ -77,6 +78,9 @@ struct sam9_rtc { unsigned int gpbr_offset; int irq; struct clk *sclk; + bool suspended; + unsigned long events; + spinlock_t lock; }; #define rtt_readl(rtc, field) \ @@ -271,14 +275,9 @@ static int at91_rtc_proc(struct device *dev, struct seq_file *seq) return 0; } -/* - * IRQ handler for the RTC - */ -static irqreturn_t at91_rtc_interrupt(int irq, void *_rtc) +static irqreturn_t at91_rtc_cache_events(struct sam9_rtc *rtc) { - struct sam9_rtc *rtc = _rtc; u32 sr, mr; - unsigned long events = 0; /* Shared interrupt may be for another device. Note: reading * SR clears it, so we must only read it in this irq handler! @@ -290,18 +289,54 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *_rtc) /* alarm status */ if (sr & AT91_RTT_ALMS) - events |= (RTC_AF | RTC_IRQF); + rtc->events |= (RTC_AF | RTC_IRQF); /* timer update/increment */ if (sr & AT91_RTT_RTTINC) - events |= (RTC_UF | RTC_IRQF); + rtc->events |= (RTC_UF | RTC_IRQF); + + return IRQ_HANDLED; +} + +static void at91_rtc_flush_events(struct sam9_rtc *rtc) +{ + if (!rtc->events) + return; - rtc_update_irq(rtc->rtcdev, 1, events); + rtc_update_irq(rtc->rtcdev, 1, rtc->events); + rtc->events = 0; pr_debug("%s: num=%ld, events=0x%02lx\n", __func__, - events >> 8, events & 0x000000FF); + rtc->events >> 8, rtc->events & 0x000000FF); +} - return IRQ_HANDLED; +/* + * IRQ handler for the RTC + */ +static irqreturn_t at91_rtc_interrupt(int irq, void *_rtc) +{ + struct sam9_rtc *rtc = _rtc; + int ret; + + spin_lock(&rtc->lock); + + ret = at91_rtc_cache_events(rtc); + + /* We're called in suspended state */ + if (rtc->suspended) { + /* Mask irqs coming from this peripheral */ + rtt_writel(rtc, MR, + rtt_readl(rtc, MR) & + ~(AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN)); + /* Trigger a system wakeup */ + pm_system_wakeup(); + } else { + at91_rtc_flush_events(rtc); + } + + spin_unlock(&rtc->lock); + + return ret; } static const struct rtc_class_ops at91_rtc_ops = { @@ -421,7 +456,8 @@ static int at91_rtc_probe(struct platform_device *pdev) /* register irq handler after we know what name we'll use */ ret = devm_request_irq(&pdev->dev, rtc->irq, at91_rtc_interrupt, - IRQF_SHARED, dev_name(&rtc->rtcdev->dev), rtc); + IRQF_SHARED | IRQF_COND_SUSPEND, + dev_name(&rtc->rtcdev->dev), rtc); if (ret) { dev_dbg(&pdev->dev, "can't share IRQ %d?\n", rtc->irq); return ret; @@ -482,7 +518,12 @@ static int at91_rtc_suspend(struct device *dev) rtc->imr = mr & (AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN); if (rtc->imr) { if (device_may_wakeup(dev) && (mr & AT91_RTT_ALMIEN)) { + unsigned long flags; + enable_irq_wake(rtc->irq); + spin_lock_irqsave(&rtc->lock, flags); + rtc->suspended = true; + spin_unlock_irqrestore(&rtc->lock, flags); /* don't let RTTINC cause wakeups */ if (mr & AT91_RTT_RTTINCIEN) rtt_writel(rtc, MR, mr & ~AT91_RTT_RTTINCIEN); @@ -499,10 +540,18 @@ static int at91_rtc_resume(struct device *dev) u32 mr; if (rtc->imr) { + unsigned long flags; + if (device_may_wakeup(dev)) disable_irq_wake(rtc->irq); mr = rtt_readl(rtc, MR); rtt_writel(rtc, MR, mr | rtc->imr); + + spin_lock_irqsave(&rtc->lock, flags); + rtc->suspended = false; + at91_rtc_cache_events(rtc); + at91_rtc_flush_events(rtc); + spin_unlock_irqrestore(&rtc->lock, flags); } return 0; -- GitLab From dd1f1f391dd7f3a39a3983df2ca076871111cec9 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Mon, 2 Mar 2015 10:18:15 +0100 Subject: [PATCH 02687/11651] rtc: at91rm9200: rework wakeup and interrupt handling The IRQ line used by the RTC device is usually shared with the system timer (PIT) on at91 platforms. Since timers are registering their handlers with IRQF_NO_SUSPEND, we should expect being called in suspended state, and properly wake the system up when this is the case. Set IRQF_COND_SUSPEND flag when registering the IRQ handler to inform irq core that it can safely be called while the system is suspended. Signed-off-by: Boris Brezillon Reviewed-by: Alexandre Belloni Acked-by: Nicolas Ferre Acked-by: Mark Rutland Signed-off-by: Rafael J. Wysocki --- drivers/rtc/rtc-at91rm9200.c | 62 ++++++++++++++++++++++++++++-------- 1 file changed, 48 insertions(+), 14 deletions(-) diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c index 70a5d94cc766..b4f7744f6751 100644 --- a/drivers/rtc/rtc-at91rm9200.c +++ b/drivers/rtc/rtc-at91rm9200.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include "rtc-at91rm9200.h" @@ -54,6 +55,10 @@ static void __iomem *at91_rtc_regs; static int irq; static DEFINE_SPINLOCK(at91_rtc_lock); static u32 at91_rtc_shadow_imr; +static bool suspended; +static DEFINE_SPINLOCK(suspended_lock); +static unsigned long cached_events; +static u32 at91_rtc_imr; static void at91_rtc_write_ier(u32 mask) { @@ -290,7 +295,9 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *dev_id) struct rtc_device *rtc = platform_get_drvdata(pdev); unsigned int rtsr; unsigned long events = 0; + int ret = IRQ_NONE; + spin_lock(&suspended_lock); rtsr = at91_rtc_read(AT91_RTC_SR) & at91_rtc_read_imr(); if (rtsr) { /* this interrupt is shared! Is it ours? */ if (rtsr & AT91_RTC_ALARM) @@ -304,14 +311,22 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *dev_id) at91_rtc_write(AT91_RTC_SCCR, rtsr); /* clear status reg */ - rtc_update_irq(rtc, 1, events); + if (!suspended) { + rtc_update_irq(rtc, 1, events); - dev_dbg(&pdev->dev, "%s(): num=%ld, events=0x%02lx\n", __func__, - events >> 8, events & 0x000000FF); + dev_dbg(&pdev->dev, "%s(): num=%ld, events=0x%02lx\n", + __func__, events >> 8, events & 0x000000FF); + } else { + cached_events |= events; + at91_rtc_write_idr(at91_rtc_imr); + pm_system_wakeup(); + } - return IRQ_HANDLED; + ret = IRQ_HANDLED; } - return IRQ_NONE; /* not handled */ + spin_lock(&suspended_lock); + + return ret; } static const struct at91_rtc_config at91rm9200_config = { @@ -401,8 +416,8 @@ static int __init at91_rtc_probe(struct platform_device *pdev) AT91_RTC_CALEV); ret = devm_request_irq(&pdev->dev, irq, at91_rtc_interrupt, - IRQF_SHARED, - "at91_rtc", pdev); + IRQF_SHARED | IRQF_COND_SUSPEND, + "at91_rtc", pdev); if (ret) { dev_err(&pdev->dev, "IRQ %d already in use.\n", irq); return ret; @@ -454,8 +469,6 @@ static void at91_rtc_shutdown(struct platform_device *pdev) /* AT91RM9200 RTC Power management control */ -static u32 at91_rtc_imr; - static int at91_rtc_suspend(struct device *dev) { /* this IRQ is shared with DBGU and other hardware which isn't @@ -464,21 +477,42 @@ static int at91_rtc_suspend(struct device *dev) at91_rtc_imr = at91_rtc_read_imr() & (AT91_RTC_ALARM|AT91_RTC_SECEV); if (at91_rtc_imr) { - if (device_may_wakeup(dev)) + if (device_may_wakeup(dev)) { + unsigned long flags; + enable_irq_wake(irq); - else + + spin_lock_irqsave(&suspended_lock, flags); + suspended = true; + spin_unlock_irqrestore(&suspended_lock, flags); + } else { at91_rtc_write_idr(at91_rtc_imr); + } } return 0; } static int at91_rtc_resume(struct device *dev) { + struct rtc_device *rtc = dev_get_drvdata(dev); + if (at91_rtc_imr) { - if (device_may_wakeup(dev)) + if (device_may_wakeup(dev)) { + unsigned long flags; + + spin_lock_irqsave(&suspended_lock, flags); + + if (cached_events) { + rtc_update_irq(rtc, 1, cached_events); + cached_events = 0; + } + + suspended = false; + spin_unlock_irqrestore(&suspended_lock, flags); + disable_irq_wake(irq); - else - at91_rtc_write_ier(at91_rtc_imr); + } + at91_rtc_write_ier(at91_rtc_imr); } return 0; } -- GitLab From 947f5b108543a6521728466ad5be6e2c4a35a65b Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Mon, 2 Mar 2015 10:18:16 +0100 Subject: [PATCH 02688/11651] clk: at91: implement suspend/resume for the PMC irqchip The irq line used by the PMC block is shared with several peripherals including the init timer which is registering its handler with IRQF_NO_SUSPEND. Implement the appropriate suspend/resume callback for the PMC irqchip, and inform irq core that PMC irq handler can be safely called while the system is suspended by setting IRQF_COND_SUSPEND. Signed-off-by: Boris Brezillon Reviewed-by: Alexandre Belloni Acked-by: Nicolas Ferre Acked-by: Mark Rutland Signed-off-by: Rafael J. Wysocki --- drivers/clk/at91/pmc.c | 20 +++++++++++++++++++- drivers/clk/at91/pmc.h | 1 + 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c index f07c8152e5cc..3f27d21fb729 100644 --- a/drivers/clk/at91/pmc.c +++ b/drivers/clk/at91/pmc.c @@ -89,12 +89,29 @@ static int pmc_irq_set_type(struct irq_data *d, unsigned type) return 0; } +static void pmc_irq_suspend(struct irq_data *d) +{ + struct at91_pmc *pmc = irq_data_get_irq_chip_data(d); + + pmc->imr = pmc_read(pmc, AT91_PMC_IMR); + pmc_write(pmc, AT91_PMC_IDR, pmc->imr); +} + +static void pmc_irq_resume(struct irq_data *d) +{ + struct at91_pmc *pmc = irq_data_get_irq_chip_data(d); + + pmc_write(pmc, AT91_PMC_IER, pmc->imr); +} + static struct irq_chip pmc_irq = { .name = "PMC", .irq_disable = pmc_irq_mask, .irq_mask = pmc_irq_mask, .irq_unmask = pmc_irq_unmask, .irq_set_type = pmc_irq_set_type, + .irq_suspend = pmc_irq_suspend, + .irq_resume = pmc_irq_resume, }; static struct lock_class_key pmc_lock_class; @@ -224,7 +241,8 @@ static struct at91_pmc *__init at91_pmc_init(struct device_node *np, goto out_free_pmc; pmc_write(pmc, AT91_PMC_IDR, 0xffffffff); - if (request_irq(pmc->virq, pmc_irq_handler, IRQF_SHARED, "pmc", pmc)) + if (request_irq(pmc->virq, pmc_irq_handler, + IRQF_SHARED | IRQF_COND_SUSPEND, "pmc", pmc)) goto out_remove_irqdomain; return pmc; diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h index 52d2041fa3f6..69abb08cf146 100644 --- a/drivers/clk/at91/pmc.h +++ b/drivers/clk/at91/pmc.h @@ -33,6 +33,7 @@ struct at91_pmc { spinlock_t lock; const struct at91_pmc_caps *caps; struct irq_domain *irqdomain; + u32 imr; }; static inline void pmc_lock(struct at91_pmc *pmc) -- GitLab From f0126539c73921776327e9d6bbf27e7e08ee0e3a Mon Sep 17 00:00:00 2001 From: Wu Fengguang Date: Thu, 5 Mar 2015 05:33:54 +0800 Subject: [PATCH 02689/11651] mpls: rtm_mpls_policy[] can be static Signed-off-by: Fengguang Wu Signed-off-by: David S. Miller --- net/mpls/af_mpls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c index 75a994a50381..23e51d13b0ff 100644 --- a/net/mpls/af_mpls.c +++ b/net/mpls/af_mpls.c @@ -216,7 +216,7 @@ static struct packet_type mpls_packet_type __read_mostly = { .func = mpls_forward, }; -const struct nla_policy rtm_mpls_policy[RTA_MAX+1] = { +static const struct nla_policy rtm_mpls_policy[RTA_MAX+1] = { [RTA_DST] = { .type = NLA_U32 }, [RTA_OIF] = { .type = NLA_U32 }, }; -- GitLab From 2e3ac940f2754d7dc616aba1643a668954fe892f Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Tue, 3 Mar 2015 17:02:21 -0600 Subject: [PATCH 02690/11651] livepatch: remove unnecessary call to klp_find_object_module() klp_find_object_module() is called from both the klp register and enable paths. Only the call from the register path is necessary because the module notifier will let us know if the patched module gets loaded or unloaded. Signed-off-by: Josh Poimboeuf Reviewed-by: Petr Mladek Signed-off-by: Jiri Kosina --- kernel/livepatch/core.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c index 26df09d56f7c..d03d6134e824 100644 --- a/kernel/livepatch/core.c +++ b/kernel/livepatch/core.c @@ -511,8 +511,6 @@ static int __klp_enable_patch(struct klp_patch *patch) pr_notice("enabling patch '%s'\n", patch->mod->name); for (obj = patch->objs; obj->funcs; obj++) { - klp_find_object_module(obj); - if (!klp_is_object_loaded(obj)) continue; -- GitLab From 69e8544cd0056e02965ffb5e8414fb7501a2ee2e Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 26 Feb 2015 14:40:24 -0800 Subject: [PATCH 02691/11651] x86/asm/64: Open-code register save/restore in trace_hardirqs*() thunks This is a preparatory patch for change in "struct pt_regs" handling in entry_64.S. trace_hardirqs*() thunks were (ab)using a part of the 'pt_regs' handling code, namely the SAVE_ARGS/RESTORE_ARGS macros, to save/restore registers across C function calls. Since SAVE_ARGS is going to be changed, open-code register saving/restoring here. Incidentally, this removes a bit of dead code: one SAVE_ARGS was used just to emit a CFI annotation, but it also generated unreachable assembly instructions. Take a page from thunk_32.S and use push/pop instructions instead of movq, they are far shorter: 1 or 2 bytes versus 5, and no need for instructions to adjust %rsp: text data bss dec hex filename 333 40 0 373 175 thunk_64_movq.o 104 40 0 144 90 thunk_64_push_pop.o [ This is ugly as sin, but we'll fix up the ugliness in the next patch. I see no point in reordering patches just to avoid an ugly intermediate state. --Andy ] Signed-off-by: Denys Vlasenko Signed-off-by: Andy Lutomirski Cc: Alexei Starovoitov Cc: Borislav Petkov Cc: Frederic Weisbecker Cc: H. Peter Anvin Cc: Kees Cook Cc: Linus Torvalds Cc: Oleg Nesterov Cc: Will Drewry Link: http://lkml.kernel.org/r/1420927210-19738-4-git-send-email-dvlasenk@redhat.com Link: http://lkml.kernel.org/r/4c979ad604f0f02c5ade3b3da308b53eabd5e198.1424989793.git.luto@amacapital.net Signed-off-by: Ingo Molnar --- arch/x86/lib/thunk_64.S | 46 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 42 insertions(+), 4 deletions(-) diff --git a/arch/x86/lib/thunk_64.S b/arch/x86/lib/thunk_64.S index b30b5ebd614a..8ec443a0777b 100644 --- a/arch/x86/lib/thunk_64.S +++ b/arch/x86/lib/thunk_64.S @@ -17,9 +17,27 @@ CFI_STARTPROC /* this one pushes 9 elems, the next one would be %rIP */ - SAVE_ARGS + pushq_cfi %rdi + CFI_REL_OFFSET rdi, 0 + pushq_cfi %rsi + CFI_REL_OFFSET rsi, 0 + pushq_cfi %rdx + CFI_REL_OFFSET rdx, 0 + pushq_cfi %rcx + CFI_REL_OFFSET rcx, 0 + pushq_cfi %rax + CFI_REL_OFFSET rax, 0 + pushq_cfi %r8 + CFI_REL_OFFSET r8, 0 + pushq_cfi %r9 + CFI_REL_OFFSET r9, 0 + pushq_cfi %r10 + CFI_REL_OFFSET r10, 0 + pushq_cfi %r11 + CFI_REL_OFFSET r11, 0 .if \put_ret_addr_in_rdi + /* 9*8(%rsp) is return addr on stack */ movq_cfi_restore 9*8, rdi .endif @@ -45,11 +63,31 @@ #endif #endif - /* SAVE_ARGS below is used only for the .cfi directives it contains. */ +#if defined(CONFIG_TRACE_IRQFLAGS) \ + || defined(CONFIG_DEBUG_LOCK_ALLOC) \ + || defined(CONFIG_PREEMPT) CFI_STARTPROC - SAVE_ARGS + CFI_ADJUST_CFA_OFFSET 9*8 restore: - RESTORE_ARGS + popq_cfi %r11 + CFI_RESTORE r11 + popq_cfi %r10 + CFI_RESTORE r10 + popq_cfi %r9 + CFI_RESTORE r9 + popq_cfi %r8 + CFI_RESTORE r8 + popq_cfi %rax + CFI_RESTORE rax + popq_cfi %rcx + CFI_RESTORE rcx + popq_cfi %rdx + CFI_RESTORE rdx + popq_cfi %rsi + CFI_RESTORE rsi + popq_cfi %rdi + CFI_RESTORE rdi ret CFI_ENDPROC _ASM_NOKPROBE(restore) +#endif -- GitLab From 49db46a67bec9ca9e29ece4729a876195877af50 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 26 Feb 2015 14:40:25 -0800 Subject: [PATCH 02692/11651] x86/asm: Introduce push/pop macros which generate CFI_REL_OFFSET and CFI_RESTORE Sequences: pushl_cfi %reg CFI_REL_OFFSET reg, 0 and: popl_cfi %reg CFI_RESTORE reg happen quite often. This patch adds macros which generate them. No assembly changes (verified with objdump -dr vmlinux.o). Signed-off-by: Denys Vlasenko Signed-off-by: Andy Lutomirski Cc: Alexei Starovoitov Cc: Borislav Petkov Cc: Frederic Weisbecker Cc: H. Peter Anvin Cc: Kees Cook Cc: Linus Torvalds Cc: Oleg Nesterov Cc: Will Drewry Link: http://lkml.kernel.org/r/1421017655-25561-1-git-send-email-dvlasenk@redhat.com Link: http://lkml.kernel.org/r/2202eb90f175cf45d1b2d1c64dbb5676a8ad07ad.1424989793.git.luto@amacapital.net Signed-off-by: Ingo Molnar --- arch/x86/include/asm/calling.h | 42 ++++++++---------------- arch/x86/include/asm/dwarf2.h | 24 ++++++++++++++ arch/x86/kernel/entry_32.S | 21 ++++-------- arch/x86/lib/atomic64_cx8_32.S | 50 ++++++++++++---------------- arch/x86/lib/checksum_32.S | 60 ++++++++++++---------------------- arch/x86/lib/msr-reg.S | 24 +++++++------- arch/x86/lib/rwsem.S | 44 ++++++++++++------------- arch/x86/lib/thunk_32.S | 18 ++++------ arch/x86/lib/thunk_64.S | 54 ++++++++++-------------------- 9 files changed, 141 insertions(+), 196 deletions(-) diff --git a/arch/x86/include/asm/calling.h b/arch/x86/include/asm/calling.h index 1f1297b46f83..3c711f2ab236 100644 --- a/arch/x86/include/asm/calling.h +++ b/arch/x86/include/asm/calling.h @@ -210,37 +210,23 @@ For 32-bit we have the following conventions - kernel is built with */ .macro SAVE_ALL - pushl_cfi %eax - CFI_REL_OFFSET eax, 0 - pushl_cfi %ebp - CFI_REL_OFFSET ebp, 0 - pushl_cfi %edi - CFI_REL_OFFSET edi, 0 - pushl_cfi %esi - CFI_REL_OFFSET esi, 0 - pushl_cfi %edx - CFI_REL_OFFSET edx, 0 - pushl_cfi %ecx - CFI_REL_OFFSET ecx, 0 - pushl_cfi %ebx - CFI_REL_OFFSET ebx, 0 + pushl_cfi_reg eax + pushl_cfi_reg ebp + pushl_cfi_reg edi + pushl_cfi_reg esi + pushl_cfi_reg edx + pushl_cfi_reg ecx + pushl_cfi_reg ebx .endm .macro RESTORE_ALL - popl_cfi %ebx - CFI_RESTORE ebx - popl_cfi %ecx - CFI_RESTORE ecx - popl_cfi %edx - CFI_RESTORE edx - popl_cfi %esi - CFI_RESTORE esi - popl_cfi %edi - CFI_RESTORE edi - popl_cfi %ebp - CFI_RESTORE ebp - popl_cfi %eax - CFI_RESTORE eax + popl_cfi_reg ebx + popl_cfi_reg ecx + popl_cfi_reg edx + popl_cfi_reg esi + popl_cfi_reg edi + popl_cfi_reg ebp + popl_cfi_reg eax .endm #endif /* CONFIG_X86_64 */ diff --git a/arch/x86/include/asm/dwarf2.h b/arch/x86/include/asm/dwarf2.h index f6f15986df6c..de1cdaf4d743 100644 --- a/arch/x86/include/asm/dwarf2.h +++ b/arch/x86/include/asm/dwarf2.h @@ -86,11 +86,23 @@ CFI_ADJUST_CFA_OFFSET 8 .endm + .macro pushq_cfi_reg reg + pushq %\reg + CFI_ADJUST_CFA_OFFSET 8 + CFI_REL_OFFSET \reg, 0 + .endm + .macro popq_cfi reg popq \reg CFI_ADJUST_CFA_OFFSET -8 .endm + .macro popq_cfi_reg reg + popq %\reg + CFI_ADJUST_CFA_OFFSET -8 + CFI_RESTORE \reg + .endm + .macro pushfq_cfi pushfq CFI_ADJUST_CFA_OFFSET 8 @@ -116,11 +128,23 @@ CFI_ADJUST_CFA_OFFSET 4 .endm + .macro pushl_cfi_reg reg + pushl %\reg + CFI_ADJUST_CFA_OFFSET 4 + CFI_REL_OFFSET \reg, 0 + .endm + .macro popl_cfi reg popl \reg CFI_ADJUST_CFA_OFFSET -4 .endm + .macro popl_cfi_reg reg + popl %\reg + CFI_ADJUST_CFA_OFFSET -4 + CFI_RESTORE \reg + .endm + .macro pushfl_cfi pushfl CFI_ADJUST_CFA_OFFSET 4 diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S index 7e0323cc0b7d..e33ba51b1069 100644 --- a/arch/x86/kernel/entry_32.S +++ b/arch/x86/kernel/entry_32.S @@ -1234,20 +1234,13 @@ error_code: /*CFI_REL_OFFSET es, 0*/ pushl_cfi %ds /*CFI_REL_OFFSET ds, 0*/ - pushl_cfi %eax - CFI_REL_OFFSET eax, 0 - pushl_cfi %ebp - CFI_REL_OFFSET ebp, 0 - pushl_cfi %edi - CFI_REL_OFFSET edi, 0 - pushl_cfi %esi - CFI_REL_OFFSET esi, 0 - pushl_cfi %edx - CFI_REL_OFFSET edx, 0 - pushl_cfi %ecx - CFI_REL_OFFSET ecx, 0 - pushl_cfi %ebx - CFI_REL_OFFSET ebx, 0 + pushl_cfi_reg eax + pushl_cfi_reg ebp + pushl_cfi_reg edi + pushl_cfi_reg esi + pushl_cfi_reg edx + pushl_cfi_reg ecx + pushl_cfi_reg ebx cld movl $(__KERNEL_PERCPU), %ecx movl %ecx, %fs diff --git a/arch/x86/lib/atomic64_cx8_32.S b/arch/x86/lib/atomic64_cx8_32.S index f5cc9eb1d51b..082a85167a5b 100644 --- a/arch/x86/lib/atomic64_cx8_32.S +++ b/arch/x86/lib/atomic64_cx8_32.S @@ -13,16 +13,6 @@ #include #include -.macro SAVE reg - pushl_cfi %\reg - CFI_REL_OFFSET \reg, 0 -.endm - -.macro RESTORE reg - popl_cfi %\reg - CFI_RESTORE \reg -.endm - .macro read64 reg movl %ebx, %eax movl %ecx, %edx @@ -67,10 +57,10 @@ ENDPROC(atomic64_xchg_cx8) .macro addsub_return func ins insc ENTRY(atomic64_\func\()_return_cx8) CFI_STARTPROC - SAVE ebp - SAVE ebx - SAVE esi - SAVE edi + pushl_cfi_reg ebp + pushl_cfi_reg ebx + pushl_cfi_reg esi + pushl_cfi_reg edi movl %eax, %esi movl %edx, %edi @@ -89,10 +79,10 @@ ENTRY(atomic64_\func\()_return_cx8) 10: movl %ebx, %eax movl %ecx, %edx - RESTORE edi - RESTORE esi - RESTORE ebx - RESTORE ebp + popl_cfi_reg edi + popl_cfi_reg esi + popl_cfi_reg ebx + popl_cfi_reg ebp ret CFI_ENDPROC ENDPROC(atomic64_\func\()_return_cx8) @@ -104,7 +94,7 @@ addsub_return sub sub sbb .macro incdec_return func ins insc ENTRY(atomic64_\func\()_return_cx8) CFI_STARTPROC - SAVE ebx + pushl_cfi_reg ebx read64 %esi 1: @@ -119,7 +109,7 @@ ENTRY(atomic64_\func\()_return_cx8) 10: movl %ebx, %eax movl %ecx, %edx - RESTORE ebx + popl_cfi_reg ebx ret CFI_ENDPROC ENDPROC(atomic64_\func\()_return_cx8) @@ -130,7 +120,7 @@ incdec_return dec sub sbb ENTRY(atomic64_dec_if_positive_cx8) CFI_STARTPROC - SAVE ebx + pushl_cfi_reg ebx read64 %esi 1: @@ -146,18 +136,18 @@ ENTRY(atomic64_dec_if_positive_cx8) 2: movl %ebx, %eax movl %ecx, %edx - RESTORE ebx + popl_cfi_reg ebx ret CFI_ENDPROC ENDPROC(atomic64_dec_if_positive_cx8) ENTRY(atomic64_add_unless_cx8) CFI_STARTPROC - SAVE ebp - SAVE ebx + pushl_cfi_reg ebp + pushl_cfi_reg ebx /* these just push these two parameters on the stack */ - SAVE edi - SAVE ecx + pushl_cfi_reg edi + pushl_cfi_reg ecx movl %eax, %ebp movl %edx, %edi @@ -179,8 +169,8 @@ ENTRY(atomic64_add_unless_cx8) 3: addl $8, %esp CFI_ADJUST_CFA_OFFSET -8 - RESTORE ebx - RESTORE ebp + popl_cfi_reg ebx + popl_cfi_reg ebp ret 4: cmpl %edx, 4(%esp) @@ -192,7 +182,7 @@ ENDPROC(atomic64_add_unless_cx8) ENTRY(atomic64_inc_not_zero_cx8) CFI_STARTPROC - SAVE ebx + pushl_cfi_reg ebx read64 %esi 1: @@ -209,7 +199,7 @@ ENTRY(atomic64_inc_not_zero_cx8) movl $1, %eax 3: - RESTORE ebx + popl_cfi_reg ebx ret CFI_ENDPROC ENDPROC(atomic64_inc_not_zero_cx8) diff --git a/arch/x86/lib/checksum_32.S b/arch/x86/lib/checksum_32.S index e78b8eee6615..c3b9953d3fa0 100644 --- a/arch/x86/lib/checksum_32.S +++ b/arch/x86/lib/checksum_32.S @@ -51,10 +51,8 @@ unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum) */ ENTRY(csum_partial) CFI_STARTPROC - pushl_cfi %esi - CFI_REL_OFFSET esi, 0 - pushl_cfi %ebx - CFI_REL_OFFSET ebx, 0 + pushl_cfi_reg esi + pushl_cfi_reg ebx movl 20(%esp),%eax # Function arg: unsigned int sum movl 16(%esp),%ecx # Function arg: int len movl 12(%esp),%esi # Function arg: unsigned char *buff @@ -131,10 +129,8 @@ ENTRY(csum_partial) jz 8f roll $8, %eax 8: - popl_cfi %ebx - CFI_RESTORE ebx - popl_cfi %esi - CFI_RESTORE esi + popl_cfi_reg ebx + popl_cfi_reg esi ret CFI_ENDPROC ENDPROC(csum_partial) @@ -145,10 +141,8 @@ ENDPROC(csum_partial) ENTRY(csum_partial) CFI_STARTPROC - pushl_cfi %esi - CFI_REL_OFFSET esi, 0 - pushl_cfi %ebx - CFI_REL_OFFSET ebx, 0 + pushl_cfi_reg esi + pushl_cfi_reg ebx movl 20(%esp),%eax # Function arg: unsigned int sum movl 16(%esp),%ecx # Function arg: int len movl 12(%esp),%esi # Function arg: const unsigned char *buf @@ -255,10 +249,8 @@ ENTRY(csum_partial) jz 90f roll $8, %eax 90: - popl_cfi %ebx - CFI_RESTORE ebx - popl_cfi %esi - CFI_RESTORE esi + popl_cfi_reg ebx + popl_cfi_reg esi ret CFI_ENDPROC ENDPROC(csum_partial) @@ -298,12 +290,9 @@ ENTRY(csum_partial_copy_generic) CFI_STARTPROC subl $4,%esp CFI_ADJUST_CFA_OFFSET 4 - pushl_cfi %edi - CFI_REL_OFFSET edi, 0 - pushl_cfi %esi - CFI_REL_OFFSET esi, 0 - pushl_cfi %ebx - CFI_REL_OFFSET ebx, 0 + pushl_cfi_reg edi + pushl_cfi_reg esi + pushl_cfi_reg ebx movl ARGBASE+16(%esp),%eax # sum movl ARGBASE+12(%esp),%ecx # len movl ARGBASE+4(%esp),%esi # src @@ -412,12 +401,9 @@ DST( movb %cl, (%edi) ) .previous - popl_cfi %ebx - CFI_RESTORE ebx - popl_cfi %esi - CFI_RESTORE esi - popl_cfi %edi - CFI_RESTORE edi + popl_cfi_reg ebx + popl_cfi_reg esi + popl_cfi_reg edi popl_cfi %ecx # equivalent to addl $4,%esp ret CFI_ENDPROC @@ -441,12 +427,9 @@ ENDPROC(csum_partial_copy_generic) ENTRY(csum_partial_copy_generic) CFI_STARTPROC - pushl_cfi %ebx - CFI_REL_OFFSET ebx, 0 - pushl_cfi %edi - CFI_REL_OFFSET edi, 0 - pushl_cfi %esi - CFI_REL_OFFSET esi, 0 + pushl_cfi_reg ebx + pushl_cfi_reg edi + pushl_cfi_reg esi movl ARGBASE+4(%esp),%esi #src movl ARGBASE+8(%esp),%edi #dst movl ARGBASE+12(%esp),%ecx #len @@ -506,12 +489,9 @@ DST( movb %dl, (%edi) ) jmp 7b .previous - popl_cfi %esi - CFI_RESTORE esi - popl_cfi %edi - CFI_RESTORE edi - popl_cfi %ebx - CFI_RESTORE ebx + popl_cfi_reg esi + popl_cfi_reg edi + popl_cfi_reg ebx ret CFI_ENDPROC ENDPROC(csum_partial_copy_generic) diff --git a/arch/x86/lib/msr-reg.S b/arch/x86/lib/msr-reg.S index f6d13eefad10..3ca5218fbece 100644 --- a/arch/x86/lib/msr-reg.S +++ b/arch/x86/lib/msr-reg.S @@ -14,8 +14,8 @@ .macro op_safe_regs op ENTRY(\op\()_safe_regs) CFI_STARTPROC - pushq_cfi %rbx - pushq_cfi %rbp + pushq_cfi_reg rbx + pushq_cfi_reg rbp movq %rdi, %r10 /* Save pointer */ xorl %r11d, %r11d /* Return value */ movl (%rdi), %eax @@ -35,8 +35,8 @@ ENTRY(\op\()_safe_regs) movl %ebp, 20(%r10) movl %esi, 24(%r10) movl %edi, 28(%r10) - popq_cfi %rbp - popq_cfi %rbx + popq_cfi_reg rbp + popq_cfi_reg rbx ret 3: CFI_RESTORE_STATE @@ -53,10 +53,10 @@ ENDPROC(\op\()_safe_regs) .macro op_safe_regs op ENTRY(\op\()_safe_regs) CFI_STARTPROC - pushl_cfi %ebx - pushl_cfi %ebp - pushl_cfi %esi - pushl_cfi %edi + pushl_cfi_reg ebx + pushl_cfi_reg ebp + pushl_cfi_reg esi + pushl_cfi_reg edi pushl_cfi $0 /* Return value */ pushl_cfi %eax movl 4(%eax), %ecx @@ -80,10 +80,10 @@ ENTRY(\op\()_safe_regs) movl %esi, 24(%eax) movl %edi, 28(%eax) popl_cfi %eax - popl_cfi %edi - popl_cfi %esi - popl_cfi %ebp - popl_cfi %ebx + popl_cfi_reg edi + popl_cfi_reg esi + popl_cfi_reg ebp + popl_cfi_reg ebx ret 3: CFI_RESTORE_STATE diff --git a/arch/x86/lib/rwsem.S b/arch/x86/lib/rwsem.S index 5dff5f042468..2322abe4da3b 100644 --- a/arch/x86/lib/rwsem.S +++ b/arch/x86/lib/rwsem.S @@ -34,10 +34,10 @@ */ #define save_common_regs \ - pushl_cfi %ecx; CFI_REL_OFFSET ecx, 0 + pushl_cfi_reg ecx #define restore_common_regs \ - popl_cfi %ecx; CFI_RESTORE ecx + popl_cfi_reg ecx /* Avoid uglifying the argument copying x86-64 needs to do. */ .macro movq src, dst @@ -64,22 +64,22 @@ */ #define save_common_regs \ - pushq_cfi %rdi; CFI_REL_OFFSET rdi, 0; \ - pushq_cfi %rsi; CFI_REL_OFFSET rsi, 0; \ - pushq_cfi %rcx; CFI_REL_OFFSET rcx, 0; \ - pushq_cfi %r8; CFI_REL_OFFSET r8, 0; \ - pushq_cfi %r9; CFI_REL_OFFSET r9, 0; \ - pushq_cfi %r10; CFI_REL_OFFSET r10, 0; \ - pushq_cfi %r11; CFI_REL_OFFSET r11, 0 + pushq_cfi_reg rdi; \ + pushq_cfi_reg rsi; \ + pushq_cfi_reg rcx; \ + pushq_cfi_reg r8; \ + pushq_cfi_reg r9; \ + pushq_cfi_reg r10; \ + pushq_cfi_reg r11 #define restore_common_regs \ - popq_cfi %r11; CFI_RESTORE r11; \ - popq_cfi %r10; CFI_RESTORE r10; \ - popq_cfi %r9; CFI_RESTORE r9; \ - popq_cfi %r8; CFI_RESTORE r8; \ - popq_cfi %rcx; CFI_RESTORE rcx; \ - popq_cfi %rsi; CFI_RESTORE rsi; \ - popq_cfi %rdi; CFI_RESTORE rdi + popq_cfi_reg r11; \ + popq_cfi_reg r10; \ + popq_cfi_reg r9; \ + popq_cfi_reg r8; \ + popq_cfi_reg rcx; \ + popq_cfi_reg rsi; \ + popq_cfi_reg rdi #endif @@ -87,12 +87,10 @@ ENTRY(call_rwsem_down_read_failed) CFI_STARTPROC save_common_regs - __ASM_SIZE(push,_cfi) %__ASM_REG(dx) - CFI_REL_OFFSET __ASM_REG(dx), 0 + __ASM_SIZE(push,_cfi_reg) __ASM_REG(dx) movq %rax,%rdi call rwsem_down_read_failed - __ASM_SIZE(pop,_cfi) %__ASM_REG(dx) - CFI_RESTORE __ASM_REG(dx) + __ASM_SIZE(pop,_cfi_reg) __ASM_REG(dx) restore_common_regs ret CFI_ENDPROC @@ -124,12 +122,10 @@ ENDPROC(call_rwsem_wake) ENTRY(call_rwsem_downgrade_wake) CFI_STARTPROC save_common_regs - __ASM_SIZE(push,_cfi) %__ASM_REG(dx) - CFI_REL_OFFSET __ASM_REG(dx), 0 + __ASM_SIZE(push,_cfi_reg) __ASM_REG(dx) movq %rax,%rdi call rwsem_downgrade_wake - __ASM_SIZE(pop,_cfi) %__ASM_REG(dx) - CFI_RESTORE __ASM_REG(dx) + __ASM_SIZE(pop,_cfi_reg) __ASM_REG(dx) restore_common_regs ret CFI_ENDPROC diff --git a/arch/x86/lib/thunk_32.S b/arch/x86/lib/thunk_32.S index e28cdaf5ac2c..5eb715087b80 100644 --- a/arch/x86/lib/thunk_32.S +++ b/arch/x86/lib/thunk_32.S @@ -13,12 +13,9 @@ .globl \name \name: CFI_STARTPROC - pushl_cfi %eax - CFI_REL_OFFSET eax, 0 - pushl_cfi %ecx - CFI_REL_OFFSET ecx, 0 - pushl_cfi %edx - CFI_REL_OFFSET edx, 0 + pushl_cfi_reg eax + pushl_cfi_reg ecx + pushl_cfi_reg edx .if \put_ret_addr_in_eax /* Place EIP in the arg1 */ @@ -26,12 +23,9 @@ .endif call \func - popl_cfi %edx - CFI_RESTORE edx - popl_cfi %ecx - CFI_RESTORE ecx - popl_cfi %eax - CFI_RESTORE eax + popl_cfi_reg edx + popl_cfi_reg ecx + popl_cfi_reg eax ret CFI_ENDPROC _ASM_NOKPROBE(\name) diff --git a/arch/x86/lib/thunk_64.S b/arch/x86/lib/thunk_64.S index 8ec443a0777b..f89ba4e93025 100644 --- a/arch/x86/lib/thunk_64.S +++ b/arch/x86/lib/thunk_64.S @@ -17,24 +17,15 @@ CFI_STARTPROC /* this one pushes 9 elems, the next one would be %rIP */ - pushq_cfi %rdi - CFI_REL_OFFSET rdi, 0 - pushq_cfi %rsi - CFI_REL_OFFSET rsi, 0 - pushq_cfi %rdx - CFI_REL_OFFSET rdx, 0 - pushq_cfi %rcx - CFI_REL_OFFSET rcx, 0 - pushq_cfi %rax - CFI_REL_OFFSET rax, 0 - pushq_cfi %r8 - CFI_REL_OFFSET r8, 0 - pushq_cfi %r9 - CFI_REL_OFFSET r9, 0 - pushq_cfi %r10 - CFI_REL_OFFSET r10, 0 - pushq_cfi %r11 - CFI_REL_OFFSET r11, 0 + pushq_cfi_reg rdi + pushq_cfi_reg rsi + pushq_cfi_reg rdx + pushq_cfi_reg rcx + pushq_cfi_reg rax + pushq_cfi_reg r8 + pushq_cfi_reg r9 + pushq_cfi_reg r10 + pushq_cfi_reg r11 .if \put_ret_addr_in_rdi /* 9*8(%rsp) is return addr on stack */ @@ -69,24 +60,15 @@ CFI_STARTPROC CFI_ADJUST_CFA_OFFSET 9*8 restore: - popq_cfi %r11 - CFI_RESTORE r11 - popq_cfi %r10 - CFI_RESTORE r10 - popq_cfi %r9 - CFI_RESTORE r9 - popq_cfi %r8 - CFI_RESTORE r8 - popq_cfi %rax - CFI_RESTORE rax - popq_cfi %rcx - CFI_RESTORE rcx - popq_cfi %rdx - CFI_RESTORE rdx - popq_cfi %rsi - CFI_RESTORE rsi - popq_cfi %rdi - CFI_RESTORE rdi + popq_cfi_reg r11 + popq_cfi_reg r10 + popq_cfi_reg r9 + popq_cfi_reg r8 + popq_cfi_reg rax + popq_cfi_reg rcx + popq_cfi_reg rdx + popq_cfi_reg rsi + popq_cfi_reg rdi ret CFI_ENDPROC _ASM_NOKPROBE(restore) -- GitLab From 6e1327bd2b20ccb387fcddc0caa605cb253cc458 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 26 Feb 2015 14:40:26 -0800 Subject: [PATCH 02693/11651] x86/asm/entry/64: Fix incorrect symbolic constant usage: R11->ARGOFFSET Since the last fix of this nature, a few more instances have crept in. Fix them up. No object code changes (constants have the same value). Signed-off-by: Denys Vlasenko Signed-off-by: Andy Lutomirski Cc: Alexei Starovoitov Cc: Borislav Petkov Cc: Frederic Weisbecker Cc: H. Peter Anvin Cc: Kees Cook Cc: Linus Torvalds Cc: Oleg Nesterov Cc: Will Drewry Link: http://lkml.kernel.org/r/1423778052-21038-1-git-send-email-dvlasenk@redhat.com Link: http://lkml.kernel.org/r/f5e1c4084319a42e5f14d41e2d638949ce66bc08.1424989793.git.luto@amacapital.net Signed-off-by: Ingo Molnar --- arch/x86/kernel/entry_64.S | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index 10074ad9ebf8..a57b3387ec7d 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -757,8 +757,8 @@ retint_swapgs: /* return to user-space */ * Try to use SYSRET instead of IRET if we're returning to * a completely clean 64-bit userspace context. */ - movq (RCX-R11)(%rsp), %rcx - cmpq %rcx,(RIP-R11)(%rsp) /* RCX == RIP */ + movq (RCX-ARGOFFSET)(%rsp), %rcx + cmpq %rcx,(RIP-ARGOFFSET)(%rsp) /* RCX == RIP */ jne opportunistic_sysret_failed /* @@ -779,7 +779,7 @@ retint_swapgs: /* return to user-space */ shr $__VIRTUAL_MASK_SHIFT, %rcx jnz opportunistic_sysret_failed - cmpq $__USER_CS,(CS-R11)(%rsp) /* CS must match SYSRET */ + cmpq $__USER_CS,(CS-ARGOFFSET)(%rsp) /* CS must match SYSRET */ jne opportunistic_sysret_failed movq (R11-ARGOFFSET)(%rsp), %r11 -- GitLab From 76f5df43cab5e765c0bd42289103e8f625813ae1 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 26 Feb 2015 14:40:27 -0800 Subject: [PATCH 02694/11651] x86/asm/entry/64: Always allocate a complete "struct pt_regs" on the kernel stack The 64-bit entry code was using six stack slots less by not saving/restoring registers which are callee-preserved according to the C ABI, and was not allocating space for them. Only when syscalls needed a complete "struct pt_regs" was the complete area allocated and filled in. As an additional twist, on interrupt entry a "slightly less truncated pt_regs" trick is used, to make nested interrupt stacks easier to unwind. This proved to be a source of significant obfuscation and subtle bugs. For example, 'stub_fork' had to pop the return address, extend the struct, save registers, and push return address back. Ugly. 'ia32_ptregs_common' pops return address and "returns" via jmp insn, throwing a wrench into CPU return stack cache. This patch changes the code to always allocate a complete "struct pt_regs" on the kernel stack. The saving of registers is still done lazily. "Partial pt_regs" trick on interrupt stack is retained. Macros which manipulate "struct pt_regs" on stack are reworked: - ALLOC_PT_GPREGS_ON_STACK allocates the structure. - SAVE_C_REGS saves to it those registers which are clobbered by C code. - SAVE_EXTRA_REGS saves to it all other registers. - Corresponding RESTORE_* and REMOVE_PT_GPREGS_FROM_STACK macros reverse it. 'ia32_ptregs_common', 'stub_fork' and friends lost their ugly dance with the return pointer. LOAD_ARGS32 in ia32entry.S now uses symbolic stack offsets instead of magic numbers. 'error_entry' and 'save_paranoid' now use SAVE_C_REGS + SAVE_EXTRA_REGS instead of having it open-coded yet again. Patch was run-tested: 64-bit executables, 32-bit executables, strace works. Timing tests did not show measurable difference in 32-bit and 64-bit syscalls. Signed-off-by: Denys Vlasenko Signed-off-by: Andy Lutomirski Cc: Alexei Starovoitov Cc: Borislav Petkov Cc: Frederic Weisbecker Cc: H. Peter Anvin Cc: Kees Cook Cc: Linus Torvalds Cc: Oleg Nesterov Cc: Will Drewry Link: http://lkml.kernel.org/r/1423778052-21038-2-git-send-email-dvlasenk@redhat.com Link: http://lkml.kernel.org/r/b89763d354aa23e670b9bdf3a40ae320320a7c2e.1424989793.git.luto@amacapital.net Signed-off-by: Ingo Molnar --- arch/x86/ia32/ia32entry.S | 47 +++--- arch/x86/include/asm/calling.h | 222 ++++++++++++------------- arch/x86/include/asm/irqflags.h | 4 +- arch/x86/include/uapi/asm/ptrace-abi.h | 1 - arch/x86/kernel/entry_64.S | 196 +++++++++------------- 5 files changed, 210 insertions(+), 260 deletions(-) diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S index 156ebcab4ada..f4bed4971673 100644 --- a/arch/x86/ia32/ia32entry.S +++ b/arch/x86/ia32/ia32entry.S @@ -62,12 +62,12 @@ */ .macro LOAD_ARGS32 offset, _r9=0 .if \_r9 - movl \offset+16(%rsp),%r9d + movl \offset+R9(%rsp),%r9d .endif - movl \offset+40(%rsp),%ecx - movl \offset+48(%rsp),%edx - movl \offset+56(%rsp),%esi - movl \offset+64(%rsp),%edi + movl \offset+RCX(%rsp),%ecx + movl \offset+RDX(%rsp),%edx + movl \offset+RSI(%rsp),%esi + movl \offset+RDI(%rsp),%edi movl %eax,%eax /* zero extension */ .endm @@ -144,7 +144,8 @@ ENTRY(ia32_sysenter_target) CFI_REL_OFFSET rip,0 pushq_cfi %rax cld - SAVE_ARGS 0,1,0 + ALLOC_PT_GPREGS_ON_STACK + SAVE_C_REGS_EXCEPT_R891011 /* no need to do an access_ok check here because rbp has been 32bit zero extended */ ASM_STAC @@ -182,7 +183,8 @@ sysexit_from_sys_call: andl $~0x200,EFLAGS-ARGOFFSET(%rsp) movl RIP-ARGOFFSET(%rsp),%edx /* User %eip */ CFI_REGISTER rip,rdx - RESTORE_ARGS 0,24,0,0,0,0 + RESTORE_RSI_RDI + REMOVE_PT_GPREGS_FROM_STACK 3*8 xorq %r8,%r8 xorq %r9,%r9 xorq %r10,%r10 @@ -256,13 +258,13 @@ sysenter_tracesys: testl $(_TIF_WORK_SYSCALL_ENTRY & ~_TIF_SYSCALL_AUDIT),TI_flags+THREAD_INFO(%rsp,RIP-ARGOFFSET) jz sysenter_auditsys #endif - SAVE_REST + SAVE_EXTRA_REGS CLEAR_RREGS movq $-ENOSYS,RAX(%rsp)/* ptrace can change this for a bad syscall */ movq %rsp,%rdi /* &pt_regs -> arg1 */ call syscall_trace_enter LOAD_ARGS32 ARGOFFSET /* reload args from stack in case ptrace changed it */ - RESTORE_REST + RESTORE_EXTRA_REGS cmpq $(IA32_NR_syscalls-1),%rax ja int_ret_from_sys_call /* sysenter_tracesys has set RAX(%rsp) */ jmp sysenter_do_call @@ -304,7 +306,8 @@ ENTRY(ia32_cstar_target) * disabled irqs and here we enable it straight after entry: */ ENABLE_INTERRUPTS(CLBR_NONE) - SAVE_ARGS 8,0,0 + ALLOC_PT_GPREGS_ON_STACK 8 + SAVE_C_REGS_EXCEPT_RCX_R891011 movl %eax,%eax /* zero extension */ movq %rax,ORIG_RAX-ARGOFFSET(%rsp) movq %rcx,RIP-ARGOFFSET(%rsp) @@ -341,7 +344,7 @@ cstar_dispatch: jnz sysretl_audit sysretl_from_sys_call: andl $~TS_COMPAT,TI_status+THREAD_INFO(%rsp,RIP-ARGOFFSET) - RESTORE_ARGS 0,-ARG_SKIP,0,0,0 + RESTORE_RSI_RDI_RDX movl RIP-ARGOFFSET(%rsp),%ecx CFI_REGISTER rip,rcx movl EFLAGS-ARGOFFSET(%rsp),%r11d @@ -372,13 +375,13 @@ cstar_tracesys: jz cstar_auditsys #endif xchgl %r9d,%ebp - SAVE_REST + SAVE_EXTRA_REGS CLEAR_RREGS 0, r9 movq $-ENOSYS,RAX(%rsp) /* ptrace can change this for a bad syscall */ movq %rsp,%rdi /* &pt_regs -> arg1 */ call syscall_trace_enter LOAD_ARGS32 ARGOFFSET, 1 /* reload args from stack in case ptrace changed it */ - RESTORE_REST + RESTORE_EXTRA_REGS xchgl %ebp,%r9d cmpq $(IA32_NR_syscalls-1),%rax ja int_ret_from_sys_call /* cstar_tracesys has set RAX(%rsp) */ @@ -433,7 +436,8 @@ ENTRY(ia32_syscall) cld /* note the registers are not zero extended to the sf. this could be a problem. */ - SAVE_ARGS 0,1,0 + ALLOC_PT_GPREGS_ON_STACK + SAVE_C_REGS_EXCEPT_R891011 orl $TS_COMPAT,TI_status+THREAD_INFO(%rsp,RIP-ARGOFFSET) testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags+THREAD_INFO(%rsp,RIP-ARGOFFSET) jnz ia32_tracesys @@ -446,16 +450,16 @@ ia32_sysret: movq %rax,RAX-ARGOFFSET(%rsp) ia32_ret_from_sys_call: CLEAR_RREGS -ARGOFFSET - jmp int_ret_from_sys_call + jmp int_ret_from_sys_call -ia32_tracesys: - SAVE_REST +ia32_tracesys: + SAVE_EXTRA_REGS CLEAR_RREGS movq $-ENOSYS,RAX(%rsp) /* ptrace can change this for a bad syscall */ movq %rsp,%rdi /* &pt_regs -> arg1 */ call syscall_trace_enter LOAD_ARGS32 ARGOFFSET /* reload args from stack in case ptrace changed it */ - RESTORE_REST + RESTORE_EXTRA_REGS cmpq $(IA32_NR_syscalls-1),%rax ja int_ret_from_sys_call /* ia32_tracesys has set RAX(%rsp) */ jmp ia32_do_call @@ -492,7 +496,6 @@ GLOBAL(stub32_clone) ALIGN ia32_ptregs_common: - popq %r11 CFI_ENDPROC CFI_STARTPROC32 simple CFI_SIGNAL_FRAME @@ -507,9 +510,9 @@ ia32_ptregs_common: /* CFI_REL_OFFSET rflags,EFLAGS-ARGOFFSET*/ CFI_REL_OFFSET rsp,RSP-ARGOFFSET /* CFI_REL_OFFSET ss,SS-ARGOFFSET*/ - SAVE_REST + SAVE_EXTRA_REGS 8 call *%rax - RESTORE_REST - jmp ia32_sysret /* misbalances the return cache */ + RESTORE_EXTRA_REGS 8 + ret CFI_ENDPROC END(ia32_ptregs_common) diff --git a/arch/x86/include/asm/calling.h b/arch/x86/include/asm/calling.h index 3c711f2ab236..38356476b131 100644 --- a/arch/x86/include/asm/calling.h +++ b/arch/x86/include/asm/calling.h @@ -55,143 +55,137 @@ For 32-bit we have the following conventions - kernel is built with * for assembly code: */ -#define R15 0 -#define R14 8 -#define R13 16 -#define R12 24 -#define RBP 32 -#define RBX 40 - -/* arguments: interrupts/non tracing syscalls only save up to here: */ -#define R11 48 -#define R10 56 -#define R9 64 -#define R8 72 -#define RAX 80 -#define RCX 88 -#define RDX 96 -#define RSI 104 -#define RDI 112 -#define ORIG_RAX 120 /* + error_code */ -/* end of arguments */ - -/* cpu exception frame or undefined in case of fast syscall: */ -#define RIP 128 -#define CS 136 -#define EFLAGS 144 -#define RSP 152 -#define SS 160 - -#define ARGOFFSET R11 - - .macro SAVE_ARGS addskip=0, save_rcx=1, save_r891011=1, rax_enosys=0 - subq $9*8+\addskip, %rsp - CFI_ADJUST_CFA_OFFSET 9*8+\addskip - movq_cfi rdi, 8*8 - movq_cfi rsi, 7*8 - movq_cfi rdx, 6*8 - - .if \save_rcx - movq_cfi rcx, 5*8 - .endif +/* The layout forms the "struct pt_regs" on the stack: */ +/* + * C ABI says these regs are callee-preserved. They aren't saved on kernel entry + * unless syscall needs a complete, fully filled "struct pt_regs". + */ +#define R15 0*8 +#define R14 1*8 +#define R13 2*8 +#define R12 3*8 +#define RBP 4*8 +#define RBX 5*8 +/* These regs are callee-clobbered. Always saved on kernel entry. */ +#define R11 6*8 +#define R10 7*8 +#define R9 8*8 +#define R8 9*8 +#define RAX 10*8 +#define RCX 11*8 +#define RDX 12*8 +#define RSI 13*8 +#define RDI 14*8 +/* + * On syscall entry, this is syscall#. On CPU exception, this is error code. + * On hw interrupt, it's IRQ number: + */ +#define ORIG_RAX 15*8 +/* Return frame for iretq */ +#define RIP 16*8 +#define CS 17*8 +#define EFLAGS 18*8 +#define RSP 19*8 +#define SS 20*8 + +#define ARGOFFSET 0 + + .macro ALLOC_PT_GPREGS_ON_STACK addskip=0 + subq $15*8+\addskip, %rsp + CFI_ADJUST_CFA_OFFSET 15*8+\addskip + .endm - .if \rax_enosys - movq $-ENOSYS, 4*8(%rsp) - .else - movq_cfi rax, 4*8 + .macro SAVE_C_REGS_HELPER offset=0 rax=1 rcx=1 r8plus=1 + .if \r8plus + movq_cfi r11, 6*8+\offset + movq_cfi r10, 7*8+\offset + movq_cfi r9, 8*8+\offset + movq_cfi r8, 9*8+\offset .endif - - .if \save_r891011 - movq_cfi r8, 3*8 - movq_cfi r9, 2*8 - movq_cfi r10, 1*8 - movq_cfi r11, 0*8 + .if \rax + movq_cfi rax, 10*8+\offset + .endif + .if \rcx + movq_cfi rcx, 11*8+\offset .endif + movq_cfi rdx, 12*8+\offset + movq_cfi rsi, 13*8+\offset + movq_cfi rdi, 14*8+\offset + .endm + .macro SAVE_C_REGS offset=0 + SAVE_C_REGS_HELPER \offset, 1, 1, 1 + .endm + .macro SAVE_C_REGS_EXCEPT_RAX_RCX offset=0 + SAVE_C_REGS_HELPER \offset, 0, 0, 1 + .endm + .macro SAVE_C_REGS_EXCEPT_R891011 + SAVE_C_REGS_HELPER 0, 1, 1, 0 + .endm + .macro SAVE_C_REGS_EXCEPT_RCX_R891011 + SAVE_C_REGS_HELPER 0, 1, 0, 0 + .endm + .macro SAVE_EXTRA_REGS offset=0 + movq_cfi r15, 0*8+\offset + movq_cfi r14, 1*8+\offset + movq_cfi r13, 2*8+\offset + movq_cfi r12, 3*8+\offset + movq_cfi rbp, 4*8+\offset + movq_cfi rbx, 5*8+\offset + .endm + .macro SAVE_EXTRA_REGS_RBP offset=0 + movq_cfi rbp, 4*8+\offset .endm -#define ARG_SKIP (9*8) + .macro RESTORE_EXTRA_REGS offset=0 + movq_cfi_restore 0*8+\offset, r15 + movq_cfi_restore 1*8+\offset, r14 + movq_cfi_restore 2*8+\offset, r13 + movq_cfi_restore 3*8+\offset, r12 + movq_cfi_restore 4*8+\offset, rbp + movq_cfi_restore 5*8+\offset, rbx + .endm - .macro RESTORE_ARGS rstor_rax=1, addskip=0, rstor_rcx=1, rstor_r11=1, \ - rstor_r8910=1, rstor_rdx=1 + .macro RESTORE_C_REGS_HELPER rstor_rax=1, rstor_rcx=1, rstor_r11=1, rstor_r8910=1, rstor_rdx=1 .if \rstor_r11 - movq_cfi_restore 0*8, r11 + movq_cfi_restore 6*8, r11 .endif - .if \rstor_r8910 - movq_cfi_restore 1*8, r10 - movq_cfi_restore 2*8, r9 - movq_cfi_restore 3*8, r8 + movq_cfi_restore 7*8, r10 + movq_cfi_restore 8*8, r9 + movq_cfi_restore 9*8, r8 .endif - .if \rstor_rax - movq_cfi_restore 4*8, rax + movq_cfi_restore 10*8, rax .endif - .if \rstor_rcx - movq_cfi_restore 5*8, rcx + movq_cfi_restore 11*8, rcx .endif - .if \rstor_rdx - movq_cfi_restore 6*8, rdx - .endif - - movq_cfi_restore 7*8, rsi - movq_cfi_restore 8*8, rdi - - .if ARG_SKIP+\addskip > 0 - addq $ARG_SKIP+\addskip, %rsp - CFI_ADJUST_CFA_OFFSET -(ARG_SKIP+\addskip) + movq_cfi_restore 12*8, rdx .endif + movq_cfi_restore 13*8, rsi + movq_cfi_restore 14*8, rdi .endm - - .macro LOAD_ARGS offset, skiprax=0 - movq \offset(%rsp), %r11 - movq \offset+8(%rsp), %r10 - movq \offset+16(%rsp), %r9 - movq \offset+24(%rsp), %r8 - movq \offset+40(%rsp), %rcx - movq \offset+48(%rsp), %rdx - movq \offset+56(%rsp), %rsi - movq \offset+64(%rsp), %rdi - .if \skiprax - .else - movq \offset+72(%rsp), %rax - .endif + .macro RESTORE_C_REGS + RESTORE_C_REGS_HELPER 1,1,1,1,1 .endm - -#define REST_SKIP (6*8) - - .macro SAVE_REST - subq $REST_SKIP, %rsp - CFI_ADJUST_CFA_OFFSET REST_SKIP - movq_cfi rbx, 5*8 - movq_cfi rbp, 4*8 - movq_cfi r12, 3*8 - movq_cfi r13, 2*8 - movq_cfi r14, 1*8 - movq_cfi r15, 0*8 + .macro RESTORE_C_REGS_EXCEPT_RAX + RESTORE_C_REGS_HELPER 0,1,1,1,1 .endm - - .macro RESTORE_REST - movq_cfi_restore 0*8, r15 - movq_cfi_restore 1*8, r14 - movq_cfi_restore 2*8, r13 - movq_cfi_restore 3*8, r12 - movq_cfi_restore 4*8, rbp - movq_cfi_restore 5*8, rbx - addq $REST_SKIP, %rsp - CFI_ADJUST_CFA_OFFSET -(REST_SKIP) + .macro RESTORE_C_REGS_EXCEPT_RCX + RESTORE_C_REGS_HELPER 1,0,1,1,1 .endm - - .macro SAVE_ALL - SAVE_ARGS - SAVE_REST + .macro RESTORE_RSI_RDI + RESTORE_C_REGS_HELPER 0,0,0,0,0 + .endm + .macro RESTORE_RSI_RDI_RDX + RESTORE_C_REGS_HELPER 0,0,0,0,1 .endm - .macro RESTORE_ALL addskip=0 - RESTORE_REST - RESTORE_ARGS 1, \addskip + .macro REMOVE_PT_GPREGS_FROM_STACK addskip=0 + addq $15*8+\addskip, %rsp + CFI_ADJUST_CFA_OFFSET -(15*8+\addskip) .endm .macro icebp diff --git a/arch/x86/include/asm/irqflags.h b/arch/x86/include/asm/irqflags.h index 0a8b519226b8..021bee9b86b6 100644 --- a/arch/x86/include/asm/irqflags.h +++ b/arch/x86/include/asm/irqflags.h @@ -171,9 +171,9 @@ static inline int arch_irqs_disabled(void) #define ARCH_LOCKDEP_SYS_EXIT_IRQ \ TRACE_IRQS_ON; \ sti; \ - SAVE_REST; \ + SAVE_EXTRA_REGS; \ LOCKDEP_SYS_EXIT; \ - RESTORE_REST; \ + RESTORE_EXTRA_REGS; \ cli; \ TRACE_IRQS_OFF; diff --git a/arch/x86/include/uapi/asm/ptrace-abi.h b/arch/x86/include/uapi/asm/ptrace-abi.h index 7b0a55a88851..ad115bf779f3 100644 --- a/arch/x86/include/uapi/asm/ptrace-abi.h +++ b/arch/x86/include/uapi/asm/ptrace-abi.h @@ -49,7 +49,6 @@ #define EFLAGS 144 #define RSP 152 #define SS 160 -#define ARGOFFSET R11 #endif /* __ASSEMBLY__ */ /* top of stack page */ diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index a57b3387ec7d..e8372e08f8c2 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -26,12 +26,6 @@ * Some macro usage: * - CFI macros are used to generate dwarf2 unwind information for better * backtraces. They don't change any code. - * - SAVE_ALL/RESTORE_ALL - Save/restore all registers - * - SAVE_ARGS/RESTORE_ARGS - Save/restore registers that C functions modify. - * There are unfortunately lots of special cases where some registers - * not touched. The macro is a big mess that should be cleaned up. - * - SAVE_REST/RESTORE_REST - Handle the registers not saved by SAVE_ARGS. - * Gives a full stack frame. * - ENTRY/END Define functions in the symbol table. * - FIXUP_TOP_OF_STACK/RESTORE_TOP_OF_STACK - Fix up the hardware stack * frame that is otherwise undefined after a SYSCALL @@ -190,9 +184,9 @@ ENDPROC(native_usergs_sysret64) .endm /* - * frame that enables calling into C. + * frame that enables passing a complete pt_regs to a C function. */ - .macro PARTIAL_FRAME start=1 offset=0 + .macro DEFAULT_FRAME start=1 offset=0 XCPT_FRAME \start, ORIG_RAX+\offset-ARGOFFSET CFI_REL_OFFSET rdi, RDI+\offset-ARGOFFSET CFI_REL_OFFSET rsi, RSI+\offset-ARGOFFSET @@ -203,13 +197,6 @@ ENDPROC(native_usergs_sysret64) CFI_REL_OFFSET r9, R9+\offset-ARGOFFSET CFI_REL_OFFSET r10, R10+\offset-ARGOFFSET CFI_REL_OFFSET r11, R11+\offset-ARGOFFSET - .endm - -/* - * frame that enables passing a complete pt_regs to a C function. - */ - .macro DEFAULT_FRAME start=1 offset=0 - PARTIAL_FRAME \start, R11+\offset-R15 CFI_REL_OFFSET rbx, RBX+\offset CFI_REL_OFFSET rbp, RBP+\offset CFI_REL_OFFSET r12, R12+\offset @@ -221,21 +208,8 @@ ENDPROC(native_usergs_sysret64) ENTRY(save_paranoid) XCPT_FRAME 1 RDI+8 cld - movq %rdi, RDI+8(%rsp) - movq %rsi, RSI+8(%rsp) - movq_cfi rdx, RDX+8 - movq_cfi rcx, RCX+8 - movq_cfi rax, RAX+8 - movq %r8, R8+8(%rsp) - movq %r9, R9+8(%rsp) - movq %r10, R10+8(%rsp) - movq %r11, R11+8(%rsp) - movq_cfi rbx, RBX+8 - movq %rbp, RBP+8(%rsp) - movq %r12, R12+8(%rsp) - movq %r13, R13+8(%rsp) - movq %r14, R14+8(%rsp) - movq %r15, R15+8(%rsp) + SAVE_C_REGS 8 + SAVE_EXTRA_REGS 8 movl $1,%ebx movl $MSR_GS_BASE,%ecx rdmsr @@ -264,7 +238,7 @@ ENTRY(ret_from_fork) GET_THREAD_INFO(%rcx) - RESTORE_REST + RESTORE_EXTRA_REGS testl $3, CS-ARGOFFSET(%rsp) # from kernel_thread? jz 1f @@ -276,12 +250,10 @@ ENTRY(ret_from_fork) jmp ret_from_sys_call # go to the SYSRET fastpath 1: - subq $REST_SKIP, %rsp # leave space for volatiles - CFI_ADJUST_CFA_OFFSET REST_SKIP movq %rbp, %rdi call *%rbx movl $0, RAX(%rsp) - RESTORE_REST + RESTORE_EXTRA_REGS jmp int_ret_from_sys_call CFI_ENDPROC END(ret_from_fork) @@ -339,9 +311,11 @@ GLOBAL(system_call_after_swapgs) * and short: */ ENABLE_INTERRUPTS(CLBR_NONE) - SAVE_ARGS 8, 0, rax_enosys=1 + ALLOC_PT_GPREGS_ON_STACK 8 + SAVE_C_REGS_EXCEPT_RAX_RCX + movq $-ENOSYS,RAX-ARGOFFSET(%rsp) movq_cfi rax,(ORIG_RAX-ARGOFFSET) - movq %rcx,RIP-ARGOFFSET(%rsp) + movq %rcx,RIP-ARGOFFSET(%rsp) CFI_REL_OFFSET rip,RIP-ARGOFFSET testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags+THREAD_INFO(%rsp,RIP-ARGOFFSET) jnz tracesys @@ -372,9 +346,9 @@ ret_from_sys_call: * sysretq will re-enable interrupts: */ TRACE_IRQS_ON + RESTORE_C_REGS_EXCEPT_RCX movq RIP-ARGOFFSET(%rsp),%rcx CFI_REGISTER rip,rcx - RESTORE_ARGS 1,-ARG_SKIP,0 /*CFI_REGISTER rflags,r11*/ movq PER_CPU_VAR(old_rsp), %rsp USERGS_SYSRET64 @@ -387,16 +361,17 @@ int_ret_from_sys_call_fixup: /* Do syscall tracing */ tracesys: - leaq -REST_SKIP(%rsp), %rdi + movq %rsp, %rdi movq $AUDIT_ARCH_X86_64, %rsi call syscall_trace_enter_phase1 test %rax, %rax jnz tracesys_phase2 /* if needed, run the slow path */ - LOAD_ARGS 0 /* else restore clobbered regs */ + RESTORE_C_REGS_EXCEPT_RAX /* else restore clobbered regs */ + movq ORIG_RAX-ARGOFFSET(%rsp), %rax jmp system_call_fastpath /* and return to the fast path */ tracesys_phase2: - SAVE_REST + SAVE_EXTRA_REGS FIXUP_TOP_OF_STACK %rdi movq %rsp, %rdi movq $AUDIT_ARCH_X86_64, %rsi @@ -408,8 +383,8 @@ tracesys_phase2: * We don't reload %rax because syscall_trace_entry_phase2() returned * the value it wants us to use in the table lookup. */ - LOAD_ARGS ARGOFFSET, 1 - RESTORE_REST + RESTORE_C_REGS_EXCEPT_RAX + RESTORE_EXTRA_REGS #if __SYSCALL_MASK == ~0 cmpq $__NR_syscall_max,%rax #else @@ -460,7 +435,7 @@ int_very_careful: TRACE_IRQS_ON ENABLE_INTERRUPTS(CLBR_NONE) int_check_syscall_exit_work: - SAVE_REST + SAVE_EXTRA_REGS /* Check for syscall exit trace */ testl $_TIF_WORK_SYSCALL_EXIT,%edx jz int_signal @@ -479,7 +454,7 @@ int_signal: call do_notify_resume 1: movl $_TIF_WORK_MASK,%edi int_restore_rest: - RESTORE_REST + RESTORE_EXTRA_REGS DISABLE_INTERRUPTS(CLBR_NONE) TRACE_IRQS_OFF jmp int_with_check @@ -489,15 +464,12 @@ END(system_call) .macro FORK_LIKE func ENTRY(stub_\func) CFI_STARTPROC - popq %r11 /* save return address */ - PARTIAL_FRAME 0 - SAVE_REST - pushq %r11 /* put it back on stack */ + DEFAULT_FRAME 0, 8 /* offset 8: return address */ + SAVE_EXTRA_REGS 8 FIXUP_TOP_OF_STACK %r11, 8 - DEFAULT_FRAME 0 8 /* offset 8: return address */ call sys_\func RESTORE_TOP_OF_STACK %r11, 8 - ret $REST_SKIP /* pop extended registers */ + ret CFI_ENDPROC END(stub_\func) .endm @@ -505,7 +477,7 @@ END(stub_\func) .macro FIXED_FRAME label,func ENTRY(\label) CFI_STARTPROC - PARTIAL_FRAME 0 8 /* offset 8: return address */ + DEFAULT_FRAME 0, 8 /* offset 8: return address */ FIXUP_TOP_OF_STACK %r11, 8-ARGOFFSET call \func RESTORE_TOP_OF_STACK %r11, 8-ARGOFFSET @@ -522,12 +494,12 @@ END(\label) ENTRY(stub_execve) CFI_STARTPROC addq $8, %rsp - PARTIAL_FRAME 0 - SAVE_REST + DEFAULT_FRAME 0 + SAVE_EXTRA_REGS FIXUP_TOP_OF_STACK %r11 call sys_execve movq %rax,RAX(%rsp) - RESTORE_REST + RESTORE_EXTRA_REGS jmp int_ret_from_sys_call CFI_ENDPROC END(stub_execve) @@ -535,13 +507,13 @@ END(stub_execve) ENTRY(stub_execveat) CFI_STARTPROC addq $8, %rsp - PARTIAL_FRAME 0 - SAVE_REST + DEFAULT_FRAME 0 + SAVE_EXTRA_REGS FIXUP_TOP_OF_STACK %r11 call sys_execveat RESTORE_TOP_OF_STACK %r11 movq %rax,RAX(%rsp) - RESTORE_REST + RESTORE_EXTRA_REGS jmp int_ret_from_sys_call CFI_ENDPROC END(stub_execveat) @@ -553,12 +525,12 @@ END(stub_execveat) ENTRY(stub_rt_sigreturn) CFI_STARTPROC addq $8, %rsp - PARTIAL_FRAME 0 - SAVE_REST + DEFAULT_FRAME 0 + SAVE_EXTRA_REGS FIXUP_TOP_OF_STACK %r11 call sys_rt_sigreturn movq %rax,RAX(%rsp) # fixme, this could be done at the higher layer - RESTORE_REST + RESTORE_EXTRA_REGS jmp int_ret_from_sys_call CFI_ENDPROC END(stub_rt_sigreturn) @@ -567,12 +539,12 @@ END(stub_rt_sigreturn) ENTRY(stub_x32_rt_sigreturn) CFI_STARTPROC addq $8, %rsp - PARTIAL_FRAME 0 - SAVE_REST + DEFAULT_FRAME 0 + SAVE_EXTRA_REGS FIXUP_TOP_OF_STACK %r11 call sys32_x32_rt_sigreturn movq %rax,RAX(%rsp) # fixme, this could be done at the higher layer - RESTORE_REST + RESTORE_EXTRA_REGS jmp int_ret_from_sys_call CFI_ENDPROC END(stub_x32_rt_sigreturn) @@ -580,13 +552,13 @@ END(stub_x32_rt_sigreturn) ENTRY(stub_x32_execve) CFI_STARTPROC addq $8, %rsp - PARTIAL_FRAME 0 - SAVE_REST + DEFAULT_FRAME 0 + SAVE_EXTRA_REGS FIXUP_TOP_OF_STACK %r11 call compat_sys_execve RESTORE_TOP_OF_STACK %r11 movq %rax,RAX(%rsp) - RESTORE_REST + RESTORE_EXTRA_REGS jmp int_ret_from_sys_call CFI_ENDPROC END(stub_x32_execve) @@ -594,13 +566,13 @@ END(stub_x32_execve) ENTRY(stub_x32_execveat) CFI_STARTPROC addq $8, %rsp - PARTIAL_FRAME 0 - SAVE_REST + DEFAULT_FRAME 0 + SAVE_EXTRA_REGS FIXUP_TOP_OF_STACK %r11 call compat_sys_execveat RESTORE_TOP_OF_STACK %r11 movq %rax,RAX(%rsp) - RESTORE_REST + RESTORE_EXTRA_REGS jmp int_ret_from_sys_call CFI_ENDPROC END(stub_x32_execveat) @@ -656,42 +628,28 @@ END(interrupt) /* 0(%rsp): ~(interrupt number) */ .macro interrupt func - /* reserve pt_regs for scratch regs and rbp */ - subq $ORIG_RAX-RBP, %rsp - CFI_ADJUST_CFA_OFFSET ORIG_RAX-RBP cld - /* start from rbp in pt_regs and jump over */ - movq_cfi rdi, (RDI-RBP) - movq_cfi rsi, (RSI-RBP) - movq_cfi rdx, (RDX-RBP) - movq_cfi rcx, (RCX-RBP) - movq_cfi rax, (RAX-RBP) - movq_cfi r8, (R8-RBP) - movq_cfi r9, (R9-RBP) - movq_cfi r10, (R10-RBP) - movq_cfi r11, (R11-RBP) - - /* Save rbp so that we can unwind from get_irq_regs() */ - movq_cfi rbp, 0 - - /* Save previous stack value */ - movq %rsp, %rsi + ALLOC_PT_GPREGS_ON_STACK -RBP + SAVE_C_REGS -RBP + /* this goes to 0(%rsp) for unwinder, not for saving the value: */ + SAVE_EXTRA_REGS_RBP -RBP + + leaq -RBP(%rsp),%rdi /* arg1 for \func (pointer to pt_regs) */ - leaq -RBP(%rsp),%rdi /* arg1 for handler */ - testl $3, CS-RBP(%rsi) + testl $3, CS-RBP(%rsp) je 1f SWAPGS +1: /* * irq_count is used to check if a CPU is already on an interrupt stack * or not. While this is essentially redundant with preempt_count it is * a little cheaper to use a separate counter in the PDA (short of * moving irq_enter into assembly, which would be too much work) */ -1: incl PER_CPU_VAR(irq_count) + movq %rsp, %rsi + incl PER_CPU_VAR(irq_count) cmovzq PER_CPU_VAR(irq_stack_ptr),%rsp CFI_DEF_CFA_REGISTER rsi - - /* Store previous stack value */ pushq %rsi CFI_ESCAPE 0x0f /* DW_CFA_def_cfa_expression */, 6, \ 0x77 /* DW_OP_breg7 */, 0, \ @@ -800,7 +758,8 @@ retint_swapgs: /* return to user-space */ */ irq_return_via_sysret: CFI_REMEMBER_STATE - RESTORE_ARGS 1,8,1 + RESTORE_C_REGS + REMOVE_PT_GPREGS_FROM_STACK 8 movq (RSP-RIP)(%rsp),%rsp USERGS_SYSRET64 CFI_RESTORE_STATE @@ -816,7 +775,8 @@ retint_restore_args: /* return to kernel space */ */ TRACE_IRQS_IRETQ restore_args: - RESTORE_ARGS 1,8,1 + RESTORE_C_REGS + REMOVE_PT_GPREGS_FROM_STACK 8 irq_return: INTERRUPT_RETURN @@ -887,12 +847,12 @@ retint_signal: jz retint_swapgs TRACE_IRQS_ON ENABLE_INTERRUPTS(CLBR_NONE) - SAVE_REST + SAVE_EXTRA_REGS movq $-1,ORIG_RAX(%rsp) xorl %esi,%esi # oldset movq %rsp,%rdi # &pt_regs call do_notify_resume - RESTORE_REST + RESTORE_EXTRA_REGS DISABLE_INTERRUPTS(CLBR_NONE) TRACE_IRQS_OFF GET_THREAD_INFO(%rcx) @@ -1019,8 +979,7 @@ ENTRY(\sym) pushq_cfi $-1 /* ORIG_RAX: no syscall to restart */ .endif - subq $ORIG_RAX-R15, %rsp - CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15 + ALLOC_PT_GPREGS_ON_STACK .if \paranoid .if \paranoid == 1 @@ -1269,7 +1228,9 @@ ENTRY(xen_failsafe_callback) addq $0x30,%rsp CFI_ADJUST_CFA_OFFSET -0x30 pushq_cfi $-1 /* orig_ax = -1 => not a system call */ - SAVE_ALL + ALLOC_PT_GPREGS_ON_STACK + SAVE_C_REGS + SAVE_EXTRA_REGS jmp error_exit CFI_ENDPROC END(xen_failsafe_callback) @@ -1321,11 +1282,15 @@ ENTRY(paranoid_exit) jnz paranoid_restore TRACE_IRQS_IRETQ 0 SWAPGS_UNSAFE_STACK - RESTORE_ALL 8 + RESTORE_EXTRA_REGS + RESTORE_C_REGS + REMOVE_PT_GPREGS_FROM_STACK 8 INTERRUPT_RETURN paranoid_restore: TRACE_IRQS_IRETQ_DEBUG 0 - RESTORE_ALL 8 + RESTORE_EXTRA_REGS + RESTORE_C_REGS + REMOVE_PT_GPREGS_FROM_STACK 8 INTERRUPT_RETURN CFI_ENDPROC END(paranoid_exit) @@ -1339,21 +1304,8 @@ ENTRY(error_entry) CFI_ADJUST_CFA_OFFSET 15*8 /* oldrax contains error code */ cld - movq %rdi, RDI+8(%rsp) - movq %rsi, RSI+8(%rsp) - movq %rdx, RDX+8(%rsp) - movq %rcx, RCX+8(%rsp) - movq %rax, RAX+8(%rsp) - movq %r8, R8+8(%rsp) - movq %r9, R9+8(%rsp) - movq %r10, R10+8(%rsp) - movq %r11, R11+8(%rsp) - movq_cfi rbx, RBX+8 - movq %rbp, RBP+8(%rsp) - movq %r12, R12+8(%rsp) - movq %r13, R13+8(%rsp) - movq %r14, R14+8(%rsp) - movq %r15, R15+8(%rsp) + SAVE_C_REGS 8 + SAVE_EXTRA_REGS 8 xorl %ebx,%ebx testl $3,CS+8(%rsp) je error_kernelspace @@ -1402,7 +1354,7 @@ END(error_entry) ENTRY(error_exit) DEFAULT_FRAME movl %ebx,%eax - RESTORE_REST + RESTORE_EXTRA_REGS DISABLE_INTERRUPTS(CLBR_NONE) TRACE_IRQS_OFF GET_THREAD_INFO(%rcx) @@ -1621,8 +1573,8 @@ end_repeat_nmi: * so that we repeat another NMI. */ pushq_cfi $-1 /* ORIG_RAX: no syscall to restart */ - subq $ORIG_RAX-R15, %rsp - CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15 + ALLOC_PT_GPREGS_ON_STACK + /* * Use save_paranoid to handle SWAPGS, but no need to use paranoid_exit * as we should not be calling schedule in NMI context. @@ -1661,8 +1613,10 @@ end_repeat_nmi: nmi_swapgs: SWAPGS_UNSAFE_STACK nmi_restore: + RESTORE_EXTRA_REGS + RESTORE_C_REGS /* Pop the extra iret frame at once */ - RESTORE_ALL 6*8 + REMOVE_PT_GPREGS_FROM_STACK 6*8 /* Clear the NMI executing stack variable */ movq $0, 5*8(%rsp) -- GitLab From e90e147cbc0cbc8dcf48000e15190badf75250f4 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 26 Feb 2015 14:40:28 -0800 Subject: [PATCH 02695/11651] x86/asm/entry/64: Fix comments - Misleading and slightly incorrect comments in "struct pt_regs" are fixed (four instances). - Fix incorrect comment atop EMPTY_FRAME macro. - Explain in more detail what we do with stack layout during hw interrupt. - Correct comments about "partial stack frame" which are no longer true. Signed-off-by: Denys Vlasenko Signed-off-by: Andy Lutomirski Cc: Alexei Starovoitov Cc: Borislav Petkov Cc: Frederic Weisbecker Cc: H. Peter Anvin Cc: Kees Cook Cc: Linus Torvalds Cc: Oleg Nesterov Cc: Will Drewry Link: http://lkml.kernel.org/r/1423778052-21038-3-git-send-email-dvlasenk@redhat.com Link: http://lkml.kernel.org/r/e1f4429c491fe6ceeddb879dea2786e0f8920f9c.1424989793.git.luto@amacapital.net Signed-off-by: Ingo Molnar --- arch/x86/include/asm/ptrace.h | 13 ++++++++++--- arch/x86/include/uapi/asm/ptrace-abi.h | 15 +++++++++++---- arch/x86/include/uapi/asm/ptrace.h | 13 ++++++++++--- arch/x86/kernel/entry_64.S | 18 ++++++++++++------ 4 files changed, 43 insertions(+), 16 deletions(-) diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h index 86fc2bb82287..4077d963a1a0 100644 --- a/arch/x86/include/asm/ptrace.h +++ b/arch/x86/include/asm/ptrace.h @@ -31,13 +31,17 @@ struct pt_regs { #else /* __i386__ */ struct pt_regs { +/* + * C ABI says these regs are callee-preserved. They aren't saved on kernel entry + * unless syscall needs a complete, fully filled "struct pt_regs". + */ unsigned long r15; unsigned long r14; unsigned long r13; unsigned long r12; unsigned long bp; unsigned long bx; -/* arguments: non interrupts/non tracing syscalls only save up to here*/ +/* These regs are callee-clobbered. Always saved on kernel entry. */ unsigned long r11; unsigned long r10; unsigned long r9; @@ -47,9 +51,12 @@ struct pt_regs { unsigned long dx; unsigned long si; unsigned long di; +/* + * On syscall entry, this is syscall#. On CPU exception, this is error code. + * On hw interrupt, it's IRQ number: + */ unsigned long orig_ax; -/* end of arguments */ -/* cpu exception frame or undefined */ +/* Return frame for iretq */ unsigned long ip; unsigned long cs; unsigned long flags; diff --git a/arch/x86/include/uapi/asm/ptrace-abi.h b/arch/x86/include/uapi/asm/ptrace-abi.h index ad115bf779f3..580aee3072e0 100644 --- a/arch/x86/include/uapi/asm/ptrace-abi.h +++ b/arch/x86/include/uapi/asm/ptrace-abi.h @@ -25,13 +25,17 @@ #else /* __i386__ */ #if defined(__ASSEMBLY__) || defined(__FRAME_OFFSETS) +/* + * C ABI says these regs are callee-preserved. They aren't saved on kernel entry + * unless syscall needs a complete, fully filled "struct pt_regs". + */ #define R15 0 #define R14 8 #define R13 16 #define R12 24 #define RBP 32 #define RBX 40 -/* arguments: interrupts/non tracing syscalls only save up to here*/ +/* These regs are callee-clobbered. Always saved on kernel entry. */ #define R11 48 #define R10 56 #define R9 64 @@ -41,9 +45,12 @@ #define RDX 96 #define RSI 104 #define RDI 112 -#define ORIG_RAX 120 /* = ERROR */ -/* end of arguments */ -/* cpu exception frame or undefined in case of fast syscall. */ +/* + * On syscall entry, this is syscall#. On CPU exception, this is error code. + * On hw interrupt, it's IRQ number: + */ +#define ORIG_RAX 120 +/* Return frame for iretq */ #define RIP 128 #define CS 136 #define EFLAGS 144 diff --git a/arch/x86/include/uapi/asm/ptrace.h b/arch/x86/include/uapi/asm/ptrace.h index ac4b9aa4d999..bc16115af39b 100644 --- a/arch/x86/include/uapi/asm/ptrace.h +++ b/arch/x86/include/uapi/asm/ptrace.h @@ -41,13 +41,17 @@ struct pt_regs { #ifndef __KERNEL__ struct pt_regs { +/* + * C ABI says these regs are callee-preserved. They aren't saved on kernel entry + * unless syscall needs a complete, fully filled "struct pt_regs". + */ unsigned long r15; unsigned long r14; unsigned long r13; unsigned long r12; unsigned long rbp; unsigned long rbx; -/* arguments: non interrupts/non tracing syscalls only save up to here*/ +/* These regs are callee-clobbered. Always saved on kernel entry. */ unsigned long r11; unsigned long r10; unsigned long r9; @@ -57,9 +61,12 @@ struct pt_regs { unsigned long rdx; unsigned long rsi; unsigned long rdi; +/* + * On syscall entry, this is syscall#. On CPU exception, this is error code. + * On hw interrupt, it's IRQ number: + */ unsigned long orig_rax; -/* end of arguments */ -/* cpu exception frame or undefined */ +/* Return frame for iretq */ unsigned long rip; unsigned long cs; unsigned long eflags; diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index e8372e08f8c2..695f4d434a84 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -14,9 +14,6 @@ * NOTE: This code handles signal-recognition, which happens every time * after an interrupt and after each system call. * - * Normal syscalls and interrupts don't save a full stack frame, this is - * only done for syscall tracing, signals or fork/exec et.al. - * * A note on terminology: * - top of stack: Architecture defined interrupt frame from SS to RIP * at the top of the kernel process stack. @@ -151,7 +148,7 @@ ENDPROC(native_usergs_sysret64) .endm /* - * initial frame state for interrupts (and exceptions without error code) + * empty frame */ .macro EMPTY_FRAME start=1 offset=0 .if \start @@ -379,7 +376,7 @@ tracesys_phase2: call syscall_trace_enter_phase2 /* - * Reload arg registers from stack in case ptrace changed them. + * Reload registers from stack in case ptrace changed them. * We don't reload %rax because syscall_trace_entry_phase2() returned * the value it wants us to use in the table lookup. */ @@ -629,6 +626,13 @@ END(interrupt) /* 0(%rsp): ~(interrupt number) */ .macro interrupt func cld + /* + * Since nothing in interrupt handling code touches r12...r15 members + * of "struct pt_regs", and since interrupts can nest, we can save + * four stack slots and simultaneously provide + * an unwind-friendly stack layout by saving "truncated" pt_regs + * exactly up to rbp slot, without these members. + */ ALLOC_PT_GPREGS_ON_STACK -RBP SAVE_C_REGS -RBP /* this goes to 0(%rsp) for unwinder, not for saving the value: */ @@ -641,6 +645,7 @@ END(interrupt) SWAPGS 1: /* + * Save previous stack pointer, optionally switch to interrupt stack. * irq_count is used to check if a CPU is already on an interrupt stack * or not. While this is essentially redundant with preempt_count it is * a little cheaper to use a separate counter in the PDA (short of @@ -681,6 +686,7 @@ ret_from_intr: /* Restore saved previous stack */ popq %rsi CFI_DEF_CFA rsi,SS+8-RBP /* reg/off reset after def_cfa_expr */ + /* return code expects complete pt_regs - adjust rsp accordingly: */ leaq ARGOFFSET-RBP(%rsi), %rsp CFI_DEF_CFA_REGISTER rsp CFI_ADJUST_CFA_OFFSET RBP-ARGOFFSET @@ -692,7 +698,7 @@ exit_intr: /* Interrupt came from user space */ /* - * Has a correct top of stack, but a partial stack frame + * Has a correct top of stack. * %rcx: thread info. Interrupts off. */ retint_with_reschedule: -- GitLab From 0d55083698ed2f498e5682c5c252e6b7224890be Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 26 Feb 2015 14:40:29 -0800 Subject: [PATCH 02696/11651] x86/asm/entry/64: Shrink code in 'paranoid_exit' RESTORE_EXTRA_REGS + RESTORE_C_REGS looks small, but it's a lot of instructions (fourteen). Let's reuse them. Signed-off-by: Denys Vlasenko [ Cleaned up the labels. ] Signed-off-by: Andy Lutomirski Cc: Alexei Starovoitov Cc: Borislav Petkov Cc: Frederic Weisbecker Cc: H. Peter Anvin Cc: Kees Cook Cc: Linus Torvalds Cc: Oleg Nesterov Cc: Will Drewry Link: http://lkml.kernel.org/r/1421272101-16847-2-git-send-email-dvlasenk@redhat.com Link: http://lkml.kernel.org/r/59d71848cee3ec9eb48c0252e602efd6bd560e3c.1424989793.git.luto@amacapital.net Signed-off-by: Ingo Molnar --- arch/x86/kernel/entry_64.S | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index 695f4d434a84..8fafed9f462d 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -1285,15 +1285,13 @@ ENTRY(paranoid_exit) DISABLE_INTERRUPTS(CLBR_NONE) TRACE_IRQS_OFF_DEBUG testl %ebx,%ebx /* swapgs needed? */ - jnz paranoid_restore + jnz paranoid_exit_no_swapgs TRACE_IRQS_IRETQ 0 SWAPGS_UNSAFE_STACK - RESTORE_EXTRA_REGS - RESTORE_C_REGS - REMOVE_PT_GPREGS_FROM_STACK 8 - INTERRUPT_RETURN -paranoid_restore: + jmp paranoid_exit_restore +paranoid_exit_no_swapgs: TRACE_IRQS_IRETQ_DEBUG 0 +paranoid_exit_restore: RESTORE_EXTRA_REGS RESTORE_C_REGS REMOVE_PT_GPREGS_FROM_STACK 8 -- GitLab From f2db9382c1140914cfdef224ce907e443c9f9b81 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 26 Feb 2015 14:40:30 -0800 Subject: [PATCH 02697/11651] x86/asm/entry: Do mass removal of 'ARGOFFSET' ARGOFFSET is zero now, removing it changes no code. A few macros lost "offset" parameter, since it is always zero now too. No code changes - verified with objdump. Signed-off-by: Denys Vlasenko Signed-off-by: Andy Lutomirski Cc: Alexei Starovoitov Cc: Borislav Petkov Cc: Frederic Weisbecker Cc: H. Peter Anvin Cc: Kees Cook Cc: Linus Torvalds Cc: Oleg Nesterov Cc: Thomas Gleixner Cc: Will Drewry Link: http://lkml.kernel.org/r/8689f937622d9d2db0ab8be82331fa15e4ed4713.1424989793.git.luto@amacapital.net Signed-off-by: Ingo Molnar --- arch/x86/ia32/ia32entry.S | 142 ++++++++++++++++----------------- arch/x86/include/asm/calling.h | 2 - arch/x86/kernel/entry_64.S | 86 ++++++++++---------- 3 files changed, 114 insertions(+), 116 deletions(-) diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S index f4bed4971673..e99f8a5be2df 100644 --- a/arch/x86/ia32/ia32entry.S +++ b/arch/x86/ia32/ia32entry.S @@ -41,13 +41,13 @@ movl %edx,%edx /* zero extension */ .endm - /* clobbers %eax */ - .macro CLEAR_RREGS offset=0, _r9=rax + /* clobbers %rax */ + .macro CLEAR_RREGS _r9=rax xorl %eax,%eax - movq %rax,\offset+R11(%rsp) - movq %rax,\offset+R10(%rsp) - movq %\_r9,\offset+R9(%rsp) - movq %rax,\offset+R8(%rsp) + movq %rax,R11(%rsp) + movq %rax,R10(%rsp) + movq %\_r9,R9(%rsp) + movq %rax,R8(%rsp) .endm /* @@ -60,14 +60,14 @@ * If it's -1 to make us punt the syscall, then (u32)-1 is still * an appropriately invalid value. */ - .macro LOAD_ARGS32 offset, _r9=0 + .macro LOAD_ARGS32 _r9=0 .if \_r9 - movl \offset+R9(%rsp),%r9d + movl R9(%rsp),%r9d .endif - movl \offset+RCX(%rsp),%ecx - movl \offset+RDX(%rsp),%edx - movl \offset+RSI(%rsp),%esi - movl \offset+RDI(%rsp),%edi + movl RCX(%rsp),%ecx + movl RDX(%rsp),%edx + movl RSI(%rsp),%esi + movl RDI(%rsp),%edi movl %eax,%eax /* zero extension */ .endm @@ -158,12 +158,12 @@ ENTRY(ia32_sysenter_target) * ourselves. To save a few cycles, we can check whether * NT was set instead of doing an unconditional popfq. */ - testl $X86_EFLAGS_NT,EFLAGS-ARGOFFSET(%rsp) + testl $X86_EFLAGS_NT,EFLAGS(%rsp) jnz sysenter_fix_flags sysenter_flags_fixed: - orl $TS_COMPAT,TI_status+THREAD_INFO(%rsp,RIP-ARGOFFSET) - testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags+THREAD_INFO(%rsp,RIP-ARGOFFSET) + orl $TS_COMPAT,TI_status+THREAD_INFO(%rsp,RIP) + testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags+THREAD_INFO(%rsp,RIP) CFI_REMEMBER_STATE jnz sysenter_tracesys cmpq $(IA32_NR_syscalls-1),%rax @@ -172,16 +172,16 @@ sysenter_do_call: IA32_ARG_FIXUP sysenter_dispatch: call *ia32_sys_call_table(,%rax,8) - movq %rax,RAX-ARGOFFSET(%rsp) + movq %rax,RAX(%rsp) DISABLE_INTERRUPTS(CLBR_NONE) TRACE_IRQS_OFF - testl $_TIF_ALLWORK_MASK,TI_flags+THREAD_INFO(%rsp,RIP-ARGOFFSET) + testl $_TIF_ALLWORK_MASK,TI_flags+THREAD_INFO(%rsp,RIP) jnz sysexit_audit sysexit_from_sys_call: - andl $~TS_COMPAT,TI_status+THREAD_INFO(%rsp,RIP-ARGOFFSET) + andl $~TS_COMPAT,TI_status+THREAD_INFO(%rsp,RIP) /* clear IF, that popfq doesn't enable interrupts early */ - andl $~0x200,EFLAGS-ARGOFFSET(%rsp) - movl RIP-ARGOFFSET(%rsp),%edx /* User %eip */ + andl $~0x200,EFLAGS(%rsp) + movl RIP(%rsp),%edx /* User %eip */ CFI_REGISTER rip,rdx RESTORE_RSI_RDI REMOVE_PT_GPREGS_FROM_STACK 3*8 @@ -207,18 +207,18 @@ sysexit_from_sys_call: movl %ebx,%esi /* 2nd arg: 1st syscall arg */ movl %eax,%edi /* 1st arg: syscall number */ call __audit_syscall_entry - movl RAX-ARGOFFSET(%rsp),%eax /* reload syscall number */ + movl RAX(%rsp),%eax /* reload syscall number */ cmpq $(IA32_NR_syscalls-1),%rax ja ia32_badsys movl %ebx,%edi /* reload 1st syscall arg */ - movl RCX-ARGOFFSET(%rsp),%esi /* reload 2nd syscall arg */ - movl RDX-ARGOFFSET(%rsp),%edx /* reload 3rd syscall arg */ - movl RSI-ARGOFFSET(%rsp),%ecx /* reload 4th syscall arg */ - movl RDI-ARGOFFSET(%rsp),%r8d /* reload 5th syscall arg */ + movl RCX(%rsp),%esi /* reload 2nd syscall arg */ + movl RDX(%rsp),%edx /* reload 3rd syscall arg */ + movl RSI(%rsp),%ecx /* reload 4th syscall arg */ + movl RDI(%rsp),%r8d /* reload 5th syscall arg */ .endm .macro auditsys_exit exit - testl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT),TI_flags+THREAD_INFO(%rsp,RIP-ARGOFFSET) + testl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT),TI_flags+THREAD_INFO(%rsp,RIP) jnz ia32_ret_from_sys_call TRACE_IRQS_ON ENABLE_INTERRUPTS(CLBR_NONE) @@ -229,13 +229,13 @@ sysexit_from_sys_call: 1: setbe %al /* 1 if error, 0 if not */ movzbl %al,%edi /* zero-extend that into %edi */ call __audit_syscall_exit - movq RAX-ARGOFFSET(%rsp),%rax /* reload syscall return value */ + movq RAX(%rsp),%rax /* reload syscall return value */ movl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT),%edi DISABLE_INTERRUPTS(CLBR_NONE) TRACE_IRQS_OFF - testl %edi,TI_flags+THREAD_INFO(%rsp,RIP-ARGOFFSET) + testl %edi,TI_flags+THREAD_INFO(%rsp,RIP) jz \exit - CLEAR_RREGS -ARGOFFSET + CLEAR_RREGS jmp int_with_check .endm @@ -255,7 +255,7 @@ sysenter_fix_flags: sysenter_tracesys: #ifdef CONFIG_AUDITSYSCALL - testl $(_TIF_WORK_SYSCALL_ENTRY & ~_TIF_SYSCALL_AUDIT),TI_flags+THREAD_INFO(%rsp,RIP-ARGOFFSET) + testl $(_TIF_WORK_SYSCALL_ENTRY & ~_TIF_SYSCALL_AUDIT),TI_flags+THREAD_INFO(%rsp,RIP) jz sysenter_auditsys #endif SAVE_EXTRA_REGS @@ -263,7 +263,7 @@ sysenter_tracesys: movq $-ENOSYS,RAX(%rsp)/* ptrace can change this for a bad syscall */ movq %rsp,%rdi /* &pt_regs -> arg1 */ call syscall_trace_enter - LOAD_ARGS32 ARGOFFSET /* reload args from stack in case ptrace changed it */ + LOAD_ARGS32 /* reload args from stack in case ptrace changed it */ RESTORE_EXTRA_REGS cmpq $(IA32_NR_syscalls-1),%rax ja int_ret_from_sys_call /* sysenter_tracesys has set RAX(%rsp) */ @@ -309,17 +309,17 @@ ENTRY(ia32_cstar_target) ALLOC_PT_GPREGS_ON_STACK 8 SAVE_C_REGS_EXCEPT_RCX_R891011 movl %eax,%eax /* zero extension */ - movq %rax,ORIG_RAX-ARGOFFSET(%rsp) - movq %rcx,RIP-ARGOFFSET(%rsp) - CFI_REL_OFFSET rip,RIP-ARGOFFSET - movq %rbp,RCX-ARGOFFSET(%rsp) /* this lies slightly to ptrace */ + movq %rax,ORIG_RAX(%rsp) + movq %rcx,RIP(%rsp) + CFI_REL_OFFSET rip,RIP + movq %rbp,RCX(%rsp) /* this lies slightly to ptrace */ movl %ebp,%ecx - movq $__USER32_CS,CS-ARGOFFSET(%rsp) - movq $__USER32_DS,SS-ARGOFFSET(%rsp) - movq %r11,EFLAGS-ARGOFFSET(%rsp) - /*CFI_REL_OFFSET rflags,EFLAGS-ARGOFFSET*/ - movq %r8,RSP-ARGOFFSET(%rsp) - CFI_REL_OFFSET rsp,RSP-ARGOFFSET + movq $__USER32_CS,CS(%rsp) + movq $__USER32_DS,SS(%rsp) + movq %r11,EFLAGS(%rsp) + /*CFI_REL_OFFSET rflags,EFLAGS*/ + movq %r8,RSP(%rsp) + CFI_REL_OFFSET rsp,RSP /* no need to do an access_ok check here because r8 has been 32bit zero extended */ /* hardware stack frame is complete now */ @@ -327,8 +327,8 @@ ENTRY(ia32_cstar_target) 1: movl (%r8),%r9d _ASM_EXTABLE(1b,ia32_badarg) ASM_CLAC - orl $TS_COMPAT,TI_status+THREAD_INFO(%rsp,RIP-ARGOFFSET) - testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags+THREAD_INFO(%rsp,RIP-ARGOFFSET) + orl $TS_COMPAT,TI_status+THREAD_INFO(%rsp,RIP) + testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags+THREAD_INFO(%rsp,RIP) CFI_REMEMBER_STATE jnz cstar_tracesys cmpq $IA32_NR_syscalls-1,%rax @@ -337,32 +337,32 @@ cstar_do_call: IA32_ARG_FIXUP 1 cstar_dispatch: call *ia32_sys_call_table(,%rax,8) - movq %rax,RAX-ARGOFFSET(%rsp) + movq %rax,RAX(%rsp) DISABLE_INTERRUPTS(CLBR_NONE) TRACE_IRQS_OFF - testl $_TIF_ALLWORK_MASK,TI_flags+THREAD_INFO(%rsp,RIP-ARGOFFSET) + testl $_TIF_ALLWORK_MASK,TI_flags+THREAD_INFO(%rsp,RIP) jnz sysretl_audit sysretl_from_sys_call: - andl $~TS_COMPAT,TI_status+THREAD_INFO(%rsp,RIP-ARGOFFSET) + andl $~TS_COMPAT,TI_status+THREAD_INFO(%rsp,RIP) RESTORE_RSI_RDI_RDX - movl RIP-ARGOFFSET(%rsp),%ecx + movl RIP(%rsp),%ecx CFI_REGISTER rip,rcx - movl EFLAGS-ARGOFFSET(%rsp),%r11d + movl EFLAGS(%rsp),%r11d /*CFI_REGISTER rflags,r11*/ xorq %r10,%r10 xorq %r9,%r9 xorq %r8,%r8 TRACE_IRQS_ON - movl RSP-ARGOFFSET(%rsp),%esp + movl RSP(%rsp),%esp CFI_RESTORE rsp USERGS_SYSRET32 #ifdef CONFIG_AUDITSYSCALL cstar_auditsys: CFI_RESTORE_STATE - movl %r9d,R9-ARGOFFSET(%rsp) /* register to be clobbered by call */ + movl %r9d,R9(%rsp) /* register to be clobbered by call */ auditsys_entry_common - movl R9-ARGOFFSET(%rsp),%r9d /* reload 6th syscall arg */ + movl R9(%rsp),%r9d /* reload 6th syscall arg */ jmp cstar_dispatch sysretl_audit: @@ -371,16 +371,16 @@ sysretl_audit: cstar_tracesys: #ifdef CONFIG_AUDITSYSCALL - testl $(_TIF_WORK_SYSCALL_ENTRY & ~_TIF_SYSCALL_AUDIT),TI_flags+THREAD_INFO(%rsp,RIP-ARGOFFSET) + testl $(_TIF_WORK_SYSCALL_ENTRY & ~_TIF_SYSCALL_AUDIT),TI_flags+THREAD_INFO(%rsp,RIP) jz cstar_auditsys #endif xchgl %r9d,%ebp SAVE_EXTRA_REGS - CLEAR_RREGS 0, r9 + CLEAR_RREGS r9 movq $-ENOSYS,RAX(%rsp) /* ptrace can change this for a bad syscall */ movq %rsp,%rdi /* &pt_regs -> arg1 */ call syscall_trace_enter - LOAD_ARGS32 ARGOFFSET, 1 /* reload args from stack in case ptrace changed it */ + LOAD_ARGS32 1 /* reload args from stack in case ptrace changed it */ RESTORE_EXTRA_REGS xchgl %ebp,%r9d cmpq $(IA32_NR_syscalls-1),%rax @@ -438,8 +438,8 @@ ENTRY(ia32_syscall) this could be a problem. */ ALLOC_PT_GPREGS_ON_STACK SAVE_C_REGS_EXCEPT_R891011 - orl $TS_COMPAT,TI_status+THREAD_INFO(%rsp,RIP-ARGOFFSET) - testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags+THREAD_INFO(%rsp,RIP-ARGOFFSET) + orl $TS_COMPAT,TI_status+THREAD_INFO(%rsp,RIP) + testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags+THREAD_INFO(%rsp,RIP) jnz ia32_tracesys cmpq $(IA32_NR_syscalls-1),%rax ja ia32_badsys @@ -447,9 +447,9 @@ ia32_do_call: IA32_ARG_FIXUP call *ia32_sys_call_table(,%rax,8) # xxx: rip relative ia32_sysret: - movq %rax,RAX-ARGOFFSET(%rsp) + movq %rax,RAX(%rsp) ia32_ret_from_sys_call: - CLEAR_RREGS -ARGOFFSET + CLEAR_RREGS jmp int_ret_from_sys_call ia32_tracesys: @@ -458,7 +458,7 @@ ia32_tracesys: movq $-ENOSYS,RAX(%rsp) /* ptrace can change this for a bad syscall */ movq %rsp,%rdi /* &pt_regs -> arg1 */ call syscall_trace_enter - LOAD_ARGS32 ARGOFFSET /* reload args from stack in case ptrace changed it */ + LOAD_ARGS32 /* reload args from stack in case ptrace changed it */ RESTORE_EXTRA_REGS cmpq $(IA32_NR_syscalls-1),%rax ja int_ret_from_sys_call /* ia32_tracesys has set RAX(%rsp) */ @@ -466,7 +466,7 @@ ia32_tracesys: END(ia32_syscall) ia32_badsys: - movq $0,ORIG_RAX-ARGOFFSET(%rsp) + movq $0,ORIG_RAX(%rsp) movq $-ENOSYS,%rax jmp ia32_sysret @@ -499,17 +499,17 @@ ia32_ptregs_common: CFI_ENDPROC CFI_STARTPROC32 simple CFI_SIGNAL_FRAME - CFI_DEF_CFA rsp,SS+8-ARGOFFSET - CFI_REL_OFFSET rax,RAX-ARGOFFSET - CFI_REL_OFFSET rcx,RCX-ARGOFFSET - CFI_REL_OFFSET rdx,RDX-ARGOFFSET - CFI_REL_OFFSET rsi,RSI-ARGOFFSET - CFI_REL_OFFSET rdi,RDI-ARGOFFSET - CFI_REL_OFFSET rip,RIP-ARGOFFSET -/* CFI_REL_OFFSET cs,CS-ARGOFFSET*/ -/* CFI_REL_OFFSET rflags,EFLAGS-ARGOFFSET*/ - CFI_REL_OFFSET rsp,RSP-ARGOFFSET -/* CFI_REL_OFFSET ss,SS-ARGOFFSET*/ + CFI_DEF_CFA rsp,SS+8 + CFI_REL_OFFSET rax,RAX + CFI_REL_OFFSET rcx,RCX + CFI_REL_OFFSET rdx,RDX + CFI_REL_OFFSET rsi,RSI + CFI_REL_OFFSET rdi,RDI + CFI_REL_OFFSET rip,RIP +/* CFI_REL_OFFSET cs,CS*/ +/* CFI_REL_OFFSET rflags,EFLAGS*/ + CFI_REL_OFFSET rsp,RSP +/* CFI_REL_OFFSET ss,SS*/ SAVE_EXTRA_REGS 8 call *%rax RESTORE_EXTRA_REGS 8 diff --git a/arch/x86/include/asm/calling.h b/arch/x86/include/asm/calling.h index 38356476b131..4a7ceb9789a5 100644 --- a/arch/x86/include/asm/calling.h +++ b/arch/x86/include/asm/calling.h @@ -88,8 +88,6 @@ For 32-bit we have the following conventions - kernel is built with #define RSP 19*8 #define SS 20*8 -#define ARGOFFSET 0 - .macro ALLOC_PT_GPREGS_ON_STACK addskip=0 subq $15*8+\addskip, %rsp CFI_ADJUST_CFA_OFFSET 15*8+\addskip diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index 8fafed9f462d..06055f9578a8 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -73,9 +73,9 @@ ENDPROC(native_usergs_sysret64) #endif /* CONFIG_PARAVIRT */ -.macro TRACE_IRQS_IRETQ offset=ARGOFFSET +.macro TRACE_IRQS_IRETQ #ifdef CONFIG_TRACE_IRQFLAGS - bt $9,EFLAGS-\offset(%rsp) /* interrupts off? */ + bt $9,EFLAGS(%rsp) /* interrupts off? */ jnc 1f TRACE_IRQS_ON 1: @@ -107,8 +107,8 @@ ENDPROC(native_usergs_sysret64) call debug_stack_reset .endm -.macro TRACE_IRQS_IRETQ_DEBUG offset=ARGOFFSET - bt $9,EFLAGS-\offset(%rsp) /* interrupts off? */ +.macro TRACE_IRQS_IRETQ_DEBUG + bt $9,EFLAGS(%rsp) /* interrupts off? */ jnc 1f TRACE_IRQS_ON_DEBUG 1: @@ -184,16 +184,16 @@ ENDPROC(native_usergs_sysret64) * frame that enables passing a complete pt_regs to a C function. */ .macro DEFAULT_FRAME start=1 offset=0 - XCPT_FRAME \start, ORIG_RAX+\offset-ARGOFFSET - CFI_REL_OFFSET rdi, RDI+\offset-ARGOFFSET - CFI_REL_OFFSET rsi, RSI+\offset-ARGOFFSET - CFI_REL_OFFSET rdx, RDX+\offset-ARGOFFSET - CFI_REL_OFFSET rcx, RCX+\offset-ARGOFFSET - CFI_REL_OFFSET rax, RAX+\offset-ARGOFFSET - CFI_REL_OFFSET r8, R8+\offset-ARGOFFSET - CFI_REL_OFFSET r9, R9+\offset-ARGOFFSET - CFI_REL_OFFSET r10, R10+\offset-ARGOFFSET - CFI_REL_OFFSET r11, R11+\offset-ARGOFFSET + XCPT_FRAME \start, ORIG_RAX+\offset + CFI_REL_OFFSET rdi, RDI+\offset + CFI_REL_OFFSET rsi, RSI+\offset + CFI_REL_OFFSET rdx, RDX+\offset + CFI_REL_OFFSET rcx, RCX+\offset + CFI_REL_OFFSET rax, RAX+\offset + CFI_REL_OFFSET r8, R8+\offset + CFI_REL_OFFSET r9, R9+\offset + CFI_REL_OFFSET r10, R10+\offset + CFI_REL_OFFSET r11, R11+\offset CFI_REL_OFFSET rbx, RBX+\offset CFI_REL_OFFSET rbp, RBP+\offset CFI_REL_OFFSET r12, R12+\offset @@ -237,13 +237,13 @@ ENTRY(ret_from_fork) RESTORE_EXTRA_REGS - testl $3, CS-ARGOFFSET(%rsp) # from kernel_thread? + testl $3,CS(%rsp) # from kernel_thread? jz 1f testl $_TIF_IA32, TI_flags(%rcx) # 32-bit compat task needs IRET jnz int_ret_from_sys_call - RESTORE_TOP_OF_STACK %rdi, -ARGOFFSET + RESTORE_TOP_OF_STACK %rdi jmp ret_from_sys_call # go to the SYSRET fastpath 1: @@ -310,11 +310,11 @@ GLOBAL(system_call_after_swapgs) ENABLE_INTERRUPTS(CLBR_NONE) ALLOC_PT_GPREGS_ON_STACK 8 SAVE_C_REGS_EXCEPT_RAX_RCX - movq $-ENOSYS,RAX-ARGOFFSET(%rsp) - movq_cfi rax,(ORIG_RAX-ARGOFFSET) - movq %rcx,RIP-ARGOFFSET(%rsp) - CFI_REL_OFFSET rip,RIP-ARGOFFSET - testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags+THREAD_INFO(%rsp,RIP-ARGOFFSET) + movq $-ENOSYS,RAX(%rsp) + movq_cfi rax,ORIG_RAX + movq %rcx,RIP(%rsp) + CFI_REL_OFFSET rip,RIP + testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags+THREAD_INFO(%rsp,RIP) jnz tracesys system_call_fastpath: #if __SYSCALL_MASK == ~0 @@ -326,13 +326,13 @@ system_call_fastpath: ja ret_from_sys_call /* and return regs->ax */ movq %r10,%rcx call *sys_call_table(,%rax,8) # XXX: rip relative - movq %rax,RAX-ARGOFFSET(%rsp) + movq %rax,RAX(%rsp) /* * Syscall return path ending with SYSRET (fast path) * Has incomplete stack frame and undefined top of stack. */ ret_from_sys_call: - testl $_TIF_ALLWORK_MASK,TI_flags+THREAD_INFO(%rsp,RIP-ARGOFFSET) + testl $_TIF_ALLWORK_MASK,TI_flags+THREAD_INFO(%rsp,RIP) jnz int_ret_from_sys_call_fixup /* Go the the slow path */ LOCKDEP_SYS_EXIT @@ -344,7 +344,7 @@ ret_from_sys_call: */ TRACE_IRQS_ON RESTORE_C_REGS_EXCEPT_RCX - movq RIP-ARGOFFSET(%rsp),%rcx + movq RIP(%rsp),%rcx CFI_REGISTER rip,rcx /*CFI_REGISTER rflags,r11*/ movq PER_CPU_VAR(old_rsp), %rsp @@ -353,7 +353,7 @@ ret_from_sys_call: CFI_RESTORE_STATE int_ret_from_sys_call_fixup: - FIXUP_TOP_OF_STACK %r11, -ARGOFFSET + FIXUP_TOP_OF_STACK %r11 jmp int_ret_from_sys_call /* Do syscall tracing */ @@ -364,7 +364,7 @@ tracesys: test %rax, %rax jnz tracesys_phase2 /* if needed, run the slow path */ RESTORE_C_REGS_EXCEPT_RAX /* else restore clobbered regs */ - movq ORIG_RAX-ARGOFFSET(%rsp), %rax + movq ORIG_RAX(%rsp), %rax jmp system_call_fastpath /* and return to the fast path */ tracesys_phase2: @@ -391,7 +391,7 @@ tracesys_phase2: ja int_ret_from_sys_call /* RAX(%rsp) is already set */ movq %r10,%rcx /* fixup for C */ call *sys_call_table(,%rax,8) - movq %rax,RAX-ARGOFFSET(%rsp) + movq %rax,RAX(%rsp) /* Use IRET because user could have changed frame */ /* @@ -475,9 +475,9 @@ END(stub_\func) ENTRY(\label) CFI_STARTPROC DEFAULT_FRAME 0, 8 /* offset 8: return address */ - FIXUP_TOP_OF_STACK %r11, 8-ARGOFFSET + FIXUP_TOP_OF_STACK %r11, 8 call \func - RESTORE_TOP_OF_STACK %r11, 8-ARGOFFSET + RESTORE_TOP_OF_STACK %r11, 8 ret CFI_ENDPROC END(\label) @@ -677,7 +677,7 @@ common_interrupt: ASM_CLAC addq $-0x80,(%rsp) /* Adjust vector to [-256,-1] range */ interrupt do_IRQ - /* 0(%rsp): old_rsp-ARGOFFSET */ + /* 0(%rsp): old_rsp */ ret_from_intr: DISABLE_INTERRUPTS(CLBR_NONE) TRACE_IRQS_OFF @@ -687,13 +687,13 @@ ret_from_intr: popq %rsi CFI_DEF_CFA rsi,SS+8-RBP /* reg/off reset after def_cfa_expr */ /* return code expects complete pt_regs - adjust rsp accordingly: */ - leaq ARGOFFSET-RBP(%rsi), %rsp + leaq -RBP(%rsi),%rsp CFI_DEF_CFA_REGISTER rsp - CFI_ADJUST_CFA_OFFSET RBP-ARGOFFSET + CFI_ADJUST_CFA_OFFSET RBP exit_intr: GET_THREAD_INFO(%rcx) - testl $3,CS-ARGOFFSET(%rsp) + testl $3,CS(%rsp) je retint_kernel /* Interrupt came from user space */ @@ -721,8 +721,8 @@ retint_swapgs: /* return to user-space */ * Try to use SYSRET instead of IRET if we're returning to * a completely clean 64-bit userspace context. */ - movq (RCX-ARGOFFSET)(%rsp), %rcx - cmpq %rcx,(RIP-ARGOFFSET)(%rsp) /* RCX == RIP */ + movq RCX(%rsp),%rcx + cmpq %rcx,RIP(%rsp) /* RCX == RIP */ jne opportunistic_sysret_failed /* @@ -743,19 +743,19 @@ retint_swapgs: /* return to user-space */ shr $__VIRTUAL_MASK_SHIFT, %rcx jnz opportunistic_sysret_failed - cmpq $__USER_CS,(CS-ARGOFFSET)(%rsp) /* CS must match SYSRET */ + cmpq $__USER_CS,CS(%rsp) /* CS must match SYSRET */ jne opportunistic_sysret_failed - movq (R11-ARGOFFSET)(%rsp), %r11 - cmpq %r11,(EFLAGS-ARGOFFSET)(%rsp) /* R11 == RFLAGS */ + movq R11(%rsp),%r11 + cmpq %r11,EFLAGS(%rsp) /* R11 == RFLAGS */ jne opportunistic_sysret_failed - testq $X86_EFLAGS_RF,%r11 /* sysret can't restore RF */ + testq $X86_EFLAGS_RF,%r11 /* sysret can't restore RF */ jnz opportunistic_sysret_failed /* nothing to check for RSP */ - cmpq $__USER_DS,(SS-ARGOFFSET)(%rsp) /* SS must match SYSRET */ + cmpq $__USER_DS,SS(%rsp) /* SS must match SYSRET */ jne opportunistic_sysret_failed /* @@ -870,7 +870,7 @@ retint_signal: ENTRY(retint_kernel) cmpl $0,PER_CPU_VAR(__preempt_count) jnz retint_restore_args - bt $9,EFLAGS-ARGOFFSET(%rsp) /* interrupts off? */ + bt $9,EFLAGS(%rsp) /* interrupts off? */ jnc retint_restore_args call preempt_schedule_irq jmp exit_intr @@ -1286,11 +1286,11 @@ ENTRY(paranoid_exit) TRACE_IRQS_OFF_DEBUG testl %ebx,%ebx /* swapgs needed? */ jnz paranoid_exit_no_swapgs - TRACE_IRQS_IRETQ 0 + TRACE_IRQS_IRETQ SWAPGS_UNSAFE_STACK jmp paranoid_exit_restore paranoid_exit_no_swapgs: - TRACE_IRQS_IRETQ_DEBUG 0 + TRACE_IRQS_IRETQ_DEBUG paranoid_exit_restore: RESTORE_EXTRA_REGS RESTORE_C_REGS -- GitLab From 050273d19b94f2adf9d35979cee949d6b6a9df84 Mon Sep 17 00:00:00 2001 From: Andy Lutomirski Date: Thu, 26 Feb 2015 14:40:31 -0800 Subject: [PATCH 02698/11651] x86/asm/entry/64: Remove 'int_check_syscall_exit_work' Nothing references it anymore. Reported-by: Denys Vlasenko Signed-off-by: Andy Lutomirski Cc: Borislav Petkov Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Oleg Nesterov Cc: Thomas Gleixner Fixes: 96b6352c1271 ("x86_64, entry: Remove the syscall exit audit and schedule optimizations") Link: http://lkml.kernel.org/r/dd2a4d26ecc7a5db61b476727175cd99ae2b32a4.1424989793.git.luto@amacapital.net Signed-off-by: Ingo Molnar --- arch/x86/kernel/entry_64.S | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index 06055f9578a8..b0fbde1876e1 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -431,7 +431,6 @@ int_careful: int_very_careful: TRACE_IRQS_ON ENABLE_INTERRUPTS(CLBR_NONE) -int_check_syscall_exit_work: SAVE_EXTRA_REGS /* Check for syscall exit trace */ testl $_TIF_WORK_SYSCALL_EXIT,%edx -- GitLab From b87cf63e2a5fbe3b368d5f5e5708e585b0fb3f84 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 26 Feb 2015 14:40:32 -0800 Subject: [PATCH 02699/11651] x86/asm/entry: Add comments about various syscall instructions SYSCALL/SYSRET and SYSENTER/SYSEXIT have weird semantics. Moreover, they differ in 32- and 64-bit mode. What is saved? What is not? Is rsp set? Are interrupts disabled? People tend to not remember these details well enough. This patch adds comments which explain in detail what registers are modified by each of these instructions. The comments are placed immediately before corresponding entry and exit points. Signed-off-by: Denys Vlasenko Signed-off-by: Andy Lutomirski Cc: Alexei Starovoitov Cc: Borislav Petkov Cc: Frederic Weisbecker Cc: H. Peter Anvin Cc: Kees Cook Cc: Linus Torvalds Cc: Oleg Nesterov Cc: Thomas Gleixner Cc: Will Drewry Link: http://lkml.kernel.org/r/a94b98b63527797c871a81402ff5060b18fa880a.1424989793.git.luto@amacapital.net Signed-off-by: Ingo Molnar --- arch/x86/ia32/ia32entry.S | 133 +++++++++++++++++++++++-------------- arch/x86/kernel/entry_64.S | 32 +++++---- 2 files changed, 102 insertions(+), 63 deletions(-) diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S index e99f8a5be2df..b5670564a1fb 100644 --- a/arch/x86/ia32/ia32entry.S +++ b/arch/x86/ia32/ia32entry.S @@ -99,22 +99,25 @@ ENDPROC(native_irq_enable_sysexit) /* * 32bit SYSENTER instruction entry. * + * SYSENTER loads ss, rsp, cs, and rip from previously programmed MSRs. + * IF and VM in rflags are cleared (IOW: interrupts are off). + * SYSENTER does not save anything on the stack, + * and does not save old rip (!!!) and rflags. + * * Arguments: - * %eax System call number. - * %ebx Arg1 - * %ecx Arg2 - * %edx Arg3 - * %esi Arg4 - * %edi Arg5 - * %ebp user stack - * 0(%ebp) Arg6 - * - * Interrupts off. - * + * eax system call number + * ebx arg1 + * ecx arg2 + * edx arg3 + * esi arg4 + * edi arg5 + * ebp user stack + * 0(%ebp) arg6 + * * This is purely a fast path. For anything complicated we use the int 0x80 - * path below. Set up a complete hardware stack frame to share code + * path below. We set up a complete hardware stack frame to share code * with the int 0x80 path. - */ + */ ENTRY(ia32_sysenter_target) CFI_STARTPROC32 simple CFI_SIGNAL_FRAME @@ -128,6 +131,7 @@ ENTRY(ia32_sysenter_target) * disabled irqs, here we enable it straight after entry: */ ENABLE_INTERRUPTS(CLBR_NONE) + /* Construct iret frame (ss,rsp,rflags,cs,rip) */ movl %ebp,%ebp /* zero extension */ pushq_cfi $__USER32_DS /*CFI_REL_OFFSET ss,0*/ @@ -140,14 +144,19 @@ ENTRY(ia32_sysenter_target) pushq_cfi $__USER32_CS /*CFI_REL_OFFSET cs,0*/ movl %eax, %eax + /* Store thread_info->sysenter_return in rip stack slot */ pushq_cfi %r10 CFI_REL_OFFSET rip,0 + /* Store orig_ax */ pushq_cfi %rax + /* Construct the rest of "struct pt_regs" */ cld ALLOC_PT_GPREGS_ON_STACK SAVE_C_REGS_EXCEPT_R891011 - /* no need to do an access_ok check here because rbp has been - 32bit zero extended */ + /* + * no need to do an access_ok check here because rbp has been + * 32bit zero extended + */ ASM_STAC 1: movl (%rbp),%ebp _ASM_EXTABLE(1b,ia32_badarg) @@ -184,6 +193,7 @@ sysexit_from_sys_call: movl RIP(%rsp),%edx /* User %eip */ CFI_REGISTER rip,rdx RESTORE_RSI_RDI + /* pop everything except ss,rsp,rflags slots */ REMOVE_PT_GPREGS_FROM_STACK 3*8 xorq %r8,%r8 xorq %r9,%r9 @@ -194,6 +204,10 @@ sysexit_from_sys_call: popq_cfi %rcx /* User %esp */ CFI_REGISTER rsp,rcx TRACE_IRQS_ON + /* + * 32bit SYSEXIT restores eip from edx, esp from ecx. + * cs and ss are loaded from MSRs. + */ ENABLE_INTERRUPTS_SYSEXIT32 CFI_RESTORE_STATE @@ -274,23 +288,33 @@ ENDPROC(ia32_sysenter_target) /* * 32bit SYSCALL instruction entry. * + * 32bit SYSCALL saves rip to rcx, clears rflags.RF, then saves rflags to r11, + * then loads new ss, cs, and rip from previously programmed MSRs. + * rflags gets masked by a value from another MSR (so CLD and CLAC + * are not needed). SYSCALL does not save anything on the stack + * and does not change rsp. + * + * Note: rflags saving+masking-with-MSR happens only in Long mode + * (in legacy 32bit mode, IF, RF and VM bits are cleared and that's it). + * Don't get confused: rflags saving+masking depends on Long Mode Active bit + * (EFER.LMA=1), NOT on bitness of userspace where SYSCALL executes + * or target CS descriptor's L bit (SYSCALL does not read segment descriptors). + * * Arguments: - * %eax System call number. - * %ebx Arg1 - * %ecx return EIP - * %edx Arg3 - * %esi Arg4 - * %edi Arg5 - * %ebp Arg2 [note: not saved in the stack frame, should not be touched] - * %esp user stack - * 0(%esp) Arg6 - * - * Interrupts off. - * + * eax system call number + * ecx return address + * ebx arg1 + * ebp arg2 (note: not saved in the stack frame, should not be touched) + * edx arg3 + * esi arg4 + * edi arg5 + * esp user stack + * 0(%esp) arg6 + * * This is purely a fast path. For anything complicated we use the int 0x80 - * path below. Set up a complete hardware stack frame to share code - * with the int 0x80 path. - */ + * path below. We set up a complete hardware stack frame to share code + * with the int 0x80 path. + */ ENTRY(ia32_cstar_target) CFI_STARTPROC32 simple CFI_SIGNAL_FRAME @@ -306,7 +330,7 @@ ENTRY(ia32_cstar_target) * disabled irqs and here we enable it straight after entry: */ ENABLE_INTERRUPTS(CLBR_NONE) - ALLOC_PT_GPREGS_ON_STACK 8 + ALLOC_PT_GPREGS_ON_STACK 8 /* +8: space for orig_ax */ SAVE_C_REGS_EXCEPT_RCX_R891011 movl %eax,%eax /* zero extension */ movq %rax,ORIG_RAX(%rsp) @@ -320,9 +344,11 @@ ENTRY(ia32_cstar_target) /*CFI_REL_OFFSET rflags,EFLAGS*/ movq %r8,RSP(%rsp) CFI_REL_OFFSET rsp,RSP - /* no need to do an access_ok check here because r8 has been - 32bit zero extended */ - /* hardware stack frame is complete now */ + /* iret stack frame is complete now */ + /* + * no need to do an access_ok check here because r8 has been + * 32bit zero extended + */ ASM_STAC 1: movl (%r8),%r9d _ASM_EXTABLE(1b,ia32_badarg) @@ -355,8 +381,15 @@ sysretl_from_sys_call: TRACE_IRQS_ON movl RSP(%rsp),%esp CFI_RESTORE rsp + /* + * 64bit->32bit SYSRET restores eip from ecx, + * eflags from r11 (but RF and VM bits are forced to 0), + * cs and ss are loaded from MSRs. + * (Note: 32bit->32bit SYSRET is different: since r11 + * does not exist, it merely sets eflags.IF=1). + */ USERGS_SYSRET32 - + #ifdef CONFIG_AUDITSYSCALL cstar_auditsys: CFI_RESTORE_STATE @@ -394,26 +427,26 @@ ia32_badarg: jmp ia32_sysret CFI_ENDPROC -/* - * Emulated IA32 system calls via int 0x80. +/* + * Emulated IA32 system calls via int 0x80. * - * Arguments: - * %eax System call number. - * %ebx Arg1 - * %ecx Arg2 - * %edx Arg3 - * %esi Arg4 - * %edi Arg5 - * %ebp Arg6 [note: not saved in the stack frame, should not be touched] + * Arguments: + * eax system call number + * ebx arg1 + * ecx arg2 + * edx arg3 + * esi arg4 + * edi arg5 + * ebp arg6 (note: not saved in the stack frame, should not be touched) * * Notes: - * Uses the same stack frame as the x86-64 version. - * All registers except %eax must be saved (but ptrace may violate that) + * Uses the same stack frame as the x86-64 version. + * All registers except eax must be saved (but ptrace may violate that). * Arguments are zero extended. For system calls that want sign extension and * take long arguments a wrapper is needed. Most calls can just be called * directly. - * Assumes it is only called from user space and entered with interrupts off. - */ + * Assumes it is only called from user space and entered with interrupts off. + */ ENTRY(ia32_syscall) CFI_STARTPROC32 simple @@ -432,7 +465,7 @@ ENTRY(ia32_syscall) */ ENABLE_INTERRUPTS(CLBR_NONE) movl %eax,%eax - pushq_cfi %rax + pushq_cfi %rax /* store orig_ax */ cld /* note the registers are not zero extended to the sf. this could be a problem. */ diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index b0fbde1876e1..e5cbfbbf9479 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -256,25 +256,25 @@ ENTRY(ret_from_fork) END(ret_from_fork) /* - * System call entry. Up to 6 arguments in registers are supported. + * 64bit SYSCALL instruction entry. Up to 6 arguments in registers. * - * SYSCALL does not save anything on the stack and does not change the - * stack pointer. However, it does mask the flags register for us, so - * CLD and CLAC are not needed. - */ - -/* - * Register setup: + * 64bit SYSCALL saves rip to rcx, clears rflags.RF, then saves rflags to r11, + * then loads new ss, cs, and rip from previously programmed MSRs. + * rflags gets masked by a value from another MSR (so CLD and CLAC + * are not needed). SYSCALL does not save anything on the stack + * and does not change rsp. + * + * Registers on entry: * rax system call number + * rcx return address + * r11 saved rflags (note: r11 is callee-clobbered register in C ABI) * rdi arg0 - * rcx return address for syscall/sysret, C arg3 * rsi arg1 * rdx arg2 - * r10 arg3 (--> moved to rcx for C) + * r10 arg3 (needs to be moved to rcx to conform to C ABI) * r8 arg4 * r9 arg5 - * r11 eflags for syscall/sysret, temporary for C - * r12-r15,rbp,rbx saved by C code, not touched. + * (note: r12-r15,rbp,rbx are callee-preserved in C ABI) * * Interrupts are off on entry. * Only called from user space. @@ -302,13 +302,14 @@ ENTRY(system_call) GLOBAL(system_call_after_swapgs) movq %rsp,PER_CPU_VAR(old_rsp) + /* kernel_stack is set so that 5 slots (iret frame) are preallocated */ movq PER_CPU_VAR(kernel_stack),%rsp /* * No need to follow this irqs off/on section - it's straight * and short: */ ENABLE_INTERRUPTS(CLBR_NONE) - ALLOC_PT_GPREGS_ON_STACK 8 + ALLOC_PT_GPREGS_ON_STACK 8 /* +8: space for orig_ax */ SAVE_C_REGS_EXCEPT_RAX_RCX movq $-ENOSYS,RAX(%rsp) movq_cfi rax,ORIG_RAX @@ -348,6 +349,11 @@ ret_from_sys_call: CFI_REGISTER rip,rcx /*CFI_REGISTER rflags,r11*/ movq PER_CPU_VAR(old_rsp), %rsp + /* + * 64bit SYSRET restores rip from rcx, + * rflags from r11 (but RF and VM bits are forced to 0), + * cs and ss are loaded from MSRs. + */ USERGS_SYSRET64 CFI_RESTORE_STATE -- GitLab From 1eeb207f870f746a863e5c59321d837d2d91c218 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 26 Feb 2015 14:40:33 -0800 Subject: [PATCH 02700/11651] x86/asm/entry/64: Move 'save_paranoid' and 'ret_from_fork' closer to their users For some odd reason, these two functions are at the very top of the file. "save_paranoid"'s caller is approximately in the middle of it, move it there. Move 'ret_from_fork' to be right after fork/exec helpers. This is a pure block move, nothing is changed in the function bodies. Signed-off-by: Denys Vlasenko Signed-off-by: Andy Lutomirski Cc: Alexei Starovoitov Cc: Borislav Petkov Cc: Frederic Weisbecker Cc: H. Peter Anvin Cc: Kees Cook Cc: Linus Torvalds Cc: Oleg Nesterov Cc: Thomas Gleixner Cc: Will Drewry Link: http://lkml.kernel.org/r/6446bbfe4094532623a5b83779b7015fec167a9d.1424989793.git.luto@amacapital.net Signed-off-by: Ingo Molnar --- arch/x86/kernel/entry_64.S | 106 ++++++++++++++++++------------------- 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index e5cbfbbf9479..9e33d492ace3 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -202,59 +202,6 @@ ENDPROC(native_usergs_sysret64) CFI_REL_OFFSET r15, R15+\offset .endm -ENTRY(save_paranoid) - XCPT_FRAME 1 RDI+8 - cld - SAVE_C_REGS 8 - SAVE_EXTRA_REGS 8 - movl $1,%ebx - movl $MSR_GS_BASE,%ecx - rdmsr - testl %edx,%edx - js 1f /* negative -> in kernel */ - SWAPGS - xorl %ebx,%ebx -1: ret - CFI_ENDPROC -END(save_paranoid) - -/* - * A newly forked process directly context switches into this address. - * - * rdi: prev task we switched from - */ -ENTRY(ret_from_fork) - DEFAULT_FRAME - - LOCK ; btr $TIF_FORK,TI_flags(%r8) - - pushq_cfi $0x0002 - popfq_cfi # reset kernel eflags - - call schedule_tail # rdi: 'prev' task parameter - - GET_THREAD_INFO(%rcx) - - RESTORE_EXTRA_REGS - - testl $3,CS(%rsp) # from kernel_thread? - jz 1f - - testl $_TIF_IA32, TI_flags(%rcx) # 32-bit compat task needs IRET - jnz int_ret_from_sys_call - - RESTORE_TOP_OF_STACK %rdi - jmp ret_from_sys_call # go to the SYSRET fastpath - -1: - movq %rbp, %rdi - call *%rbx - movl $0, RAX(%rsp) - RESTORE_EXTRA_REGS - jmp int_ret_from_sys_call - CFI_ENDPROC -END(ret_from_fork) - /* * 64bit SYSCALL instruction entry. Up to 6 arguments in registers. * @@ -581,6 +528,43 @@ END(stub_x32_execveat) #endif +/* + * A newly forked process directly context switches into this address. + * + * rdi: prev task we switched from + */ +ENTRY(ret_from_fork) + DEFAULT_FRAME + + LOCK ; btr $TIF_FORK,TI_flags(%r8) + + pushq_cfi $0x0002 + popfq_cfi # reset kernel eflags + + call schedule_tail # rdi: 'prev' task parameter + + GET_THREAD_INFO(%rcx) + + RESTORE_EXTRA_REGS + + testl $3,CS(%rsp) # from kernel_thread? + jz 1f + + testl $_TIF_IA32, TI_flags(%rcx) # 32-bit compat task needs IRET + jnz int_ret_from_sys_call + + RESTORE_TOP_OF_STACK %rdi + jmp ret_from_sys_call # go to the SYSRET fastpath + +1: + movq %rbp, %rdi + call *%rbx + movl $0, RAX(%rsp) + RESTORE_EXTRA_REGS + jmp int_ret_from_sys_call + CFI_ENDPROC +END(ret_from_fork) + /* * Build the entry stubs and pointer table with some assembler magic. * We pack 7 stubs into a single 32-byte chunk, which will fit in a @@ -1273,6 +1257,22 @@ idtentry async_page_fault do_async_page_fault has_error_code=1 idtentry machine_check has_error_code=0 paranoid=1 do_sym=*machine_check_vector(%rip) #endif +ENTRY(save_paranoid) + XCPT_FRAME 1 RDI+8 + cld + SAVE_C_REGS 8 + SAVE_EXTRA_REGS 8 + movl $1,%ebx + movl $MSR_GS_BASE,%ecx + rdmsr + testl %edx,%edx + js 1f /* negative -> in kernel */ + SWAPGS + xorl %ebx,%ebx +1: ret + CFI_ENDPROC +END(save_paranoid) + /* * "Paranoid" exit path from exception stack. This is invoked * only on return from non-NMI IST interrupts that came -- GitLab From ebfc453e27c676e104378366a0b027e5c6918631 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 26 Feb 2015 14:40:34 -0800 Subject: [PATCH 02701/11651] x86/asm/entry/64: Clean up and document various entry code details This patch does a lot of cleanup in comments and formatting, but it does not change any code: - Rename 'save_paranoid' to 'paranoid_entry': this makes naming similar to its "non-paranoid" sibling, 'error_entry', and to its counterpart, 'paranoid_exit'. - Use the same CFI annotation atop 'paranoid_entry' and 'error_entry'. - Fix irregular indentation of assembler operands. - Add/fix comments on top of 'paranoid_entry' and 'error_entry'. - Remove stale comment about "oldrax". - Make comments about "no swapgs" flag in ebx more prominent. - Deindent wrongly indented top-level comment atop 'paranoid_exit'. - Indent wrongly deindented comment inside 'error_entry'. Signed-off-by: Denys Vlasenko Signed-off-by: Andy Lutomirski Cc: Alexei Starovoitov Cc: Borislav Petkov Cc: Frederic Weisbecker Cc: H. Peter Anvin Cc: Kees Cook Cc: Linus Torvalds Cc: Oleg Nesterov Cc: Will Drewry Link: http://lkml.kernel.org/r/4640f9fcd5ea46eb299b1cd6d3f5da3167d2f78d.1424989793.git.luto@amacapital.net Signed-off-by: Ingo Molnar --- arch/x86/kernel/entry_64.S | 68 ++++++++++++++++++++------------------ 1 file changed, 36 insertions(+), 32 deletions(-) diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index 9e33d492ace3..466947770648 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -982,10 +982,11 @@ ENTRY(\sym) testl $3, CS(%rsp) /* If coming from userspace, switch */ jnz 1f /* stacks. */ .endif - call save_paranoid + call paranoid_entry .else call error_entry .endif + /* returned flag: ebx=0: need swapgs on exit, ebx=1: don't need it */ DEFAULT_FRAME 0 @@ -1016,10 +1017,11 @@ ENTRY(\sym) addq $EXCEPTION_STKSZ, INIT_TSS_IST(\shift_ist) .endif + /* these procedures expect "no swapgs" flag in ebx */ .if \paranoid - jmp paranoid_exit /* %ebx: no swapgs flag */ + jmp paranoid_exit .else - jmp error_exit /* %ebx: no swapgs flag */ + jmp error_exit .endif .if \paranoid == 1 @@ -1257,8 +1259,13 @@ idtentry async_page_fault do_async_page_fault has_error_code=1 idtentry machine_check has_error_code=0 paranoid=1 do_sym=*machine_check_vector(%rip) #endif -ENTRY(save_paranoid) - XCPT_FRAME 1 RDI+8 +/* + * Save all registers in pt_regs, and switch gs if needed. + * Use slow, but surefire "are we in kernel?" check. + * Return: ebx=0: need swapgs on exit, ebx=1: otherwise + */ +ENTRY(paranoid_entry) + XCPT_FRAME 1 15*8 cld SAVE_C_REGS 8 SAVE_EXTRA_REGS 8 @@ -1271,20 +1278,19 @@ ENTRY(save_paranoid) xorl %ebx,%ebx 1: ret CFI_ENDPROC -END(save_paranoid) - - /* - * "Paranoid" exit path from exception stack. This is invoked - * only on return from non-NMI IST interrupts that came - * from kernel space. - * - * We may be returning to very strange contexts (e.g. very early - * in syscall entry), so checking for preemption here would - * be complicated. Fortunately, we there's no good reason - * to try to handle preemption here. - */ +END(paranoid_entry) - /* ebx: no swapgs flag */ +/* + * "Paranoid" exit path from exception stack. This is invoked + * only on return from non-NMI IST interrupts that came + * from kernel space. + * + * We may be returning to very strange contexts (e.g. very early + * in syscall entry), so checking for preemption here would + * be complicated. Fortunately, we there's no good reason + * to try to handle preemption here. + */ +/* On entry, ebx is "no swapgs" flag (1: don't need swapgs, 0: need it) */ ENTRY(paranoid_exit) DEFAULT_FRAME DISABLE_INTERRUPTS(CLBR_NONE) @@ -1305,13 +1311,11 @@ paranoid_exit_restore: END(paranoid_exit) /* - * Exception entry point. This expects an error code/orig_rax on the stack. - * returns in "no swapgs flag" in %ebx. + * Save all registers in pt_regs, and switch gs if needed. + * Return: ebx=0: need swapgs on exit, ebx=1: otherwise */ ENTRY(error_entry) - XCPT_FRAME - CFI_ADJUST_CFA_OFFSET 15*8 - /* oldrax contains error code */ + XCPT_FRAME 1 15*8 cld SAVE_C_REGS 8 SAVE_EXTRA_REGS 8 @@ -1324,12 +1328,12 @@ error_sti: TRACE_IRQS_OFF ret -/* - * There are two places in the kernel that can potentially fault with - * usergs. Handle them here. B stepping K8s sometimes report a - * truncated RIP for IRET exceptions returning to compat mode. Check - * for these here too. - */ + /* + * There are two places in the kernel that can potentially fault with + * usergs. Handle them here. B stepping K8s sometimes report a + * truncated RIP for IRET exceptions returning to compat mode. Check + * for these here too. + */ error_kernelspace: CFI_REL_OFFSET rcx, RCX+8 incl %ebx @@ -1359,7 +1363,7 @@ error_bad_iret: END(error_entry) -/* ebx: no swapgs flag (1: don't need swapgs, 0: need it) */ +/* On entry, ebx is "no swapgs" flag (1: don't need swapgs, 0: need it) */ ENTRY(error_exit) DEFAULT_FRAME movl %ebx,%eax @@ -1585,13 +1589,13 @@ end_repeat_nmi: ALLOC_PT_GPREGS_ON_STACK /* - * Use save_paranoid to handle SWAPGS, but no need to use paranoid_exit + * Use paranoid_entry to handle SWAPGS, but no need to use paranoid_exit * as we should not be calling schedule in NMI context. * Even with normal interrupts enabled. An NMI should not be * setting NEED_RESCHED or anything that normal interrupts and * exceptions might do. */ - call save_paranoid + call paranoid_entry DEFAULT_FRAME 0 /* -- GitLab From 14f6e9532dda399a7b789f744dc045f8865a9e42 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 26 Feb 2015 14:40:35 -0800 Subject: [PATCH 02702/11651] x86/asm/entry/64/compat: Fold the IA32_ARG_FIXUP macro into its callers Use of a small macro - one with conditional expansion - does more harm than good. It obfuscates code, with minimal code reuse. For example, because of obfuscation it's not obvious that in 'ia32_sysenter_target', we can optimize loading of r9 - currently it is loaded with a detour through ebp. This patch folds the IA32_ARG_FIXUP macro into its callers. No code changes. Signed-off-by: Denys Vlasenko Signed-off-by: Andy Lutomirski Cc: Alexei Starovoitov Cc: Borislav Petkov Cc: Frederic Weisbecker Cc: H. Peter Anvin Cc: Kees Cook Cc: Linus Torvalds Cc: Oleg Nesterov Cc: Will Drewry Link: http://lkml.kernel.org/r/4da092094cd78734384ac31e0d4ec1d8f69145a2.1424989793.git.luto@amacapital.net Signed-off-by: Ingo Molnar --- arch/x86/ia32/ia32entry.S | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S index b5670564a1fb..6dcd37256979 100644 --- a/arch/x86/ia32/ia32entry.S +++ b/arch/x86/ia32/ia32entry.S @@ -30,17 +30,6 @@ .section .entry.text, "ax" - .macro IA32_ARG_FIXUP noebp=0 - movl %edi,%r8d - .if \noebp - .else - movl %ebp,%r9d - .endif - xchg %ecx,%esi - movl %ebx,%edi - movl %edx,%edx /* zero extension */ - .endm - /* clobbers %rax */ .macro CLEAR_RREGS _r9=rax xorl %eax,%eax @@ -178,7 +167,12 @@ sysenter_flags_fixed: cmpq $(IA32_NR_syscalls-1),%rax ja ia32_badsys sysenter_do_call: - IA32_ARG_FIXUP + /* 32bit syscall -> 64bit C ABI argument conversion */ + movl %edi,%r8d /* arg5 */ + movl %ebp,%r9d /* arg6 */ + xchg %ecx,%esi /* rsi:arg2, rcx:arg4 */ + movl %ebx,%edi /* arg1 */ + movl %edx,%edx /* arg3 (zero extension) */ sysenter_dispatch: call *ia32_sys_call_table(,%rax,8) movq %rax,RAX(%rsp) @@ -360,7 +354,12 @@ ENTRY(ia32_cstar_target) cmpq $IA32_NR_syscalls-1,%rax ja ia32_badsys cstar_do_call: - IA32_ARG_FIXUP 1 + /* 32bit syscall -> 64bit C ABI argument conversion */ + movl %edi,%r8d /* arg5 */ + /* r9 already loaded */ /* arg6 */ + xchg %ecx,%esi /* rsi:arg2, rcx:arg4 */ + movl %ebx,%edi /* arg1 */ + movl %edx,%edx /* arg3 (zero extension) */ cstar_dispatch: call *ia32_sys_call_table(,%rax,8) movq %rax,RAX(%rsp) @@ -477,7 +476,12 @@ ENTRY(ia32_syscall) cmpq $(IA32_NR_syscalls-1),%rax ja ia32_badsys ia32_do_call: - IA32_ARG_FIXUP + /* 32bit syscall -> 64bit C ABI argument conversion */ + movl %edi,%r8d /* arg5 */ + movl %ebp,%r9d /* arg6 */ + xchg %ecx,%esi /* rsi:arg2, rcx:arg4 */ + movl %ebx,%edi /* arg1 */ + movl %edx,%edx /* arg3 (zero extension) */ call *ia32_sys_call_table(,%rax,8) # xxx: rip relative ia32_sysret: movq %rax,RAX(%rsp) -- GitLab From 911d2bb5ccaab102abbab2bb58438c75bc342ca9 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 26 Feb 2015 14:40:36 -0800 Subject: [PATCH 02703/11651] x86/asm/entry/64: Use more readable constants Constants such as SS+8 or SS+8-RIP are mysterious. In most cases, SS+8 is just meant to be SIZEOF_PTREGS, SS+8-RIP is RIP's offset in the iret frame. This patch changes some of these constants to be less mysterious. No code changes (verified with objdump). Signed-off-by: Denys Vlasenko Signed-off-by: Andy Lutomirski Cc: Alexei Starovoitov Cc: Borislav Petkov Cc: Frederic Weisbecker Cc: H. Peter Anvin Cc: Kees Cook Cc: Linus Torvalds Cc: Oleg Nesterov Cc: Thomas Gleixner Cc: Will Drewry Link: http://lkml.kernel.org/r/1d20491384773bd606e23a382fac23ddb49b5178.1424989793.git.luto@amacapital.net Signed-off-by: Ingo Molnar --- arch/x86/include/asm/calling.h | 2 ++ arch/x86/kernel/entry_64.S | 28 ++++++++++++++++------------ 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/arch/x86/include/asm/calling.h b/arch/x86/include/asm/calling.h index 4a7ceb9789a5..337423590b08 100644 --- a/arch/x86/include/asm/calling.h +++ b/arch/x86/include/asm/calling.h @@ -88,6 +88,8 @@ For 32-bit we have the following conventions - kernel is built with #define RSP 19*8 #define SS 20*8 +#define SIZEOF_PTREGS 21*8 + .macro ALLOC_PT_GPREGS_ON_STACK addskip=0 subq $15*8+\addskip, %rsp CFI_ADJUST_CFA_OFFSET 15*8+\addskip diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index 466947770648..858e94e86f5e 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -164,12 +164,12 @@ ENDPROC(native_usergs_sysret64) * initial frame state for interrupts (and exceptions without error code) */ .macro INTR_FRAME start=1 offset=0 - EMPTY_FRAME \start, SS+8+\offset-RIP - /*CFI_REL_OFFSET ss, SS+\offset-RIP*/ - CFI_REL_OFFSET rsp, RSP+\offset-RIP - /*CFI_REL_OFFSET rflags, EFLAGS+\offset-RIP*/ - /*CFI_REL_OFFSET cs, CS+\offset-RIP*/ - CFI_REL_OFFSET rip, RIP+\offset-RIP + EMPTY_FRAME \start, 5*8+\offset + /*CFI_REL_OFFSET ss, 4*8+\offset*/ + CFI_REL_OFFSET rsp, 3*8+\offset + /*CFI_REL_OFFSET rflags, 2*8+\offset*/ + /*CFI_REL_OFFSET cs, 1*8+\offset*/ + CFI_REL_OFFSET rip, 0*8+\offset .endm /* @@ -177,7 +177,7 @@ ENDPROC(native_usergs_sysret64) * with vector already pushed) */ .macro XCPT_FRAME start=1 offset=0 - INTR_FRAME \start, RIP+\offset-ORIG_RAX + INTR_FRAME \start, 1*8+\offset .endm /* @@ -645,10 +645,14 @@ END(interrupt) cmovzq PER_CPU_VAR(irq_stack_ptr),%rsp CFI_DEF_CFA_REGISTER rsi pushq %rsi + /* + * For debugger: + * "CFA (Current Frame Address) is the value on stack + offset" + */ CFI_ESCAPE 0x0f /* DW_CFA_def_cfa_expression */, 6, \ - 0x77 /* DW_OP_breg7 */, 0, \ + 0x77 /* DW_OP_breg7 (rsp) */, 0, \ 0x06 /* DW_OP_deref */, \ - 0x08 /* DW_OP_const1u */, SS+8-RBP, \ + 0x08 /* DW_OP_const1u */, SIZEOF_PTREGS-RBP, \ 0x22 /* DW_OP_plus */ /* We entered an interrupt context - irqs are off: */ TRACE_IRQS_OFF @@ -674,7 +678,7 @@ ret_from_intr: /* Restore saved previous stack */ popq %rsi - CFI_DEF_CFA rsi,SS+8-RBP /* reg/off reset after def_cfa_expr */ + CFI_DEF_CFA rsi,SIZEOF_PTREGS-RBP /* reg/off reset after def_cfa_expr */ /* return code expects complete pt_regs - adjust rsp accordingly: */ leaq -RBP(%rsi),%rsp CFI_DEF_CFA_REGISTER rsp @@ -1549,7 +1553,7 @@ first_nmi: .rept 5 pushq_cfi 11*8(%rsp) .endr - CFI_DEF_CFA_OFFSET SS+8-RIP + CFI_DEF_CFA_OFFSET 5*8 /* Everything up to here is safe from nested NMIs */ @@ -1577,7 +1581,7 @@ repeat_nmi: pushq_cfi -6*8(%rsp) .endr subq $(5*8), %rsp - CFI_DEF_CFA_OFFSET SS+8-RIP + CFI_DEF_CFA_OFFSET 5*8 end_repeat_nmi: /* -- GitLab From b3ab90b333e94659e7c351843ab41ec0004f73e8 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 26 Feb 2015 14:40:37 -0800 Subject: [PATCH 02704/11651] x86/asm/entry/64/compat: Use more readable constant The last instance of "mysterious" SS+8 constant is replaced by SIZEOF_PTREGS. Message-Id: <1424822419-10267-1-git-send-email-dvlasenk@redhat.com> Signed-off-by: Denys Vlasenko Signed-off-by: Andy Lutomirski Cc: Alexei Starovoitov Cc: Borislav Petkov Cc: Frederic Weisbecker Cc: H. Peter Anvin Cc: Kees Cook Cc: Linus Torvalds Cc: Oleg Nesterov Cc: Steven Rostedt Cc: Will Drewry Link: http://lkml.kernel.org/r/d35aeba3059407ac54f472ddcfbea767ff8916ac.1424989793.git.luto@amacapital.net Signed-off-by: Ingo Molnar --- arch/x86/ia32/ia32entry.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S index 6dcd37256979..ed9746340363 100644 --- a/arch/x86/ia32/ia32entry.S +++ b/arch/x86/ia32/ia32entry.S @@ -536,7 +536,7 @@ ia32_ptregs_common: CFI_ENDPROC CFI_STARTPROC32 simple CFI_SIGNAL_FRAME - CFI_DEF_CFA rsp,SS+8 + CFI_DEF_CFA rsp,SIZEOF_PTREGS CFI_REL_OFFSET rax,RAX CFI_REL_OFFSET rcx,RCX CFI_REL_OFFSET rdx,RDX -- GitLab From d441c1f2b73ec742c2e55be804ebc6fee130c77f Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 26 Feb 2015 14:40:38 -0800 Subject: [PATCH 02705/11651] x86/asm/entry/64: Simplify optimistic SYSRET Avoid redundant load of %r11 (it is already loaded a few instructions before). Also simplify %rsp restoration, instead of two steps: add $0x80, %rsp mov 0x18(%rsp), %rsp we can do a simplified single step to restore user-space RSP: mov 0x98(%rsp), %rsp and get the same result. Signed-off-by: Denys Vlasenko Signed-off-by: Andy Lutomirski [ Clarified the changelog. ] Cc: Alexei Starovoitov Cc: Borislav Petkov Cc: Frederic Weisbecker Cc: H. Peter Anvin Cc: Kees Cook Cc: Linus Torvalds Cc: Oleg Nesterov Cc: Steven Rostedt Cc: Thomas Gleixner Cc: Will Drewry Link: http://lkml.kernel.org/r/1aef69b346a6db0d99cdfb0f5ba83e8c985e27d7.1424989793.git.luto@amacapital.net Signed-off-by: Ingo Molnar --- arch/x86/include/asm/calling.h | 3 +++ arch/x86/kernel/entry_64.S | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/arch/x86/include/asm/calling.h b/arch/x86/include/asm/calling.h index 337423590b08..f1a962ff7ddf 100644 --- a/arch/x86/include/asm/calling.h +++ b/arch/x86/include/asm/calling.h @@ -176,6 +176,9 @@ For 32-bit we have the following conventions - kernel is built with .macro RESTORE_C_REGS_EXCEPT_RCX RESTORE_C_REGS_HELPER 1,0,1,1,1 .endm + .macro RESTORE_C_REGS_EXCEPT_R11 + RESTORE_C_REGS_HELPER 1,1,0,1,1 + .endm .macro RESTORE_RSI_RDI RESTORE_C_REGS_HELPER 0,0,0,0,0 .endm diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index 858e94e86f5e..bc1527889c40 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -757,9 +757,9 @@ retint_swapgs: /* return to user-space */ */ irq_return_via_sysret: CFI_REMEMBER_STATE - RESTORE_C_REGS - REMOVE_PT_GPREGS_FROM_STACK 8 - movq (RSP-RIP)(%rsp),%rsp + /* r11 is already restored (see code above) */ + RESTORE_C_REGS_EXCEPT_R11 + movq RSP(%rsp),%rsp USERGS_SYSRET64 CFI_RESTORE_STATE -- GitLab From 1e3fbb8a1d814f35e2e689cf87714d38d9f3564d Mon Sep 17 00:00:00 2001 From: Andy Lutomirski Date: Thu, 26 Feb 2015 14:40:39 -0800 Subject: [PATCH 02706/11651] x86/asm/entry/64: Remove a bogus 'ret_from_fork' optimization 'ret_from_fork' checks TIF_IA32 to determine whether 'pt_regs' and the related state make sense for 'ret_from_sys_call'. This is entirely the wrong check. TS_COMPAT would make a little more sense, but there's really no point in keeping this optimization at all. This fixes a return to the wrong user CS if we came from int 0x80 in a 64-bit task. Signed-off-by: Andy Lutomirski Cc: Borislav Petkov Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Oleg Nesterov Cc: Thomas Gleixner Link: http://lkml.kernel.org/r/4710be56d76ef994ddf59087aad98c000fbab9a4.1424989793.git.luto@amacapital.net Signed-off-by: Ingo Molnar --- arch/x86/kernel/entry_64.S | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index bc1527889c40..622ce4254893 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -550,11 +550,14 @@ ENTRY(ret_from_fork) testl $3,CS(%rsp) # from kernel_thread? jz 1f - testl $_TIF_IA32, TI_flags(%rcx) # 32-bit compat task needs IRET - jnz int_ret_from_sys_call - - RESTORE_TOP_OF_STACK %rdi - jmp ret_from_sys_call # go to the SYSRET fastpath + /* + * By the time we get here, we have no idea whether our pt_regs, + * ti flags, and ti status came from the 64-bit SYSCALL fast path, + * the slow path, or one of the ia32entry paths. + * Use int_ret_from_sys_call to return, since it can safely handle + * all of the above. + */ + jmp int_ret_from_sys_call 1: movq %rbp, %rdi -- GitLab From f3dddf2432e3123ef34b470129295641f7513d26 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 4 Mar 2015 14:10:26 -0800 Subject: [PATCH 02707/11651] HID: map telephony usage page Currently HID code maps usages from telephony page into BTN_0, BTN_1, etc keys which get interpreted by mousedev and userspace as left/right/middle button clicks, which is not really helpful. This change adds mappings for usages that have corresponding input event definitions, and leaves the rest unmapped. This can be changed when there are userspace consumers for more telephony usages. Signed-off-by: Dmitry Torokhov Signed-off-by: Jiri Kosina --- drivers/hid/hid-input.c | 23 +++++++++++++++++++++++ include/linux/hid.h | 1 + include/uapi/linux/input.h | 4 ++++ 3 files changed, 28 insertions(+) diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 052869d0ab78..19603efc8fa2 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -711,6 +711,29 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel } break; + case HID_UP_TELEPHONY: + switch (usage->hid & HID_USAGE) { + case 0x2f: map_key_clear(KEY_MICMUTE); break; + case 0xb0: map_key_clear(KEY_NUMERIC_0); break; + case 0xb1: map_key_clear(KEY_NUMERIC_1); break; + case 0xb2: map_key_clear(KEY_NUMERIC_2); break; + case 0xb3: map_key_clear(KEY_NUMERIC_3); break; + case 0xb4: map_key_clear(KEY_NUMERIC_4); break; + case 0xb5: map_key_clear(KEY_NUMERIC_5); break; + case 0xb6: map_key_clear(KEY_NUMERIC_6); break; + case 0xb7: map_key_clear(KEY_NUMERIC_7); break; + case 0xb8: map_key_clear(KEY_NUMERIC_8); break; + case 0xb9: map_key_clear(KEY_NUMERIC_9); break; + case 0xba: map_key_clear(KEY_NUMERIC_STAR); break; + case 0xbb: map_key_clear(KEY_NUMERIC_POUND); break; + case 0xbc: map_key_clear(KEY_NUMERIC_A); break; + case 0xbd: map_key_clear(KEY_NUMERIC_B); break; + case 0xbe: map_key_clear(KEY_NUMERIC_C); break; + case 0xbf: map_key_clear(KEY_NUMERIC_D); break; + default: goto ignore; + } + break; + case HID_UP_CONSUMER: /* USB HUT v1.12, pages 75-84 */ switch (usage->hid & HID_USAGE) { case 0x000: goto ignore; diff --git a/include/linux/hid.h b/include/linux/hid.h index efc7787a41a8..69f9cf7f078d 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -159,6 +159,7 @@ struct hid_item { #define HID_UP_LED 0x00080000 #define HID_UP_BUTTON 0x00090000 #define HID_UP_ORDINAL 0x000a0000 +#define HID_UP_TELEPHONY 0x000b0000 #define HID_UP_CONSUMER 0x000c0000 #define HID_UP_DIGITIZER 0x000d0000 #define HID_UP_PID 0x000f0000 diff --git a/include/uapi/linux/input.h b/include/uapi/linux/input.h index b0a813079852..2b628c316882 100644 --- a/include/uapi/linux/input.h +++ b/include/uapi/linux/input.h @@ -702,6 +702,10 @@ struct input_keymap_entry { #define KEY_NUMERIC_9 0x209 #define KEY_NUMERIC_STAR 0x20a #define KEY_NUMERIC_POUND 0x20b +#define KEY_NUMERIC_A 0x20c /* Phone key A - HUT Telephony 0xb9 */ +#define KEY_NUMERIC_B 0x20d +#define KEY_NUMERIC_C 0x20e +#define KEY_NUMERIC_D 0x20f #define KEY_CAMERA_FOCUS 0x210 #define KEY_WPS_BUTTON 0x211 /* WiFi Protected Setup key */ -- GitLab From 0164bf0239777811bdc3e01f45501174dc6db19d Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Wed, 4 Mar 2015 17:34:32 -0500 Subject: [PATCH 02708/11651] locks: fix fasync_struct memory leak in lease upgrade/downgrade handling Commit 8634b51f6ca2 (locks: convert lease handling to file_lock_context) introduced a regression in the handling of lease upgrade/downgrades. In the event that we already have a lease on a file and are going to either upgrade or downgrade it, we skip doing any list insertion or deletion and simply re-call lm_setup on the existing lease. As of commit 8634b51f6ca2 however, we end up calling lm_setup on the lease that was passed in, instead of on the existing lease. This causes us to leak the fasync_struct that was allocated in the event that there was not already an existing one (as it always appeared that there wasn't one). Fixes: 8634b51f6ca2 (locks: convert lease handling to file_lock_context) Reported-and-Tested-by: Daniel Wagner Signed-off-by: Jeff Layton --- fs/locks.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/locks.c b/fs/locks.c index 365c82e1b3a9..f1bad681fc1c 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -1665,7 +1665,8 @@ generic_add_lease(struct file *filp, long arg, struct file_lock **flp, void **pr } if (my_fl != NULL) { - error = lease->fl_lmops->lm_change(my_fl, arg, &dispose); + lease = my_fl; + error = lease->fl_lmops->lm_change(lease, arg, &dispose); if (error) goto out; goto out_setup; -- GitLab From afc1ad7e55c8944eb3cac8f922d809d4b40c7172 Mon Sep 17 00:00:00 2001 From: Tyler Baker Date: Tue, 10 Feb 2015 19:52:28 -0800 Subject: [PATCH 02709/11651] ARM: sunxi_defconfig: increase the number of maximum number of CPUs to 8 The a80 optimus has 8 CPUs. I propose we increase the maximum number of CPUs to 8 to avoid the following warning identified during automated boot testing [1]. ------------[ cut here ]------------ WARNING: CPU: 0 PID: 0 at ../arch/arm/kernel/devtree.c:144 arm_dt_init_cpu_maps+0x110/0x1e0() DT /cpu 5 nodes greater than max cores 4, capping them CPU: 0 PID: 0 Comm: swapper Not tainted 3.19.0-00528-gbdccc4edeb03 #1 Hardware name: Allwinner sun9i Family [] (unwind_backtrace) from [] (show_stack+0x10/0x14) [] (show_stack) from [] (dump_stack+0x74/0x90) [] (dump_stack) from [] (warn_slowpath_common+0x70/0xac) [] (warn_slowpath_common) from [] (warn_slowpath_fmt+0x30/0x40) [] (warn_slowpath_fmt) from [] (arm_dt_init_cpu_maps+0x110/0x1e0) [] (arm_dt_init_cpu_maps) from [] (setup_arch+0x634/0x8d4) [] (setup_arch) from [] (start_kernel+0x88/0x3ac) [] (start_kernel) from [<20008074>] (0x20008074) ---[ end trace cb88537fdc8fa200 ]--- [1] http://storage.kernelci.org/mainline/v3.19-528-gbdccc4edeb03/arm-sunxi_defconfig/lab-tbaker/boot-sun9i-a80-optimus.html Cc: Maxime Ripard Cc: Olof Johansson Cc: Kevin Hilman Cc: Arnd Bergmann Signed-off-by: Tyler Baker Signed-off-by: Arnd Bergmann --- arch/arm/configs/sunxi_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/configs/sunxi_defconfig b/arch/arm/configs/sunxi_defconfig index 38840a812924..8f6a5702b696 100644 --- a/arch/arm/configs/sunxi_defconfig +++ b/arch/arm/configs/sunxi_defconfig @@ -4,6 +4,7 @@ CONFIG_BLK_DEV_INITRD=y CONFIG_PERF_EVENTS=y CONFIG_ARCH_SUNXI=y CONFIG_SMP=y +CONFIG_NR_CPUS=8 CONFIG_AEABI=y CONFIG_HIGHMEM=y CONFIG_HIGHPTE=y -- GitLab From b09e0ec4ddcb951c1c377ab114db5610eb7f3c98 Mon Sep 17 00:00:00 2001 From: Tyler Baker Date: Tue, 10 Feb 2015 19:52:27 -0800 Subject: [PATCH 02710/11651] ARM: multi_v7_defconfig: increase the number of maximum number of CPUs to 16 The HiSilicon HiP04 has 16 CPUs. I propose we increase the maximum number of CPUs to 16 to avoid the following warning identified during automated boot testing [1]. ------------[ cut here ]------------ WARNING: CPU: 0 PID: 0 at ../arch/arm/kernel/devtree.c:144 arm_dt_init_cpu_maps+0x118/0x1e8() DT /cpu 9 nodes greater than max cores 8, capping them Modules linked in: CPU: 0 PID: 0 Comm: swapper Not tainted 3.19.0-00528-gbdccc4edeb03 #1 Hardware name: Hisilicon HiP04 (Flattened Device Tree) [] (unwind_backtrace) from [] (show_stack+0x10/0x14) [] (show_stack) from [] (dump_stack+0x78/0x94) [] (dump_stack) from [] (warn_slowpath_common+0x74/0xb0) [] (warn_slowpath_common) from [] (warn_slowpath_fmt+0x30/0x40) [] (warn_slowpath_fmt) from [] (arm_dt_init_cpu_maps+0x118/0x1e8) [] (arm_dt_init_cpu_maps) from [] (setup_arch+0x638/0x9a0) [] (setup_arch) from [] (start_kernel+0x8c/0x3b4) [] (start_kernel) from [<10208074>] (0x10208074) ---[ end trace cb88537fdc8fa200 ]--- [1] http://storage.kernelci.org/mainline/v3.19-528-gbdccc4edeb03/arm-multi_v7_defconfig/lab-tbaker/boot-hip04-d01.html Cc: Olof Johansson Cc: Kevin Hilman Cc: Arnd Bergmann Signed-off-by: Tyler Baker Signed-off-by: Arnd Bergmann --- arch/arm/configs/multi_v7_defconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig index b7e6b6fba5e0..06075b6d2463 100644 --- a/arch/arm/configs/multi_v7_defconfig +++ b/arch/arm/configs/multi_v7_defconfig @@ -99,7 +99,7 @@ CONFIG_PCI_RCAR_GEN2=y CONFIG_PCI_RCAR_GEN2_PCIE=y CONFIG_PCIEPORTBUS=y CONFIG_SMP=y -CONFIG_NR_CPUS=8 +CONFIG_NR_CPUS=16 CONFIG_HIGHPTE=y CONFIG_CMA=y CONFIG_ARM_APPENDED_DTB=y -- GitLab From 66c9270b6898de629ab2a7428e56993800ea9a6c Mon Sep 17 00:00:00 2001 From: Daniel Tang Date: Mon, 9 Feb 2015 19:41:57 +1100 Subject: [PATCH 02711/11651] devicetree: Add TI-NSPIRE USB OTG support to device tree Signed-off-by: Daniel Tang Signed-off-by: Arnd Bergmann --- arch/arm/boot/dts/nspire-classic.dtsi | 5 +++++ arch/arm/boot/dts/nspire-cx.dts | 4 ++++ arch/arm/boot/dts/nspire.dtsi | 21 +++++++++++++++++++++ 3 files changed, 30 insertions(+) diff --git a/arch/arm/boot/dts/nspire-classic.dtsi b/arch/arm/boot/dts/nspire-classic.dtsi index 9565199bce7a..4907c5085d4b 100644 --- a/arch/arm/boot/dts/nspire-classic.dtsi +++ b/arch/arm/boot/dts/nspire-classic.dtsi @@ -51,6 +51,11 @@ compatible = "lsi,nspire-classic-ahb-divider"; }; + +&vbus_reg { + gpio = <&gpio 5 0>; +}; + / { memory { device_type = "memory"; diff --git a/arch/arm/boot/dts/nspire-cx.dts b/arch/arm/boot/dts/nspire-cx.dts index 375b924f60d8..08e0b81b3385 100644 --- a/arch/arm/boot/dts/nspire-cx.dts +++ b/arch/arm/boot/dts/nspire-cx.dts @@ -69,6 +69,10 @@ 0x0709001d 0x070a0033 >; }; +&vbus_reg { + gpio = <&gpio 2 0>; +}; + / { model = "TI-NSPIRE CX"; compatible = "ti,nspire-cx"; diff --git a/arch/arm/boot/dts/nspire.dtsi b/arch/arm/boot/dts/nspire.dtsi index a22ffe633b49..390c91aea16d 100644 --- a/arch/arm/boot/dts/nspire.dtsi +++ b/arch/arm/boot/dts/nspire.dtsi @@ -54,6 +54,20 @@ clocks = <&ahb_clk>; }; + usb_phy: usb_phy { + compatible = "usb-nop-xceiv"; + }; + + vbus_reg: vbus_reg { + compatible = "regulator-fixed"; + + regulator-name = "USB VBUS output"; + regulator-type = "voltage"; + + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; + ahb { compatible = "simple-bus"; #address-cells = <1>; @@ -65,8 +79,12 @@ }; usb0: usb@B0000000 { + compatible = "lsi,zevio-usb"; reg = <0xB0000000 0x1000>; interrupts = <8>; + + usb-phy = <&usb_phy>; + vbus-supply = <&vbus_reg>; }; usb1: usb@B4000000 { @@ -105,8 +123,11 @@ ranges; gpio: gpio@90000000 { + compatible = "lsi,zevio-gpio"; reg = <0x90000000 0x1000>; interrupts = <7>; + gpio-controller; + #gpio-cells = <2>; }; fast_timer: timer@90010000 { -- GitLab From 440fd5283a87345cdd4237bdf45fb01130ea0056 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Fri, 23 Jan 2015 09:05:06 +0100 Subject: [PATCH 02712/11651] drm/mm: Support 4 GiB and larger ranges The current implementation is limited by the number of addresses that fit into an unsigned long. This causes problems on 32-bit Tegra where unsigned long is 32-bit but drm_mm is used to manage an IOVA space of 4 GiB. Given the 32-bit limitation, the range is limited to 4 GiB - 1 (or 4 GiB - 4 KiB for page granularity). This commit changes the start and size of the range to be an unsigned 64-bit integer, thus allowing much larger ranges to be supported. [airlied: fix i915 warnings and coloring callback] Signed-off-by: Thierry Reding Reviewed-by: Alex Deucher Reviewed-by: Chris Wilson Signed-off-by: Dave Airlie fixupo --- drivers/gpu/drm/drm_mm.c | 152 +++++++++++++++------------- drivers/gpu/drm/i915/i915_debugfs.c | 4 +- drivers/gpu/drm/i915/i915_gem_gtt.c | 6 +- include/drm/drm_mm.h | 52 +++++----- 4 files changed, 110 insertions(+), 104 deletions(-) diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index 04a209e2b66d..7fc6f8bd4821 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c @@ -91,29 +91,29 @@ */ static struct drm_mm_node *drm_mm_search_free_generic(const struct drm_mm *mm, - unsigned long size, + u64 size, unsigned alignment, unsigned long color, enum drm_mm_search_flags flags); static struct drm_mm_node *drm_mm_search_free_in_range_generic(const struct drm_mm *mm, - unsigned long size, + u64 size, unsigned alignment, unsigned long color, - unsigned long start, - unsigned long end, + u64 start, + u64 end, enum drm_mm_search_flags flags); static void drm_mm_insert_helper(struct drm_mm_node *hole_node, struct drm_mm_node *node, - unsigned long size, unsigned alignment, + u64 size, unsigned alignment, unsigned long color, enum drm_mm_allocator_flags flags) { struct drm_mm *mm = hole_node->mm; - unsigned long hole_start = drm_mm_hole_node_start(hole_node); - unsigned long hole_end = drm_mm_hole_node_end(hole_node); - unsigned long adj_start = hole_start; - unsigned long adj_end = hole_end; + u64 hole_start = drm_mm_hole_node_start(hole_node); + u64 hole_end = drm_mm_hole_node_end(hole_node); + u64 adj_start = hole_start; + u64 adj_end = hole_end; BUG_ON(node->allocated); @@ -124,12 +124,15 @@ static void drm_mm_insert_helper(struct drm_mm_node *hole_node, adj_start = adj_end - size; if (alignment) { - unsigned tmp = adj_start % alignment; - if (tmp) { + u64 tmp = adj_start; + unsigned rem; + + rem = do_div(tmp, alignment); + if (rem) { if (flags & DRM_MM_CREATE_TOP) - adj_start -= tmp; + adj_start -= rem; else - adj_start += alignment - tmp; + adj_start += alignment - rem; } } @@ -176,9 +179,9 @@ static void drm_mm_insert_helper(struct drm_mm_node *hole_node, int drm_mm_reserve_node(struct drm_mm *mm, struct drm_mm_node *node) { struct drm_mm_node *hole; - unsigned long end = node->start + node->size; - unsigned long hole_start; - unsigned long hole_end; + u64 end = node->start + node->size; + u64 hole_start; + u64 hole_end; BUG_ON(node == NULL); @@ -227,7 +230,7 @@ EXPORT_SYMBOL(drm_mm_reserve_node); * 0 on success, -ENOSPC if there's no suitable hole. */ int drm_mm_insert_node_generic(struct drm_mm *mm, struct drm_mm_node *node, - unsigned long size, unsigned alignment, + u64 size, unsigned alignment, unsigned long color, enum drm_mm_search_flags sflags, enum drm_mm_allocator_flags aflags) @@ -246,16 +249,16 @@ EXPORT_SYMBOL(drm_mm_insert_node_generic); static void drm_mm_insert_helper_range(struct drm_mm_node *hole_node, struct drm_mm_node *node, - unsigned long size, unsigned alignment, + u64 size, unsigned alignment, unsigned long color, - unsigned long start, unsigned long end, + u64 start, u64 end, enum drm_mm_allocator_flags flags) { struct drm_mm *mm = hole_node->mm; - unsigned long hole_start = drm_mm_hole_node_start(hole_node); - unsigned long hole_end = drm_mm_hole_node_end(hole_node); - unsigned long adj_start = hole_start; - unsigned long adj_end = hole_end; + u64 hole_start = drm_mm_hole_node_start(hole_node); + u64 hole_end = drm_mm_hole_node_end(hole_node); + u64 adj_start = hole_start; + u64 adj_end = hole_end; BUG_ON(!hole_node->hole_follows || node->allocated); @@ -271,12 +274,15 @@ static void drm_mm_insert_helper_range(struct drm_mm_node *hole_node, mm->color_adjust(hole_node, color, &adj_start, &adj_end); if (alignment) { - unsigned tmp = adj_start % alignment; - if (tmp) { + u64 tmp = adj_start; + unsigned rem; + + rem = do_div(tmp, alignment); + if (rem) { if (flags & DRM_MM_CREATE_TOP) - adj_start -= tmp; + adj_start -= rem; else - adj_start += alignment - tmp; + adj_start += alignment - rem; } } @@ -324,9 +330,9 @@ static void drm_mm_insert_helper_range(struct drm_mm_node *hole_node, * 0 on success, -ENOSPC if there's no suitable hole. */ int drm_mm_insert_node_in_range_generic(struct drm_mm *mm, struct drm_mm_node *node, - unsigned long size, unsigned alignment, + u64 size, unsigned alignment, unsigned long color, - unsigned long start, unsigned long end, + u64 start, u64 end, enum drm_mm_search_flags sflags, enum drm_mm_allocator_flags aflags) { @@ -387,32 +393,34 @@ void drm_mm_remove_node(struct drm_mm_node *node) } EXPORT_SYMBOL(drm_mm_remove_node); -static int check_free_hole(unsigned long start, unsigned long end, - unsigned long size, unsigned alignment) +static int check_free_hole(u64 start, u64 end, u64 size, unsigned alignment) { if (end - start < size) return 0; if (alignment) { - unsigned tmp = start % alignment; + u64 tmp = start; + unsigned rem; + + rem = do_div(tmp, alignment); if (tmp) - start += alignment - tmp; + start += alignment - rem; } return end >= start + size; } static struct drm_mm_node *drm_mm_search_free_generic(const struct drm_mm *mm, - unsigned long size, + u64 size, unsigned alignment, unsigned long color, enum drm_mm_search_flags flags) { struct drm_mm_node *entry; struct drm_mm_node *best; - unsigned long adj_start; - unsigned long adj_end; - unsigned long best_size; + u64 adj_start; + u64 adj_end; + u64 best_size; BUG_ON(mm->scanned_blocks); @@ -421,7 +429,7 @@ static struct drm_mm_node *drm_mm_search_free_generic(const struct drm_mm *mm, __drm_mm_for_each_hole(entry, mm, adj_start, adj_end, flags & DRM_MM_SEARCH_BELOW) { - unsigned long hole_size = adj_end - adj_start; + u64 hole_size = adj_end - adj_start; if (mm->color_adjust) { mm->color_adjust(entry, color, &adj_start, &adj_end); @@ -445,18 +453,18 @@ static struct drm_mm_node *drm_mm_search_free_generic(const struct drm_mm *mm, } static struct drm_mm_node *drm_mm_search_free_in_range_generic(const struct drm_mm *mm, - unsigned long size, + u64 size, unsigned alignment, unsigned long color, - unsigned long start, - unsigned long end, + u64 start, + u64 end, enum drm_mm_search_flags flags) { struct drm_mm_node *entry; struct drm_mm_node *best; - unsigned long adj_start; - unsigned long adj_end; - unsigned long best_size; + u64 adj_start; + u64 adj_end; + u64 best_size; BUG_ON(mm->scanned_blocks); @@ -465,7 +473,7 @@ static struct drm_mm_node *drm_mm_search_free_in_range_generic(const struct drm_ __drm_mm_for_each_hole(entry, mm, adj_start, adj_end, flags & DRM_MM_SEARCH_BELOW) { - unsigned long hole_size = adj_end - adj_start; + u64 hole_size = adj_end - adj_start; if (adj_start < start) adj_start = start; @@ -561,7 +569,7 @@ EXPORT_SYMBOL(drm_mm_replace_node); * adding/removing nodes to/from the scan list are allowed. */ void drm_mm_init_scan(struct drm_mm *mm, - unsigned long size, + u64 size, unsigned alignment, unsigned long color) { @@ -594,11 +602,11 @@ EXPORT_SYMBOL(drm_mm_init_scan); * adding/removing nodes to/from the scan list are allowed. */ void drm_mm_init_scan_with_range(struct drm_mm *mm, - unsigned long size, + u64 size, unsigned alignment, unsigned long color, - unsigned long start, - unsigned long end) + u64 start, + u64 end) { mm->scan_color = color; mm->scan_alignment = alignment; @@ -627,8 +635,8 @@ bool drm_mm_scan_add_block(struct drm_mm_node *node) { struct drm_mm *mm = node->mm; struct drm_mm_node *prev_node; - unsigned long hole_start, hole_end; - unsigned long adj_start, adj_end; + u64 hole_start, hole_end; + u64 adj_start, adj_end; mm->scanned_blocks++; @@ -731,7 +739,7 @@ EXPORT_SYMBOL(drm_mm_clean); * * Note that @mm must be cleared to 0 before calling this function. */ -void drm_mm_init(struct drm_mm * mm, unsigned long start, unsigned long size) +void drm_mm_init(struct drm_mm * mm, u64 start, u64 size) { INIT_LIST_HEAD(&mm->hole_stack); mm->scanned_blocks = 0; @@ -766,18 +774,17 @@ void drm_mm_takedown(struct drm_mm * mm) } EXPORT_SYMBOL(drm_mm_takedown); -static unsigned long drm_mm_debug_hole(struct drm_mm_node *entry, - const char *prefix) +static u64 drm_mm_debug_hole(struct drm_mm_node *entry, + const char *prefix) { - unsigned long hole_start, hole_end, hole_size; + u64 hole_start, hole_end, hole_size; if (entry->hole_follows) { hole_start = drm_mm_hole_node_start(entry); hole_end = drm_mm_hole_node_end(entry); hole_size = hole_end - hole_start; - printk(KERN_DEBUG "%s 0x%08lx-0x%08lx: %8lu: free\n", - prefix, hole_start, hole_end, - hole_size); + pr_debug("%s %#llx-%#llx: %llu: free\n", prefix, hole_start, + hole_end, hole_size); return hole_size; } @@ -792,35 +799,34 @@ static unsigned long drm_mm_debug_hole(struct drm_mm_node *entry, void drm_mm_debug_table(struct drm_mm *mm, const char *prefix) { struct drm_mm_node *entry; - unsigned long total_used = 0, total_free = 0, total = 0; + u64 total_used = 0, total_free = 0, total = 0; total_free += drm_mm_debug_hole(&mm->head_node, prefix); drm_mm_for_each_node(entry, mm) { - printk(KERN_DEBUG "%s 0x%08lx-0x%08lx: %8lu: used\n", - prefix, entry->start, entry->start + entry->size, - entry->size); + pr_debug("%s %#llx-%#llx: %llu: used\n", prefix, entry->start, + entry->start + entry->size, entry->size); total_used += entry->size; total_free += drm_mm_debug_hole(entry, prefix); } total = total_free + total_used; - printk(KERN_DEBUG "%s total: %lu, used %lu free %lu\n", prefix, total, - total_used, total_free); + pr_debug("%s total: %llu, used %llu free %llu\n", prefix, total, + total_used, total_free); } EXPORT_SYMBOL(drm_mm_debug_table); #if defined(CONFIG_DEBUG_FS) -static unsigned long drm_mm_dump_hole(struct seq_file *m, struct drm_mm_node *entry) +static u64 drm_mm_dump_hole(struct seq_file *m, struct drm_mm_node *entry) { - unsigned long hole_start, hole_end, hole_size; + u64 hole_start, hole_end, hole_size; if (entry->hole_follows) { hole_start = drm_mm_hole_node_start(entry); hole_end = drm_mm_hole_node_end(entry); hole_size = hole_end - hole_start; - seq_printf(m, "0x%08lx-0x%08lx: 0x%08lx: free\n", - hole_start, hole_end, hole_size); + seq_printf(m, "%#llx-%#llx: %llu: free\n", hole_start, + hole_end, hole_size); return hole_size; } @@ -835,20 +841,20 @@ static unsigned long drm_mm_dump_hole(struct seq_file *m, struct drm_mm_node *en int drm_mm_dump_table(struct seq_file *m, struct drm_mm *mm) { struct drm_mm_node *entry; - unsigned long total_used = 0, total_free = 0, total = 0; + u64 total_used = 0, total_free = 0, total = 0; total_free += drm_mm_dump_hole(m, &mm->head_node); drm_mm_for_each_node(entry, mm) { - seq_printf(m, "0x%08lx-0x%08lx: 0x%08lx: used\n", - entry->start, entry->start + entry->size, - entry->size); + seq_printf(m, "%#016llx-%#016llx: %llu: used\n", entry->start, + entry->start + entry->size, entry->size); total_used += entry->size; total_free += drm_mm_dump_hole(m, entry); } total = total_free + total_used; - seq_printf(m, "total: %lu, used %lu free %lu\n", total, total_used, total_free); + seq_printf(m, "total: %llu, used %llu free %llu\n", total, + total_used, total_free); return 0; } EXPORT_SYMBOL(drm_mm_dump_table); diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 96e811fe24ca..e8b18e542da4 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -152,12 +152,12 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) seq_puts(m, " (pp"); else seq_puts(m, " (g"); - seq_printf(m, "gtt offset: %08lx, size: %08lx, type: %u)", + seq_printf(m, "gtt offset: %08llx, size: %08llx, type: %u)", vma->node.start, vma->node.size, vma->ggtt_view.type); } if (obj->stolen) - seq_printf(m, " (stolen: %08lx)", obj->stolen->start); + seq_printf(m, " (stolen: %08llx)", obj->stolen->start); if (obj->pin_mappable || obj->fault_mappable) { char s[3], *t = s; if (obj->pin_mappable) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 746f77fb57a3..dccdc8aad2e2 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -1145,7 +1145,7 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt) ppgtt->base.clear_range(&ppgtt->base, 0, ppgtt->base.total, true); - DRM_DEBUG_DRIVER("Allocated pde space (%ldM) at GTT entry: %lx\n", + DRM_DEBUG_DRIVER("Allocated pde space (%lldM) at GTT entry: %llx\n", ppgtt->node.size >> 20, ppgtt->node.start / PAGE_SIZE); @@ -1713,8 +1713,8 @@ void i915_gem_gtt_finish_object(struct drm_i915_gem_object *obj) static void i915_gtt_color_adjust(struct drm_mm_node *node, unsigned long color, - unsigned long *start, - unsigned long *end) + u64 *start, + u64 *end) { if (node->color != color) *start += 4096; diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h index a24addfdfcec..0de6290df4da 100644 --- a/include/drm/drm_mm.h +++ b/include/drm/drm_mm.h @@ -68,8 +68,8 @@ struct drm_mm_node { unsigned scanned_preceeds_hole : 1; unsigned allocated : 1; unsigned long color; - unsigned long start; - unsigned long size; + u64 start; + u64 size; struct drm_mm *mm; }; @@ -82,16 +82,16 @@ struct drm_mm { unsigned int scan_check_range : 1; unsigned scan_alignment; unsigned long scan_color; - unsigned long scan_size; - unsigned long scan_hit_start; - unsigned long scan_hit_end; + u64 scan_size; + u64 scan_hit_start; + u64 scan_hit_end; unsigned scanned_blocks; - unsigned long scan_start; - unsigned long scan_end; + u64 scan_start; + u64 scan_end; struct drm_mm_node *prev_scanned_node; void (*color_adjust)(struct drm_mm_node *node, unsigned long color, - unsigned long *start, unsigned long *end); + u64 *start, u64 *end); }; /** @@ -124,7 +124,7 @@ static inline bool drm_mm_initialized(struct drm_mm *mm) return mm->hole_stack.next; } -static inline unsigned long __drm_mm_hole_node_start(struct drm_mm_node *hole_node) +static inline u64 __drm_mm_hole_node_start(struct drm_mm_node *hole_node) { return hole_node->start + hole_node->size; } @@ -140,13 +140,13 @@ static inline unsigned long __drm_mm_hole_node_start(struct drm_mm_node *hole_no * Returns: * Start of the subsequent hole. */ -static inline unsigned long drm_mm_hole_node_start(struct drm_mm_node *hole_node) +static inline u64 drm_mm_hole_node_start(struct drm_mm_node *hole_node) { BUG_ON(!hole_node->hole_follows); return __drm_mm_hole_node_start(hole_node); } -static inline unsigned long __drm_mm_hole_node_end(struct drm_mm_node *hole_node) +static inline u64 __drm_mm_hole_node_end(struct drm_mm_node *hole_node) { return list_entry(hole_node->node_list.next, struct drm_mm_node, node_list)->start; @@ -163,7 +163,7 @@ static inline unsigned long __drm_mm_hole_node_end(struct drm_mm_node *hole_node * Returns: * End of the subsequent hole. */ -static inline unsigned long drm_mm_hole_node_end(struct drm_mm_node *hole_node) +static inline u64 drm_mm_hole_node_end(struct drm_mm_node *hole_node) { return __drm_mm_hole_node_end(hole_node); } @@ -222,7 +222,7 @@ int drm_mm_reserve_node(struct drm_mm *mm, struct drm_mm_node *node); int drm_mm_insert_node_generic(struct drm_mm *mm, struct drm_mm_node *node, - unsigned long size, + u64 size, unsigned alignment, unsigned long color, enum drm_mm_search_flags sflags, @@ -245,7 +245,7 @@ int drm_mm_insert_node_generic(struct drm_mm *mm, */ static inline int drm_mm_insert_node(struct drm_mm *mm, struct drm_mm_node *node, - unsigned long size, + u64 size, unsigned alignment, enum drm_mm_search_flags flags) { @@ -255,11 +255,11 @@ static inline int drm_mm_insert_node(struct drm_mm *mm, int drm_mm_insert_node_in_range_generic(struct drm_mm *mm, struct drm_mm_node *node, - unsigned long size, + u64 size, unsigned alignment, unsigned long color, - unsigned long start, - unsigned long end, + u64 start, + u64 end, enum drm_mm_search_flags sflags, enum drm_mm_allocator_flags aflags); /** @@ -282,10 +282,10 @@ int drm_mm_insert_node_in_range_generic(struct drm_mm *mm, */ static inline int drm_mm_insert_node_in_range(struct drm_mm *mm, struct drm_mm_node *node, - unsigned long size, + u64 size, unsigned alignment, - unsigned long start, - unsigned long end, + u64 start, + u64 end, enum drm_mm_search_flags flags) { return drm_mm_insert_node_in_range_generic(mm, node, size, alignment, @@ -296,21 +296,21 @@ static inline int drm_mm_insert_node_in_range(struct drm_mm *mm, void drm_mm_remove_node(struct drm_mm_node *node); void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new); void drm_mm_init(struct drm_mm *mm, - unsigned long start, - unsigned long size); + u64 start, + u64 size); void drm_mm_takedown(struct drm_mm *mm); bool drm_mm_clean(struct drm_mm *mm); void drm_mm_init_scan(struct drm_mm *mm, - unsigned long size, + u64 size, unsigned alignment, unsigned long color); void drm_mm_init_scan_with_range(struct drm_mm *mm, - unsigned long size, + u64 size, unsigned alignment, unsigned long color, - unsigned long start, - unsigned long end); + u64 start, + u64 end); bool drm_mm_scan_add_block(struct drm_mm_node *node); bool drm_mm_scan_remove_block(struct drm_mm_node *node); -- GitLab From 54c4cd68ed7abd9f245722bee39464d04ddb4cfd Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 4 Mar 2015 00:18:38 -0500 Subject: [PATCH 02713/11651] drm/ttm: device address space != CPU address space We need to store device offsets in 64 bit as the device address space may be larger than the CPU's. Fixes GPU init failures on radeons with 4GB or more of vram on 32 bit kernels. We put vram at the start of the GPU's address space so the gart aperture starts at 4 GB causing all GPU addresses in the gart aperture to get truncated. bug: https://bugs.freedesktop.org/show_bug.cgi?id=89072 [airlied: fix warning on nouveau build] Signed-off-by: Alex Deucher Cc: thellstrom@vmware.com Acked-by: Thomas Hellstrom Signed-off-by: Dave Airlie --- drivers/gpu/drm/nouveau/nouveau_fbcon.c | 2 +- drivers/gpu/drm/ttm/ttm_bo.c | 2 +- include/drm/ttm/ttm_bo_api.h | 2 +- include/drm/ttm/ttm_bo_driver.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index 79924e4b1b49..6751553abe4a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -418,7 +418,7 @@ nouveau_fbcon_create(struct drm_fb_helper *helper, nouveau_fbcon_zfill(dev, fbcon); /* To allow resizeing without swapping buffers */ - NV_INFO(drm, "allocated %dx%d fb: 0x%lx, bo %p\n", + NV_INFO(drm, "allocated %dx%d fb: 0x%llx, bo %p\n", nouveau_fb->base.width, nouveau_fb->base.height, nvbo->bo.offset, nvbo); diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index d395b0bef73b..8d9b7de25613 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -74,7 +74,7 @@ static void ttm_mem_type_debug(struct ttm_bo_device *bdev, int mem_type) pr_err(" has_type: %d\n", man->has_type); pr_err(" use_type: %d\n", man->use_type); pr_err(" flags: 0x%08X\n", man->flags); - pr_err(" gpu_offset: 0x%08lX\n", man->gpu_offset); + pr_err(" gpu_offset: 0x%08llX\n", man->gpu_offset); pr_err(" size: %llu\n", man->size); pr_err(" available_caching: 0x%08X\n", man->available_caching); pr_err(" default_caching: 0x%08X\n", man->default_caching); diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h index 0ccf7f267ff9..c768ddfbe53c 100644 --- a/include/drm/ttm/ttm_bo_api.h +++ b/include/drm/ttm/ttm_bo_api.h @@ -249,7 +249,7 @@ struct ttm_buffer_object { * either of these locks held. */ - unsigned long offset; + uint64_t offset; /* GPU address space is independent of CPU word size */ uint32_t cur_placement; struct sg_table *sg; diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h index 142d752fc450..813042cede57 100644 --- a/include/drm/ttm/ttm_bo_driver.h +++ b/include/drm/ttm/ttm_bo_driver.h @@ -277,7 +277,7 @@ struct ttm_mem_type_manager { bool has_type; bool use_type; uint32_t flags; - unsigned long gpu_offset; + uint64_t gpu_offset; /* GPU address space is independent of CPU word size */ uint64_t size; uint32_t available_caching; uint32_t default_caching; -- GitLab From 93050db2065726c7fd0db1b9a53311a74eee94c3 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Fri, 27 Feb 2015 15:49:51 -0800 Subject: [PATCH 02714/11651] Input: ALPS - fix memory leak when detection fails MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes memory leak introduced by commit a09221e83e13e09a33109b9b037484eade901cea Acked-by: Pali Rohár Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/alps.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index d28726a0ef85..1bd15ebc01f2 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -2605,8 +2605,10 @@ int alps_detect(struct psmouse *psmouse, bool set_properties) return -ENOMEM; error = alps_identify(psmouse, priv); - if (error) + if (error) { + kfree(priv); return error; + } if (set_properties) { psmouse->vendor = "ALPS"; -- GitLab From 20f02d66f042f2b6a929519fd9ee62f77013ccaa Mon Sep 17 00:00:00 2001 From: Valentin Rothberg Date: Wed, 4 Mar 2015 15:10:45 -0800 Subject: [PATCH 02715/11651] Input: tc3589x-keypad - set IRQF_ONESHOT flag to ensure IRQ request Since commit 1c6c69525b40eb76de8adf039409722015927dc3 ("genirq: Reject bogus threaded irq requests") threaded IRQs without a primary handler need to be requested with IRQF_ONESHOT, otherwise the request will fail. Currently, plat->irqtype is only set to IRQF_TRIGGER_FALLING. This patch sets the ONESHOT flag directly in request_threaded_irq() to enforce the flag without being affected by future changes to plat->irqtype. Generated by: scripts/coccinelle/misc/irqf_oneshot.cocci Signed-off-by: Valentin Rothberg Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/tc3589x-keypad.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/input/keyboard/tc3589x-keypad.c b/drivers/input/keyboard/tc3589x-keypad.c index 8ff612d160b0..563932500ff1 100644 --- a/drivers/input/keyboard/tc3589x-keypad.c +++ b/drivers/input/keyboard/tc3589x-keypad.c @@ -411,9 +411,9 @@ static int tc3589x_keypad_probe(struct platform_device *pdev) input_set_drvdata(input, keypad); - error = request_threaded_irq(irq, NULL, - tc3589x_keypad_irq, plat->irqtype, - "tc3589x-keypad", keypad); + error = request_threaded_irq(irq, NULL, tc3589x_keypad_irq, + plat->irqtype | IRQF_ONESHOT, + "tc3589x-keypad", keypad); if (error < 0) { dev_err(&pdev->dev, "Could not allocate irq %d,error %d\n", -- GitLab From 5db0f6e880eb99ad400d5f1c646dffc7fd939c78 Mon Sep 17 00:00:00 2001 From: Stephane Viau Date: Fri, 20 Feb 2015 12:40:58 -0500 Subject: [PATCH 02716/11651] drm/msm/mdp5: fixup "drm/msm: fix fallout of atomic dpms changes" Commit 0b776d457b94 ("drm/msm: fix fallout of atomic dpms changes") has a typo in both mdp5_encoder_helper_funcs and mdp5_crtc_helper_funcs definitions: .dpms entry should be replaced by .disable and .enable Also fixed a typo in mdp5_encoder_enable(). Note that these typos are only present for MDP5. MDP4 is fine. Signed-off-by: Stephane Viau Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c | 4 ++-- drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c index 46fac545dc2b..946b71b6e608 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c @@ -544,8 +544,8 @@ static const struct drm_crtc_funcs mdp5_crtc_funcs = { static const struct drm_crtc_helper_funcs mdp5_crtc_helper_funcs = { .mode_fixup = mdp5_crtc_mode_fixup, .mode_set_nofb = mdp5_crtc_mode_set_nofb, - .prepare = mdp5_crtc_disable, - .commit = mdp5_crtc_enable, + .disable = mdp5_crtc_disable, + .enable = mdp5_crtc_enable, .atomic_check = mdp5_crtc_atomic_check, .atomic_begin = mdp5_crtc_atomic_begin, .atomic_flush = mdp5_crtc_atomic_flush, diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c index d6a14bb99988..af0e02fa4f48 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c @@ -267,14 +267,14 @@ static void mdp5_encoder_enable(struct drm_encoder *encoder) mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(intf), 1); spin_unlock_irqrestore(&mdp5_encoder->intf_lock, flags); - mdp5_encoder->enabled = false; + mdp5_encoder->enabled = true; } static const struct drm_encoder_helper_funcs mdp5_encoder_helper_funcs = { .mode_fixup = mdp5_encoder_mode_fixup, .mode_set = mdp5_encoder_mode_set, - .prepare = mdp5_encoder_disable, - .commit = mdp5_encoder_enable, + .disable = mdp5_encoder_disable, + .enable = mdp5_encoder_enable, }; /* initialize encoder */ -- GitLab From 8a4247d645a3b864e3359a5b60d41dc74a7a7b2a Mon Sep 17 00:00:00 2001 From: Stephane Viau Date: Fri, 20 Feb 2015 16:30:55 -0500 Subject: [PATCH 02717/11651] drm/msm: update generated headers (add 6th lm.base entry) Some target have up to 6 layer mixers (LM). Let the header file access the last LM's base address. Signed-off-by: Stephane Viau Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h index 09b4a25eb553..c276624290af 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h @@ -8,17 +8,9 @@ http://github.com/freedreno/envytools/ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: -- /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 676 bytes, from 2014-12-05 15:34:49) -- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20908 bytes, from 2014-12-08 16:13:00) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2357 bytes, from 2014-12-08 16:13:00) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 27208 bytes, from 2015-01-13 23:56:11) -- /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 11712 bytes, from 2013-08-17 17:13:43) -- /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2013-08-11 19:26:32) -- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2014-10-31 16:48:57) -- /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2013-07-05 19:21:12) -- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 26848 bytes, from 2015-01-13 23:55:57) -- /home/robclark/src/freedreno/envytools/rnndb/edp/edp.xml ( 8253 bytes, from 2014-12-08 16:13:00) +- /local/mnt2/workspace2/sviau/envytools/rnndb/mdp/mdp5.xml ( 27229 bytes, from 2015-02-10 17:00:41) +- /local/mnt2/workspace2/sviau/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2014-06-02 18:31:15) +- /local/mnt2/workspace2/sviau/envytools/rnndb/mdp/mdp_common.xml ( 2357 bytes, from 2015-01-23 16:20:19) Copyright (C) 2013-2015 by the following authors: - Rob Clark (robclark) @@ -910,6 +902,7 @@ static inline uint32_t __offset_LM(uint32_t idx) case 2: return (mdp5_cfg->lm.base[2]); case 3: return (mdp5_cfg->lm.base[3]); case 4: return (mdp5_cfg->lm.base[4]); + case 5: return (mdp5_cfg->lm.base[5]); default: return INVALID_IDX(idx); } } -- GitLab From ba0312a6108f5214efb4659c4dbba218c5b9eb8d Mon Sep 17 00:00:00 2001 From: Stephane Viau Date: Fri, 20 Feb 2015 16:30:56 -0500 Subject: [PATCH 02718/11651] drm/msm/mdp5: Avoid flushing registers when CRTC is disabled When a CRTC is disabled, no CTL is allocated to it (CRTC->ctl == NULL); in that case we should not try to FLUSH registers and do nothing instead. This can happen when we try to move a cursor but the CRTC's CTL (CONTROL) has not been allocated yet (inactive CRTC). It can also happens when we .atomic_check()/.atomic_flush() on a disabled CRTC. A CTL needs to be kept as long as the CRTC is alive. Releasing it after the last VBlank is safer than in .atomic_flush(). Signed-off-by: Stephane Viau Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c | 26 +++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c index 946b71b6e608..2aeae7351621 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c @@ -103,8 +103,8 @@ static void crtc_flush_all(struct drm_crtc *crtc) struct drm_plane *plane; uint32_t flush_mask = 0; - /* we could have already released CTL in the disable path: */ - if (!mdp5_crtc->ctl) + /* this should not happen: */ + if (WARN_ON(!mdp5_crtc->ctl)) return; drm_atomic_crtc_for_each_plane(plane, crtc) { @@ -143,6 +143,11 @@ static void complete_flip(struct drm_crtc *crtc, struct drm_file *file) drm_atomic_crtc_for_each_plane(plane, crtc) { mdp5_plane_complete_flip(plane); } + + if (mdp5_crtc->ctl && !crtc->state->enable) { + mdp5_ctl_release(mdp5_crtc->ctl); + mdp5_crtc->ctl = NULL; + } } static void unref_cursor_worker(struct drm_flip_work *work, void *val) @@ -386,14 +391,17 @@ static void mdp5_crtc_atomic_flush(struct drm_crtc *crtc) mdp5_crtc->event = crtc->state->event; spin_unlock_irqrestore(&dev->event_lock, flags); + /* + * If no CTL has been allocated in mdp5_crtc_atomic_check(), + * it means we are trying to flush a CRTC whose state is disabled: + * nothing else needs to be done. + */ + if (unlikely(!mdp5_crtc->ctl)) + return; + blend_setup(crtc); crtc_flush_all(crtc); request_pending(crtc, PENDING_FLIP); - - if (mdp5_crtc->ctl && !crtc->state->enable) { - mdp5_ctl_release(mdp5_crtc->ctl); - mdp5_crtc->ctl = NULL; - } } static int mdp5_crtc_set_property(struct drm_crtc *crtc, @@ -495,6 +503,10 @@ static int mdp5_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) uint32_t roi_h; unsigned long flags; + /* In case the CRTC is disabled, just drop the cursor update */ + if (unlikely(!crtc->state->enable)) + return 0; + x = (x > 0) ? x : 0; y = (y > 0) ? y : 0; -- GitLab From 5b2e2b6c5e542f7334dcaeb5b577d8328a5f2fc0 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Mon, 23 Feb 2015 00:58:03 +0200 Subject: [PATCH 02719/11651] drm/msm/atomic: Don't leak atomic commit object when commit fails If the atomic commit fails due to completion wait interruption the atomic commit object is not freed and is thus leaked. Free it. Signed-off-by: Laurent Pinchart Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_atomic.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c index 871aa2108dc6..18fd643b6e69 100644 --- a/drivers/gpu/drm/msm/msm_atomic.c +++ b/drivers/gpu/drm/msm/msm_atomic.c @@ -219,8 +219,10 @@ int msm_atomic_commit(struct drm_device *dev, * mark our set of crtc's as busy: */ ret = start_atomic(dev->dev_private, c->crtc_mask); - if (ret) + if (ret) { + kfree(c); return ret; + } /* * This is the point of no return - everything below never fails except -- GitLab From 58560890b3e33d789c4f13a10324af9c85c52308 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Tue, 24 Feb 2015 14:47:57 -0500 Subject: [PATCH 02720/11651] drm/msm/mdp5: fix cursor ROI If cursor is set near the edge of the screen, it is not valid to use the new cursor width/height as the ROI dimensions. Split out the ROI calc and use it both cursor_set and cursor_move. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c | 68 ++++++++++++++---------- 1 file changed, 40 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c index 2aeae7351621..4c4be4344653 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c @@ -62,8 +62,8 @@ struct mdp5_crtc { /* current cursor being scanned out: */ struct drm_gem_object *scanout_bo; - uint32_t width; - uint32_t height; + uint32_t width, height; + uint32_t x, y; } cursor; }; #define to_mdp5_crtc(x) container_of(x, struct mdp5_crtc, base) @@ -411,6 +411,32 @@ static int mdp5_crtc_set_property(struct drm_crtc *crtc, return -EINVAL; } +static void get_roi(struct drm_crtc *crtc, uint32_t *roi_w, uint32_t *roi_h) +{ + struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); + uint32_t xres = crtc->mode.hdisplay; + uint32_t yres = crtc->mode.vdisplay; + + /* + * Cursor Region Of Interest (ROI) is a plane read from cursor + * buffer to render. The ROI region is determined by the visibility of + * the cursor point. In the default Cursor image the cursor point will + * be at the top left of the cursor image, unless it is specified + * otherwise using hotspot feature. + * + * If the cursor point reaches the right (xres - x < cursor.width) or + * bottom (yres - y < cursor.height) boundary of the screen, then ROI + * width and ROI height need to be evaluated to crop the cursor image + * accordingly. + * (xres-x) will be new cursor width when x > (xres - cursor.width) + * (yres-y) will be new cursor height when y > (yres - cursor.height) + */ + *roi_w = min(mdp5_crtc->cursor.width, xres - + mdp5_crtc->cursor.x); + *roi_h = min(mdp5_crtc->cursor.height, yres - + mdp5_crtc->cursor.y); +} + static int mdp5_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file, uint32_t handle, uint32_t width, uint32_t height) @@ -424,6 +450,7 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc, unsigned int depth; enum mdp5_cursor_alpha cur_alpha = CURSOR_ALPHA_PER_PIXEL; uint32_t flush_mask = mdp_ctl_flush_mask_cursor(0); + uint32_t roi_w, roi_h; unsigned long flags; if ((width > CURSOR_WIDTH) || (height > CURSOR_HEIGHT)) { @@ -454,6 +481,12 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc, spin_lock_irqsave(&mdp5_crtc->cursor.lock, flags); old_bo = mdp5_crtc->cursor.scanout_bo; + mdp5_crtc->cursor.scanout_bo = cursor_bo; + mdp5_crtc->cursor.width = width; + mdp5_crtc->cursor.height = height; + + get_roi(crtc, &roi_w, &roi_h); + mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_STRIDE(lm), stride); mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_FORMAT(lm), MDP5_LM_CURSOR_FORMAT_FORMAT(CURSOR_FMT_ARGB8888)); @@ -461,19 +494,15 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc, MDP5_LM_CURSOR_IMG_SIZE_SRC_H(height) | MDP5_LM_CURSOR_IMG_SIZE_SRC_W(width)); mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_SIZE(lm), - MDP5_LM_CURSOR_SIZE_ROI_H(height) | - MDP5_LM_CURSOR_SIZE_ROI_W(width)); + MDP5_LM_CURSOR_SIZE_ROI_H(roi_h) | + MDP5_LM_CURSOR_SIZE_ROI_W(roi_w)); mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_BASE_ADDR(lm), cursor_addr); - blendcfg = MDP5_LM_CURSOR_BLEND_CONFIG_BLEND_EN; blendcfg |= MDP5_LM_CURSOR_BLEND_CONFIG_BLEND_TRANSP_EN; blendcfg |= MDP5_LM_CURSOR_BLEND_CONFIG_BLEND_ALPHA_SEL(cur_alpha); mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_BLEND_CONFIG(lm), blendcfg); - mdp5_crtc->cursor.scanout_bo = cursor_bo; - mdp5_crtc->cursor.width = width; - mdp5_crtc->cursor.height = height; spin_unlock_irqrestore(&mdp5_crtc->cursor.lock, flags); ret = mdp5_ctl_set_cursor(mdp5_crtc->ctl, true); @@ -497,8 +526,6 @@ static int mdp5_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) struct mdp5_kms *mdp5_kms = get_kms(crtc); struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); uint32_t flush_mask = mdp_ctl_flush_mask_cursor(0); - uint32_t xres = crtc->mode.hdisplay; - uint32_t yres = crtc->mode.vdisplay; uint32_t roi_w; uint32_t roi_h; unsigned long flags; @@ -507,25 +534,10 @@ static int mdp5_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) if (unlikely(!crtc->state->enable)) return 0; - x = (x > 0) ? x : 0; - y = (y > 0) ? y : 0; + mdp5_crtc->cursor.x = x = max(x, 0); + mdp5_crtc->cursor.y = y = max(y, 0); - /* - * Cursor Region Of Interest (ROI) is a plane read from cursor - * buffer to render. The ROI region is determined by the visiblity of - * the cursor point. In the default Cursor image the cursor point will - * be at the top left of the cursor image, unless it is specified - * otherwise using hotspot feature. - * - * If the cursor point reaches the right (xres - x < cursor.width) or - * bottom (yres - y < cursor.height) boundary of the screen, then ROI - * width and ROI height need to be evaluated to crop the cursor image - * accordingly. - * (xres-x) will be new cursor width when x > (xres - cursor.width) - * (yres-y) will be new cursor height when y > (yres - cursor.height) - */ - roi_w = min(mdp5_crtc->cursor.width, xres - x); - roi_h = min(mdp5_crtc->cursor.height, yres - y); + get_roi(crtc, &roi_w, &roi_h); spin_lock_irqsave(&mdp5_crtc->cursor.lock, flags); mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_SIZE(mdp5_crtc->lm), -- GitLab From 757fdfaf413c4a85dade5374b6f5c05d541cf32e Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Tue, 24 Feb 2015 15:29:37 -0500 Subject: [PATCH 02721/11651] drm/msm/mdp5: fix cursor blending Seems like we just want BLEND_EN and not BLEND_TRANSP_EN (setting the latter results in black pixels in the cursor image treated as transparent). Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c index 4c4be4344653..2f2863cf8b45 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c @@ -499,7 +499,6 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc, mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_BASE_ADDR(lm), cursor_addr); blendcfg = MDP5_LM_CURSOR_BLEND_CONFIG_BLEND_EN; - blendcfg |= MDP5_LM_CURSOR_BLEND_CONFIG_BLEND_TRANSP_EN; blendcfg |= MDP5_LM_CURSOR_BLEND_CONFIG_BLEND_ALPHA_SEL(cur_alpha); mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_BLEND_CONFIG(lm), blendcfg); -- GitLab From aa80a4a5190e697a6945849ab36fa7dabca815f3 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Mon, 2 Mar 2015 16:19:06 -0500 Subject: [PATCH 02722/11651] drm/msm: kexec fixes In kexec environment, we are more likely to encounter irq's already enabled from previous environment. At which point we find that writes to disable/clear pending irq's are slightly less than useless without first enabling clocks. TODO: full blown state read-in so kexec'd kernel can inherit the mode already setup. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/mdp/mdp4/mdp4_irq.c | 5 +++++ drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_irq.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_irq.c index 8edd531cb621..7369ee7f0c55 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_irq.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_irq.c @@ -32,7 +32,10 @@ static void mdp4_irq_error_handler(struct mdp_irq *irq, uint32_t irqstatus) void mdp4_irq_preinstall(struct msm_kms *kms) { struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms)); + mdp4_enable(mdp4_kms); mdp4_write(mdp4_kms, REG_MDP4_INTR_CLEAR, 0xffffffff); + mdp4_write(mdp4_kms, REG_MDP4_INTR_ENABLE, 0x00000000); + mdp4_disable(mdp4_kms); } int mdp4_irq_postinstall(struct msm_kms *kms) @@ -53,7 +56,9 @@ int mdp4_irq_postinstall(struct msm_kms *kms) void mdp4_irq_uninstall(struct msm_kms *kms) { struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms)); + mdp4_enable(mdp4_kms); mdp4_write(mdp4_kms, REG_MDP4_INTR_ENABLE, 0x00000000); + mdp4_disable(mdp4_kms); } irqreturn_t mdp4_irq(struct msm_kms *kms) diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c index 70ac81edd40f..a9407105b9b7 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c @@ -34,7 +34,10 @@ static void mdp5_irq_error_handler(struct mdp_irq *irq, uint32_t irqstatus) void mdp5_irq_preinstall(struct msm_kms *kms) { struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms)); + mdp5_enable(mdp5_kms); mdp5_write(mdp5_kms, REG_MDP5_INTR_CLEAR, 0xffffffff); + mdp5_write(mdp5_kms, REG_MDP5_INTR_EN, 0x00000000); + mdp5_disable(mdp5_kms); } int mdp5_irq_postinstall(struct msm_kms *kms) @@ -57,7 +60,9 @@ int mdp5_irq_postinstall(struct msm_kms *kms) void mdp5_irq_uninstall(struct msm_kms *kms) { struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms)); + mdp5_enable(mdp5_kms); mdp5_write(mdp5_kms, REG_MDP5_INTR_EN, 0x00000000); + mdp5_disable(mdp5_kms); } static void mdp5_irq_mdp(struct mdp_kms *mdp_kms) -- GitLab From 5eca7453d61003bf886992388f8cb407e6f0d051 Mon Sep 17 00:00:00 2001 From: Wang Nan Date: Fri, 27 Feb 2015 12:19:49 +0800 Subject: [PATCH 02723/11651] x86/traps: Separate set_intr_gate() and clean up early_trap_init() As early_trap_init() doesn't use IST, replace set_intr_gate_ist() and set_system_intr_gate_ist() with their standard counterparts. set_intr_gate() requires a trace_debug symbol which we don't have and won't use. This patch separates set_intr_gate() into two parts, and uses base version in early_trap_init(). Reported-by: Andy Lutomirski Signed-off-by: Wang Nan Acked-by: Andy Lutomirski Cc: Cc: Cc: Cc: Cc: Cc: Borislav Petkov Cc: H. Peter Anvin Cc: Thomas Gleixner Link: http://lkml.kernel.org/r/1425010789-13714-1-git-send-email-wangnan0@huawei.com Signed-off-by: Ingo Molnar --- arch/x86/include/asm/desc.h | 7 ++++++- arch/x86/kernel/traps.c | 20 ++++++++++++-------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h index a94b82e8f156..a0bf89fd2647 100644 --- a/arch/x86/include/asm/desc.h +++ b/arch/x86/include/asm/desc.h @@ -376,11 +376,16 @@ static inline void _set_gate(int gate, unsigned type, void *addr, * Pentium F0 0F bugfix can have resulted in the mapped * IDT being write-protected. */ -#define set_intr_gate(n, addr) \ +#define set_intr_gate_notrace(n, addr) \ do { \ BUG_ON((unsigned)n > 0xFF); \ _set_gate(n, GATE_INTERRUPT, (void *)addr, 0, 0, \ __KERNEL_CS); \ + } while (0) + +#define set_intr_gate(n, addr) \ + do { \ + set_intr_gate_notrace(n, addr); \ _trace_set_gate(n, GATE_INTERRUPT, (void *)trace_##addr,\ 0, 0, __KERNEL_CS); \ } while (0) diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 42819886be0c..9965bd1916db 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -926,16 +926,20 @@ dotraplinkage void do_iret_error(struct pt_regs *regs, long error_code) void __init early_trap_init(void) { /* - * Don't set ist to DEBUG_STACK as it doesn't work until TSS is - * ready in cpu_init() <-- trap_init(). Before trap_init(), CPU - * runs at ring 0 so it is impossible to hit an invalid stack. - * Using the original stack works well enough at this early - * stage. DEBUG_STACK will be equipped after cpu_init() in + * Don't use IST to set DEBUG_STACK as it doesn't work until TSS + * is ready in cpu_init() <-- trap_init(). Before trap_init(), + * CPU runs at ring 0 so it is impossible to hit an invalid + * stack. Using the original stack works well enough at this + * early stage. DEBUG_STACK will be equipped after cpu_init() in * trap_init(). + * + * We don't need to set trace_idt_table like set_intr_gate(), + * since we don't have trace_debug and it will be reset to + * 'debug' in trap_init() by set_intr_gate_ist(). */ - set_intr_gate_ist(X86_TRAP_DB, &debug, 0); + set_intr_gate_notrace(X86_TRAP_DB, debug); /* int3 can be called from all */ - set_system_intr_gate_ist(X86_TRAP_BP, &int3, 0); + set_system_intr_gate(X86_TRAP_BP, &int3); #ifdef CONFIG_X86_32 set_intr_gate(X86_TRAP_PF, page_fault); #endif @@ -1015,7 +1019,7 @@ void __init trap_init(void) /* * X86_TRAP_DB and X86_TRAP_BP have been set - * in early_trap_init(). However, DEBUG_STACK works only after + * in early_trap_init(). However, ITS works only after * cpu_init() loads TSS. See comments in early_trap_init(). */ set_intr_gate_ist(X86_TRAP_DB, &debug, DEBUG_STACK); -- GitLab From d136dfeec84bfe3e4238bacd23f21e161268deac Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Tue, 3 Mar 2015 14:22:31 +0000 Subject: [PATCH 02724/11651] drm: Pass in new and old plane state to prepare_fb and cleanup_fb Use cases like rotation require these hooks to have some context so they know how to prepare and cleanup the frame buffer correctly. For i915 specifically, object backing pages need to be mapped differently for different rotation modes and the driver needs to know which mapping to instantiate and which to tear down when transitioning between them. v2: Made passed in states const. (Daniel Vetter) [airlied: add mdp5 and atmel fixups] Signed-off-by: Tvrtko Ursulin Cc: Daniel Vetter Cc: dri-devel@lists.freedesktop.org Reviewed-by: Rob Clark Signed-off-by: Dave Airlie --- drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 3 ++- drivers/gpu/drm/drm_atomic_helper.c | 13 ++++++++----- drivers/gpu/drm/drm_plane_helper.c | 5 +++-- drivers/gpu/drm/i915/intel_display.c | 6 ++++-- drivers/gpu/drm/i915/intel_drv.h | 6 ++++-- drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c | 6 ++++-- drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 6 ++++-- drivers/gpu/drm/tegra/dc.c | 6 ++++-- include/drm/drm_plane_helper.h | 6 ++++-- 9 files changed, 37 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c index dbf97d999d40..be9fa8220499 100644 --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c @@ -712,7 +712,8 @@ static int atmel_hlcdc_plane_atomic_check(struct drm_plane *p, } static int atmel_hlcdc_plane_prepare_fb(struct drm_plane *p, - struct drm_framebuffer *fb) + struct drm_framebuffer *fb, + const struct drm_plane_state *new_state) { struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p); diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 28aa87510551..7715c40d4e74 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -1116,6 +1116,7 @@ int drm_atomic_helper_prepare_planes(struct drm_device *dev, for (i = 0; i < nplanes; i++) { struct drm_plane_helper_funcs *funcs; struct drm_plane *plane = state->planes[i]; + struct drm_plane_state *plane_state = state->plane_states[i]; struct drm_framebuffer *fb; if (!plane) @@ -1123,10 +1124,10 @@ int drm_atomic_helper_prepare_planes(struct drm_device *dev, funcs = plane->helper_private; - fb = state->plane_states[i]->fb; + fb = plane_state->fb; if (fb && funcs->prepare_fb) { - ret = funcs->prepare_fb(plane, fb); + ret = funcs->prepare_fb(plane, fb, plane_state); if (ret) goto fail; } @@ -1138,6 +1139,7 @@ fail: for (i--; i >= 0; i--) { struct drm_plane_helper_funcs *funcs; struct drm_plane *plane = state->planes[i]; + struct drm_plane_state *plane_state = state->plane_states[i]; struct drm_framebuffer *fb; if (!plane) @@ -1148,7 +1150,7 @@ fail: fb = state->plane_states[i]->fb; if (fb && funcs->cleanup_fb) - funcs->cleanup_fb(plane, fb); + funcs->cleanup_fb(plane, fb, plane_state); } @@ -1254,6 +1256,7 @@ void drm_atomic_helper_cleanup_planes(struct drm_device *dev, for (i = 0; i < nplanes; i++) { struct drm_plane_helper_funcs *funcs; struct drm_plane *plane = old_state->planes[i]; + struct drm_plane_state *plane_state = old_state->plane_states[i]; struct drm_framebuffer *old_fb; if (!plane) @@ -1261,10 +1264,10 @@ void drm_atomic_helper_cleanup_planes(struct drm_device *dev, funcs = plane->helper_private; - old_fb = old_state->plane_states[i]->fb; + old_fb = plane_state->fb; if (old_fb && funcs->cleanup_fb) - funcs->cleanup_fb(plane, old_fb); + funcs->cleanup_fb(plane, old_fb, plane_state); } } EXPORT_SYMBOL(drm_atomic_helper_cleanup_planes); diff --git a/drivers/gpu/drm/drm_plane_helper.c b/drivers/gpu/drm/drm_plane_helper.c index 5ba5792bfdba..813a06627eb3 100644 --- a/drivers/gpu/drm/drm_plane_helper.c +++ b/drivers/gpu/drm/drm_plane_helper.c @@ -437,7 +437,8 @@ int drm_plane_helper_commit(struct drm_plane *plane, if (plane_funcs->prepare_fb && plane_state->fb && plane_state->fb != old_fb) { - ret = plane_funcs->prepare_fb(plane, plane_state->fb); + ret = plane_funcs->prepare_fb(plane, plane_state->fb, + plane_state); if (ret) goto out; } @@ -487,7 +488,7 @@ int drm_plane_helper_commit(struct drm_plane *plane, } if (plane_funcs->cleanup_fb && old_fb) - plane_funcs->cleanup_fb(plane, old_fb); + plane_funcs->cleanup_fb(plane, old_fb, plane_state); out: if (plane_state) { if (plane->funcs->atomic_destroy_state) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 3b0fe9f1f3c9..c234af0379fc 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11776,7 +11776,8 @@ static void intel_shared_dpll_init(struct drm_device *dev) */ int intel_prepare_plane_fb(struct drm_plane *plane, - struct drm_framebuffer *fb) + struct drm_framebuffer *fb, + const struct drm_plane_state *new_state) { struct drm_device *dev = plane->dev; struct intel_plane *intel_plane = to_intel_plane(plane); @@ -11830,7 +11831,8 @@ intel_prepare_plane_fb(struct drm_plane *plane, */ void intel_cleanup_plane_fb(struct drm_plane *plane, - struct drm_framebuffer *fb) + struct drm_framebuffer *fb, + const struct drm_plane_state *old_state) { struct drm_device *dev = plane->dev; struct drm_i915_gem_object *obj = intel_fb_obj(fb); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 1de8e20474d7..58d11a8066d4 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -943,9 +943,11 @@ void intel_finish_page_flip(struct drm_device *dev, int pipe); void intel_finish_page_flip_plane(struct drm_device *dev, int plane); void intel_check_page_flip(struct drm_device *dev, int pipe); int intel_prepare_plane_fb(struct drm_plane *plane, - struct drm_framebuffer *fb); + struct drm_framebuffer *fb, + const struct drm_plane_state *new_state); void intel_cleanup_plane_fb(struct drm_plane *plane, - struct drm_framebuffer *fb); + struct drm_framebuffer *fb, + const struct drm_plane_state *old_state); int intel_plane_atomic_get_property(struct drm_plane *plane, const struct drm_plane_state *state, struct drm_property *property, diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c index cde25009203a..dbc068988377 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c @@ -83,7 +83,8 @@ static const struct drm_plane_funcs mdp4_plane_funcs = { }; static int mdp4_plane_prepare_fb(struct drm_plane *plane, - struct drm_framebuffer *fb) + struct drm_framebuffer *fb, + const struct drm_plane_state *new_state) { struct mdp4_plane *mdp4_plane = to_mdp4_plane(plane); struct mdp4_kms *mdp4_kms = get_kms(plane); @@ -93,7 +94,8 @@ static int mdp4_plane_prepare_fb(struct drm_plane *plane, } static void mdp4_plane_cleanup_fb(struct drm_plane *plane, - struct drm_framebuffer *fb) + struct drm_framebuffer *fb, + const struct drm_plane_state *old_state) { struct mdp4_plane *mdp4_plane = to_mdp4_plane(plane); struct mdp4_kms *mdp4_kms = get_kms(plane); diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c index 05cf9ab2a876..6bd48e246283 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c @@ -156,7 +156,8 @@ static const struct drm_plane_funcs mdp5_plane_funcs = { }; static int mdp5_plane_prepare_fb(struct drm_plane *plane, - struct drm_framebuffer *fb) + struct drm_framebuffer *fb, + const struct drm_plane_state *new_state) { struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane); struct mdp5_kms *mdp5_kms = get_kms(plane); @@ -166,7 +167,8 @@ static int mdp5_plane_prepare_fb(struct drm_plane *plane, } static void mdp5_plane_cleanup_fb(struct drm_plane *plane, - struct drm_framebuffer *fb) + struct drm_framebuffer *fb, + const struct drm_plane_state *old_state) { struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane); struct mdp5_kms *mdp5_kms = get_kms(plane); diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index 3aaa84ae2681..bc3e85186b88 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -472,13 +472,15 @@ static const struct drm_plane_funcs tegra_primary_plane_funcs = { }; static int tegra_plane_prepare_fb(struct drm_plane *plane, - struct drm_framebuffer *fb) + struct drm_framebuffer *fb, + const struct drm_plane_state *new_state) { return 0; } static void tegra_plane_cleanup_fb(struct drm_plane *plane, - struct drm_framebuffer *fb) + struct drm_framebuffer *fb, + const struct drm_plane_state *old_fb) { } diff --git a/include/drm/drm_plane_helper.h b/include/drm/drm_plane_helper.h index 31c11d36fae6..72ddab02ebd9 100644 --- a/include/drm/drm_plane_helper.h +++ b/include/drm/drm_plane_helper.h @@ -59,9 +59,11 @@ extern int drm_crtc_init(struct drm_device *dev, */ struct drm_plane_helper_funcs { int (*prepare_fb)(struct drm_plane *plane, - struct drm_framebuffer *fb); + struct drm_framebuffer *fb, + const struct drm_plane_state *new_state); void (*cleanup_fb)(struct drm_plane *plane, - struct drm_framebuffer *fb); + struct drm_framebuffer *fb, + const struct drm_plane_state *old_state); int (*atomic_check)(struct drm_plane *plane, struct drm_plane_state *state); -- GitLab From 956421fbb74c3a6261903f3836c0740187cf038b Mon Sep 17 00:00:00 2001 From: Andy Lutomirski Date: Thu, 5 Mar 2015 01:09:44 +0100 Subject: [PATCH 02725/11651] x86/asm/entry/64: Remove a bogus 'ret_from_fork' optimization 'ret_from_fork' checks TIF_IA32 to determine whether 'pt_regs' and the related state make sense for 'ret_from_sys_call'. This is entirely the wrong check. TS_COMPAT would make a little more sense, but there's really no point in keeping this optimization at all. This fixes a return to the wrong user CS if we came from int 0x80 in a 64-bit task. Signed-off-by: Andy Lutomirski Cc: Borislav Petkov Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Oleg Nesterov Cc: Thomas Gleixner Cc: Link: http://lkml.kernel.org/r/4710be56d76ef994ddf59087aad98c000fbab9a4.1424989793.git.luto@amacapital.net [ Backported from tip:x86/asm. ] Signed-off-by: Ingo Molnar --- arch/x86/kernel/entry_64.S | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index 10074ad9ebf8..1d74d161687c 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -269,11 +269,14 @@ ENTRY(ret_from_fork) testl $3, CS-ARGOFFSET(%rsp) # from kernel_thread? jz 1f - testl $_TIF_IA32, TI_flags(%rcx) # 32-bit compat task needs IRET - jnz int_ret_from_sys_call - - RESTORE_TOP_OF_STACK %rdi, -ARGOFFSET - jmp ret_from_sys_call # go to the SYSRET fastpath + /* + * By the time we get here, we have no idea whether our pt_regs, + * ti flags, and ti status came from the 64-bit SYSCALL fast path, + * the slow path, or one of the ia32entry paths. + * Use int_ret_from_sys_call to return, since it can safely handle + * all of the above. + */ + jmp int_ret_from_sys_call 1: subq $REST_SKIP, %rsp # leave space for volatiles -- GitLab From bb3ab878a29a3879669bb922bebce87b9a9af755 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 4 Mar 2015 13:14:20 +0100 Subject: [PATCH 02726/11651] ARM: shmobile: Enable bockw board in multiplatform defconfig Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/configs/shmobile_defconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm/configs/shmobile_defconfig b/arch/arm/configs/shmobile_defconfig index 11554158fa96..b58618e2d13c 100644 --- a/arch/arm/configs/shmobile_defconfig +++ b/arch/arm/configs/shmobile_defconfig @@ -14,6 +14,7 @@ CONFIG_ARCH_EMEV2=y CONFIG_ARCH_R7S72100=y CONFIG_ARCH_R8A73A4=y CONFIG_ARCH_R8A7740=y +CONFIG_ARCH_R8A7778=y CONFIG_ARCH_R8A7779=y CONFIG_ARCH_R8A7790=y CONFIG_ARCH_R8A7791=y @@ -137,6 +138,7 @@ CONFIG_V4L_MEM2MEM_DRIVERS=y CONFIG_VIDEO_RENESAS_VSP1=y # CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set CONFIG_VIDEO_ADV7180=y +CONFIG_VIDEO_ML86V7667=y CONFIG_DRM=y CONFIG_DRM_RCAR_DU=y CONFIG_FB_SH_MOBILE_LCDC=y @@ -171,6 +173,7 @@ CONFIG_LEDS_GPIO=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_RS5C372=y CONFIG_RTC_DRV_S35390A=y +CONFIG_RTC_DRV_RX8581=y CONFIG_DMADEVICES=y CONFIG_SH_DMAE=y CONFIG_RCAR_DMAC=y -- GitLab From ce9594c6b332fd6fe464e22a83b0e6e0a287aac6 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 27 Feb 2015 14:13:02 +0100 Subject: [PATCH 02727/11651] ASoC: ak4671: Fix control-less DAPM routes Routes without a control must use NULL for the control name. The ak4671 driver uses "NULL" instead in a few places. Previous to commit 5fe5b767dc6f ("ASoC: dapm: Do not pretend to support controls for non mixer/mux widgets") the DAPM core silently ignored non-NULL controls on non-mixer and non-mux routes. But starting with that commit it will complain and not add the route breaking the ak4671 driver in the process. This patch replaces the incorrect "NULL" control name with NULL to fix the issue. Fixes: 5fe5b767dc6f ("ASoC: dapm: Do not pretend to support controls for non mixer/mux widgets") Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- sound/soc/codecs/ak4671.c | 44 +++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c index 632e89f793a7..2a58b1dccd2f 100644 --- a/sound/soc/codecs/ak4671.c +++ b/sound/soc/codecs/ak4671.c @@ -343,25 +343,25 @@ static const struct snd_soc_dapm_widget ak4671_dapm_widgets[] = { }; static const struct snd_soc_dapm_route ak4671_intercon[] = { - {"DAC Left", "NULL", "PMPLL"}, - {"DAC Right", "NULL", "PMPLL"}, - {"ADC Left", "NULL", "PMPLL"}, - {"ADC Right", "NULL", "PMPLL"}, + {"DAC Left", NULL, "PMPLL"}, + {"DAC Right", NULL, "PMPLL"}, + {"ADC Left", NULL, "PMPLL"}, + {"ADC Right", NULL, "PMPLL"}, /* Outputs */ - {"LOUT1", "NULL", "LOUT1 Mixer"}, - {"ROUT1", "NULL", "ROUT1 Mixer"}, - {"LOUT2", "NULL", "LOUT2 Mix Amp"}, - {"ROUT2", "NULL", "ROUT2 Mix Amp"}, - {"LOUT3", "NULL", "LOUT3 Mixer"}, - {"ROUT3", "NULL", "ROUT3 Mixer"}, + {"LOUT1", NULL, "LOUT1 Mixer"}, + {"ROUT1", NULL, "ROUT1 Mixer"}, + {"LOUT2", NULL, "LOUT2 Mix Amp"}, + {"ROUT2", NULL, "ROUT2 Mix Amp"}, + {"LOUT3", NULL, "LOUT3 Mixer"}, + {"ROUT3", NULL, "ROUT3 Mixer"}, {"LOUT1 Mixer", "DACL", "DAC Left"}, {"ROUT1 Mixer", "DACR", "DAC Right"}, {"LOUT2 Mixer", "DACHL", "DAC Left"}, {"ROUT2 Mixer", "DACHR", "DAC Right"}, - {"LOUT2 Mix Amp", "NULL", "LOUT2 Mixer"}, - {"ROUT2 Mix Amp", "NULL", "ROUT2 Mixer"}, + {"LOUT2 Mix Amp", NULL, "LOUT2 Mixer"}, + {"ROUT2 Mix Amp", NULL, "ROUT2 Mixer"}, {"LOUT3 Mixer", "DACSL", "DAC Left"}, {"ROUT3 Mixer", "DACSR", "DAC Right"}, @@ -381,18 +381,18 @@ static const struct snd_soc_dapm_route ak4671_intercon[] = { {"LIN2", NULL, "Mic Bias"}, {"RIN2", NULL, "Mic Bias"}, - {"ADC Left", "NULL", "LIN MUX"}, - {"ADC Right", "NULL", "RIN MUX"}, + {"ADC Left", NULL, "LIN MUX"}, + {"ADC Right", NULL, "RIN MUX"}, /* Analog Loops */ - {"LIN1 Mixing Circuit", "NULL", "LIN1"}, - {"RIN1 Mixing Circuit", "NULL", "RIN1"}, - {"LIN2 Mixing Circuit", "NULL", "LIN2"}, - {"RIN2 Mixing Circuit", "NULL", "RIN2"}, - {"LIN3 Mixing Circuit", "NULL", "LIN3"}, - {"RIN3 Mixing Circuit", "NULL", "RIN3"}, - {"LIN4 Mixing Circuit", "NULL", "LIN4"}, - {"RIN4 Mixing Circuit", "NULL", "RIN4"}, + {"LIN1 Mixing Circuit", NULL, "LIN1"}, + {"RIN1 Mixing Circuit", NULL, "RIN1"}, + {"LIN2 Mixing Circuit", NULL, "LIN2"}, + {"RIN2 Mixing Circuit", NULL, "RIN2"}, + {"LIN3 Mixing Circuit", NULL, "LIN3"}, + {"RIN3 Mixing Circuit", NULL, "RIN3"}, + {"LIN4 Mixing Circuit", NULL, "LIN4"}, + {"RIN4 Mixing Circuit", NULL, "RIN4"}, {"LOUT1 Mixer", "LINL1", "LIN1 Mixing Circuit"}, {"ROUT1 Mixer", "RINR1", "RIN1 Mixing Circuit"}, -- GitLab From 8e6a75c102f8e232b599a06e06731d8c5d5f2c5d Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 27 Feb 2015 14:13:03 +0100 Subject: [PATCH 02728/11651] ASoC: da732x: Fix control-less DAPM routes Routes without a control must use NULL for the control name. The da732x driver uses "NULL" instead in a few places. Previous to commit 5fe5b767dc6f ("ASoC: dapm: Do not pretend to support controls for non mixer/mux widgets") the DAPM core silently ignored non-NULL controls on non-mixer and non-mux routes. But starting with that commit it will complain and not add the route breaking the da732x driver in the process. This patch replaces the incorrect "NULL" control name with NULL to fix the issue. Fixes: 5fe5b767dc6f ("ASoC: dapm: Do not pretend to support controls for non mixer/mux widgets") Signed-off-by: Lars-Peter Clausen Acked-by: Adam Thomson Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- sound/soc/codecs/da732x.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/da732x.c b/sound/soc/codecs/da732x.c index ffe96175a8a5..911c26c705fc 100644 --- a/sound/soc/codecs/da732x.c +++ b/sound/soc/codecs/da732x.c @@ -876,11 +876,11 @@ static const struct snd_soc_dapm_widget da732x_dapm_widgets[] = { static const struct snd_soc_dapm_route da732x_dapm_routes[] = { /* Inputs */ - {"AUX1L PGA", "NULL", "AUX1L"}, - {"AUX1R PGA", "NULL", "AUX1R"}, + {"AUX1L PGA", NULL, "AUX1L"}, + {"AUX1R PGA", NULL, "AUX1R"}, {"MIC1 PGA", NULL, "MIC1"}, - {"MIC2 PGA", "NULL", "MIC2"}, - {"MIC3 PGA", "NULL", "MIC3"}, + {"MIC2 PGA", NULL, "MIC2"}, + {"MIC3 PGA", NULL, "MIC3"}, /* Capture Path */ {"ADC1 Left MUX", "MIC1", "MIC1 PGA"}, -- GitLab From cdd3d2a93f08823a0b9802147dc28c99029dfdfd Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 27 Feb 2015 14:13:04 +0100 Subject: [PATCH 02729/11651] ASoC: sn95031: Fix control-less DAPM routes Routes without a control must use NULL for the control name. The sn95031 driver uses "NULL" instead in a few places. Previous to commit 5fe5b767dc6f ("ASoC: dapm: Do not pretend to support controls for non mixer/mux widgets") the DAPM core silently ignored non-NULL controls on non-mixer and non-mux routes. But starting with that commit it will complain and not add the route breaking the sn95031 driver in the process. This patch replaces the incorrect "NULL" control name with NULL to fix the issue. Fixes: 5fe5b767dc6f ("ASoC: dapm: Do not pretend to support controls for non mixer/mux widgets") Signed-off-by: Lars-Peter Clausen Acked-by: Vinod Koul Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- sound/soc/codecs/sn95031.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/sn95031.c b/sound/soc/codecs/sn95031.c index 47b257e41809..82095d6cd070 100644 --- a/sound/soc/codecs/sn95031.c +++ b/sound/soc/codecs/sn95031.c @@ -538,8 +538,8 @@ static const struct snd_soc_dapm_route sn95031_audio_map[] = { /* speaker map */ { "IHFOUTL", NULL, "Speaker Rail"}, { "IHFOUTR", NULL, "Speaker Rail"}, - { "IHFOUTL", "NULL", "Speaker Left Playback"}, - { "IHFOUTR", "NULL", "Speaker Right Playback"}, + { "IHFOUTL", NULL, "Speaker Left Playback"}, + { "IHFOUTR", NULL, "Speaker Right Playback"}, { "Speaker Left Playback", NULL, "Speaker Left Filter"}, { "Speaker Right Playback", NULL, "Speaker Right Filter"}, { "Speaker Left Filter", NULL, "IHFDAC Left"}, -- GitLab From 90aff15b3e0858eaefdcd390e64849542845d489 Mon Sep 17 00:00:00 2001 From: "Maciej S. Szmigiero" Date: Wed, 4 Mar 2015 22:48:30 +0100 Subject: [PATCH 02730/11651] fsl_ssi: fix of_property_read_u32_array return value check of_property_read_u32_array returns 0 on success, so the return value shouldn't be inverted twice, first on assignment then in condition expression. Signed-off-by: Maciej Szmigiero Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_ssi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index d7365c5d7ec0..134388f7d1b8 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -1227,7 +1227,7 @@ static int fsl_ssi_imx_probe(struct platform_device *pdev, ssi_private->dma_params_tx.addr = ssi_private->ssi_phys + CCSR_SSI_STX0; ssi_private->dma_params_rx.addr = ssi_private->ssi_phys + CCSR_SSI_SRX0; - ret = !of_property_read_u32_array(np, "dmas", dmas, 4); + ret = of_property_read_u32_array(np, "dmas", dmas, 4); if (ssi_private->use_dma && !ret && dmas[2] == IMX_DMATYPE_SSI_DUAL) { ssi_private->use_dual_fifo = true; /* When using dual fifo mode, we need to keep watermark -- GitLab From bbed297d373471c8e4c3183bf67472a768576664 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Sun, 22 Feb 2015 16:43:21 +0000 Subject: [PATCH 02731/11651] ASoC: wm8804: Split out bus drivers Simplify dependencies by using new style split out bus interfaces. Signed-off-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/Kconfig | 18 ++++- sound/soc/codecs/Makefile | 4 + sound/soc/codecs/wm8804-i2c.c | 64 ++++++++++++++++ sound/soc/codecs/wm8804-spi.c | 56 ++++++++++++++ sound/soc/codecs/wm8804.c | 139 ++++------------------------------ sound/soc/codecs/wm8804.h | 7 ++ 6 files changed, 162 insertions(+), 126 deletions(-) create mode 100644 sound/soc/codecs/wm8804-i2c.c create mode 100644 sound/soc/codecs/wm8804-spi.c diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 064e6c18e109..1d17988df796 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -141,7 +141,8 @@ config SND_SOC_ALL_CODECS select SND_SOC_WM8770 if SPI_MASTER select SND_SOC_WM8776 if SND_SOC_I2C_AND_SPI select SND_SOC_WM8782 - select SND_SOC_WM8804 if SND_SOC_I2C_AND_SPI + select SND_SOC_WM8804_I2C if I2C + select SND_SOC_WM8804_SPI if SPI_MASTER select SND_SOC_WM8900 if I2C select SND_SOC_WM8903 if I2C select SND_SOC_WM8904 if I2C @@ -744,8 +745,19 @@ config SND_SOC_WM8782 tristate config SND_SOC_WM8804 - tristate "Wolfson Microelectronics WM8804 S/PDIF transceiver" - depends on SND_SOC_I2C_AND_SPI + tristate + +config SND_SOC_WM8804_I2C + tristate "Wolfson Microelectronics WM8804 S/PDIF transceiver I2C" + depends on I2C + select SND_SOC_WM8804 + select REGMAP_I2C + +config SND_SOC_WM8804_SPI + tristate "Wolfson Microelectronics WM8804 S/PDIF transceiver SPI" + depends on SPI_MASTER + select SND_SOC_WM8804 + select REGMAP_SPI config SND_SOC_WM8900 tristate diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 69b8666d187a..7acb6c174cb4 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -145,6 +145,8 @@ snd-soc-wm8770-objs := wm8770.o snd-soc-wm8776-objs := wm8776.o snd-soc-wm8782-objs := wm8782.o snd-soc-wm8804-objs := wm8804.o +snd-soc-wm8804-i2c-objs := wm8804-i2c.o +snd-soc-wm8804-spi-objs := wm8804-spi.o snd-soc-wm8900-objs := wm8900.o snd-soc-wm8903-objs := wm8903.o snd-soc-wm8904-objs := wm8904.o @@ -323,6 +325,8 @@ obj-$(CONFIG_SND_SOC_WM8770) += snd-soc-wm8770.o obj-$(CONFIG_SND_SOC_WM8776) += snd-soc-wm8776.o obj-$(CONFIG_SND_SOC_WM8782) += snd-soc-wm8782.o obj-$(CONFIG_SND_SOC_WM8804) += snd-soc-wm8804.o +obj-$(CONFIG_SND_SOC_WM8804_I2C) += snd-soc-wm8804-i2c.o +obj-$(CONFIG_SND_SOC_WM8804_SPI) += snd-soc-wm8804-spi.o obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o obj-$(CONFIG_SND_SOC_WM8904) += snd-soc-wm8904.o diff --git a/sound/soc/codecs/wm8804-i2c.c b/sound/soc/codecs/wm8804-i2c.c new file mode 100644 index 000000000000..5bd4af2b4059 --- /dev/null +++ b/sound/soc/codecs/wm8804-i2c.c @@ -0,0 +1,64 @@ +/* + * wm8804-i2c.c -- WM8804 S/PDIF transceiver driver - I2C + * + * Copyright 2015 Cirrus Logic Inc + * + * Author: Charles Keepax + * + * 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 +#include +#include + +#include "wm8804.h" + +static int wm8804_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + struct regmap *regmap; + + regmap = devm_regmap_init_i2c(i2c, &wm8804_regmap_config); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + return wm8804_probe(&i2c->dev, regmap); +} + +static int wm8804_i2c_remove(struct i2c_client *i2c) +{ + wm8804_remove(&i2c->dev); + return 0; +} + +static const struct i2c_device_id wm8804_i2c_id[] = { + { "wm8804", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, wm8804_i2c_id); + +static const struct of_device_id wm8804_of_match[] = { + { .compatible = "wlf,wm8804", }, + { } +}; +MODULE_DEVICE_TABLE(of, wm8804_of_match); + +static struct i2c_driver wm8804_i2c_driver = { + .driver = { + .name = "wm8804", + .owner = THIS_MODULE, + .of_match_table = wm8804_of_match, + }, + .probe = wm8804_i2c_probe, + .remove = wm8804_i2c_remove, + .id_table = wm8804_i2c_id +}; + +module_i2c_driver(wm8804_i2c_driver); + +MODULE_DESCRIPTION("ASoC WM8804 driver - I2C"); +MODULE_AUTHOR("Charles Keepax "); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/wm8804-spi.c b/sound/soc/codecs/wm8804-spi.c new file mode 100644 index 000000000000..287e11e90794 --- /dev/null +++ b/sound/soc/codecs/wm8804-spi.c @@ -0,0 +1,56 @@ +/* + * wm8804-spi.c -- WM8804 S/PDIF transceiver driver - SPI + * + * Copyright 2015 Cirrus Logic Inc + * + * Author: Charles Keepax + * + * 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 +#include +#include + +#include "wm8804.h" + +static int wm8804_spi_probe(struct spi_device *spi) +{ + struct regmap *regmap; + + regmap = devm_regmap_init_spi(spi, &wm8804_regmap_config); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + return wm8804_probe(&spi->dev, regmap); +} + +static int wm8804_spi_remove(struct spi_device *spi) +{ + wm8804_remove(&spi->dev); + return 0; +} + +static const struct of_device_id wm8804_of_match[] = { + { .compatible = "wlf,wm8804", }, + { } +}; +MODULE_DEVICE_TABLE(of, wm8804_of_match); + +static struct spi_driver wm8804_spi_driver = { + .driver = { + .name = "wm8804", + .owner = THIS_MODULE, + .of_match_table = wm8804_of_match, + }, + .probe = wm8804_spi_probe, + .remove = wm8804_spi_remove +}; + +module_spi_driver(wm8804_spi_driver); + +MODULE_DESCRIPTION("ASoC WM8804 driver - SPI"); +MODULE_AUTHOR("Charles Keepax "); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c index b2b0e68f707e..b5a04fc5060f 100644 --- a/sound/soc/codecs/wm8804.c +++ b/sound/soc/codecs/wm8804.c @@ -15,10 +15,7 @@ #include #include #include -#include #include -#include -#include #include #include #include @@ -518,7 +515,7 @@ static int wm8804_set_bias_level(struct snd_soc_codec *codec, return 0; } -static int wm8804_remove(struct snd_soc_codec *codec) +static int wm8804_codec_remove(struct snd_soc_codec *codec) { struct wm8804_priv *wm8804; int i; @@ -531,7 +528,7 @@ static int wm8804_remove(struct snd_soc_codec *codec) return 0; } -static int wm8804_probe(struct snd_soc_codec *codec) +static int wm8804_codec_probe(struct snd_soc_codec *codec) { struct wm8804_priv *wm8804; int i, id1, id2, ret; @@ -649,8 +646,8 @@ static struct snd_soc_dai_driver wm8804_dai = { }; static const struct snd_soc_codec_driver soc_codec_dev_wm8804 = { - .probe = wm8804_probe, - .remove = wm8804_remove, + .probe = wm8804_codec_probe, + .remove = wm8804_codec_remove, .set_bias_level = wm8804_set_bias_level, .idle_bias_off = true, @@ -658,13 +655,7 @@ static const struct snd_soc_codec_driver soc_codec_dev_wm8804 = { .num_controls = ARRAY_SIZE(wm8804_snd_controls), }; -static const struct of_device_id wm8804_of_match[] = { - { .compatible = "wlf,wm8804", }, - { } -}; -MODULE_DEVICE_TABLE(of, wm8804_of_match); - -static const struct regmap_config wm8804_regmap_config = { +const struct regmap_config wm8804_regmap_config = { .reg_bits = 8, .val_bits = 8, @@ -675,128 +666,30 @@ static const struct regmap_config wm8804_regmap_config = { .reg_defaults = wm8804_reg_defaults, .num_reg_defaults = ARRAY_SIZE(wm8804_reg_defaults), }; +EXPORT_SYMBOL_GPL(wm8804_regmap_config); -#if defined(CONFIG_SPI_MASTER) -static int wm8804_spi_probe(struct spi_device *spi) +int wm8804_probe(struct device *dev, struct regmap *regmap) { struct wm8804_priv *wm8804; - int ret; - wm8804 = devm_kzalloc(&spi->dev, sizeof *wm8804, GFP_KERNEL); + wm8804 = devm_kzalloc(dev, sizeof(*wm8804), GFP_KERNEL); if (!wm8804) return -ENOMEM; - wm8804->regmap = devm_regmap_init_spi(spi, &wm8804_regmap_config); - if (IS_ERR(wm8804->regmap)) { - ret = PTR_ERR(wm8804->regmap); - return ret; - } - - spi_set_drvdata(spi, wm8804); + dev_set_drvdata(dev, wm8804); - ret = snd_soc_register_codec(&spi->dev, - &soc_codec_dev_wm8804, &wm8804_dai, 1); - - return ret; -} - -static int wm8804_spi_remove(struct spi_device *spi) -{ - snd_soc_unregister_codec(&spi->dev); - return 0; -} - -static struct spi_driver wm8804_spi_driver = { - .driver = { - .name = "wm8804", - .owner = THIS_MODULE, - .of_match_table = wm8804_of_match, - }, - .probe = wm8804_spi_probe, - .remove = wm8804_spi_remove -}; -#endif - -#if IS_ENABLED(CONFIG_I2C) -static int wm8804_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) -{ - struct wm8804_priv *wm8804; - int ret; - - wm8804 = devm_kzalloc(&i2c->dev, sizeof *wm8804, GFP_KERNEL); - if (!wm8804) - return -ENOMEM; + wm8804->regmap = regmap; - wm8804->regmap = devm_regmap_init_i2c(i2c, &wm8804_regmap_config); - if (IS_ERR(wm8804->regmap)) { - ret = PTR_ERR(wm8804->regmap); - return ret; - } - - i2c_set_clientdata(i2c, wm8804); - - ret = snd_soc_register_codec(&i2c->dev, - &soc_codec_dev_wm8804, &wm8804_dai, 1); - return ret; -} - -static int wm8804_i2c_remove(struct i2c_client *i2c) -{ - snd_soc_unregister_codec(&i2c->dev); - return 0; -} - -static const struct i2c_device_id wm8804_i2c_id[] = { - { "wm8804", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, wm8804_i2c_id); - -static struct i2c_driver wm8804_i2c_driver = { - .driver = { - .name = "wm8804", - .owner = THIS_MODULE, - .of_match_table = wm8804_of_match, - }, - .probe = wm8804_i2c_probe, - .remove = wm8804_i2c_remove, - .id_table = wm8804_i2c_id -}; -#endif - -static int __init wm8804_modinit(void) -{ - int ret = 0; - -#if IS_ENABLED(CONFIG_I2C) - ret = i2c_add_driver(&wm8804_i2c_driver); - if (ret) { - printk(KERN_ERR "Failed to register wm8804 I2C driver: %d\n", - ret); - } -#endif -#if defined(CONFIG_SPI_MASTER) - ret = spi_register_driver(&wm8804_spi_driver); - if (ret != 0) { - printk(KERN_ERR "Failed to register wm8804 SPI driver: %d\n", - ret); - } -#endif - return ret; + return snd_soc_register_codec(dev, &soc_codec_dev_wm8804, + &wm8804_dai, 1); } -module_init(wm8804_modinit); +EXPORT_SYMBOL_GPL(wm8804_probe); -static void __exit wm8804_exit(void) +void wm8804_remove(struct device *dev) { -#if IS_ENABLED(CONFIG_I2C) - i2c_del_driver(&wm8804_i2c_driver); -#endif -#if defined(CONFIG_SPI_MASTER) - spi_unregister_driver(&wm8804_spi_driver); -#endif + snd_soc_unregister_codec(dev); } -module_exit(wm8804_exit); +EXPORT_SYMBOL_GPL(wm8804_remove); MODULE_DESCRIPTION("ASoC WM8804 driver"); MODULE_AUTHOR("Dimitris Papastamos "); diff --git a/sound/soc/codecs/wm8804.h b/sound/soc/codecs/wm8804.h index e72d4f4ba6b1..a39a2563dc67 100644 --- a/sound/soc/codecs/wm8804.h +++ b/sound/soc/codecs/wm8804.h @@ -13,6 +13,8 @@ #ifndef _WM8804_H #define _WM8804_H +#include + /* * Register values. */ @@ -62,4 +64,9 @@ #define WM8804_MCLKDIV_256FS 0 #define WM8804_MCLKDIV_128FS 1 +extern const struct regmap_config wm8804_regmap_config; + +int wm8804_probe(struct device *dev, struct regmap *regmap); +void wm8804_remove(struct device *dev); + #endif /* _WM8804_H */ -- GitLab From 6f2c9348095ae1a489abafe2ab3db7deca406e49 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Sun, 22 Feb 2015 16:43:22 +0000 Subject: [PATCH 02732/11651] ASoC: wm8804: Merge CODEC probe and bus probe All of the things in the CODEC probe, such as getting the regulators and verifying the chip ID, are better done in bus probe. It is better to fail during bus probe if this is the wrong chip and all resource allocation should be done in the bus probe anyway. This patch merges the CODEC probe into bus probe. Signed-off-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm8804.c | 180 +++++++++++++++++--------------------- 1 file changed, 82 insertions(+), 98 deletions(-) diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c index b5a04fc5060f..1bd4ace29594 100644 --- a/sound/soc/codecs/wm8804.c +++ b/sound/soc/codecs/wm8804.c @@ -182,9 +182,9 @@ static bool wm8804_volatile(struct device *dev, unsigned int reg) } } -static int wm8804_reset(struct snd_soc_codec *codec) +static int wm8804_reset(struct wm8804_priv *wm8804) { - return snd_soc_write(codec, WM8804_RST_DEVID1, 0x0); + return regmap_write(wm8804->regmap, WM8804_RST_DEVID1, 0x0); } static int wm8804_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) @@ -515,100 +515,6 @@ static int wm8804_set_bias_level(struct snd_soc_codec *codec, return 0; } -static int wm8804_codec_remove(struct snd_soc_codec *codec) -{ - struct wm8804_priv *wm8804; - int i; - - wm8804 = snd_soc_codec_get_drvdata(codec); - - for (i = 0; i < ARRAY_SIZE(wm8804->supplies); ++i) - regulator_unregister_notifier(wm8804->supplies[i].consumer, - &wm8804->disable_nb[i]); - return 0; -} - -static int wm8804_codec_probe(struct snd_soc_codec *codec) -{ - struct wm8804_priv *wm8804; - int i, id1, id2, ret; - - wm8804 = snd_soc_codec_get_drvdata(codec); - - for (i = 0; i < ARRAY_SIZE(wm8804->supplies); i++) - wm8804->supplies[i].supply = wm8804_supply_names[i]; - - ret = devm_regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8804->supplies), - wm8804->supplies); - if (ret) { - dev_err(codec->dev, "Failed to request supplies: %d\n", ret); - return ret; - } - - wm8804->disable_nb[0].notifier_call = wm8804_regulator_event_0; - wm8804->disable_nb[1].notifier_call = wm8804_regulator_event_1; - - /* This should really be moved into the regulator core */ - for (i = 0; i < ARRAY_SIZE(wm8804->supplies); i++) { - ret = regulator_register_notifier(wm8804->supplies[i].consumer, - &wm8804->disable_nb[i]); - if (ret != 0) { - dev_err(codec->dev, - "Failed to register regulator notifier: %d\n", - ret); - } - } - - ret = regulator_bulk_enable(ARRAY_SIZE(wm8804->supplies), - wm8804->supplies); - if (ret) { - dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); - return ret; - } - - id1 = snd_soc_read(codec, WM8804_RST_DEVID1); - if (id1 < 0) { - dev_err(codec->dev, "Failed to read device ID: %d\n", id1); - ret = id1; - goto err_reg_enable; - } - - id2 = snd_soc_read(codec, WM8804_DEVID2); - if (id2 < 0) { - dev_err(codec->dev, "Failed to read device ID: %d\n", id2); - ret = id2; - goto err_reg_enable; - } - - id2 = (id2 << 8) | id1; - - if (id2 != 0x8805) { - dev_err(codec->dev, "Invalid device ID: %#x\n", id2); - ret = -EINVAL; - goto err_reg_enable; - } - - ret = snd_soc_read(codec, WM8804_DEVREV); - if (ret < 0) { - dev_err(codec->dev, "Failed to read device revision: %d\n", - ret); - goto err_reg_enable; - } - dev_info(codec->dev, "revision %c\n", ret + 'A'); - - ret = wm8804_reset(codec); - if (ret < 0) { - dev_err(codec->dev, "Failed to issue reset: %d\n", ret); - goto err_reg_enable; - } - - return 0; - -err_reg_enable: - regulator_bulk_disable(ARRAY_SIZE(wm8804->supplies), wm8804->supplies); - return ret; -} - static const struct snd_soc_dai_ops wm8804_dai_ops = { .hw_params = wm8804_hw_params, .set_fmt = wm8804_set_fmt, @@ -646,8 +552,6 @@ static struct snd_soc_dai_driver wm8804_dai = { }; static const struct snd_soc_codec_driver soc_codec_dev_wm8804 = { - .probe = wm8804_codec_probe, - .remove = wm8804_codec_remove, .set_bias_level = wm8804_set_bias_level, .idle_bias_off = true, @@ -671,6 +575,8 @@ EXPORT_SYMBOL_GPL(wm8804_regmap_config); int wm8804_probe(struct device *dev, struct regmap *regmap) { struct wm8804_priv *wm8804; + unsigned int id1, id2; + int i, ret; wm8804 = devm_kzalloc(dev, sizeof(*wm8804), GFP_KERNEL); if (!wm8804) @@ -680,13 +586,91 @@ int wm8804_probe(struct device *dev, struct regmap *regmap) wm8804->regmap = regmap; + for (i = 0; i < ARRAY_SIZE(wm8804->supplies); i++) + wm8804->supplies[i].supply = wm8804_supply_names[i]; + + ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(wm8804->supplies), + wm8804->supplies); + if (ret) { + dev_err(dev, "Failed to request supplies: %d\n", ret); + return ret; + } + + wm8804->disable_nb[0].notifier_call = wm8804_regulator_event_0; + wm8804->disable_nb[1].notifier_call = wm8804_regulator_event_1; + + /* This should really be moved into the regulator core */ + for (i = 0; i < ARRAY_SIZE(wm8804->supplies); i++) { + ret = regulator_register_notifier(wm8804->supplies[i].consumer, + &wm8804->disable_nb[i]); + if (ret != 0) { + dev_err(dev, + "Failed to register regulator notifier: %d\n", + ret); + } + } + + ret = regulator_bulk_enable(ARRAY_SIZE(wm8804->supplies), + wm8804->supplies); + if (ret) { + dev_err(dev, "Failed to enable supplies: %d\n", ret); + goto err_reg_enable; + } + + ret = regmap_read(regmap, WM8804_RST_DEVID1, &id1); + if (ret < 0) { + dev_err(dev, "Failed to read device ID: %d\n", ret); + goto err_reg_enable; + } + + ret = regmap_read(regmap, WM8804_DEVID2, &id2); + if (ret < 0) { + dev_err(dev, "Failed to read device ID: %d\n", ret); + goto err_reg_enable; + } + + id2 = (id2 << 8) | id1; + + if (id2 != 0x8805) { + dev_err(dev, "Invalid device ID: %#x\n", id2); + ret = -EINVAL; + goto err_reg_enable; + } + + ret = regmap_read(regmap, WM8804_DEVREV, &id1); + if (ret < 0) { + dev_err(dev, "Failed to read device revision: %d\n", + ret); + goto err_reg_enable; + } + dev_info(dev, "revision %c\n", id1 + 'A'); + + ret = wm8804_reset(wm8804); + if (ret < 0) { + dev_err(dev, "Failed to issue reset: %d\n", ret); + goto err_reg_enable; + } + return snd_soc_register_codec(dev, &soc_codec_dev_wm8804, &wm8804_dai, 1); + +err_reg_enable: + regulator_bulk_disable(ARRAY_SIZE(wm8804->supplies), wm8804->supplies); + return ret; } EXPORT_SYMBOL_GPL(wm8804_probe); void wm8804_remove(struct device *dev) { + struct wm8804_priv *wm8804; + int i; + + wm8804 = dev_get_drvdata(dev); + + for (i = 0; i < ARRAY_SIZE(wm8804->supplies); ++i) + regulator_unregister_notifier(wm8804->supplies[i].consumer, + &wm8804->disable_nb[i]); + snd_soc_unregister_codec(dev); } EXPORT_SYMBOL_GPL(wm8804_remove); -- GitLab From 4f6e24ed9de8634d6471ef86b382cba6d4e57ca8 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 5 Mar 2015 10:45:30 +1030 Subject: [PATCH 02733/11651] virtio_console: init work unconditionally when multiport is off, we don't initialize config work, but we then cancel uninitialized control_work on freeze. Signed-off-by: Michael S. Tsirkin Reviewed-by: Amit Shah Signed-off-by: Rusty Russell Cc: stable@kernel.org --- drivers/char/virtio_console.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index fae2dbbf5745..def736ddfc0e 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -2040,12 +2040,13 @@ static int virtcons_probe(struct virtio_device *vdev) virtio_device_ready(portdev->vdev); + INIT_WORK(&portdev->control_work, &control_work_handler); + if (multiport) { unsigned int nr_added_bufs; spin_lock_init(&portdev->c_ivq_lock); spin_lock_init(&portdev->c_ovq_lock); - INIT_WORK(&portdev->control_work, &control_work_handler); nr_added_bufs = fill_queue(portdev->c_ivq, &portdev->c_ivq_lock); -- GitLab From eeb8a7e8bb123e84daeef84f5a2eab99ad2839a2 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 5 Mar 2015 10:45:49 +1030 Subject: [PATCH 02734/11651] virtio_console: avoid config access from irq when multiport is off, virtio console invokes config access from irq context, config access is blocking on s390. Fix this up by scheduling work from config irq - similar to what we do for multiport configs. Signed-off-by: Michael S. Tsirkin Reviewed-by: Amit Shah Signed-off-by: Rusty Russell Cc: stable@kernel.org --- drivers/char/virtio_console.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index def736ddfc0e..72d7028f779b 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -142,6 +142,7 @@ struct ports_device { * notification */ struct work_struct control_work; + struct work_struct config_work; struct list_head ports; @@ -1837,10 +1838,21 @@ static void config_intr(struct virtio_device *vdev) portdev = vdev->priv; + if (!use_multiport(portdev)) + schedule_work(&portdev->config_work); +} + +static void config_work_handler(struct work_struct *work) +{ + struct ports_device *portdev; + + portdev = container_of(work, struct ports_device, control_work); if (!use_multiport(portdev)) { + struct virtio_device *vdev; struct port *port; u16 rows, cols; + vdev = portdev->vdev; virtio_cread(vdev, struct virtio_console_config, cols, &cols); virtio_cread(vdev, struct virtio_console_config, rows, &rows); @@ -2040,6 +2052,7 @@ static int virtcons_probe(struct virtio_device *vdev) virtio_device_ready(portdev->vdev); + INIT_WORK(&portdev->config_work, &config_work_handler); INIT_WORK(&portdev->control_work, &control_work_handler); if (multiport) { @@ -2114,6 +2127,8 @@ static void virtcons_remove(struct virtio_device *vdev) /* Finish up work that's lined up */ if (use_multiport(portdev)) cancel_work_sync(&portdev->control_work); + else + cancel_work_sync(&portdev->config_work); list_for_each_entry_safe(port, port2, &portdev->ports, list) unplug_port(port); @@ -2165,6 +2180,7 @@ static int virtcons_freeze(struct virtio_device *vdev) virtqueue_disable_cb(portdev->c_ivq); cancel_work_sync(&portdev->control_work); + cancel_work_sync(&portdev->config_work); /* * Once more: if control_work_handler() was running, it would * enable the cb as the last step. -- GitLab From 270bd400e8030ed921e80f334c3ebf274fd93037 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 5 Mar 2015 10:47:49 +1030 Subject: [PATCH 02735/11651] cpumask: fix cpu-hotplug documentation It refers to an obsolete function. Signed-off-by: Rusty Russell Cc: Jonathan Corbet Cc: linux-doc@vger.kernel.org --- Documentation/cpu-hotplug.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/cpu-hotplug.txt b/Documentation/cpu-hotplug.txt index a0b005d2bd95..f9ad5e048b11 100644 --- a/Documentation/cpu-hotplug.txt +++ b/Documentation/cpu-hotplug.txt @@ -108,7 +108,7 @@ Never use anything other than cpumask_t to represent bitmap of CPUs. for_each_possible_cpu - Iterate over cpu_possible_mask for_each_online_cpu - Iterate over cpu_online_mask for_each_present_cpu - Iterate over cpu_present_mask - for_each_cpu_mask(x,mask) - Iterate over some random collection of cpu mask. + for_each_cpu(x,mask) - Iterate over some random collection of cpu mask. #include get_online_cpus() and put_online_cpus(): -- GitLab From 51f7bd8590267011db7b632f53f3d32ec83ee8bb Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 5 Mar 2015 10:48:49 +1030 Subject: [PATCH 02736/11651] ia64: Use for_each_cpu_and() and cpumask_any_and() instead of temp var. Just a bit of manual neatening, before spatch cleans the rest. Signed-off-by: Rusty Russell Cc: Tony Luck Cc: Fenghua Yu Cc: linux-ia64@vger.kernel.org --- arch/ia64/kernel/irq_ia64.c | 4 +--- arch/ia64/kernel/msi_ia64.c | 10 ++++------ 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c index 698d8fefde6c..3329177c262e 100644 --- a/arch/ia64/kernel/irq_ia64.c +++ b/arch/ia64/kernel/irq_ia64.c @@ -161,7 +161,6 @@ int bind_irq_vector(int irq, int vector, cpumask_t domain) static void __clear_irq_vector(int irq) { int vector, cpu; - cpumask_t mask; cpumask_t domain; struct irq_cfg *cfg = &irq_cfg[irq]; @@ -169,8 +168,7 @@ static void __clear_irq_vector(int irq) BUG_ON(cfg->vector == IRQ_VECTOR_UNASSIGNED); vector = cfg->vector; domain = cfg->domain; - cpumask_and(&mask, &cfg->domain, cpu_online_mask); - for_each_cpu_mask(cpu, mask) + for_each_cpu_and(cpu, &cfg->domain, cpu_online_mask) per_cpu(vector_irq, cpu)[vector] = -1; cfg->vector = IRQ_VECTOR_UNASSIGNED; cfg->domain = CPU_MASK_NONE; diff --git a/arch/ia64/kernel/msi_ia64.c b/arch/ia64/kernel/msi_ia64.c index 8ae36ea177d3..9dd7464f8c17 100644 --- a/arch/ia64/kernel/msi_ia64.c +++ b/arch/ia64/kernel/msi_ia64.c @@ -47,15 +47,14 @@ int ia64_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc) struct msi_msg msg; unsigned long dest_phys_id; int irq, vector; - cpumask_t mask; irq = create_irq(); if (irq < 0) return irq; irq_set_msi_desc(irq, desc); - cpumask_and(&mask, &(irq_to_domain(irq)), cpu_online_mask); - dest_phys_id = cpu_physical_id(first_cpu(mask)); + dest_phys_id = cpu_physical_id(cpumask_any_and(&(irq_to_domain(irq)), + cpu_online_mask)); vector = irq_to_vector(irq); msg.address_hi = 0; @@ -171,10 +170,9 @@ msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_msg *msg) { struct irq_cfg *cfg = irq_cfg + irq; unsigned dest; - cpumask_t mask; - cpumask_and(&mask, &(irq_to_domain(irq)), cpu_online_mask); - dest = cpu_physical_id(first_cpu(mask)); + dest = cpu_physical_id(cpumask_first_and(&(irq_to_domain(irq)), + cpu_online_mask)); msg->address_hi = 0; msg->address_lo = -- GitLab From f9b531fe14a539ec2ad802b73c9638f324e4a4ff Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 5 Mar 2015 10:49:16 +1030 Subject: [PATCH 02737/11651] drivers: fix up obsolete cpu function usage. Thanks to spatch, plus manual removal of "&*". Then a sweep for for_each_cpu_mask => for_each_cpu. Signed-off-by: Rusty Russell Acked-by: Rafael J. Wysocki Cc: Thomas Gleixner Cc: Herbert Xu Cc: Jason Cooper Cc: Chris Metcalf Cc: netdev@vger.kernel.org --- drivers/clocksource/dw_apb_timer.c | 3 ++- drivers/cpuidle/coupled.c | 6 +++--- drivers/crypto/n2_core.c | 4 ++-- drivers/irqchip/irq-gic-v3.c | 2 +- drivers/irqchip/irq-mips-gic.c | 6 +++--- drivers/net/ethernet/tile/tilegx.c | 4 ++-- 6 files changed, 13 insertions(+), 12 deletions(-) diff --git a/drivers/clocksource/dw_apb_timer.c b/drivers/clocksource/dw_apb_timer.c index f3656a6b0382..35a88097af3c 100644 --- a/drivers/clocksource/dw_apb_timer.c +++ b/drivers/clocksource/dw_apb_timer.c @@ -117,7 +117,8 @@ static void apbt_set_mode(enum clock_event_mode mode, unsigned long period; struct dw_apb_clock_event_device *dw_ced = ced_to_dw_apb_ced(evt); - pr_debug("%s CPU %d mode=%d\n", __func__, first_cpu(*evt->cpumask), + pr_debug("%s CPU %d mode=%d\n", __func__, + cpumask_first(evt->cpumask), mode); switch (mode) { diff --git a/drivers/cpuidle/coupled.c b/drivers/cpuidle/coupled.c index 73fe2f8d7f96..7936dce4b878 100644 --- a/drivers/cpuidle/coupled.c +++ b/drivers/cpuidle/coupled.c @@ -292,7 +292,7 @@ static inline int cpuidle_coupled_get_state(struct cpuidle_device *dev, */ smp_rmb(); - for_each_cpu_mask(i, coupled->coupled_cpus) + for_each_cpu(i, &coupled->coupled_cpus) if (cpu_online(i) && coupled->requested_state[i] < state) state = coupled->requested_state[i]; @@ -338,7 +338,7 @@ static void cpuidle_coupled_poke_others(int this_cpu, { int cpu; - for_each_cpu_mask(cpu, coupled->coupled_cpus) + for_each_cpu(cpu, &coupled->coupled_cpus) if (cpu != this_cpu && cpu_online(cpu)) cpuidle_coupled_poke(cpu); } @@ -638,7 +638,7 @@ int cpuidle_coupled_register_device(struct cpuidle_device *dev) if (cpumask_empty(&dev->coupled_cpus)) return 0; - for_each_cpu_mask(cpu, dev->coupled_cpus) { + for_each_cpu(cpu, &dev->coupled_cpus) { other_dev = per_cpu(cpuidle_devices, cpu); if (other_dev && other_dev->coupled) { coupled = other_dev->coupled; diff --git a/drivers/crypto/n2_core.c b/drivers/crypto/n2_core.c index afd136b45f49..10a9aeff1666 100644 --- a/drivers/crypto/n2_core.c +++ b/drivers/crypto/n2_core.c @@ -1754,7 +1754,7 @@ static int spu_mdesc_walk_arcs(struct mdesc_handle *mdesc, dev->dev.of_node->full_name); return -EINVAL; } - cpu_set(*id, p->sharing); + cpumask_set_cpu(*id, &p->sharing); table[*id] = p; } return 0; @@ -1776,7 +1776,7 @@ static int handle_exec_unit(struct spu_mdesc_info *ip, struct list_head *list, return -ENOMEM; } - cpus_clear(p->sharing); + cpumask_clear(&p->sharing); spin_lock_init(&p->lock); p->q_type = q_type; INIT_LIST_HEAD(&p->jobs); diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index 1c6dea2fbc34..04b6f0732c1a 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -512,7 +512,7 @@ static void gic_raise_softirq(const struct cpumask *mask, unsigned int irq) */ smp_wmb(); - for_each_cpu_mask(cpu, *mask) { + for_each_cpu(cpu, mask) { u64 cluster_id = cpu_logical_map(cpu) & ~0xffUL; u16 tlist; diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index 9acdc080e7ec..f26307908a2a 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c @@ -345,19 +345,19 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask, int i; cpumask_and(&tmp, cpumask, cpu_online_mask); - if (cpus_empty(tmp)) + if (cpumask_empty(&tmp)) return -EINVAL; /* Assumption : cpumask refers to a single CPU */ spin_lock_irqsave(&gic_lock, flags); /* Re-route this IRQ */ - gic_map_to_vpe(irq, first_cpu(tmp)); + gic_map_to_vpe(irq, cpumask_first(&tmp)); /* Update the pcpu_masks */ for (i = 0; i < NR_CPUS; i++) clear_bit(irq, pcpu_masks[i].pcpu_mask); - set_bit(irq, pcpu_masks[first_cpu(tmp)].pcpu_mask); + set_bit(irq, pcpu_masks[cpumask_first(&tmp)].pcpu_mask); cpumask_copy(d->affinity, cpumask); spin_unlock_irqrestore(&gic_lock, flags); diff --git a/drivers/net/ethernet/tile/tilegx.c b/drivers/net/ethernet/tile/tilegx.c index bea8cd2bb56c..deac41498c6e 100644 --- a/drivers/net/ethernet/tile/tilegx.c +++ b/drivers/net/ethernet/tile/tilegx.c @@ -1122,7 +1122,7 @@ static int alloc_percpu_mpipe_resources(struct net_device *dev, addr + i * sizeof(struct tile_net_comps); /* If this is a network cpu, create an iqueue. */ - if (cpu_isset(cpu, network_cpus_map)) { + if (cpumask_test_cpu(cpu, &network_cpus_map)) { order = get_order(NOTIF_RING_SIZE); page = homecache_alloc_pages(GFP_KERNEL, order, cpu); if (page == NULL) { @@ -1298,7 +1298,7 @@ static int tile_net_init_mpipe(struct net_device *dev) int first_ring, ring; int instance = mpipe_instance(dev); struct mpipe_data *md = &mpipe_data[instance]; - int network_cpus_count = cpus_weight(network_cpus_map); + int network_cpus_count = cpumask_weight(&network_cpus_map); if (!hash_default) { netdev_err(dev, "Networking requires hash_default!\n"); -- GitLab From 04b91701d471fbc09689b96d2e7c94ee3a0fff74 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 4 Mar 2015 23:39:18 +0100 Subject: [PATCH 02738/11651] ARM: fix typos in smc91x platform data I recently did a rework of the smc91x driver and did some build-testing by compiling hundreds of randconfig kernels. Unfortunately, my script was wrong and did not actually test the configurations that mattered, so I introduced stupid typos in almost every file I touched. I fixed my script now, built all configurations that actually matter and fixed all the typos, this is the result. Signed-off-by: Arnd Bergmann Fixes: b70661c70830d ("net: smc91x: use run-time configuration on all ARM machines") Signed-off-by: David S. Miller --- arch/arm/mach-pxa/idp.c | 1 + arch/arm/mach-pxa/lpd270.c | 2 +- arch/arm/mach-sa1100/neponset.c | 4 ++-- arch/arm/mach-sa1100/pleb.c | 2 +- drivers/net/ethernet/smsc/smc91x.c | 1 + 5 files changed, 6 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-pxa/idp.c b/arch/arm/mach-pxa/idp.c index 7d8eab857a93..f6d02e4cbcda 100644 --- a/arch/arm/mach-pxa/idp.c +++ b/arch/arm/mach-pxa/idp.c @@ -36,6 +36,7 @@ #include #include #include +#include #include "generic.h" #include "devices.h" diff --git a/arch/arm/mach-pxa/lpd270.c b/arch/arm/mach-pxa/lpd270.c index 28da319d389f..eaee2c20b189 100644 --- a/arch/arm/mach-pxa/lpd270.c +++ b/arch/arm/mach-pxa/lpd270.c @@ -195,7 +195,7 @@ static struct resource smc91x_resources[] = { }; struct smc91x_platdata smc91x_platdata = { - .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT; + .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT, }; static struct platform_device smc91x_device = { diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c index 7b0cd3172354..af868d258e66 100644 --- a/arch/arm/mach-sa1100/neponset.c +++ b/arch/arm/mach-sa1100/neponset.c @@ -268,8 +268,8 @@ static int neponset_probe(struct platform_device *dev) .id = 0, .res = smc91x_resources, .num_res = ARRAY_SIZE(smc91x_resources), - .data = &smc91c_platdata, - .size_data = sizeof(smc91c_platdata), + .data = &smc91x_platdata, + .size_data = sizeof(smc91x_platdata), }; int ret, irq; diff --git a/arch/arm/mach-sa1100/pleb.c b/arch/arm/mach-sa1100/pleb.c index 696fd0fe4806..1525d7b5f1b7 100644 --- a/arch/arm/mach-sa1100/pleb.c +++ b/arch/arm/mach-sa1100/pleb.c @@ -54,7 +54,7 @@ static struct platform_device smc91x_device = { .num_resources = ARRAY_SIZE(smc91x_resources), .resource = smc91x_resources, .dev = { - .platform_data = &smc91c_platdata, + .platform_data = &smc91x_platdata, }, }; diff --git a/drivers/net/ethernet/smsc/smc91x.c b/drivers/net/ethernet/smsc/smc91x.c index 209ee1b27f8d..5d093dc0f5f5 100644 --- a/drivers/net/ethernet/smsc/smc91x.c +++ b/drivers/net/ethernet/smsc/smc91x.c @@ -92,6 +92,7 @@ static const char version[] = #include "smc91x.h" #if defined(CONFIG_ASSABET_NEPONSET) +#include #include #endif -- GitLab From 7289e6ddb633aaee6ccea2bd2e410654c47b29a6 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Wed, 4 Mar 2015 14:58:19 -0800 Subject: [PATCH 02739/11651] fib_trie: Only resize tnodes once instead of on each leaf removal in fib_table_flush This change makes it so that we only call resize on the tnodes, instead of from each of the leaves. By doing this we can significantly reduce the amount of time spent resizing as we can update all of the leaves in the tnode first before we make any determinations about resizing. As a result we can simply free the tnode in the case that all of the leaves from a given tnode are flushed instead of resizing with each leaf removed. Signed-off-by: Alexander Duyck Signed-off-by: David S. Miller --- net/ipv4/fib_trie.c | 141 ++++++++++++++++++++++++-------------------- 1 file changed, 78 insertions(+), 63 deletions(-) diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index f48534577f8d..d8b68b4de532 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -1399,25 +1399,6 @@ found: } EXPORT_SYMBOL_GPL(fib_table_lookup); -/* - * Remove the leaf and return parent. - */ -static void trie_leaf_remove(struct trie *t, struct tnode *l) -{ - struct tnode *tp = node_parent(l); - - pr_debug("entering trie_leaf_remove(%p)\n", l); - - if (tp) { - put_child(tp, get_index(l->key, tp), NULL); - trie_rebalance(t, tp); - } else { - RCU_INIT_POINTER(t->trie, NULL); - } - - node_free(l); -} - /* * Caller must hold RTNL. */ @@ -1483,8 +1464,18 @@ int fib_table_delete(struct fib_table *tb, struct fib_config *cfg) if (!plen) tb->tb_num_default--; - if (hlist_empty(&l->leaf)) - trie_leaf_remove(t, l); + if (hlist_empty(&l->leaf)) { + struct tnode *tp = node_parent(l); + + if (tp) { + put_child(tp, get_index(l->key, tp), NULL); + trie_rebalance(t, tp); + } else { + RCU_INIT_POINTER(t->trie, NULL); + } + + node_free(l); + } if (fa->fa_state & FA_S_ACCESSED) rt_cache_flush(cfg->fc_nlinfo.nl_net); @@ -1494,33 +1485,6 @@ int fib_table_delete(struct fib_table *tb, struct fib_config *cfg) return 0; } -static int trie_flush_leaf(struct tnode *l) -{ - struct hlist_node *tmp; - unsigned char slen = 0; - struct fib_alias *fa; - int found = 0; - - hlist_for_each_entry_safe(fa, tmp, &l->leaf, fa_list) { - struct fib_info *fi = fa->fa_info; - - if (fi && (fi->fib_flags & RTNH_F_DEAD)) { - hlist_del_rcu(&fa->fa_list); - fib_release_info(fa->fa_info); - alias_free_mem_rcu(fa); - found++; - - continue; - } - - slen = fa->fa_slen; - } - - l->slen = slen; - - return found; -} - /* Scan for the next right leaf starting at node p->child[idx] * Since we have back pointer, no recursion necessary. */ @@ -1588,30 +1552,81 @@ static struct tnode *trie_leafindex(struct trie *t, int index) */ int fib_table_flush(struct fib_table *tb) { - struct trie *t = (struct trie *) tb->tb_data; - struct tnode *l, *ll = NULL; + struct trie *t = (struct trie *)tb->tb_data; + struct hlist_node *tmp; + struct fib_alias *fa; + struct tnode *n, *pn; + unsigned long cindex; + unsigned char slen; int found = 0; - for (l = trie_firstleaf(t); l; l = trie_nextleaf(l)) { - found += trie_flush_leaf(l); + n = rcu_dereference(t->trie); + if (!n) + goto flush_complete; + + pn = NULL; + cindex = 0; + + while (IS_TNODE(n)) { + /* record pn and cindex for leaf walking */ + pn = n; + cindex = 1ul << n->bits; +backtrace: + /* walk trie in reverse order */ + do { + while (!(cindex--)) { + t_key pkey = pn->key; + + n = pn; + pn = node_parent(n); + + /* resize completed node */ + resize(t, n); + + /* if we got the root we are done */ + if (!pn) + goto flush_complete; - if (ll) { - if (hlist_empty(&ll->leaf)) - trie_leaf_remove(t, ll); - else - leaf_pull_suffix(ll); + cindex = get_index(pkey, pn); + } + + /* grab the next available node */ + n = tnode_get_child(pn, cindex); + } while (!n); + } + + /* track slen in case any prefixes survive */ + slen = 0; + + hlist_for_each_entry_safe(fa, tmp, &n->leaf, fa_list) { + struct fib_info *fi = fa->fa_info; + + if (fi && (fi->fib_flags & RTNH_F_DEAD)) { + hlist_del_rcu(&fa->fa_list); + fib_release_info(fa->fa_info); + alias_free_mem_rcu(fa); + found++; + + continue; } - ll = l; + slen = fa->fa_slen; } - if (ll) { - if (hlist_empty(&ll->leaf)) - trie_leaf_remove(t, ll); - else - leaf_pull_suffix(ll); + /* update leaf slen */ + n->slen = slen; + + if (hlist_empty(&n->leaf)) { + put_child_root(pn, t, n->key, NULL); + node_free(n); + } else { + leaf_pull_suffix(n); } + /* if trie is leaf only loop is completed */ + if (pn) + goto backtrace; +flush_complete: pr_debug("trie_flush found=%d\n", found); return found; } -- GitLab From 8be33e955cb959dabc1a6eef0b7356fe8cf73fa6 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Wed, 4 Mar 2015 14:59:19 -0800 Subject: [PATCH 02740/11651] fib_trie: Fib walk rcu should take a tnode and key instead of a trie and a leaf This change makes it so that leaf_walk_rcu takes a tnode and a key instead of the trie and a leaf. The main idea behind this is to avoid using the leaf parent pointer as that can have additional overhead in the future as I am trying to reduce the size of a leaf down to 16 bytes on 64b systems and 12b on 32b systems. Signed-off-by: Alexander Duyck Signed-off-by: David S. Miller --- net/ipv4/fib_trie.c | 216 ++++++++++++++++++++++++-------------------- 1 file changed, 120 insertions(+), 96 deletions(-) diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index d8b68b4de532..bf488cee524a 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -1485,71 +1485,71 @@ int fib_table_delete(struct fib_table *tb, struct fib_config *cfg) return 0; } -/* Scan for the next right leaf starting at node p->child[idx] - * Since we have back pointer, no recursion necessary. - */ -static struct tnode *leaf_walk_rcu(struct tnode *p, struct tnode *c) +/* Scan for the next leaf starting at the provided key value */ +static struct tnode *leaf_walk_rcu(struct tnode **tn, t_key key) { - do { - unsigned long idx = c ? idx = get_index(c->key, p) + 1 : 0; - - while (idx < tnode_child_length(p)) { - c = tnode_get_child_rcu(p, idx++); - if (!c) - continue; - - if (IS_LEAF(c)) - return c; - - /* Rescan start scanning in new node */ - p = c; - idx = 0; - } + struct tnode *pn, *n = *tn; + unsigned long cindex; - /* Node empty, walk back up to parent */ - c = p; - } while ((p = node_parent_rcu(c)) != NULL); + /* record parent node for backtracing */ + pn = n; + cindex = n ? get_index(key, n) : 0; - return NULL; /* Root of trie */ -} + /* this loop is meant to try and find the key in the trie */ + while (n) { + unsigned long idx = get_index(key, n); -static struct tnode *trie_firstleaf(struct trie *t) -{ - struct tnode *n = rcu_dereference_rtnl(t->trie); + /* guarantee forward progress on the keys */ + if (IS_LEAF(n) && (n->key >= key)) + goto found; + if (idx >= (1ul << n->bits)) + break; - if (!n) - return NULL; + /* record parent and next child index */ + pn = n; + cindex = idx; - if (IS_LEAF(n)) /* trie is just a leaf */ - return n; + /* descend into the next child */ + n = tnode_get_child_rcu(pn, cindex++); + } - return leaf_walk_rcu(n, NULL); -} + /* this loop will search for the next leaf with a greater key */ + while (pn) { + /* if we exhausted the parent node we will need to climb */ + if (cindex >= (1ul << pn->bits)) { + t_key pkey = pn->key; -static struct tnode *trie_nextleaf(struct tnode *l) -{ - struct tnode *p = node_parent_rcu(l); + pn = node_parent_rcu(pn); + if (!pn) + break; - if (!p) - return NULL; /* trie with just one leaf */ + cindex = get_index(pkey, pn) + 1; + continue; + } - return leaf_walk_rcu(p, l); -} + /* grab the next available node */ + n = tnode_get_child_rcu(pn, cindex++); + if (!n) + continue; -static struct tnode *trie_leafindex(struct trie *t, int index) -{ - struct tnode *l = trie_firstleaf(t); + /* no need to compare keys since we bumped the index */ + if (IS_LEAF(n)) + goto found; - while (l && index-- > 0) - l = trie_nextleaf(l); + /* Rescan start scanning in new node */ + pn = n; + cindex = 0; + } - return l; + *tn = pn; + return NULL; /* Root of trie */ +found: + /* if we are at the limit for keys just return NULL for the tnode */ + *tn = (n->key == KEY_MAX) ? NULL : pn; + return n; } - -/* - * Caller must hold RTNL. - */ +/* Caller must hold RTNL. */ int fib_table_flush(struct fib_table *tb) { struct trie *t = (struct trie *)tb->tb_data; @@ -1680,42 +1680,42 @@ static int fn_trie_dump_leaf(struct tnode *l, struct fib_table *tb, int fib_table_dump(struct fib_table *tb, struct sk_buff *skb, struct netlink_callback *cb) { - struct tnode *l; - struct trie *t = (struct trie *) tb->tb_data; - t_key key = cb->args[2]; - int count = cb->args[3]; - - rcu_read_lock(); + struct trie *t = (struct trie *)tb->tb_data; + struct tnode *l, *tp; /* Dump starting at last key. * Note: 0.0.0.0/0 (ie default) is first key. */ - if (count == 0) - l = trie_firstleaf(t); - else { - /* Normally, continue from last key, but if that is missing - * fallback to using slow rescan - */ - l = fib_find_node(t, key); - if (!l) - l = trie_leafindex(t, count); - } + int count = cb->args[2]; + t_key key = cb->args[3]; - while (l) { - cb->args[2] = l->key; + rcu_read_lock(); + + tp = rcu_dereference_rtnl(t->trie); + + while ((l = leaf_walk_rcu(&tp, key)) != NULL) { if (fn_trie_dump_leaf(l, tb, skb, cb) < 0) { - cb->args[3] = count; + cb->args[3] = key; + cb->args[2] = count; rcu_read_unlock(); return -1; } ++count; - l = trie_nextleaf(l); + key = l->key + 1; + memset(&cb->args[4], 0, sizeof(cb->args) - 4*sizeof(cb->args[0])); + + /* stop loop if key wrapped back to 0 */ + if (key < l->key) + break; } - cb->args[3] = count; + rcu_read_unlock(); + cb->args[3] = key; + cb->args[2] = count; + return skb->len; } @@ -2186,31 +2186,46 @@ static const struct file_operations fib_trie_fops = { struct fib_route_iter { struct seq_net_private p; - struct trie *main_trie; + struct fib_table *main_tb; + struct tnode *tnode; loff_t pos; t_key key; }; static struct tnode *fib_route_get_idx(struct fib_route_iter *iter, loff_t pos) { - struct tnode *l = NULL; - struct trie *t = iter->main_trie; + struct fib_table *tb = iter->main_tb; + struct tnode *l, **tp = &iter->tnode; + struct trie *t; + t_key key; - /* use cache location of last found key */ - if (iter->pos > 0 && pos >= iter->pos && (l = fib_find_node(t, iter->key))) + /* use cache location of next-to-find key */ + if (iter->pos > 0 && pos >= iter->pos) { pos -= iter->pos; - else { + key = iter->key; + } else { + t = (struct trie *)tb->tb_data; + iter->tnode = rcu_dereference_rtnl(t->trie); iter->pos = 0; - l = trie_firstleaf(t); + key = 0; } - while (l && pos-- > 0) { + while ((l = leaf_walk_rcu(tp, key)) != NULL) { + key = l->key + 1; iter->pos++; - l = trie_nextleaf(l); + + if (pos-- <= 0) + break; + + l = NULL; + + /* handle unlikely case of a key wrap */ + if (!key) + break; } if (l) - iter->key = pos; /* remember it */ + iter->key = key; /* remember it */ else iter->pos = 0; /* forget it */ @@ -2222,37 +2237,46 @@ static void *fib_route_seq_start(struct seq_file *seq, loff_t *pos) { struct fib_route_iter *iter = seq->private; struct fib_table *tb; + struct trie *t; rcu_read_lock(); + tb = fib_get_table(seq_file_net(seq), RT_TABLE_MAIN); if (!tb) return NULL; - iter->main_trie = (struct trie *) tb->tb_data; - if (*pos == 0) - return SEQ_START_TOKEN; - else - return fib_route_get_idx(iter, *pos - 1); + iter->main_tb = tb; + + if (*pos != 0) + return fib_route_get_idx(iter, *pos); + + t = (struct trie *)tb->tb_data; + iter->tnode = rcu_dereference_rtnl(t->trie); + iter->pos = 0; + iter->key = 0; + + return SEQ_START_TOKEN; } static void *fib_route_seq_next(struct seq_file *seq, void *v, loff_t *pos) { struct fib_route_iter *iter = seq->private; - struct tnode *l = v; + struct tnode *l = NULL; + t_key key = iter->key; ++*pos; - if (v == SEQ_START_TOKEN) { - iter->pos = 0; - l = trie_firstleaf(iter->main_trie); - } else { + + /* only allow key of 0 for start of sequence */ + if ((v == SEQ_START_TOKEN) || key) + l = leaf_walk_rcu(&iter->tnode, key); + + if (l) { + iter->key = l->key + 1; iter->pos++; - l = trie_nextleaf(l); + } else { + iter->pos = 0; } - if (l) - iter->key = l->key; - else - iter->pos = 0; return l; } -- GitLab From d4a975e83f4de2e454d7f937b36ce13b010c65ce Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Wed, 4 Mar 2015 15:01:59 -0800 Subject: [PATCH 02741/11651] fib_trie: Fib find node should return parent This change makes it so that the parent pointer is returned by reference in fib_find_node. By doing this I can use it to find the parent node when I am performing an insertion and I don't have to look for it again in fib_insert_node. Signed-off-by: Alexander Duyck Signed-off-by: David S. Miller --- net/ipv4/fib_trie.c | 42 ++++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index bf488cee524a..5d0f145dbafe 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -912,9 +912,9 @@ static void fib_insert_alias(struct tnode *l, struct fib_alias *fa, } /* rcu_read_lock needs to be hold by caller from readside */ -static struct tnode *fib_find_node(struct trie *t, u32 key) +static struct tnode *fib_find_node(struct trie *t, struct tnode **tn, u32 key) { - struct tnode *n = rcu_dereference_rtnl(t->trie); + struct tnode *pn = NULL, *n = rcu_dereference_rtnl(t->trie); while (n) { unsigned long index = get_index(key, n); @@ -924,21 +924,30 @@ static struct tnode *fib_find_node(struct trie *t, u32 key) * prefix plus zeros for the bits in the cindex. The index * is the difference between the key and this value. From * this we can actually derive several pieces of data. - * if (index & (~0ul << bits)) + * if (index >= (1ul << bits)) * we have a mismatch in skip bits and failed * else * we know the value is cindex + * + * This check is safe even if bits == KEYLENGTH due to the + * fact that we can only allocate a node with 32 bits if a + * long is greater than 32 bits. */ - if (index & (~0ul << n->bits)) - return NULL; + if (index >= (1ul << n->bits)) { + n = NULL; + break; + } /* we have found a leaf. Prefixes have already been compared */ if (IS_LEAF(n)) break; + pn = n; n = tnode_get_child_rcu(n, index); } + *tn = pn; + return n; } @@ -1071,15 +1080,15 @@ static struct tnode *fib_insert_node(struct trie *t, u32 key, int plen) */ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg) { - struct trie *t = (struct trie *) tb->tb_data; + struct trie *t = (struct trie *)tb->tb_data; struct fib_alias *fa, *new_fa; + struct tnode *l, *tp; struct fib_info *fi; u8 plen = cfg->fc_dst_len; u8 slen = KEYLENGTH - plen; u8 tos = cfg->fc_tos; - u32 key, mask; + u32 key; int err; - struct tnode *l; if (plen > KEYLENGTH) return -EINVAL; @@ -1088,9 +1097,7 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg) pr_debug("Insert table=%u %08x/%d\n", tb->tb_id, key, plen); - mask = ntohl(inet_make_mask(plen)); - - if (key & ~mask) + if ((plen < KEYLENGTH) && (key << plen)) return -EINVAL; fi = fib_create_info(cfg); @@ -1099,7 +1106,7 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg) goto err; } - l = fib_find_node(t, key); + l = fib_find_node(t, &tp, key); fa = l ? fib_find_alias(&l->leaf, slen, tos, fi->fib_priority) : NULL; /* Now fa, if non-NULL, points to the first fib alias @@ -1406,22 +1413,21 @@ int fib_table_delete(struct fib_table *tb, struct fib_config *cfg) { struct trie *t = (struct trie *) tb->tb_data; struct fib_alias *fa, *fa_to_delete; + struct tnode *l, *tp; u8 plen = cfg->fc_dst_len; - u8 tos = cfg->fc_tos; u8 slen = KEYLENGTH - plen; - struct tnode *l; - u32 key, mask; + u8 tos = cfg->fc_tos; + u32 key; if (plen > KEYLENGTH) return -EINVAL; key = ntohl(cfg->fc_dst); - mask = ntohl(inet_make_mask(plen)); - if (key & ~mask) + if ((plen < KEYLENGTH) && (key << plen)) return -EINVAL; - l = fib_find_node(t, key); + l = fib_find_node(t, &tp, key); if (!l) return -ESRCH; -- GitLab From d5d6487cb8f019ab663df4c03519cd69e4362795 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Wed, 4 Mar 2015 15:02:18 -0800 Subject: [PATCH 02742/11651] fib_trie: Update insert and delete to make use of tp from find_node This change makes it so that the insert and delete functions make use of the tnode pointer returned in the fib_find_node call. By doing this we will not have to rely on the parent pointer in the leaf which will be going away soon. Signed-off-by: Alexander Duyck Signed-off-by: David S. Miller --- net/ipv4/fib_trie.c | 237 ++++++++++++++++++-------------------------- 1 file changed, 95 insertions(+), 142 deletions(-) diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 5d0f145dbafe..5be88df02b27 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -300,7 +300,7 @@ static inline void empty_child_dec(struct tnode *n) n->empty_children-- ? : n->full_children--; } -static struct tnode *leaf_new(t_key key) +static struct tnode *leaf_new(t_key key, struct fib_alias *fa) { struct tnode *l = kmem_cache_alloc(trie_leaf_kmem, GFP_KERNEL); if (l) { @@ -310,12 +310,14 @@ static struct tnode *leaf_new(t_key key) * as the nodes are searched */ l->key = key; - l->slen = 0; + l->slen = fa->fa_slen; l->pos = 0; /* set bits to 0 indicating we are not a tnode */ l->bits = 0; + /* link leaf to fib alias */ INIT_HLIST_HEAD(&l->leaf); + hlist_add_head(&fa->fa_list, &l->leaf); } return l; } @@ -842,10 +844,8 @@ static void resize(struct trie *t, struct tnode *tn) } } -static void leaf_pull_suffix(struct tnode *l) +static void leaf_pull_suffix(struct tnode *tp, struct tnode *l) { - struct tnode *tp = node_parent(l); - while (tp && (tp->slen > tp->pos) && (tp->slen > l->slen)) { if (update_suffix(tp) > l->slen) break; @@ -853,10 +853,8 @@ static void leaf_pull_suffix(struct tnode *l) } } -static void leaf_push_suffix(struct tnode *l) +static void leaf_push_suffix(struct tnode *tn, struct tnode *l) { - struct tnode *tn = node_parent(l); - /* if this is a new leaf then tn will be NULL and we can sort * out parent suffix lengths as a part of trie_rebalance */ @@ -866,51 +864,6 @@ static void leaf_push_suffix(struct tnode *l) } } -static void fib_remove_alias(struct tnode *l, struct fib_alias *old) -{ - /* record the location of the previous list_info entry */ - struct hlist_node **pprev = old->fa_list.pprev; - struct fib_alias *fa = hlist_entry(pprev, typeof(*fa), fa_list.next); - - /* remove the fib_alias from the list */ - hlist_del_rcu(&old->fa_list); - - /* only access fa if it is pointing at the last valid hlist_node */ - if (hlist_empty(&l->leaf) || (*pprev)) - return; - - /* update the trie with the latest suffix length */ - l->slen = fa->fa_slen; - leaf_pull_suffix(l); -} - -static void fib_insert_alias(struct tnode *l, struct fib_alias *fa, - struct fib_alias *new) -{ - if (fa) { - hlist_add_before_rcu(&new->fa_list, &fa->fa_list); - } else { - struct fib_alias *last; - - hlist_for_each_entry(last, &l->leaf, fa_list) { - if (new->fa_slen < last->fa_slen) - break; - fa = last; - } - - if (fa) - hlist_add_behind_rcu(&new->fa_list, &fa->fa_list); - else - hlist_add_head_rcu(&new->fa_list, &l->leaf); - } - - /* if we added to the tail node then we need to update slen */ - if (l->slen < new->fa_slen) { - l->slen = new->fa_slen; - leaf_push_suffix(l); - } -} - /* rcu_read_lock needs to be hold by caller from readside */ static struct tnode *fib_find_node(struct trie *t, struct tnode **tn, u32 key) { @@ -980,61 +933,28 @@ static void trie_rebalance(struct trie *t, struct tnode *tn) { struct tnode *tp; - while ((tp = node_parent(tn)) != NULL) { + while (tn) { + tp = node_parent(tn); resize(t, tn); tn = tp; } - - /* Handle last (top) tnode */ - if (IS_TNODE(tn)) - resize(t, tn); } /* only used from updater-side */ - -static struct tnode *fib_insert_node(struct trie *t, u32 key, int plen) +static int fib_insert_node(struct trie *t, struct tnode *tp, + struct fib_alias *new, t_key key) { - struct tnode *l, *n, *tp = NULL; - - n = rtnl_dereference(t->trie); - - /* If we point to NULL, stop. Either the tree is empty and we should - * just put a new leaf in if, or we have reached an empty child slot, - * and we should just put our new leaf in that. - * - * If we hit a node with a key that does't match then we should stop - * and create a new tnode to replace that node and insert ourselves - * and the other node into the new tnode. - */ - while (n) { - unsigned long index = get_index(key, n); - - /* This bit of code is a bit tricky but it combines multiple - * checks into a single check. The prefix consists of the - * prefix plus zeros for the "bits" in the prefix. The index - * is the difference between the key and this value. From - * this we can actually derive several pieces of data. - * if !(index >> bits) - * we know the value is child index - * else - * we have a mismatch in skip bits and failed - */ - if (index >> n->bits) - break; - - /* we have found a leaf. Prefixes have already been compared */ - if (IS_LEAF(n)) { - /* Case 1: n is a leaf, and prefixes match*/ - return n; - } - - tp = n; - n = tnode_get_child_rcu(n, index); - } + struct tnode *n, *l; - l = leaf_new(key); + l = leaf_new(key, new); if (!l) - return NULL; + return -ENOMEM; + + /* retrieve child from parent node */ + if (tp) + n = tnode_get_child(tp, get_index(key, tp)); + else + n = rcu_dereference_rtnl(t->trie); /* Case 2: n is a LEAF or a TNODE and the key doesn't match. * @@ -1048,7 +968,7 @@ static struct tnode *fib_insert_node(struct trie *t, u32 key, int plen) tn = tnode_new(key, __fls(key ^ n->key), 1); if (!tn) { node_free(l); - return NULL; + return -ENOMEM; } /* initialize routes out of node */ @@ -1064,20 +984,47 @@ static struct tnode *fib_insert_node(struct trie *t, u32 key, int plen) } /* Case 3: n is NULL, and will just insert a new leaf */ - if (tp) { - NODE_INIT_PARENT(l, tp); - put_child(tp, get_index(key, tp), l); - trie_rebalance(t, tp); + NODE_INIT_PARENT(l, tp); + put_child_root(tp, t, key, l); + trie_rebalance(t, tp); + + return 0; +} + +static int fib_insert_alias(struct trie *t, struct tnode *tp, + struct tnode *l, struct fib_alias *new, + struct fib_alias *fa, t_key key) +{ + if (!l) + return fib_insert_node(t, tp, new, key); + + if (fa) { + hlist_add_before_rcu(&new->fa_list, &fa->fa_list); } else { - rcu_assign_pointer(t->trie, l); + struct fib_alias *last; + + hlist_for_each_entry(last, &l->leaf, fa_list) { + if (new->fa_slen < last->fa_slen) + break; + fa = last; + } + + if (fa) + hlist_add_behind_rcu(&new->fa_list, &fa->fa_list); + else + hlist_add_head_rcu(&new->fa_list, &l->leaf); } - return l; + /* if we added to the tail node then we need to update slen */ + if (l->slen < new->fa_slen) { + l->slen = new->fa_slen; + leaf_push_suffix(tp, l); + } + + return 0; } -/* - * Caller must hold RTNL. - */ +/* Caller must hold RTNL. */ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg) { struct trie *t = (struct trie *)tb->tb_data; @@ -1205,19 +1152,13 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg) new_fa->fa_slen = slen; /* Insert new entry to the list. */ - if (!l) { - l = fib_insert_node(t, key, plen); - if (unlikely(!l)) { - err = -ENOMEM; - goto out_free_new_fa; - } - } + err = fib_insert_alias(t, tp, l, new_fa, fa, key); + if (err) + goto out_free_new_fa; if (!plen) tb->tb_num_default++; - fib_insert_alias(l, fa, new_fa); - rt_cache_flush(cfg->fc_nlinfo.nl_net); rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen, tb->tb_id, &cfg->fc_nlinfo, 0); @@ -1406,9 +1347,36 @@ found: } EXPORT_SYMBOL_GPL(fib_table_lookup); -/* - * Caller must hold RTNL. - */ +static void fib_remove_alias(struct trie *t, struct tnode *tp, + struct tnode *l, struct fib_alias *old) +{ + /* record the location of the previous list_info entry */ + struct hlist_node **pprev = old->fa_list.pprev; + struct fib_alias *fa = hlist_entry(pprev, typeof(*fa), fa_list.next); + + /* remove the fib_alias from the list */ + hlist_del_rcu(&old->fa_list); + + /* if we emptied the list this leaf will be freed and we can sort + * out parent suffix lengths as a part of trie_rebalance + */ + if (hlist_empty(&l->leaf)) { + put_child_root(tp, t, l->key, NULL); + node_free(l); + trie_rebalance(t, tp); + return; + } + + /* only access fa if it is pointing at the last valid hlist_node */ + if (*pprev) + return; + + /* update the trie with the latest suffix length */ + l->slen = fa->fa_slen; + leaf_pull_suffix(tp, l); +} + +/* Caller must hold RTNL. */ int fib_table_delete(struct fib_table *tb, struct fib_config *cfg) { struct trie *t = (struct trie *) tb->tb_data; @@ -1432,7 +1400,6 @@ int fib_table_delete(struct fib_table *tb, struct fib_config *cfg) return -ESRCH; fa = fib_find_alias(&l->leaf, slen, tos, 0); - if (!fa) return -ESRCH; @@ -1461,33 +1428,19 @@ int fib_table_delete(struct fib_table *tb, struct fib_config *cfg) if (!fa_to_delete) return -ESRCH; - fa = fa_to_delete; - rtmsg_fib(RTM_DELROUTE, htonl(key), fa, plen, tb->tb_id, + rtmsg_fib(RTM_DELROUTE, htonl(key), fa_to_delete, plen, tb->tb_id, &cfg->fc_nlinfo, 0); - fib_remove_alias(l, fa); - if (!plen) tb->tb_num_default--; - if (hlist_empty(&l->leaf)) { - struct tnode *tp = node_parent(l); - - if (tp) { - put_child(tp, get_index(l->key, tp), NULL); - trie_rebalance(t, tp); - } else { - RCU_INIT_POINTER(t->trie, NULL); - } - - node_free(l); - } + fib_remove_alias(t, tp, l, fa_to_delete); - if (fa->fa_state & FA_S_ACCESSED) + if (fa_to_delete->fa_state & FA_S_ACCESSED) rt_cache_flush(cfg->fc_nlinfo.nl_net); - fib_release_info(fa->fa_info); - alias_free_mem_rcu(fa); + fib_release_info(fa_to_delete->fa_info); + alias_free_mem_rcu(fa_to_delete); return 0; } @@ -1626,7 +1579,7 @@ backtrace: put_child_root(pn, t, n->key, NULL); node_free(n); } else { - leaf_pull_suffix(n); + leaf_pull_suffix(pn, n); } /* if trie is leaf only loop is completed */ -- GitLab From 41b489fd6ce03e96e90fcffdb69b168065ae2e40 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Wed, 4 Mar 2015 15:02:33 -0800 Subject: [PATCH 02743/11651] fib_trie: move leaf and tnode to occupy the same spot in the key vector If we are going to compact the leaf and tnode we first need to make sure the fields are all in the same place. In that regard I am moving the leaf pointer which represents the fib_alias hash list to occupy what is currently the first key_vector pointer. Signed-off-by: Alexander Duyck Signed-off-by: David S. Miller --- net/ipv4/fib_trie.c | 51 ++++++++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 5be88df02b27..2233ebf2aae8 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -94,24 +94,27 @@ typedef unsigned int t_key; #define get_index(_key, _kv) (((_key) ^ (_kv)->key) >> (_kv)->pos) struct tnode { + struct rcu_head rcu; + + t_key empty_children; /* KEYLENGTH bits needed */ + t_key full_children; /* KEYLENGTH bits needed */ + struct tnode __rcu *parent; + t_key key; - unsigned char bits; /* 2log(KEYLENGTH) bits needed */ unsigned char pos; /* 2log(KEYLENGTH) bits needed */ + unsigned char bits; /* 2log(KEYLENGTH) bits needed */ unsigned char slen; - struct tnode __rcu *parent; - struct rcu_head rcu; union { - /* The fields in this struct are valid if bits > 0 (TNODE) */ - struct { - t_key empty_children; /* KEYLENGTH bits needed */ - t_key full_children; /* KEYLENGTH bits needed */ - struct tnode __rcu *child[0]; - }; - /* This list pointer if valid if bits == 0 (LEAF) */ + /* This list pointer if valid if (pos | bits) == 0 (LEAF) */ struct hlist_head leaf; + /* This array is valid if (pos | bits) > 0 (TNODE) */ + struct tnode __rcu *tnode[0]; }; }; +#define TNODE_SIZE(n) offsetof(struct tnode, tnode[n]) +#define LEAF_SIZE TNODE_SIZE(1) + #ifdef CONFIG_IP_FIB_TRIE_STATS struct trie_use_stats { unsigned int gets; @@ -180,14 +183,14 @@ static inline unsigned long tnode_child_length(const struct tnode *tn) static inline struct tnode *tnode_get_child(const struct tnode *tn, unsigned long i) { - return rtnl_dereference(tn->child[i]); + return rtnl_dereference(tn->tnode[i]); } /* caller must hold RCU read lock or RTNL */ static inline struct tnode *tnode_get_child_rcu(const struct tnode *tn, unsigned long i) { - return rcu_dereference_rtnl(tn->child[i]); + return rcu_dereference_rtnl(tn->tnode[i]); } /* To understand this stuff, an understanding of keys and all their bits is @@ -266,7 +269,7 @@ static inline void alias_free_mem_rcu(struct fib_alias *fa) } #define TNODE_KMALLOC_MAX \ - ilog2((PAGE_SIZE - sizeof(struct tnode)) / sizeof(struct tnode *)) + ilog2((PAGE_SIZE - TNODE_SIZE(0)) / sizeof(struct tnode *)) static void __node_free_rcu(struct rcu_head *head) { @@ -324,7 +327,7 @@ static struct tnode *leaf_new(t_key key, struct fib_alias *fa) static struct tnode *tnode_new(t_key key, int pos, int bits) { - size_t sz = offsetof(struct tnode, child[1ul << bits]); + size_t sz = TNODE_SIZE(1ul << bits); struct tnode *tn = tnode_alloc(sz); unsigned int shift = pos + bits; @@ -343,7 +346,7 @@ static struct tnode *tnode_new(t_key key, int pos, int bits) tn->empty_children = 1ul << bits; } - pr_debug("AT %p s=%zu %zu\n", tn, sizeof(struct tnode), + pr_debug("AT %p s=%zu %zu\n", tn, TNODE_SIZE(0), sizeof(struct tnode *) << bits); return tn; } @@ -384,7 +387,7 @@ static void put_child(struct tnode *tn, unsigned long i, struct tnode *n) if (n && (tn->slen < n->slen)) tn->slen = n->slen; - rcu_assign_pointer(tn->child[i], n); + rcu_assign_pointer(tn->tnode[i], n); } static void update_children(struct tnode *tn) @@ -435,7 +438,7 @@ static void tnode_free(struct tnode *tn) while (head) { head = head->next; - tnode_free_size += offsetof(struct tnode, child[1 << tn->bits]); + tnode_free_size += TNODE_SIZE(1ul << tn->bits); node_free(tn); tn = container_of(head, struct tnode, rcu); @@ -788,7 +791,7 @@ static void resize(struct trie *t, struct tnode *tn) * doing it ourselves. This way we can let RCU fully do its * thing without us interfering */ - cptr = tp ? &tp->child[get_index(tn->key, tp)] : &t->trie; + cptr = tp ? &tp->tnode[get_index(tn->key, tp)] : &t->trie; BUG_ON(tn != rtnl_dereference(*cptr)); /* Double as long as the resulting node has a number of @@ -1241,7 +1244,7 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi4 *flp, /* Step 2: Sort out leaves and begin backtracing for longest prefix */ for (;;) { /* record the pointer where our next node pointer is stored */ - struct tnode __rcu **cptr = n->child; + struct tnode __rcu **cptr = n->tnode; /* This test verifies that none of the bits that differ * between the key and the prefix exist in the region of @@ -1287,7 +1290,7 @@ backtrace: cindex &= cindex - 1; /* grab pointer for next child node */ - cptr = &pn->child[cindex]; + cptr = &pn->tnode[cindex]; } } @@ -1685,7 +1688,7 @@ void __init fib_trie_init(void) 0, SLAB_PANIC, NULL); trie_leaf_kmem = kmem_cache_create("ip_fib_trie", - sizeof(struct tnode), + LEAF_SIZE, 0, SLAB_PANIC, NULL); } @@ -1843,13 +1846,13 @@ static void trie_show_stats(struct seq_file *seq, struct trie_stat *stat) seq_printf(seq, "\tMax depth: %u\n", stat->maxdepth); seq_printf(seq, "\tLeaves: %u\n", stat->leaves); - bytes = sizeof(struct tnode) * stat->leaves; + bytes = LEAF_SIZE * stat->leaves; seq_printf(seq, "\tPrefixes: %u\n", stat->prefixes); bytes += sizeof(struct fib_alias) * stat->prefixes; seq_printf(seq, "\tInternal nodes: %u\n\t", stat->tnodes); - bytes += sizeof(struct tnode) * stat->tnodes; + bytes += TNODE_SIZE(0) * stat->tnodes; max = MAX_STAT_DEPTH; while (max > 0 && stat->nodesizes[max-1] == 0) @@ -1918,7 +1921,7 @@ static int fib_triestat_seq_show(struct seq_file *seq, void *v) seq_printf(seq, "Basic info: size of leaf:" " %Zd bytes, size of tnode: %Zd bytes.\n", - sizeof(struct tnode), sizeof(struct tnode)); + LEAF_SIZE, TNODE_SIZE(0)); for (h = 0; h < FIB_TABLE_HASHSZ; h++) { struct hlist_head *head = &net->ipv4.fib_table_hash[h]; -- GitLab From a7e53531234dc206bb75abb5305a72665dd4d75d Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Wed, 4 Mar 2015 15:02:44 -0800 Subject: [PATCH 02744/11651] fib_trie: Make fib_table rcu safe The fib_table was wrapped in several places with an rcu_read_lock/rcu_read_unlock however after looking over the code I found several spots where the tables were being accessed as just standard pointers without any protections. This change fixes that so that all of the proper protections are in place when accessing the table to take RCU replacement or removal of the table into account. Signed-off-by: Alexander Duyck Signed-off-by: David S. Miller --- include/net/ip_fib.h | 70 ++++++++++++++++++++++++---------------- include/net/netns/ipv4.h | 7 ++-- net/ipv4/fib_frontend.c | 52 ++++++++++++++++++++--------- net/ipv4/fib_trie.c | 21 ++++++++---- 4 files changed, 98 insertions(+), 52 deletions(-) diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h index cba4b7c32935..825cb2800908 100644 --- a/include/net/ip_fib.h +++ b/include/net/ip_fib.h @@ -185,6 +185,7 @@ struct fib_table { u32 tb_id; int tb_default; int tb_num_default; + struct rcu_head rcu; unsigned long tb_data[0]; }; @@ -206,12 +207,16 @@ void fib_free_table(struct fib_table *tb); static inline struct fib_table *fib_get_table(struct net *net, u32 id) { + struct hlist_node *tb_hlist; struct hlist_head *ptr; ptr = id == RT_TABLE_LOCAL ? &net->ipv4.fib_table_hash[TABLE_LOCAL_INDEX] : &net->ipv4.fib_table_hash[TABLE_MAIN_INDEX]; - return hlist_entry(ptr->first, struct fib_table, tb_hlist); + + tb_hlist = rcu_dereference_rtnl(hlist_first_rcu(ptr)); + + return hlist_entry(tb_hlist, struct fib_table, tb_hlist); } static inline struct fib_table *fib_new_table(struct net *net, u32 id) @@ -222,15 +227,19 @@ static inline struct fib_table *fib_new_table(struct net *net, u32 id) static inline int fib_lookup(struct net *net, const struct flowi4 *flp, struct fib_result *res) { - int err = -ENETUNREACH; + struct fib_table *tb; + int err; rcu_read_lock(); - if (!fib_table_lookup(fib_get_table(net, RT_TABLE_LOCAL), flp, res, - FIB_LOOKUP_NOREF) || - !fib_table_lookup(fib_get_table(net, RT_TABLE_MAIN), flp, res, - FIB_LOOKUP_NOREF)) - err = 0; + for (err = 0; !err; err = -ENETUNREACH) { + tb = fib_get_table(net, RT_TABLE_LOCAL); + if (tb && !fib_table_lookup(tb, flp, res, FIB_LOOKUP_NOREF)) + break; + tb = fib_get_table(net, RT_TABLE_MAIN); + if (tb && !fib_table_lookup(tb, flp, res, FIB_LOOKUP_NOREF)) + break; + } rcu_read_unlock(); @@ -249,28 +258,33 @@ int __fib_lookup(struct net *net, struct flowi4 *flp, struct fib_result *res); static inline int fib_lookup(struct net *net, struct flowi4 *flp, struct fib_result *res) { - if (!net->ipv4.fib_has_custom_rules) { - int err = -ENETUNREACH; - - rcu_read_lock(); - - res->tclassid = 0; - if ((net->ipv4.fib_local && - !fib_table_lookup(net->ipv4.fib_local, flp, res, - FIB_LOOKUP_NOREF)) || - (net->ipv4.fib_main && - !fib_table_lookup(net->ipv4.fib_main, flp, res, - FIB_LOOKUP_NOREF)) || - (net->ipv4.fib_default && - !fib_table_lookup(net->ipv4.fib_default, flp, res, - FIB_LOOKUP_NOREF))) - err = 0; - - rcu_read_unlock(); - - return err; + struct fib_table *tb; + int err; + + if (net->ipv4.fib_has_custom_rules) + return __fib_lookup(net, flp, res); + + rcu_read_lock(); + + res->tclassid = 0; + + for (err = 0; !err; err = -ENETUNREACH) { + tb = rcu_dereference_rtnl(net->ipv4.fib_local); + if (tb && !fib_table_lookup(tb, flp, res, FIB_LOOKUP_NOREF)) + break; + + tb = rcu_dereference_rtnl(net->ipv4.fib_main); + if (tb && !fib_table_lookup(tb, flp, res, FIB_LOOKUP_NOREF)) + break; + + tb = rcu_dereference_rtnl(net->ipv4.fib_default); + if (tb && !fib_table_lookup(tb, flp, res, FIB_LOOKUP_NOREF)) + break; } - return __fib_lookup(net, flp, res); + + rcu_read_unlock(); + + return err; } #endif /* CONFIG_IP_MULTIPLE_TABLES */ diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h index 1b26c6c3fd7c..db1db158a00e 100644 --- a/include/net/netns/ipv4.h +++ b/include/net/netns/ipv4.h @@ -7,6 +7,7 @@ #include #include +#include struct tcpm_hash_bucket; struct ctl_table_header; @@ -38,9 +39,9 @@ struct netns_ipv4 { #ifdef CONFIG_IP_MULTIPLE_TABLES struct fib_rules_ops *rules_ops; bool fib_has_custom_rules; - struct fib_table *fib_local; - struct fib_table *fib_main; - struct fib_table *fib_default; + struct fib_table __rcu *fib_local; + struct fib_table __rcu *fib_main; + struct fib_table __rcu *fib_default; #endif #ifdef CONFIG_IP_ROUTE_CLASSID int fib_num_tclassid_users; diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 57be71dd6a9e..220c4b4af4cf 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -89,17 +89,14 @@ struct fib_table *fib_new_table(struct net *net, u32 id) switch (id) { case RT_TABLE_LOCAL: - net->ipv4.fib_local = tb; + rcu_assign_pointer(net->ipv4.fib_local, tb); break; - case RT_TABLE_MAIN: - net->ipv4.fib_main = tb; + rcu_assign_pointer(net->ipv4.fib_main, tb); break; - case RT_TABLE_DEFAULT: - net->ipv4.fib_default = tb; + rcu_assign_pointer(net->ipv4.fib_default, tb); break; - default: break; } @@ -132,13 +129,14 @@ struct fib_table *fib_get_table(struct net *net, u32 id) static void fib_flush(struct net *net) { int flushed = 0; - struct fib_table *tb; - struct hlist_head *head; unsigned int h; for (h = 0; h < FIB_TABLE_HASHSZ; h++) { - head = &net->ipv4.fib_table_hash[h]; - hlist_for_each_entry(tb, head, tb_hlist) + struct hlist_head *head = &net->ipv4.fib_table_hash[h]; + struct hlist_node *tmp; + struct fib_table *tb; + + hlist_for_each_entry_safe(tb, tmp, head, tb_hlist) flushed += fib_table_flush(tb); } @@ -665,10 +663,12 @@ static int inet_dump_fib(struct sk_buff *skb, struct netlink_callback *cb) s_h = cb->args[0]; s_e = cb->args[1]; + rcu_read_lock(); + for (h = s_h; h < FIB_TABLE_HASHSZ; h++, s_e = 0) { e = 0; head = &net->ipv4.fib_table_hash[h]; - hlist_for_each_entry(tb, head, tb_hlist) { + hlist_for_each_entry_rcu(tb, head, tb_hlist) { if (e < s_e) goto next; if (dumped) @@ -682,6 +682,8 @@ next: } } out: + rcu_read_unlock(); + cb->args[1] = e; cb->args[0] = h; @@ -1117,14 +1119,34 @@ static void ip_fib_net_exit(struct net *net) rtnl_lock(); for (i = 0; i < FIB_TABLE_HASHSZ; i++) { - struct fib_table *tb; - struct hlist_head *head; + struct hlist_head *head = &net->ipv4.fib_table_hash[i]; struct hlist_node *tmp; + struct fib_table *tb; + + /* this is done in two passes as flushing the table could + * cause it to be reallocated in order to accommodate new + * tnodes at the root as the table shrinks. + */ + hlist_for_each_entry_safe(tb, tmp, head, tb_hlist) + fib_table_flush(tb); - head = &net->ipv4.fib_table_hash[i]; hlist_for_each_entry_safe(tb, tmp, head, tb_hlist) { +#ifdef CONFIG_IP_MULTIPLE_TABLES + switch (tb->tb_id) { + case RT_TABLE_LOCAL: + RCU_INIT_POINTER(net->ipv4.fib_local, NULL); + break; + case RT_TABLE_MAIN: + RCU_INIT_POINTER(net->ipv4.fib_main, NULL); + break; + case RT_TABLE_DEFAULT: + RCU_INIT_POINTER(net->ipv4.fib_default, NULL); + break; + default: + break; + } +#endif hlist_del(&tb->tb_hlist); - fib_table_flush(tb); fib_free_table(tb); } } diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 2233ebf2aae8..3642b17c8726 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -193,6 +193,13 @@ static inline struct tnode *tnode_get_child_rcu(const struct tnode *tn, return rcu_dereference_rtnl(tn->tnode[i]); } +static inline struct fib_table *trie_get_table(struct trie *t) +{ + unsigned long *tb_data = (unsigned long *)t; + + return container_of(tb_data, struct fib_table, tb_data[0]); +} + /* To understand this stuff, an understanding of keys and all their bits is * necessary. Every node in the trie has a key associated with it, but not * all of the bits in that key are significant. @@ -1593,8 +1600,9 @@ flush_complete: return found; } -void fib_free_table(struct fib_table *tb) +static void __trie_free_rcu(struct rcu_head *head) { + struct fib_table *tb = container_of(head, struct fib_table, rcu); #ifdef CONFIG_IP_FIB_TRIE_STATS struct trie *t = (struct trie *)tb->tb_data; @@ -1603,6 +1611,11 @@ void fib_free_table(struct fib_table *tb) kfree(tb); } +void fib_free_table(struct fib_table *tb) +{ + call_rcu(&tb->rcu, __trie_free_rcu); +} + static int fn_trie_dump_leaf(struct tnode *l, struct fib_table *tb, struct sk_buff *skb, struct netlink_callback *cb) { @@ -1639,6 +1652,7 @@ static int fn_trie_dump_leaf(struct tnode *l, struct fib_table *tb, return skb->len; } +/* rcu_read_lock needs to be hold by caller from readside */ int fib_table_dump(struct fib_table *tb, struct sk_buff *skb, struct netlink_callback *cb) { @@ -1650,15 +1664,12 @@ int fib_table_dump(struct fib_table *tb, struct sk_buff *skb, int count = cb->args[2]; t_key key = cb->args[3]; - rcu_read_lock(); - tp = rcu_dereference_rtnl(t->trie); while ((l = leaf_walk_rcu(&tp, key)) != NULL) { if (fn_trie_dump_leaf(l, tb, skb, cb) < 0) { cb->args[3] = key; cb->args[2] = count; - rcu_read_unlock(); return -1; } @@ -1673,8 +1684,6 @@ int fib_table_dump(struct fib_table *tb, struct sk_buff *skb, break; } - rcu_read_unlock(); - cb->args[3] = key; cb->args[2] = count; -- GitLab From 71e8b67d0fdd2fe22a657bb98716c5cf0e31e828 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Wed, 4 Mar 2015 15:04:03 -0800 Subject: [PATCH 02745/11651] fib_trie: Update last spot w/ idx >> n->bits code and explanation This change updates the fib_table_lookup function so that it is in sync with the fib_find_node function in terms of the explanation for the index check based on the bits value. I have also updated it from doing a mask to just doing a compare as I have found that seems to provide more options to the compiler as I have seen it turn this into a shift of the value and test under some circumstances. In addition I addressed one minor issue in which we kept computing the key ^ n->key when checking the fib aliases. I pulled the xor out of the loop in order to reduce the number of memory reads in the lookup. As a result we should save a couple cycles since the xor is only done once much earlier in the lookup. Signed-off-by: Alexander Duyck Signed-off-by: David S. Miller --- net/ipv4/fib_trie.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 3642b17c8726..08676c56efc3 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -1201,6 +1201,7 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi4 *flp, const t_key key = ntohl(flp->daddr); struct tnode *n, *pn; struct fib_alias *fa; + unsigned long index; t_key cindex; n = rcu_dereference(t->trie); @@ -1216,19 +1217,23 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi4 *flp, /* Step 1: Travel to the longest prefix match in the trie */ for (;;) { - unsigned long index = get_index(key, n); + index = get_index(key, n); /* This bit of code is a bit tricky but it combines multiple * checks into a single check. The prefix consists of the * prefix plus zeros for the "bits" in the prefix. The index * is the difference between the key and this value. From * this we can actually derive several pieces of data. - * if (index & (~0ul << bits)) + * if (index >= (1ul << bits)) * we have a mismatch in skip bits and failed * else * we know the value is cindex + * + * This check is safe even if bits == KEYLENGTH due to the + * fact that we can only allocate a node with 32 bits if a + * long is greater than 32 bits. */ - if (index & (~0ul << n->bits)) + if (index >= (1ul << n->bits)) break; /* we have found a leaf. Prefixes have already been compared */ @@ -1302,14 +1307,17 @@ backtrace: } found: + /* this line carries forward the xor from earlier in the function */ + index = key ^ n->key; + /* Step 3: Process the leaf, if that fails fall back to backtracing */ hlist_for_each_entry_rcu(fa, &n->leaf, fa_list) { struct fib_info *fi = fa->fa_info; int nhsel, err; - if (((key ^ n->key) >= (1ul << fa->fa_slen)) && + if ((index >= (1ul << fa->fa_slen)) && ((BITS_PER_LONG > KEYLENGTH) || (fa->fa_slen != KEYLENGTH))) - continue; + continue; if (fa->fa_tos && fa->fa_tos != flp->flowi4_tos) continue; if (fi->fib_dead) -- GitLab From 1de3d87bcd2c2e631500b9e4f0c40b38ce0d0d57 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Wed, 4 Mar 2015 15:04:46 -0800 Subject: [PATCH 02746/11651] fib_trie: Prevent allocating tnode if bits is too big for size_t This patch adds code to prevent us from attempting to allocate a tnode with a size larger than what can be represented by size_t. Signed-off-by: Alexander Duyck Signed-off-by: David S. Miller --- net/ipv4/fib_trie.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 08676c56efc3..fae34ad4bb1a 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -277,6 +277,8 @@ static inline void alias_free_mem_rcu(struct fib_alias *fa) #define TNODE_KMALLOC_MAX \ ilog2((PAGE_SIZE - TNODE_SIZE(0)) / sizeof(struct tnode *)) +#define TNODE_VMALLOC_MAX \ + ilog2((SIZE_MAX - TNODE_SIZE(0)) / sizeof(struct tnode *)) static void __node_free_rcu(struct rcu_head *head) { @@ -292,8 +294,17 @@ static void __node_free_rcu(struct rcu_head *head) #define node_free(n) call_rcu(&n->rcu, __node_free_rcu) -static struct tnode *tnode_alloc(size_t size) +static struct tnode *tnode_alloc(int bits) { + size_t size; + + /* verify bits is within bounds */ + if (bits > TNODE_VMALLOC_MAX) + return NULL; + + /* determine size and verify it is non-zero and didn't overflow */ + size = TNODE_SIZE(1ul << bits); + if (size <= PAGE_SIZE) return kzalloc(size, GFP_KERNEL); else @@ -334,8 +345,7 @@ static struct tnode *leaf_new(t_key key, struct fib_alias *fa) static struct tnode *tnode_new(t_key key, int pos, int bits) { - size_t sz = TNODE_SIZE(1ul << bits); - struct tnode *tn = tnode_alloc(sz); + struct tnode *tn = tnode_alloc(bits); unsigned int shift = pos + bits; /* verify bits and pos their msb bits clear and values are valid */ -- GitLab From 4d4eb4d4fbd9403682e2b75117b6b895531d8e01 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Wed, 4 Mar 2015 23:30:45 -0500 Subject: [PATCH 02747/11651] seq_buf: Fix seq_buf_bprintf() truncation In seq_buf_bprintf(), bstr_printf() is used to copy the format into the buffer remaining in the seq_buf structure. The return of bstr_printf() is the amount of characters written to the buffer excluding the '\0', unless the line was truncated! If the line copied does not fit, it is truncated, and a '\0' is added to the end of the buffer. But in this case, '\0' is included in the length of the line written. To know if the buffer had overflowed, the return length will be the same or greater than the length of the buffer passed in. The check in seq_buf_bprintf() only checked if the length returned from bstr_printf() would fit in the buffer, as the seq_buf_bprintf() is only to be an all or nothing command. It either writes all the string into the seq_buf, or none of it. If the string is truncated, the pointers inside the seq_buf must be reset to what they were when the function was called. This is not the case. On overflow, it copies only part of the string. The fix is to change the overflow check to see if the length returned from bstr_printf() is less than the length remaining in the seq_buf buffer, and not if it is less than or equal to as it currently does. Then seq_buf_bprintf() will know if the write from bstr_printf() was truncated or not. Link: http://lkml.kernel.org/r/1425500481.2712.27.camel@perches.com Cc: stable@vger.kernel.org Reported-by: Joe Perches Signed-off-by: Steven Rostedt --- lib/seq_buf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/seq_buf.c b/lib/seq_buf.c index 0c92583b7b7e..5c94e1012a91 100644 --- a/lib/seq_buf.c +++ b/lib/seq_buf.c @@ -118,7 +118,7 @@ int seq_buf_bprintf(struct seq_buf *s, const char *fmt, const u32 *binary) if (s->len < s->size) { ret = bstr_printf(s->buffer + s->len, len, fmt, binary); - if (seq_buf_can_fit(s, ret)) { + if (s->len + ret < s->size) { s->len += ret; return 0; } -- GitLab From 66d06757d9eb74a29775737b8c770e3b57e536d9 Mon Sep 17 00:00:00 2001 From: Petri Gynther Date: Wed, 4 Mar 2015 14:30:01 -0800 Subject: [PATCH 02748/11651] net: bcmgenet: simplify __bcmgenet_tx_reclaim() 1. Use c_index and ring->c_index to determine how many TxCBs/TxBDs are ready for cleanup - c_index = the current value of TDMA_CONS_INDEX - TDMA_CONS_INDEX is HW-incremented and auto-wraparound (0x0-0xFFFF) - ring->c_index = __bcmgenet_tx_reclaim() cleaned up to this point on the previous invocation 2. Add bcmgenet_tx_ring->clean_ptr - index of the next TxCB to be cleaned - incremented as TxCBs/TxBDs are processed - value always in range [ring->cb_ptr, ring->end_ptr] 3. Fix incrementing of dev->stats.tx_packets - should be incremented only when tx_cb_ptr->skb != NULL These changes simplify __bcmgenet_tx_reclaim(). Furthermore, Tx ring size can now be any value. With the old code, Tx ring size had to be a power-of-2: num_tx_bds = ring->size; c_index &= (num_tx_bds - 1); last_c_index &= (num_tx_bds - 1); Signed-off-by: Petri Gynther Reviewed-by: Florian Fainelli Signed-off-by: David S. Miller --- .../net/ethernet/broadcom/genet/bcmgenet.c | 45 +++++++++---------- .../net/ethernet/broadcom/genet/bcmgenet.h | 1 + 2 files changed, 22 insertions(+), 24 deletions(-) diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index 84feb241d60b..9137187063f7 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -978,39 +978,32 @@ static unsigned int __bcmgenet_tx_reclaim(struct net_device *dev, struct bcmgenet_tx_ring *ring) { struct bcmgenet_priv *priv = netdev_priv(dev); - int last_tx_cn, last_c_index, num_tx_bds; struct enet_cb *tx_cb_ptr; struct netdev_queue *txq; unsigned int pkts_compl = 0; - unsigned int bds_compl; unsigned int c_index; + unsigned int txbds_ready; + unsigned int txbds_processed = 0; /* Compute how many buffers are transmitted since last xmit call */ c_index = bcmgenet_tdma_ring_readl(priv, ring->index, TDMA_CONS_INDEX); - txq = netdev_get_tx_queue(dev, ring->queue); - - last_c_index = ring->c_index; - num_tx_bds = ring->size; - - c_index &= (num_tx_bds - 1); + c_index &= DMA_C_INDEX_MASK; - if (c_index >= last_c_index) - last_tx_cn = c_index - last_c_index; + if (likely(c_index >= ring->c_index)) + txbds_ready = c_index - ring->c_index; else - last_tx_cn = num_tx_bds - last_c_index + c_index; + txbds_ready = (DMA_C_INDEX_MASK + 1) - ring->c_index + c_index; netif_dbg(priv, tx_done, dev, - "%s ring=%d index=%d last_tx_cn=%d last_index=%d\n", - __func__, ring->index, - c_index, last_tx_cn, last_c_index); + "%s ring=%d old_c_index=%u c_index=%u txbds_ready=%u\n", + __func__, ring->index, ring->c_index, c_index, txbds_ready); /* Reclaim transmitted buffers */ - while (last_tx_cn-- > 0) { - tx_cb_ptr = ring->cbs + last_c_index; - bds_compl = 0; + while (txbds_processed < txbds_ready) { + tx_cb_ptr = &priv->tx_cbs[ring->clean_ptr]; if (tx_cb_ptr->skb) { pkts_compl++; - bds_compl = skb_shinfo(tx_cb_ptr->skb)->nr_frags + 1; + dev->stats.tx_packets++; dev->stats.tx_bytes += tx_cb_ptr->skb->len; dma_unmap_single(&dev->dev, dma_unmap_addr(tx_cb_ptr, dma_addr), @@ -1026,20 +1019,23 @@ static unsigned int __bcmgenet_tx_reclaim(struct net_device *dev, DMA_TO_DEVICE); dma_unmap_addr_set(tx_cb_ptr, dma_addr, 0); } - dev->stats.tx_packets++; - ring->free_bds += bds_compl; - last_c_index++; - last_c_index &= (num_tx_bds - 1); + txbds_processed++; + if (likely(ring->clean_ptr < ring->end_ptr)) + ring->clean_ptr++; + else + ring->clean_ptr = ring->cb_ptr; } + ring->free_bds += txbds_processed; + ring->c_index = (ring->c_index + txbds_processed) & DMA_C_INDEX_MASK; + if (ring->free_bds > (MAX_SKB_FRAGS + 1)) { + txq = netdev_get_tx_queue(dev, ring->queue); if (netif_tx_queue_stopped(txq)) netif_tx_wake_queue(txq); } - ring->c_index = c_index; - return pkts_compl; } @@ -1734,6 +1730,7 @@ static void bcmgenet_init_tx_ring(struct bcmgenet_priv *priv, } ring->cbs = priv->tx_cbs + start_ptr; ring->size = size; + ring->clean_ptr = start_ptr; ring->c_index = 0; ring->free_bds = size; ring->write_ptr = start_ptr; diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.h b/drivers/net/ethernet/broadcom/genet/bcmgenet.h index 016bd12bf493..548b7e934727 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h @@ -525,6 +525,7 @@ struct bcmgenet_tx_ring { unsigned int queue; /* queue index */ struct enet_cb *cbs; /* tx ring buffer control block*/ unsigned int size; /* size of each tx ring */ + unsigned int clean_ptr; /* Tx ring clean pointer */ unsigned int c_index; /* last consumer index of each ring*/ unsigned int free_bds; /* # of free bds for each ring */ unsigned int write_ptr; /* Tx ring write pointer SW copy */ -- GitLab From 5d2068da8d339e4dff8f9b9a1246e6a79e2949d8 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 5 Mar 2015 10:49:16 +1030 Subject: [PATCH 02749/11651] ia64: fix up obsolete cpu function usage. Thanks to spatch, then a sweep for for_each_cpu_mask => for_each_cpu. Signed-off-by: Rusty Russell Cc: Tony Luck Cc: Fenghua Yu Cc: linux-ia64@vger.kernel.org --- arch/ia64/include/asm/acpi.h | 6 +++--- arch/ia64/kernel/acpi.c | 2 +- arch/ia64/kernel/iosapic.c | 2 +- arch/ia64/kernel/irq_ia64.c | 28 ++++++++++++------------ arch/ia64/kernel/mca.c | 10 ++++----- arch/ia64/kernel/numa.c | 10 ++++----- arch/ia64/kernel/salinfo.c | 24 ++++++++++----------- arch/ia64/kernel/setup.c | 11 +++++----- arch/ia64/kernel/smp.c | 6 +++--- arch/ia64/kernel/smpboot.c | 42 +++++++++++++++++++----------------- arch/ia64/kernel/topology.c | 6 +++--- 11 files changed, 75 insertions(+), 72 deletions(-) diff --git a/arch/ia64/include/asm/acpi.h b/arch/ia64/include/asm/acpi.h index a1d91ab4c5ef..aa0fdf125aba 100644 --- a/arch/ia64/include/asm/acpi.h +++ b/arch/ia64/include/asm/acpi.h @@ -117,7 +117,7 @@ static inline void arch_acpi_set_pdc_bits(u32 *buf) #ifdef CONFIG_ACPI_NUMA extern cpumask_t early_cpu_possible_map; #define for_each_possible_early_cpu(cpu) \ - for_each_cpu_mask((cpu), early_cpu_possible_map) + for_each_cpu((cpu), &early_cpu_possible_map) static inline void per_cpu_scan_finalize(int min_cpus, int reserve_cpus) { @@ -125,13 +125,13 @@ static inline void per_cpu_scan_finalize(int min_cpus, int reserve_cpus) int cpu; int next_nid = 0; - low_cpu = cpus_weight(early_cpu_possible_map); + low_cpu = cpumask_weight(&early_cpu_possible_map); high_cpu = max(low_cpu, min_cpus); high_cpu = min(high_cpu + reserve_cpus, NR_CPUS); for (cpu = low_cpu; cpu < high_cpu; cpu++) { - cpu_set(cpu, early_cpu_possible_map); + cpumask_set_cpu(cpu, &early_cpu_possible_map); if (node_cpuid[cpu].nid == NUMA_NO_NODE) { node_cpuid[cpu].nid = next_nid; next_nid++; diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index 2c4498919d3c..35bf22cc71b7 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c @@ -483,7 +483,7 @@ acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa) (pa->apic_id << 8) | (pa->local_sapic_eid); /* nid should be overridden as logical node id later */ node_cpuid[srat_num_cpus].nid = pxm; - cpu_set(srat_num_cpus, early_cpu_possible_map); + cpumask_set_cpu(srat_num_cpus, &early_cpu_possible_map); srat_num_cpus++; } diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c index cd44a57c73be..bc9501e36e77 100644 --- a/arch/ia64/kernel/iosapic.c +++ b/arch/ia64/kernel/iosapic.c @@ -690,7 +690,7 @@ skip_numa_setup: do { if (++cpu >= nr_cpu_ids) cpu = 0; - } while (!cpu_online(cpu) || !cpu_isset(cpu, domain)); + } while (!cpu_online(cpu) || !cpumask_test_cpu(cpu, &domain)); return cpu_physical_id(cpu); #else /* CONFIG_SMP */ diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c index 3329177c262e..9f40d972969c 100644 --- a/arch/ia64/kernel/irq_ia64.c +++ b/arch/ia64/kernel/irq_ia64.c @@ -109,13 +109,13 @@ static inline int find_unassigned_vector(cpumask_t domain) int pos, vector; cpumask_and(&mask, &domain, cpu_online_mask); - if (cpus_empty(mask)) + if (cpumask_empty(&mask)) return -EINVAL; for (pos = 0; pos < IA64_NUM_DEVICE_VECTORS; pos++) { vector = IA64_FIRST_DEVICE_VECTOR + pos; - cpus_and(mask, domain, vector_table[vector]); - if (!cpus_empty(mask)) + cpumask_and(&mask, &domain, &vector_table[vector]); + if (!cpumask_empty(&mask)) continue; return vector; } @@ -132,18 +132,18 @@ static int __bind_irq_vector(int irq, int vector, cpumask_t domain) BUG_ON((unsigned)vector >= IA64_NUM_VECTORS); cpumask_and(&mask, &domain, cpu_online_mask); - if (cpus_empty(mask)) + if (cpumask_empty(&mask)) return -EINVAL; - if ((cfg->vector == vector) && cpus_equal(cfg->domain, domain)) + if ((cfg->vector == vector) && cpumask_equal(&cfg->domain, &domain)) return 0; if (cfg->vector != IRQ_VECTOR_UNASSIGNED) return -EBUSY; - for_each_cpu_mask(cpu, mask) + for_each_cpu(cpu, &mask) per_cpu(vector_irq, cpu)[vector] = irq; cfg->vector = vector; cfg->domain = domain; irq_status[irq] = IRQ_USED; - cpus_or(vector_table[vector], vector_table[vector], domain); + cpumask_or(&vector_table[vector], &vector_table[vector], &domain); return 0; } @@ -242,7 +242,7 @@ void __setup_vector_irq(int cpu) per_cpu(vector_irq, cpu)[vector] = -1; /* Mark the inuse vectors */ for (irq = 0; irq < NR_IRQS; ++irq) { - if (!cpu_isset(cpu, irq_cfg[irq].domain)) + if (!cpumask_test_cpu(cpu, &irq_cfg[irq].domain)) continue; vector = irq_to_vector(irq); per_cpu(vector_irq, cpu)[vector] = irq; @@ -273,7 +273,7 @@ static int __irq_prepare_move(int irq, int cpu) return -EBUSY; if (cfg->vector == IRQ_VECTOR_UNASSIGNED || !cpu_online(cpu)) return -EINVAL; - if (cpu_isset(cpu, cfg->domain)) + if (cpumask_test_cpu(cpu, &cfg->domain)) return 0; domain = vector_allocation_domain(cpu); vector = find_unassigned_vector(domain); @@ -307,12 +307,12 @@ void irq_complete_move(unsigned irq) if (likely(!cfg->move_in_progress)) return; - if (unlikely(cpu_isset(smp_processor_id(), cfg->old_domain))) + if (unlikely(cpumask_test_cpu(smp_processor_id(), &cfg->old_domain))) return; cpumask_and(&cleanup_mask, &cfg->old_domain, cpu_online_mask); - cfg->move_cleanup_count = cpus_weight(cleanup_mask); - for_each_cpu_mask(i, cleanup_mask) + cfg->move_cleanup_count = cpumask_weight(&cleanup_mask); + for_each_cpu(i, &cleanup_mask) platform_send_ipi(i, IA64_IRQ_MOVE_VECTOR, IA64_IPI_DM_INT, 0); cfg->move_in_progress = 0; } @@ -338,12 +338,12 @@ static irqreturn_t smp_irq_move_cleanup_interrupt(int irq, void *dev_id) if (!cfg->move_cleanup_count) goto unlock; - if (!cpu_isset(me, cfg->old_domain)) + if (!cpumask_test_cpu(me, &cfg->old_domain)) goto unlock; spin_lock_irqsave(&vector_lock, flags); __this_cpu_write(vector_irq[vector], -1); - cpu_clear(me, vector_table[vector]); + cpumask_clear_cpu(me, &vector_table[vector]); spin_unlock_irqrestore(&vector_lock, flags); cfg->move_cleanup_count--; unlock: diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c index 8bfd36af46f8..dd5801eb4c69 100644 --- a/arch/ia64/kernel/mca.c +++ b/arch/ia64/kernel/mca.c @@ -1293,7 +1293,7 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw, monarch_cpu = cpu; sos->monarch = 1; } else { - cpu_set(cpu, mca_cpu); + cpumask_set_cpu(cpu, &mca_cpu); sos->monarch = 0; } mprintk(KERN_INFO "Entered OS MCA handler. PSP=%lx cpu=%d " @@ -1316,7 +1316,7 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw, */ ia64_mca_wakeup_all(); } else { - while (cpu_isset(cpu, mca_cpu)) + while (cpumask_test_cpu(cpu, &mca_cpu)) cpu_relax(); /* spin until monarch wakes us */ } @@ -1355,9 +1355,9 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw, * and put this cpu in the rendez loop. */ for_each_online_cpu(i) { - if (cpu_isset(i, mca_cpu)) { + if (cpumask_test_cpu(i, &mca_cpu)) { monarch_cpu = i; - cpu_clear(i, mca_cpu); /* wake next cpu */ + cpumask_clear_cpu(i, &mca_cpu); /* wake next cpu */ while (monarch_cpu != -1) cpu_relax(); /* spin until last cpu leaves */ set_curr_task(cpu, previous_current); @@ -1822,7 +1822,7 @@ format_mca_init_stack(void *mca_data, unsigned long offset, ti->cpu = cpu; p->stack = ti; p->state = TASK_UNINTERRUPTIBLE; - cpu_set(cpu, p->cpus_allowed); + cpumask_set_cpu(cpu, &p->cpus_allowed); INIT_LIST_HEAD(&p->tasks); p->parent = p->real_parent = p->group_leader = p; INIT_LIST_HEAD(&p->children); diff --git a/arch/ia64/kernel/numa.c b/arch/ia64/kernel/numa.c index d288cde93606..92c376279c6d 100644 --- a/arch/ia64/kernel/numa.c +++ b/arch/ia64/kernel/numa.c @@ -39,7 +39,7 @@ void map_cpu_to_node(int cpu, int nid) } /* sanity check first */ oldnid = cpu_to_node_map[cpu]; - if (cpu_isset(cpu, node_to_cpu_mask[oldnid])) { + if (cpumask_test_cpu(cpu, &node_to_cpu_mask[oldnid])) { return; /* nothing to do */ } /* we don't have cpu-driven node hot add yet... @@ -47,16 +47,16 @@ void map_cpu_to_node(int cpu, int nid) if (!node_online(nid)) nid = first_online_node; cpu_to_node_map[cpu] = nid; - cpu_set(cpu, node_to_cpu_mask[nid]); + cpumask_set_cpu(cpu, &node_to_cpu_mask[nid]); return; } void unmap_cpu_from_node(int cpu, int nid) { - WARN_ON(!cpu_isset(cpu, node_to_cpu_mask[nid])); + WARN_ON(!cpumask_test_cpu(cpu, &node_to_cpu_mask[nid])); WARN_ON(cpu_to_node_map[cpu] != nid); cpu_to_node_map[cpu] = 0; - cpu_clear(cpu, node_to_cpu_mask[nid]); + cpumask_clear_cpu(cpu, &node_to_cpu_mask[nid]); } @@ -71,7 +71,7 @@ void __init build_cpu_to_node_map(void) int cpu, i, node; for(node=0; node < MAX_NUMNODES; node++) - cpus_clear(node_to_cpu_mask[node]); + cpumask_clear(&node_to_cpu_mask[node]); for_each_possible_early_cpu(cpu) { node = -1; diff --git a/arch/ia64/kernel/salinfo.c b/arch/ia64/kernel/salinfo.c index ee9719eebb1e..1eeffb7fbb16 100644 --- a/arch/ia64/kernel/salinfo.c +++ b/arch/ia64/kernel/salinfo.c @@ -256,7 +256,7 @@ salinfo_log_wakeup(int type, u8 *buffer, u64 size, int irqsafe) data_saved->buffer = buffer; } } - cpu_set(smp_processor_id(), data->cpu_event); + cpumask_set_cpu(smp_processor_id(), &data->cpu_event); if (irqsafe) { salinfo_work_to_do(data); spin_unlock_irqrestore(&data_saved_lock, flags); @@ -274,7 +274,7 @@ salinfo_timeout_check(struct salinfo_data *data) unsigned long flags; if (!data->open) return; - if (!cpus_empty(data->cpu_event)) { + if (!cpumask_empty(&data->cpu_event)) { spin_lock_irqsave(&data_saved_lock, flags); salinfo_work_to_do(data); spin_unlock_irqrestore(&data_saved_lock, flags); @@ -308,7 +308,7 @@ salinfo_event_read(struct file *file, char __user *buffer, size_t count, loff_t int i, n, cpu = -1; retry: - if (cpus_empty(data->cpu_event) && down_trylock(&data->mutex)) { + if (cpumask_empty(&data->cpu_event) && down_trylock(&data->mutex)) { if (file->f_flags & O_NONBLOCK) return -EAGAIN; if (down_interruptible(&data->mutex)) @@ -317,9 +317,9 @@ retry: n = data->cpu_check; for (i = 0; i < nr_cpu_ids; i++) { - if (cpu_isset(n, data->cpu_event)) { + if (cpumask_test_cpu(n, &data->cpu_event)) { if (!cpu_online(n)) { - cpu_clear(n, data->cpu_event); + cpumask_clear_cpu(n, &data->cpu_event); continue; } cpu = n; @@ -451,7 +451,7 @@ retry: call_on_cpu(cpu, salinfo_log_read_cpu, data); if (!data->log_size) { data->state = STATE_NO_DATA; - cpu_clear(cpu, data->cpu_event); + cpumask_clear_cpu(cpu, &data->cpu_event); } else { data->state = STATE_LOG_RECORD; } @@ -491,11 +491,11 @@ salinfo_log_clear(struct salinfo_data *data, int cpu) unsigned long flags; spin_lock_irqsave(&data_saved_lock, flags); data->state = STATE_NO_DATA; - if (!cpu_isset(cpu, data->cpu_event)) { + if (!cpumask_test_cpu(cpu, &data->cpu_event)) { spin_unlock_irqrestore(&data_saved_lock, flags); return 0; } - cpu_clear(cpu, data->cpu_event); + cpumask_clear_cpu(cpu, &data->cpu_event); if (data->saved_num) { shift1_data_saved(data, data->saved_num - 1); data->saved_num = 0; @@ -509,7 +509,7 @@ salinfo_log_clear(struct salinfo_data *data, int cpu) salinfo_log_new_read(cpu, data); if (data->state == STATE_LOG_RECORD) { spin_lock_irqsave(&data_saved_lock, flags); - cpu_set(cpu, data->cpu_event); + cpumask_set_cpu(cpu, &data->cpu_event); salinfo_work_to_do(data); spin_unlock_irqrestore(&data_saved_lock, flags); } @@ -581,7 +581,7 @@ salinfo_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu for (i = 0, data = salinfo_data; i < ARRAY_SIZE(salinfo_data); ++i, ++data) { - cpu_set(cpu, data->cpu_event); + cpumask_set_cpu(cpu, &data->cpu_event); salinfo_work_to_do(data); } spin_unlock_irqrestore(&data_saved_lock, flags); @@ -601,7 +601,7 @@ salinfo_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu shift1_data_saved(data, j); } } - cpu_clear(cpu, data->cpu_event); + cpumask_clear_cpu(cpu, &data->cpu_event); } spin_unlock_irqrestore(&data_saved_lock, flags); break; @@ -659,7 +659,7 @@ salinfo_init(void) /* we missed any events before now */ for_each_online_cpu(j) - cpu_set(j, data->cpu_event); + cpumask_set_cpu(j, &data->cpu_event); *sdir++ = dir; } diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index d86669bcdfb2..b9761389cb8d 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c @@ -562,8 +562,8 @@ setup_arch (char **cmdline_p) # ifdef CONFIG_ACPI_HOTPLUG_CPU prefill_possible_map(); # endif - per_cpu_scan_finalize((cpus_weight(early_cpu_possible_map) == 0 ? - 32 : cpus_weight(early_cpu_possible_map)), + per_cpu_scan_finalize((cpumask_weight(&early_cpu_possible_map) == 0 ? + 32 : cpumask_weight(&early_cpu_possible_map)), additional_cpus > 0 ? additional_cpus : 0); # endif #endif /* CONFIG_APCI_BOOT */ @@ -702,7 +702,8 @@ show_cpuinfo (struct seq_file *m, void *v) c->itc_freq / 1000000, c->itc_freq % 1000000, lpj*HZ/500000, (lpj*HZ/5000) % 100); #ifdef CONFIG_SMP - seq_printf(m, "siblings : %u\n", cpus_weight(cpu_core_map[cpunum])); + seq_printf(m, "siblings : %u\n", + cpumask_weight(&cpu_core_map[cpunum])); if (c->socket_id != -1) seq_printf(m, "physical id: %u\n", c->socket_id); if (c->threads_per_core > 1 || c->cores_per_socket > 1) @@ -933,8 +934,8 @@ cpu_init (void) * (must be done after per_cpu area is setup) */ if (smp_processor_id() == 0) { - cpu_set(0, per_cpu(cpu_sibling_map, 0)); - cpu_set(0, cpu_core_map[0]); + cpumask_set_cpu(0, &per_cpu(cpu_sibling_map, 0)); + cpumask_set_cpu(0, &cpu_core_map[0]); } else { /* * Set ar.k3 so that assembly code in MCA handler can compute diff --git a/arch/ia64/kernel/smp.c b/arch/ia64/kernel/smp.c index 9fcd4e63048f..7f706d4f84f7 100644 --- a/arch/ia64/kernel/smp.c +++ b/arch/ia64/kernel/smp.c @@ -262,11 +262,11 @@ smp_flush_tlb_cpumask(cpumask_t xcpumask) preempt_disable(); mycpu = smp_processor_id(); - for_each_cpu_mask(cpu, cpumask) + for_each_cpu(cpu, &cpumask) counts[cpu] = local_tlb_flush_counts[cpu].count & 0xffff; mb(); - for_each_cpu_mask(cpu, cpumask) { + for_each_cpu(cpu, &cpumask) { if (cpu == mycpu) flush_mycpu = 1; else @@ -276,7 +276,7 @@ smp_flush_tlb_cpumask(cpumask_t xcpumask) if (flush_mycpu) smp_local_flush_tlb(); - for_each_cpu_mask(cpu, cpumask) + for_each_cpu(cpu, &cpumask) while(counts[cpu] == (local_tlb_flush_counts[cpu].count & 0xffff)) udelay(FLUSH_DELAY); diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c index 547a48d78bd7..15051e9c2c6f 100644 --- a/arch/ia64/kernel/smpboot.c +++ b/arch/ia64/kernel/smpboot.c @@ -434,7 +434,7 @@ smp_callin (void) /* * Allow the master to continue. */ - cpu_set(cpuid, cpu_callin_map); + cpumask_set_cpu(cpuid, &cpu_callin_map); Dprintk("Stack on CPU %d at about %p\n",cpuid, &cpuid); } @@ -475,13 +475,13 @@ do_boot_cpu (int sapicid, int cpu, struct task_struct *idle) */ Dprintk("Waiting on callin_map ..."); for (timeout = 0; timeout < 100000; timeout++) { - if (cpu_isset(cpu, cpu_callin_map)) + if (cpumask_test_cpu(cpu, &cpu_callin_map)) break; /* It has booted */ udelay(100); } Dprintk("\n"); - if (!cpu_isset(cpu, cpu_callin_map)) { + if (!cpumask_test_cpu(cpu, &cpu_callin_map)) { printk(KERN_ERR "Processor 0x%x/0x%x is stuck.\n", cpu, sapicid); ia64_cpu_to_sapicid[cpu] = -1; set_cpu_online(cpu, false); /* was set in smp_callin() */ @@ -541,7 +541,7 @@ smp_prepare_cpus (unsigned int max_cpus) smp_setup_percpu_timer(); - cpu_set(0, cpu_callin_map); + cpumask_set_cpu(0, &cpu_callin_map); local_cpu_data->loops_per_jiffy = loops_per_jiffy; ia64_cpu_to_sapicid[0] = boot_cpu_id; @@ -565,7 +565,7 @@ smp_prepare_cpus (unsigned int max_cpus) void smp_prepare_boot_cpu(void) { set_cpu_online(smp_processor_id(), true); - cpu_set(smp_processor_id(), cpu_callin_map); + cpumask_set_cpu(smp_processor_id(), &cpu_callin_map); set_numa_node(cpu_to_node_map[smp_processor_id()]); per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE; paravirt_post_smp_prepare_boot_cpu(); @@ -577,10 +577,10 @@ clear_cpu_sibling_map(int cpu) { int i; - for_each_cpu_mask(i, per_cpu(cpu_sibling_map, cpu)) - cpu_clear(cpu, per_cpu(cpu_sibling_map, i)); - for_each_cpu_mask(i, cpu_core_map[cpu]) - cpu_clear(cpu, cpu_core_map[i]); + for_each_cpu(i, &per_cpu(cpu_sibling_map, cpu)) + cpumask_clear_cpu(cpu, &per_cpu(cpu_sibling_map, i)); + for_each_cpu(i, &cpu_core_map[cpu]) + cpumask_clear_cpu(cpu, &cpu_core_map[i]); per_cpu(cpu_sibling_map, cpu) = cpu_core_map[cpu] = CPU_MASK_NONE; } @@ -592,12 +592,12 @@ remove_siblinginfo(int cpu) if (cpu_data(cpu)->threads_per_core == 1 && cpu_data(cpu)->cores_per_socket == 1) { - cpu_clear(cpu, cpu_core_map[cpu]); - cpu_clear(cpu, per_cpu(cpu_sibling_map, cpu)); + cpumask_clear_cpu(cpu, &cpu_core_map[cpu]); + cpumask_clear_cpu(cpu, &per_cpu(cpu_sibling_map, cpu)); return; } - last = (cpus_weight(cpu_core_map[cpu]) == 1 ? 1 : 0); + last = (cpumask_weight(&cpu_core_map[cpu]) == 1 ? 1 : 0); /* remove it from all sibling map's */ clear_cpu_sibling_map(cpu); @@ -673,7 +673,7 @@ int __cpu_disable(void) remove_siblinginfo(cpu); fixup_irqs(); local_flush_tlb_all(); - cpu_clear(cpu, cpu_callin_map); + cpumask_clear_cpu(cpu, &cpu_callin_map); return 0; } @@ -718,11 +718,13 @@ static inline void set_cpu_sibling_map(int cpu) for_each_online_cpu(i) { if ((cpu_data(cpu)->socket_id == cpu_data(i)->socket_id)) { - cpu_set(i, cpu_core_map[cpu]); - cpu_set(cpu, cpu_core_map[i]); + cpumask_set_cpu(i, &cpu_core_map[cpu]); + cpumask_set_cpu(cpu, &cpu_core_map[i]); if (cpu_data(cpu)->core_id == cpu_data(i)->core_id) { - cpu_set(i, per_cpu(cpu_sibling_map, cpu)); - cpu_set(cpu, per_cpu(cpu_sibling_map, i)); + cpumask_set_cpu(i, + &per_cpu(cpu_sibling_map, cpu)); + cpumask_set_cpu(cpu, + &per_cpu(cpu_sibling_map, i)); } } } @@ -742,7 +744,7 @@ __cpu_up(unsigned int cpu, struct task_struct *tidle) * Already booted cpu? not valid anymore since we dont * do idle loop tightspin anymore. */ - if (cpu_isset(cpu, cpu_callin_map)) + if (cpumask_test_cpu(cpu, &cpu_callin_map)) return -EINVAL; per_cpu(cpu_state, cpu) = CPU_UP_PREPARE; @@ -753,8 +755,8 @@ __cpu_up(unsigned int cpu, struct task_struct *tidle) if (cpu_data(cpu)->threads_per_core == 1 && cpu_data(cpu)->cores_per_socket == 1) { - cpu_set(cpu, per_cpu(cpu_sibling_map, cpu)); - cpu_set(cpu, cpu_core_map[cpu]); + cpumask_set_cpu(cpu, &per_cpu(cpu_sibling_map, cpu)); + cpumask_set_cpu(cpu, &cpu_core_map[cpu]); return 0; } diff --git a/arch/ia64/kernel/topology.c b/arch/ia64/kernel/topology.c index 965ab42fabb0..c01fe8991244 100644 --- a/arch/ia64/kernel/topology.c +++ b/arch/ia64/kernel/topology.c @@ -148,7 +148,7 @@ static void cache_shared_cpu_map_setup(unsigned int cpu, if (cpu_data(cpu)->threads_per_core <= 1 && cpu_data(cpu)->cores_per_socket <= 1) { - cpu_set(cpu, this_leaf->shared_cpu_map); + cpumask_set_cpu(cpu, &this_leaf->shared_cpu_map); return; } @@ -164,7 +164,7 @@ static void cache_shared_cpu_map_setup(unsigned int cpu, if (cpu_data(cpu)->socket_id == cpu_data(j)->socket_id && cpu_data(j)->core_id == csi.log1_cid && cpu_data(j)->thread_id == csi.log1_tid) - cpu_set(j, this_leaf->shared_cpu_map); + cpumask_set_cpu(j, &this_leaf->shared_cpu_map); i++; } while (i < num_shared && @@ -177,7 +177,7 @@ static void cache_shared_cpu_map_setup(unsigned int cpu, static void cache_shared_cpu_map_setup(unsigned int cpu, struct cache_info * this_leaf) { - cpu_set(cpu, this_leaf->shared_cpu_map); + cpumask_set_cpu(cpu, &this_leaf->shared_cpu_map); return; } #endif -- GitLab From b09fcc90dc834b98c47cbb4d151526526ff10397 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 5 Mar 2015 10:49:17 +1030 Subject: [PATCH 02750/11651] um: fix up obsolete cpu function usage. Thanks to spatch. Signed-off-by: Rusty Russell Cc: Jeff Dike Cc: Richard Weinberger Cc: user-mode-linux-devel@lists.sourceforge.net --- arch/um/kernel/smp.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/um/kernel/smp.c b/arch/um/kernel/smp.c index 5c8c3ea7db7b..74077892b34a 100644 --- a/arch/um/kernel/smp.c +++ b/arch/um/kernel/smp.c @@ -67,12 +67,12 @@ static int idle_proc(void *cpup) os_set_fd_async(cpu_data[cpu].ipi_pipe[0]); wmb(); - if (cpu_test_and_set(cpu, cpu_callin_map)) { + if (cpumask_test_and_set_cpu(cpu, &cpu_callin_map)) { printk(KERN_ERR "huh, CPU#%d already present??\n", cpu); BUG(); } - while (!cpu_isset(cpu, smp_commenced_mask)) + while (!cpumask_test_cpu(cpu, &smp_commenced_mask)) cpu_relax(); notify_cpu_starting(cpu); @@ -111,7 +111,7 @@ void smp_prepare_cpus(unsigned int maxcpus) set_cpu_possible(i, true); set_cpu_online(me, true); - cpu_set(me, cpu_callin_map); + cpumask_set_cpu(me, &cpu_callin_map); err = os_pipe(cpu_data[me].ipi_pipe, 1, 1); if (err < 0) @@ -127,11 +127,11 @@ void smp_prepare_cpus(unsigned int maxcpus) init_idle(idle, cpu); waittime = 200000000; - while (waittime-- && !cpu_isset(cpu, cpu_callin_map)) + while (waittime-- && !cpumask_test_cpu(cpu, &cpu_callin_map)) cpu_relax(); printk(KERN_INFO "%s\n", - cpu_isset(cpu, cpu_calling_map) ? "done" : "failed"); + cpumask_test_cpu(cpu, &cpu_calling_map) ? "done" : "failed"); } } @@ -142,7 +142,7 @@ void smp_prepare_boot_cpu(void) int __cpu_up(unsigned int cpu, struct task_struct *tidle) { - cpu_set(cpu, smp_commenced_mask); + cpumask_set_cpu(cpu, &smp_commenced_mask); while (!cpu_online(cpu)) mb(); return 0; -- GitLab From d089f8e97d371a662dd233491e03bda377c9d46d Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 5 Mar 2015 10:49:17 +1030 Subject: [PATCH 02751/11651] x86: fix up obsolete cpu function usage. Thanks to spatch, plus manual removal of "&*". Signed-off-by: Rusty Russell Cc: x86@kernel.org --- arch/x86/kernel/apic/x2apic_cluster.c | 8 ++++---- arch/x86/kernel/irq.c | 4 ++-- arch/x86/platform/uv/tlb_uv.c | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/arch/x86/kernel/apic/x2apic_cluster.c b/arch/x86/kernel/apic/x2apic_cluster.c index e658f21681c8..d9d0bd2faaf4 100644 --- a/arch/x86/kernel/apic/x2apic_cluster.c +++ b/arch/x86/kernel/apic/x2apic_cluster.c @@ -135,12 +135,12 @@ static void init_x2apic_ldr(void) per_cpu(x86_cpu_to_logical_apicid, this_cpu) = apic_read(APIC_LDR); - __cpu_set(this_cpu, per_cpu(cpus_in_cluster, this_cpu)); + cpumask_set_cpu(this_cpu, per_cpu(cpus_in_cluster, this_cpu)); for_each_online_cpu(cpu) { if (x2apic_cluster(this_cpu) != x2apic_cluster(cpu)) continue; - __cpu_set(this_cpu, per_cpu(cpus_in_cluster, cpu)); - __cpu_set(cpu, per_cpu(cpus_in_cluster, this_cpu)); + cpumask_set_cpu(this_cpu, per_cpu(cpus_in_cluster, cpu)); + cpumask_set_cpu(cpu, per_cpu(cpus_in_cluster, this_cpu)); } } @@ -195,7 +195,7 @@ static int x2apic_init_cpu_notifier(void) BUG_ON(!per_cpu(cpus_in_cluster, cpu) || !per_cpu(ipi_mask, cpu)); - __cpu_set(cpu, per_cpu(cpus_in_cluster, cpu)); + cpumask_set_cpu(cpu, per_cpu(cpus_in_cluster, cpu)); register_hotcpu_notifier(&x2apic_cpu_notifier); return 1; } diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c index 67b1cbe0093a..e5952c225532 100644 --- a/arch/x86/kernel/irq.c +++ b/arch/x86/kernel/irq.c @@ -295,7 +295,7 @@ int check_irq_vectors_for_cpu_disable(void) this_cpu = smp_processor_id(); cpumask_copy(&online_new, cpu_online_mask); - cpu_clear(this_cpu, online_new); + cpumask_clear_cpu(this_cpu, &online_new); this_count = 0; for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; vector++) { @@ -307,7 +307,7 @@ int check_irq_vectors_for_cpu_disable(void) data = irq_desc_get_irq_data(desc); cpumask_copy(&affinity_new, data->affinity); - cpu_clear(this_cpu, affinity_new); + cpumask_clear_cpu(this_cpu, &affinity_new); /* Do not count inactive or per-cpu irqs. */ if (!irq_has_action(irq) || irqd_is_per_cpu(data)) diff --git a/arch/x86/platform/uv/tlb_uv.c b/arch/x86/platform/uv/tlb_uv.c index 994798548b1a..3b6ec42718e4 100644 --- a/arch/x86/platform/uv/tlb_uv.c +++ b/arch/x86/platform/uv/tlb_uv.c @@ -415,7 +415,7 @@ static void reset_with_ipi(struct pnmask *distribution, struct bau_control *bcp) struct reset_args reset_args; reset_args.sender = sender; - cpus_clear(*mask); + cpumask_clear(mask); /* find a single cpu for each uvhub in this distribution mask */ maskbits = sizeof(struct pnmask) * BITSPERBYTE; /* each bit is a pnode relative to the partition base pnode */ @@ -425,7 +425,7 @@ static void reset_with_ipi(struct pnmask *distribution, struct bau_control *bcp) continue; apnode = pnode + bcp->partition_base_pnode; cpu = pnode_to_first_cpu(apnode, smaster); - cpu_set(cpu, *mask); + cpumask_set_cpu(cpu, mask); } /* IPI all cpus; preemption is already disabled */ @@ -1126,7 +1126,7 @@ const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask, /* don't actually do a shootdown of the local cpu */ cpumask_andnot(flush_mask, cpumask, cpumask_of(cpu)); - if (cpu_isset(cpu, *cpumask)) + if (cpumask_test_cpu(cpu, cpumask)) stat->s_ntargself++; bau_desc = bcp->descriptor_base; -- GitLab From 8dd928915a73bf95a727a46037964243eb1e042c Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 5 Mar 2015 10:49:17 +1030 Subject: [PATCH 02752/11651] mips: fix up obsolete cpu function usage. Thanks to spatch, plus manual removal of "&*". Then a sweep for for_each_cpu_mask => for_each_cpu. Signed-off-by: Rusty Russell Cc: Ralf Baechle Cc: Kevin Cernekee Cc: Florian Fainelli Cc: linux-mips@linux-mips.org --- arch/mips/bcm63xx/irq.c | 4 ++-- arch/mips/cavium-octeon/smp.c | 4 ++-- arch/mips/kernel/crash.c | 8 ++++---- arch/mips/kernel/mips-mt-fpaff.c | 4 ++-- arch/mips/kernel/process.c | 2 +- arch/mips/kernel/smp-bmips.c | 2 +- arch/mips/kernel/smp-cmp.c | 4 ++-- arch/mips/kernel/smp-cps.c | 4 ++-- arch/mips/kernel/smp-mt.c | 4 ++-- arch/mips/kernel/smp.c | 26 +++++++++++++------------- arch/mips/kernel/traps.c | 6 +++--- arch/mips/loongson/loongson-3/numa.c | 4 ++-- arch/mips/loongson/loongson-3/smp.c | 2 +- arch/mips/paravirt/paravirt-smp.c | 2 +- arch/mips/sgi-ip27/ip27-init.c | 2 +- arch/mips/sgi-ip27/ip27-klnuma.c | 10 +++++----- arch/mips/sgi-ip27/ip27-memory.c | 2 +- 17 files changed, 45 insertions(+), 45 deletions(-) diff --git a/arch/mips/bcm63xx/irq.c b/arch/mips/bcm63xx/irq.c index b94bf44d8d8e..e3e808a6c542 100644 --- a/arch/mips/bcm63xx/irq.c +++ b/arch/mips/bcm63xx/irq.c @@ -58,9 +58,9 @@ static inline int enable_irq_for_cpu(int cpu, struct irq_data *d, #ifdef CONFIG_SMP if (m) - enable &= cpu_isset(cpu, *m); + enable &= cpumask_test_cpu(cpu, m); else if (irqd_affinity_was_set(d)) - enable &= cpu_isset(cpu, *d->affinity); + enable &= cpumask_test_cpu(cpu, d->affinity); #endif return enable; } diff --git a/arch/mips/cavium-octeon/smp.c b/arch/mips/cavium-octeon/smp.c index 8b1eeffa12ed..56f5d080ef9d 100644 --- a/arch/mips/cavium-octeon/smp.c +++ b/arch/mips/cavium-octeon/smp.c @@ -72,7 +72,7 @@ static inline void octeon_send_ipi_mask(const struct cpumask *mask, { unsigned int i; - for_each_cpu_mask(i, *mask) + for_each_cpu(i, mask) octeon_send_ipi_single(i, action); } @@ -239,7 +239,7 @@ static int octeon_cpu_disable(void) return -ENOTSUPP; set_cpu_online(cpu, false); - cpu_clear(cpu, cpu_callin_map); + cpumask_clear_cpu(cpu, &cpu_callin_map); octeon_fixup_irqs(); flush_cache_all(); diff --git a/arch/mips/kernel/crash.c b/arch/mips/kernel/crash.c index d21264681e97..d434d5d5ae6e 100644 --- a/arch/mips/kernel/crash.c +++ b/arch/mips/kernel/crash.c @@ -25,9 +25,9 @@ static void crash_shutdown_secondary(void *ignore) return; local_irq_disable(); - if (!cpu_isset(cpu, cpus_in_crash)) + if (!cpumask_test_cpu(cpu, &cpus_in_crash)) crash_save_cpu(regs, cpu); - cpu_set(cpu, cpus_in_crash); + cpumask_set_cpu(cpu, &cpus_in_crash); while (!atomic_read(&kexec_ready_to_reboot)) cpu_relax(); @@ -50,7 +50,7 @@ static void crash_kexec_prepare_cpus(void) */ pr_emerg("Sending IPI to other cpus...\n"); msecs = 10000; - while ((cpus_weight(cpus_in_crash) < ncpus) && (--msecs > 0)) { + while ((cpumask_weight(&cpus_in_crash) < ncpus) && (--msecs > 0)) { cpu_relax(); mdelay(1); } @@ -66,5 +66,5 @@ void default_machine_crash_shutdown(struct pt_regs *regs) crashing_cpu = smp_processor_id(); crash_save_cpu(regs, crashing_cpu); crash_kexec_prepare_cpus(); - cpu_set(crashing_cpu, cpus_in_crash); + cpumask_set_cpu(crashing_cpu, &cpus_in_crash); } diff --git a/arch/mips/kernel/mips-mt-fpaff.c b/arch/mips/kernel/mips-mt-fpaff.c index 362bb3707e62..3e4491aa6d6b 100644 --- a/arch/mips/kernel/mips-mt-fpaff.c +++ b/arch/mips/kernel/mips-mt-fpaff.c @@ -114,8 +114,8 @@ asmlinkage long mipsmt_sys_sched_setaffinity(pid_t pid, unsigned int len, /* Compute new global allowed CPU set if necessary */ ti = task_thread_info(p); if (test_ti_thread_flag(ti, TIF_FPUBOUND) && - cpus_intersects(*new_mask, mt_fpu_cpumask)) { - cpus_and(*effective_mask, *new_mask, mt_fpu_cpumask); + cpumask_intersects(new_mask, &mt_fpu_cpumask)) { + cpumask_and(effective_mask, new_mask, &mt_fpu_cpumask); retval = set_cpus_allowed_ptr(p, effective_mask); } else { cpumask_copy(effective_mask, new_mask); diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index bf85cc180d91..4501c7a4bd58 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c @@ -49,7 +49,7 @@ void arch_cpu_idle_dead(void) { /* What the heck is this check doing ? */ - if (!cpu_isset(smp_processor_id(), cpu_callin_map)) + if (!cpumask_test_cpu(smp_processor_id(), &cpu_callin_map)) play_dead(); } #endif diff --git a/arch/mips/kernel/smp-bmips.c b/arch/mips/kernel/smp-bmips.c index b8bd9340c9c7..fd528d7ea278 100644 --- a/arch/mips/kernel/smp-bmips.c +++ b/arch/mips/kernel/smp-bmips.c @@ -362,7 +362,7 @@ static int bmips_cpu_disable(void) pr_info("SMP: CPU%d is offline\n", cpu); set_cpu_online(cpu, false); - cpu_clear(cpu, cpu_callin_map); + cpumask_clear_cpu(cpu, &cpu_callin_map); clear_c0_status(IE_IRQ5); local_flush_tlb_all(); diff --git a/arch/mips/kernel/smp-cmp.c b/arch/mips/kernel/smp-cmp.c index e36a859af666..d5e0f949dc48 100644 --- a/arch/mips/kernel/smp-cmp.c +++ b/arch/mips/kernel/smp-cmp.c @@ -66,7 +66,7 @@ static void cmp_smp_finish(void) #ifdef CONFIG_MIPS_MT_FPAFF /* If we have an FPU, enroll ourselves in the FPU-full mask */ if (cpu_has_fpu) - cpu_set(smp_processor_id(), mt_fpu_cpumask); + cpumask_set_cpu(smp_processor_id(), &mt_fpu_cpumask); #endif /* CONFIG_MIPS_MT_FPAFF */ local_irq_enable(); @@ -110,7 +110,7 @@ void __init cmp_smp_setup(void) #ifdef CONFIG_MIPS_MT_FPAFF /* If we have an FPU, enroll ourselves in the FPU-full mask */ if (cpu_has_fpu) - cpu_set(0, mt_fpu_cpumask); + cpumask_set_cpu(0, &mt_fpu_cpumask); #endif /* CONFIG_MIPS_MT_FPAFF */ for (i = 1; i < NR_CPUS; i++) { diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c index bed7590e475f..b0fe93e6537e 100644 --- a/arch/mips/kernel/smp-cps.c +++ b/arch/mips/kernel/smp-cps.c @@ -284,7 +284,7 @@ static void cps_smp_finish(void) #ifdef CONFIG_MIPS_MT_FPAFF /* If we have an FPU, enroll ourselves in the FPU-full mask */ if (cpu_has_fpu) - cpu_set(smp_processor_id(), mt_fpu_cpumask); + cpumask_set_cpu(smp_processor_id(), &mt_fpu_cpumask); #endif /* CONFIG_MIPS_MT_FPAFF */ local_irq_enable(); @@ -307,7 +307,7 @@ static int cps_cpu_disable(void) atomic_sub(1 << cpu_vpe_id(¤t_cpu_data), &core_cfg->vpe_mask); smp_mb__after_atomic(); set_cpu_online(cpu, false); - cpu_clear(cpu, cpu_callin_map); + cpumask_clear_cpu(cpu, &cpu_callin_map); return 0; } diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c index 17ea705f6c40..86311a164ef1 100644 --- a/arch/mips/kernel/smp-mt.c +++ b/arch/mips/kernel/smp-mt.c @@ -178,7 +178,7 @@ static void vsmp_smp_finish(void) #ifdef CONFIG_MIPS_MT_FPAFF /* If we have an FPU, enroll ourselves in the FPU-full mask */ if (cpu_has_fpu) - cpu_set(smp_processor_id(), mt_fpu_cpumask); + cpumask_set_cpu(smp_processor_id(), &mt_fpu_cpumask); #endif /* CONFIG_MIPS_MT_FPAFF */ local_irq_enable(); @@ -239,7 +239,7 @@ static void __init vsmp_smp_setup(void) #ifdef CONFIG_MIPS_MT_FPAFF /* If we have an FPU, enroll ourselves in the FPU-full mask */ if (cpu_has_fpu) - cpu_set(0, mt_fpu_cpumask); + cpumask_set_cpu(0, &mt_fpu_cpumask); #endif /* CONFIG_MIPS_MT_FPAFF */ if (!cpu_has_mipsmt) return; diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index 1c0d8c50b7e1..357acd3ac0e6 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c @@ -75,30 +75,30 @@ static inline void set_cpu_sibling_map(int cpu) { int i; - cpu_set(cpu, cpu_sibling_setup_map); + cpumask_set_cpu(cpu, &cpu_sibling_setup_map); if (smp_num_siblings > 1) { - for_each_cpu_mask(i, cpu_sibling_setup_map) { + for_each_cpu(i, &cpu_sibling_setup_map) { if (cpu_data[cpu].package == cpu_data[i].package && cpu_data[cpu].core == cpu_data[i].core) { - cpu_set(i, cpu_sibling_map[cpu]); - cpu_set(cpu, cpu_sibling_map[i]); + cpumask_set_cpu(i, &cpu_sibling_map[cpu]); + cpumask_set_cpu(cpu, &cpu_sibling_map[i]); } } } else - cpu_set(cpu, cpu_sibling_map[cpu]); + cpumask_set_cpu(cpu, &cpu_sibling_map[cpu]); } static inline void set_cpu_core_map(int cpu) { int i; - cpu_set(cpu, cpu_core_setup_map); + cpumask_set_cpu(cpu, &cpu_core_setup_map); - for_each_cpu_mask(i, cpu_core_setup_map) { + for_each_cpu(i, &cpu_core_setup_map) { if (cpu_data[cpu].package == cpu_data[i].package) { - cpu_set(i, cpu_core_map[cpu]); - cpu_set(cpu, cpu_core_map[i]); + cpumask_set_cpu(i, &cpu_core_map[cpu]); + cpumask_set_cpu(cpu, &cpu_core_map[i]); } } } @@ -138,7 +138,7 @@ asmlinkage void start_secondary(void) cpu = smp_processor_id(); cpu_data[cpu].udelay_val = loops_per_jiffy; - cpu_set(cpu, cpu_coherent_mask); + cpumask_set_cpu(cpu, &cpu_coherent_mask); notify_cpu_starting(cpu); set_cpu_online(cpu, true); @@ -146,7 +146,7 @@ asmlinkage void start_secondary(void) set_cpu_sibling_map(cpu); set_cpu_core_map(cpu); - cpu_set(cpu, cpu_callin_map); + cpumask_set_cpu(cpu, &cpu_callin_map); synchronise_count_slave(cpu); @@ -210,7 +210,7 @@ void smp_prepare_boot_cpu(void) { set_cpu_possible(0, true); set_cpu_online(0, true); - cpu_set(0, cpu_callin_map); + cpumask_set_cpu(0, &cpu_callin_map); } int __cpu_up(unsigned int cpu, struct task_struct *tidle) @@ -220,7 +220,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *tidle) /* * Trust is futile. We should really have timeouts ... */ - while (!cpu_isset(cpu, cpu_callin_map)) + while (!cpumask_test_cpu(cpu, &cpu_callin_map)) udelay(100); synchronise_count_master(cpu); diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 33984c04b60b..b05b9462c728 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -1121,13 +1121,13 @@ static void mt_ase_fp_affinity(void) * restricted the allowed set to exclude any CPUs with FPUs, * we'll skip the procedure. */ - if (cpus_intersects(current->cpus_allowed, mt_fpu_cpumask)) { + if (cpumask_intersects(¤t->cpus_allowed, &mt_fpu_cpumask)) { cpumask_t tmask; current->thread.user_cpus_allowed = current->cpus_allowed; - cpus_and(tmask, current->cpus_allowed, - mt_fpu_cpumask); + cpumask_and(&tmask, ¤t->cpus_allowed, + &mt_fpu_cpumask); set_cpus_allowed_ptr(current, &tmask); set_thread_flag(TIF_FPUBOUND); } diff --git a/arch/mips/loongson/loongson-3/numa.c b/arch/mips/loongson/loongson-3/numa.c index 6cae0e75de27..12d14ed48778 100644 --- a/arch/mips/loongson/loongson-3/numa.c +++ b/arch/mips/loongson/loongson-3/numa.c @@ -233,7 +233,7 @@ static __init void prom_meminit(void) if (node_online(node)) { szmem(node); node_mem_init(node); - cpus_clear(__node_data[(node)]->cpumask); + cpumask_clear(&__node_data[(node)]->cpumask); } } for (cpu = 0; cpu < loongson_sysconf.nr_cpus; cpu++) { @@ -244,7 +244,7 @@ static __init void prom_meminit(void) if (loongson_sysconf.reserved_cpus_mask & (1<cpumask); + cpumask_set_cpu(active_cpu, &__node_data[(node)]->cpumask); pr_info("NUMA: set cpumask cpu %d on node %d\n", active_cpu, node); active_cpu++; diff --git a/arch/mips/loongson/loongson-3/smp.c b/arch/mips/loongson/loongson-3/smp.c index e2eb688b5434..e3c68b5da18d 100644 --- a/arch/mips/loongson/loongson-3/smp.c +++ b/arch/mips/loongson/loongson-3/smp.c @@ -408,7 +408,7 @@ static int loongson3_cpu_disable(void) return -EBUSY; set_cpu_online(cpu, false); - cpu_clear(cpu, cpu_callin_map); + cpumask_clear_cpu(cpu, &cpu_callin_map); local_irq_save(flags); fixup_irqs(); local_irq_restore(flags); diff --git a/arch/mips/paravirt/paravirt-smp.c b/arch/mips/paravirt/paravirt-smp.c index 0164b0c48352..42181c7105df 100644 --- a/arch/mips/paravirt/paravirt-smp.c +++ b/arch/mips/paravirt/paravirt-smp.c @@ -75,7 +75,7 @@ static void paravirt_send_ipi_mask(const struct cpumask *mask, unsigned int acti { unsigned int cpu; - for_each_cpu_mask(cpu, *mask) + for_each_cpu(cpu, mask) paravirt_send_ipi_single(cpu, action); } diff --git a/arch/mips/sgi-ip27/ip27-init.c b/arch/mips/sgi-ip27/ip27-init.c index ee736bd103f8..570098bfdf87 100644 --- a/arch/mips/sgi-ip27/ip27-init.c +++ b/arch/mips/sgi-ip27/ip27-init.c @@ -60,7 +60,7 @@ static void per_hub_init(cnodeid_t cnode) nasid_t nasid = COMPACT_TO_NASID_NODEID(cnode); int i; - cpu_set(smp_processor_id(), hub->h_cpus); + cpumask_set_cpu(smp_processor_id(), &hub->h_cpus); if (test_and_set_bit(cnode, hub_init_mask)) return; diff --git a/arch/mips/sgi-ip27/ip27-klnuma.c b/arch/mips/sgi-ip27/ip27-klnuma.c index ecbb62f339c5..bda90cf87e8c 100644 --- a/arch/mips/sgi-ip27/ip27-klnuma.c +++ b/arch/mips/sgi-ip27/ip27-klnuma.c @@ -29,8 +29,8 @@ static cpumask_t ktext_repmask; void __init setup_replication_mask(void) { /* Set only the master cnode's bit. The master cnode is always 0. */ - cpus_clear(ktext_repmask); - cpu_set(0, ktext_repmask); + cpumask_clear(&ktext_repmask); + cpumask_set_cpu(0, &ktext_repmask); #ifdef CONFIG_REPLICATE_KTEXT #ifndef CONFIG_MAPPED_KERNEL @@ -43,7 +43,7 @@ void __init setup_replication_mask(void) if (cnode == 0) continue; /* Advertise that we have a copy of the kernel */ - cpu_set(cnode, ktext_repmask); + cpumask_set_cpu(cnode, &ktext_repmask); } } #endif @@ -99,7 +99,7 @@ void __init replicate_kernel_text() client_nasid = COMPACT_TO_NASID_NODEID(cnode); /* Check if this node should get a copy of the kernel */ - if (cpu_isset(cnode, ktext_repmask)) { + if (cpumask_test_cpu(cnode, &ktext_repmask)) { server_nasid = client_nasid; copy_kernel(server_nasid); } @@ -124,7 +124,7 @@ unsigned long node_getfirstfree(cnodeid_t cnode) loadbase += 16777216; #endif offset = PAGE_ALIGN((unsigned long)(&_end)) - loadbase; - if ((cnode == 0) || (cpu_isset(cnode, ktext_repmask))) + if ((cnode == 0) || (cpumask_test_cpu(cnode, &ktext_repmask))) return TO_NODE(nasid, offset) >> PAGE_SHIFT; else return KDM_TO_PHYS(PAGE_ALIGN(SYMMON_STK_ADDR(nasid, 0))) >> PAGE_SHIFT; diff --git a/arch/mips/sgi-ip27/ip27-memory.c b/arch/mips/sgi-ip27/ip27-memory.c index 0b68469e063f..8d0eb2643248 100644 --- a/arch/mips/sgi-ip27/ip27-memory.c +++ b/arch/mips/sgi-ip27/ip27-memory.c @@ -404,7 +404,7 @@ static void __init node_mem_init(cnodeid_t node) NODE_DATA(node)->node_start_pfn = start_pfn; NODE_DATA(node)->node_spanned_pages = end_pfn - start_pfn; - cpus_clear(hub_data(node)->h_cpus); + cpumask_clear(&hub_data(node)->h_cpus); slot_freepfn += PFN_UP(sizeof(struct pglist_data) + sizeof(struct hub_data)); -- GitLab From 434ed7f4b08fb8c23bdfabbb1f9427f2ed9ec27c Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 5 Mar 2015 10:49:18 +1030 Subject: [PATCH 02753/11651] arm64: fix up obsolete cpu function usage. Thanks to spatch. Signed-off-by: Rusty Russell Cc: Catalin Marinas Cc: Will Deacon Cc: linux-arm-kernel@lists.infradead.org --- arch/arm64/kernel/smp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index 328b8ce4b007..ccf734ad4961 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c @@ -635,7 +635,7 @@ void smp_send_stop(void) cpumask_t mask; cpumask_copy(&mask, cpu_online_mask); - cpu_clear(smp_processor_id(), mask); + cpumask_clear_cpu(smp_processor_id(), &mask); smp_cross_call(&mask, IPI_CPU_STOP); } -- GitLab From 0cc0cd7049f06a5ddaf38b6b268f0663c806a337 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 5 Mar 2015 10:49:18 +1030 Subject: [PATCH 02754/11651] tile: fix up obsolete cpu function usage. Thanks to spatch. Signed-off-by: Rusty Russell Cc: Chris Metcalf --- arch/tile/kernel/setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/tile/kernel/setup.c b/arch/tile/kernel/setup.c index f1f579914952..776c741b84a4 100644 --- a/arch/tile/kernel/setup.c +++ b/arch/tile/kernel/setup.c @@ -773,7 +773,7 @@ static void __init zone_sizes_init(void) * though, there'll be no lowmem, so we just alloc_bootmem * the memmap. There will be no percpu memory either. */ - if (i != 0 && cpu_isset(i, isolnodes)) { + if (i != 0 && cpumask_test_cpu(i, &isolnodes)) { node_memmap_pfn[i] = alloc_bootmem_pfn(0, memmap_size, 0); BUG_ON(node_percpu[i] != 0); -- GitLab From 409e56f3ef355ef7670b33e3fc6de8d1256a11d3 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 5 Mar 2015 10:49:18 +1030 Subject: [PATCH 02755/11651] parisc: fix up obsolete cpu function usage. Thanks to spatch. Signed-off-by: Rusty Russell Cc: "James E.J. Bottomley" Cc: Helge Deller Cc: linux-parisc@vger.kernel.org --- arch/parisc/kernel/irq.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c index cfe056fe7f5c..f3191db6e2e9 100644 --- a/arch/parisc/kernel/irq.c +++ b/arch/parisc/kernel/irq.c @@ -525,8 +525,8 @@ void do_cpu_irq_mask(struct pt_regs *regs) desc = irq_to_desc(irq); cpumask_copy(&dest, desc->irq_data.affinity); if (irqd_is_per_cpu(&desc->irq_data) && - !cpu_isset(smp_processor_id(), dest)) { - int cpu = first_cpu(dest); + !cpumask_test_cpu(smp_processor_id(), &dest)) { + int cpu = cpumask_first(&dest); printk(KERN_DEBUG "redirecting irq %d from CPU %d to %d\n", irq, smp_processor_id(), cpu); -- GitLab From 35168f512ff7eff9153e8c192f1155c994a75a0a Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 5 Mar 2015 10:49:18 +1030 Subject: [PATCH 02756/11651] blackfin: fix up obsolete cpu function usage. Signed-off-by: Rusty Russell Cc: Steven Miao Cc: adi-buildroot-devel@lists.sourceforge.net --- arch/blackfin/mach-bf561/smp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/blackfin/mach-bf561/smp.c b/arch/blackfin/mach-bf561/smp.c index 11789beca75a..8c0c80fd1a45 100644 --- a/arch/blackfin/mach-bf561/smp.c +++ b/arch/blackfin/mach-bf561/smp.c @@ -124,7 +124,7 @@ void platform_send_ipi(cpumask_t callmap, int irq) unsigned int cpu; int offset = (irq == IRQ_SUPPLE_0) ? 6 : 8; - for_each_cpu_mask(cpu, callmap) { + for_each_cpu(cpu, &callmap) { BUG_ON(cpu >= 2); SSYNC(); bfin_write_SICB_SYSCR(bfin_read_SICB_SYSCR() | (1 << (offset + cpu))); -- GitLab From dc0d838a0527296730af6d3826bcda79d2918613 Mon Sep 17 00:00:00 2001 From: Oleg Drokin Date: Wed, 4 Mar 2015 01:07:51 -0500 Subject: [PATCH 02757/11651] staging/lustre/ptlrpc: Do not use deprecated cpus_* functions As per Rusty Russel, cpus_* functions are deprecated. When mixing cpumask_copy with cpus_weight, they operate on different sized masks if CPUMASK_OFFSTACK is enabled, causing an immediate assertion failure. Copying of cpumasks by assignment is also not allowed now. Additionally, in ptlrpc/service.c avoid the cpumask copies, since we only use it to check how many siblings are there for core #0 and nothing else. Reported-by: Tyson Whitehead Signed-off-by: Oleg Drokin Signed-off-by: Rusty Russell --- drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c | 8 ++++---- drivers/staging/lustre/lustre/ptlrpc/service.c | 9 +++------ 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c index 4621b71fe0b6..7f13a2845e9f 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c +++ b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c @@ -511,10 +511,10 @@ static int ptlrpcd_bind(int index, int max) #if defined(CONFIG_NUMA) { int i; - mask = *cpumask_of_node(cpu_to_node(index)); + cpumask_copy(&mask, cpumask_of_node(cpu_to_node(index))); for (i = max; i < num_online_cpus(); i++) - cpu_clear(i, mask); - pc->pc_npartners = cpus_weight(mask) - 1; + cpumask_clear_cpu(i, &mask); + pc->pc_npartners = cpumask_weight(&mask) - 1; set_bit(LIOD_BIND, &pc->pc_flags); } #else @@ -554,7 +554,7 @@ static int ptlrpcd_bind(int index, int max) * that are already initialized */ for (pidx = 0, i = 0; i < index; i++) { - if (cpu_isset(i, mask)) { + if (cpumask_test_cpu(i, &mask)) { ppc = &ptlrpcds->pd_threads[i]; pc->pc_partners[pidx++] = ppc; ppc->pc_partners[ppc-> diff --git a/drivers/staging/lustre/lustre/ptlrpc/service.c b/drivers/staging/lustre/lustre/ptlrpc/service.c index 635b12b22cef..8e61421515cb 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/service.c +++ b/drivers/staging/lustre/lustre/ptlrpc/service.c @@ -543,7 +543,6 @@ ptlrpc_server_nthreads_check(struct ptlrpc_service *svc, if (tc->tc_thr_factor != 0) { int factor = tc->tc_thr_factor; const int fade = 4; - cpumask_t mask; /* * User wants to increase number of threads with for @@ -557,8 +556,8 @@ ptlrpc_server_nthreads_check(struct ptlrpc_service *svc, * have too many threads no matter how many cores/HTs * there are. */ - cpumask_copy(&mask, topology_thread_cpumask(0)); - if (cpus_weight(mask) > 1) { /* weight is # of HTs */ + /* weight is # of HTs */ + if (cpumask_weight(topology_thread_cpumask(0)) > 1) { /* depress thread factor for hyper-thread */ factor = factor - (factor >> 1) + (factor >> 3); } @@ -2752,7 +2751,6 @@ int ptlrpc_start_thread(struct ptlrpc_service_part *svcpt, int wait) int ptlrpc_hr_init(void) { - cpumask_t mask; struct ptlrpc_hr_partition *hrp; struct ptlrpc_hr_thread *hrt; int rc; @@ -2770,8 +2768,7 @@ int ptlrpc_hr_init(void) init_waitqueue_head(&ptlrpc_hr.hr_waitq); - cpumask_copy(&mask, topology_thread_cpumask(0)); - weight = cpus_weight(mask); + weight = cpumask_weight(topology_thread_cpumask(0)); cfs_percpt_for_each(hrp, i, ptlrpc_hr.hr_partitions) { hrp->hrp_cpt = i; -- GitLab From b25e74b56a34908c777c1e72ecd9c56c4c8e124d Mon Sep 17 00:00:00 2001 From: Oleg Drokin Date: Wed, 4 Mar 2015 01:07:52 -0500 Subject: [PATCH 02758/11651] staging/lustre/libcfs: replace deprecated cpus_ calls with cpumask_ Rusty Russel advises that cpus_* functions are deprecated to work on cpumasks and cpumask_* functions should be called instead, otherwise problems with CPUMASK_OFFSTACK arise. Signed-off-by: Oleg Drokin Signed-off-by: Rusty Russell --- .../lustre/lustre/libcfs/linux/linux-cpu.c | 102 +++++++++--------- 1 file changed, 53 insertions(+), 49 deletions(-) diff --git a/drivers/staging/lustre/lustre/libcfs/linux/linux-cpu.c b/drivers/staging/lustre/lustre/libcfs/linux/linux-cpu.c index 05f7595f18aa..cc3ab351943e 100644 --- a/drivers/staging/lustre/lustre/libcfs/linux/linux-cpu.c +++ b/drivers/staging/lustre/lustre/libcfs/linux/linux-cpu.c @@ -204,7 +204,7 @@ cfs_cpt_table_print(struct cfs_cpt_table *cptab, char *buf, int len) } tmp += rc; - for_each_cpu_mask(j, *cptab->ctb_parts[i].cpt_cpumask) { + for_each_cpu(j, cptab->ctb_parts[i].cpt_cpumask) { rc = snprintf(tmp, len, "%d ", j); len -= rc; if (len <= 0) { @@ -240,8 +240,8 @@ cfs_cpt_weight(struct cfs_cpt_table *cptab, int cpt) LASSERT(cpt == CFS_CPT_ANY || (cpt >= 0 && cpt < cptab->ctb_nparts)); return cpt == CFS_CPT_ANY ? - cpus_weight(*cptab->ctb_cpumask) : - cpus_weight(*cptab->ctb_parts[cpt].cpt_cpumask); + cpumask_weight(cptab->ctb_cpumask) : + cpumask_weight(cptab->ctb_parts[cpt].cpt_cpumask); } EXPORT_SYMBOL(cfs_cpt_weight); @@ -251,8 +251,10 @@ cfs_cpt_online(struct cfs_cpt_table *cptab, int cpt) LASSERT(cpt == CFS_CPT_ANY || (cpt >= 0 && cpt < cptab->ctb_nparts)); return cpt == CFS_CPT_ANY ? - any_online_cpu(*cptab->ctb_cpumask) != NR_CPUS : - any_online_cpu(*cptab->ctb_parts[cpt].cpt_cpumask) != NR_CPUS; + cpumask_any_and(cptab->ctb_cpumask, + cpu_online_mask) < nr_cpu_ids : + cpumask_any_and(cptab->ctb_parts[cpt].cpt_cpumask, + cpu_online_mask) < nr_cpu_ids; } EXPORT_SYMBOL(cfs_cpt_online); @@ -283,7 +285,7 @@ cfs_cpt_set_cpu(struct cfs_cpt_table *cptab, int cpt, int cpu) LASSERT(cpt >= 0 && cpt < cptab->ctb_nparts); - if (cpu < 0 || cpu >= NR_CPUS || !cpu_online(cpu)) { + if (cpu < 0 || cpu >= nr_cpu_ids || !cpu_online(cpu)) { CDEBUG(D_INFO, "CPU %d is invalid or it's offline\n", cpu); return 0; } @@ -296,11 +298,11 @@ cfs_cpt_set_cpu(struct cfs_cpt_table *cptab, int cpt, int cpu) cptab->ctb_cpu2cpt[cpu] = cpt; - LASSERT(!cpu_isset(cpu, *cptab->ctb_cpumask)); - LASSERT(!cpu_isset(cpu, *cptab->ctb_parts[cpt].cpt_cpumask)); + LASSERT(!cpumask_test_cpu(cpu, cptab->ctb_cpumask)); + LASSERT(!cpumask_test_cpu(cpu, cptab->ctb_parts[cpt].cpt_cpumask)); - cpu_set(cpu, *cptab->ctb_cpumask); - cpu_set(cpu, *cptab->ctb_parts[cpt].cpt_cpumask); + cpumask_set_cpu(cpu, cptab->ctb_cpumask); + cpumask_set_cpu(cpu, cptab->ctb_parts[cpt].cpt_cpumask); node = cpu_to_node(cpu); @@ -324,7 +326,7 @@ cfs_cpt_unset_cpu(struct cfs_cpt_table *cptab, int cpt, int cpu) LASSERT(cpt == CFS_CPT_ANY || (cpt >= 0 && cpt < cptab->ctb_nparts)); - if (cpu < 0 || cpu >= NR_CPUS) { + if (cpu < 0 || cpu >= nr_cpu_ids) { CDEBUG(D_INFO, "Invalid CPU id %d\n", cpu); return; } @@ -344,11 +346,11 @@ cfs_cpt_unset_cpu(struct cfs_cpt_table *cptab, int cpt, int cpu) return; } - LASSERT(cpu_isset(cpu, *cptab->ctb_parts[cpt].cpt_cpumask)); - LASSERT(cpu_isset(cpu, *cptab->ctb_cpumask)); + LASSERT(cpumask_test_cpu(cpu, cptab->ctb_parts[cpt].cpt_cpumask)); + LASSERT(cpumask_test_cpu(cpu, cptab->ctb_cpumask)); - cpu_clear(cpu, *cptab->ctb_parts[cpt].cpt_cpumask); - cpu_clear(cpu, *cptab->ctb_cpumask); + cpumask_clear_cpu(cpu, cptab->ctb_parts[cpt].cpt_cpumask); + cpumask_clear_cpu(cpu, cptab->ctb_cpumask); cptab->ctb_cpu2cpt[cpu] = -1; node = cpu_to_node(cpu); @@ -356,22 +358,22 @@ cfs_cpt_unset_cpu(struct cfs_cpt_table *cptab, int cpt, int cpu) LASSERT(node_isset(node, *cptab->ctb_parts[cpt].cpt_nodemask)); LASSERT(node_isset(node, *cptab->ctb_nodemask)); - for_each_cpu_mask(i, *cptab->ctb_parts[cpt].cpt_cpumask) { + for_each_cpu(i, cptab->ctb_parts[cpt].cpt_cpumask) { /* this CPT has other CPU belonging to this node? */ if (cpu_to_node(i) == node) break; } - if (i == NR_CPUS) + if (i >= nr_cpu_ids) node_clear(node, *cptab->ctb_parts[cpt].cpt_nodemask); - for_each_cpu_mask(i, *cptab->ctb_cpumask) { + for_each_cpu(i, cptab->ctb_cpumask) { /* this CPT-table has other CPU belonging to this node? */ if (cpu_to_node(i) == node) break; } - if (i == NR_CPUS) + if (i >= nr_cpu_ids) node_clear(node, *cptab->ctb_nodemask); return; @@ -383,13 +385,14 @@ cfs_cpt_set_cpumask(struct cfs_cpt_table *cptab, int cpt, cpumask_t *mask) { int i; - if (cpus_weight(*mask) == 0 || any_online_cpu(*mask) == NR_CPUS) { + if (cpumask_weight(mask) == 0 || + cpumask_any_and(mask, cpu_online_mask) >= nr_cpu_ids) { CDEBUG(D_INFO, "No online CPU is found in the CPU mask for CPU partition %d\n", cpt); return 0; } - for_each_cpu_mask(i, *mask) { + for_each_cpu(i, mask) { if (!cfs_cpt_set_cpu(cptab, cpt, i)) return 0; } @@ -403,7 +406,7 @@ cfs_cpt_unset_cpumask(struct cfs_cpt_table *cptab, int cpt, cpumask_t *mask) { int i; - for_each_cpu_mask(i, *mask) + for_each_cpu(i, mask) cfs_cpt_unset_cpu(cptab, cpt, i); } EXPORT_SYMBOL(cfs_cpt_unset_cpumask); @@ -493,7 +496,7 @@ cfs_cpt_clear(struct cfs_cpt_table *cptab, int cpt) } for (; cpt <= last; cpt++) { - for_each_cpu_mask(i, *cptab->ctb_parts[cpt].cpt_cpumask) + for_each_cpu(i, cptab->ctb_parts[cpt].cpt_cpumask) cfs_cpt_unset_cpu(cptab, cpt, i); } } @@ -554,7 +557,7 @@ EXPORT_SYMBOL(cfs_cpt_current); int cfs_cpt_of_cpu(struct cfs_cpt_table *cptab, int cpu) { - LASSERT(cpu >= 0 && cpu < NR_CPUS); + LASSERT(cpu >= 0 && cpu < nr_cpu_ids); return cptab->ctb_cpu2cpt[cpu]; } @@ -578,14 +581,14 @@ cfs_cpt_bind(struct cfs_cpt_table *cptab, int cpt) nodemask = cptab->ctb_parts[cpt].cpt_nodemask; } - if (any_online_cpu(*cpumask) == NR_CPUS) { + if (cpumask_any_and(cpumask, cpu_online_mask) >= nr_cpu_ids) { CERROR("No online CPU found in CPU partition %d, did someone do CPU hotplug on system? You might need to reload Lustre modules to keep system working well.\n", cpt); return -EINVAL; } for_each_online_cpu(i) { - if (cpu_isset(i, *cpumask)) + if (cpumask_test_cpu(i, cpumask)) continue; rc = set_cpus_allowed_ptr(current, cpumask); @@ -616,14 +619,14 @@ cfs_cpt_choose_ncpus(struct cfs_cpt_table *cptab, int cpt, LASSERT(number > 0); - if (number >= cpus_weight(*node)) { - while (!cpus_empty(*node)) { - cpu = first_cpu(*node); + if (number >= cpumask_weight(node)) { + while (!cpumask_empty(node)) { + cpu = cpumask_first(node); rc = cfs_cpt_set_cpu(cptab, cpt, cpu); if (!rc) return -EINVAL; - cpu_clear(cpu, *node); + cpumask_clear_cpu(cpu, node); } return 0; } @@ -636,27 +639,27 @@ cfs_cpt_choose_ncpus(struct cfs_cpt_table *cptab, int cpt, goto out; } - while (!cpus_empty(*node)) { - cpu = first_cpu(*node); + while (!cpumask_empty(node)) { + cpu = cpumask_first(node); /* get cpumask for cores in the same socket */ cfs_cpu_core_siblings(cpu, socket); - cpus_and(*socket, *socket, *node); + cpumask_and(socket, socket, node); - LASSERT(!cpus_empty(*socket)); + LASSERT(!cpumask_empty(socket)); - while (!cpus_empty(*socket)) { + while (!cpumask_empty(socket)) { int i; /* get cpumask for hts in the same core */ cfs_cpu_ht_siblings(cpu, core); - cpus_and(*core, *core, *node); + cpumask_and(core, core, node); - LASSERT(!cpus_empty(*core)); + LASSERT(!cpumask_empty(core)); - for_each_cpu_mask(i, *core) { - cpu_clear(i, *socket); - cpu_clear(i, *node); + for_each_cpu(i, core) { + cpumask_clear_cpu(i, socket); + cpumask_clear_cpu(i, node); rc = cfs_cpt_set_cpu(cptab, cpt, i); if (!rc) { @@ -667,7 +670,7 @@ cfs_cpt_choose_ncpus(struct cfs_cpt_table *cptab, int cpt, if (--number == 0) goto out; } - cpu = first_cpu(*socket); + cpu = cpumask_first(socket); } } @@ -767,7 +770,7 @@ cfs_cpt_table_create(int ncpt) for_each_online_node(i) { cfs_node_to_cpumask(i, mask); - while (!cpus_empty(*mask)) { + while (!cpumask_empty(mask)) { struct cfs_cpu_partition *part; int n; @@ -776,24 +779,24 @@ cfs_cpt_table_create(int ncpt) part = &cptab->ctb_parts[cpt]; - n = num - cpus_weight(*part->cpt_cpumask); + n = num - cpumask_weight(part->cpt_cpumask); LASSERT(n > 0); rc = cfs_cpt_choose_ncpus(cptab, cpt, mask, n); if (rc < 0) goto failed; - LASSERT(num >= cpus_weight(*part->cpt_cpumask)); - if (num == cpus_weight(*part->cpt_cpumask)) + LASSERT(num >= cpumask_weight(part->cpt_cpumask)); + if (num == cpumask_weight(part->cpt_cpumask)) cpt++; } } if (cpt != ncpt || - num != cpus_weight(*cptab->ctb_parts[ncpt - 1].cpt_cpumask)) { + num != cpumask_weight(cptab->ctb_parts[ncpt - 1].cpt_cpumask)) { CERROR("Expect %d(%d) CPU partitions but got %d(%d), CPU hotplug/unplug while setting?\n", cptab->ctb_nparts, num, cpt, - cpus_weight(*cptab->ctb_parts[ncpt - 1].cpt_cpumask)); + cpumask_weight(cptab->ctb_parts[ncpt - 1].cpt_cpumask)); goto failed; } @@ -845,7 +848,7 @@ cfs_cpt_table_create_pattern(char *pattern) return NULL; } - high = node ? MAX_NUMNODES - 1 : NR_CPUS - 1; + high = node ? MAX_NUMNODES - 1 : nr_cpu_ids - 1; cptab = cfs_cpt_table_alloc(ncpt); if (cptab == NULL) { @@ -965,7 +968,8 @@ cfs_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu) mutex_lock(&cpt_data.cpt_mutex); /* if all HTs in a core are offline, it may break affinity */ cfs_cpu_ht_siblings(cpu, cpt_data.cpt_cpumask); - warn = any_online_cpu(*cpt_data.cpt_cpumask) >= nr_cpu_ids; + warn = cpumask_any_and(cpt_data.cpt_cpumask, + cpu_online_mask) >= nr_cpu_ids; mutex_unlock(&cpt_data.cpt_mutex); CDEBUG(warn ? D_WARNING : D_INFO, "Lustre: can't support CPU plug-out well now, performance and stability could be impacted [CPU %u action: %lx]\n", -- GitLab From e97636b487d0767500a1b898513577a5ce000ad9 Mon Sep 17 00:00:00 2001 From: Oleg Drokin Date: Wed, 4 Mar 2015 01:07:53 -0500 Subject: [PATCH 02759/11651] staging/lustre/o2iblnd: Don't use cpus_weight cpus_weight and for_each_cpu_mask are deprecated, so replace them with cpumask_weight and for_each_cpu respectively. Signed-off-by: Oleg Drokin Signed-off-by: Rusty Russell --- drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c index 651016919669..a25816ab9e53 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c @@ -638,8 +638,8 @@ kiblnd_get_completion_vector(kib_conn_t *conn, int cpt) return 0; /* hash NID to CPU id in this partition... */ - off = do_div(nid, cpus_weight(*mask)); - for_each_cpu_mask(i, *mask) { + off = do_div(nid, cpumask_weight(mask)); + for_each_cpu(i, mask) { if (off-- == 0) return i % vectors; } -- GitLab From 9941a383df98193aa9a9b3662af7c1fcbc3070ee Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 5 Mar 2015 10:49:19 +1030 Subject: [PATCH 02760/11651] CPU_MASK_ALL/CPU_MASK_NONE: remove from deprecated region. They're used to initialize various static fields, though static cpumasks should generally be avoided. Signed-off-by: Rusty Russell --- include/linux/cpumask.h | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h index 086549a665e2..dc037ae6f4f2 100644 --- a/include/linux/cpumask.h +++ b/include/linux/cpumask.h @@ -768,7 +768,7 @@ static inline const struct cpumask *get_cpu_mask(unsigned int cpu) #if NR_CPUS <= BITS_PER_LONG #define CPU_BITS_ALL \ { \ - [BITS_TO_LONGS(NR_CPUS)-1] = CPU_MASK_LAST_WORD \ + [BITS_TO_LONGS(NR_CPUS)-1] = BITMAP_LAST_WORD_MASK(NR_CPUS) \ } #else /* NR_CPUS > BITS_PER_LONG */ @@ -776,7 +776,7 @@ static inline const struct cpumask *get_cpu_mask(unsigned int cpu) #define CPU_BITS_ALL \ { \ [0 ... BITS_TO_LONGS(NR_CPUS)-2] = ~0UL, \ - [BITS_TO_LONGS(NR_CPUS)-1] = CPU_MASK_LAST_WORD \ + [BITS_TO_LONGS(NR_CPUS)-1] = BITMAP_LAST_WORD_MASK(NR_CPUS) \ } #endif /* NR_CPUS > BITS_PER_LONG */ @@ -797,38 +797,31 @@ cpumap_print_to_pagebuf(bool list, char *buf, const struct cpumask *mask) nr_cpu_ids); } -/* - * - * From here down, all obsolete. Use cpumask_ variants! - * - */ -#ifndef CONFIG_DISABLE_OBSOLETE_CPUMASK_FUNCTIONS -#define cpumask_of_cpu(cpu) (*get_cpu_mask(cpu)) - -#define CPU_MASK_LAST_WORD BITMAP_LAST_WORD_MASK(NR_CPUS) - #if NR_CPUS <= BITS_PER_LONG - #define CPU_MASK_ALL \ (cpumask_t) { { \ - [BITS_TO_LONGS(NR_CPUS)-1] = CPU_MASK_LAST_WORD \ + [BITS_TO_LONGS(NR_CPUS)-1] = BITMAP_LAST_WORD_MASK(NR_CPUS) \ } } - #else - #define CPU_MASK_ALL \ (cpumask_t) { { \ [0 ... BITS_TO_LONGS(NR_CPUS)-2] = ~0UL, \ - [BITS_TO_LONGS(NR_CPUS)-1] = CPU_MASK_LAST_WORD \ + [BITS_TO_LONGS(NR_CPUS)-1] = BITMAP_LAST_WORD_MASK(NR_CPUS) \ } } - -#endif +#endif /* NR_CPUS > BITS_PER_LONG */ #define CPU_MASK_NONE \ (cpumask_t) { { \ [0 ... BITS_TO_LONGS(NR_CPUS)-1] = 0UL \ } } +/* + * + * From here down, all obsolete. Use cpumask_ variants! + * + */ +#ifndef CONFIG_DISABLE_OBSOLETE_CPUMASK_FUNCTIONS + #define CPU_MASK_CPU0 \ (cpumask_t) { { \ [0] = 1UL \ -- GitLab From d5bce867778c8cb5ff655efe47fecb4b31f30406 Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Mon, 2 Mar 2015 13:12:07 -0800 Subject: [PATCH 02761/11651] Thermal/int340x: Fix memleak for aux trip When thermal zone device register fails or on module exit, the memory for aux_trip is not freed. This change fixes this issue. Signed-off-by: Srinivas Pandruvada Signed-off-by: Eduardo Valentin --- drivers/thermal/int340x_thermal/int340x_thermal_zone.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/thermal/int340x_thermal/int340x_thermal_zone.c b/drivers/thermal/int340x_thermal/int340x_thermal_zone.c index f88b08877025..1e25133d35e2 100644 --- a/drivers/thermal/int340x_thermal/int340x_thermal_zone.c +++ b/drivers/thermal/int340x_thermal/int340x_thermal_zone.c @@ -208,7 +208,7 @@ struct int34x_thermal_zone *int340x_thermal_zone_add(struct acpi_device *adev, trip_cnt, GFP_KERNEL); if (!int34x_thermal_zone->aux_trips) { ret = -ENOMEM; - goto free_mem; + goto err_trip_alloc; } trip_mask = BIT(trip_cnt) - 1; int34x_thermal_zone->aux_trip_nr = trip_cnt; @@ -248,14 +248,15 @@ struct int34x_thermal_zone *int340x_thermal_zone_add(struct acpi_device *adev, 0, 0); if (IS_ERR(int34x_thermal_zone->zone)) { ret = PTR_ERR(int34x_thermal_zone->zone); - goto free_lpat; + goto err_thermal_zone; } return int34x_thermal_zone; -free_lpat: +err_thermal_zone: acpi_lpat_free_conversion_table(int34x_thermal_zone->lpat_table); -free_mem: + kfree(int34x_thermal_zone->aux_trips); +err_trip_alloc: kfree(int34x_thermal_zone); return ERR_PTR(ret); } @@ -266,6 +267,7 @@ void int340x_thermal_zone_remove(struct int34x_thermal_zone { thermal_zone_device_unregister(int34x_thermal_zone->zone); acpi_lpat_free_conversion_table(int34x_thermal_zone->lpat_table); + kfree(int34x_thermal_zone->aux_trips); kfree(int34x_thermal_zone); } EXPORT_SYMBOL_GPL(int340x_thermal_zone_remove); -- GitLab From 2dc10f8963e6a03a1a75deafe1d1984bafab08dd Mon Sep 17 00:00:00 2001 From: Matthias Kaehlcke Date: Fri, 20 Feb 2015 18:10:08 -0800 Subject: [PATCH 02762/11651] thermal: Make sysfs attributes of cooling devices default attributes Default attributes are created when the device is registered. Attributes created after device registration can lead to race conditions, where user space (e.g. udev) sees the device but not the attributes. Signed-off-by: Matthias Kaehlcke Signed-off-by: Eduardo Valentin --- drivers/thermal/thermal_core.c | 37 ++++++++++++++++------------------ 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index 48491d1a81d6..174d3bcf8bd7 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -899,6 +899,22 @@ thermal_cooling_device_trip_point_show(struct device *dev, return sprintf(buf, "%d\n", instance->trip); } +static struct attribute *cooling_device_attrs[] = { + &dev_attr_cdev_type.attr, + &dev_attr_max_state.attr, + &dev_attr_cur_state.attr, + NULL, +}; + +static const struct attribute_group cooling_device_attr_group = { + .attrs = cooling_device_attrs, +}; + +static const struct attribute_group *cooling_device_attr_groups[] = { + &cooling_device_attr_group, + NULL, +}; + /* Device management */ /** @@ -1130,6 +1146,7 @@ __thermal_cooling_device_register(struct device_node *np, cdev->ops = ops; cdev->updated = false; cdev->device.class = &thermal_class; + cdev->device.groups = cooling_device_attr_groups; cdev->devdata = devdata; dev_set_name(&cdev->device, "cooling_device%d", cdev->id); result = device_register(&cdev->device); @@ -1139,21 +1156,6 @@ __thermal_cooling_device_register(struct device_node *np, return ERR_PTR(result); } - /* sys I/F */ - if (type) { - result = device_create_file(&cdev->device, &dev_attr_cdev_type); - if (result) - goto unregister; - } - - result = device_create_file(&cdev->device, &dev_attr_max_state); - if (result) - goto unregister; - - result = device_create_file(&cdev->device, &dev_attr_cur_state); - if (result) - goto unregister; - /* Add 'this' new cdev to the global cdev list */ mutex_lock(&thermal_list_lock); list_add(&cdev->node, &thermal_cdev_list); @@ -1163,11 +1165,6 @@ __thermal_cooling_device_register(struct device_node *np, bind_cdev(cdev); return cdev; - -unregister: - release_idr(&thermal_cdev_idr, &thermal_idr_lock, cdev->id); - device_unregister(&cdev->device); - return ERR_PTR(result); } /** -- GitLab From d9fd579c218e22c897f0f1b9e132af9b436cf445 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Wed, 4 Mar 2015 17:24:11 -0800 Subject: [PATCH 02763/11651] x86/mm: Use IS_ENABLED() for direct_gbpages Replace #ifdef eyesore with IS_ENABLED() use. Signed-off-by: Luis R. Rodriguez Cc: Andrew Morton Cc: Andy Lutomirski Cc: Borislav Petkov Cc: Borislav Petkov Cc: Dave Hansen Cc: David Vrabel Cc: Dexuan Cui Cc: Greg Kroah-Hartman Cc: H. Peter Anvin Cc: JBeulich@suse.com Cc: Jan Beulich Cc: Joonsoo Kim Cc: Juergen Gross Cc: Linus Torvalds Cc: Pavel Machek Cc: Thomas Gleixner Cc: Tony Lindgren Cc: Toshi Kani Cc: Vlastimil Babka Cc: Xishi Qiu Cc: julia.lawall@lip6.fr Link: http://lkml.kernel.org/r/1425518654-3403-2-git-send-email-mcgrof@do-not-panic.com Signed-off-by: Ingo Molnar --- arch/x86/mm/init.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c index a110efca6d06..74f2b37fd073 100644 --- a/arch/x86/mm/init.c +++ b/arch/x86/mm/init.c @@ -131,11 +131,7 @@ void __init early_alloc_pgt_buf(void) int after_bootmem; -int direct_gbpages -#ifdef CONFIG_DIRECT_GBPAGES - = 1 -#endif -; +int direct_gbpages = IS_ENABLED(CONFIG_DIRECT_GBPAGES); static void __init init_gbpages(void) { -- GitLab From e5008abe929c160d36e44b8c2b644d4330d2e389 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Wed, 4 Mar 2015 17:24:12 -0800 Subject: [PATCH 02764/11651] x86/mm: Simplify enabling direct_gbpages direct_gbpages can be force enabled as an early parameter but not really have taken effect when DEBUG_PAGEALLOC or KMEMCHECK is enabled. You can also enable direct_gbpages right now if you have an x86_64 architecture but your CPU doesn't really have support for this feature. In both cases PG_LEVEL_1G won't actually be enabled but direct_gbpages is used in other areas under the assumptions that PG_LEVEL_1G was set. Fix this by putting together all requirements which make this feature sensible to enable under, and only enable both finally flipping on PG_LEVEL_1G and leaving PG_LEVEL_1G set when this is true. We only enable this feature then to be possible on sensible builds defined by the new ENABLE_DIRECT_GBPAGES. If the CPU has support for it you can either enable this by using the DIRECT_GBPAGES option or using the early kernel parameter. If a platform had support for this you can always force disable it as well. Signed-off-by: Luis R. Rodriguez Cc: Andrew Morton Cc: Andy Lutomirski Cc: Borislav Petkov Cc: Borislav Petkov Cc: Dave Hansen Cc: David Vrabel Cc: Dexuan Cui Cc: Greg Kroah-Hartman Cc: H. Peter Anvin Cc: JBeulich@suse.com Cc: Jan Beulich Cc: Joonsoo Kim Cc: Juergen Gross Cc: Linus Torvalds Cc: Pavel Machek Cc: Thomas Gleixner Cc: Tony Lindgren Cc: Toshi Kani Cc: Vlastimil Babka Cc: Xishi Qiu Cc: julia.lawall@lip6.fr Link: http://lkml.kernel.org/r/1425518654-3403-3-git-send-email-mcgrof@do-not-panic.com Signed-off-by: Ingo Molnar --- arch/x86/Kconfig | 18 +++++++++++++----- arch/x86/mm/init.c | 17 +++++++++-------- arch/x86/mm/pageattr.c | 2 -- 3 files changed, 22 insertions(+), 15 deletions(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index c2fb8a87dccb..4d06e1c8294a 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -1299,14 +1299,22 @@ config ARCH_DMA_ADDR_T_64BIT def_bool y depends on X86_64 || HIGHMEM64G +config ENABLE_DIRECT_GBPAGES + def_bool y + depends on X86_64 && !DEBUG_PAGEALLOC && !KMEMCHECK + config DIRECT_GBPAGES bool "Enable 1GB pages for kernel pagetables" if EXPERT default y - depends on X86_64 - ---help--- - Allow the kernel linear mapping to use 1GB pages on CPUs that - support it. This can improve the kernel's performance a tiny bit by - reducing TLB pressure. If in doubt, say "Y". + depends on ENABLE_DIRECT_GBPAGES + ---help--- + Enable by default the kernel linear mapping to use 1GB pages on CPUs + that support it. This can improve the kernel's performance a tiny bit + by reducing TLB pressure. If in doubt, say "Y". If you've disabled + option but your platform is capable of handling support for this + you can use the gbpages kernel parameter. Likewise if you've enabled + this but you'd like to force disable this option you can use the + nogbpages kernel parameter. # Common NUMA Features config NUMA diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c index 74f2b37fd073..2ce2c8e8c99c 100644 --- a/arch/x86/mm/init.c +++ b/arch/x86/mm/init.c @@ -131,16 +131,21 @@ void __init early_alloc_pgt_buf(void) int after_bootmem; +static int page_size_mask; + int direct_gbpages = IS_ENABLED(CONFIG_DIRECT_GBPAGES); static void __init init_gbpages(void) { -#ifdef CONFIG_X86_64 - if (direct_gbpages && cpu_has_gbpages) + if (!IS_ENABLED(CONFIG_ENABLE_DIRECT_GBPAGES)) { + direct_gbpages = 0; + return; + } + if (direct_gbpages && cpu_has_gbpages) { printk(KERN_INFO "Using GB pages for direct mapping\n"); - else + page_size_mask |= 1 << PG_LEVEL_1G; + } else direct_gbpages = 0; -#endif } struct map_range { @@ -149,8 +154,6 @@ struct map_range { unsigned page_size_mask; }; -static int page_size_mask; - static void __init probe_page_size_mask(void) { init_gbpages(); @@ -161,8 +164,6 @@ static void __init probe_page_size_mask(void) * This will simplify cpa(), which otherwise needs to support splitting * large pages into small in interrupt context, etc. */ - if (direct_gbpages) - page_size_mask |= 1 << PG_LEVEL_1G; if (cpu_has_pse) page_size_mask |= 1 << PG_LEVEL_2M; #endif diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index 81e8282d8c2f..89af288ec674 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c @@ -81,11 +81,9 @@ void arch_report_meminfo(struct seq_file *m) seq_printf(m, "DirectMap4M: %8lu kB\n", direct_pages_count[PG_LEVEL_2M] << 12); #endif -#ifdef CONFIG_X86_64 if (direct_gbpages) seq_printf(m, "DirectMap1G: %8lu kB\n", direct_pages_count[PG_LEVEL_1G] << 20); -#endif } #else static inline void split_page_count(int level) { } -- GitLab From bfb33bad83f650f265ed65cbfe8352b7c3ce8c76 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Wed, 4 Mar 2015 17:24:13 -0800 Subject: [PATCH 02765/11651] init.h: Add early_param_on_off() At times all you need is a kconfig variable to enable a feature, by default but you may want to also enable / disable it through a kernel parameter. In such cases the parameter routines to turn the thing on / off are really simple. Just use a wrapper for this, it lets us generalize the code and makes it easier to associate parameters with related kernel configuration options. Signed-off-by: Luis R. Rodriguez Cc: Andrew Morton Cc: Andy Lutomirski Cc: Borislav Petkov Cc: Borislav Petkov Cc: Dave Hansen Cc: David Vrabel Cc: Dexuan Cui Cc: Greg Kroah-Hartman Cc: H. Peter Anvin Cc: JBeulich@suse.com Cc: Jan Beulich Cc: Joonsoo Kim Cc: Juergen Gross Cc: Linus Torvalds Cc: Pavel Machek Cc: Thomas Gleixner Cc: Tony Lindgren Cc: Toshi Kani Cc: Vlastimil Babka Cc: Xishi Qiu Cc: julia.lawall@lip6.fr Link: http://lkml.kernel.org/r/1425518654-3403-4-git-send-email-mcgrof@do-not-panic.com Signed-off-by: Ingo Molnar --- include/linux/init.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/include/linux/init.h b/include/linux/init.h index 2df8e8dd10a4..bc11ff96f336 100644 --- a/include/linux/init.h +++ b/include/linux/init.h @@ -268,6 +268,21 @@ struct obs_kernel_param { #define early_param(str, fn) \ __setup_param(str, fn, fn, 1) +#define early_param_on_off(str_on, str_off, var, config) \ + int var = IS_ENABLED(config); \ + static int __init parse_##var##_on(char *arg) \ + { \ + var = 1; \ + return 0; \ + } \ + static int __init parse_##var##_off(char *arg) \ + { \ + var = 0; \ + return 0; \ + } \ + __setup_param(str_on, parse_##var##_on, parse_##var##_on, 1); \ + __setup_param(str_off, parse_##var##_off, parse_##var##_off, 1) + /* Relies on boot_command_line being set */ void __init parse_early_param(void); void __init parse_early_options(char *cmdline); -- GitLab From 73c8c861dc5bddf1b24c6aeffee2292c96cf8db2 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Wed, 4 Mar 2015 17:24:14 -0800 Subject: [PATCH 02766/11651] x86/mm: Use early_param_on_off() for direct_gbpages The enabler / disabler is pretty simple, just use the provided wrappers, this lets us easily relate the variable to the associated Kconfig entry. Signed-off-by: Luis R. Rodriguez Cc: Andrew Morton Cc: Andy Lutomirski Cc: Borislav Petkov Cc: Borislav Petkov Cc: Dave Hansen Cc: David Vrabel Cc: Dexuan Cui Cc: Greg Kroah-Hartman Cc: H. Peter Anvin Cc: JBeulich@suse.com Cc: Jan Beulich Cc: Joonsoo Kim Cc: Juergen Gross Cc: Linus Torvalds Cc: Pavel Machek Cc: Thomas Gleixner Cc: Tony Lindgren Cc: Toshi Kani Cc: Vlastimil Babka Cc: Xishi Qiu Cc: julia.lawall@lip6.fr Link: http://lkml.kernel.org/r/1425518654-3403-5-git-send-email-mcgrof@do-not-panic.com Signed-off-by: Ingo Molnar --- arch/x86/mm/init.c | 3 ++- arch/x86/mm/init_64.c | 14 -------------- 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c index 2ce2c8e8c99c..c35ba8bce7cb 100644 --- a/arch/x86/mm/init.c +++ b/arch/x86/mm/init.c @@ -133,7 +133,8 @@ int after_bootmem; static int page_size_mask; -int direct_gbpages = IS_ENABLED(CONFIG_DIRECT_GBPAGES); +early_param_on_off("gbpages", "nogbpages", + direct_gbpages, CONFIG_DIRECT_GBPAGES); static void __init init_gbpages(void) { diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 30eb05ae7061..3fba623e3ba5 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c @@ -130,20 +130,6 @@ int kernel_ident_mapping_init(struct x86_mapping_info *info, pgd_t *pgd_page, return 0; } -static int __init parse_direct_gbpages_off(char *arg) -{ - direct_gbpages = 0; - return 0; -} -early_param("nogbpages", parse_direct_gbpages_off); - -static int __init parse_direct_gbpages_on(char *arg) -{ - direct_gbpages = 1; - return 0; -} -early_param("gbpages", parse_direct_gbpages_on); - /* * NOTE: pagetable_init alloc all the fixmap pagetables contiguous on the * physical space so we can cache the place of the first one and move -- GitLab From 48f86b7f2673352d075e567a8f3425c548be8424 Mon Sep 17 00:00:00 2001 From: Jakub Pawlowski Date: Wed, 4 Mar 2015 16:24:24 -0800 Subject: [PATCH 02767/11651] Bluetooth: Move Service Discovery logic before refactoring This patch moves whole packet filering logic of service discovery into new function is_filter_match. It's done because logic inside mgmt_device_found is very complicated and needs some simplification. Also having whole logic in one place will allow to simplify it in the future. Signed-off-by: Jakub Pawlowski Signed-off-by: Johan Hedberg --- net/bluetooth/mgmt.c | 141 ++++++++++++++++++++++++------------------- 1 file changed, 79 insertions(+), 62 deletions(-) diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 1e4635a3374d..a41a5efa4391 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -7280,32 +7280,16 @@ static void restart_le_scan(struct hci_dev *hdev) DISCOV_LE_RESTART_DELAY); } -void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, - u8 addr_type, u8 *dev_class, s8 rssi, u32 flags, - u8 *eir, u16 eir_len, u8 *scan_rsp, u8 scan_rsp_len) +static bool is_filter_match(struct hci_dev *hdev, s8 rssi, u8 *eir, + u16 eir_len, u8 *scan_rsp, u8 scan_rsp_len) { - char buf[512]; - struct mgmt_ev_device_found *ev = (void *) buf; - size_t ev_size; bool match; - /* Don't send events for a non-kernel initiated discovery. With - * LE one exception is if we have pend_le_reports > 0 in which - * case we're doing passive scanning and want these events. - */ - if (!hci_discovery_active(hdev)) { - if (link_type == ACL_LINK) - return; - if (link_type == LE_LINK && list_empty(&hdev->pend_le_reports)) - return; - } - - /* When using service discovery with a RSSI threshold, then check - * if such a RSSI threshold is specified. If a RSSI threshold has - * been specified, and HCI_QUIRK_STRICT_DUPLICATE_FILTER is not set, - * then all results with a RSSI smaller than the RSSI threshold will be - * dropped. If the quirk is set, let it through for further processing, - * as we might need to restart the scan. + /* If a RSSI threshold has been specified, and + * HCI_QUIRK_STRICT_DUPLICATE_FILTER is not set, then all results with + * a RSSI smaller than the RSSI threshold will be dropped. If the quirk + * is set, let it through for further processing, as we might need to + * restart the scan. * * For BR/EDR devices (pre 1.2) providing no RSSI during inquiry, * the results are also dropped. @@ -7314,32 +7298,8 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, (rssi == HCI_RSSI_INVALID || (rssi < hdev->discovery.rssi && !test_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks)))) - return; - - /* Make sure that the buffer is big enough. The 5 extra bytes - * are for the potential CoD field. - */ - if (sizeof(*ev) + eir_len + scan_rsp_len + 5 > sizeof(buf)) - return; - - memset(buf, 0, sizeof(buf)); - - /* In case of device discovery with BR/EDR devices (pre 1.2), the - * RSSI value was reported as 0 when not available. This behavior - * is kept when using device discovery. This is required for full - * backwards compatibility with the API. - * - * However when using service discovery, the value 127 will be - * returned when the RSSI is not available. - */ - if (rssi == HCI_RSSI_INVALID && !hdev->discovery.report_invalid_rssi && - link_type == ACL_LINK) - rssi = 0; + return false; - bacpy(&ev->addr.bdaddr, bdaddr); - ev->addr.type = link_to_bdaddr(link_type, addr_type); - ev->rssi = rssi; - ev->flags = cpu_to_le32(flags); if (eir_len > 0) { /* When using service discovery and a list of UUID is @@ -7364,25 +7324,18 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, } if (!match && !scan_rsp_len) - return; - - /* Copy EIR or advertising data into event */ - memcpy(ev->eir, eir, eir_len); + return false; } else { /* When using service discovery and a list of UUID is * provided, results with empty EIR or advertising data * should be dropped since they do not match any UUID. */ if (hdev->discovery.uuid_count > 0 && !scan_rsp_len) - return; + return false; match = false; } - if (dev_class && !eir_has_data_type(ev->eir, eir_len, EIR_CLASS_OF_DEV)) - eir_len = eir_append_data(ev->eir, eir_len, EIR_CLASS_OF_DEV, - dev_class, 3); - if (scan_rsp_len > 0) { /* When using service discovery and a list of UUID is * provided, results with no matching UUID should be @@ -7393,7 +7346,7 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, if (!match && !eir_has_uuids(scan_rsp, scan_rsp_len, hdev->discovery.uuid_count, hdev->discovery.uuids)) - return; + return false; /* If duplicate filtering does not report RSSI changes, * then restart scanning to ensure updated result with @@ -7403,16 +7356,13 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, &hdev->quirks)) restart_le_scan(hdev); } - - /* Append scan response data to event */ - memcpy(ev->eir + eir_len, scan_rsp, scan_rsp_len); } else { /* When using service discovery and a list of UUID is * provided, results with empty scan response and no * previous matched advertising data should be dropped. */ if (hdev->discovery.uuid_count > 0 && !match) - return; + return false; } /* Validate the reported RSSI value against the RSSI threshold once more @@ -7421,8 +7371,75 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, */ if (hdev->discovery.rssi != HCI_RSSI_INVALID && rssi < hdev->discovery.rssi) + return false; + + return true; +} + +void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, + u8 addr_type, u8 *dev_class, s8 rssi, u32 flags, + u8 *eir, u16 eir_len, u8 *scan_rsp, u8 scan_rsp_len) +{ + char buf[512]; + struct mgmt_ev_device_found *ev = (void *)buf; + size_t ev_size; + + /* Don't send events for a non-kernel initiated discovery. With + * LE one exception is if we have pend_le_reports > 0 in which + * case we're doing passive scanning and want these events. + */ + if (!hci_discovery_active(hdev)) { + if (link_type == ACL_LINK) + return; + if (link_type == LE_LINK && list_empty(&hdev->pend_le_reports)) + return; + } + + if (hdev->discovery.rssi != HCI_RSSI_INVALID || + hdev->discovery.uuid_count > 0) { + /* We are using service discovery */ + if (!is_filter_match(hdev, rssi, eir, eir_len, scan_rsp, + scan_rsp_len)) + return; + } + + /* Make sure that the buffer is big enough. The 5 extra bytes + * are for the potential CoD field. + */ + if (sizeof(*ev) + eir_len + scan_rsp_len + 5 > sizeof(buf)) return; + memset(buf, 0, sizeof(buf)); + + /* In case of device discovery with BR/EDR devices (pre 1.2), the + * RSSI value was reported as 0 when not available. This behavior + * is kept when using device discovery. This is required for full + * backwards compatibility with the API. + * + * However when using service discovery, the value 127 will be + * returned when the RSSI is not available. + */ + if (rssi == HCI_RSSI_INVALID && !hdev->discovery.report_invalid_rssi && + link_type == ACL_LINK) + rssi = 0; + + bacpy(&ev->addr.bdaddr, bdaddr); + ev->addr.type = link_to_bdaddr(link_type, addr_type); + ev->rssi = rssi; + ev->flags = cpu_to_le32(flags); + + if (eir_len > 0) + /* Copy EIR or advertising data into event */ + memcpy(ev->eir, eir, eir_len); + + if (dev_class && !eir_has_data_type(ev->eir, eir_len, EIR_CLASS_OF_DEV)) + eir_len = eir_append_data(ev->eir, eir_len, EIR_CLASS_OF_DEV, + dev_class, 3); + + if (scan_rsp_len > 0) + /* Append scan response data to event */ + memcpy(ev->eir + eir_len, scan_rsp, scan_rsp_len); + ev->eir_len = cpu_to_le16(eir_len + scan_rsp_len); ev_size = sizeof(*ev) + eir_len + scan_rsp_len; -- GitLab From 2976cdeb27c83c83bf010a314309f07659ead228 Mon Sep 17 00:00:00 2001 From: Jakub Pawlowski Date: Wed, 4 Mar 2015 16:24:25 -0800 Subject: [PATCH 02768/11651] Bluetooth: Refactor service discovery filter logic This patch refactor code responsible for filtering when service discovery method is used. Previously this code was mixed with mgmt_device found logic. Now when it's in one place whole logic can be greatly simplified. That includes removing no longer necessary length field and merging checks for eir and scan_rsp. Signed-off-by: Jakub Pawlowski Signed-off-by: Johan Hedberg --- net/bluetooth/mgmt.c | 89 ++++++++++---------------------------------- 1 file changed, 19 insertions(+), 70 deletions(-) diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index a41a5efa4391..bc09c5a37032 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -7283,8 +7283,6 @@ static void restart_le_scan(struct hci_dev *hdev) static bool is_filter_match(struct hci_dev *hdev, s8 rssi, u8 *eir, u16 eir_len, u8 *scan_rsp, u8 scan_rsp_len) { - bool match; - /* If a RSSI threshold has been specified, and * HCI_QUIRK_STRICT_DUPLICATE_FILTER is not set, then all results with * a RSSI smaller than the RSSI threshold will be dropped. If the quirk @@ -7300,78 +7298,29 @@ static bool is_filter_match(struct hci_dev *hdev, s8 rssi, u8 *eir, !test_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks)))) return false; - - if (eir_len > 0) { - /* When using service discovery and a list of UUID is - * provided, results with no matching UUID should be - * dropped. In case there is a match the result is - * kept and checking possible scan response data - * will be skipped. - */ - if (hdev->discovery.uuid_count > 0) { - match = eir_has_uuids(eir, eir_len, - hdev->discovery.uuid_count, - hdev->discovery.uuids); - /* If duplicate filtering does not report RSSI changes, - * then restart scanning to ensure updated result with - * updated RSSI values. - */ - if (match && test_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, - &hdev->quirks)) - restart_le_scan(hdev); - } else { - match = true; - } - - if (!match && !scan_rsp_len) - return false; - } else { - /* When using service discovery and a list of UUID is - * provided, results with empty EIR or advertising data - * should be dropped since they do not match any UUID. - */ - if (hdev->discovery.uuid_count > 0 && !scan_rsp_len) - return false; - - match = false; - } - - if (scan_rsp_len > 0) { - /* When using service discovery and a list of UUID is - * provided, results with no matching UUID should be - * dropped if there is no previous match from the - * advertising data. - */ - if (hdev->discovery.uuid_count > 0) { - if (!match && !eir_has_uuids(scan_rsp, scan_rsp_len, - hdev->discovery.uuid_count, - hdev->discovery.uuids)) - return false; - - /* If duplicate filtering does not report RSSI changes, - * then restart scanning to ensure updated result with - * updated RSSI values. - */ - if (test_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, - &hdev->quirks)) - restart_le_scan(hdev); - } - } else { - /* When using service discovery and a list of UUID is - * provided, results with empty scan response and no - * previous matched advertising data should be dropped. + if (hdev->discovery.uuid_count != 0) { + /* If a list of UUIDs is provided in filter, results with no + * matching UUID should be dropped. */ - if (hdev->discovery.uuid_count > 0 && !match) - return false; + if (!eir_has_uuids(eir, eir_len, hdev->discovery.uuid_count, + hdev->discovery.uuids) && + !eir_has_uuids(scan_rsp, scan_rsp_len, + hdev->discovery.uuid_count, + hdev->discovery.uuids)) + return false; } - /* Validate the reported RSSI value against the RSSI threshold once more - * incase HCI_QUIRK_STRICT_DUPLICATE_FILTER forced a restart of LE - * scanning. + /* If duplicate filtering does not report RSSI changes, then restart + * scanning to ensure updated result with updated RSSI values. */ - if (hdev->discovery.rssi != HCI_RSSI_INVALID && - rssi < hdev->discovery.rssi) - return false; + if (test_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks)) { + restart_le_scan(hdev); + + /* Validate RSSI value against the RSSI threshold once more. */ + if (hdev->discovery.rssi != HCI_RSSI_INVALID && + rssi < hdev->discovery.rssi) + return false; + } return true; } -- GitLab From 82f8b651a94d5c7090563fe55cfdb286c461a16c Mon Sep 17 00:00:00 2001 From: Jakub Pawlowski Date: Wed, 4 Mar 2015 16:24:26 -0800 Subject: [PATCH 02769/11651] Bluetooth: fix service discovery behaviour for empty uuids filter This patch fixes service discovery behaviour, when provided uuid filter is empty and HCI_QUIRK_STRICT_DUPLICATE_FILTER is set. Before this patch, empty uuid filter was unable to trigger scan restart, and that caused inconsistent behaviour in applications. Example: two DBus clients call BlueZ, one to find all devices with service abcd, second to find all devices with rssi smaller than -90. Sum of those filters, that is passed to mgmt_service_scan is empty filter, with no rssi or uuids set. That caused kernel not to restart scan when quirk was set. That was inconsistent with what happen when there's only one of those two filters set (scan is restarted and reports devices). To fix that, new variable hdev->discovery.result_filtering was introduced. It can indicate that filtered scan is running, no matter what uuid or rssi filter is set. Signed-off-by: Jakub Pawlowski Signed-off-by: Johan Hedberg --- include/net/bluetooth/hci_core.h | 2 ++ net/bluetooth/mgmt.c | 7 +++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index acec9140c3f9..15c761c1f82a 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -76,6 +76,7 @@ struct discovery_state { u8 last_adv_data[HCI_MAX_AD_LENGTH]; u8 last_adv_data_len; bool report_invalid_rssi; + bool result_filtering; s8 rssi; u16 uuid_count; u8 (*uuids)[16]; @@ -525,6 +526,7 @@ static inline void discovery_init(struct hci_dev *hdev) static inline void hci_discovery_filter_clear(struct hci_dev *hdev) { + hdev->discovery.result_filtering = false; hdev->discovery.report_invalid_rssi = true; hdev->discovery.rssi = HCI_RSSI_INVALID; hdev->discovery.uuid_count = 0; diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index bc09c5a37032..967f07fdbbbe 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -3933,8 +3933,7 @@ static void start_discovery_complete(struct hci_dev *hdev, u8 status, */ if (test_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks) && - (hdev->discovery.uuid_count > 0 || - hdev->discovery.rssi != HCI_RSSI_INVALID)) { + hdev->discovery.result_filtering) { hdev->discovery.scan_start = jiffies; hdev->discovery.scan_duration = timeout; } @@ -4087,6 +4086,7 @@ static int start_service_discovery(struct sock *sk, struct hci_dev *hdev, */ hci_discovery_filter_clear(hdev); + hdev->discovery.result_filtering = true; hdev->discovery.type = cp->type; hdev->discovery.rssi = cp->rssi; hdev->discovery.uuid_count = uuid_count; @@ -7344,8 +7344,7 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, return; } - if (hdev->discovery.rssi != HCI_RSSI_INVALID || - hdev->discovery.uuid_count > 0) { + if (hdev->discovery.result_filtering) { /* We are using service discovery */ if (!is_filter_match(hdev, rssi, eir, eir_len, scan_rsp, scan_rsp_len)) -- GitLab From ff6b8090e26ef7649ef0cc6b42389141ef48b0cf Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Tue, 27 Jan 2015 18:08:22 +0530 Subject: [PATCH 02770/11651] nbd: fix possible memory leak we have already allocated memory for nbd_dev, but we were not releasing that memory and just returning the error value. Signed-off-by: Sudip Mukherjee Acked-by: Paul Clements Cc: Signed-off-by: Markus Pargmann --- drivers/block/nbd.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 4bc2a5cb9935..a98c41f72c63 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -803,10 +803,6 @@ static int __init nbd_init(void) return -EINVAL; } - nbd_dev = kcalloc(nbds_max, sizeof(*nbd_dev), GFP_KERNEL); - if (!nbd_dev) - return -ENOMEM; - part_shift = 0; if (max_part > 0) { part_shift = fls(max_part); @@ -828,6 +824,10 @@ static int __init nbd_init(void) if (nbds_max > 1UL << (MINORBITS - part_shift)) return -EINVAL; + nbd_dev = kcalloc(nbds_max, sizeof(*nbd_dev), GFP_KERNEL); + if (!nbd_dev) + return -ENOMEM; + for (i = 0; i < nbds_max; i++) { struct gendisk *disk = alloc_disk(1 << part_shift); if (!disk) -- GitLab From 10971ab269bbf22120edac95fcfa3c873a549bea Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 5 Mar 2015 08:18:23 +0100 Subject: [PATCH 02771/11651] x86/mm: Further simplify 1 GB kernel linear mappings handling It's a bit pointless to allow Kconfig configuration for 1GB kernel mappings, it's already hidden behind a 'default y' and CONFIG_EXPERT. Remove this complication and simplify the code by renaming CONFIG_ENABLE_DIRECT_GBPAGES to CONFIG_X86_DIRECT_GBPAGES and document the DEBUG_PAGE_ALLOC and KMEMCHECK quirks. Cc: Luis R. Rodriguez Cc: Andrew Morton Cc: Andy Lutomirski Cc: Borislav Petkov Cc: Borislav Petkov Cc: Dave Hansen Cc: David Vrabel Cc: Dexuan Cui Cc: Greg Kroah-Hartman Cc: H. Peter Anvin Cc: JBeulich@suse.com Cc: Jan Beulich Cc: Joonsoo Kim Cc: Juergen Gross Cc: Linus Torvalds Cc: Pavel Machek Cc: Thomas Gleixner Cc: Tony Lindgren Cc: Toshi Kani Cc: Vlastimil Babka Cc: Xishi Qiu Cc: julia.lawall@lip6.fr Signed-off-by: Ingo Molnar --- arch/x86/Kconfig | 20 ++++++-------------- arch/x86/mm/init.c | 7 +------ 2 files changed, 7 insertions(+), 20 deletions(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 4d06e1c8294a..d03847513b6d 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -1299,22 +1299,14 @@ config ARCH_DMA_ADDR_T_64BIT def_bool y depends on X86_64 || HIGHMEM64G -config ENABLE_DIRECT_GBPAGES +config X86_DIRECT_GBPAGES def_bool y depends on X86_64 && !DEBUG_PAGEALLOC && !KMEMCHECK - -config DIRECT_GBPAGES - bool "Enable 1GB pages for kernel pagetables" if EXPERT - default y - depends on ENABLE_DIRECT_GBPAGES - ---help--- - Enable by default the kernel linear mapping to use 1GB pages on CPUs - that support it. This can improve the kernel's performance a tiny bit - by reducing TLB pressure. If in doubt, say "Y". If you've disabled - option but your platform is capable of handling support for this - you can use the gbpages kernel parameter. Likewise if you've enabled - this but you'd like to force disable this option you can use the - nogbpages kernel parameter. + ---help--- + Certain kernel features effectively disable kernel + linear 1 GB mappings (even if the CPU otherwise + supports them), so don't confuse the user by printing + that we have them enabled. # Common NUMA Features config NUMA diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c index c35ba8bce7cb..8704153f2675 100644 --- a/arch/x86/mm/init.c +++ b/arch/x86/mm/init.c @@ -133,15 +133,10 @@ int after_bootmem; static int page_size_mask; -early_param_on_off("gbpages", "nogbpages", - direct_gbpages, CONFIG_DIRECT_GBPAGES); +early_param_on_off("gbpages", "nogbpages", direct_gbpages, CONFIG_X86_DIRECT_GBPAGES); static void __init init_gbpages(void) { - if (!IS_ENABLED(CONFIG_ENABLE_DIRECT_GBPAGES)) { - direct_gbpages = 0; - return; - } if (direct_gbpages && cpu_has_gbpages) { printk(KERN_INFO "Using GB pages for direct mapping\n"); page_size_mask |= 1 << PG_LEVEL_1G; -- GitLab From e61980a70245715ab39cbee2b9d6e6afc1ec37d4 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 5 Mar 2015 08:25:01 +0100 Subject: [PATCH 02772/11651] x86/mm: Simplify probe_page_size_mask() Now that we've simplified the gbpages config space, move the 'page_size_mask' initialization into probe_page_size_mask(), right next to the PSE and PGE enablement lines. Cc: Luis R. Rodriguez Cc: Andrew Morton Cc: Andy Lutomirski Cc: Borislav Petkov Cc: Borislav Petkov Cc: Dave Hansen Cc: David Vrabel Cc: Dexuan Cui Cc: Greg Kroah-Hartman Cc: H. Peter Anvin Cc: JBeulich@suse.com Cc: Jan Beulich Cc: Joonsoo Kim Cc: Juergen Gross Cc: Linus Torvalds Cc: Pavel Machek Cc: Thomas Gleixner Cc: Tony Lindgren Cc: Toshi Kani Cc: Vlastimil Babka Cc: Xishi Qiu Cc: julia.lawall@lip6.fr Signed-off-by: Ingo Molnar --- arch/x86/mm/init.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c index 8704153f2675..6dc85d51cd98 100644 --- a/arch/x86/mm/init.c +++ b/arch/x86/mm/init.c @@ -131,29 +131,18 @@ void __init early_alloc_pgt_buf(void) int after_bootmem; -static int page_size_mask; - early_param_on_off("gbpages", "nogbpages", direct_gbpages, CONFIG_X86_DIRECT_GBPAGES); -static void __init init_gbpages(void) -{ - if (direct_gbpages && cpu_has_gbpages) { - printk(KERN_INFO "Using GB pages for direct mapping\n"); - page_size_mask |= 1 << PG_LEVEL_1G; - } else - direct_gbpages = 0; -} - struct map_range { unsigned long start; unsigned long end; unsigned page_size_mask; }; +static int page_size_mask; + static void __init probe_page_size_mask(void) { - init_gbpages(); - #if !defined(CONFIG_DEBUG_PAGEALLOC) && !defined(CONFIG_KMEMCHECK) /* * For CONFIG_DEBUG_PAGEALLOC, identity mapping will use small pages. @@ -173,6 +162,14 @@ static void __init probe_page_size_mask(void) cr4_set_bits_and_update_boot(X86_CR4_PGE); __supported_pte_mask |= _PAGE_GLOBAL; } + + /* Enable 1 GB linear kernel mappings if available: */ + if (direct_gbpages && cpu_has_gbpages) { + printk(KERN_INFO "Using GB pages for direct mapping\n"); + page_size_mask |= 1 << PG_LEVEL_1G; + } else { + direct_gbpages = 0; + } } #ifdef CONFIG_X86_32 -- GitLab From c281b94570ab711fdf21e81bdfb3d79764492bcf Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 5 Mar 2015 08:28:48 +0100 Subject: [PATCH 02773/11651] init.h: Clean up the __setup()/early_param() macros Make it all a bit easier on the eyes: - Move the __setup_param() lines right after their init functions - Use consistent vertical spacing - Use more horizontal spacing to make it look like regular C code - Use standard comment style Cc: Luis R. Rodriguez Cc: Andrew Morton Cc: Andy Lutomirski Cc: Borislav Petkov Cc: Borislav Petkov Cc: Dave Hansen Cc: David Vrabel Cc: Dexuan Cui Cc: Greg Kroah-Hartman Cc: H. Peter Anvin Cc: Jan Beulich Cc: Joonsoo Kim Cc: Juergen Gross Cc: Linus Torvalds Cc: Pavel Machek Cc: Thomas Gleixner Cc: Tony Lindgren Cc: Toshi Kani Cc: Vlastimil Babka Cc: Xishi Qiu Cc: julia.lawall@lip6.fr Signed-off-by: Ingo Molnar --- include/linux/init.h | 49 ++++++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/include/linux/init.h b/include/linux/init.h index bc11ff96f336..21b6d768edd7 100644 --- a/include/linux/init.h +++ b/include/linux/init.h @@ -253,34 +253,39 @@ struct obs_kernel_param { * obs_kernel_param "array" too far apart in .init.setup. */ #define __setup_param(str, unique_id, fn, early) \ - static const char __setup_str_##unique_id[] __initconst \ - __aligned(1) = str; \ - static struct obs_kernel_param __setup_##unique_id \ - __used __section(.init.setup) \ - __attribute__((aligned((sizeof(long))))) \ + static const char __setup_str_##unique_id[] __initconst \ + __aligned(1) = str; \ + static struct obs_kernel_param __setup_##unique_id \ + __used __section(.init.setup) \ + __attribute__((aligned((sizeof(long))))) \ = { __setup_str_##unique_id, fn, early } -#define __setup(str, fn) \ +#define __setup(str, fn) \ __setup_param(str, fn, fn, 0) -/* NOTE: fn is as per module_param, not __setup! Emits warning if fn - * returns non-zero. */ -#define early_param(str, fn) \ +/* + * NOTE: fn is as per module_param, not __setup! + * Emits warning if fn returns non-zero. + */ +#define early_param(str, fn) \ __setup_param(str, fn, fn, 1) -#define early_param_on_off(str_on, str_off, var, config) \ - int var = IS_ENABLED(config); \ - static int __init parse_##var##_on(char *arg) \ - { \ - var = 1; \ - return 0; \ - } \ - static int __init parse_##var##_off(char *arg) \ - { \ - var = 0; \ - return 0; \ - } \ - __setup_param(str_on, parse_##var##_on, parse_##var##_on, 1); \ +#define early_param_on_off(str_on, str_off, var, config) \ + \ + int var = IS_ENABLED(config); \ + \ + static int __init parse_##var##_on(char *arg) \ + { \ + var = 1; \ + return 0; \ + } \ + __setup_param(str_on, parse_##var##_on, parse_##var##_on, 1); \ + \ + static int __init parse_##var##_off(char *arg) \ + { \ + var = 0; \ + return 0; \ + } \ __setup_param(str_off, parse_##var##_off, parse_##var##_off, 1) /* Relies on boot_command_line being set */ -- GitLab From 94b3eed7b8a4311f56a86b36430e9068b596ada4 Mon Sep 17 00:00:00 2001 From: Jie Yang Date: Thu, 5 Mar 2015 14:08:08 +0800 Subject: [PATCH 02774/11651] dmaengine: dw: don't handle interrupt when dmaengine is not used When dma controller is not used by any user and set off, we should disble interrupt handler, at least the interrupt reset part, for some subsystem, e.g. ADSP, may use the dma in its own logic, here reset the interrupt may make this subsystem work abnormally. Signed-off-by: Jie Yang Signed-off-by: Vinod Koul --- drivers/dma/dw/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma/dw/core.c b/drivers/dma/dw/core.c index 455b7a4f1e87..a8ad05291b27 100644 --- a/drivers/dma/dw/core.c +++ b/drivers/dma/dw/core.c @@ -626,7 +626,7 @@ static irqreturn_t dw_dma_interrupt(int irq, void *dev_id) dev_vdbg(dw->dma.dev, "%s: status=0x%x\n", __func__, status); /* Check if we have any interrupt from the DMAC */ - if (!status) + if (!status || !dw->in_use) return IRQ_NONE; /* -- GitLab From c709feda56886c38af3116254f84cbe6a78b3a5d Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 5 Mar 2015 08:58:44 +0100 Subject: [PATCH 02775/11651] x86/mm/pat: Initialize __cachemode2pte_tbl[] and __pte2cachemode_tbl[] in a bit more readable fashion The initialization of these two arrays is a bit difficult to follow: restructure it optically so that a 2D structure shows which bit in the PTE is set and which not. Also improve on comments a bit. No code or data changed: # arch/x86/mm/init.o: text data bss dec hex filename 4585 424 29776 34785 87e1 init.o.before 4585 424 29776 34785 87e1 init.o.after md5: a82e11ff58bcfd0af3a94662a701f65d init.o.before.asm a82e11ff58bcfd0af3a94662a701f65d init.o.after.asm Reviewed-by: Juergen Gross Cc: Andy Lutomirski Cc: Dave Hansen Cc: Jan Beulich Cc: Linus Torvalds Cc: Luis R. Rodriguez Cc: Toshi Kani Cc: linux-kernel@vger.kernel.org Link: http://lkml.kernel.org/r/20150305082135.GB5969@gmail.com Signed-off-by: Ingo Molnar --- arch/x86/mm/init.c | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c index 6dc85d51cd98..4469563f8c3b 100644 --- a/arch/x86/mm/init.c +++ b/arch/x86/mm/init.c @@ -29,29 +29,33 @@ /* * Tables translating between page_cache_type_t and pte encoding. - * Minimal supported modes are defined statically, modified if more supported - * cache modes are available. - * Index into __cachemode2pte_tbl is the cachemode. - * Index into __pte2cachemode_tbl are the caching attribute bits of the pte - * (_PAGE_PWT, _PAGE_PCD, _PAGE_PAT) at index bit positions 0, 1, 2. + * + * Minimal supported modes are defined statically, they are modified + * during bootup if more supported cache modes are available. + * + * Index into __cachemode2pte_tbl[] is the cachemode. + * + * Index into __pte2cachemode_tbl[] are the caching attribute bits of the pte + * (_PAGE_PWT, _PAGE_PCD, _PAGE_PAT) at index bit positions 0, 1, 2. */ uint16_t __cachemode2pte_tbl[_PAGE_CACHE_MODE_NUM] = { - [_PAGE_CACHE_MODE_WB] = 0, - [_PAGE_CACHE_MODE_WC] = _PAGE_PWT, - [_PAGE_CACHE_MODE_UC_MINUS] = _PAGE_PCD, - [_PAGE_CACHE_MODE_UC] = _PAGE_PCD | _PAGE_PWT, - [_PAGE_CACHE_MODE_WT] = _PAGE_PCD, - [_PAGE_CACHE_MODE_WP] = _PAGE_PCD, + [_PAGE_CACHE_MODE_WB ] = 0 | 0 , + [_PAGE_CACHE_MODE_WC ] = _PAGE_PWT | 0 , + [_PAGE_CACHE_MODE_UC_MINUS] = 0 | _PAGE_PCD, + [_PAGE_CACHE_MODE_UC ] = _PAGE_PWT | _PAGE_PCD, + [_PAGE_CACHE_MODE_WT ] = 0 | _PAGE_PCD, + [_PAGE_CACHE_MODE_WP ] = 0 | _PAGE_PCD, }; EXPORT_SYMBOL(__cachemode2pte_tbl); + uint8_t __pte2cachemode_tbl[8] = { - [__pte2cm_idx(0)] = _PAGE_CACHE_MODE_WB, - [__pte2cm_idx(_PAGE_PWT)] = _PAGE_CACHE_MODE_WC, - [__pte2cm_idx(_PAGE_PCD)] = _PAGE_CACHE_MODE_UC_MINUS, - [__pte2cm_idx(_PAGE_PWT | _PAGE_PCD)] = _PAGE_CACHE_MODE_UC, - [__pte2cm_idx(_PAGE_PAT)] = _PAGE_CACHE_MODE_WB, - [__pte2cm_idx(_PAGE_PWT | _PAGE_PAT)] = _PAGE_CACHE_MODE_WC, - [__pte2cm_idx(_PAGE_PCD | _PAGE_PAT)] = _PAGE_CACHE_MODE_UC_MINUS, + [__pte2cm_idx( 0 | 0 | 0 )] = _PAGE_CACHE_MODE_WB, + [__pte2cm_idx(_PAGE_PWT | 0 | 0 )] = _PAGE_CACHE_MODE_WC, + [__pte2cm_idx( 0 | _PAGE_PCD | 0 )] = _PAGE_CACHE_MODE_UC_MINUS, + [__pte2cm_idx(_PAGE_PWT | _PAGE_PCD | 0 )] = _PAGE_CACHE_MODE_UC, + [__pte2cm_idx( 0 | 0 | _PAGE_PAT)] = _PAGE_CACHE_MODE_WB, + [__pte2cm_idx(_PAGE_PWT | 0 | _PAGE_PAT)] = _PAGE_CACHE_MODE_WC, + [__pte2cm_idx(0 | _PAGE_PCD | _PAGE_PAT)] = _PAGE_CACHE_MODE_UC_MINUS, [__pte2cm_idx(_PAGE_PWT | _PAGE_PCD | _PAGE_PAT)] = _PAGE_CACHE_MODE_UC, }; EXPORT_SYMBOL(__pte2cachemode_tbl); -- GitLab From 7f2e553a7173b485db41a52060f91fb8e5ab1c69 Mon Sep 17 00:00:00 2001 From: Rojhalat Ibrahim Date: Wed, 11 Feb 2015 17:27:55 +0100 Subject: [PATCH 02776/11651] gpiolib: define gpio suffixes globally Avoid multiple identical definitions of the gpio suffix strings by putting them into a global constant array. Signed-off-by: Rojhalat Ibrahim Reviewed-by: Alexandre Courbot Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib.c | 14 ++++++-------- drivers/gpio/gpiolib.h | 3 +++ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 15837263dbb3..2f8296c021e5 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1662,19 +1662,18 @@ static struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id, unsigned int idx, enum gpio_lookup_flags *flags) { - static const char * const suffixes[] = { "gpios", "gpio" }; char prop_name[32]; /* 32 is max size of property name */ enum of_gpio_flags of_flags; struct gpio_desc *desc; unsigned int i; - for (i = 0; i < ARRAY_SIZE(suffixes); i++) { + for (i = 0; i < ARRAY_SIZE(gpio_suffixes); i++) { if (con_id) snprintf(prop_name, sizeof(prop_name), "%s-%s", con_id, - suffixes[i]); + gpio_suffixes[i]); else snprintf(prop_name, sizeof(prop_name), "%s", - suffixes[i]); + gpio_suffixes[i]); desc = of_get_named_gpiod_flags(dev->of_node, prop_name, idx, &of_flags); @@ -1695,7 +1694,6 @@ static struct gpio_desc *acpi_find_gpio(struct device *dev, const char *con_id, unsigned int idx, enum gpio_lookup_flags *flags) { - static const char * const suffixes[] = { "gpios", "gpio" }; struct acpi_device *adev = ACPI_COMPANION(dev); struct acpi_gpio_info info; struct gpio_desc *desc; @@ -1703,13 +1701,13 @@ static struct gpio_desc *acpi_find_gpio(struct device *dev, const char *con_id, int i; /* Try first from _DSD */ - for (i = 0; i < ARRAY_SIZE(suffixes); i++) { + for (i = 0; i < ARRAY_SIZE(gpio_suffixes); i++) { if (con_id && strcmp(con_id, "gpios")) { snprintf(propname, sizeof(propname), "%s-%s", - con_id, suffixes[i]); + con_id, gpio_suffixes[i]); } else { snprintf(propname, sizeof(propname), "%s", - suffixes[i]); + gpio_suffixes[i]); } desc = acpi_get_gpiod_by_index(adev, propname, idx, &info); diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h index cadba26c45a6..205dd12659c0 100644 --- a/drivers/gpio/gpiolib.h +++ b/drivers/gpio/gpiolib.h @@ -27,6 +27,9 @@ struct acpi_gpio_info { bool active_low; }; +/* gpio suffixes used for ACPI and device tree lookup */ +static const char * const gpio_suffixes[] = { "gpios", "gpio" }; + #ifdef CONFIG_ACPI void acpi_gpiochip_add(struct gpio_chip *chip); void acpi_gpiochip_remove(struct gpio_chip *chip); -- GitLab From 668585273246f67b0cdafa30dd2da2047a2e1290 Mon Sep 17 00:00:00 2001 From: Rojhalat Ibrahim Date: Wed, 11 Feb 2015 17:27:58 +0100 Subject: [PATCH 02777/11651] gpiolib: add gpiod_get_array and gpiod_put_array functions Introduce new functions for conveniently obtaining and disposing of an entire array of GPIOs with one function call. ACPI parts tested by Mika Westerberg, DT parts tested by Rojhalat Ibrahim. Change log: v5: move the ACPI functions to gpiolib-acpi.c v4: - use shorter names for members of struct gpio_descs - rename lut_gpio_count to platform_gpio_count for clarity - add check for successful memory allocation - use ERR_CAST() v3: - rebase on current linux-gpio devel branch - fix ACPI GPIO counting - allow for zero-sized arrays - make the flags argument mandatory for the new functions - clarify documentation v2: change interface Suggested-by: Alexandre Courbot Signed-off-by: Rojhalat Ibrahim Reviewed-by: Alexandre Courbot Reviewed-by: Mika Westerberg Tested-by: Mika Westerberg Tested-by: Rojhalat Ibrahim Signed-off-by: Linus Walleij --- Documentation/gpio/consumer.txt | 33 +++++++- drivers/gpio/gpiolib-acpi.c | 84 ++++++++++++++++++ drivers/gpio/gpiolib.c | 145 ++++++++++++++++++++++++++++++++ drivers/gpio/gpiolib.h | 7 ++ include/linux/gpio/consumer.h | 46 ++++++++++ 5 files changed, 312 insertions(+), 3 deletions(-) diff --git a/Documentation/gpio/consumer.txt b/Documentation/gpio/consumer.txt index d85fbae451ea..2924f2ffcd91 100644 --- a/Documentation/gpio/consumer.txt +++ b/Documentation/gpio/consumer.txt @@ -58,7 +58,6 @@ pattern where a GPIO is optional, the gpiod_get_optional() and gpiod_get_index_optional() functions can be used. These functions return NULL instead of -ENOENT if no GPIO has been assigned to the requested function: - struct gpio_desc *gpiod_get_optional(struct device *dev, const char *con_id, enum gpiod_flags flags) @@ -68,6 +67,27 @@ instead of -ENOENT if no GPIO has been assigned to the requested function: unsigned int index, enum gpiod_flags flags) +For a function using multiple GPIOs all of those can be obtained with one call: + + struct gpio_descs *gpiod_get_array(struct device *dev, + const char *con_id, + enum gpiod_flags flags) + +This function returns a struct gpio_descs which contains an array of +descriptors: + + struct gpio_descs { + unsigned int ndescs; + struct gpio_desc *desc[]; + } + +The following function returns NULL instead of -ENOENT if no GPIOs have been +assigned to the requested function: + + struct gpio_descs *gpiod_get_array_optional(struct device *dev, + const char *con_id, + enum gpiod_flags flags) + Device-managed variants of these functions are also defined: struct gpio_desc *devm_gpiod_get(struct device *dev, const char *con_id, @@ -91,8 +111,15 @@ A GPIO descriptor can be disposed of using the gpiod_put() function: void gpiod_put(struct gpio_desc *desc) -It is strictly forbidden to use a descriptor after calling this function. The -device-managed variant is, unsurprisingly: +For an array of GPIOs this function can be used: + + void gpiod_put_array(struct gpio_descs *descs) + +It is strictly forbidden to use a descriptor after calling these functions. +It is also not allowed to individually release descriptors (using gpiod_put()) +from an array acquired with gpiod_get_array(). + +The device-managed variant is, unsurprisingly: void devm_gpiod_put(struct device *dev, struct gpio_desc *desc) diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c index c0929d938ced..c4919966453d 100644 --- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c @@ -712,3 +712,87 @@ void acpi_gpiochip_remove(struct gpio_chip *chip) acpi_detach_data(handle, acpi_gpio_chip_dh); kfree(acpi_gpio); } + +static unsigned int acpi_gpio_package_count(const union acpi_object *obj) +{ + const union acpi_object *element = obj->package.elements; + const union acpi_object *end = element + obj->package.count; + unsigned int count = 0; + + while (element < end) { + if (element->type == ACPI_TYPE_LOCAL_REFERENCE) + count++; + + element++; + } + return count; +} + +static int acpi_find_gpio_count(struct acpi_resource *ares, void *data) +{ + unsigned int *count = data; + + if (ares->type == ACPI_RESOURCE_TYPE_GPIO) + *count += ares->data.gpio.pin_table_length; + + return 1; +} + +/** + * acpi_gpio_count - return the number of GPIOs associated with a + * device / function or -ENOENT if no GPIO has been + * assigned to the requested function. + * @dev: GPIO consumer, can be NULL for system-global GPIOs + * @con_id: function within the GPIO consumer + */ +int acpi_gpio_count(struct device *dev, const char *con_id) +{ + struct acpi_device *adev = ACPI_COMPANION(dev); + const union acpi_object *obj; + const struct acpi_gpio_mapping *gm; + int count = -ENOENT; + int ret; + char propname[32]; + unsigned int i; + + /* Try first from _DSD */ + for (i = 0; i < ARRAY_SIZE(gpio_suffixes); i++) { + if (con_id && strcmp(con_id, "gpios")) + snprintf(propname, sizeof(propname), "%s-%s", + con_id, gpio_suffixes[i]); + else + snprintf(propname, sizeof(propname), "%s", + gpio_suffixes[i]); + + ret = acpi_dev_get_property(adev, propname, ACPI_TYPE_ANY, + &obj); + if (ret == 0) { + if (obj->type == ACPI_TYPE_LOCAL_REFERENCE) + count = 1; + else if (obj->type == ACPI_TYPE_PACKAGE) + count = acpi_gpio_package_count(obj); + } else if (adev->driver_gpios) { + for (gm = adev->driver_gpios; gm->name; gm++) + if (strcmp(propname, gm->name) == 0) { + count = gm->size; + break; + } + } + if (count >= 0) + break; + } + + /* Then from plain _CRS GPIOs */ + if (count < 0) { + struct list_head resource_list; + unsigned int crs_count = 0; + + INIT_LIST_HEAD(&resource_list); + acpi_dev_get_resources(adev, &resource_list, + acpi_find_gpio_count, &crs_count); + acpi_dev_free_resource_list(&resource_list); + if (crs_count > 0) + count = crs_count; + } + return count; +} diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 2f8296c021e5..3d5b85a7dcdf 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1806,6 +1806,70 @@ static struct gpio_desc *gpiod_find(struct device *dev, const char *con_id, return desc; } +static int dt_gpio_count(struct device *dev, const char *con_id) +{ + int ret; + char propname[32]; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(gpio_suffixes); i++) { + if (con_id) + snprintf(propname, sizeof(propname), "%s-%s", + con_id, gpio_suffixes[i]); + else + snprintf(propname, sizeof(propname), "%s", + gpio_suffixes[i]); + + ret = of_gpio_named_count(dev->of_node, propname); + if (ret >= 0) + break; + } + return ret; +} + +static int platform_gpio_count(struct device *dev, const char *con_id) +{ + struct gpiod_lookup_table *table; + struct gpiod_lookup *p; + unsigned int count = 0; + + table = gpiod_find_lookup_table(dev); + if (!table) + return -ENOENT; + + for (p = &table->table[0]; p->chip_label; p++) { + if ((con_id && p->con_id && !strcmp(con_id, p->con_id)) || + (!con_id && !p->con_id)) + count++; + } + if (!count) + return -ENOENT; + + return count; +} + +/** + * gpiod_count - return the number of GPIOs associated with a device / function + * or -ENOENT if no GPIO has been assigned to the requested function + * @dev: GPIO consumer, can be NULL for system-global GPIOs + * @con_id: function within the GPIO consumer + */ +int gpiod_count(struct device *dev, const char *con_id) +{ + int count = -ENOENT; + + if (IS_ENABLED(CONFIG_OF) && dev && dev->of_node) + count = dt_gpio_count(dev, con_id); + else if (IS_ENABLED(CONFIG_ACPI) && dev && ACPI_HANDLE(dev)) + count = acpi_gpio_count(dev, con_id); + + if (count < 0) + count = platform_gpio_count(dev, con_id); + + return count; +} +EXPORT_SYMBOL_GPL(gpiod_count); + /** * gpiod_get - obtain a GPIO for a given GPIO function * @dev: GPIO consumer, can be NULL for system-global GPIOs @@ -2089,6 +2153,72 @@ static void gpiochip_free_hogs(struct gpio_chip *chip) } } +/** + * gpiod_get_array - obtain multiple GPIOs from a multi-index GPIO function + * @dev: GPIO consumer, can be NULL for system-global GPIOs + * @con_id: function within the GPIO consumer + * @flags: optional GPIO initialization flags + * + * This function acquires all the GPIOs defined under a given function. + * + * Return a struct gpio_descs containing an array of descriptors, -ENOENT if + * no GPIO has been assigned to the requested function, or another IS_ERR() + * code if an error occurred while trying to acquire the GPIOs. + */ +struct gpio_descs *__must_check gpiod_get_array(struct device *dev, + const char *con_id, + enum gpiod_flags flags) +{ + struct gpio_desc *desc; + struct gpio_descs *descs; + int count; + + count = gpiod_count(dev, con_id); + if (count < 0) + return ERR_PTR(count); + + descs = kzalloc(sizeof(*descs) + sizeof(descs->desc[0]) * count, + GFP_KERNEL); + if (!descs) + return ERR_PTR(-ENOMEM); + + for (descs->ndescs = 0; descs->ndescs < count; ) { + desc = gpiod_get_index(dev, con_id, descs->ndescs, flags); + if (IS_ERR(desc)) { + gpiod_put_array(descs); + return ERR_CAST(desc); + } + descs->desc[descs->ndescs] = desc; + descs->ndescs++; + } + return descs; +} +EXPORT_SYMBOL_GPL(gpiod_get_array); + +/** + * gpiod_get_array_optional - obtain multiple GPIOs from a multi-index GPIO + * function + * @dev: GPIO consumer, can be NULL for system-global GPIOs + * @con_id: function within the GPIO consumer + * @flags: optional GPIO initialization flags + * + * This is equivalent to gpiod_get_array(), except that when no GPIO was + * assigned to the requested function it will return NULL. + */ +struct gpio_descs *__must_check gpiod_get_array_optional(struct device *dev, + const char *con_id, + enum gpiod_flags flags) +{ + struct gpio_descs *descs; + + descs = gpiod_get_array(dev, con_id, flags); + if (IS_ERR(descs) && (PTR_ERR(descs) == -ENOENT)) + return NULL; + + return descs; +} +EXPORT_SYMBOL_GPL(gpiod_get_array_optional); + /** * gpiod_put - dispose of a GPIO descriptor * @desc: GPIO descriptor to dispose of @@ -2101,6 +2231,21 @@ void gpiod_put(struct gpio_desc *desc) } EXPORT_SYMBOL_GPL(gpiod_put); +/** + * gpiod_put_array - dispose of multiple GPIO descriptors + * @descs: struct gpio_descs containing an array of descriptors + */ +void gpiod_put_array(struct gpio_descs *descs) +{ + unsigned int i; + + for (i = 0; i < descs->ndescs; i++) + gpiod_put(descs->desc[i]); + + kfree(descs); +} +EXPORT_SYMBOL_GPL(gpiod_put_array); + #ifdef CONFIG_DEBUG_FS static void gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip) diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h index 205dd12659c0..54bc5ec91398 100644 --- a/drivers/gpio/gpiolib.h +++ b/drivers/gpio/gpiolib.h @@ -40,6 +40,8 @@ void acpi_gpiochip_free_interrupts(struct gpio_chip *chip); struct gpio_desc *acpi_get_gpiod_by_index(struct acpi_device *adev, const char *propname, int index, struct acpi_gpio_info *info); + +int acpi_gpio_count(struct device *dev, const char *con_id); #else static inline void acpi_gpiochip_add(struct gpio_chip *chip) { } static inline void acpi_gpiochip_remove(struct gpio_chip *chip) { } @@ -56,6 +58,11 @@ acpi_get_gpiod_by_index(struct acpi_device *adev, const char *propname, { return ERR_PTR(-ENOSYS); } + +static inline int acpi_gpio_count(struct device *dev, const char *con_id) +{ + return -ENODEV; +} #endif struct gpio_desc *of_get_named_gpiod_flags(struct device_node *np, diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h index ed20759229eb..33eb52fd0932 100644 --- a/include/linux/gpio/consumer.h +++ b/include/linux/gpio/consumer.h @@ -16,6 +16,15 @@ struct device; */ struct gpio_desc; +/** + * Struct containing an array of descriptors that can be obtained using + * gpiod_get_array(). + */ +struct gpio_descs { + unsigned int ndescs; + struct gpio_desc *desc[]; +}; + #define GPIOD_FLAGS_BIT_DIR_SET BIT(0) #define GPIOD_FLAGS_BIT_DIR_OUT BIT(1) #define GPIOD_FLAGS_BIT_DIR_VAL BIT(2) @@ -34,6 +43,9 @@ enum gpiod_flags { #ifdef CONFIG_GPIOLIB +/* Return the number of GPIOs associated with a device / function */ +int gpiod_count(struct device *dev, const char *con_id); + /* Acquire and dispose GPIOs */ struct gpio_desc *__must_check __gpiod_get(struct device *dev, const char *con_id, @@ -49,7 +61,14 @@ struct gpio_desc *__must_check __gpiod_get_index_optional(struct device *dev, const char *con_id, unsigned int index, enum gpiod_flags flags); +struct gpio_descs *__must_check gpiod_get_array(struct device *dev, + const char *con_id, + enum gpiod_flags flags); +struct gpio_descs *__must_check gpiod_get_array_optional(struct device *dev, + const char *con_id, + enum gpiod_flags flags); void gpiod_put(struct gpio_desc *desc); +void gpiod_put_array(struct gpio_descs *descs); struct gpio_desc *__must_check __devm_gpiod_get(struct device *dev, const char *con_id, @@ -114,6 +133,11 @@ struct gpio_desc *devm_get_gpiod_from_child(struct device *dev, struct fwnode_handle *child); #else /* CONFIG_GPIOLIB */ +static inline int gpiod_count(struct device *dev, const char *con_id) +{ + return 0; +} + static inline struct gpio_desc *__must_check __gpiod_get(struct device *dev, const char *con_id, enum gpiod_flags flags) @@ -143,6 +167,20 @@ __gpiod_get_index_optional(struct device *dev, const char *con_id, return ERR_PTR(-ENOSYS); } +static inline struct gpio_descs *__must_check +gpiod_get_array(struct device *dev, const char *con_id, + enum gpiod_flags flags) +{ + return ERR_PTR(-ENOSYS); +} + +static inline struct gpio_descs *__must_check +gpiod_get_array_optional(struct device *dev, const char *con_id, + enum gpiod_flags flags) +{ + return ERR_PTR(-ENOSYS); +} + static inline void gpiod_put(struct gpio_desc *desc) { might_sleep(); @@ -151,6 +189,14 @@ static inline void gpiod_put(struct gpio_desc *desc) WARN_ON(1); } +static inline void gpiod_put_array(struct gpio_descs *descs) +{ + might_sleep(); + + /* GPIO can never have been requested */ + WARN_ON(1); +} + static inline struct gpio_desc *__must_check __devm_gpiod_get(struct device *dev, const char *con_id, -- GitLab From 331758eef83620eef3f21289f0f44aba094d0503 Mon Sep 17 00:00:00 2001 From: Rojhalat Ibrahim Date: Wed, 11 Feb 2015 17:28:02 +0100 Subject: [PATCH 02778/11651] gpiolib: add devm_gpiod_get_array and devm_gpiod_put_array functions Add device managed variants of gpiod_get_array() / gpiod_put_array() functions for conveniently obtaining and disposing of an entire array of GPIOs with one function call. Signed-off-by: Rojhalat Ibrahim Reviewed-by: Alexandre Courbot Signed-off-by: Linus Walleij --- Documentation/gpio/consumer.txt | 14 +++++- drivers/gpio/devres.c | 89 +++++++++++++++++++++++++++++++++ include/linux/gpio/consumer.h | 30 +++++++++++ 3 files changed, 131 insertions(+), 2 deletions(-) diff --git a/Documentation/gpio/consumer.txt b/Documentation/gpio/consumer.txt index 2924f2ffcd91..d29a9725c9e5 100644 --- a/Documentation/gpio/consumer.txt +++ b/Documentation/gpio/consumer.txt @@ -102,11 +102,19 @@ Device-managed variants of these functions are also defined: const char *con_id, enum gpiod_flags flags) - struct gpio_desc * devm_gpiod_get_index_optional(struct device *dev, + struct gpio_desc *devm_gpiod_get_index_optional(struct device *dev, const char *con_id, unsigned int index, enum gpiod_flags flags) + struct gpio_descs *devm_gpiod_get_array(struct device *dev, + const char *con_id, + enum gpiod_flags flags) + + struct gpio_descs *devm_gpiod_get_array_optional(struct device *dev, + const char *con_id, + enum gpiod_flags flags) + A GPIO descriptor can be disposed of using the gpiod_put() function: void gpiod_put(struct gpio_desc *desc) @@ -119,10 +127,12 @@ It is strictly forbidden to use a descriptor after calling these functions. It is also not allowed to individually release descriptors (using gpiod_put()) from an array acquired with gpiod_get_array(). -The device-managed variant is, unsurprisingly: +The device-managed variants are, unsurprisingly: void devm_gpiod_put(struct device *dev, struct gpio_desc *desc) + void devm_gpiod_put_array(struct device *dev, struct gpio_descs *descs) + Using GPIOs =========== diff --git a/drivers/gpio/devres.c b/drivers/gpio/devres.c index 12c2082f968e..ec24da2418b3 100644 --- a/drivers/gpio/devres.c +++ b/drivers/gpio/devres.c @@ -35,6 +35,20 @@ static int devm_gpiod_match(struct device *dev, void *res, void *data) return *this == *gpio; } +static void devm_gpiod_release_array(struct device *dev, void *res) +{ + struct gpio_descs **descs = res; + + gpiod_put_array(*descs); +} + +static int devm_gpiod_match_array(struct device *dev, void *res, void *data) +{ + struct gpio_descs **this = res, **gpios = data; + + return *this == *gpios; +} + /** * devm_gpiod_get - Resource-managed gpiod_get() * @dev: GPIO consumer @@ -185,6 +199,66 @@ struct gpio_desc *__must_check __devm_gpiod_get_index_optional(struct device *de } EXPORT_SYMBOL(__devm_gpiod_get_index_optional); +/** + * devm_gpiod_get_array - Resource-managed gpiod_get_array() + * @dev: GPIO consumer + * @con_id: function within the GPIO consumer + * @flags: optional GPIO initialization flags + * + * Managed gpiod_get_array(). GPIO descriptors returned from this function are + * automatically disposed on driver detach. See gpiod_get_array() for detailed + * information about behavior and return values. + */ +struct gpio_descs *__must_check devm_gpiod_get_array(struct device *dev, + const char *con_id, + enum gpiod_flags flags) +{ + struct gpio_descs **dr; + struct gpio_descs *descs; + + dr = devres_alloc(devm_gpiod_release_array, + sizeof(struct gpio_descs *), GFP_KERNEL); + if (!dr) + return ERR_PTR(-ENOMEM); + + descs = gpiod_get_array(dev, con_id, flags); + if (IS_ERR(descs)) { + devres_free(dr); + return descs; + } + + *dr = descs; + devres_add(dev, dr); + + return descs; +} +EXPORT_SYMBOL(devm_gpiod_get_array); + +/** + * devm_gpiod_get_array_optional - Resource-managed gpiod_get_array_optional() + * @dev: GPIO consumer + * @con_id: function within the GPIO consumer + * @flags: optional GPIO initialization flags + * + * Managed gpiod_get_array_optional(). GPIO descriptors returned from this + * function are automatically disposed on driver detach. + * See gpiod_get_array_optional() for detailed information about behavior and + * return values. + */ +struct gpio_descs *__must_check +devm_gpiod_get_array_optional(struct device *dev, const char *con_id, + enum gpiod_flags flags) +{ + struct gpio_descs *descs; + + descs = devm_gpiod_get_array(dev, con_id, flags); + if (IS_ERR(descs) && (PTR_ERR(descs) == -ENOENT)) + return NULL; + + return descs; +} +EXPORT_SYMBOL(devm_gpiod_get_array_optional); + /** * devm_gpiod_put - Resource-managed gpiod_put() * @desc: GPIO descriptor to dispose of @@ -200,6 +274,21 @@ void devm_gpiod_put(struct device *dev, struct gpio_desc *desc) } EXPORT_SYMBOL(devm_gpiod_put); +/** + * devm_gpiod_put_array - Resource-managed gpiod_put_array() + * @descs: GPIO descriptor array to dispose of + * + * Dispose of an array of GPIO descriptors obtained with devm_gpiod_get_array(). + * Normally this function will not be called as the GPIOs will be disposed of + * by the resource management code. + */ +void devm_gpiod_put_array(struct device *dev, struct gpio_descs *descs) +{ + WARN_ON(devres_release(dev, devm_gpiod_release_array, + devm_gpiod_match_array, &descs)); +} +EXPORT_SYMBOL(devm_gpiod_put_array); + diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h index 33eb52fd0932..3a7c9ffd5ab9 100644 --- a/include/linux/gpio/consumer.h +++ b/include/linux/gpio/consumer.h @@ -83,7 +83,14 @@ struct gpio_desc *__must_check __devm_gpiod_get_optional(struct device *dev, struct gpio_desc *__must_check __devm_gpiod_get_index_optional(struct device *dev, const char *con_id, unsigned int index, enum gpiod_flags flags); +struct gpio_descs *__must_check devm_gpiod_get_array(struct device *dev, + const char *con_id, + enum gpiod_flags flags); +struct gpio_descs *__must_check +devm_gpiod_get_array_optional(struct device *dev, const char *con_id, + enum gpiod_flags flags); void devm_gpiod_put(struct device *dev, struct gpio_desc *desc); +void devm_gpiod_put_array(struct device *dev, struct gpio_descs *descs); int gpiod_get_direction(struct gpio_desc *desc); int gpiod_direction_input(struct gpio_desc *desc); @@ -228,6 +235,20 @@ __devm_gpiod_get_index_optional(struct device *dev, const char *con_id, return ERR_PTR(-ENOSYS); } +static inline struct gpio_descs *__must_check +devm_gpiod_get_array(struct device *dev, const char *con_id, + enum gpiod_flags flags) +{ + return ERR_PTR(-ENOSYS); +} + +static inline struct gpio_descs *__must_check +devm_gpiod_get_array_optional(struct device *dev, const char *con_id, + enum gpiod_flags flags) +{ + return ERR_PTR(-ENOSYS); +} + static inline void devm_gpiod_put(struct device *dev, struct gpio_desc *desc) { might_sleep(); @@ -236,6 +257,15 @@ static inline void devm_gpiod_put(struct device *dev, struct gpio_desc *desc) WARN_ON(1); } +static inline void devm_gpiod_put_array(struct device *dev, + struct gpio_descs *descs) +{ + might_sleep(); + + /* GPIO can never have been requested */ + WARN_ON(1); +} + static inline int gpiod_get_direction(const struct gpio_desc *desc) { -- GitLab From 6eb9d3c1e9c5977f7fe6be125006443e7da2427c Mon Sep 17 00:00:00 2001 From: Ludovic Desroches Date: Thu, 12 Feb 2015 16:30:30 +0100 Subject: [PATCH 02779/11651] dmaengine: at_xdmac: fix for chan conf simplification When simplificating the channel configuration, the cyclic case has been forgotten. It leads to use bad configuration causing many bugs. Signed-off-by: Ludovic Desroches Acked-by: Nicolas Ferre Signed-off-by: Vinod Koul --- drivers/dma/at_xdmac.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c index 09e2825a547a..d9891d3461f6 100644 --- a/drivers/dma/at_xdmac.c +++ b/drivers/dma/at_xdmac.c @@ -664,7 +664,6 @@ at_xdmac_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, struct at_xdmac_desc *first = NULL, *prev = NULL; unsigned int periods = buf_len / period_len; int i; - u32 cfg; dev_dbg(chan2dev(chan), "%s: buf_addr=%pad, buf_len=%zd, period_len=%zd, dir=%s, flags=0x%lx\n", __func__, &buf_addr, buf_len, period_len, @@ -700,17 +699,17 @@ at_xdmac_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, if (direction == DMA_DEV_TO_MEM) { desc->lld.mbr_sa = atchan->per_src_addr; desc->lld.mbr_da = buf_addr + i * period_len; - cfg = atchan->cfg[AT_XDMAC_DEV_TO_MEM_CFG]; + desc->lld.mbr_cfg = atchan->cfg[AT_XDMAC_DEV_TO_MEM_CFG]; } else { desc->lld.mbr_sa = buf_addr + i * period_len; desc->lld.mbr_da = atchan->per_dst_addr; - cfg = atchan->cfg[AT_XDMAC_MEM_TO_DEV_CFG]; + desc->lld.mbr_cfg = atchan->cfg[AT_XDMAC_MEM_TO_DEV_CFG]; } desc->lld.mbr_ubc = AT_XDMAC_MBR_UBC_NDV1 | AT_XDMAC_MBR_UBC_NDEN | AT_XDMAC_MBR_UBC_NSEN | AT_XDMAC_MBR_UBC_NDE - | period_len >> at_xdmac_get_dwidth(cfg); + | period_len >> at_xdmac_get_dwidth(desc->lld.mbr_cfg); dev_dbg(chan2dev(chan), "%s: lld: mbr_sa=%pad, mbr_da=%pad, mbr_ubc=0x%08x\n", -- GitLab From 9ca1c5f2ab9d5bc8955a2cc7ad36ba7074dd7c60 Mon Sep 17 00:00:00 2001 From: Dave Jiang Date: Fri, 13 Feb 2015 12:23:53 -0700 Subject: [PATCH 02780/11651] dmaengine: ioatdma: workaround for incorrect DMACAP register BDX-DE IOATDMA reports incorrect DMACAP register for PQ related ops. Ignoring those bits. Signed-off-by: Dave Jiang Acked-by: Dan Williams Signed-off-by: Vinod Koul --- drivers/dma/ioat/dma_v3.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/dma/ioat/dma_v3.c b/drivers/dma/ioat/dma_v3.c index 77a6dcf25b98..194ec20c9408 100644 --- a/drivers/dma/ioat/dma_v3.c +++ b/drivers/dma/ioat/dma_v3.c @@ -230,6 +230,10 @@ static bool is_bwd_noraid(struct pci_dev *pdev) switch (pdev->device) { case PCI_DEVICE_ID_INTEL_IOAT_BWD2: case PCI_DEVICE_ID_INTEL_IOAT_BWD3: + case PCI_DEVICE_ID_INTEL_IOAT_BDXDE0: + case PCI_DEVICE_ID_INTEL_IOAT_BDXDE1: + case PCI_DEVICE_ID_INTEL_IOAT_BDXDE2: + case PCI_DEVICE_ID_INTEL_IOAT_BDXDE3: return true; default: return false; -- GitLab From c668a12c7bc92cc99de269647701b9d277f295b8 Mon Sep 17 00:00:00 2001 From: Greg Rose Date: Thu, 26 Feb 2015 16:10:39 +0000 Subject: [PATCH 02781/11651] i40e: Fix NPAR Tx Scheduler init Recent changes to the driver initialization have caused the BW configurations to not take effect. We use a BW configuration read and write back to "kick" the Tx scheduler into action. Change-ID: I94ab377c58d3a3986e3de62b6c199be3fd2ee5e6 Signed-off-by: Greg Rose Tested-by: Jim Young Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_main.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 56bdaff9f27e..620dd237cce4 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -7576,6 +7576,10 @@ static int i40e_sw_init(struct i40e_pf *pf) mutex_init(&pf->switch_mutex); + /* If NPAR is enabled nudge the Tx scheduler */ + if (pf->hw.func_caps.npar_enable && (!i40e_get_npar_bw_setting(pf))) + i40e_set_npar_bw_setting(pf); + sw_init_done: return err; } -- GitLab From 40eeb111d7c88bfbc38e1dfe330bc4cec05e0806 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 5 Mar 2015 10:08:14 +0100 Subject: [PATCH 02782/11651] Revert "pinctrl: consumer: use correct retval for placeholder functions" This reverts commit 5a7d2efdd93f6c4bb6cd3d5df3d2f5611c9b87ac. As per discussion on the mailing list, this is not the right thing to do. NULL cookies are valid in the stubs. Reported-by: Wolfram Sang Signed-off-by: Linus Walleij --- include/linux/pinctrl/consumer.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/linux/pinctrl/consumer.h b/include/linux/pinctrl/consumer.h index 72c0415d6c21..18eccefea06e 100644 --- a/include/linux/pinctrl/consumer.h +++ b/include/linux/pinctrl/consumer.h @@ -82,7 +82,7 @@ static inline int pinctrl_gpio_direction_output(unsigned gpio) static inline struct pinctrl * __must_check pinctrl_get(struct device *dev) { - return ERR_PTR(-ENOSYS); + return NULL; } static inline void pinctrl_put(struct pinctrl *p) @@ -93,7 +93,7 @@ static inline struct pinctrl_state * __must_check pinctrl_lookup_state( struct pinctrl *p, const char *name) { - return ERR_PTR(-ENOSYS); + return NULL; } static inline int pinctrl_select_state(struct pinctrl *p, @@ -104,7 +104,7 @@ static inline int pinctrl_select_state(struct pinctrl *p, static inline struct pinctrl * __must_check devm_pinctrl_get(struct device *dev) { - return ERR_PTR(-ENOSYS); + return NULL; } static inline void devm_pinctrl_put(struct pinctrl *p) -- GitLab From b84d5cd8198fa140abcd9293ab795897f2fc937f Mon Sep 17 00:00:00 2001 From: Matt Jared Date: Thu, 26 Feb 2015 16:11:30 +0000 Subject: [PATCH 02783/11651] i40e: during LED interaction ignore activity LED src modes Modify our get and set LED functions so they ignore activity LEDs, as we are required to blink the link LEDs only. Change-ID: I647ea67a6fc95cbbab6e3cd01d81ec9ae096a9ad Signed-off-by: Matt Jared Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_common.c | 35 ++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c index 1da7d05abd38..cc10303c388d 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_common.c +++ b/drivers/net/ethernet/intel/i40e/i40e_common.c @@ -1083,8 +1083,11 @@ static u32 i40e_led_is_mine(struct i40e_hw *hw, int idx) return gpio_val; } -#define I40E_LED0 22 +#define I40E_COMBINED_ACTIVITY 0xA +#define I40E_FILTER_ACTIVITY 0xE #define I40E_LINK_ACTIVITY 0xC +#define I40E_MAC_ACTIVITY 0xD +#define I40E_LED0 22 /** * i40e_led_get - return current on/off mode @@ -1097,6 +1100,7 @@ static u32 i40e_led_is_mine(struct i40e_hw *hw, int idx) **/ u32 i40e_led_get(struct i40e_hw *hw) { + u32 current_mode = 0; u32 mode = 0; int i; @@ -1109,6 +1113,20 @@ u32 i40e_led_get(struct i40e_hw *hw) if (!gpio_val) continue; + /* ignore gpio LED src mode entries related to the activity + * LEDs + */ + current_mode = ((gpio_val & I40E_GLGEN_GPIO_CTL_LED_MODE_MASK) + >> I40E_GLGEN_GPIO_CTL_LED_MODE_SHIFT); + switch (current_mode) { + case I40E_COMBINED_ACTIVITY: + case I40E_FILTER_ACTIVITY: + case I40E_MAC_ACTIVITY: + continue; + default: + break; + } + mode = (gpio_val & I40E_GLGEN_GPIO_CTL_LED_MODE_MASK) >> I40E_GLGEN_GPIO_CTL_LED_MODE_SHIFT; break; @@ -1128,6 +1146,7 @@ u32 i40e_led_get(struct i40e_hw *hw) **/ void i40e_led_set(struct i40e_hw *hw, u32 mode, bool blink) { + u32 current_mode = 0; int i; if (mode & 0xfffffff0) @@ -1142,6 +1161,20 @@ void i40e_led_set(struct i40e_hw *hw, u32 mode, bool blink) if (!gpio_val) continue; + /* ignore gpio LED src mode entries related to the activity + * LEDs + */ + current_mode = ((gpio_val & I40E_GLGEN_GPIO_CTL_LED_MODE_MASK) + >> I40E_GLGEN_GPIO_CTL_LED_MODE_SHIFT); + switch (current_mode) { + case I40E_COMBINED_ACTIVITY: + case I40E_FILTER_ACTIVITY: + case I40E_MAC_ACTIVITY: + continue; + default: + break; + } + gpio_val &= ~I40E_GLGEN_GPIO_CTL_LED_MODE_MASK; /* this & is a bit of paranoia, but serves as a range check */ gpio_val |= ((mode << I40E_GLGEN_GPIO_CTL_LED_MODE_SHIFT) & -- GitLab From 32c006a99799f6f3c759b77ba761c3a5981e34eb Mon Sep 17 00:00:00 2001 From: Kevin Hao Date: Thu, 12 Feb 2015 14:52:49 +0800 Subject: [PATCH 02784/11651] gpio: mpc8xxx: remove __initdata annotation for mpc8xxx_gpio_ids[] Since commit 98686d9a52ee ("gpio: mpc8xxx: Convert to platform device interface"), we get the following section mismatch warning. Remove the __initdata annotation to fix it. WARNING: vmlinux.o(.data+0xbc28): Section mismatch in reference from the variable mpc8xxx_plat_driver to the variable .init.data:mpc8xxx_gpio_ids The variable mpc8xxx_plat_driver references the variable __initdata mpc8xxx_gpio_ids If the reference is valid then annotate the variable with __init* or __refdata (see linux/init.h) or name the variable: *_template, *_timer, *_sht, *_ops, *_probe, *_probe_one, *_console Signed-off-by: Kevin Hao Signed-off-by: Linus Walleij --- drivers/gpio/gpio-mpc8xxx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpio/gpio-mpc8xxx.c b/drivers/gpio/gpio-mpc8xxx.c index a6952ba343a8..a65b75161aa4 100644 --- a/drivers/gpio/gpio-mpc8xxx.c +++ b/drivers/gpio/gpio-mpc8xxx.c @@ -334,7 +334,7 @@ static struct irq_domain_ops mpc8xxx_gpio_irq_ops = { .xlate = irq_domain_xlate_twocell, }; -static struct of_device_id mpc8xxx_gpio_ids[] __initdata = { +static struct of_device_id mpc8xxx_gpio_ids[] = { { .compatible = "fsl,mpc8349-gpio", }, { .compatible = "fsl,mpc8572-gpio", }, { .compatible = "fsl,mpc8610-gpio", }, -- GitLab From 3c5ecc9ed3537846fd95e8f288d6d6968075879f Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Wed, 21 Jan 2015 15:43:11 +0900 Subject: [PATCH 02785/11651] pinctrl: exynos: Add support for Exynos5433 This patch adds driver data for Exynos5433 SoC. Exynos5433 includes 228 multi- functional input/output port pins and 135 memory port pins. There are 41 general port groups and 2 memory port groups. Cc: Thomas Abraham Acked-by: Tomasz Figa Signed-off-by: Chanwoo Choi Acked-by: Inki Dae Signed-off-by: Linus Walleij --- drivers/pinctrl/samsung/pinctrl-exynos.c | 153 ++++++++++++++++++++++ drivers/pinctrl/samsung/pinctrl-samsung.c | 2 + drivers/pinctrl/samsung/pinctrl-samsung.h | 1 + 3 files changed, 156 insertions(+) diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c index c8f83f96546c..d273fda5cc89 100644 --- a/drivers/pinctrl/samsung/pinctrl-exynos.c +++ b/drivers/pinctrl/samsung/pinctrl-exynos.c @@ -1240,6 +1240,159 @@ const struct samsung_pin_ctrl exynos5420_pin_ctrl[] __initconst = { }, }; +/* pin banks of exynos5433 pin-controller - ALIVE */ +static const struct samsung_pin_bank_data exynos5433_pin_banks0[] = { + EXYNOS_PIN_BANK_EINTW(8, 0x000, "gpa0", 0x00), + EXYNOS_PIN_BANK_EINTW(8, 0x020, "gpa1", 0x04), + EXYNOS_PIN_BANK_EINTW(8, 0x040, "gpa2", 0x08), + EXYNOS_PIN_BANK_EINTW(8, 0x060, "gpa3", 0x0c), +}; + +/* pin banks of exynos5433 pin-controller - AUD */ +static const struct samsung_pin_bank_data exynos5433_pin_banks1[] = { + EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpz0", 0x00), + EXYNOS_PIN_BANK_EINTG(4, 0x020, "gpz1", 0x04), +}; + +/* pin banks of exynos5433 pin-controller - CPIF */ +static const struct samsung_pin_bank_data exynos5433_pin_banks2[] = { + EXYNOS_PIN_BANK_EINTG(2, 0x000, "gpv6", 0x00), +}; + +/* pin banks of exynos5433 pin-controller - eSE */ +static const struct samsung_pin_bank_data exynos5433_pin_banks3[] = { + EXYNOS_PIN_BANK_EINTG(3, 0x000, "gpj2", 0x00), +}; + +/* pin banks of exynos5433 pin-controller - FINGER */ +static const struct samsung_pin_bank_data exynos5433_pin_banks4[] = { + EXYNOS_PIN_BANK_EINTG(4, 0x000, "gpd5", 0x00), +}; + +/* pin banks of exynos5433 pin-controller - FSYS */ +static const struct samsung_pin_bank_data exynos5433_pin_banks5[] = { + EXYNOS_PIN_BANK_EINTG(6, 0x000, "gph1", 0x00), + EXYNOS_PIN_BANK_EINTG(7, 0x020, "gpr4", 0x04), + EXYNOS_PIN_BANK_EINTG(5, 0x040, "gpr0", 0x08), + EXYNOS_PIN_BANK_EINTG(8, 0x060, "gpr1", 0x0c), + EXYNOS_PIN_BANK_EINTG(2, 0x080, "gpr2", 0x10), + EXYNOS_PIN_BANK_EINTG(8, 0x0a0, "gpr3", 0x14), +}; + +/* pin banks of exynos5433 pin-controller - IMEM */ +static const struct samsung_pin_bank_data exynos5433_pin_banks6[] = { + EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpf0", 0x00), +}; + +/* pin banks of exynos5433 pin-controller - NFC */ +static const struct samsung_pin_bank_data exynos5433_pin_banks7[] = { + EXYNOS_PIN_BANK_EINTG(3, 0x000, "gpj0", 0x00), +}; + +/* pin banks of exynos5433 pin-controller - PERIC */ +static const struct samsung_pin_bank_data exynos5433_pin_banks8[] = { + EXYNOS_PIN_BANK_EINTG(6, 0x000, "gpv7", 0x00), + EXYNOS_PIN_BANK_EINTG(5, 0x020, "gpb0", 0x04), + EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpc0", 0x08), + EXYNOS_PIN_BANK_EINTG(2, 0x060, "gpc1", 0x0c), + EXYNOS_PIN_BANK_EINTG(6, 0x080, "gpc2", 0x10), + EXYNOS_PIN_BANK_EINTG(8, 0x0a0, "gpc3", 0x14), + EXYNOS_PIN_BANK_EINTG(2, 0x0c0, "gpg0", 0x18), + EXYNOS_PIN_BANK_EINTG(4, 0x0e0, "gpd0", 0x1c), + EXYNOS_PIN_BANK_EINTG(6, 0x100, "gpd1", 0x20), + EXYNOS_PIN_BANK_EINTG(8, 0x120, "gpd2", 0x24), + EXYNOS_PIN_BANK_EINTG(5, 0x140, "gpd4", 0x28), + EXYNOS_PIN_BANK_EINTG(2, 0x160, "gpd8", 0x2c), + EXYNOS_PIN_BANK_EINTG(7, 0x180, "gpd6", 0x30), + EXYNOS_PIN_BANK_EINTG(3, 0x1a0, "gpd7", 0x34), + EXYNOS_PIN_BANK_EINTG(5, 0x1c0, "gpg1", 0x38), + EXYNOS_PIN_BANK_EINTG(2, 0x1e0, "gpg2", 0x3c), + EXYNOS_PIN_BANK_EINTG(8, 0x200, "gpg3", 0x40), +}; + +/* pin banks of exynos5433 pin-controller - TOUCH */ +static const struct samsung_pin_bank_data exynos5433_pin_banks9[] = { + EXYNOS_PIN_BANK_EINTG(3, 0x000, "gpj1", 0x00), +}; + +/* + * Samsung pinctrl driver data for Exynos5433 SoC. Exynos5433 SoC includes + * ten gpio/pin-mux/pinconfig controllers. + */ +const struct samsung_pin_ctrl exynos5433_pin_ctrl[] = { + { + /* pin-controller instance 0 data */ + .pin_banks = exynos5433_pin_banks0, + .nr_banks = ARRAY_SIZE(exynos5433_pin_banks0), + .eint_wkup_init = exynos_eint_wkup_init, + .suspend = exynos_pinctrl_suspend, + .resume = exynos_pinctrl_resume, + }, { + /* pin-controller instance 1 data */ + .pin_banks = exynos5433_pin_banks1, + .nr_banks = ARRAY_SIZE(exynos5433_pin_banks1), + .eint_gpio_init = exynos_eint_gpio_init, + .suspend = exynos_pinctrl_suspend, + .resume = exynos_pinctrl_resume, + }, { + /* pin-controller instance 2 data */ + .pin_banks = exynos5433_pin_banks2, + .nr_banks = ARRAY_SIZE(exynos5433_pin_banks2), + .eint_gpio_init = exynos_eint_gpio_init, + .suspend = exynos_pinctrl_suspend, + .resume = exynos_pinctrl_resume, + }, { + /* pin-controller instance 3 data */ + .pin_banks = exynos5433_pin_banks3, + .nr_banks = ARRAY_SIZE(exynos5433_pin_banks3), + .eint_gpio_init = exynos_eint_gpio_init, + .suspend = exynos_pinctrl_suspend, + .resume = exynos_pinctrl_resume, + }, { + /* pin-controller instance 4 data */ + .pin_banks = exynos5433_pin_banks4, + .nr_banks = ARRAY_SIZE(exynos5433_pin_banks4), + .eint_gpio_init = exynos_eint_gpio_init, + .suspend = exynos_pinctrl_suspend, + .resume = exynos_pinctrl_resume, + }, { + /* pin-controller instance 5 data */ + .pin_banks = exynos5433_pin_banks5, + .nr_banks = ARRAY_SIZE(exynos5433_pin_banks5), + .eint_gpio_init = exynos_eint_gpio_init, + .suspend = exynos_pinctrl_suspend, + .resume = exynos_pinctrl_resume, + }, { + /* pin-controller instance 6 data */ + .pin_banks = exynos5433_pin_banks6, + .nr_banks = ARRAY_SIZE(exynos5433_pin_banks6), + .eint_gpio_init = exynos_eint_gpio_init, + .suspend = exynos_pinctrl_suspend, + .resume = exynos_pinctrl_resume, + }, { + /* pin-controller instance 7 data */ + .pin_banks = exynos5433_pin_banks7, + .nr_banks = ARRAY_SIZE(exynos5433_pin_banks7), + .eint_gpio_init = exynos_eint_gpio_init, + .suspend = exynos_pinctrl_suspend, + .resume = exynos_pinctrl_resume, + }, { + /* pin-controller instance 8 data */ + .pin_banks = exynos5433_pin_banks8, + .nr_banks = ARRAY_SIZE(exynos5433_pin_banks8), + .eint_gpio_init = exynos_eint_gpio_init, + .suspend = exynos_pinctrl_suspend, + .resume = exynos_pinctrl_resume, + }, { + /* pin-controller instance 9 data */ + .pin_banks = exynos5433_pin_banks9, + .nr_banks = ARRAY_SIZE(exynos5433_pin_banks9), + .eint_gpio_init = exynos_eint_gpio_init, + .suspend = exynos_pinctrl_suspend, + .resume = exynos_pinctrl_resume, + }, +}; + /* pin banks of exynos7 pin-controller - ALIVE */ static const struct samsung_pin_bank_data exynos7_pin_banks0[] __initconst = { EXYNOS_PIN_BANK_EINTW(8, 0x000, "gpa0", 0x00), diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c index ec580af35856..ed165ba2eb2f 100644 --- a/drivers/pinctrl/samsung/pinctrl-samsung.c +++ b/drivers/pinctrl/samsung/pinctrl-samsung.c @@ -1239,6 +1239,8 @@ static const struct of_device_id samsung_pinctrl_dt_match[] = { .data = (void *)exynos5260_pin_ctrl }, { .compatible = "samsung,exynos5420-pinctrl", .data = (void *)exynos5420_pin_ctrl }, + { .compatible = "samsung,exynos5433-pinctrl", + .data = (void *)exynos5433_pin_ctrl }, { .compatible = "samsung,s5pv210-pinctrl", .data = (void *)s5pv210_pin_ctrl }, { .compatible = "samsung,exynos7-pinctrl", diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.h b/drivers/pinctrl/samsung/pinctrl-samsung.h index 1b8c0139d604..c1239ff6157d 100644 --- a/drivers/pinctrl/samsung/pinctrl-samsung.h +++ b/drivers/pinctrl/samsung/pinctrl-samsung.h @@ -271,6 +271,7 @@ extern const struct samsung_pin_ctrl exynos4415_pin_ctrl[]; extern const struct samsung_pin_ctrl exynos5250_pin_ctrl[]; extern const struct samsung_pin_ctrl exynos5260_pin_ctrl[]; extern const struct samsung_pin_ctrl exynos5420_pin_ctrl[]; +extern const struct samsung_pin_ctrl exynos5433_pin_ctrl[]; extern const struct samsung_pin_ctrl exynos7_pin_ctrl[]; extern const struct samsung_pin_ctrl s3c64xx_pin_ctrl[]; extern const struct samsung_pin_ctrl s3c2412_pin_ctrl[]; -- GitLab From 7589f65b32f4465e38cc1d71490ea6f3e170c08c Mon Sep 17 00:00:00 2001 From: Neerav Parikh Date: Thu, 26 Feb 2015 16:12:00 +0000 Subject: [PATCH 02786/11651] i40e: Don't check operational or sync bit for App TLV In CEE mode the firmware does not set the operational status bit of the application TLV status as returned from the "Get CEE DCBX Oper Cfg" AQ command. This occurs whenever a DCBX configuration is changed. This is a workaround to remove the check for the operational and sync bits of the application TLV status till a firmware fix is provided. Change-ID: I1a31ff2fcadcb06feb5b55776a33593afc6ea176 Signed-off-by: Neerav Parikh Acked-by: Shannon Nelson Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_dcb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_dcb.c b/drivers/net/ethernet/intel/i40e/i40e_dcb.c index 3ce43588592d..6e1466756760 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_dcb.c +++ b/drivers/net/ethernet/intel/i40e/i40e_dcb.c @@ -459,7 +459,7 @@ static void i40e_cee_to_dcb_v1_config( sync = (status & I40E_TLV_STATUS_SYNC) ? 1 : 0; oper = (status & I40E_TLV_STATUS_OPER) ? 1 : 0; /* Add APPs if Error is False and Oper/Sync is True */ - if (!err && sync && oper) { + if (!err) { /* CEE operating configuration supports FCoE/iSCSI/FIP only */ dcbcfg->numapps = I40E_CEE_OPER_MAX_APPS; -- GitLab From 5a5a6451acbc197339783fd1ee06fd877ace4bbf Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 4 Mar 2015 15:41:27 +0100 Subject: [PATCH 02787/11651] ARM: at91: debug: fix non MMU debug Linux may be used without MMU on atmel SoCs, fix debug in this configuration. Signed-off-by: Alexandre Belloni Signed-off-by: Nicolas Ferre --- arch/arm/include/debug/at91.S | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/arm/include/debug/at91.S b/arch/arm/include/debug/at91.S index 80a6501b4d50..c3c45e628e33 100644 --- a/arch/arm/include/debug/at91.S +++ b/arch/arm/include/debug/at91.S @@ -18,8 +18,11 @@ #define AT91_DBGU 0xfc00c000 /* SAMA5D4_BASE_USART3 */ #endif -/* Keep in sync with mach-at91/include/mach/hardware.h */ +#ifdef CONFIG_MMU #define AT91_IO_P2V(x) ((x) - 0x01000000) +#else +#define AT91_IO_P2V(x) (x) +#endif #define AT91_DBGU_SR (0x14) /* Status Register */ #define AT91_DBGU_THR (0x1c) /* Transmitter Holding Register */ -- GitLab From b6d7d3f1f39eaf3f31534cc85b2179f1f9897139 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Fri, 1 Aug 2014 09:41:13 +0200 Subject: [PATCH 02788/11651] ARM: at91/dt: sama5d4: rename lcd_clk into lcdc_clk Rename lcd_clk into lcdc_clk to be consistent with sama5d3 clock definitions. Signed-off-by: Boris BREZILLON Signed-off-by: Nicolas Ferre --- arch/arm/boot/dts/sama5d4.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/sama5d4.dtsi b/arch/arm/boot/dts/sama5d4.dtsi index 97d5b9759c07..0ed74e049506 100644 --- a/arch/arm/boot/dts/sama5d4.dtsi +++ b/arch/arm/boot/dts/sama5d4.dtsi @@ -771,7 +771,7 @@ reg = <50>; }; - lcd_clk: lcd_clk { + lcdc_clk: lcdc_clk { #clock-cells = <0>; reg = <51>; }; -- GitLab From db68e71a0e3726573999b1930d20bc30232cea6e Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Fri, 1 Aug 2014 09:41:46 +0200 Subject: [PATCH 02789/11651] ARM: at91/dt: sama5d4: fix lcdck clock definition lcdck takes mck (not smd) as its parent. It is also assigned id 3 and not 4. Signed-off-by: Boris BREZILLON [nicolas.ferre@atmel.com: squashed 2 related patches] Signed-off-by: Nicolas Ferre --- arch/arm/boot/dts/sama5d4.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/sama5d4.dtsi b/arch/arm/boot/dts/sama5d4.dtsi index 0ed74e049506..8240b490825c 100644 --- a/arch/arm/boot/dts/sama5d4.dtsi +++ b/arch/arm/boot/dts/sama5d4.dtsi @@ -462,8 +462,8 @@ lcdck: lcdck { #clock-cells = <0>; - reg = <4>; - clocks = <&smd>; + reg = <3>; + clocks = <&mck>; }; smdck: smdck { -- GitLab From 5957457a2d96e4c9b2fecd40f29cdb3bb841d75e Mon Sep 17 00:00:00 2001 From: Patrice Vilchez Date: Thu, 12 Feb 2015 10:52:13 +0800 Subject: [PATCH 02790/11651] ARM: at91/pm: MOR register KEY was missing Because writing the MOR register requires the PASSWD(0x37), if missed, the write operation will be aborted. Signed-off-by: Patrice Vilchez Acked-by: Alexandre Belloni Signed-off-by: Nicolas Ferre --- arch/arm/mach-at91/pm_slowclock.S | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/mach-at91/pm_slowclock.S b/arch/arm/mach-at91/pm_slowclock.S index a2cc49f96f61..8ab80e579be0 100644 --- a/arch/arm/mach-at91/pm_slowclock.S +++ b/arch/arm/mach-at91/pm_slowclock.S @@ -205,6 +205,7 @@ sdr_sr_done: /* Turn off the main oscillator */ ldr tmp1, [pmc, #AT91_CKGR_MOR] bic tmp1, tmp1, #AT91_PMC_MOSCEN + orr tmp1, tmp1, #AT91_PMC_KEY str tmp1, [pmc, #AT91_CKGR_MOR] /* Wait for interrupt */ @@ -213,6 +214,7 @@ sdr_sr_done: /* Turn on the main oscillator */ ldr tmp1, [pmc, #AT91_CKGR_MOR] orr tmp1, tmp1, #AT91_PMC_MOSCEN + orr tmp1, tmp1, #AT91_PMC_KEY str tmp1, [pmc, #AT91_CKGR_MOR] wait_moscrdy -- GitLab From 4f651a5b0aa561962c97b76bb67ceb57491efabc Mon Sep 17 00:00:00 2001 From: Shannon Nelson Date: Thu, 26 Feb 2015 16:12:26 +0000 Subject: [PATCH 02791/11651] i40e/i40evf: grab NVM devstarter version not image version 0x2A is the NVM version so it has useful data but it is per image version every image can have a different one. 0x18 is the dev starter version which all the images for release will have the same version. Of the two 0x18 is more useful and is what should be displayed. Change-ID: Idf493da13a42ab211e2de0bef287f5de51033cca Signed-off-by: Shannon Nelson Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_adminq.c | 3 ++- drivers/net/ethernet/intel/i40e/i40e_type.h | 2 +- drivers/net/ethernet/intel/i40evf/i40e_type.h | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_adminq.c b/drivers/net/ethernet/intel/i40e/i40e_adminq.c index dc2ed359e945..3e0d20037675 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_adminq.c +++ b/drivers/net/ethernet/intel/i40e/i40e_adminq.c @@ -606,7 +606,8 @@ i40e_status i40e_init_adminq(struct i40e_hw *hw) goto init_adminq_free_arq; /* get the NVM version info */ - i40e_read_nvm_word(hw, I40E_SR_NVM_IMAGE_VERSION, &hw->nvm.version); + i40e_read_nvm_word(hw, I40E_SR_NVM_DEV_STARTER_VERSION, + &hw->nvm.version); i40e_read_nvm_word(hw, I40E_SR_NVM_EETRACK_LO, &eetrack_lo); i40e_read_nvm_word(hw, I40E_SR_NVM_EETRACK_HI, &eetrack_hi); hw->nvm.eetrack = (eetrack_hi << 16) | eetrack_lo; diff --git a/drivers/net/ethernet/intel/i40e/i40e_type.h b/drivers/net/ethernet/intel/i40e/i40e_type.h index 90069396bb28..83032d2c2275 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_type.h +++ b/drivers/net/ethernet/intel/i40e/i40e_type.h @@ -1143,7 +1143,7 @@ struct i40e_hw_port_stats { #define I40E_SR_EMP_MODULE_PTR 0x0F #define I40E_SR_PBA_FLAGS 0x15 #define I40E_SR_PBA_BLOCK_PTR 0x16 -#define I40E_SR_NVM_IMAGE_VERSION 0x18 +#define I40E_SR_NVM_DEV_STARTER_VERSION 0x18 #define I40E_SR_NVM_WAKE_ON_LAN 0x19 #define I40E_SR_ALTERNATE_SAN_MAC_ADDRESS_PTR 0x27 #define I40E_SR_NVM_EETRACK_LO 0x2D diff --git a/drivers/net/ethernet/intel/i40evf/i40e_type.h b/drivers/net/ethernet/intel/i40evf/i40e_type.h index a2693865594a..eba6e4b34f70 100644 --- a/drivers/net/ethernet/intel/i40evf/i40e_type.h +++ b/drivers/net/ethernet/intel/i40evf/i40e_type.h @@ -1116,7 +1116,7 @@ struct i40e_hw_port_stats { /* Checksum and Shadow RAM pointers */ #define I40E_SR_NVM_CONTROL_WORD 0x00 #define I40E_SR_EMP_MODULE_PTR 0x0F -#define I40E_SR_NVM_IMAGE_VERSION 0x18 +#define I40E_SR_NVM_DEV_STARTER_VERSION 0x18 #define I40E_SR_NVM_WAKE_ON_LAN 0x19 #define I40E_SR_ALTERNATE_SAN_MAC_ADDRESS_PTR 0x27 #define I40E_SR_NVM_EETRACK_LO 0x2D -- GitLab From b09f5ec18b16b82f4db8a735e453332db7514275 Mon Sep 17 00:00:00 2001 From: Chen Gang Date: Wed, 4 Mar 2015 05:16:18 +0800 Subject: [PATCH 02792/11651] bcma: Kconfig: Let it depend on PCI bcma also needs PCI, just like IOMEM and DMA, so let it depend on PCI, or will cause building break for allmodconfig under c6x: CC [M] drivers/bcma/driver_pcie2.o drivers/bcma/driver_pcie2.c: In function 'bcma_core_pcie2_up': drivers/bcma/driver_pcie2.c:196:8: error: implicit declaration of function 'pcie_set_readrq' [-Werror=implicit-function-declaration] err = pcie_set_readrq(dev, pcie2->reqsize); ^ Signed-off-by: Chen Gang Signed-off-by: Kalle Valo --- drivers/bcma/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/bcma/Kconfig b/drivers/bcma/Kconfig index 0ee48be23837..8be284edc73c 100644 --- a/drivers/bcma/Kconfig +++ b/drivers/bcma/Kconfig @@ -1,6 +1,6 @@ config BCMA_POSSIBLE bool - depends on HAS_IOMEM && HAS_DMA + depends on HAS_IOMEM && HAS_DMA && PCI default y menu "Broadcom specific AMBA" -- GitLab From ce7ca75176dc3d87c75ea47a7b35a0ac50c7589c Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Thu, 26 Feb 2015 16:12:58 +0000 Subject: [PATCH 02793/11651] i40e: use more portable sign extension Use automatic sign extension by replacing 0xffff... constants with ~(u64)0 or ~(u32)0. Change-ID: I73cab4cd2611795bb12e00f0f24fafaaee07457c Signed-off-by: Jesse Brandeburg Signed-off-by: Kevin Scott Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_lan_hmc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_lan_hmc.c b/drivers/net/ethernet/intel/i40e/i40e_lan_hmc.c index 4627588f4613..0079ad7bcd0e 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_lan_hmc.c +++ b/drivers/net/ethernet/intel/i40e/i40e_lan_hmc.c @@ -856,7 +856,7 @@ static void i40e_write_dword(u8 *hmc_bits, if (ce_info->width < 32) mask = ((u32)1 << ce_info->width) - 1; else - mask = 0xFFFFFFFF; + mask = ~(u32)0; /* don't swizzle the bits until after the mask because the mask bits * will be in a different bit position on big endian machines @@ -908,7 +908,7 @@ static void i40e_write_qword(u8 *hmc_bits, if (ce_info->width < 64) mask = ((u64)1 << ce_info->width) - 1; else - mask = 0xFFFFFFFFFFFFFFFF; + mask = ~(u64)0; /* don't swizzle the bits until after the mask because the mask bits * will be in a different bit position on big endian machines -- GitLab From 096a020a9ef5c947577d3b57199bfc9b7e686b49 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 5 Mar 2015 14:26:37 +0300 Subject: [PATCH 02794/11651] ALSA: msnd: add some missing curly braces There were some curly braces intended here. Signed-off-by: Dan Carpenter Signed-off-by: Takashi Iwai --- sound/isa/msnd/msnd_pinnacle_mixer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/isa/msnd/msnd_pinnacle_mixer.c b/sound/isa/msnd/msnd_pinnacle_mixer.c index 17e49a071af4..b408540798c1 100644 --- a/sound/isa/msnd/msnd_pinnacle_mixer.c +++ b/sound/isa/msnd/msnd_pinnacle_mixer.c @@ -306,11 +306,12 @@ int snd_msndmix_new(struct snd_card *card) spin_lock_init(&chip->mixer_lock); strcpy(card->mixername, "MSND Pinnacle Mixer"); - for (idx = 0; idx < ARRAY_SIZE(snd_msnd_controls); idx++) + for (idx = 0; idx < ARRAY_SIZE(snd_msnd_controls); idx++) { err = snd_ctl_add(card, snd_ctl_new1(snd_msnd_controls + idx, chip)); if (err < 0) return err; + } return 0; } -- GitLab From f44f07cf3910f84b15b2a78c4933d5946bf409cf Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 5 Mar 2015 13:03:28 +0100 Subject: [PATCH 02795/11651] ALSA: line6: Clamp values correctly The usages of clamp() macro in sound/usb/line6/playback.c are just wrong, the low and high values are swapped. Reported-by: Dan Carpenter Signed-off-by: Takashi Iwai --- sound/usb/line6/playback.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/usb/line6/playback.c b/sound/usb/line6/playback.c index 05dee690f487..97ed593f6010 100644 --- a/sound/usb/line6/playback.c +++ b/sound/usb/line6/playback.c @@ -39,7 +39,7 @@ static void change_volume(struct urb *urb_out, int volume[], for (; p < buf_end; ++p) { short pv = le16_to_cpu(*p); int val = (pv * volume[chn & 1]) >> 8; - pv = clamp(val, 0x7fff, -0x8000); + pv = clamp(val, -0x8000, 0x7fff); *p = cpu_to_le16(pv); ++chn; } @@ -54,7 +54,7 @@ static void change_volume(struct urb *urb_out, int volume[], val = p[0] + (p[1] << 8) + ((signed char)p[2] << 16); val = (val * volume[chn & 1]) >> 8; - val = clamp(val, 0x7fffff, -0x800000); + val = clamp(val, -0x800000, 0x7fffff); p[0] = val; p[1] = val >> 8; p[2] = val >> 16; @@ -126,7 +126,7 @@ static void add_monitor_signal(struct urb *urb_out, unsigned char *signal, short pov = le16_to_cpu(*po); short piv = le16_to_cpu(*pi); int val = pov + ((piv * volume) >> 8); - pov = clamp(val, 0x7fff, -0x8000); + pov = clamp(val, -0x8000, 0x7fff); *po = cpu_to_le16(pov); } } -- GitLab From c32ec2a11321978c34296d9a6bd5b0c31a2eb182 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Wed, 4 Mar 2015 12:14:41 +0100 Subject: [PATCH 02796/11651] bcma: make bcma_host_pci_(up|down) calls safe for every config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We were providing declarations but actual code was compiled only with CONFIG_BCMA_HOST_PCI set. This could result in: ERROR: "bcma_host_pci_down" [drivers/net/wireless/brcm80211/brcmsmac/brcmsmac.ko] undefined! ERROR: "bcma_host_pci_up" [drivers/net/wireless/brcm80211/brcmsmac/brcmsmac.ko] undefined! ERROR: "bcma_host_pci_down" [drivers/net/wireless/b43/b43.ko] undefined! ERROR: "bcma_host_pci_up" [drivers/net/wireless/b43/b43.ko] undefined! Reported-by: Arnd Bergmann Signed-off-by: Rafał Miłecki Signed-off-by: Kalle Valo --- include/linux/bcma/bcma.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h index 037620b3f113..44057b45ed32 100644 --- a/include/linux/bcma/bcma.h +++ b/include/linux/bcma/bcma.h @@ -434,8 +434,17 @@ static inline struct bcma_device *bcma_find_core(struct bcma_bus *bus, return bcma_find_core_unit(bus, coreid, 0); } +#ifdef CONFIG_BCMA_HOST_PCI extern void bcma_host_pci_up(struct bcma_bus *bus); extern void bcma_host_pci_down(struct bcma_bus *bus); +#else +static inline void bcma_host_pci_up(struct bcma_bus *bus) +{ +} +static inline void bcma_host_pci_down(struct bcma_bus *bus) +{ +} +#endif extern bool bcma_core_is_enabled(struct bcma_device *core); extern void bcma_core_disable(struct bcma_device *core, u32 flags); -- GitLab From 0a4e699a41f767dff76ca7dc1019b9ca6de3eb42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Wed, 4 Mar 2015 14:24:52 +0100 Subject: [PATCH 02797/11651] bcma: move internal function declarations to private header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These functions are not exported nor used anywhere, so there is no reason to put them in public headers. Also drop unused bcma_chipco_(suspend|resume). Signed-off-by: Rafał Miłecki Signed-off-by: Kalle Valo --- drivers/bcma/bcma_private.h | 41 +++++++++++++++++++++ include/linux/bcma/bcma_driver_chipcommon.h | 11 ------ include/linux/bcma/bcma_driver_gmac_cmn.h | 6 --- include/linux/bcma/bcma_driver_mips.h | 15 -------- include/linux/bcma/bcma_driver_pci.h | 2 - include/linux/bcma/bcma_driver_pcie2.h | 2 - 6 files changed, 41 insertions(+), 36 deletions(-) diff --git a/drivers/bcma/bcma_private.h b/drivers/bcma/bcma_private.h index 29565e30700a..5a1d22489afc 100644 --- a/drivers/bcma/bcma_private.h +++ b/drivers/bcma/bcma_private.h @@ -43,6 +43,9 @@ int bcma_bus_scan(struct bcma_bus *bus); int bcma_sprom_get(struct bcma_bus *bus); /* driver_chipcommon.c */ +void bcma_core_chipcommon_early_init(struct bcma_drv_cc *cc); +void bcma_core_chipcommon_init(struct bcma_drv_cc *cc); +void bcma_chipco_bcm4331_ext_pa_lines_ctl(struct bcma_drv_cc *cc, bool enable); #ifdef CONFIG_BCMA_DRIVER_MIPS void bcma_chipco_serial_init(struct bcma_drv_cc *cc); extern struct platform_device bcma_pflash_dev; @@ -53,6 +56,8 @@ int bcma_core_chipcommon_b_init(struct bcma_drv_cc_b *ccb); void bcma_core_chipcommon_b_free(struct bcma_drv_cc_b *ccb); /* driver_chipcommon_pmu.c */ +void bcma_pmu_early_init(struct bcma_drv_cc *cc); +void bcma_pmu_init(struct bcma_drv_cc *cc); u32 bcma_pmu_get_alp_clock(struct bcma_drv_cc *cc); u32 bcma_pmu_get_cpu_clock(struct bcma_drv_cc *cc); @@ -102,10 +107,13 @@ static inline void __exit bcma_host_soc_unregister_driver(void) /* driver_pci.c */ u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address); +void bcma_core_pci_early_init(struct bcma_drv_pci *pc); +void bcma_core_pci_init(struct bcma_drv_pci *pc); void bcma_core_pci_up(struct bcma_drv_pci *pc); void bcma_core_pci_down(struct bcma_drv_pci *pc); /* driver_pcie2.c */ +void bcma_core_pcie2_init(struct bcma_drv_pcie2 *pcie2); void bcma_core_pcie2_up(struct bcma_drv_pcie2 *pcie2); extern int bcma_chipco_watchdog_register(struct bcma_drv_cc *cc); @@ -123,6 +131,39 @@ static inline void bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc) } #endif /* CONFIG_BCMA_DRIVER_PCI_HOSTMODE */ +/************************************************** + * driver_mips.c + **************************************************/ + +#ifdef CONFIG_BCMA_DRIVER_MIPS +unsigned int bcma_core_mips_irq(struct bcma_device *dev); +void bcma_core_mips_early_init(struct bcma_drv_mips *mcore); +void bcma_core_mips_init(struct bcma_drv_mips *mcore); +#else +static inline unsigned int bcma_core_mips_irq(struct bcma_device *dev) +{ + return 0; +} +static inline void bcma_core_mips_early_init(struct bcma_drv_mips *mcore) +{ +} +static inline void bcma_core_mips_init(struct bcma_drv_mips *mcore) +{ +} +#endif + +/************************************************** + * driver_gmac_cmn.c + **************************************************/ + +#ifdef CONFIG_BCMA_DRIVER_GMAC_CMN +void bcma_core_gmac_cmn_init(struct bcma_drv_gmac_cmn *gc); +#else +static inline void bcma_core_gmac_cmn_init(struct bcma_drv_gmac_cmn *gc) +{ +} +#endif + #ifdef CONFIG_BCMA_DRIVER_GPIO /* driver_gpio.c */ int bcma_gpio_init(struct bcma_drv_cc *cc); diff --git a/include/linux/bcma/bcma_driver_chipcommon.h b/include/linux/bcma/bcma_driver_chipcommon.h index db6fa217f98b..6cceedf65ca2 100644 --- a/include/linux/bcma/bcma_driver_chipcommon.h +++ b/include/linux/bcma/bcma_driver_chipcommon.h @@ -663,14 +663,6 @@ struct bcma_drv_cc_b { #define bcma_cc_maskset32(cc, offset, mask, set) \ bcma_cc_write32(cc, offset, (bcma_cc_read32(cc, offset) & (mask)) | (set)) -extern void bcma_core_chipcommon_init(struct bcma_drv_cc *cc); -extern void bcma_core_chipcommon_early_init(struct bcma_drv_cc *cc); - -extern void bcma_chipco_suspend(struct bcma_drv_cc *cc); -extern void bcma_chipco_resume(struct bcma_drv_cc *cc); - -void bcma_chipco_bcm4331_ext_pa_lines_ctl(struct bcma_drv_cc *cc, bool enable); - extern u32 bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc, u32 ticks); extern u32 bcma_chipco_get_alp_clock(struct bcma_drv_cc *cc); @@ -690,9 +682,6 @@ u32 bcma_chipco_gpio_pullup(struct bcma_drv_cc *cc, u32 mask, u32 value); u32 bcma_chipco_gpio_pulldown(struct bcma_drv_cc *cc, u32 mask, u32 value); /* PMU support */ -extern void bcma_pmu_init(struct bcma_drv_cc *cc); -extern void bcma_pmu_early_init(struct bcma_drv_cc *cc); - extern void bcma_chipco_pll_write(struct bcma_drv_cc *cc, u32 offset, u32 value); extern void bcma_chipco_pll_maskset(struct bcma_drv_cc *cc, u32 offset, diff --git a/include/linux/bcma/bcma_driver_gmac_cmn.h b/include/linux/bcma/bcma_driver_gmac_cmn.h index 4dd1f33e36a2..4354d4ea6713 100644 --- a/include/linux/bcma/bcma_driver_gmac_cmn.h +++ b/include/linux/bcma/bcma_driver_gmac_cmn.h @@ -91,10 +91,4 @@ struct bcma_drv_gmac_cmn { #define gmac_cmn_write16(gc, offset, val) bcma_write16((gc)->core, offset, val) #define gmac_cmn_write32(gc, offset, val) bcma_write32((gc)->core, offset, val) -#ifdef CONFIG_BCMA_DRIVER_GMAC_CMN -extern void bcma_core_gmac_cmn_init(struct bcma_drv_gmac_cmn *gc); -#else -static inline void bcma_core_gmac_cmn_init(struct bcma_drv_gmac_cmn *gc) { } -#endif - #endif /* LINUX_BCMA_DRIVER_GMAC_CMN_H_ */ diff --git a/include/linux/bcma/bcma_driver_mips.h b/include/linux/bcma/bcma_driver_mips.h index 0b3b32aeeb8a..8eea7f9e33b4 100644 --- a/include/linux/bcma/bcma_driver_mips.h +++ b/include/linux/bcma/bcma_driver_mips.h @@ -39,21 +39,6 @@ struct bcma_drv_mips { u8 early_setup_done:1; }; -#ifdef CONFIG_BCMA_DRIVER_MIPS -extern void bcma_core_mips_init(struct bcma_drv_mips *mcore); -extern void bcma_core_mips_early_init(struct bcma_drv_mips *mcore); - -extern unsigned int bcma_core_mips_irq(struct bcma_device *dev); -#else -static inline void bcma_core_mips_init(struct bcma_drv_mips *mcore) { } -static inline void bcma_core_mips_early_init(struct bcma_drv_mips *mcore) { } - -static inline unsigned int bcma_core_mips_irq(struct bcma_device *dev) -{ - return 0; -} -#endif - extern u32 bcma_cpu_clock(struct bcma_drv_mips *mcore); #endif /* LINUX_BCMA_DRIVER_MIPS_H_ */ diff --git a/include/linux/bcma/bcma_driver_pci.h b/include/linux/bcma/bcma_driver_pci.h index 6b8bca67851f..8e90004fdfd7 100644 --- a/include/linux/bcma/bcma_driver_pci.h +++ b/include/linux/bcma/bcma_driver_pci.h @@ -238,8 +238,6 @@ struct bcma_drv_pci { #define pcicore_write16(pc, offset, val) bcma_write16((pc)->core, offset, val) #define pcicore_write32(pc, offset, val) bcma_write32((pc)->core, offset, val) -extern void bcma_core_pci_early_init(struct bcma_drv_pci *pc); -extern void bcma_core_pci_init(struct bcma_drv_pci *pc); extern int bcma_core_pci_irq_ctl(struct bcma_bus *bus, struct bcma_device *core, bool enable); extern void bcma_core_pci_power_save(struct bcma_bus *bus, bool up); diff --git a/include/linux/bcma/bcma_driver_pcie2.h b/include/linux/bcma/bcma_driver_pcie2.h index d8c43294c527..31e6d17ab798 100644 --- a/include/linux/bcma/bcma_driver_pcie2.h +++ b/include/linux/bcma/bcma_driver_pcie2.h @@ -155,6 +155,4 @@ struct bcma_drv_pcie2 { #define pcie2_set32(pcie2, offset, set) bcma_set32((pcie2)->core, offset, set) #define pcie2_mask32(pcie2, offset, mask) bcma_mask32((pcie2)->core, offset, mask) -void bcma_core_pcie2_init(struct bcma_drv_pcie2 *pcie2); - #endif /* LINUX_BCMA_DRIVER_PCIE2_H_ */ -- GitLab From 1ca2760fb2c13959fcba794695cd5b306cbfa6a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Wed, 4 Mar 2015 23:07:05 +0100 Subject: [PATCH 02798/11651] bcma: prepare Kconfig symbol for PCI driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Driver for PCIe core requires PCI to be enabled, however we shouldn't require it for the whole bus. Someone may be not interested in extra PCI devices and what's more there are SoCs without any PCI at all (like BCM5356C0, BCM5357*, BCM47186B0). For more details see Kconfig "help". Please note this patch doesn't allow disabling PCI drivers yet, as it requires more work on calls to bcma_core_pci_* functions. Signed-off-by: Rafał Miłecki Signed-off-by: Kalle Valo --- drivers/bcma/Kconfig | 17 +++++++++++++++++ drivers/bcma/Makefile | 4 ++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/drivers/bcma/Kconfig b/drivers/bcma/Kconfig index 8be284edc73c..9be17d3431bb 100644 --- a/drivers/bcma/Kconfig +++ b/drivers/bcma/Kconfig @@ -26,6 +26,7 @@ config BCMA_HOST_PCI_POSSIBLE config BCMA_HOST_PCI bool "Support for BCMA on PCI-host bus" depends on BCMA_HOST_PCI_POSSIBLE + select BCMA_DRIVER_PCI default y config BCMA_DRIVER_PCI_HOSTMODE @@ -44,6 +45,22 @@ config BCMA_HOST_SOC If unsure, say N +# TODO: make it depend on PCI when ready +config BCMA_DRIVER_PCI + bool + default y + help + BCMA bus may have many versions of PCIe core. This driver + supports: + 1) PCIe core working in clientmode + 2) PCIe Gen 2 clientmode core + + In general PCIe (Gen 2) clientmode core is required on PCIe + hosted buses. It's responsible for initialization and basic + hardware management. + This driver is also prerequisite for a hostmode PCIe core + support. + config BCMA_DRIVER_MIPS bool "BCMA Broadcom MIPS core driver" depends on BCMA && MIPS diff --git a/drivers/bcma/Makefile b/drivers/bcma/Makefile index 838b4b9d352f..f32af9b76bcd 100644 --- a/drivers/bcma/Makefile +++ b/drivers/bcma/Makefile @@ -3,8 +3,8 @@ bcma-y += driver_chipcommon.o driver_chipcommon_pmu.o bcma-y += driver_chipcommon_b.o bcma-$(CONFIG_BCMA_SFLASH) += driver_chipcommon_sflash.o bcma-$(CONFIG_BCMA_NFLASH) += driver_chipcommon_nflash.o -bcma-y += driver_pci.o -bcma-y += driver_pcie2.o +bcma-$(CONFIG_BCMA_DRIVER_PCI) += driver_pci.o +bcma-$(CONFIG_BCMA_DRIVER_PCI) += driver_pcie2.o bcma-$(CONFIG_BCMA_DRIVER_PCI_HOSTMODE) += driver_pci_host.o bcma-$(CONFIG_BCMA_DRIVER_MIPS) += driver_mips.o bcma-$(CONFIG_BCMA_DRIVER_GMAC_CMN) += driver_gmac_cmn.o -- GitLab From 4cd4b50cc2429294c23a1998c33fdfd804db0f37 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 5 Mar 2015 13:43:15 +0200 Subject: [PATCH 02799/11651] iwlwifi: mvm: BT Coex - fix a NULL pointer exception The commit below introduced an unsafe dereference of mvmvif->phy_ctxt. It can be NULL even if we hold the mutex. We can be handling a BT Coex notification while the vif has already been unassigned. This can happen since the BT Coex notification is hanled asynchronuously: we can have started to handle the BT Coex notification trying to acquire the mutex while the unassign flow already got it. The BT Coex notification handling will wait for the mutext. I'll get it later, but then mvmvif->phy_ctxt will be NULL. Panic log: BUG: unable to handle kernel NULL pointer dereference at (null) IP: [] iwl_mvm_bt_notif_iterator+0x9d/0x340 [iwlmvm] *pdpt = 0000000000000000 *pde = f000eef300000007 Oops: 0000 [#1] SMP Workqueue: events iwl_mvm_async_handlers_wk [iwlmvm] task: ed719b20 ti: ec03e000 task.ti: ec03e000 EIP: 0060:[] EFLAGS: 00010202 CPU: 2 EIP is at iwl_mvm_bt_notif_iterator+0x9d/0x340 [iwlmvm] EAX: 00000000 EBX: f6d3cb70 ECX: f6d3cb70 EDX: 00000000 ESI: ec03fe40 EDI: efeb8810 EBP: ec03fdf0 ESP: ec03fdac DS: 007b ES: 007b FS: 00d8 GS: 0000 SS: 0068 CR0: 80050033 CR2: 00000000 CR3: 01a1a000 CR4: 001407f0 Stack: f743ca80 f744a404 ec03fdcc c10e3952 00003aba f743ca80 00000246 f743ca80 00000246 00000000 00000001 00000000 ebd45ff6 ebd458a4 f6d3c500 ebd45578 ebd44b01 ec03fe18 f99e1bc2 00000002 ebd44bc0 f9851770 00000000 f6d3c500 Call Trace: [] ? ring_buffer_unlock_commit+0xa2/0xd0 [] __iterate_interfaces+0x82/0x110 [mac80211] [] ? iwl_mvm_bt_coex_reduced_txp+0x140/0x140 [iwlmvm] [] ieee80211_iterate_active_interfaces_atomic+0x1a/0x20 [mac80211] [] iwl_mvm_bt_coex_notif_handle+0x77/0x280 [iwlmvm] [] iwl_mvm_rx_bt_coex_notif_old+0x211/0x220 [iwlmvm] [] iwl_mvm_rx_bt_coex_notif+0x19b/0x1b0 [iwlmvm] [] iwl_mvm_async_handlers_wk+0x7f/0xe0 [iwlmvm] CC: [3.19+] Fixes: 123f515635b1 ("iwlwifi: mvm: BT Coex - add support for TTC / RRC") Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/coex.c | 3 ++- drivers/net/wireless/iwlwifi/mvm/coex_legacy.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/coex.c b/drivers/net/wireless/iwlwifi/mvm/coex.c index 1ec4d55155f7..7810c41cf9a7 100644 --- a/drivers/net/wireless/iwlwifi/mvm/coex.c +++ b/drivers/net/wireless/iwlwifi/mvm/coex.c @@ -793,7 +793,8 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac, if (!vif->bss_conf.assoc) smps_mode = IEEE80211_SMPS_AUTOMATIC; - if (IWL_COEX_IS_RRC_ON(mvm->last_bt_notif.ttc_rrc_status, + if (mvmvif->phy_ctxt && + IWL_COEX_IS_RRC_ON(mvm->last_bt_notif.ttc_rrc_status, mvmvif->phy_ctxt->id)) smps_mode = IEEE80211_SMPS_AUTOMATIC; diff --git a/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c b/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c index d530ef3da107..542ee74f290a 100644 --- a/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c +++ b/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c @@ -832,7 +832,8 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac, if (!vif->bss_conf.assoc) smps_mode = IEEE80211_SMPS_AUTOMATIC; - if (data->notif->rrc_enabled & BIT(mvmvif->phy_ctxt->id)) + if (mvmvif->phy_ctxt && + data->notif->rrc_enabled & BIT(mvmvif->phy_ctxt->id)) smps_mode = IEEE80211_SMPS_AUTOMATIC; IWL_DEBUG_COEX(data->mvm, -- GitLab From 6c8ca30eec7b6f8eb09c957e8dcced89e5f100c7 Mon Sep 17 00:00:00 2001 From: Nicolin Chen Date: Wed, 4 Mar 2015 21:05:04 -0800 Subject: [PATCH 02800/11651] ASoC: fsl_ssi: Don't try to round-up for PM divisor calculation According to i.MX6 Series Reference Manual, the formula to calculate the sys clock is sysclk rate = bclk rate * (div2 + 1) * (7 * psr + 1) * (pm + 1) * 2 Commit aafa85e71a75 ("ASoC: fsl_ssi: Add DAI master mode support for SSI on i.MX series") added the divisor calculation which relies on the clk_round_rate(). However, at that time, clk_round_rate() didn't provide closest clock rates for some cases because it might not use a correct rounding policy. So using the original formula (pm + 1) for PM divisor was not able to give us a desired clock rate. And then we used (pm + 2) to do the trick. However, the clk-divider driver has been refined a lot since commit b11d282dbea2 ("clk: divider: fix rate calculation for fractional rates") Now using (pm + 2) trick would result an incorrect clock rate. So this patch fixes the problem by removing the useless trick. Reported-by: Stephane Cerveau Signed-off-by: Nicolin Chen Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_ssi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 134388f7d1b8..7eebc0889c9d 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -603,7 +603,7 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream *substream, factor = (div2 + 1) * (7 * psr + 1) * 2; for (i = 0; i < 255; i++) { - tmprate = freq * factor * (i + 2); + tmprate = freq * factor * (i + 1); if (baudclk_is_used) clkrate = clk_get_rate(ssi_private->baudclk); -- GitLab From 9a660eeae2779cea72ef306b721273a0e951e7d7 Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Thu, 26 Feb 2015 16:13:22 +0000 Subject: [PATCH 02801/11651] i40e: fix XPS mask when resetting During resets (possibly caused by a Tx hang) the driver would accidentally clear the XPS mask for all queues back to 0. This caused higher CPU utilization and had some other performance impacts for transmit tests. Change-ID: I95f112432c9e643a153eaa31cd28cdcbfdd01831 Signed-off-by: Jesse Brandeburg Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_main.c | 22 ++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 620dd237cce4..a287cc84597a 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -2399,20 +2399,20 @@ static void i40e_config_xps_tx_ring(struct i40e_ring *ring) struct i40e_vsi *vsi = ring->vsi; cpumask_var_t mask; - if (ring->q_vector && ring->netdev) { - /* Single TC mode enable XPS */ - if (vsi->tc_config.numtc <= 1 && - !test_and_set_bit(__I40E_TX_XPS_INIT_DONE, &ring->state)) { + if (!ring->q_vector || !ring->netdev) + return; + + /* Single TC mode enable XPS */ + if (vsi->tc_config.numtc <= 1) { + if (!test_and_set_bit(__I40E_TX_XPS_INIT_DONE, &ring->state)) netif_set_xps_queue(ring->netdev, &ring->q_vector->affinity_mask, ring->queue_index); - } else if (alloc_cpumask_var(&mask, GFP_KERNEL)) { - /* Disable XPS to allow selection based on TC */ - bitmap_zero(cpumask_bits(mask), nr_cpumask_bits); - netif_set_xps_queue(ring->netdev, mask, - ring->queue_index); - free_cpumask_var(mask); - } + } else if (alloc_cpumask_var(&mask, GFP_KERNEL)) { + /* Disable XPS to allow selection based on TC */ + bitmap_zero(cpumask_bits(mask), nr_cpumask_bits); + netif_set_xps_queue(ring->netdev, mask, ring->queue_index); + free_cpumask_var(mask); } } -- GitLab From 8603e1b30027f943cc9c1eef2b291d42c3347af1 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 5 Mar 2015 08:04:13 -0500 Subject: [PATCH 02802/11651] workqueue: fix hang involving racing cancel[_delayed]_work_sync()'s for PREEMPT_NONE cancel[_delayed]_work_sync() are implemented using __cancel_work_timer() which grabs the PENDING bit using try_to_grab_pending() and then flushes the work item with PENDING set to prevent the on-going execution of the work item from requeueing itself. try_to_grab_pending() can always grab PENDING bit without blocking except when someone else is doing the above flushing during cancelation. In that case, try_to_grab_pending() returns -ENOENT. In this case, __cancel_work_timer() currently invokes flush_work(). The assumption is that the completion of the work item is what the other canceling task would be waiting for too and thus waiting for the same condition and retrying should allow forward progress without excessive busy looping Unfortunately, this doesn't work if preemption is disabled or the latter task has real time priority. Let's say task A just got woken up from flush_work() by the completion of the target work item. If, before task A starts executing, task B gets scheduled and invokes __cancel_work_timer() on the same work item, its try_to_grab_pending() will return -ENOENT as the work item is still being canceled by task A and flush_work() will also immediately return false as the work item is no longer executing. This puts task B in a busy loop possibly preventing task A from executing and clearing the canceling state on the work item leading to a hang. task A task B worker executing work __cancel_work_timer() try_to_grab_pending() set work CANCELING flush_work() block for work completion completion, wakes up A __cancel_work_timer() while (forever) { try_to_grab_pending() -ENOENT as work is being canceled flush_work() false as work is no longer executing } This patch removes the possible hang by updating __cancel_work_timer() to explicitly wait for clearing of CANCELING rather than invoking flush_work() after try_to_grab_pending() fails with -ENOENT. Link: http://lkml.kernel.org/g/20150206171156.GA8942@axis.com v3: bit_waitqueue() can't be used for work items defined in vmalloc area. Switched to custom wake function which matches the target work item and exclusive wait and wakeup. v2: v1 used wake_up() on bit_waitqueue() which leads to NULL deref if the target bit waitqueue has wait_bit_queue's on it. Use DEFINE_WAIT_BIT() and __wake_up_bit() instead. Reported by Tomeu Vizoso. Signed-off-by: Tejun Heo Reported-by: Rabin Vincent Cc: Tomeu Vizoso Cc: stable@vger.kernel.org Tested-by: Jesper Nilsson Tested-by: Rabin Vincent --- include/linux/workqueue.h | 3 ++- kernel/workqueue.c | 56 ++++++++++++++++++++++++++++++++++++--- 2 files changed, 54 insertions(+), 5 deletions(-) diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h index 74db135f9957..f597846ff605 100644 --- a/include/linux/workqueue.h +++ b/include/linux/workqueue.h @@ -70,7 +70,8 @@ enum { /* data contains off-queue information when !WORK_STRUCT_PWQ */ WORK_OFFQ_FLAG_BASE = WORK_STRUCT_COLOR_SHIFT, - WORK_OFFQ_CANCELING = (1 << WORK_OFFQ_FLAG_BASE), + __WORK_OFFQ_CANCELING = WORK_OFFQ_FLAG_BASE, + WORK_OFFQ_CANCELING = (1 << __WORK_OFFQ_CANCELING), /* * When a work item is off queue, its high bits point to the last diff --git a/kernel/workqueue.c b/kernel/workqueue.c index f28849394791..41ff75b478c6 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -2728,19 +2728,57 @@ bool flush_work(struct work_struct *work) } EXPORT_SYMBOL_GPL(flush_work); +struct cwt_wait { + wait_queue_t wait; + struct work_struct *work; +}; + +static int cwt_wakefn(wait_queue_t *wait, unsigned mode, int sync, void *key) +{ + struct cwt_wait *cwait = container_of(wait, struct cwt_wait, wait); + + if (cwait->work != key) + return 0; + return autoremove_wake_function(wait, mode, sync, key); +} + static bool __cancel_work_timer(struct work_struct *work, bool is_dwork) { + static DECLARE_WAIT_QUEUE_HEAD(cancel_waitq); unsigned long flags; int ret; do { ret = try_to_grab_pending(work, is_dwork, &flags); /* - * If someone else is canceling, wait for the same event it - * would be waiting for before retrying. + * If someone else is already canceling, wait for it to + * finish. flush_work() doesn't work for PREEMPT_NONE + * because we may get scheduled between @work's completion + * and the other canceling task resuming and clearing + * CANCELING - flush_work() will return false immediately + * as @work is no longer busy, try_to_grab_pending() will + * return -ENOENT as @work is still being canceled and the + * other canceling task won't be able to clear CANCELING as + * we're hogging the CPU. + * + * Let's wait for completion using a waitqueue. As this + * may lead to the thundering herd problem, use a custom + * wake function which matches @work along with exclusive + * wait and wakeup. */ - if (unlikely(ret == -ENOENT)) - flush_work(work); + if (unlikely(ret == -ENOENT)) { + struct cwt_wait cwait; + + init_wait(&cwait.wait); + cwait.wait.func = cwt_wakefn; + cwait.work = work; + + prepare_to_wait_exclusive(&cancel_waitq, &cwait.wait, + TASK_UNINTERRUPTIBLE); + if (work_is_canceling(work)) + schedule(); + finish_wait(&cancel_waitq, &cwait.wait); + } } while (unlikely(ret < 0)); /* tell other tasks trying to grab @work to back off */ @@ -2749,6 +2787,16 @@ static bool __cancel_work_timer(struct work_struct *work, bool is_dwork) flush_work(work); clear_work_data(work); + + /* + * Paired with prepare_to_wait() above so that either + * waitqueue_active() is visible here or !work_is_canceling() is + * visible there. + */ + smp_mb(); + if (waitqueue_active(&cancel_waitq)) + __wake_up(&cancel_waitq, TASK_NORMAL, 1, work); + return ret; } -- GitLab From 695df2132cfe3782784d4b0e1f0027168c1830ca Mon Sep 17 00:00:00 2001 From: Zefan Li Date: Wed, 4 Mar 2015 17:09:33 +0800 Subject: [PATCH 02803/11651] cpuset: initialize cpuset a bit early Now we call ss->bind() in cgroup_init(), so cgroup_init() will call cpuset_bind() and then the latter will access top_cpuset's cpumask, which is NULL, because cpuset_init() is called after cgroup_init() The simplest fix is to swap cgroup_init() and cpuset_init(). Cc: Vladimir Davydov Fixes: 295458e67284 ("cgroup: call cgroup_subsys->bind on cgroup subsys initialization") Reported by: Ming Lei Signed-off-by: Zefan Li Signed-off-by: Tejun Heo Acked-by: Vladimir Davydov --- init/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/init/main.c b/init/main.c index 6f0f1c5ff8cc..4a6974e67839 100644 --- a/init/main.c +++ b/init/main.c @@ -654,8 +654,8 @@ asmlinkage __visible void __init start_kernel(void) page_writeback_init(); proc_root_init(); nsfs_init(); - cgroup_init(); cpuset_init(); + cgroup_init(); taskstats_init_early(); delayacct_init(); -- GitLab From 088c4ee370ecc5c7ce2681e75b78429825c860bf Mon Sep 17 00:00:00 2001 From: Catherine Sullivan Date: Thu, 26 Feb 2015 16:14:12 +0000 Subject: [PATCH 02804/11651] i40e: Reassign incorrect PHY type to fix a FW bug Some FW versions are incorrectly reporting a breakout cable as PHY type 0x3 when it should be 0x16 (I40E_PHY_TYPE_10GBASE_SFPP_CU). If we get this value back from FW and the version is < 4.40, reassign it to I40E_PHY_TYPE_10GBASE_SFPP_CU. Change-ID: Ibb41a0e3cd2c0753744e8553959240df6ed13ae8 Signed-off-by: Catherine Sullivan Tested-by: Jim Young Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_common.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c index cc10303c388d..0bfc82b9e921 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_common.c +++ b/drivers/net/ethernet/intel/i40e/i40e_common.c @@ -1481,6 +1481,10 @@ i40e_status i40e_aq_get_link_info(struct i40e_hw *hw, else hw_link_info->lse_enable = false; + if ((hw->aq.fw_maj_ver < 4 || (hw->aq.fw_maj_ver == 4 && + hw->aq.fw_min_ver < 40)) && hw_link_info->phy_type == 0xE) + hw_link_info->phy_type = I40E_PHY_TYPE_10GBASE_SFPP_CU; + /* save link status information */ if (link) *link = *hw_link_info; -- GitLab From 5b86c5cf7536e383b301bf3322087b4bd4f6547b Mon Sep 17 00:00:00 2001 From: Greg Rose Date: Thu, 26 Feb 2015 16:14:35 +0000 Subject: [PATCH 02805/11651] i40e: Fix ethtool offline test If the system administrator is requesting an offline diagnostic test using 'ethtool -t' then we should, you know, actually take the device offline before doing the testing. Change-ID: I6afa1cbfcc821c9ab6e6f47ed4d8dc2d8dd20e82 Signed-off-by: Greg Rose Tested-by: Jim Young Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c index 7413b0e429c8..415aebceed9a 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c @@ -1530,6 +1530,7 @@ static void i40e_diag_test(struct net_device *netdev, struct ethtool_test *eth_test, u64 *data) { struct i40e_netdev_priv *np = netdev_priv(netdev); + bool if_running = netif_running(netdev); struct i40e_pf *pf = np->vsi->back; if (eth_test->flags == ETH_TEST_FL_OFFLINE) { @@ -1537,6 +1538,12 @@ static void i40e_diag_test(struct net_device *netdev, netif_info(pf, drv, netdev, "offline testing starting\n"); set_bit(__I40E_TESTING, &pf->state); + /* If the device is online then take it offline */ + if (if_running) + /* indicate we're in test mode */ + dev_close(netdev); + else + i40e_do_reset(pf, (1 << __I40E_PF_RESET_REQUESTED)); /* Link test performed before hardware reset * so autoneg doesn't interfere with test result @@ -1559,6 +1566,9 @@ static void i40e_diag_test(struct net_device *netdev, clear_bit(__I40E_TESTING, &pf->state); i40e_do_reset(pf, (1 << __I40E_PF_RESET_REQUESTED)); + + if (if_running) + dev_open(netdev); } else { /* Online tests */ netif_info(pf, drv, netdev, "online testing starting\n"); -- GitLab From 7b8f10da3bf1056546133c9f54f49ce389fd95ab Mon Sep 17 00:00:00 2001 From: Yongbae Park Date: Tue, 3 Mar 2015 19:46:49 +0900 Subject: [PATCH 02806/11651] clocksource: efm32: Fix a NULL pointer dereference MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The initialisation of the efm32 clocksource first sets up the irq and only after that initialises the data needed for irq handling. In case this initialisation is delayed the irq handler would dereference a NULL pointer. I'm not aware of anything that could delay the process in such a way, but it's better to be safe than sorry, so setup the irq only when the clock event device is ready. Cc: stable@vger.kernel.org Acked-by: Uwe Kleine-König Signed-off-by: Yongbae Park Signed-off-by: Daniel Lezcano --- drivers/clocksource/time-efm32.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clocksource/time-efm32.c b/drivers/clocksource/time-efm32.c index bba62f9deefb..ec57ba2bbd87 100644 --- a/drivers/clocksource/time-efm32.c +++ b/drivers/clocksource/time-efm32.c @@ -225,12 +225,12 @@ static int __init efm32_clockevent_init(struct device_node *np) clock_event_ddata.base = base; clock_event_ddata.periodic_top = DIV_ROUND_CLOSEST(rate, 1024 * HZ); - setup_irq(irq, &efm32_clock_event_irq); - clockevents_config_and_register(&clock_event_ddata.evtdev, DIV_ROUND_CLOSEST(rate, 1024), 0xf, 0xffff); + setup_irq(irq, &efm32_clock_event_irq); + return 0; err_get_irq: -- GitLab From 1096be084ac59927158ce80ff1d31c33eed0e565 Mon Sep 17 00:00:00 2001 From: Yongbae Park Date: Tue, 3 Mar 2015 13:05:48 +0900 Subject: [PATCH 02807/11651] clockevents: sun5i: Fix setup_irq init sequence The interrupt is enabled before the handler is set. Even this bug did not appear, it is potentially dangerous as it can lead to a NULL pointer dereference. Fix the error by enabling the interrupt after clockevents_config_and_register() is called. Cc: stable@vger.kernel.org Signed-off-by: Yongbae Park Signed-off-by: Daniel Lezcano --- drivers/clocksource/timer-sun5i.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/clocksource/timer-sun5i.c b/drivers/clocksource/timer-sun5i.c index 02268448dc85..5dcbf90b8015 100644 --- a/drivers/clocksource/timer-sun5i.c +++ b/drivers/clocksource/timer-sun5i.c @@ -178,10 +178,6 @@ static void __init sun5i_timer_init(struct device_node *node) ticks_per_jiffy = DIV_ROUND_UP(rate, HZ); - ret = setup_irq(irq, &sun5i_timer_irq); - if (ret) - pr_warn("failed to setup irq %d\n", irq); - /* Enable timer0 interrupt */ val = readl(timer_base + TIMER_IRQ_EN_REG); writel(val | TIMER_IRQ_EN(0), timer_base + TIMER_IRQ_EN_REG); @@ -191,6 +187,10 @@ static void __init sun5i_timer_init(struct device_node *node) clockevents_config_and_register(&sun5i_clockevent, rate, TIMER_SYNC_TICKS, 0xffffffff); + + ret = setup_irq(irq, &sun5i_timer_irq); + if (ret) + pr_warn("failed to setup irq %d\n", irq); } CLOCKSOURCE_OF_DECLARE(sun5i_a13, "allwinner,sun5i-a13-hstimer", sun5i_timer_init); -- GitLab From 180204c79ffc5c525c51a209291c323b127fb32e Mon Sep 17 00:00:00 2001 From: Catherine Sullivan Date: Thu, 26 Feb 2015 16:14:58 +0000 Subject: [PATCH 02808/11651] i40e: Add AOC PHY types to case statements Add the 10G and 40G AOC PHY types to the case statement in get_media_type and ethtool get_settings so that the correct information gets reported back to the user. Change-ID: I1b4849d22199a9acf7c8807166d0317c1faad375 Signed-off-by: Catherine Sullivan Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_common.c | 2 ++ drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c index 0bfc82b9e921..99af78835d5d 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_common.c +++ b/drivers/net/ethernet/intel/i40e/i40e_common.c @@ -834,6 +834,8 @@ static enum i40e_media_type i40e_get_media_type(struct i40e_hw *hw) case I40E_PHY_TYPE_10GBASE_CR1: case I40E_PHY_TYPE_40GBASE_CR4: case I40E_PHY_TYPE_10GBASE_SFPP_CU: + case I40E_PHY_TYPE_40GBASE_AOC: + case I40E_PHY_TYPE_10GBASE_AOC: media = I40E_MEDIA_TYPE_DA; break; case I40E_PHY_TYPE_1000BASE_KX: diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c index 415aebceed9a..764305e9d95a 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c @@ -259,6 +259,7 @@ static void i40e_get_settings_link_up(struct i40e_hw *hw, break; case I40E_PHY_TYPE_XLAUI: case I40E_PHY_TYPE_XLPPI: + case I40E_PHY_TYPE_40GBASE_AOC: ecmd->supported = SUPPORTED_40000baseCR4_Full; break; case I40E_PHY_TYPE_40GBASE_KR4: @@ -328,6 +329,7 @@ static void i40e_get_settings_link_up(struct i40e_hw *hw, case I40E_PHY_TYPE_XFI: case I40E_PHY_TYPE_SFI: case I40E_PHY_TYPE_10GBASE_SFPP_CU: + case I40E_PHY_TYPE_10GBASE_AOC: ecmd->supported = SUPPORTED_10000baseT_Full; break; case I40E_PHY_TYPE_SGMII: -- GitLab From 5bbc330100285e56871a64d4148b9d3a1ac0f297 Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Thu, 26 Feb 2015 16:15:20 +0000 Subject: [PATCH 02809/11651] i40e/i40evf: Clean up some formatting and other things Fix some double blank lines and un-split a function declaration that all fits on one line. Also make i40e_get_priv_flags static. Change-ID: I11b5d25d1153a06b286d0d2f5d916d7727c58e4a Signed-off-by: Jesse Brandeburg Signed-off-by: Neerav Parikh Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_common.c | 1 - drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 2 +- drivers/net/ethernet/intel/i40e/i40e_fcoe.c | 2 -- drivers/net/ethernet/intel/i40e/i40e_fcoe.h | 1 - drivers/net/ethernet/intel/i40e/i40e_main.c | 1 - drivers/net/ethernet/intel/i40evf/i40e_common.c | 1 - drivers/net/ethernet/intel/i40evf/i40e_prototype.h | 3 +-- drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c | 1 - 8 files changed, 2 insertions(+), 10 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c index 99af78835d5d..10f9451339ed 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_common.c +++ b/drivers/net/ethernet/intel/i40e/i40e_common.c @@ -541,7 +541,6 @@ struct i40e_rx_ptype_decoded i40e_ptype_lookup[] = { I40E_PTT_UNUSED_ENTRY(255) }; - /** * i40e_init_shared_code - Initialize the shared code * @hw: pointer to hardware structure diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c index 764305e9d95a..e045de133251 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c @@ -2380,7 +2380,7 @@ static int i40e_set_channels(struct net_device *dev, * * Returns a u32 bitmap of flags. **/ -u32 i40e_get_priv_flags(struct net_device *dev) +static u32 i40e_get_priv_flags(struct net_device *dev) { struct i40e_netdev_priv *np = netdev_priv(dev); struct i40e_vsi *vsi = np->vsi; diff --git a/drivers/net/ethernet/intel/i40e/i40e_fcoe.c b/drivers/net/ethernet/intel/i40e/i40e_fcoe.c index 05d883e4d4ac..0357b31e4a5c 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_fcoe.c +++ b/drivers/net/ethernet/intel/i40e/i40e_fcoe.c @@ -24,7 +24,6 @@ * ******************************************************************************/ - #include #include #include @@ -1447,7 +1446,6 @@ static int i40e_fcoe_set_features(struct net_device *netdev, return 0; } - static const struct net_device_ops i40e_fcoe_netdev_ops = { .ndo_open = i40e_open, .ndo_stop = i40e_close, diff --git a/drivers/net/ethernet/intel/i40e/i40e_fcoe.h b/drivers/net/ethernet/intel/i40e/i40e_fcoe.h index 21e0f582031c..0d49e2d15d40 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_fcoe.h +++ b/drivers/net/ethernet/intel/i40e/i40e_fcoe.h @@ -37,7 +37,6 @@ #define I40E_FILTER_CONTEXT_DESC(R, i) \ (&(((struct i40e_fcoe_filter_context_desc *)((R)->desc))[i])) - /* receive queue descriptor filter status for FCoE */ #define I40E_RX_DESC_FLTSTAT_FCMASK 0x3 #define I40E_RX_DESC_FLTSTAT_NOMTCH 0x0 /* no ddp context match */ diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index a287cc84597a..02b57c3aa4bb 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -9586,7 +9586,6 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent) dev_info(&pdev->dev, "The driver for the device detected an older version of the NVM image than expected. Please update the NVM image.\n"); - i40e_verify_eeprom(pf); /* Rev 0 hardware was never productized */ diff --git a/drivers/net/ethernet/intel/i40evf/i40e_common.c b/drivers/net/ethernet/intel/i40evf/i40e_common.c index 50b0ee54fc06..0335b3f08cc1 100644 --- a/drivers/net/ethernet/intel/i40evf/i40e_common.c +++ b/drivers/net/ethernet/intel/i40evf/i40e_common.c @@ -542,7 +542,6 @@ struct i40e_rx_ptype_decoded i40evf_ptype_lookup[] = { I40E_PTT_UNUSED_ENTRY(255) }; - /** * i40e_aq_send_msg_to_pf * @hw: pointer to the hardware structure diff --git a/drivers/net/ethernet/intel/i40evf/i40e_prototype.h b/drivers/net/ethernet/intel/i40evf/i40e_prototype.h index 9173834825ac..58e37a44b80a 100644 --- a/drivers/net/ethernet/intel/i40evf/i40e_prototype.h +++ b/drivers/net/ethernet/intel/i40evf/i40e_prototype.h @@ -59,8 +59,7 @@ void i40evf_debug_aq(struct i40e_hw *hw, enum i40e_debug_mask mask, void i40e_idle_aq(struct i40e_hw *hw); void i40evf_resume_aq(struct i40e_hw *hw); bool i40evf_check_asq_alive(struct i40e_hw *hw); -i40e_status i40evf_aq_queue_shutdown(struct i40e_hw *hw, - bool unloading); +i40e_status i40evf_aq_queue_shutdown(struct i40e_hw *hw, bool unloading); i40e_status i40e_set_mac_type(struct i40e_hw *hw); diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c b/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c index 681a5d4b4f6a..b68b73163311 100644 --- a/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c +++ b/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c @@ -29,7 +29,6 @@ #include - struct i40evf_stats { char stat_string[ETH_GSTRING_LEN]; int stat_offset; -- GitLab From 232f47060ada14c4b77ce1f21eec9332b9234a87 Mon Sep 17 00:00:00 2001 From: Anjali Singhai Date: Thu, 26 Feb 2015 16:15:39 +0000 Subject: [PATCH 02810/11651] i40e: Ioremap changes For future device support we do not want to map the whole CSR space since some of it is mapped by other drivers with different mapping methods. Note: As a side effect, the flash region (if exposed through the memory map) gets unmapped too since it follows the future use region. Change-ID: Ic729a2eacd692984220b1a415ff4fa0f98ea419a Signed-off-by: Anjali Singhai Jain Signed-off-by: Jesse Brandeburg Tested-by: Jim Young Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e.h | 1 + drivers/net/ethernet/intel/i40e/i40e_main.c | 8 ++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h index c5137313b62a..ce3fbb87544e 100644 --- a/drivers/net/ethernet/intel/i40e/i40e.h +++ b/drivers/net/ethernet/intel/i40e/i40e.h @@ -72,6 +72,7 @@ #define I40E_MAX_NUM_DESCRIPTORS 4096 #define I40E_MAX_REGISTER 0x800000 +#define I40E_MAX_CSR_SPACE (4 * 1024 * 1024 - 64 * 1024) #define I40E_DEFAULT_NUM_DESCRIPTORS 512 #define I40E_REQ_DESCRIPTOR_MULTIPLE 32 #define I40E_MIN_NUM_DESCRIPTORS 64 diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 02b57c3aa4bb..f769005ea28c 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -9459,6 +9459,7 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent) struct i40e_pf *pf; struct i40e_hw *hw; static u16 pfs_found; + u32 ioremap_len; u16 link_status; int err = 0; u32 len; @@ -9507,8 +9508,11 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent) hw = &pf->hw; hw->back = pf; - hw->hw_addr = ioremap(pci_resource_start(pdev, 0), - pci_resource_len(pdev, 0)); + + ioremap_len = min_t(int, pci_resource_len(pdev, 0), + I40E_MAX_CSR_SPACE); + + hw->hw_addr = ioremap(pci_resource_start(pdev, 0), ioremap_len); if (!hw->hw_addr) { err = -EIO; dev_info(&pdev->dev, "ioremap(0x%04x, 0x%04x) failed: 0x%x\n", -- GitLab From 3b44439934055f91be7ee1c890bc5d5f3c904f88 Mon Sep 17 00:00:00 2001 From: Shannon Nelson Date: Thu, 26 Feb 2015 16:15:57 +0000 Subject: [PATCH 02811/11651] i40e: move IRQ tracking setup into MSIX setup Move the IRQ tracking setup and teardown into the same routines that do the IRQ setup and teardown. This keeps like activities together and allows us to track exactly the number of vectors reserved from the OS, which may be fewer than are available from the HW. Change-ID: I6b2b1a955c5f0ac6b94c3084304ed0b2ea6777cf Signed-off-by: Shannon Nelson Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_main.c | 60 ++++++++++----------- 1 file changed, 29 insertions(+), 31 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index f769005ea28c..bca62c11b7c3 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -3831,6 +3831,8 @@ static void i40e_reset_interrupt_capability(struct i40e_pf *pf) pci_disable_msix(pf->pdev); kfree(pf->msix_entries); pf->msix_entries = NULL; + kfree(pf->irq_pile); + pf->irq_pile = NULL; } else if (pf->flags & I40E_FLAG_MSI_ENABLED) { pci_disable_msi(pf->pdev); } @@ -6933,15 +6935,14 @@ static int i40e_reserve_msix_vectors(struct i40e_pf *pf, int vectors) * * Work with the OS to set up the MSIX vectors needed. * - * Returns 0 on success, negative on failure + * Returns the number of vectors reserved or negative on failure **/ static int i40e_init_msix(struct i40e_pf *pf) { - i40e_status err = 0; struct i40e_hw *hw = &pf->hw; int other_vecs = 0; int v_budget, i; - int vec; + int v_actual; if (!(pf->flags & I40E_FLAG_MSIX_ENABLED)) return -ENODEV; @@ -6990,9 +6991,9 @@ static int i40e_init_msix(struct i40e_pf *pf) for (i = 0; i < v_budget; i++) pf->msix_entries[i].entry = i; - vec = i40e_reserve_msix_vectors(pf, v_budget); + v_actual = i40e_reserve_msix_vectors(pf, v_budget); - if (vec != v_budget) { + if (v_actual != v_budget) { /* If we have limited resources, we will start with no vectors * for the special features and then allocate vectors to some * of these features based on the policy and at the end disable @@ -7005,22 +7006,24 @@ static int i40e_init_msix(struct i40e_pf *pf) pf->num_vmdq_msix = 0; } - if (vec < I40E_MIN_MSIX) { + if (v_actual < I40E_MIN_MSIX) { pf->flags &= ~I40E_FLAG_MSIX_ENABLED; kfree(pf->msix_entries); pf->msix_entries = NULL; return -ENODEV; - } else if (vec == I40E_MIN_MSIX) { + } else if (v_actual == I40E_MIN_MSIX) { /* Adjust for minimal MSIX use */ pf->num_vmdq_vsis = 0; pf->num_vmdq_qps = 0; pf->num_lan_qps = 1; pf->num_lan_msix = 1; - } else if (vec != v_budget) { + } else if (v_actual != v_budget) { + int vec; + /* reserve the misc vector */ - vec--; + vec = v_actual - 1; /* Scale vector usage down */ pf->num_vmdq_msix = 1; /* force VMDqs to only one vector */ @@ -7070,7 +7073,7 @@ static int i40e_init_msix(struct i40e_pf *pf) pf->flags &= ~I40E_FLAG_FCOE_ENABLED; } #endif - return err; + return v_actual; } /** @@ -7147,11 +7150,12 @@ err_out: **/ static void i40e_init_interrupt_scheme(struct i40e_pf *pf) { - int err = 0; + int vectors = 0; + ssize_t size; if (pf->flags & I40E_FLAG_MSIX_ENABLED) { - err = i40e_init_msix(pf); - if (err) { + vectors = i40e_init_msix(pf); + if (vectors < 0) { pf->flags &= ~(I40E_FLAG_MSIX_ENABLED | #ifdef I40E_FCOE I40E_FLAG_FCOE_ENABLED | @@ -7171,18 +7175,26 @@ static void i40e_init_interrupt_scheme(struct i40e_pf *pf) if (!(pf->flags & I40E_FLAG_MSIX_ENABLED) && (pf->flags & I40E_FLAG_MSI_ENABLED)) { dev_info(&pf->pdev->dev, "MSI-X not available, trying MSI\n"); - err = pci_enable_msi(pf->pdev); - if (err) { - dev_info(&pf->pdev->dev, "MSI init failed - %d\n", err); + vectors = pci_enable_msi(pf->pdev); + if (vectors < 0) { + dev_info(&pf->pdev->dev, "MSI init failed - %d\n", + vectors); pf->flags &= ~I40E_FLAG_MSI_ENABLED; } + vectors = 1; /* one MSI or Legacy vector */ } if (!(pf->flags & (I40E_FLAG_MSIX_ENABLED | I40E_FLAG_MSI_ENABLED))) dev_info(&pf->pdev->dev, "MSI-X and MSI not available, falling back to Legacy IRQ\n"); + /* set up vector assignment tracking */ + size = sizeof(struct i40e_lump_tracking) + (sizeof(u16) * vectors); + pf->irq_pile = kzalloc(size, GFP_KERNEL); + pf->irq_pile->num_entries = vectors; + pf->irq_pile->search_hint = 0; + /* track first vector for misc interrupts */ - err = i40e_get_lump(pf, pf->irq_pile, 1, I40E_PILE_VALID_BIT-1); + (void)i40e_get_lump(pf, pf->irq_pile, 1, I40E_PILE_VALID_BIT - 1); } /** @@ -7560,18 +7572,6 @@ static int i40e_sw_init(struct i40e_pf *pf) pf->qp_pile->num_entries = pf->hw.func_caps.num_tx_qp; pf->qp_pile->search_hint = 0; - /* set up vector assignment tracking */ - size = sizeof(struct i40e_lump_tracking) - + (sizeof(u16) * pf->hw.func_caps.num_msix_vectors); - pf->irq_pile = kzalloc(size, GFP_KERNEL); - if (!pf->irq_pile) { - kfree(pf->qp_pile); - err = -ENOMEM; - goto sw_init_done; - } - pf->irq_pile->num_entries = pf->hw.func_caps.num_msix_vectors; - pf->irq_pile->search_hint = 0; - pf->tx_timeout_recovery_level = 1; mutex_init(&pf->switch_mutex); @@ -9840,7 +9840,6 @@ err_configure_lan_hmc: (void)i40e_shutdown_lan_hmc(hw); err_init_lan_hmc: kfree(pf->qp_pile); - kfree(pf->irq_pile); err_sw_init: err_adminq_setup: (void)i40e_shutdown_adminq(hw); @@ -9940,7 +9939,6 @@ static void i40e_remove(struct pci_dev *pdev) } kfree(pf->qp_pile); - kfree(pf->irq_pile); kfree(pf->vsi); iounmap(pf->hw.hw_addr); -- GitLab From 94666990015a28d1880b56215bac081df218a4a1 Mon Sep 17 00:00:00 2001 From: Mitch A Williams Date: Thu, 26 Feb 2015 16:16:19 +0000 Subject: [PATCH 02812/11651] i40e: don't spam the system log The PF driver spams the system log with messages about VF VSI when VFs are created, as well as each time they are reset. This is annoying, and the information isn't even useful most of the time. Remove this message to reduce user annoyance. Change-ID: I8de90d05380f54b038c9c8c3265150be87c9242c Signed-off-by: Mitch Williams Tested-by: Jim Young Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c index 910c45e83fdd..1d8b94d80a87 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c @@ -403,9 +403,6 @@ static int i40e_alloc_vsi_res(struct i40e_vf *vf, enum i40e_vsi_type type) u8 brdcast[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; vf->lan_vsi_index = vsi->idx; vf->lan_vsi_id = vsi->id; - dev_info(&pf->pdev->dev, - "VF %d assigned LAN VSI index %d, VSI id %d\n", - vf->vf_id, vsi->idx, vsi->id); /* If the port VLAN has been configured and then the * VF driver was removed then the VSI port VLAN * configuration was destroyed. Check if there is -- GitLab From fe4be5e9f99d433fe6420a12f4e94f05f2ae39a6 Mon Sep 17 00:00:00 2001 From: Stanimir Varbanov Date: Thu, 5 Mar 2015 15:03:04 +0200 Subject: [PATCH 02813/11651] dmaengine: bam-dma: fix a warning about missing capabilities Avoid the warning below triggered during dmaengine async device registration. WARNING: CPU: 1 PID: 1 at linux/drivers/dma/dmaengine.c:863 dma_async_device_register+0x2a8/0x4b8() this driver doesn't support generic slave capabilities reporting To do that fill mandatory .directions bit mask, .src/dst_addr_widths and .residue_granularity dma_device fields with appropriate values. Signed-off-by: Stanimir Varbanov Signed-off-by: Vinod Koul --- drivers/dma/qcom_bam_dma.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/dma/qcom_bam_dma.c b/drivers/dma/qcom_bam_dma.c index d7a33b3ac466..d9f1a18b9295 100644 --- a/drivers/dma/qcom_bam_dma.c +++ b/drivers/dma/qcom_bam_dma.c @@ -1143,6 +1143,10 @@ static int bam_dma_probe(struct platform_device *pdev) dma_cap_set(DMA_SLAVE, bdev->common.cap_mask); /* initialize dmaengine apis */ + bdev->common.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); + bdev->common.residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT; + bdev->common.src_addr_widths = DMA_SLAVE_BUSWIDTH_4_BYTES; + bdev->common.dst_addr_widths = DMA_SLAVE_BUSWIDTH_4_BYTES; bdev->common.device_alloc_chan_resources = bam_alloc_chan; bdev->common.device_free_chan_resources = bam_free_chan; bdev->common.device_prep_slave_sg = bam_prep_slave_sg; -- GitLab From 68c062eaa87b7b85b65f20f25c54524437715a95 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Thu, 5 Mar 2015 11:42:43 +0100 Subject: [PATCH 02814/11651] dmaengine: Remove net_dma leftovers Commit 7bce d397 510a ("net_dma: simple removal") removed the net_dma support entirely but left some functions and prototypes in the dmaengine header. Remove them. Signed-off-by: Maxime Ripard Signed-off-by: Vinod Koul --- include/linux/dmaengine.h | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index db0104b0da4d..f5cc5d4f1ad5 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -1108,27 +1108,4 @@ static inline struct dma_chan return __dma_request_channel(mask, fn, fn_param); } - -/* --- Helper iov-locking functions --- */ - -struct dma_page_list { - char __user *base_address; - int nr_pages; - struct page **pages; -}; - -struct dma_pinned_list { - int nr_iovecs; - struct dma_page_list page_list[0]; -}; - -struct dma_pinned_list *dma_pin_iovec_pages(struct iovec *iov, size_t len); -void dma_unpin_iovec_pages(struct dma_pinned_list* pinned_list); - -dma_cookie_t dma_memcpy_to_iovec(struct dma_chan *chan, struct iovec *iov, - struct dma_pinned_list *pinned_list, unsigned char *kdata, size_t len); -dma_cookie_t dma_memcpy_pg_to_iovec(struct dma_chan *chan, struct iovec *iov, - struct dma_pinned_list *pinned_list, struct page *page, - unsigned int offset, size_t len); - #endif /* DMAENGINE_H */ -- GitLab From bfde98bd762346639f0a5a557e02c4828dd6273b Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Thu, 5 Mar 2015 11:48:50 +0100 Subject: [PATCH 02815/11651] dmaengine: Remove net_dma_find_channel Since commit 7bced397510a ("net_dma: simple removal") removed the net_dma support entirely, net_dma_find_channel has no users left. Remove the function entirely. Signed-off-by: Maxime Ripard Signed-off-by: Vinod Koul --- drivers/dma/dmaengine.c | 14 -------------- include/linux/dmaengine.h | 1 - 2 files changed, 15 deletions(-) diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index f15712f2fec6..344b0ac6d985 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c @@ -355,20 +355,6 @@ struct dma_chan *dma_find_channel(enum dma_transaction_type tx_type) } EXPORT_SYMBOL(dma_find_channel); -/* - * net_dma_find_channel - find a channel for net_dma - * net_dma has alignment requirements - */ -struct dma_chan *net_dma_find_channel(void) -{ - struct dma_chan *chan = dma_find_channel(DMA_MEMCPY); - if (chan && !is_dma_copy_aligned(chan->device, 1, 1, 1)) - return NULL; - - return chan; -} -EXPORT_SYMBOL(net_dma_find_channel); - /** * dma_issue_pending_all - flush all pending operations across all channels */ diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index f5cc5d4f1ad5..2bff9abc162a 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -1090,7 +1090,6 @@ void dma_async_device_unregister(struct dma_device *device); void dma_run_dependencies(struct dma_async_tx_descriptor *tx); struct dma_chan *dma_get_slave_channel(struct dma_chan *chan); struct dma_chan *dma_get_any_slave_channel(struct dma_device *device); -struct dma_chan *net_dma_find_channel(void); #define dma_request_channel(mask, x, y) __dma_request_channel(&(mask), x, y) #define dma_request_slave_channel_compat(mask, x, y, dev, name) \ __dma_request_slave_channel_compat(&(mask), x, y, dev, name) -- GitLab From d3866a071c426ee75649714cce062903d94e2f71 Mon Sep 17 00:00:00 2001 From: Sravanthi Tangeda Date: Thu, 26 Feb 2015 16:16:44 +0000 Subject: [PATCH 02816/11651] i40e/i40evf: Version bump Bump i40e to 1.2.11 and i40evf to 1.2.5 Change-ID: Ie13375941606b0a027e5b5dbc235f5f5f03b75c8 Signed-off-by: Sravanthi Tangeda Tested-by: Jim Young Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_main.c | 2 +- drivers/net/ethernet/intel/i40evf/i40evf_main.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index bca62c11b7c3..fb369f773780 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -39,7 +39,7 @@ static const char i40e_driver_string[] = #define DRV_VERSION_MAJOR 1 #define DRV_VERSION_MINOR 2 -#define DRV_VERSION_BUILD 10 +#define DRV_VERSION_BUILD 11 #define DRV_VERSION __stringify(DRV_VERSION_MAJOR) "." \ __stringify(DRV_VERSION_MINOR) "." \ __stringify(DRV_VERSION_BUILD) DRV_KERN diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c b/drivers/net/ethernet/intel/i40evf/i40evf_main.c index a95135846ea9..3d53bb4c3208 100644 --- a/drivers/net/ethernet/intel/i40evf/i40evf_main.c +++ b/drivers/net/ethernet/intel/i40evf/i40evf_main.c @@ -36,7 +36,7 @@ char i40evf_driver_name[] = "i40evf"; static const char i40evf_driver_string[] = "Intel(R) XL710/X710 Virtual Function Network Driver"; -#define DRV_VERSION "1.2.4" +#define DRV_VERSION "1.2.5" const char i40evf_driver_version[] = DRV_VERSION; static const char i40evf_copyright[] = "Copyright (c) 2013 - 2014 Intel Corporation."; -- GitLab From f33c9d655893d8632460696bbbdee737cb315711 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 24 Feb 2015 02:06:43 +0000 Subject: [PATCH 02817/11651] mmc: tmio: mmc: tmio: tmio_mmc_data has .chan_priv_?x dma_request_slave_channel_compat() in tmio_mmc_dma needs .chan_priv_tx/.chan_priv_rx. But these are copied from sh_mobile_sdhi only, and sh_mobile_sdhi_info is now almost same as tmio_mmc_data except .chan_priv_?x. sh_mobile_sdhi_info can be replaced to tmio_mmc_data, but it is used from ${LINUX}/arch/arm/mach-shmobile, ${LINUX}/arch/sh. So, this patch adds .chan_priv_?x into tmio_mmc_data as 1st step, and sh_mobile_sdhi driver has dummy operation for now. It will be replaced/removed together with platform data replace. Signed-off-by: Kuninori Morimoto Acked-by: Arnd Bergmann Acked-by: Ulf Hansson Acked-by: Lee Jones Signed-off-by: Vinod Koul --- drivers/mmc/host/sh_mobile_sdhi.c | 44 +++++++++++++++++++------------ drivers/mmc/host/tmio_mmc.h | 2 -- drivers/mmc/host/tmio_mmc_dma.c | 6 ++--- include/linux/mfd/tmio.h | 2 ++ 4 files changed, 32 insertions(+), 22 deletions(-) diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c index 11991f5f3fef..3137e292270e 100644 --- a/drivers/mmc/host/sh_mobile_sdhi.c +++ b/drivers/mmc/host/sh_mobile_sdhi.c @@ -201,6 +201,7 @@ static int sh_mobile_sdhi_probe(struct platform_device *pdev) of_match_device(sh_mobile_sdhi_of_match, &pdev->dev); struct sh_mobile_sdhi *priv; struct tmio_mmc_data *mmc_data; + struct tmio_mmc_data *mmd = pdev->dev.platform_data; struct sh_mobile_sdhi_info *p = pdev->dev.platform_data; struct tmio_mmc_host *host; struct resource *res; @@ -245,28 +246,37 @@ static int sh_mobile_sdhi_probe(struct platform_device *pdev) else host->bus_shift = 0; - mmc_data->capabilities = MMC_CAP_MMC_HIGHSPEED; - if (p) { - mmc_data->flags = p->tmio_flags; - mmc_data->ocr_mask = p->tmio_ocr_mask; - mmc_data->capabilities |= p->tmio_caps; - mmc_data->capabilities2 |= p->tmio_caps2; - mmc_data->cd_gpio = p->cd_gpio; - - if (p->dma_slave_tx > 0 && p->dma_slave_rx > 0) { - /* - * Yes, we have to provide slave IDs twice to TMIO: - * once as a filter parameter and once for channel - * configuration as an explicit slave ID - */ - dma_priv->chan_priv_tx = (void *)p->dma_slave_tx; - dma_priv->chan_priv_rx = (void *)p->dma_slave_rx; - } + if (mmd) { + /* + * FIXME + * + * sh_mobile_sdhi_info will be replaced to tmio_mmc_data soon. + * But, sh_mobile_sdhi_info is used under + * ${LINUX}/arch/arm/mach-shmobile/ + * ${LINUX}/arch/sh/ + * To separate large patch into "tmio_mmc_data has .chan_priv_?x" + * and "replace sh_mobile_sdhi_info in tmio_mmc_data", + * here has dummy method. + * These should be removed. + */ + struct tmio_mmc_data m; + + mmd = &m; + m.flags = p->tmio_flags; + m.ocr_mask = p->tmio_ocr_mask; + m.capabilities = p->tmio_caps; + m.capabilities2 = p->tmio_caps2; + m.cd_gpio = p->cd_gpio; + m.chan_priv_tx = (void *)p->dma_slave_tx; + m.chan_priv_rx = (void *)p->dma_slave_rx; + + *mmc_data = *mmd; } dma_priv->filter = shdma_chan_filter; dma_priv->enable = sh_mobile_sdhi_enable_dma; mmc_data->alignment_shift = 1; /* 2-byte alignment */ + mmc_data->capabilities |= MMC_CAP_MMC_HIGHSPEED; /* * All SDHI blocks support 2-byte and larger block sizes in 4-bit diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h index 1aea5c67af94..4a597f5a53e2 100644 --- a/drivers/mmc/host/tmio_mmc.h +++ b/drivers/mmc/host/tmio_mmc.h @@ -43,8 +43,6 @@ struct tmio_mmc_data; struct tmio_mmc_host; struct tmio_mmc_dma { - void *chan_priv_tx; - void *chan_priv_rx; enum dma_slave_buswidth dma_buswidth; bool (*filter)(struct dma_chan *chan, void *arg); void (*enable)(struct tmio_mmc_host *host, bool enable); diff --git a/drivers/mmc/host/tmio_mmc_dma.c b/drivers/mmc/host/tmio_mmc_dma.c index 8dbd785366a6..e4b05dbb9ca8 100644 --- a/drivers/mmc/host/tmio_mmc_dma.c +++ b/drivers/mmc/host/tmio_mmc_dma.c @@ -261,7 +261,7 @@ void tmio_mmc_request_dma(struct tmio_mmc_host *host, struct tmio_mmc_data *pdat { /* We can only either use DMA for both Tx and Rx or not use it at all */ if (!host->dma || (!host->pdev->dev.of_node && - (!host->dma->chan_priv_tx || !host->dma->chan_priv_rx))) + (!pdata->chan_priv_tx || !pdata->chan_priv_rx))) return; if (!host->chan_tx && !host->chan_rx) { @@ -278,7 +278,7 @@ void tmio_mmc_request_dma(struct tmio_mmc_host *host, struct tmio_mmc_data *pdat dma_cap_set(DMA_SLAVE, mask); host->chan_tx = dma_request_slave_channel_compat(mask, - host->dma->filter, host->dma->chan_priv_tx, + host->dma->filter, pdata->chan_priv_tx, &host->pdev->dev, "tx"); dev_dbg(&host->pdev->dev, "%s: TX: got channel %p\n", __func__, host->chan_tx); @@ -297,7 +297,7 @@ void tmio_mmc_request_dma(struct tmio_mmc_host *host, struct tmio_mmc_data *pdat goto ecfgtx; host->chan_rx = dma_request_slave_channel_compat(mask, - host->dma->filter, host->dma->chan_priv_rx, + host->dma->filter, pdata->chan_priv_rx, &host->pdev->dev, "rx"); dev_dbg(&host->pdev->dev, "%s: RX: got channel %p\n", __func__, host->chan_rx); diff --git a/include/linux/mfd/tmio.h b/include/linux/mfd/tmio.h index 605812820e48..24b86d538e88 100644 --- a/include/linux/mfd/tmio.h +++ b/include/linux/mfd/tmio.h @@ -111,6 +111,8 @@ struct dma_chan; * data for the MMC controller */ struct tmio_mmc_data { + void *chan_priv_tx; + void *chan_priv_rx; unsigned int hclk; unsigned long capabilities; unsigned long capabilities2; -- GitLab From 84f11d5b1f2abc0e22895b7e12e037f0ec03caeb Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 24 Feb 2015 02:07:07 +0000 Subject: [PATCH 02818/11651] mmc: sh_mobile_sdhi: remove sh_mobile_sdhi_info Current sh_mobile_sdhi's platform data is set via sh_mobile_sdhi_info and it is just copied to tmio_mmc_data. Now, tmio mmc platform data is specified via tmio_mmc_data. This patch replace sh_mobile_sdhi_info to tmio_mmc_data struct sh_mobile_sdhi_info { -> struct tmio_mmc_data { int dma_slave_tx; -> void *chan_priv_tx; int dma_slave_rx; -> void *chan_priv_rx; unsigned long tmio_flags; -> unsigned long flags; unsigned long tmio_caps; -> unsigned long capabilities; unsigned long tmio_caps2; -> unsigned long capabilities2; u32 tmio_ocr_mask; -> u32 ocr_mask; unsigned int cd_gpio; -> unsigned int cd_gpio; }; unsigned int hclk; void (*set_pwr)(...); void (*set_clk_div)(...); }; Signed-off-by: Kuninori Morimoto Acked-by: Arnd Bergmann Acked-by: Ulf Hansson Signed-off-by: Vinod Koul --- .../arm/mach-shmobile/board-armadillo800eva.c | 20 ++++++------- arch/arm/mach-shmobile/board-bockw.c | 14 +++++----- arch/arm/mach-shmobile/board-kzm9g.c | 20 ++++++------- arch/arm/mach-shmobile/board-marzen.c | 10 +++---- arch/sh/boards/board-sh7757lcr.c | 9 +++--- arch/sh/boards/mach-ap325rxa/setup.c | 9 +++--- arch/sh/boards/mach-ecovec24/setup.c | 20 ++++++------- arch/sh/boards/mach-kfr2r09/setup.c | 10 +++---- arch/sh/boards/mach-migor/setup.c | 9 +++--- arch/sh/boards/mach-se/7724/setup.c | 17 +++++------ drivers/mmc/host/sh_mobile_sdhi.c | 28 ++----------------- include/linux/mmc/sh_mobile_sdhi.h | 10 ------- 12 files changed, 73 insertions(+), 103 deletions(-) diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c index 6d949f1c850b..7eac84687cb4 100644 --- a/arch/arm/mach-shmobile/board-armadillo800eva.c +++ b/arch/arm/mach-shmobile/board-armadillo800eva.c @@ -754,12 +754,12 @@ static struct platform_device vcc_sdhi1 = { }; /* SDHI0 */ -static struct sh_mobile_sdhi_info sdhi0_info = { - .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX, - .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX, - .tmio_caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ | +static struct tmio_mmc_data sdhi0_info = { + .chan_priv_tx = (void *)SHDMA_SLAVE_SDHI0_TX, + .chan_priv_rx = (void *)SHDMA_SLAVE_SDHI0_RX, + .capabilities = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ | MMC_CAP_POWER_OFF_CARD, - .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_USE_GPIO_CD, + .flags = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_USE_GPIO_CD, .cd_gpio = 167, }; @@ -796,12 +796,12 @@ static struct platform_device sdhi0_device = { }; /* SDHI1 */ -static struct sh_mobile_sdhi_info sdhi1_info = { - .dma_slave_tx = SHDMA_SLAVE_SDHI1_TX, - .dma_slave_rx = SHDMA_SLAVE_SDHI1_RX, - .tmio_caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ | +static struct tmio_mmc_data sdhi1_info = { + .chan_priv_tx = (void *)SHDMA_SLAVE_SDHI1_TX, + .chan_priv_rx = (void *)SHDMA_SLAVE_SDHI1_RX, + .capabilities = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ | MMC_CAP_POWER_OFF_CARD, - .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_USE_GPIO_CD, + .flags = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_USE_GPIO_CD, /* Port72 cannot generate IRQs, will be used in polling mode. */ .cd_gpio = 72, }; diff --git a/arch/arm/mach-shmobile/board-bockw.c b/arch/arm/mach-shmobile/board-bockw.c index f27b5a833bf0..25558d1f417f 100644 --- a/arch/arm/mach-shmobile/board-bockw.c +++ b/arch/arm/mach-shmobile/board-bockw.c @@ -201,12 +201,12 @@ static struct rcar_phy_platform_data usb_phy_platform_data __initdata = /* SDHI */ -static struct sh_mobile_sdhi_info sdhi0_info __initdata = { - .dma_slave_tx = HPBDMA_SLAVE_SDHI0_TX, - .dma_slave_rx = HPBDMA_SLAVE_SDHI0_RX, - .tmio_caps = MMC_CAP_SD_HIGHSPEED, - .tmio_ocr_mask = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34, - .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT, +static struct tmio_mmc_data sdhi0_info __initdata = { + .chan_priv_tx = (void *)HPBDMA_SLAVE_SDHI0_TX, + .chan_priv_rx = (void *)HPBDMA_SLAVE_SDHI0_RX, + .capabilities = MMC_CAP_SD_HIGHSPEED, + .ocr_mask = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34, + .flags = TMIO_MMC_HAS_IDLE_WAIT, }; static struct resource sdhi0_resources[] __initdata = { @@ -683,7 +683,7 @@ static void __init bockw_init(void) platform_device_register_resndata( NULL, "sh_mobile_sdhi", 0, sdhi0_resources, ARRAY_SIZE(sdhi0_resources), - &sdhi0_info, sizeof(struct sh_mobile_sdhi_info)); + &sdhi0_info, sizeof(struct tmio_mmc_data)); } /* for Audio */ diff --git a/arch/arm/mach-shmobile/board-kzm9g.c b/arch/arm/mach-shmobile/board-kzm9g.c index 7c9b63bdde9f..260d8319fd82 100644 --- a/arch/arm/mach-shmobile/board-kzm9g.c +++ b/arch/arm/mach-shmobile/board-kzm9g.c @@ -442,11 +442,11 @@ static struct platform_device vcc_sdhi2 = { }; /* SDHI */ -static struct sh_mobile_sdhi_info sdhi0_info = { - .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX, - .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX, - .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT, - .tmio_caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ | +static struct tmio_mmc_data sdhi0_info = { + .chan_priv_tx = (void *)SHDMA_SLAVE_SDHI0_TX, + .chan_priv_rx = (void *)SHDMA_SLAVE_SDHI0_RX, + .flags = TMIO_MMC_HAS_IDLE_WAIT, + .capabilities = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ | MMC_CAP_POWER_OFF_CARD, }; @@ -484,13 +484,13 @@ static struct platform_device sdhi0_device = { }; /* Micro SD */ -static struct sh_mobile_sdhi_info sdhi2_info = { - .dma_slave_tx = SHDMA_SLAVE_SDHI2_TX, - .dma_slave_rx = SHDMA_SLAVE_SDHI2_RX, - .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT | +static struct tmio_mmc_data sdhi2_info = { + .chan_priv_tx = (void *)SHDMA_SLAVE_SDHI2_TX, + .chan_priv_rx = (void *)SHDMA_SLAVE_SDHI2_RX, + .flags = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_USE_GPIO_CD | TMIO_MMC_WRPROTECT_DISABLE, - .tmio_caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_POWER_OFF_CARD, + .capabilities = MMC_CAP_SD_HIGHSPEED | MMC_CAP_POWER_OFF_CARD, .cd_gpio = 13, }; diff --git a/arch/arm/mach-shmobile/board-marzen.c b/arch/arm/mach-shmobile/board-marzen.c index 598f704f76ae..51db288f192a 100644 --- a/arch/arm/mach-shmobile/board-marzen.c +++ b/arch/arm/mach-shmobile/board-marzen.c @@ -122,11 +122,11 @@ static struct resource sdhi0_resources[] = { }, }; -static struct sh_mobile_sdhi_info sdhi0_platform_data = { - .dma_slave_tx = HPBDMA_SLAVE_SDHI0_TX, - .dma_slave_rx = HPBDMA_SLAVE_SDHI0_RX, - .tmio_flags = TMIO_MMC_WRPROTECT_DISABLE | TMIO_MMC_HAS_IDLE_WAIT, - .tmio_caps = MMC_CAP_SD_HIGHSPEED, +static struct tmio_mmc_data sdhi0_platform_data = { + .chan_priv_tx = (void *)HPBDMA_SLAVE_SDHI0_TX, + .chan_priv_rx = (void *)HPBDMA_SLAVE_SDHI0_RX, + .flags = TMIO_MMC_WRPROTECT_DISABLE | TMIO_MMC_HAS_IDLE_WAIT, + .capabilities = MMC_CAP_SD_HIGHSPEED, }; static struct platform_device sdhi0_device = { diff --git a/arch/sh/boards/board-sh7757lcr.c b/arch/sh/boards/board-sh7757lcr.c index 669df51a82e3..324599bfad14 100644 --- a/arch/sh/boards/board-sh7757lcr.c +++ b/arch/sh/boards/board-sh7757lcr.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -243,10 +244,10 @@ static struct platform_device sh_mmcif_device = { }; /* SDHI0 */ -static struct sh_mobile_sdhi_info sdhi_info = { - .dma_slave_tx = SHDMA_SLAVE_SDHI_TX, - .dma_slave_rx = SHDMA_SLAVE_SDHI_RX, - .tmio_caps = MMC_CAP_SD_HIGHSPEED, +static struct tmio_mmc_data sdhi_info = { + .chan_priv_tx = (void *)SHDMA_SLAVE_SDHI_TX, + .chan_priv_rx = (void *)SHDMA_SLAVE_SDHI_RX, + .capabilities = MMC_CAP_SD_HIGHSPEED, }; static struct resource sdhi_resources[] = { diff --git a/arch/sh/boards/mach-ap325rxa/setup.c b/arch/sh/boards/mach-ap325rxa/setup.c index d4b01d4cc102..cbd2a9f02a91 100644 --- a/arch/sh/boards/mach-ap325rxa/setup.c +++ b/arch/sh/boards/mach-ap325rxa/setup.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -447,8 +448,8 @@ static struct resource sdhi0_cn3_resources[] = { }, }; -static struct sh_mobile_sdhi_info sdhi0_cn3_data = { - .tmio_caps = MMC_CAP_SDIO_IRQ, +static struct tmio_mmc_data sdhi0_cn3_data = { + .capabilities = MMC_CAP_SDIO_IRQ, }; static struct platform_device sdhi0_cn3_device = { @@ -474,8 +475,8 @@ static struct resource sdhi1_cn7_resources[] = { }, }; -static struct sh_mobile_sdhi_info sdhi1_cn7_data = { - .tmio_caps = MMC_CAP_SDIO_IRQ, +static struct tmio_mmc_data sdhi1_cn7_data = { + .capabilities = MMC_CAP_SDIO_IRQ, }; static struct platform_device sdhi1_cn7_device = { diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c index 0d3049244cd3..d531791f06ff 100644 --- a/arch/sh/boards/mach-ecovec24/setup.c +++ b/arch/sh/boards/mach-ecovec24/setup.c @@ -601,12 +601,12 @@ static struct platform_device sdhi0_power = { }, }; -static struct sh_mobile_sdhi_info sdhi0_info = { - .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX, - .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX, - .tmio_caps = MMC_CAP_SDIO_IRQ | MMC_CAP_POWER_OFF_CARD | +static struct tmio_mmc_data sdhi0_info = { + .chan_priv_tx = (void *)SHDMA_SLAVE_SDHI0_TX, + .chan_priv_rx = (void *)SHDMA_SLAVE_SDHI0_RX, + .capabilities = MMC_CAP_SDIO_IRQ | MMC_CAP_POWER_OFF_CARD | MMC_CAP_NEEDS_POLL, - .tmio_flags = TMIO_MMC_USE_GPIO_CD, + .flags = TMIO_MMC_USE_GPIO_CD, .cd_gpio = GPIO_PTY7, }; @@ -635,12 +635,12 @@ static struct platform_device sdhi0_device = { #if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE) /* SDHI1 */ -static struct sh_mobile_sdhi_info sdhi1_info = { - .dma_slave_tx = SHDMA_SLAVE_SDHI1_TX, - .dma_slave_rx = SHDMA_SLAVE_SDHI1_RX, - .tmio_caps = MMC_CAP_SDIO_IRQ | MMC_CAP_POWER_OFF_CARD | +static struct tmio_mmc_data sdhi1_info = { + .chan_priv_tx = (void *)SHDMA_SLAVE_SDHI1_TX, + .chan_priv_rx = (void *)SHDMA_SLAVE_SDHI1_RX, + .capabilities = MMC_CAP_SDIO_IRQ | MMC_CAP_POWER_OFF_CARD | MMC_CAP_NEEDS_POLL, - .tmio_flags = TMIO_MMC_USE_GPIO_CD, + .flags = TMIO_MMC_USE_GPIO_CD, .cd_gpio = GPIO_PTW7, }; diff --git a/arch/sh/boards/mach-kfr2r09/setup.c b/arch/sh/boards/mach-kfr2r09/setup.c index 1df4398f8375..7d997cec09c5 100644 --- a/arch/sh/boards/mach-kfr2r09/setup.c +++ b/arch/sh/boards/mach-kfr2r09/setup.c @@ -373,11 +373,11 @@ static struct resource kfr2r09_sh_sdhi0_resources[] = { }, }; -static struct sh_mobile_sdhi_info sh7724_sdhi0_data = { - .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX, - .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX, - .tmio_flags = TMIO_MMC_WRPROTECT_DISABLE, - .tmio_caps = MMC_CAP_SDIO_IRQ, +static struct tmio_mmc_data sh7724_sdhi0_data = { + .chan_priv_tx = (void *)SHDMA_SLAVE_SDHI0_TX, + .chan_priv_rx = (void *)SHDMA_SLAVE_SDHI0_RX, + .flags = TMIO_MMC_WRPROTECT_DISABLE, + .capabilities = MMC_CAP_SDIO_IRQ, }; static struct platform_device kfr2r09_sh_sdhi0_device = { diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c index 8b73194ed2ce..29b7c0dcfc51 100644 --- a/arch/sh/boards/mach-migor/setup.c +++ b/arch/sh/boards/mach-migor/setup.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -408,10 +409,10 @@ static struct resource sdhi_cn9_resources[] = { }, }; -static struct sh_mobile_sdhi_info sh7724_sdhi_data = { - .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX, - .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX, - .tmio_caps = MMC_CAP_SDIO_IRQ, +static struct tmio_mmc_data sh7724_sdhi_data = { + .chan_priv_tx = (void *)SHDMA_SLAVE_SDHI0_TX, + .chan_priv_rx = (void *)SHDMA_SLAVE_SDHI0_RX, + .capabilities = MMC_CAP_SDIO_IRQ, }; static struct platform_device sdhi_cn9_device = { diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c index 1162bc6945a3..4f6635a075f2 100644 --- a/arch/sh/boards/mach-se/7724/setup.c +++ b/arch/sh/boards/mach-se/7724/setup.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -468,10 +469,10 @@ static struct resource sdhi0_cn7_resources[] = { }, }; -static struct sh_mobile_sdhi_info sh7724_sdhi0_data = { - .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX, - .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX, - .tmio_caps = MMC_CAP_SDIO_IRQ, +static struct tmio_mmc_data sh7724_sdhi0_data = { + .chan_priv_tx = (void *)SHDMA_SLAVE_SDHI0_TX, + .chan_priv_rx = (void *)SHDMA_SLAVE_SDHI0_RX, + .capabilities = MMC_CAP_SDIO_IRQ, }; static struct platform_device sdhi0_cn7_device = { @@ -497,10 +498,10 @@ static struct resource sdhi1_cn8_resources[] = { }, }; -static struct sh_mobile_sdhi_info sh7724_sdhi1_data = { - .dma_slave_tx = SHDMA_SLAVE_SDHI1_TX, - .dma_slave_rx = SHDMA_SLAVE_SDHI1_RX, - .tmio_caps = MMC_CAP_SDIO_IRQ, +static struct tmio_mmc_data sh7724_sdhi1_data = { + .chan_priv_tx = (void *)SHDMA_SLAVE_SDHI1_TX, + .chan_priv_rx = (void *)SHDMA_SLAVE_SDHI1_RX, + .capabilities = MMC_CAP_SDIO_IRQ, }; static struct platform_device sdhi1_cn8_device = { diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c index 3137e292270e..354f4f335ed5 100644 --- a/drivers/mmc/host/sh_mobile_sdhi.c +++ b/drivers/mmc/host/sh_mobile_sdhi.c @@ -202,7 +202,6 @@ static int sh_mobile_sdhi_probe(struct platform_device *pdev) struct sh_mobile_sdhi *priv; struct tmio_mmc_data *mmc_data; struct tmio_mmc_data *mmd = pdev->dev.platform_data; - struct sh_mobile_sdhi_info *p = pdev->dev.platform_data; struct tmio_mmc_host *host; struct resource *res; int irq, ret, i = 0; @@ -246,32 +245,9 @@ static int sh_mobile_sdhi_probe(struct platform_device *pdev) else host->bus_shift = 0; - if (mmd) { - /* - * FIXME - * - * sh_mobile_sdhi_info will be replaced to tmio_mmc_data soon. - * But, sh_mobile_sdhi_info is used under - * ${LINUX}/arch/arm/mach-shmobile/ - * ${LINUX}/arch/sh/ - * To separate large patch into "tmio_mmc_data has .chan_priv_?x" - * and "replace sh_mobile_sdhi_info in tmio_mmc_data", - * here has dummy method. - * These should be removed. - */ - struct tmio_mmc_data m; - - mmd = &m; - m.flags = p->tmio_flags; - m.ocr_mask = p->tmio_ocr_mask; - m.capabilities = p->tmio_caps; - m.capabilities2 = p->tmio_caps2; - m.cd_gpio = p->cd_gpio; - m.chan_priv_tx = (void *)p->dma_slave_tx; - m.chan_priv_rx = (void *)p->dma_slave_rx; - + if (mmd) *mmc_data = *mmd; - } + dma_priv->filter = shdma_chan_filter; dma_priv->enable = sh_mobile_sdhi_enable_dma; diff --git a/include/linux/mmc/sh_mobile_sdhi.h b/include/linux/mmc/sh_mobile_sdhi.h index da77e5e2041d..95d6f0314a7d 100644 --- a/include/linux/mmc/sh_mobile_sdhi.h +++ b/include/linux/mmc/sh_mobile_sdhi.h @@ -7,14 +7,4 @@ #define SH_MOBILE_SDHI_IRQ_SDCARD "sdcard" #define SH_MOBILE_SDHI_IRQ_SDIO "sdio" -struct sh_mobile_sdhi_info { - int dma_slave_tx; - int dma_slave_rx; - unsigned long tmio_flags; - unsigned long tmio_caps; - unsigned long tmio_caps2; - u32 tmio_ocr_mask; /* available MMC voltages */ - unsigned int cd_gpio; -}; - #endif /* LINUX_MMC_SH_MOBILE_SDHI_H */ -- GitLab From 90b1047f138459e86861cf401c5e9f0a9aa3b23b Mon Sep 17 00:00:00 2001 From: Stanimir Varbanov Date: Thu, 19 Feb 2015 18:45:50 +0200 Subject: [PATCH 02819/11651] dmaengine: qcom_bam_dma: fix wrong register offsets The commit fb93f520e (dmaengine: qcom_bam_dma: Generalize BAM register offset calculations) wrongly populated base offsets for event registers for bam v1.4. Signed-off-by: Stanimir Varbanov Reviewed-by: Archit Taneja Reviewed-by: Andy Gross Signed-off-by: Vinod Koul --- drivers/dma/qcom_bam_dma.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/dma/qcom_bam_dma.c b/drivers/dma/qcom_bam_dma.c index d9f1a18b9295..9c914d625906 100644 --- a/drivers/dma/qcom_bam_dma.c +++ b/drivers/dma/qcom_bam_dma.c @@ -162,9 +162,9 @@ static const struct reg_offset_data bam_v1_4_reg_info[] = { [BAM_P_IRQ_STTS] = { 0x1010, 0x1000, 0x00, 0x00 }, [BAM_P_IRQ_CLR] = { 0x1014, 0x1000, 0x00, 0x00 }, [BAM_P_IRQ_EN] = { 0x1018, 0x1000, 0x00, 0x00 }, - [BAM_P_EVNT_DEST_ADDR] = { 0x102C, 0x00, 0x1000, 0x00 }, - [BAM_P_EVNT_REG] = { 0x1018, 0x00, 0x1000, 0x00 }, - [BAM_P_SW_OFSTS] = { 0x1000, 0x00, 0x1000, 0x00 }, + [BAM_P_EVNT_DEST_ADDR] = { 0x182C, 0x00, 0x1000, 0x00 }, + [BAM_P_EVNT_REG] = { 0x1818, 0x00, 0x1000, 0x00 }, + [BAM_P_SW_OFSTS] = { 0x1800, 0x00, 0x1000, 0x00 }, [BAM_P_DATA_FIFO_ADDR] = { 0x1824, 0x00, 0x1000, 0x00 }, [BAM_P_DESC_FIFO_ADDR] = { 0x181C, 0x00, 0x1000, 0x00 }, [BAM_P_EVNT_GEN_TRSHLD] = { 0x1828, 0x00, 0x1000, 0x00 }, -- GitLab From 26f7af37eeaab359c3013c704f75749a2b5ce1b1 Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Fri, 20 Feb 2015 17:58:44 +0530 Subject: [PATCH 02820/11651] dmaengine: jz4740: Remove extra check Remove double check on chan->desc. Found by Coccinelle. Signed-off-by: Tapasweni Pathak Acked-by: Julia Lawall Signed-off-by: Vinod Koul --- drivers/dma/dma-jz4740.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma/dma-jz4740.c b/drivers/dma/dma-jz4740.c index 4527a3ebeac4..f6a4c4270dcd 100644 --- a/drivers/dma/dma-jz4740.c +++ b/drivers/dma/dma-jz4740.c @@ -343,7 +343,7 @@ static void jz4740_dma_chan_irq(struct jz4740_dmaengine_chan *chan) { spin_lock(&chan->vchan.lock); if (chan->desc) { - if (chan->desc && chan->desc->cyclic) { + if (chan->desc->cyclic) { vchan_cyclic_callback(&chan->desc->vdesc); } else { if (chan->next_sg == chan->desc->num_sgs) { -- GitLab From 6afda7f5075440f6737d953ab00fc82efb6cabae Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Thu, 5 Mar 2015 16:55:21 +0200 Subject: [PATCH 02821/11651] ASoC: davinci-mcasp: Allow complete shutdown of McASP when not in use Rearrange the pm_runtime_get/put_sync calls so the IP will be turned off when it is not in use. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/davinci/davinci-mcasp.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 0c882995a357..33cea0728cd2 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -62,6 +62,7 @@ struct davinci_mcasp_context { u32 config_regs[ARRAY_SIZE(context_regs)]; u32 afifo_regs[2]; /* for read/write fifo control registers */ u32 *xrsr_regs; /* for serializer configuration */ + bool pm_state; }; struct davinci_mcasp { @@ -519,7 +520,7 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRPOL); } out: - pm_runtime_put_sync(mcasp->dev); + pm_runtime_put(mcasp->dev); return ret; } @@ -528,6 +529,7 @@ static int __davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id, { struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai); + pm_runtime_get_sync(mcasp->dev); switch (div_id) { case 0: /* MCLK divider */ mcasp_mod_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG, @@ -553,6 +555,7 @@ static int __davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id, return -EINVAL; } + pm_runtime_put(mcasp->dev); return 0; } @@ -567,6 +570,7 @@ static int davinci_mcasp_set_sysclk(struct snd_soc_dai *dai, int clk_id, { struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai); + pm_runtime_get_sync(mcasp->dev); if (dir == SND_SOC_CLOCK_OUT) { mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXE); mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKRCTL_REG, AHCLKRE); @@ -579,6 +583,7 @@ static int davinci_mcasp_set_sysclk(struct snd_soc_dai *dai, int clk_id, mcasp->sysclk_freq = freq; + pm_runtime_put(mcasp->dev); return 0; } @@ -1053,6 +1058,10 @@ static int davinci_mcasp_suspend(struct snd_soc_dai *dai) u32 reg; int i; + context->pm_state = pm_runtime_enabled(mcasp->dev) + if (!context->pm_state) + pm_runtime_get_sync(mcasp->dev); + for (i = 0; i < ARRAY_SIZE(context_regs); i++) context->config_regs[i] = mcasp_get_reg(mcasp, context_regs[i]); @@ -1069,6 +1078,8 @@ static int davinci_mcasp_suspend(struct snd_soc_dai *dai) context->xrsr_regs[i] = mcasp_get_reg(mcasp, DAVINCI_MCASP_XRSRCTL_REG(i)); + pm_runtime_put_sync(mcasp->dev); + return 0; } @@ -1079,6 +1090,8 @@ static int davinci_mcasp_resume(struct snd_soc_dai *dai) u32 reg; int i; + pm_runtime_get_sync(mcasp->dev); + for (i = 0; i < ARRAY_SIZE(context_regs); i++) mcasp_set_reg(mcasp, context_regs[i], context->config_regs[i]); @@ -1095,6 +1108,9 @@ static int davinci_mcasp_resume(struct snd_soc_dai *dai) mcasp_set_reg(mcasp, DAVINCI_MCASP_XRSRCTL_REG(i), context->xrsr_regs[i]); + if (!context->pm_state) + pm_runtime_put_sync(mcasp->dev); + return 0; } #else @@ -1398,13 +1414,6 @@ static int davinci_mcasp_probe(struct platform_device *pdev) pm_runtime_enable(&pdev->dev); - ret = pm_runtime_get_sync(&pdev->dev); - if (IS_ERR_VALUE(ret)) { - dev_err(&pdev->dev, "pm_runtime_get_sync() failed\n"); - pm_runtime_disable(&pdev->dev); - return ret; - } - mcasp->base = devm_ioremap(&pdev->dev, mem->start, resource_size(mem)); if (!mcasp->base) { dev_err(&pdev->dev, "ioremap failed\n"); @@ -1584,14 +1593,12 @@ static int davinci_mcasp_probe(struct platform_device *pdev) return 0; err: - pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); return ret; } static int davinci_mcasp_remove(struct platform_device *pdev) { - pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); return 0; -- GitLab From 046db763aaaeb987ea01ea8c7e6d618e0ad1e6b8 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 5 Mar 2015 15:39:20 +0000 Subject: [PATCH 02822/11651] regulator: core: Add devres versions of notifier registration Add devm_regulator_register_notifier, this adds the resource against the device for the consumer supply we are registering the notifier for. There seem to be few use-cases where this wouldn't be the users intention and this ensures the notifiers will always be removed at the correct time. Signed-off-by: Charles Keepax Signed-off-by: Mark Brown --- drivers/regulator/devres.c | 85 ++++++++++++++++++++++++++++++ include/linux/regulator/consumer.h | 16 ++++++ 2 files changed, 101 insertions(+) diff --git a/drivers/regulator/devres.c b/drivers/regulator/devres.c index 8f785bc9e510..6ec1d400adae 100644 --- a/drivers/regulator/devres.c +++ b/drivers/regulator/devres.c @@ -413,3 +413,88 @@ void devm_regulator_bulk_unregister_supply_alias(struct device *dev, devm_regulator_unregister_supply_alias(dev, id[i]); } EXPORT_SYMBOL_GPL(devm_regulator_bulk_unregister_supply_alias); + +struct regulator_notifier_match { + struct regulator *regulator; + struct notifier_block *nb; +}; + +static int devm_regulator_match_notifier(struct device *dev, void *res, + void *data) +{ + struct regulator_notifier_match *match = res; + struct regulator_notifier_match *target = data; + + return match->regulator == target->regulator && match->nb == target->nb; +} + +static void devm_regulator_destroy_notifier(struct device *dev, void *res) +{ + struct regulator_notifier_match *match = res; + + regulator_unregister_notifier(match->regulator, match->nb); +} + +/** + * devm_regulator_register_notifier - Resource managed + * regulator_register_notifier + * + * @regulator: regulator source + * @nb: notifier block + * + * The notifier will be registers under the consumer device and be + * automatically be unregistered when the source device is unbound. + */ +int devm_regulator_register_notifier(struct regulator *regulator, + struct notifier_block *nb) +{ + struct regulator_notifier_match *match; + int ret; + + match = devres_alloc(devm_regulator_destroy_notifier, + sizeof(struct regulator_notifier_match), + GFP_KERNEL); + if (!match) + return -ENOMEM; + + match->regulator = regulator; + match->nb = nb; + + ret = regulator_register_notifier(regulator, nb); + if (ret < 0) { + devres_free(match); + return ret; + } + + devres_add(regulator->dev, match); + + return 0; +} +EXPORT_SYMBOL_GPL(devm_regulator_register_notifier); + +/** + * devm_regulator_unregister_notifier - Resource managed + * regulator_unregister_notifier() + * + * @regulator: regulator source + * @nb: notifier block + * + * Unregister a notifier registered with devm_regulator_register_notifier(). + * Normally this function will not need to be called and the resource + * management code will ensure that the resource is freed. + */ +void devm_regulator_unregister_notifier(struct regulator *regulator, + struct notifier_block *nb) +{ + struct regulator_notifier_match match; + int rc; + + match.regulator = regulator; + match.nb = nb; + + rc = devres_release(regulator->dev, devm_regulator_destroy_notifier, + devm_regulator_match_notifier, &match); + if (rc != 0) + WARN_ON(rc); +} +EXPORT_SYMBOL_GPL(devm_regulator_unregister_notifier); diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h index d17e1ff7ad01..bd631ee5f1da 100644 --- a/include/linux/regulator/consumer.h +++ b/include/linux/regulator/consumer.h @@ -252,8 +252,12 @@ int regulator_list_hardware_vsel(struct regulator *regulator, /* regulator notifier block */ int regulator_register_notifier(struct regulator *regulator, struct notifier_block *nb); +int devm_regulator_register_notifier(struct regulator *regulator, + struct notifier_block *nb); int regulator_unregister_notifier(struct regulator *regulator, struct notifier_block *nb); +void devm_regulator_unregister_notifier(struct regulator *regulator, + struct notifier_block *nb); /* driver data - core doesn't touch */ void *regulator_get_drvdata(struct regulator *regulator); @@ -515,12 +519,24 @@ static inline int regulator_register_notifier(struct regulator *regulator, return 0; } +static inline int devm_regulator_register_notifier(struct regulator *regulator, + struct notifier_block *nb) +{ + return 0; +} + static inline int regulator_unregister_notifier(struct regulator *regulator, struct notifier_block *nb) { return 0; } +static inline int devm_regulator_unregister_notifier(struct regulator *regulator, + struct notifier_block *nb) +{ + return 0; +} + static inline void *regulator_get_drvdata(struct regulator *regulator) { return NULL; -- GitLab From 9ab6eb51ef4ad63cb71533d3a4dfb09ea8f69b4c Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 5 Mar 2015 17:24:04 +0200 Subject: [PATCH 02823/11651] x86/intel/quark: Select COMMON_CLK The commit 8bbc2a135b63 ("x86/intel/quark: Add Intel Quark platform support") introduced a minimal support of Intel Quark SoC. That allows to use core parts of the SoC. However, the SPI, I2C, and GPIO drivers can't be selected by kernel configuration because they depend on COMMON_CLK. The patch adds a COMMON_CLK selection to the platfrom definition to allow user choose the drivers. Signed-off-by: Andy Shevchenko Acked-by: Ong, Boon Leong Cc: Bryan O'Donoghue Cc: Darren Hart Fixes: 8bbc2a135b63 ("x86/intel/quark: Add Intel Quark platform support") Link: http://lkml.kernel.org/r/1425569044-2867-1-git-send-email-andriy.shevchenko@linux.intel.com Signed-off-by: Ingo Molnar --- arch/x86/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index c2fb8a87dccb..b7d31ca55187 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -499,6 +499,7 @@ config X86_INTEL_QUARK depends on X86_IO_APIC select IOSF_MBI select INTEL_IMR + select COMMON_CLK ---help--- Select to include support for Quark X1000 SoC. Say Y here if you have a Quark based system such as the Arduino -- GitLab From ecb9b4241f696b746215b1de36106258bc8ed957 Mon Sep 17 00:00:00 2001 From: Robert Jarzmik Date: Sun, 15 Feb 2015 19:49:16 +0100 Subject: [PATCH 02824/11651] dmaengine: mmp_pdma: fix warning about slave caps Fix the dmaengine complaint about missing slave caps : - declare the available bus widths - declare the available transfer types - declare the residue calculation type Signed-off-by: Robert Jarzmik Signed-off-by: Vinod Koul --- drivers/dma/mmp_pdma.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/dma/mmp_pdma.c b/drivers/dma/mmp_pdma.c index abf1450bb25d..eb410044e1af 100644 --- a/drivers/dma/mmp_pdma.c +++ b/drivers/dma/mmp_pdma.c @@ -1002,6 +1002,9 @@ static int mmp_pdma_probe(struct platform_device *op) struct resource *iores; int i, ret, irq = 0; int dma_channels = 0, irq_num = 0; + const enum dma_slave_buswidth widths = + DMA_SLAVE_BUSWIDTH_1_BYTE | DMA_SLAVE_BUSWIDTH_2_BYTES | + DMA_SLAVE_BUSWIDTH_4_BYTES; pdev = devm_kzalloc(&op->dev, sizeof(*pdev), GFP_KERNEL); if (!pdev) @@ -1069,6 +1072,10 @@ static int mmp_pdma_probe(struct platform_device *op) pdev->device.device_config = mmp_pdma_config; pdev->device.device_terminate_all = mmp_pdma_terminate_all; pdev->device.copy_align = PDMA_ALIGNMENT; + pdev->device.src_addr_widths = widths; + pdev->device.dst_addr_widths = widths; + pdev->device.directions = BIT(DMA_MEM_TO_DEV) | BIT(DMA_DEV_TO_MEM); + pdev->device.residue_granularity = DMA_RESIDUE_GRANULARITY_DESCRIPTOR; if (pdev->dev->coherent_dma_mask) dma_set_mask(pdev->dev, pdev->dev->coherent_dma_mask); -- GitLab From 0be9653a02830637ed385d99bf898d456e8eae8f Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 5 Mar 2015 15:39:21 +0000 Subject: [PATCH 02825/11651] ASoC: wm8804: Use new devres regulator_register_notifier This is more idiomatic and also fixes an issue where the notifiers were being leaked if probe failed. Signed-off-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm8804.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c index 1bd4ace29594..7804ddf53a04 100644 --- a/sound/soc/codecs/wm8804.c +++ b/sound/soc/codecs/wm8804.c @@ -601,8 +601,10 @@ int wm8804_probe(struct device *dev, struct regmap *regmap) /* This should really be moved into the regulator core */ for (i = 0; i < ARRAY_SIZE(wm8804->supplies); i++) { - ret = regulator_register_notifier(wm8804->supplies[i].consumer, - &wm8804->disable_nb[i]); + struct regulator *regulator = wm8804->supplies[i].consumer; + + ret = devm_regulator_register_notifier(regulator, + &wm8804->disable_nb[i]); if (ret != 0) { dev_err(dev, "Failed to register regulator notifier: %d\n", @@ -662,15 +664,6 @@ EXPORT_SYMBOL_GPL(wm8804_probe); void wm8804_remove(struct device *dev) { - struct wm8804_priv *wm8804; - int i; - - wm8804 = dev_get_drvdata(dev); - - for (i = 0; i < ARRAY_SIZE(wm8804->supplies); ++i) - regulator_unregister_notifier(wm8804->supplies[i].consumer, - &wm8804->disable_nb[i]); - snd_soc_unregister_codec(dev); } EXPORT_SYMBOL_GPL(wm8804_remove); -- GitLab From fcf638f9953eb7f3b97fad7e970ae59dcdbd70c1 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 5 Mar 2015 15:39:22 +0000 Subject: [PATCH 02826/11651] ASoC: wm8804: Fix small issues in probe error paths This patch fixes some small issues on the probe error paths. Firstly, fail probe if we can't register the regulator notifiers as this will cause the cache to never be synchronised which will result in odd behaviour if the regulators are controllable. Secondly, we don't need to call regulator_bulk_disable if the enable fails, because the regulator core will handle this clean up for us. Finally, we need to disable the regulators if snd_soc_register_codecs fails. Signed-off-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm8804.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c index 7804ddf53a04..f44da83f50dc 100644 --- a/sound/soc/codecs/wm8804.c +++ b/sound/soc/codecs/wm8804.c @@ -609,6 +609,7 @@ int wm8804_probe(struct device *dev, struct regmap *regmap) dev_err(dev, "Failed to register regulator notifier: %d\n", ret); + return ret; } } @@ -616,7 +617,7 @@ int wm8804_probe(struct device *dev, struct regmap *regmap) wm8804->supplies); if (ret) { dev_err(dev, "Failed to enable supplies: %d\n", ret); - goto err_reg_enable; + return ret; } ret = regmap_read(regmap, WM8804_RST_DEVID1, &id1); @@ -653,8 +654,14 @@ int wm8804_probe(struct device *dev, struct regmap *regmap) goto err_reg_enable; } - return snd_soc_register_codec(dev, &soc_codec_dev_wm8804, - &wm8804_dai, 1); + ret = snd_soc_register_codec(dev, &soc_codec_dev_wm8804, + &wm8804_dai, 1); + if (ret < 0) { + dev_err(dev, "Failed to register CODEC: %d\n", ret); + goto err_reg_enable; + } + + return 0; err_reg_enable: regulator_bulk_disable(ARRAY_SIZE(wm8804->supplies), wm8804->supplies); -- GitLab From 45ad3e67f663af3f7988552165e8b8ebddde0ac7 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 5 Mar 2015 15:42:51 +0000 Subject: [PATCH 02827/11651] ASoC: wm8804: Update DT binding document to cover regulator supplies Signed-off-by: Charles Keepax Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/wm8804.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/sound/wm8804.txt b/Documentation/devicetree/bindings/sound/wm8804.txt index 4d3a56f38adc..10ef07606b84 100644 --- a/Documentation/devicetree/bindings/sound/wm8804.txt +++ b/Documentation/devicetree/bindings/sound/wm8804.txt @@ -10,6 +10,9 @@ Required properties: - reg : the I2C address of the device for I2C, the chip select number for SPI. + - PVDD-supply, DVDD-supply : Power supplies for the device, as covered + in Documentation/devicetree/bindings/regulator/regulator.txt + Example: codec: wm8804@1a { -- GitLab From 7f43a87e06e2f19892ff3f278e0181cbf9901b15 Mon Sep 17 00:00:00 2001 From: Matt Porter Date: Wed, 4 Mar 2015 14:12:58 -0500 Subject: [PATCH 02828/11651] spi: fsl-imx-cspi: add explicit compatible strings and required clock properties The fsl-imx-cspi binding contains language indicating compatible strings to be used that is not valid for all supported parts e.g. Should be "fsl,-cspi" or "fsl,-ecspi". Fix this by enumerating the set of valid compatible strings. The binding is also missing the clocks/clock-names properties so document these and the two required ipg and per clocks. Signed-off-by: Matt Porter Signed-off-by: Mark Brown --- .../devicetree/bindings/spi/fsl-imx-cspi.txt | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt b/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt index aad527b357a0..523341a0e113 100644 --- a/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt +++ b/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt @@ -2,11 +2,21 @@ (CSPI/eCSPI) for i.MX Required properties: -- compatible : Should be "fsl,-cspi" or "fsl,-ecspi" +- compatible : + - "fsl,imx1-cspi" for SPI compatible with the one integrated on i.MX1 + - "fsl,imx21-cspi" for SPI compatible with the one integrated on i.MX21 + - "fsl,imx27-cspi" for SPI compatible with the one integrated on i.MX27 + - "fsl,imx31-cspi" for SPI compatible with the one integrated on i.MX31 + - "fsl,imx35-cspi" for SPI compatible with the one integrated on i.MX35 + - "fsl,imx51-ecspi" for SPI compatible with the one integrated on i.MX51 - reg : Offset and length of the register set for the device - interrupts : Should contain CSPI/eCSPI interrupt - fsl,spi-num-chipselects : Contains the number of the chipselect - cs-gpios : Specifies the gpio pins to be used for chipselects. +- clocks : Clock specifiers for both ipg and per clocks. +- clock-names : Clock names should include both "ipg" and "per" +See the clock consumer binding, + Documentation/devicetree/bindings/clock/clock-bindings.txt - dmas: DMA specifiers for tx and rx dma. See the DMA client binding, Documentation/devicetree/bindings/dma/dma.txt - dma-names: DMA request names should include "tx" and "rx" if present. -- GitLab From 012baec5c1eaab7ad98b461eb7afae2faf79dbea Mon Sep 17 00:00:00 2001 From: kbuild test robot Date: Thu, 5 Mar 2015 03:37:39 +0800 Subject: [PATCH 02829/11651] ASoC: tegra: fix platform_no_drv_owner.cocci warnings sound/soc/tegra/tegra_rt5677.c:334:3-8: No need to set .owner here. The core will do it. Remove .owner field if calls are used which set it automatically Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci CC: Anatol Pomozov Signed-off-by: Fengguang Wu Signed-off-by: Mark Brown --- sound/soc/tegra/tegra_rt5677.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/tegra/tegra_rt5677.c b/sound/soc/tegra/tegra_rt5677.c index e4cf978a6e3a..4453566405ef 100644 --- a/sound/soc/tegra/tegra_rt5677.c +++ b/sound/soc/tegra/tegra_rt5677.c @@ -331,7 +331,6 @@ static const struct of_device_id tegra_rt5677_of_match[] = { static struct platform_driver tegra_rt5677_driver = { .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, .of_match_table = tegra_rt5677_of_match, }, -- GitLab From cd59f13823ae65a16b7c99fdd338ebac0c6487f2 Mon Sep 17 00:00:00 2001 From: Kenneth Westfield Date: Tue, 3 Mar 2015 16:21:53 -0800 Subject: [PATCH 02830/11651] ASoC: qcom: add LPASS header files Add the LPASS header files for ipq806x SOC. This includes the register definitions for the ipq806x LPAIF, and the structure definition for the driver data. Signed-off-by: Kenneth Westfield Acked-by: Banajit Goswami Signed-off-by: Mark Brown --- sound/soc/qcom/lpass-lpaif-ipq806x.h | 172 +++++++++++++++++++++++++++ sound/soc/qcom/lpass.h | 51 ++++++++ 2 files changed, 223 insertions(+) create mode 100644 sound/soc/qcom/lpass-lpaif-ipq806x.h create mode 100644 sound/soc/qcom/lpass.h diff --git a/sound/soc/qcom/lpass-lpaif-ipq806x.h b/sound/soc/qcom/lpass-lpaif-ipq806x.h new file mode 100644 index 000000000000..dc423b888842 --- /dev/null +++ b/sound/soc/qcom/lpass-lpaif-ipq806x.h @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2010-2011,2013-2015 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + * lpass-lpaif-ipq806x.h -- Definitions for the QTi LPAIF in the ipq806x LPASS + */ + +#ifndef __LPASS_LPAIF_H__ +#define __LPASS_LPAIF_H__ + +#define LPAIF_BANK_OFFSET 0x1000 + +/* LPAIF I2S */ + +#define LPAIF_I2SCTL_REG_BASE 0x0010 +#define LPAIF_I2SCTL_REG_STRIDE 0x4 +#define LPAIF_I2SCTL_REG_ADDR(addr, port) \ + (LPAIF_I2SCTL_REG_BASE + (addr) + (LPAIF_I2SCTL_REG_STRIDE * (port))) + +enum lpaif_i2s_ports { + LPAIF_I2S_PORT_MIN = 0, + + LPAIF_I2S_PORT_CODEC_SPK = 0, + LPAIF_I2S_PORT_CODEC_MIC = 1, + LPAIF_I2S_PORT_SEC_SPK = 2, + LPAIF_I2S_PORT_SEC_MIC = 3, + LPAIF_I2S_PORT_MI2S = 4, + + LPAIF_I2S_PORT_MAX = 4, + LPAIF_I2S_PORT_NUM = 5, +}; + +#define LPAIF_I2SCTL_REG(port) LPAIF_I2SCTL_REG_ADDR(0x0, (port)) + +#define LPAIF_I2SCTL_LOOPBACK_MASK 0x8000 +#define LPAIF_I2SCTL_LOOPBACK_SHIFT 15 +#define LPAIF_I2SCTL_LOOPBACK_DISABLE (0 << LPAIF_I2SCTL_LOOPBACK_SHIFT) +#define LPAIF_I2SCTL_LOOPBACK_ENABLE (1 << LPAIF_I2SCTL_LOOPBACK_SHIFT) + +#define LPAIF_I2SCTL_SPKEN_MASK 0x4000 +#define LPAIF_I2SCTL_SPKEN_SHIFT 14 +#define LPAIF_I2SCTL_SPKEN_DISABLE (0 << LPAIF_I2SCTL_SPKEN_SHIFT) +#define LPAIF_I2SCTL_SPKEN_ENABLE (1 << LPAIF_I2SCTL_SPKEN_SHIFT) + +#define LPAIF_I2SCTL_SPKMODE_MASK 0x3C00 +#define LPAIF_I2SCTL_SPKMODE_SHIFT 10 +#define LPAIF_I2SCTL_SPKMODE_NONE (0 << LPAIF_I2SCTL_SPKMODE_SHIFT) +#define LPAIF_I2SCTL_SPKMODE_SD0 (1 << LPAIF_I2SCTL_SPKMODE_SHIFT) +#define LPAIF_I2SCTL_SPKMODE_SD1 (2 << LPAIF_I2SCTL_SPKMODE_SHIFT) +#define LPAIF_I2SCTL_SPKMODE_SD2 (3 << LPAIF_I2SCTL_SPKMODE_SHIFT) +#define LPAIF_I2SCTL_SPKMODE_SD3 (4 << LPAIF_I2SCTL_SPKMODE_SHIFT) +#define LPAIF_I2SCTL_SPKMODE_QUAD01 (5 << LPAIF_I2SCTL_SPKMODE_SHIFT) +#define LPAIF_I2SCTL_SPKMODE_QUAD23 (6 << LPAIF_I2SCTL_SPKMODE_SHIFT) +#define LPAIF_I2SCTL_SPKMODE_6CH (7 << LPAIF_I2SCTL_SPKMODE_SHIFT) +#define LPAIF_I2SCTL_SPKMODE_8CH (8 << LPAIF_I2SCTL_SPKMODE_SHIFT) + +#define LPAIF_I2SCTL_SPKMONO_MASK 0x0200 +#define LPAIF_I2SCTL_SPKMONO_SHIFT 9 +#define LPAIF_I2SCTL_SPKMONO_STEREO (0 << LPAIF_I2SCTL_SPKMONO_SHIFT) +#define LPAIF_I2SCTL_SPKMONO_MONO (1 << LPAIF_I2SCTL_SPKMONO_SHIFT) + +#define LPAIF_I2SCTL_WSSRC_MASK 0x0004 +#define LPAIF_I2SCTL_WSSRC_SHIFT 2 +#define LPAIF_I2SCTL_WSSRC_INTERNAL (0 << LPAIF_I2SCTL_WSSRC_SHIFT) +#define LPAIF_I2SCTL_WSSRC_EXTERNAL (1 << LPAIF_I2SCTL_WSSRC_SHIFT) + +#define LPAIF_I2SCTL_BITWIDTH_MASK 0x0003 +#define LPAIF_I2SCTL_BITWIDTH_SHIFT 0 +#define LPAIF_I2SCTL_BITWIDTH_16 (0 << LPAIF_I2SCTL_BITWIDTH_SHIFT) +#define LPAIF_I2SCTL_BITWIDTH_24 (1 << LPAIF_I2SCTL_BITWIDTH_SHIFT) +#define LPAIF_I2SCTL_BITWIDTH_32 (2 << LPAIF_I2SCTL_BITWIDTH_SHIFT) + +/* LPAIF IRQ */ + +#define LPAIF_IRQ_REG_BASE 0x3000 +#define LPAIF_IRQ_REG_STRIDE 0x1000 +#define LPAIF_IRQ_REG_ADDR(addr, port) \ + (LPAIF_IRQ_REG_BASE + (addr) + (LPAIF_IRQ_REG_STRIDE * (port))) + +enum lpaif_irq_ports { + LPAIF_IRQ_PORT_MIN = 0, + + LPAIF_IRQ_PORT_HOST = 0, + LPAIF_IRQ_PORT_ADSP = 1, + + LPAIF_IRQ_PORT_MAX = 2, + LPAIF_IRQ_PORT_NUM = 3, +}; + +#define LPAIF_IRQEN_REG(port) LPAIF_IRQ_REG_ADDR(0x0, (port)) +#define LPAIF_IRQSTAT_REG(port) LPAIF_IRQ_REG_ADDR(0x4, (port)) +#define LPAIF_IRQCLEAR_REG(port) LPAIF_IRQ_REG_ADDR(0xC, (port)) + +#define LPAIF_IRQ_BITSTRIDE 3 +#define LPAIF_IRQ_PER(chan) (1 << (LPAIF_IRQ_BITSTRIDE * (chan))) +#define LPAIF_IRQ_XRUN(chan) (2 << (LPAIF_IRQ_BITSTRIDE * (chan))) +#define LPAIF_IRQ_ERR(chan) (4 << (LPAIF_IRQ_BITSTRIDE * (chan))) +#define LPAIF_IRQ_ALL(chan) (7 << (LPAIF_IRQ_BITSTRIDE * (chan))) + +/* LPAIF DMA */ + +#define LPAIF_RDMA_REG_BASE 0x6000 +#define LPAIF_RDMA_REG_STRIDE 0x1000 +#define LPAIF_RDMA_REG_ADDR(addr, chan) \ + (LPAIF_RDMA_REG_BASE + (addr) + (LPAIF_RDMA_REG_STRIDE * (chan))) + +enum lpaif_dma_channels { + LPAIF_RDMA_CHAN_MIN = 0, + + LPAIF_RDMA_CHAN_MI2S = 0, + LPAIF_RDMA_CHAN_PCM0 = 1, + LPAIF_RDMA_CHAN_PCM1 = 2, + + LPAIF_RDMA_CHAN_MAX = 4, + LPAIF_RDMA_CHAN_NUM = 5, +}; + +#define LPAIF_RDMACTL_REG(chan) LPAIF_RDMA_REG_ADDR(0x00, (chan)) +#define LPAIF_RDMABASE_REG(chan) LPAIF_RDMA_REG_ADDR(0x04, (chan)) +#define LPAIF_RDMABUFF_REG(chan) LPAIF_RDMA_REG_ADDR(0x08, (chan)) +#define LPAIF_RDMACURR_REG(chan) LPAIF_RDMA_REG_ADDR(0x0C, (chan)) +#define LPAIF_RDMAPER_REG(chan) LPAIF_RDMA_REG_ADDR(0x10, (chan)) + +#define LPAIF_RDMACTL_BURSTEN_MASK 0x800 +#define LPAIF_RDMACTL_BURSTEN_SHIFT 11 +#define LPAIF_RDMACTL_BURSTEN_SINGLE (0 << LPAIF_RDMACTL_BURSTEN_SHIFT) +#define LPAIF_RDMACTL_BURSTEN_INCR4 (1 << LPAIF_RDMACTL_BURSTEN_SHIFT) + +#define LPAIF_RDMACTL_WPSCNT_MASK 0x700 +#define LPAIF_RDMACTL_WPSCNT_SHIFT 8 +#define LPAIF_RDMACTL_WPSCNT_ONE (0 << LPAIF_RDMACTL_WPSCNT_SHIFT) +#define LPAIF_RDMACTL_WPSCNT_TWO (1 << LPAIF_RDMACTL_WPSCNT_SHIFT) +#define LPAIF_RDMACTL_WPSCNT_THREE (2 << LPAIF_RDMACTL_WPSCNT_SHIFT) +#define LPAIF_RDMACTL_WPSCNT_FOUR (3 << LPAIF_RDMACTL_WPSCNT_SHIFT) +#define LPAIF_RDMACTL_WPSCNT_SIX (5 << LPAIF_RDMACTL_WPSCNT_SHIFT) +#define LPAIF_RDMACTL_WPSCNT_EIGHT (7 << LPAIF_RDMACTL_WPSCNT_SHIFT) + +#define LPAIF_RDMACTL_AUDINTF_MASK 0x0F0 +#define LPAIF_RDMACTL_AUDINTF_SHIFT 4 +#define LPAIF_RDMACTL_AUDINTF_NONE (0 << LPAIF_RDMACTL_AUDINTF_SHIFT) +#define LPAIF_RDMACTL_AUDINTF_CODEC (1 << LPAIF_RDMACTL_AUDINTF_SHIFT) +#define LPAIF_RDMACTL_AUDINTF_PCM (2 << LPAIF_RDMACTL_AUDINTF_SHIFT) +#define LPAIF_RDMACTL_AUDINTF_SEC_I2S (3 << LPAIF_RDMACTL_AUDINTF_SHIFT) +#define LPAIF_RDMACTL_AUDINTF_MI2S (4 << LPAIF_RDMACTL_AUDINTF_SHIFT) +#define LPAIF_RDMACTL_AUDINTF_HDMI (5 << LPAIF_RDMACTL_AUDINTF_SHIFT) +#define LPAIF_RDMACTL_AUDINTF_SEC_PCM (7 << LPAIF_RDMACTL_AUDINTF_SHIFT) + +#define LPAIF_RDMACTL_FIFOWM_MASK 0x00E +#define LPAIF_RDMACTL_FIFOWM_SHIFT 1 +#define LPAIF_RDMACTL_FIFOWM_1 (0 << LPAIF_RDMACTL_FIFOWM_SHIFT) +#define LPAIF_RDMACTL_FIFOWM_2 (1 << LPAIF_RDMACTL_FIFOWM_SHIFT) +#define LPAIF_RDMACTL_FIFOWM_3 (2 << LPAIF_RDMACTL_FIFOWM_SHIFT) +#define LPAIF_RDMACTL_FIFOWM_4 (3 << LPAIF_RDMACTL_FIFOWM_SHIFT) +#define LPAIF_RDMACTL_FIFOWM_5 (4 << LPAIF_RDMACTL_FIFOWM_SHIFT) +#define LPAIF_RDMACTL_FIFOWM_6 (5 << LPAIF_RDMACTL_FIFOWM_SHIFT) +#define LPAIF_RDMACTL_FIFOWM_7 (6 << LPAIF_RDMACTL_FIFOWM_SHIFT) +#define LPAIF_RDMACTL_FIFOWM_8 (7 << LPAIF_RDMACTL_FIFOWM_SHIFT) + +#define LPAIF_RDMACTL_ENABLE_MASK 0x1 +#define LPAIF_RDMACTL_ENABLE_SHIFT 0 +#define LPAIF_RDMACTL_ENABLE_OFF (0 << LPAIF_RDMACTL_ENABLE_SHIFT) +#define LPAIF_RDMACTL_ENABLE_ON (1 << LPAIF_RDMACTL_ENABLE_SHIFT) + +#endif /* __LPASS_LPAIF_H__ */ diff --git a/sound/soc/qcom/lpass.h b/sound/soc/qcom/lpass.h new file mode 100644 index 000000000000..5c99b3dace86 --- /dev/null +++ b/sound/soc/qcom/lpass.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2010-2011,2013-2015 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + * lpass.h - Definitions for the QTi LPASS + */ + +#ifndef __LPASS_H__ +#define __LPASS_H__ + +#include +#include +#include +#include + +#define LPASS_AHBIX_CLOCK_FREQUENCY 131072000 + +/* Both the CPU DAI and platform drivers will access this data */ +struct lpass_data { + + /* AHB-I/X bus clocks inside the low-power audio subsystem (LPASS) */ + struct clk *ahbix_clk; + + /* MI2S system clock */ + struct clk *mi2s_osr_clk; + + /* MI2S bit clock (derived from system clock by a divider */ + struct clk *mi2s_bit_clk; + + /* low-power audio interface (LPAIF) registers */ + void __iomem *lpaif; + + /* regmap backed by the low-power audio interface (LPAIF) registers */ + struct regmap *lpaif_map; + + /* interrupts from the low-power audio interface (LPAIF) */ + int lpaif_irq; +}; + +/* register the platform driver from the CPU DAI driver */ +int asoc_qcom_lpass_platform_register(struct platform_device *); + +#endif /* __LPASS_H__ */ -- GitLab From 06c8173eb92bbfc03a0fe8bb64315857d0badd06 Mon Sep 17 00:00:00 2001 From: Quentin Casasnovas Date: Thu, 5 Mar 2015 13:19:22 +0100 Subject: [PATCH 02831/11651] x86/fpu/xsaves: Fix improper uses of __ex_table Commit: f31a9f7c7169 ("x86/xsaves: Use xsaves/xrstors to save and restore xsave area") introduced alternative instructions for XSAVES/XRSTORS and commit: adb9d526e982 ("x86/xsaves: Add xsaves and xrstors support for booting time") added support for the XSAVES/XRSTORS instructions at boot time. Unfortunately both failed to properly protect them against faulting: The 'xstate_fault' macro will use the closest label named '1' backward and that ends up in the .altinstr_replacement section rather than in .text. This means that the kernel will never find in the __ex_table the .text address where this instruction might fault, leading to serious problems if userspace manages to trigger the fault. Signed-off-by: Quentin Casasnovas Signed-off-by: Jamie Iles [ Improved the changelog, fixed some whitespace noise. ] Acked-by: Borislav Petkov Acked-by: Linus Torvalds Cc: Cc: Allan Xavier Cc: H. Peter Anvin Cc: Thomas Gleixner Fixes: adb9d526e982 ("x86/xsaves: Add xsaves and xrstors support for booting time") Fixes: f31a9f7c7169 ("x86/xsaves: Use xsaves/xrstors to save and restore xsave area") Signed-off-by: Ingo Molnar --- arch/x86/include/asm/xsave.h | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/arch/x86/include/asm/xsave.h b/arch/x86/include/asm/xsave.h index 5fa9770035dc..c9a6d68b8d62 100644 --- a/arch/x86/include/asm/xsave.h +++ b/arch/x86/include/asm/xsave.h @@ -82,18 +82,15 @@ static inline int xsave_state_booting(struct xsave_struct *fx, u64 mask) if (boot_cpu_has(X86_FEATURE_XSAVES)) asm volatile("1:"XSAVES"\n\t" "2:\n\t" - : : "D" (fx), "m" (*fx), "a" (lmask), "d" (hmask) + xstate_fault + : "D" (fx), "m" (*fx), "a" (lmask), "d" (hmask) : "memory"); else asm volatile("1:"XSAVE"\n\t" "2:\n\t" - : : "D" (fx), "m" (*fx), "a" (lmask), "d" (hmask) + xstate_fault + : "D" (fx), "m" (*fx), "a" (lmask), "d" (hmask) : "memory"); - - asm volatile(xstate_fault - : "0" (0) - : "memory"); - return err; } @@ -112,18 +109,15 @@ static inline int xrstor_state_booting(struct xsave_struct *fx, u64 mask) if (boot_cpu_has(X86_FEATURE_XSAVES)) asm volatile("1:"XRSTORS"\n\t" "2:\n\t" - : : "D" (fx), "m" (*fx), "a" (lmask), "d" (hmask) + xstate_fault + : "D" (fx), "m" (*fx), "a" (lmask), "d" (hmask) : "memory"); else asm volatile("1:"XRSTOR"\n\t" "2:\n\t" - : : "D" (fx), "m" (*fx), "a" (lmask), "d" (hmask) + xstate_fault + : "D" (fx), "m" (*fx), "a" (lmask), "d" (hmask) : "memory"); - - asm volatile(xstate_fault - : "0" (0) - : "memory"); - return err; } @@ -149,9 +143,9 @@ static inline int xsave_state(struct xsave_struct *fx, u64 mask) */ alternative_input_2( "1:"XSAVE, - "1:"XSAVEOPT, + XSAVEOPT, X86_FEATURE_XSAVEOPT, - "1:"XSAVES, + XSAVES, X86_FEATURE_XSAVES, [fx] "D" (fx), "a" (lmask), "d" (hmask) : "memory"); @@ -178,7 +172,7 @@ static inline int xrstor_state(struct xsave_struct *fx, u64 mask) */ alternative_input( "1: " XRSTOR, - "1: " XRSTORS, + XRSTORS, X86_FEATURE_XSAVES, "D" (fx), "m" (*fx), "a" (lmask), "d" (hmask) : "memory"); -- GitLab From 80beab8e1d86d7da843e6c3e439bbca5320c568d Mon Sep 17 00:00:00 2001 From: Kenneth Westfield Date: Tue, 3 Mar 2015 16:21:54 -0800 Subject: [PATCH 02832/11651] ASoC: qcom: Add LPASS CPU DAI driver Add the CPU DAI driver for the Qualcomm Technologies low-power audio subsystem (LPASS). Signed-off-by: Kenneth Westfield Acked-by: Banajit Goswami Signed-off-by: Mark Brown --- sound/soc/qcom/lpass-cpu.c | 510 +++++++++++++++++++++++++++++++++++++ 1 file changed, 510 insertions(+) create mode 100644 sound/soc/qcom/lpass-cpu.c diff --git a/sound/soc/qcom/lpass-cpu.c b/sound/soc/qcom/lpass-cpu.c new file mode 100644 index 000000000000..d5167131787f --- /dev/null +++ b/sound/soc/qcom/lpass-cpu.c @@ -0,0 +1,510 @@ +/* + * Copyright (c) 2010-2011,2013-2015 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + * lpass-cpu.c -- ALSA SoC CPU DAI driver for QTi LPASS + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "lpass-lpaif-ipq806x.h" +#include "lpass.h" + +static int lpass_cpu_daiops_set_sysclk(struct snd_soc_dai *dai, int clk_id, + unsigned int freq, int dir) +{ + struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai); + int ret; + + ret = clk_set_rate(drvdata->mi2s_osr_clk, freq); + if (ret) + dev_err(dai->dev, "%s() error setting mi2s osrclk to %u: %d\n", + __func__, freq, ret); + + return ret; +} + +static int lpass_cpu_daiops_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai); + int ret; + + ret = clk_prepare_enable(drvdata->mi2s_osr_clk); + if (ret) { + dev_err(dai->dev, "%s() error in enabling mi2s osr clk: %d\n", + __func__, ret); + return ret; + } + + ret = clk_prepare_enable(drvdata->mi2s_bit_clk); + if (ret) { + dev_err(dai->dev, "%s() error in enabling mi2s bit clk: %d\n", + __func__, ret); + clk_disable_unprepare(drvdata->mi2s_osr_clk); + return ret; + } + + return 0; +} + +static void lpass_cpu_daiops_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai); + + clk_disable_unprepare(drvdata->mi2s_bit_clk); + clk_disable_unprepare(drvdata->mi2s_osr_clk); +} + +static int lpass_cpu_daiops_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) +{ + struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai); + snd_pcm_format_t format = params_format(params); + unsigned int channels = params_channels(params); + unsigned int rate = params_rate(params); + unsigned int regval; + int bitwidth, ret; + + bitwidth = snd_pcm_format_width(format); + if (bitwidth < 0) { + dev_err(dai->dev, "%s() invalid bit width given: %d\n", + __func__, bitwidth); + return bitwidth; + } + + regval = LPAIF_I2SCTL_LOOPBACK_DISABLE | + LPAIF_I2SCTL_WSSRC_INTERNAL; + + switch (bitwidth) { + case 16: + regval |= LPAIF_I2SCTL_BITWIDTH_16; + break; + case 24: + regval |= LPAIF_I2SCTL_BITWIDTH_24; + break; + case 32: + regval |= LPAIF_I2SCTL_BITWIDTH_32; + break; + default: + dev_err(dai->dev, "%s() invalid bitwidth given: %d\n", + __func__, bitwidth); + return -EINVAL; + } + + switch (channels) { + case 1: + regval |= LPAIF_I2SCTL_SPKMODE_SD0; + regval |= LPAIF_I2SCTL_SPKMONO_MONO; + break; + case 2: + regval |= LPAIF_I2SCTL_SPKMODE_SD0; + regval |= LPAIF_I2SCTL_SPKMONO_STEREO; + break; + case 4: + regval |= LPAIF_I2SCTL_SPKMODE_QUAD01; + regval |= LPAIF_I2SCTL_SPKMONO_STEREO; + break; + case 6: + regval |= LPAIF_I2SCTL_SPKMODE_6CH; + regval |= LPAIF_I2SCTL_SPKMONO_STEREO; + break; + case 8: + regval |= LPAIF_I2SCTL_SPKMODE_8CH; + regval |= LPAIF_I2SCTL_SPKMONO_STEREO; + break; + default: + dev_err(dai->dev, "%s() invalid channels given: %u\n", + __func__, channels); + return -EINVAL; + } + + ret = regmap_write(drvdata->lpaif_map, + LPAIF_I2SCTL_REG(LPAIF_I2S_PORT_MI2S), regval); + if (ret) { + dev_err(dai->dev, "%s() error writing to i2sctl reg: %d\n", + __func__, ret); + return ret; + } + + ret = clk_set_rate(drvdata->mi2s_bit_clk, rate * bitwidth * 2); + if (ret) { + dev_err(dai->dev, "%s() error setting mi2s bitclk to %u: %d\n", + __func__, rate * bitwidth * 2, ret); + return ret; + } + + return 0; +} + +static int lpass_cpu_daiops_hw_free(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai); + int ret; + + ret = regmap_write(drvdata->lpaif_map, + LPAIF_I2SCTL_REG(LPAIF_I2S_PORT_MI2S), 0); + if (ret) + dev_err(dai->dev, "%s() error writing to i2sctl reg: %d\n", + __func__, ret); + + return ret; +} + +static int lpass_cpu_daiops_prepare(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai); + int ret; + + ret = regmap_update_bits(drvdata->lpaif_map, + LPAIF_I2SCTL_REG(LPAIF_I2S_PORT_MI2S), + LPAIF_I2SCTL_SPKEN_MASK, LPAIF_I2SCTL_SPKEN_ENABLE); + if (ret) + dev_err(dai->dev, "%s() error writing to i2sctl reg: %d\n", + __func__, ret); + + return ret; +} + +static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream, + int cmd, struct snd_soc_dai *dai) +{ + struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai); + int ret; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + ret = regmap_update_bits(drvdata->lpaif_map, + LPAIF_I2SCTL_REG(LPAIF_I2S_PORT_MI2S), + LPAIF_I2SCTL_SPKEN_MASK, + LPAIF_I2SCTL_SPKEN_ENABLE); + if (ret) + dev_err(dai->dev, "%s() error writing to i2sctl reg: %d\n", + __func__, ret); + break; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + ret = regmap_update_bits(drvdata->lpaif_map, + LPAIF_I2SCTL_REG(LPAIF_I2S_PORT_MI2S), + LPAIF_I2SCTL_SPKEN_MASK, + LPAIF_I2SCTL_SPKEN_DISABLE); + if (ret) + dev_err(dai->dev, "%s() error writing to i2sctl reg: %d\n", + __func__, ret); + break; + } + + return ret; +} + +static struct snd_soc_dai_ops lpass_cpu_dai_ops = { + .set_sysclk = lpass_cpu_daiops_set_sysclk, + .startup = lpass_cpu_daiops_startup, + .shutdown = lpass_cpu_daiops_shutdown, + .hw_params = lpass_cpu_daiops_hw_params, + .hw_free = lpass_cpu_daiops_hw_free, + .prepare = lpass_cpu_daiops_prepare, + .trigger = lpass_cpu_daiops_trigger, +}; + +static int lpass_cpu_dai_probe(struct snd_soc_dai *dai) +{ + struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai); + int ret; + + /* ensure audio hardware is disabled */ + ret = regmap_write(drvdata->lpaif_map, + LPAIF_I2SCTL_REG(LPAIF_I2S_PORT_MI2S), 0); + if (ret) + dev_err(dai->dev, "%s() error writing to i2sctl reg: %d\n", + __func__, ret); + + return ret; +} + +static struct snd_soc_dai_driver lpass_cpu_dai_driver = { + .playback = { + .stream_name = "lpass-cpu-playback", + .formats = SNDRV_PCM_FMTBIT_S16 | + SNDRV_PCM_FMTBIT_S24 | + SNDRV_PCM_FMTBIT_S32, + .rates = SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | + SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_96000, + .rate_min = 8000, + .rate_max = 96000, + .channels_min = 1, + .channels_max = 8, + }, + .probe = &lpass_cpu_dai_probe, + .ops = &lpass_cpu_dai_ops, +}; + +static const struct snd_soc_component_driver lpass_cpu_comp_driver = { + .name = "lpass-cpu", +}; + +static bool lpass_cpu_regmap_writeable(struct device *dev, unsigned int reg) +{ + int i; + + for (i = 0; i < LPAIF_I2S_PORT_NUM; ++i) + if (reg == LPAIF_I2SCTL_REG(i)) + return true; + + for (i = 0; i < LPAIF_IRQ_PORT_NUM; ++i) { + if (reg == LPAIF_IRQEN_REG(i)) + return true; + if (reg == LPAIF_IRQCLEAR_REG(i)) + return true; + } + + for (i = 0; i < LPAIF_RDMA_CHAN_NUM; ++i) { + if (reg == LPAIF_RDMACTL_REG(i)) + return true; + if (reg == LPAIF_RDMABASE_REG(i)) + return true; + if (reg == LPAIF_RDMABUFF_REG(i)) + return true; + if (reg == LPAIF_RDMAPER_REG(i)) + return true; + } + + return false; +} + +static bool lpass_cpu_regmap_readable(struct device *dev, unsigned int reg) +{ + int i; + + for (i = 0; i < LPAIF_I2S_PORT_NUM; ++i) + if (reg == LPAIF_I2SCTL_REG(i)) + return true; + + for (i = 0; i < LPAIF_IRQ_PORT_NUM; ++i) { + if (reg == LPAIF_IRQEN_REG(i)) + return true; + if (reg == LPAIF_IRQSTAT_REG(i)) + return true; + } + + for (i = 0; i < LPAIF_RDMA_CHAN_NUM; ++i) { + if (reg == LPAIF_RDMACTL_REG(i)) + return true; + if (reg == LPAIF_RDMABASE_REG(i)) + return true; + if (reg == LPAIF_RDMABUFF_REG(i)) + return true; + if (reg == LPAIF_RDMACURR_REG(i)) + return true; + if (reg == LPAIF_RDMAPER_REG(i)) + return true; + } + + return false; +} + +static bool lpass_cpu_regmap_volatile(struct device *dev, unsigned int reg) +{ + int i; + + for (i = 0; i < LPAIF_IRQ_PORT_NUM; ++i) + if (reg == LPAIF_IRQSTAT_REG(i)) + return true; + + for (i = 0; i < LPAIF_RDMA_CHAN_NUM; ++i) + if (reg == LPAIF_RDMACURR_REG(i)) + return true; + + return false; +} + +static const struct regmap_config lpass_cpu_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = LPAIF_RDMAPER_REG(LPAIF_RDMA_CHAN_MAX), + .writeable_reg = lpass_cpu_regmap_writeable, + .readable_reg = lpass_cpu_regmap_readable, + .volatile_reg = lpass_cpu_regmap_volatile, + .cache_type = REGCACHE_FLAT, +}; + +static int lpass_cpu_parse_of(struct device *dev) +{ + struct device_node *dsp_of_node; + + dsp_of_node = of_get_child_by_name(dev->of_node, "qcom,adsp"); + if (!dsp_of_node) { + dev_err(dev, "%s() error getting qcom,adsp sub-node\n", + __func__); + return -EINVAL; + } + + if (of_device_is_available(dsp_of_node)) { + dev_err(dev, "%s() DSP exists and holds audio resources\n", + __func__); + return -EBUSY; + } + + return 0; +} + +static int lpass_cpu_platform_probe(struct platform_device *pdev) +{ + struct lpass_data *drvdata; + struct resource *res; + int ret; + + drvdata = devm_kzalloc(&pdev->dev, sizeof(struct lpass_data), + GFP_KERNEL); + if (!drvdata) + return -ENOMEM; + platform_set_drvdata(pdev, drvdata); + + ret = lpass_cpu_parse_of(&pdev->dev); + if (ret) { + dev_err(&pdev->dev, "%s() error getting DT node info: %d\n", + __func__, ret); + return ret; + } + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "lpass-lpaif"); + if (!res) { + dev_err(&pdev->dev, "%s() error getting resource\n", __func__); + return -ENODEV; + } + + drvdata->lpaif = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR((void const __force *)drvdata->lpaif)) { + dev_err(&pdev->dev, "%s() error mapping reg resource: %ld\n", + __func__, + PTR_ERR((void const __force *)drvdata->lpaif)); + return PTR_ERR((void const __force *)drvdata->lpaif); + } + + drvdata->lpaif_map = devm_regmap_init_mmio(&pdev->dev, drvdata->lpaif, + &lpass_cpu_regmap_config); + if (IS_ERR(drvdata->lpaif_map)) { + dev_err(&pdev->dev, "%s() error initializing regmap: %ld\n", + __func__, PTR_ERR(drvdata->lpaif_map)); + return PTR_ERR(drvdata->lpaif_map); + } + + drvdata->mi2s_osr_clk = devm_clk_get(&pdev->dev, "mi2s-osr-clk"); + if (IS_ERR(drvdata->mi2s_osr_clk)) { + dev_err(&pdev->dev, "%s() error getting mi2s-osr-clk: %ld\n", + __func__, PTR_ERR(drvdata->mi2s_osr_clk)); + return PTR_ERR(drvdata->mi2s_osr_clk); + } + + drvdata->mi2s_bit_clk = devm_clk_get(&pdev->dev, "mi2s-bit-clk"); + if (IS_ERR(drvdata->mi2s_bit_clk)) { + dev_err(&pdev->dev, "%s() error getting mi2s-bit-clk: %ld\n", + __func__, PTR_ERR(drvdata->mi2s_bit_clk)); + return PTR_ERR(drvdata->mi2s_bit_clk); + } + + drvdata->ahbix_clk = devm_clk_get(&pdev->dev, "ahbix-clk"); + if (IS_ERR(drvdata->ahbix_clk)) { + dev_err(&pdev->dev, "%s() error getting ahbix-clk: %ld\n", + __func__, PTR_ERR(drvdata->ahbix_clk)); + return PTR_ERR(drvdata->ahbix_clk); + } + + ret = clk_set_rate(drvdata->ahbix_clk, LPASS_AHBIX_CLOCK_FREQUENCY); + if (ret) { + dev_err(&pdev->dev, "%s() error setting rate on ahbix_clk: %d\n", + __func__, ret); + return ret; + } + dev_dbg(&pdev->dev, "%s() set ahbix_clk rate to %lu\n", __func__, + clk_get_rate(drvdata->ahbix_clk)); + + ret = clk_prepare_enable(drvdata->ahbix_clk); + if (ret) { + dev_err(&pdev->dev, "%s() error enabling ahbix_clk: %d\n", + __func__, ret); + return ret; + } + + ret = devm_snd_soc_register_component(&pdev->dev, + &lpass_cpu_comp_driver, &lpass_cpu_dai_driver, 1); + if (ret) { + dev_err(&pdev->dev, "%s() error registering cpu driver: %d\n", + __func__, ret); + goto err_clk; + } + + ret = asoc_qcom_lpass_platform_register(pdev); + if (ret) { + dev_err(&pdev->dev, "%s() error registering platform driver: %d\n", + __func__, ret); + goto err_clk; + } + + return 0; + +err_clk: + clk_disable_unprepare(drvdata->ahbix_clk); + return ret; +} + +static int lpass_cpu_platform_remove(struct platform_device *pdev) +{ + struct lpass_data *drvdata = platform_get_drvdata(pdev); + + clk_disable_unprepare(drvdata->ahbix_clk); + + return 0; +} + +#ifdef CONFIG_OF +static const struct of_device_id lpass_cpu_device_id[] = { + { .compatible = "qcom,lpass-cpu" }, + {} +}; +MODULE_DEVICE_TABLE(of, lpass_cpu_device_id); +#endif + +static struct platform_driver lpass_cpu_platform_driver = { + .driver = { + .name = "lpass-cpu", + .of_match_table = of_match_ptr(lpass_cpu_device_id), + }, + .probe = lpass_cpu_platform_probe, + .remove = lpass_cpu_platform_remove, +}; +module_platform_driver(lpass_cpu_platform_driver); + +MODULE_DESCRIPTION("QTi LPASS CPU Driver"); +MODULE_LICENSE("GPL v2"); -- GitLab From c5c8635a04711c7a7aca82f90e6b1e6df1c057be Mon Sep 17 00:00:00 2001 From: Kenneth Westfield Date: Tue, 3 Mar 2015 16:21:55 -0800 Subject: [PATCH 02833/11651] ASoC: qcom: Add LPASS platform driver Add platform driver for the Qualcomm Technologies low-power audio subsystem (LPASS) ports. Signed-off-by: Kenneth Westfield Acked-by: Banajit Goswami Signed-off-by: Mark Brown --- sound/soc/qcom/lpass-platform.c | 526 ++++++++++++++++++++++++++++++++ 1 file changed, 526 insertions(+) create mode 100644 sound/soc/qcom/lpass-platform.c diff --git a/sound/soc/qcom/lpass-platform.c b/sound/soc/qcom/lpass-platform.c new file mode 100644 index 000000000000..2fa6280dfb23 --- /dev/null +++ b/sound/soc/qcom/lpass-platform.c @@ -0,0 +1,526 @@ +/* + * Copyright (c) 2010-2011,2013-2015 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + * lpass-platform.c -- ALSA SoC platform driver for QTi LPASS + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "lpass-lpaif-ipq806x.h" +#include "lpass.h" + +#define LPASS_PLATFORM_BUFFER_SIZE (16 * 1024) +#define LPASS_PLATFORM_PERIODS 2 + +static struct snd_pcm_hardware lpass_platform_pcm_hardware = { + .info = SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_PAUSE | + SNDRV_PCM_INFO_RESUME, + .formats = SNDRV_PCM_FMTBIT_S16 | + SNDRV_PCM_FMTBIT_S24 | + SNDRV_PCM_FMTBIT_S32, + .rates = SNDRV_PCM_RATE_8000_192000, + .rate_min = 8000, + .rate_max = 192000, + .channels_min = 1, + .channels_max = 8, + .buffer_bytes_max = LPASS_PLATFORM_BUFFER_SIZE, + .period_bytes_max = LPASS_PLATFORM_BUFFER_SIZE / + LPASS_PLATFORM_PERIODS, + .period_bytes_min = LPASS_PLATFORM_BUFFER_SIZE / + LPASS_PLATFORM_PERIODS, + .periods_min = LPASS_PLATFORM_PERIODS, + .periods_max = LPASS_PLATFORM_PERIODS, + .fifo_size = 0, +}; + +static int lpass_platform_pcmops_open(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; + int ret; + + snd_soc_set_runtime_hwparams(substream, &lpass_platform_pcm_hardware); + + runtime->dma_bytes = lpass_platform_pcm_hardware.buffer_bytes_max; + + ret = snd_pcm_hw_constraint_integer(runtime, + SNDRV_PCM_HW_PARAM_PERIODS); + if (ret < 0) { + dev_err(soc_runtime->dev, "%s() setting constraints failed: %d\n", + __func__, ret); + return -EINVAL; + } + + snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); + + return 0; +} + +static int lpass_platform_pcmops_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; + struct lpass_data *drvdata = + snd_soc_platform_get_drvdata(soc_runtime->platform); + snd_pcm_format_t format = params_format(params); + unsigned int channels = params_channels(params); + unsigned int regval; + int bitwidth; + int ret; + + bitwidth = snd_pcm_format_width(format); + if (bitwidth < 0) { + dev_err(soc_runtime->dev, "%s() invalid bit width given: %d\n", + __func__, bitwidth); + return bitwidth; + } + + regval = LPAIF_RDMACTL_BURSTEN_INCR4 | + LPAIF_RDMACTL_AUDINTF_MI2S | + LPAIF_RDMACTL_FIFOWM_8; + + switch (bitwidth) { + case 16: + switch (channels) { + case 1: + case 2: + regval |= LPAIF_RDMACTL_WPSCNT_ONE; + break; + case 4: + regval |= LPAIF_RDMACTL_WPSCNT_TWO; + break; + case 6: + regval |= LPAIF_RDMACTL_WPSCNT_THREE; + break; + case 8: + regval |= LPAIF_RDMACTL_WPSCNT_FOUR; + break; + default: + dev_err(soc_runtime->dev, "%s() invalid PCM config given: bw=%d, ch=%u\n", + __func__, bitwidth, channels); + return -EINVAL; + } + break; + case 24: + case 32: + switch (channels) { + case 1: + regval |= LPAIF_RDMACTL_WPSCNT_ONE; + break; + case 2: + regval |= LPAIF_RDMACTL_WPSCNT_TWO; + break; + case 4: + regval |= LPAIF_RDMACTL_WPSCNT_FOUR; + break; + case 6: + regval |= LPAIF_RDMACTL_WPSCNT_SIX; + break; + case 8: + regval |= LPAIF_RDMACTL_WPSCNT_EIGHT; + break; + default: + dev_err(soc_runtime->dev, "%s() invalid PCM config given: bw=%d, ch=%u\n", + __func__, bitwidth, channels); + return -EINVAL; + } + break; + default: + dev_err(soc_runtime->dev, "%s() invalid PCM config given: bw=%d, ch=%u\n", + __func__, bitwidth, channels); + return -EINVAL; + } + + ret = regmap_write(drvdata->lpaif_map, + LPAIF_RDMACTL_REG(LPAIF_RDMA_CHAN_MI2S), regval); + if (ret) { + dev_err(soc_runtime->dev, "%s() error writing to rdmactl reg: %d\n", + __func__, ret); + return ret; + } + + return 0; +} + +static int lpass_platform_pcmops_hw_free(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; + struct lpass_data *drvdata = + snd_soc_platform_get_drvdata(soc_runtime->platform); + int ret; + + ret = regmap_write(drvdata->lpaif_map, + LPAIF_RDMACTL_REG(LPAIF_RDMA_CHAN_MI2S), 0); + if (ret) + dev_err(soc_runtime->dev, "%s() error writing to rdmactl reg: %d\n", + __func__, ret); + + return ret; +} + +static int lpass_platform_pcmops_prepare(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; + struct lpass_data *drvdata = + snd_soc_platform_get_drvdata(soc_runtime->platform); + int ret; + + ret = regmap_write(drvdata->lpaif_map, + LPAIF_RDMABASE_REG(LPAIF_RDMA_CHAN_MI2S), + runtime->dma_addr); + if (ret) { + dev_err(soc_runtime->dev, "%s() error writing to rdmabase reg: %d\n", + __func__, ret); + return ret; + } + + ret = regmap_write(drvdata->lpaif_map, + LPAIF_RDMABUFF_REG(LPAIF_RDMA_CHAN_MI2S), + (snd_pcm_lib_buffer_bytes(substream) >> 2) - 1); + if (ret) { + dev_err(soc_runtime->dev, "%s() error writing to rdmabuff reg: %d\n", + __func__, ret); + return ret; + } + + ret = regmap_write(drvdata->lpaif_map, + LPAIF_RDMAPER_REG(LPAIF_RDMA_CHAN_MI2S), + (snd_pcm_lib_period_bytes(substream) >> 2) - 1); + if (ret) { + dev_err(soc_runtime->dev, "%s() error writing to rdmaper reg: %d\n", + __func__, ret); + return ret; + } + + ret = regmap_update_bits(drvdata->lpaif_map, + LPAIF_RDMACTL_REG(LPAIF_RDMA_CHAN_MI2S), + LPAIF_RDMACTL_ENABLE_MASK, LPAIF_RDMACTL_ENABLE_ON); + if (ret) { + dev_err(soc_runtime->dev, "%s() error writing to rdmactl reg: %d\n", + __func__, ret); + return ret; + } + + return 0; +} + +static int lpass_platform_pcmops_trigger(struct snd_pcm_substream *substream, + int cmd) +{ + struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; + struct lpass_data *drvdata = + snd_soc_platform_get_drvdata(soc_runtime->platform); + int ret; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + /* clear status before enabling interrupts */ + ret = regmap_write(drvdata->lpaif_map, + LPAIF_IRQCLEAR_REG(LPAIF_IRQ_PORT_HOST), + LPAIF_IRQ_ALL(LPAIF_RDMA_CHAN_MI2S)); + if (ret) { + dev_err(soc_runtime->dev, "%s() error writing to irqclear reg: %d\n", + __func__, ret); + return ret; + } + + ret = regmap_update_bits(drvdata->lpaif_map, + LPAIF_IRQEN_REG(LPAIF_IRQ_PORT_HOST), + LPAIF_IRQ_ALL(LPAIF_RDMA_CHAN_MI2S), + LPAIF_IRQ_ALL(LPAIF_RDMA_CHAN_MI2S)); + if (ret) { + dev_err(soc_runtime->dev, "%s() error writing to irqen reg: %d\n", + __func__, ret); + return ret; + } + + ret = regmap_update_bits(drvdata->lpaif_map, + LPAIF_RDMACTL_REG(LPAIF_RDMA_CHAN_MI2S), + LPAIF_RDMACTL_ENABLE_MASK, + LPAIF_RDMACTL_ENABLE_ON); + if (ret) { + dev_err(soc_runtime->dev, "%s() error writing to rdmactl reg: %d\n", + __func__, ret); + return ret; + } + break; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + ret = regmap_update_bits(drvdata->lpaif_map, + LPAIF_RDMACTL_REG(LPAIF_RDMA_CHAN_MI2S), + LPAIF_RDMACTL_ENABLE_MASK, + LPAIF_RDMACTL_ENABLE_OFF); + if (ret) { + dev_err(soc_runtime->dev, "%s() error writing to rdmactl reg: %d\n", + __func__, ret); + return ret; + } + + ret = regmap_update_bits(drvdata->lpaif_map, + LPAIF_IRQEN_REG(LPAIF_IRQ_PORT_HOST), + LPAIF_IRQ_ALL(LPAIF_RDMA_CHAN_MI2S), 0); + if (ret) { + dev_err(soc_runtime->dev, "%s() error writing to irqen reg: %d\n", + __func__, ret); + return ret; + } + break; + } + + return 0; +} + +static snd_pcm_uframes_t lpass_platform_pcmops_pointer( + struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; + struct lpass_data *drvdata = + snd_soc_platform_get_drvdata(soc_runtime->platform); + unsigned int base_addr, curr_addr; + int ret; + + ret = regmap_read(drvdata->lpaif_map, + LPAIF_RDMABASE_REG(LPAIF_RDMA_CHAN_MI2S), &base_addr); + if (ret) { + dev_err(soc_runtime->dev, "%s() error reading from rdmabase reg: %d\n", + __func__, ret); + return ret; + } + + ret = regmap_read(drvdata->lpaif_map, + LPAIF_RDMACURR_REG(LPAIF_RDMA_CHAN_MI2S), &curr_addr); + if (ret) { + dev_err(soc_runtime->dev, "%s() error reading from rdmacurr reg: %d\n", + __func__, ret); + return ret; + } + + return bytes_to_frames(substream->runtime, curr_addr - base_addr); +} + +static int lpass_platform_pcmops_mmap(struct snd_pcm_substream *substream, + struct vm_area_struct *vma) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + + return dma_mmap_coherent(substream->pcm->card->dev, vma, + runtime->dma_area, runtime->dma_addr, + runtime->dma_bytes); +} + +static struct snd_pcm_ops lpass_platform_pcm_ops = { + .open = lpass_platform_pcmops_open, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = lpass_platform_pcmops_hw_params, + .hw_free = lpass_platform_pcmops_hw_free, + .prepare = lpass_platform_pcmops_prepare, + .trigger = lpass_platform_pcmops_trigger, + .pointer = lpass_platform_pcmops_pointer, + .mmap = lpass_platform_pcmops_mmap, +}; + +static irqreturn_t lpass_platform_lpaif_irq(int irq, void *data) +{ + struct snd_pcm_substream *substream = data; + struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; + struct lpass_data *drvdata = + snd_soc_platform_get_drvdata(soc_runtime->platform); + unsigned int interrupts; + irqreturn_t ret = IRQ_NONE; + int rv; + + rv = regmap_read(drvdata->lpaif_map, + LPAIF_IRQSTAT_REG(LPAIF_IRQ_PORT_HOST), &interrupts); + if (rv) { + dev_err(soc_runtime->dev, "%s() error reading from irqstat reg: %d\n", + __func__, rv); + return IRQ_NONE; + } + interrupts &= LPAIF_IRQ_ALL(LPAIF_RDMA_CHAN_MI2S); + + if (interrupts & LPAIF_IRQ_PER(LPAIF_RDMA_CHAN_MI2S)) { + rv = regmap_write(drvdata->lpaif_map, + LPAIF_IRQCLEAR_REG(LPAIF_IRQ_PORT_HOST), + LPAIF_IRQ_PER(LPAIF_RDMA_CHAN_MI2S)); + if (rv) { + dev_err(soc_runtime->dev, "%s() error writing to irqclear reg: %d\n", + __func__, rv); + return IRQ_NONE; + } + snd_pcm_period_elapsed(substream); + ret = IRQ_HANDLED; + } + + if (interrupts & LPAIF_IRQ_XRUN(LPAIF_RDMA_CHAN_MI2S)) { + rv = regmap_write(drvdata->lpaif_map, + LPAIF_IRQCLEAR_REG(LPAIF_IRQ_PORT_HOST), + LPAIF_IRQ_XRUN(LPAIF_RDMA_CHAN_MI2S)); + if (rv) { + dev_err(soc_runtime->dev, "%s() error writing to irqclear reg: %d\n", + __func__, rv); + return IRQ_NONE; + } + dev_warn(soc_runtime->dev, "%s() xrun warning\n", __func__); + snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); + ret = IRQ_HANDLED; + } + + if (interrupts & LPAIF_IRQ_ERR(LPAIF_RDMA_CHAN_MI2S)) { + rv = regmap_write(drvdata->lpaif_map, + LPAIF_IRQCLEAR_REG(LPAIF_IRQ_PORT_HOST), + LPAIF_IRQ_ERR(LPAIF_RDMA_CHAN_MI2S)); + if (rv) { + dev_err(soc_runtime->dev, "%s() error writing to irqclear reg: %d\n", + __func__, rv); + return IRQ_NONE; + } + dev_err(soc_runtime->dev, "%s() bus access error\n", __func__); + snd_pcm_stop(substream, SNDRV_PCM_STATE_DISCONNECTED); + ret = IRQ_HANDLED; + } + + return ret; +} + +static int lpass_platform_alloc_buffer(struct snd_pcm_substream *substream, + struct snd_soc_pcm_runtime *soc_runtime) +{ + struct snd_dma_buffer *buf = &substream->dma_buffer; + size_t size = lpass_platform_pcm_hardware.buffer_bytes_max; + + buf->dev.type = SNDRV_DMA_TYPE_DEV; + buf->dev.dev = soc_runtime->dev; + buf->private_data = NULL; + buf->area = dma_alloc_coherent(soc_runtime->dev, size, &buf->addr, + GFP_KERNEL); + if (!buf->area) { + dev_err(soc_runtime->dev, "%s: Could not allocate DMA buffer\n", + __func__); + return -ENOMEM; + } + buf->bytes = size; + + return 0; +} + +static void lpass_platform_free_buffer(struct snd_pcm_substream *substream, + struct snd_soc_pcm_runtime *soc_runtime) +{ + struct snd_dma_buffer *buf = &substream->dma_buffer; + + if (buf->area) { + dma_free_coherent(soc_runtime->dev, buf->bytes, buf->area, + buf->addr); + } + buf->area = NULL; +} + +static int lpass_platform_pcm_new(struct snd_soc_pcm_runtime *soc_runtime) +{ + struct snd_pcm *pcm = soc_runtime->pcm; + struct snd_pcm_substream *substream = + pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; + struct lpass_data *drvdata = + snd_soc_platform_get_drvdata(soc_runtime->platform); + int ret; + + soc_runtime->dev->coherent_dma_mask = DMA_BIT_MASK(32); + soc_runtime->dev->dma_mask = &soc_runtime->dev->coherent_dma_mask; + + ret = lpass_platform_alloc_buffer(substream, soc_runtime); + if (ret) + return ret; + + ret = devm_request_irq(soc_runtime->dev, drvdata->lpaif_irq, + lpass_platform_lpaif_irq, IRQF_TRIGGER_RISING, + "lpass-irq-lpaif", substream); + if (ret) { + dev_err(soc_runtime->dev, "%s() irq request failed: %d\n", + __func__, ret); + goto err_buf; + } + + /* ensure audio hardware is disabled */ + ret = regmap_write(drvdata->lpaif_map, + LPAIF_IRQEN_REG(LPAIF_IRQ_PORT_HOST), 0); + if (ret) { + dev_err(soc_runtime->dev, "%s() error writing to irqen reg: %d\n", + __func__, ret); + return ret; + } + ret = regmap_write(drvdata->lpaif_map, + LPAIF_RDMACTL_REG(LPAIF_RDMA_CHAN_MI2S), 0); + if (ret) { + dev_err(soc_runtime->dev, "%s() error writing to rdmactl reg: %d\n", + __func__, ret); + return ret; + } + + return 0; + +err_buf: + lpass_platform_free_buffer(substream, soc_runtime); + return ret; +} + +static void lpass_platform_pcm_free(struct snd_pcm *pcm) +{ + struct snd_pcm_substream *substream = + pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; + struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; + + lpass_platform_free_buffer(substream, soc_runtime); +} + +static struct snd_soc_platform_driver lpass_platform_driver = { + .pcm_new = lpass_platform_pcm_new, + .pcm_free = lpass_platform_pcm_free, + .ops = &lpass_platform_pcm_ops, +}; + +int asoc_qcom_lpass_platform_register(struct platform_device *pdev) +{ + struct lpass_data *drvdata = platform_get_drvdata(pdev); + + drvdata->lpaif_irq = platform_get_irq_byname(pdev, "lpass-irq-lpaif"); + if (drvdata->lpaif_irq < 0) { + dev_err(&pdev->dev, "%s() error getting irq handle: %d\n", + __func__, drvdata->lpaif_irq); + return -ENODEV; + } + + return devm_snd_soc_register_platform(&pdev->dev, + &lpass_platform_driver); +} +EXPORT_SYMBOL_GPL(asoc_qcom_lpass_platform_register); + +MODULE_DESCRIPTION("QTi LPASS Platform Driver"); +MODULE_LICENSE("GPL v2"); -- GitLab From 8dd72c42d38e62b82d7e3c47173b502d851c48ad Mon Sep 17 00:00:00 2001 From: Kenneth Westfield Date: Tue, 3 Mar 2015 16:21:51 -0800 Subject: [PATCH 02834/11651] ASoC: qcom: Document LPASS CPU bindings Add documentation to the sound directory of the device-tree bindings for the QTi LPASS CPU DAI device. Signed-off-by: Kenneth Westfield Acked-by: Banajit Goswami Signed-off-by: Mark Brown --- .../bindings/sound/qcom,lpass-cpu.txt | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/qcom,lpass-cpu.txt diff --git a/Documentation/devicetree/bindings/sound/qcom,lpass-cpu.txt b/Documentation/devicetree/bindings/sound/qcom,lpass-cpu.txt new file mode 100644 index 000000000000..e7c6e9321863 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/qcom,lpass-cpu.txt @@ -0,0 +1,49 @@ +* Qualcomm Technologies LPASS CPU DAI + +This node models the Qualcomm Technologies Low-Power Audio SubSystem (LPASS). + +Required properties: + +- compatible : "qcom,lpass-cpu" +- clocks : Must contain an entry for each entry in clock-names. +- clock-names : A list which must include the following entries: + * "ahbix-clk" + * "mi2s-osr-clk" + * "mi2s-bit-clk" +- interrupts : Must contain an entry for each entry in + interrupt-names. +- interrupt-names : A list which must include the following entries: + * "lpass-irq-lpaif" +- pinctrl-N : One property must exist for each entry in + pinctrl-names. See ../pinctrl/pinctrl-bindings.txt + for details of the property values. +- pinctrl-names : Must contain a "default" entry. +- reg : Must contain an address for each entry in reg-names. +- reg-names : A list which must include the following entries: + * "lpass-lpaif" + +Required subnodes: + +- qcom,adsp : Audio DSP sub-node + +Optional Audio DSP subnode properties: + +- status : "disabled" indicates the adsp is not available. + +Example: + +lpass@28100000 { + compatible = "qcom,lpass-cpu"; + clocks = <&lcc AHBIX_CLK>, <&lcc MI2S_OSR_CLK>, <&lcc MI2S_BIT_CLK>; + clock-names = "ahbix-clk", "mi2s-osr-clk", "mi2s-bit-clk"; + interrupts = <0 85 1>; + interrupt-names = "lpass-irq-lpaif"; + pinctrl-names = "default", "idle"; + pinctrl-0 = <&mi2s_default>; + pinctrl-1 = <&mi2s_idle>; + reg = <0x28100000 0x10000>; + reg-names = "lpass-lpaif"; + qcom,adsp { + status = "disabled"; + }; +}; -- GitLab From 2d800897e868ba561733ecffb30d840cbe5c86d4 Mon Sep 17 00:00:00 2001 From: Kenneth Westfield Date: Tue, 3 Mar 2015 16:21:50 -0800 Subject: [PATCH 02835/11651] MAINTAINERS: Add QCOM audio ASoC maintainer Add maintainers for the Qualcomm Technologies sound drivers. Signed-off-by: Kenneth Westfield Acked-by: Banajit Goswami Signed-off-by: Mark Brown --- MAINTAINERS | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index ddc5a8cf9a8a..9514b794b74d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5254,6 +5254,13 @@ F: drivers/char/ipmi/ F: include/linux/ipmi* F: include/uapi/linux/ipmi* +QCOM AUDIO (ASoC) DRIVERS +M: Patrick Lai +M: Banajit Goswami +L: alsa-devel@alsa-project.org (moderated for non-subscribers) +S: Supported +F: sound/soc/qcom/ + IPS SCSI RAID DRIVER M: Adaptec OEM Raid Solutions L: linux-scsi@vger.kernel.org -- GitLab From 1b42085af787eb2e465863ba82633bbd905a7897 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Thu, 26 Feb 2015 01:54:51 -0300 Subject: [PATCH 02836/11651] regulator: wm8350: Remove unused variable Commit 8f45acb5f9f34eab ("regulator: wm8350: Pass NULL data with REGULATION_OUT and UNDER_VOLTAGE events") introduced the following build warning: drivers/regulator/wm8350-regulator.c: In function 'pmic_uv_handler': drivers/regulator/wm8350-regulator.c:1154:17: warning: unused variable 'wm8350' [-Wunused-variable] Remove 'wm8350' as it is unused now. Signed-off-by: Fabio Estevam Acked-by: Geert Uytterhoeven Signed-off-by: Mark Brown --- drivers/regulator/wm8350-regulator.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/regulator/wm8350-regulator.c b/drivers/regulator/wm8350-regulator.c index 78efead3b39f..95f6b040186e 100644 --- a/drivers/regulator/wm8350-regulator.c +++ b/drivers/regulator/wm8350-regulator.c @@ -1151,7 +1151,6 @@ static const struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = { static irqreturn_t pmic_uv_handler(int irq, void *data) { struct regulator_dev *rdev = (struct regulator_dev *)data; - struct wm8350 *wm8350 = rdev_get_drvdata(rdev); mutex_lock(&rdev->mutex); if (irq == WM8350_IRQ_CS1 || irq == WM8350_IRQ_CS2) -- GitLab From 787fb2bd42b9d798f4ed85b66e878222a9e28ae6 Mon Sep 17 00:00:00 2001 From: kbuild test robot Date: Thu, 5 Mar 2015 06:54:00 -0600 Subject: [PATCH 02837/11651] ax25: Fix the build when CONFIG_INET is disabled > > >> net/ax25/ax25_ip.c:225:26: error: unknown type name 'sturct' > netdev_tx_t ax25_ip_xmit(sturct sk_buff *skb) > ^ > > vim +/sturct +225 net/ax25/ax25_ip.c > > 219 unsigned short type, const void *daddr, > 220 const void *saddr, unsigned int len) > 221 { > 222 return -AX25_HEADER_LEN; > 223 } > 224 > > 225 netdev_tx_t ax25_ip_xmit(sturct sk_buff *skb) > 226 { > 227 kfree_skb(skb); > 228 return NETDEV_TX_OK; Ooops I misspelled struct... Signed-off-by: "Eric W. Biederman" Signed-off-by: David S. Miller --- net/ax25/ax25_ip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ax25/ax25_ip.c b/net/ax25/ax25_ip.c index 8b35af4ef93e..7c646bb2c6f7 100644 --- a/net/ax25/ax25_ip.c +++ b/net/ax25/ax25_ip.c @@ -222,7 +222,7 @@ static int ax25_hard_header(struct sk_buff *skb, struct net_device *dev, return -AX25_HEADER_LEN; } -netdev_tx_t ax25_ip_xmit(sturct sk_buff *skb) +netdev_tx_t ax25_ip_xmit(struct sk_buff *skb) { kfree_skb(skb); return NETDEV_TX_OK; -- GitLab From 3995614d9b0320e10ce202836c8477e1bcf1a2d4 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 5 Mar 2015 15:27:28 -0300 Subject: [PATCH 02838/11651] perf annotate: Fix fallback to unparsed disassembler line When annotating source/disasm lines the perf tools parse the output of objdump, trying to provide augmented output that allows navigating jumps, calls, etc. But when a line output by objdump can't be parsed the annotation code falls back to just presenting the unparsed line. When fixing a leak in the 0fb9f2aab738 commit ("perf annotate: Fix memory leaks in LOCK handling") we failed to take that into account and instead tried to free one of the data structures that should be freed only when successfully allocated, oops, segfault. There was a change in the way the objdump output for lock prefixed instructions is formatted that lead the relevant parser to fail to grok it. At least RHEL7 works ok, but Fedora 20 segfaults. Fix it by making the ins__delete() destructor work like the most basic destructor: free(). Namely make it accept a NULL pointer and when handling it just do nothing. Further investigation is needed to figure out the nature of the objdump output change so as to make the parser grok it. Reported-by: Linus Torvalds Cc: David Ahern Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Rabin Vincent Link: http://lkml.kernel.org/n/tip-7wsy0zo292pif0yjoqpfryrz@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/annotate.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 61bf9128e1f2..9d9db3b296dd 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -30,6 +30,8 @@ static int disasm_line__parse(char *line, char **namep, char **rawp); static void ins__delete(struct ins_operands *ops) { + if (ops == NULL) + return; zfree(&ops->source.raw); zfree(&ops->source.name); zfree(&ops->target.raw); -- GitLab From 842a9ae08a25671db3d4f689eed68b4d64be15b5 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Wed, 4 Mar 2015 12:54:21 +0200 Subject: [PATCH 02839/11651] bridge: Extend Proxy ARP design to allow optional rules for Wi-Fi This extends the design in commit 958501163ddd ("bridge: Add support for IEEE 802.11 Proxy ARP") with optional set of rules that are needed to meet the IEEE 802.11 and Hotspot 2.0 requirements for ProxyARP. The previously added BR_PROXYARP behavior is left as-is and a new BR_PROXYARP_WIFI alternative is added so that this behavior can be configured from user space when required. In addition, this enables proxyarp functionality for unicast ARP requests for both BR_PROXYARP and BR_PROXYARP_WIFI since it is possible to use unicast as well as broadcast for these frames. The key differences in functionality: BR_PROXYARP: - uses the flag on the bridge port on which the request frame was received to determine whether to reply - block bridge port flooding completely on ports that enable proxy ARP BR_PROXYARP_WIFI: - uses the flag on the bridge port to which the target device of the request belongs - block bridge port flooding selectively based on whether the proxyarp functionality replied Signed-off-by: Jouni Malinen Signed-off-by: David S. Miller --- include/linux/if_bridge.h | 1 + include/uapi/linux/if_link.h | 1 + net/bridge/br_forward.c | 3 +++ net/bridge/br_input.c | 17 ++++++++++------- net/bridge/br_netlink.c | 5 ++++- net/bridge/br_private.h | 1 + net/bridge/br_sysfs_if.c | 2 ++ 7 files changed, 22 insertions(+), 8 deletions(-) diff --git a/include/linux/if_bridge.h b/include/linux/if_bridge.h index a57bca2ea97e..dad8b00beed2 100644 --- a/include/linux/if_bridge.h +++ b/include/linux/if_bridge.h @@ -44,6 +44,7 @@ struct br_ip_list { #define BR_PROMISC BIT(7) #define BR_PROXYARP BIT(8) #define BR_LEARNING_SYNC BIT(9) +#define BR_PROXYARP_WIFI BIT(10) extern void brioctl_set(int (*ioctl_hook)(struct net *, unsigned int, void __user *)); diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h index dfd0bb22e554..756436e1ce89 100644 --- a/include/uapi/linux/if_link.h +++ b/include/uapi/linux/if_link.h @@ -247,6 +247,7 @@ enum { IFLA_BRPORT_UNICAST_FLOOD, /* flood unicast traffic */ IFLA_BRPORT_PROXYARP, /* proxy ARP */ IFLA_BRPORT_LEARNING_SYNC, /* mac learning sync from device */ + IFLA_BRPORT_PROXYARP_WIFI, /* proxy ARP for Wi-Fi */ __IFLA_BRPORT_MAX }; #define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1) diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c index f96933a823e3..1238fabff874 100644 --- a/net/bridge/br_forward.c +++ b/net/bridge/br_forward.c @@ -188,6 +188,9 @@ static void br_flood(struct net_bridge *br, struct sk_buff *skb, /* Do not flood to ports that enable proxy ARP */ if (p->flags & BR_PROXYARP) continue; + if ((p->flags & BR_PROXYARP_WIFI) && + BR_INPUT_SKB_CB(skb)->proxyarp_replied) + continue; prev = maybe_deliver(prev, p, skb, __packet_hook); if (IS_ERR(prev)) diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index e2aa7be3a847..052c5ebbc947 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c @@ -60,7 +60,7 @@ static int br_pass_frame_up(struct sk_buff *skb) } static void br_do_proxy_arp(struct sk_buff *skb, struct net_bridge *br, - u16 vid) + u16 vid, struct net_bridge_port *p) { struct net_device *dev = br->dev; struct neighbour *n; @@ -68,6 +68,8 @@ static void br_do_proxy_arp(struct sk_buff *skb, struct net_bridge *br, u8 *arpptr, *sha; __be32 sip, tip; + BR_INPUT_SKB_CB(skb)->proxyarp_replied = false; + if (dev->flags & IFF_NOARP) return; @@ -105,9 +107,12 @@ static void br_do_proxy_arp(struct sk_buff *skb, struct net_bridge *br, } f = __br_fdb_get(br, n->ha, vid); - if (f) + if (f && ((p->flags & BR_PROXYARP) || + (f->dst && (f->dst->flags & BR_PROXYARP_WIFI)))) { arp_send(ARPOP_REPLY, ETH_P_ARP, sip, skb->dev, tip, sha, n->ha, sha); + BR_INPUT_SKB_CB(skb)->proxyarp_replied = true; + } neigh_release(n); } @@ -153,12 +158,10 @@ int br_handle_frame_finish(struct sk_buff *skb) dst = NULL; - if (is_broadcast_ether_addr(dest)) { - if (IS_ENABLED(CONFIG_INET) && - p->flags & BR_PROXYARP && - skb->protocol == htons(ETH_P_ARP)) - br_do_proxy_arp(skb, br, vid); + if (IS_ENABLED(CONFIG_INET) && skb->protocol == htons(ETH_P_ARP)) + br_do_proxy_arp(skb, br, vid, p); + if (is_broadcast_ether_addr(dest)) { skb2 = skb; unicast = false; } else if (is_multicast_ether_addr(dest)) { diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index c72083968768..8bc6b67457dc 100644 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c @@ -143,7 +143,9 @@ static int br_port_fill_attrs(struct sk_buff *skb, nla_put_u8(skb, IFLA_BRPORT_FAST_LEAVE, !!(p->flags & BR_MULTICAST_FAST_LEAVE)) || nla_put_u8(skb, IFLA_BRPORT_LEARNING, !!(p->flags & BR_LEARNING)) || nla_put_u8(skb, IFLA_BRPORT_UNICAST_FLOOD, !!(p->flags & BR_FLOOD)) || - nla_put_u8(skb, IFLA_BRPORT_PROXYARP, !!(p->flags & BR_PROXYARP))) + nla_put_u8(skb, IFLA_BRPORT_PROXYARP, !!(p->flags & BR_PROXYARP)) || + nla_put_u8(skb, IFLA_BRPORT_PROXYARP_WIFI, + !!(p->flags & BR_PROXYARP_WIFI))) return -EMSGSIZE; return 0; @@ -553,6 +555,7 @@ static int br_setport(struct net_bridge_port *p, struct nlattr *tb[]) br_set_port_flag(p, tb, IFLA_BRPORT_LEARNING, BR_LEARNING); br_set_port_flag(p, tb, IFLA_BRPORT_UNICAST_FLOOD, BR_FLOOD); br_set_port_flag(p, tb, IFLA_BRPORT_PROXYARP, BR_PROXYARP); + br_set_port_flag(p, tb, IFLA_BRPORT_PROXYARP_WIFI, BR_PROXYARP_WIFI); if (tb[IFLA_BRPORT_COST]) { err = br_stp_set_path_cost(p, nla_get_u32(tb[IFLA_BRPORT_COST])); diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index de0919975a25..c32e279c62f8 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -305,6 +305,7 @@ struct br_input_skb_cb { #endif u16 frag_max_size; + bool proxyarp_replied; #ifdef CONFIG_BRIDGE_VLAN_FILTERING bool vlan_filtered; diff --git a/net/bridge/br_sysfs_if.c b/net/bridge/br_sysfs_if.c index 2de5d91199e8..4905845a94e9 100644 --- a/net/bridge/br_sysfs_if.c +++ b/net/bridge/br_sysfs_if.c @@ -171,6 +171,7 @@ BRPORT_ATTR_FLAG(root_block, BR_ROOT_BLOCK); BRPORT_ATTR_FLAG(learning, BR_LEARNING); BRPORT_ATTR_FLAG(unicast_flood, BR_FLOOD); BRPORT_ATTR_FLAG(proxyarp, BR_PROXYARP); +BRPORT_ATTR_FLAG(proxyarp_wifi, BR_PROXYARP_WIFI); #ifdef CONFIG_BRIDGE_IGMP_SNOOPING static ssize_t show_multicast_router(struct net_bridge_port *p, char *buf) @@ -215,6 +216,7 @@ static const struct brport_attribute *brport_attrs[] = { &brport_attr_multicast_fast_leave, #endif &brport_attr_proxyarp, + &brport_attr_proxyarp_wifi, NULL }; -- GitLab From d8bf368d0631d4bc2612d8bf2e4e8e74e620d0cc Mon Sep 17 00:00:00 2001 From: Valentin Rothberg Date: Thu, 5 Mar 2015 15:23:08 +0100 Subject: [PATCH 02840/11651] genirq: Remove the deprecated 'IRQF_DISABLED' request_irq() flag entirely The IRQF_DISABLED flag is a NOOP and has been scheduled for removal since Linux v2.6.36 by commit 6932bf37bed4 ("genirq: Remove IRQF_DISABLED from core code"). According to commit e58aa3d2d0cc ("genirq: Run irq handlers with interrupts disabled"), running IRQ handlers with interrupts enabled can cause stack overflows when the interrupt line of the issuing device is still active. This patch ends the grace period for IRQF_DISABLED (i.e., SA_INTERRUPT in older versions of Linux) and removes the definition and all remaining usages of this flag. There's still a few non-functional references left in the kernel source: - The bigger hunk in Documentation/scsi/ncr53c8xx.txt is removed entirely as IRQF_DISABLED is gone now; the usage in older kernel versions (including the old SA_INTERRUPT flag) should be discouraged. The trouble of using IRQF_SHARED is a general problem and not specific to any driver. - I left the reference in Documentation/PCI/MSI-HOWTO.txt untouched since it has already been removed in linux-next. - All remaining references are changelogs that I suggest to keep. Signed-off-by: Valentin Rothberg Cc: Afzal Mohammed Cc: Arnd Bergmann Cc: Brian Norris Cc: Christoph Hellwig Cc: Dan Carpenter Cc: David Woodhouse Cc: Ewan Milne Cc: Eyal Perry Cc: Felipe Balbi Cc: Greg Kroah-Hartman Cc: H. Peter Anvin Cc: Hannes Reinecke Cc: Hongliang Tao Cc: Huacai Chen Cc: Jiri Kosina Cc: Jonathan Corbet Cc: Keerthy Cc: Laurent Pinchart Cc: Linus Torvalds Cc: Nishanth Menon Cc: Paul Bolle Cc: Peter Ujfalusi Cc: Peter Zijlstra Cc: Quentin Lambert Cc: Rajendra Nayak Cc: Ralf Baechle Cc: Santosh Shilimkar Cc: Sricharan R Cc: Thomas Gleixner Cc: Tony Lindgren Cc: Zhou Wang Cc: iss_storagedev@hp.com Cc: linux-mips@linux-mips.org Cc: linux-mtd@lists.infradead.org Link: http://lkml.kernel.org/r/1425565425-12604-1-git-send-email-valentinrothberg@gmail.com Signed-off-by: Ingo Molnar --- Documentation/scsi/ncr53c8xx.txt | 25 ------------------------- Documentation/scsi/tmscsim.txt | 4 ---- arch/mips/loongson/loongson-3/hpet.c | 2 +- drivers/block/cpqarray.c | 4 ++-- drivers/bus/omap_l3_noc.c | 4 ++-- drivers/bus/omap_l3_smx.c | 10 ++++------ drivers/mtd/nand/hisi504_nand.c | 3 +-- drivers/usb/isp1760/isp1760-core.c | 3 +-- drivers/usb/isp1760/isp1760-udc.c | 4 ++-- include/linux/interrupt.h | 3 --- 10 files changed, 13 insertions(+), 49 deletions(-) diff --git a/Documentation/scsi/ncr53c8xx.txt b/Documentation/scsi/ncr53c8xx.txt index 1d508dcbf859..8586efff1e99 100644 --- a/Documentation/scsi/ncr53c8xx.txt +++ b/Documentation/scsi/ncr53c8xx.txt @@ -786,7 +786,6 @@ port address 0x1400. irqm:1 same as initial settings (assumed BIOS settings) irqm:2 always totem pole irqm:0x10 driver will not use IRQF_SHARED flag when requesting irq - irqm:0x20 driver will not use IRQF_DISABLED flag when requesting irq (Bits 0x10 and 0x20 can be combined with hardware irq mode option) @@ -1231,30 +1230,6 @@ they only refer to system buffers that are well aligned. So, a work around may only be needed under Linux when a scatter/gather list is not used and when the SCSI DATA IN phase is reentered after a phase mismatch. -14.5 IRQ sharing problems - -When an IRQ is shared by devices that are handled by different drivers, it -may happen that one driver complains about the request of the IRQ having -failed. Inder Linux-2.0, this may be due to one driver having requested the -IRQ using the IRQF_DISABLED flag but some other having requested the same IRQ -without this flag. Under both Linux-2.0 and linux-2.2, this may be caused by -one driver not having requested the IRQ with the IRQF_SHARED flag. - -By default, the ncr53c8xx and sym53c8xx drivers request IRQs with both the -IRQF_DISABLED and the IRQF_SHARED flag under Linux-2.0 and with only the IRQF_SHARED -flag under Linux-2.2. - -Under Linux-2.0, you can disable use of IRQF_DISABLED flag from the boot -command line by using the following option: - - ncr53c8xx=irqm:0x20 (for the generic ncr53c8xx driver) - sym53c8xx=irqm:0x20 (for the sym53c8xx driver) - -If this does not fix the problem, then you may want to check how all other -drivers are requesting the IRQ and report the problem. Note that if at least -a single driver does not request the IRQ with the IRQF_SHARED flag (share IRQ), -then the request of the IRQ obviously will not succeed for all the drivers. - 15. SCSI problem troubleshooting 15.1 Problem tracking diff --git a/Documentation/scsi/tmscsim.txt b/Documentation/scsi/tmscsim.txt index 0810132772a8..0e0322bf0020 100644 --- a/Documentation/scsi/tmscsim.txt +++ b/Documentation/scsi/tmscsim.txt @@ -107,10 +107,6 @@ produced errors and started to corrupt my disks. So don't do that! A 37.50 MHz PCI bus works for me, though, but I don't recommend using higher clocks than the 33.33 MHz being in the PCI spec. -If you want to share the IRQ with another device and the driver refuses to -do so, you might succeed with changing the DC390_IRQ type in tmscsim.c to -IRQF_SHARED | IRQF_DISABLED. - 3.Features ---------- diff --git a/arch/mips/loongson/loongson-3/hpet.c b/arch/mips/loongson/loongson-3/hpet.c index e898d68668a9..5c21cd3bd339 100644 --- a/arch/mips/loongson/loongson-3/hpet.c +++ b/arch/mips/loongson/loongson-3/hpet.c @@ -162,7 +162,7 @@ static irqreturn_t hpet_irq_handler(int irq, void *data) static struct irqaction hpet_irq = { .handler = hpet_irq_handler, - .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_TIMER, + .flags = IRQF_NOBALANCING | IRQF_TIMER, .name = "hpet", }; diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c index 2b9440384536..f749df9e15cd 100644 --- a/drivers/block/cpqarray.c +++ b/drivers/block/cpqarray.c @@ -405,8 +405,8 @@ static int cpqarray_register_ctlr(int i, struct pci_dev *pdev) goto Enomem4; } hba[i]->access.set_intr_mask(hba[i], 0); - if (request_irq(hba[i]->intr, do_ida_intr, - IRQF_DISABLED|IRQF_SHARED, hba[i]->devname, hba[i])) + if (request_irq(hba[i]->intr, do_ida_intr, IRQF_SHARED, + hba[i]->devname, hba[i])) { printk(KERN_ERR "cpqarray: Unable to get irq %d for %s\n", hba[i]->intr, hba[i]->devname); diff --git a/drivers/bus/omap_l3_noc.c b/drivers/bus/omap_l3_noc.c index 029bc73de001..11f7982cbdb3 100644 --- a/drivers/bus/omap_l3_noc.c +++ b/drivers/bus/omap_l3_noc.c @@ -284,7 +284,7 @@ static int omap_l3_probe(struct platform_device *pdev) */ l3->debug_irq = platform_get_irq(pdev, 0); ret = devm_request_irq(l3->dev, l3->debug_irq, l3_interrupt_handler, - IRQF_DISABLED, "l3-dbg-irq", l3); + 0x0, "l3-dbg-irq", l3); if (ret) { dev_err(l3->dev, "request_irq failed for %d\n", l3->debug_irq); @@ -293,7 +293,7 @@ static int omap_l3_probe(struct platform_device *pdev) l3->app_irq = platform_get_irq(pdev, 1); ret = devm_request_irq(l3->dev, l3->app_irq, l3_interrupt_handler, - IRQF_DISABLED, "l3-app-irq", l3); + 0x0, "l3-app-irq", l3); if (ret) dev_err(l3->dev, "request_irq failed for %d\n", l3->app_irq); diff --git a/drivers/bus/omap_l3_smx.c b/drivers/bus/omap_l3_smx.c index 597fdaee7315..360a5c0a4ee0 100644 --- a/drivers/bus/omap_l3_smx.c +++ b/drivers/bus/omap_l3_smx.c @@ -251,18 +251,16 @@ static int omap3_l3_probe(struct platform_device *pdev) } l3->debug_irq = platform_get_irq(pdev, 0); - ret = request_irq(l3->debug_irq, omap3_l3_app_irq, - IRQF_DISABLED | IRQF_TRIGGER_RISING, - "l3-debug-irq", l3); + ret = request_irq(l3->debug_irq, omap3_l3_app_irq, IRQF_TRIGGER_RISING, + "l3-debug-irq", l3); if (ret) { dev_err(&pdev->dev, "couldn't request debug irq\n"); goto err1; } l3->app_irq = platform_get_irq(pdev, 1); - ret = request_irq(l3->app_irq, omap3_l3_app_irq, - IRQF_DISABLED | IRQF_TRIGGER_RISING, - "l3-app-irq", l3); + ret = request_irq(l3->app_irq, omap3_l3_app_irq, IRQF_TRIGGER_RISING, + "l3-app-irq", l3); if (ret) { dev_err(&pdev->dev, "couldn't request app irq\n"); goto err2; diff --git a/drivers/mtd/nand/hisi504_nand.c b/drivers/mtd/nand/hisi504_nand.c index 289ad3ac3e80..8dcc7b8fee40 100644 --- a/drivers/mtd/nand/hisi504_nand.c +++ b/drivers/mtd/nand/hisi504_nand.c @@ -758,8 +758,7 @@ static int hisi_nfc_probe(struct platform_device *pdev) hisi_nfc_host_init(host); - ret = devm_request_irq(dev, irq, hinfc_irq_handle, IRQF_DISABLED, - "nandc", host); + ret = devm_request_irq(dev, irq, hinfc_irq_handle, 0x0, "nandc", host); if (ret) { dev_err(dev, "failed to request IRQ\n"); goto err_res; diff --git a/drivers/usb/isp1760/isp1760-core.c b/drivers/usb/isp1760/isp1760-core.c index b9827556455f..5c37f40f6122 100644 --- a/drivers/usb/isp1760/isp1760-core.c +++ b/drivers/usb/isp1760/isp1760-core.c @@ -151,8 +151,7 @@ int isp1760_register(struct resource *mem, int irq, unsigned long irqflags, } if (IS_ENABLED(CONFIG_USB_ISP1761_UDC) && !udc_disabled) { - ret = isp1760_udc_register(isp, irq, irqflags | IRQF_SHARED | - IRQF_DISABLED); + ret = isp1760_udc_register(isp, irq, irqflags | IRQF_SHARED); if (ret < 0) { isp1760_hcd_unregister(&isp->hcd); return ret; diff --git a/drivers/usb/isp1760/isp1760-udc.c b/drivers/usb/isp1760/isp1760-udc.c index 9612d7990565..0b46ff01299f 100644 --- a/drivers/usb/isp1760/isp1760-udc.c +++ b/drivers/usb/isp1760/isp1760-udc.c @@ -1451,8 +1451,8 @@ int isp1760_udc_register(struct isp1760_device *isp, int irq, sprintf(udc->irqname, "%s (udc)", devname); - ret = request_irq(irq, isp1760_udc_irq, IRQF_SHARED | IRQF_DISABLED | - irqflags, udc->irqname, udc); + ret = request_irq(irq, isp1760_udc_irq, IRQF_SHARED | irqflags, + udc->irqname, udc); if (ret < 0) goto error; diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index 3bb01b9a379c..2cee1761c77d 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -39,8 +39,6 @@ * These flags used only by the kernel as part of the * irq handling routines. * - * IRQF_DISABLED - keep irqs disabled when calling the action handler. - * DEPRECATED. This flag is a NOOP and scheduled to be removed * IRQF_SHARED - allow sharing the irq among several devices * IRQF_PROBE_SHARED - set by callers when they expect sharing mismatches to occur * IRQF_TIMER - Flag to mark this interrupt as timer interrupt @@ -58,7 +56,6 @@ * IRQF_EARLY_RESUME - Resume IRQ early during syscore instead of at device * resume time. */ -#define IRQF_DISABLED 0x00000020 #define IRQF_SHARED 0x00000080 #define IRQF_PROBE_SHARED 0x00000100 #define __IRQF_TIMER 0x00000200 -- GitLab From d63951d7442982ef81df585a9c08c2b5fd49f898 Mon Sep 17 00:00:00 2001 From: David Vrabel Date: Wed, 4 Mar 2015 11:14:46 +0000 Subject: [PATCH 02841/11651] xen-netback: return correct ethtool stats Use correct pointer arithmetic to get the pointer to each stat. Signed-off-by: David Vrabel Signed-off-by: David S. Miller --- drivers/net/xen-netback/interface.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c index f38227afe099..3aa8648080c8 100644 --- a/drivers/net/xen-netback/interface.c +++ b/drivers/net/xen-netback/interface.c @@ -340,12 +340,11 @@ static void xenvif_get_ethtool_stats(struct net_device *dev, unsigned int num_queues = vif->num_queues; int i; unsigned int queue_index; - struct xenvif_stats *vif_stats; for (i = 0; i < ARRAY_SIZE(xenvif_stats); i++) { unsigned long accum = 0; for (queue_index = 0; queue_index < num_queues; ++queue_index) { - vif_stats = &vif->queues[queue_index].stats; + void *vif_stats = &vif->queues[queue_index].stats; accum += *(unsigned long *)(vif_stats + xenvif_stats[i].offset); } data[i] = accum; -- GitLab From 49d9991a18f9aae7b14abbd9c1cc87555330a769 Mon Sep 17 00:00:00 2001 From: David Vrabel Date: Wed, 4 Mar 2015 11:14:47 +0000 Subject: [PATCH 02842/11651] xen-netback: unref frags when handling a from-guest skb with a frag list Every time a VIF is destroyed up to 256 pages may be leaked if packets with more than MAX_SKB_FRAGS frags were transmitted from the guest. Even worse, if another user of ballooned pages allocated one of these ballooned pages it would not handle the unexpectedly >1 page count (e.g., gntdev would deadlock when unmapping a grant because the page count would never reach 1). When handling a from-guest skb with a frag list, unref the frags before releasing them so they are freed correctly when the VIF is destroyed. Signed-off-by: David Vrabel Signed-off-by: David S. Miller --- drivers/net/xen-netback/netback.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c index c4d68d768408..f1d84fb1eba8 100644 --- a/drivers/net/xen-netback/netback.c +++ b/drivers/net/xen-netback/netback.c @@ -1349,7 +1349,7 @@ static int xenvif_handle_frag_list(struct xenvif_queue *queue, struct sk_buff *s { unsigned int offset = skb_headlen(skb); skb_frag_t frags[MAX_SKB_FRAGS]; - int i; + int i, f; struct ubuf_info *uarg; struct sk_buff *nskb = skb_shinfo(skb)->frag_list; @@ -1389,6 +1389,11 @@ static int xenvif_handle_frag_list(struct xenvif_queue *queue, struct sk_buff *s frags[i].page_offset = 0; skb_frag_size_set(&frags[i], len); } + + /* Release all the original (foreign) frags. */ + for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) + skb_frag_unref(skb, f); + /* swap out with old one */ memcpy(skb_shinfo(skb)->frags, frags, -- GitLab From b0c21badf174eb00160f842398f3918d7b365853 Mon Sep 17 00:00:00 2001 From: David Vrabel Date: Wed, 4 Mar 2015 11:14:48 +0000 Subject: [PATCH 02843/11651] xen-netback: refactor xenvif_handle_frag_list() When handling a from-guest frag list, xenvif_handle_frag_list() replaces the frags before calling the destructor to clean up the original (foreign) frags. Whilst this is safe (the destructor doesn't actually use the frags), it looks odd. Reorder the function to be less confusing. Signed-off-by: David Vrabel Signed-off-by: David S. Miller --- drivers/net/xen-netback/netback.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c index f1d84fb1eba8..cab9f5257f57 100644 --- a/drivers/net/xen-netback/netback.c +++ b/drivers/net/xen-netback/netback.c @@ -1390,27 +1390,24 @@ static int xenvif_handle_frag_list(struct xenvif_queue *queue, struct sk_buff *s skb_frag_size_set(&frags[i], len); } + /* Copied all the bits from the frag list -- free it. */ + skb_frag_list_init(skb); + xenvif_skb_zerocopy_prepare(queue, nskb); + kfree_skb(nskb); + /* Release all the original (foreign) frags. */ for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) skb_frag_unref(skb, f); - - /* swap out with old one */ - memcpy(skb_shinfo(skb)->frags, - frags, - i * sizeof(skb_frag_t)); - skb_shinfo(skb)->nr_frags = i; - skb->truesize += i * PAGE_SIZE; - - /* remove traces of mapped pages and frag_list */ - skb_frag_list_init(skb); uarg = skb_shinfo(skb)->destructor_arg; /* increase inflight counter to offset decrement in callback */ atomic_inc(&queue->inflight_packets); uarg->callback(uarg, true); skb_shinfo(skb)->destructor_arg = NULL; - xenvif_skb_zerocopy_prepare(queue, nskb); - kfree_skb(nskb); + /* Fill the skb with the new (local) frags. */ + memcpy(skb_shinfo(skb)->frags, frags, i * sizeof(skb_frag_t)); + skb_shinfo(skb)->nr_frags = i; + skb->truesize += i * PAGE_SIZE; return 0; } -- GitLab From 1c6a5b0e3446c36e3fc3f4531b1cf2db61f8319b Mon Sep 17 00:00:00 2001 From: Hariprasad Shenai Date: Wed, 4 Mar 2015 18:16:27 +0530 Subject: [PATCH 02844/11651] cxgb4: Move offload Rx queue allocation to separate function Adds a common function for all Rx queue allocation. Signed-off-by: Hariprasad Shenai Signed-off-by: David S. Miller --- .../net/ethernet/chelsio/cxgb4/cxgb4_main.c | 73 +++++++++---------- 1 file changed, 35 insertions(+), 38 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index a22cf932ca35..836e41166915 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -957,6 +957,28 @@ static void enable_rx(struct adapter *adap) } } +static int alloc_ofld_rxqs(struct adapter *adap, struct sge_ofld_rxq *q, + unsigned int nq, unsigned int per_chan, int msi_idx, + u16 *ids) +{ + int i, err; + + for (i = 0; i < nq; i++, q++) { + if (msi_idx > 0) + msi_idx++; + err = t4_sge_alloc_rxq(adap, &q->rspq, false, + adap->port[i / per_chan], + msi_idx, q->fl.size ? &q->fl : NULL, + uldrx_handler); + if (err) + return err; + memset(&q->stats, 0, sizeof(q->stats)); + if (ids) + ids[i] = q->rspq.abs_id; + } + return 0; +} + /** * setup_sge_queues - configure SGE Tx/Rx/response queues * @adap: the adapter @@ -1018,51 +1040,26 @@ freeout: t4_free_sge_resources(adap); j = s->ofldqsets / adap->params.nports; /* ofld queues per channel */ for_each_ofldrxq(s, i) { - struct sge_ofld_rxq *q = &s->ofldrxq[i]; - struct net_device *dev = adap->port[i / j]; - - if (msi_idx > 0) - msi_idx++; - err = t4_sge_alloc_rxq(adap, &q->rspq, false, dev, msi_idx, - q->fl.size ? &q->fl : NULL, - uldrx_handler); - if (err) - goto freeout; - memset(&q->stats, 0, sizeof(q->stats)); - s->ofld_rxq[i] = q->rspq.abs_id; - err = t4_sge_alloc_ofld_txq(adap, &s->ofldtxq[i], dev, + err = t4_sge_alloc_ofld_txq(adap, &s->ofldtxq[i], + adap->port[i / j], s->fw_evtq.cntxt_id); if (err) goto freeout; } - for_each_rdmarxq(s, i) { - struct sge_ofld_rxq *q = &s->rdmarxq[i]; +#define ALLOC_OFLD_RXQS(firstq, nq, per_chan, ids) do { \ + err = alloc_ofld_rxqs(adap, firstq, nq, per_chan, msi_idx, ids); \ + if (err) \ + goto freeout; \ + if (msi_idx > 0) \ + msi_idx += nq; \ +} while (0) - if (msi_idx > 0) - msi_idx++; - err = t4_sge_alloc_rxq(adap, &q->rspq, false, adap->port[i], - msi_idx, q->fl.size ? &q->fl : NULL, - uldrx_handler); - if (err) - goto freeout; - memset(&q->stats, 0, sizeof(q->stats)); - s->rdma_rxq[i] = q->rspq.abs_id; - } + ALLOC_OFLD_RXQS(s->ofldrxq, s->ofldqsets, j, s->ofld_rxq); + ALLOC_OFLD_RXQS(s->rdmarxq, s->rdmaqs, 1, s->rdma_rxq); + ALLOC_OFLD_RXQS(s->rdmaciq, s->rdmaciqs, 1, s->rdma_ciq); - for_each_rdmaciq(s, i) { - struct sge_ofld_rxq *q = &s->rdmaciq[i]; - - if (msi_idx > 0) - msi_idx++; - err = t4_sge_alloc_rxq(adap, &q->rspq, false, adap->port[i], - msi_idx, q->fl.size ? &q->fl : NULL, - uldrx_handler); - if (err) - goto freeout; - memset(&q->stats, 0, sizeof(q->stats)); - s->rdma_ciq[i] = q->rspq.abs_id; - } +#undef ALLOC_OFLD_RXQS for_each_port(adap, i) { /* -- GitLab From f36e58e5668694cd89d0a4d04a767a6286d497cc Mon Sep 17 00:00:00 2001 From: Hariprasad Shenai Date: Wed, 4 Mar 2015 18:16:28 +0530 Subject: [PATCH 02845/11651] cxgb4: Try and provide an RDMA CIQ per cpu To allow for better scalability on systems with large core counts, we will try and allocate enough RDMA Concentrator IQs and MSI/X vectors as we have cores. If we cannot get enough MSI/X vectors, fall back to the minimum required: 1 per adapter rx channel. Also clean up cxgb_enable_msix() to make it readable and correct a bug where the vectors are not correctly assigned if the driver doesn't get the full amount requested. Signed-off-by: Steve Wise Signed-off-by: Hariprasad Shenai Signed-off-by: David S. Miller --- drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 6 +-- .../ethernet/chelsio/cxgb4/cxgb4_debugfs.c | 4 ++ .../net/ethernet/chelsio/cxgb4/cxgb4_main.c | 53 ++++++++++++++----- 3 files changed, 46 insertions(+), 17 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h index 97842d03675b..4555634b985d 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h @@ -369,7 +369,7 @@ enum { MAX_OFLD_QSETS = 16, /* # of offload Tx/Rx queue sets */ MAX_CTRL_QUEUES = NCHAN, /* # of control Tx queues */ MAX_RDMA_QUEUES = NCHAN, /* # of streaming RDMA Rx queues */ - MAX_RDMA_CIQS = NCHAN, /* # of RDMA concentrator IQs */ + MAX_RDMA_CIQS = 32, /* # of RDMA concentrator IQs */ MAX_ISCSI_QUEUES = NCHAN, /* # of streaming iSCSI Rx queues */ }; @@ -599,8 +599,8 @@ struct sge { u16 rdmaqs; /* # of available RDMA Rx queues */ u16 rdmaciqs; /* # of available RDMA concentrator IQs */ u16 ofld_rxq[MAX_OFLD_QSETS]; - u16 rdma_rxq[NCHAN]; - u16 rdma_ciq[NCHAN]; + u16 rdma_rxq[MAX_RDMA_QUEUES]; + u16 rdma_ciq[MAX_RDMA_CIQS]; u16 timer_val[SGE_NTIMERS]; u8 counter_val[SGE_NCOUNTERS]; u32 fl_pg_order; /* large page allocation size */ diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c index 78854ceb0870..0918c16bb154 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c @@ -1769,6 +1769,8 @@ do { \ int n = min(4, adap->sge.rdmaqs - 4 * rdma_idx); S("QType:", "RDMA-CPL"); + S("Interface:", + rx[i].rspq.netdev ? rx[i].rspq.netdev->name : "N/A"); R("RspQ ID:", rspq.abs_id); R("RspQ size:", rspq.size); R("RspQE size:", rspq.iqe_len); @@ -1788,6 +1790,8 @@ do { \ int n = min(4, adap->sge.rdmaciqs - 4 * ciq_idx); S("QType:", "RDMA-CIQ"); + S("Interface:", + rx[i].rspq.netdev ? rx[i].rspq.netdev->name : "N/A"); R("RspQ ID:", rspq.abs_id); R("RspQ size:", rspq.size); R("RspQE size:", rspq.iqe_len); diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 836e41166915..e344bdcd40b3 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -1057,7 +1057,8 @@ freeout: t4_free_sge_resources(adap); ALLOC_OFLD_RXQS(s->ofldrxq, s->ofldqsets, j, s->ofld_rxq); ALLOC_OFLD_RXQS(s->rdmarxq, s->rdmaqs, 1, s->rdma_rxq); - ALLOC_OFLD_RXQS(s->rdmaciq, s->rdmaciqs, 1, s->rdma_ciq); + j = s->rdmaciqs / adap->params.nports; /* rdmaq queues per channel */ + ALLOC_OFLD_RXQS(s->rdmaciq, s->rdmaciqs, j, s->rdma_ciq); #undef ALLOC_OFLD_RXQS @@ -5702,7 +5703,16 @@ static void cfg_queues(struct adapter *adap) s->ofldqsets = adap->params.nports; /* For RDMA one Rx queue per channel suffices */ s->rdmaqs = adap->params.nports; - s->rdmaciqs = adap->params.nports; + /* Try and allow at least 1 CIQ per cpu rounding down + * to the number of ports, with a minimum of 1 per port. + * A 2 port card in a 6 cpu system: 6 CIQs, 3 / port. + * A 4 port card in a 6 cpu system: 4 CIQs, 1 / port. + * A 4 port card in a 2 cpu system: 4 CIQs, 1 / port. + */ + s->rdmaciqs = min_t(int, MAX_RDMA_CIQS, num_online_cpus()); + s->rdmaciqs = (s->rdmaciqs / adap->params.nports) * + adap->params.nports; + s->rdmaciqs = max_t(int, s->rdmaciqs, adap->params.nports); } for (i = 0; i < ARRAY_SIZE(s->ethrxq); i++) { @@ -5788,12 +5798,17 @@ static void reduce_ethqs(struct adapter *adap, int n) static int enable_msix(struct adapter *adap) { int ofld_need = 0; - int i, want, need; + int i, want, need, allocated; struct sge *s = &adap->sge; unsigned int nchan = adap->params.nports; - struct msix_entry entries[MAX_INGQ + 1]; + struct msix_entry *entries; + + entries = kmalloc(sizeof(*entries) * (MAX_INGQ + 1), + GFP_KERNEL); + if (!entries) + return -ENOMEM; - for (i = 0; i < ARRAY_SIZE(entries); ++i) + for (i = 0; i < MAX_INGQ + 1; ++i) entries[i].entry = i; want = s->max_ethqsets + EXTRA_VECS; @@ -5810,29 +5825,39 @@ static int enable_msix(struct adapter *adap) #else need = adap->params.nports + EXTRA_VECS + ofld_need; #endif - want = pci_enable_msix_range(adap->pdev, entries, need, want); - if (want < 0) - return want; + allocated = pci_enable_msix_range(adap->pdev, entries, need, want); + if (allocated < 0) { + dev_info(adap->pdev_dev, "not enough MSI-X vectors left," + " not using MSI-X\n"); + kfree(entries); + return allocated; + } - /* - * Distribute available vectors to the various queue groups. + /* Distribute available vectors to the various queue groups. * Every group gets its minimum requirement and NIC gets top * priority for leftovers. */ - i = want - EXTRA_VECS - ofld_need; + i = allocated - EXTRA_VECS - ofld_need; if (i < s->max_ethqsets) { s->max_ethqsets = i; if (i < s->ethqsets) reduce_ethqs(adap, i); } if (is_offload(adap)) { - i = want - EXTRA_VECS - s->max_ethqsets; - i -= ofld_need - nchan; + if (allocated < want) { + s->rdmaqs = nchan; + s->rdmaciqs = nchan; + } + + /* leftovers go to OFLD */ + i = allocated - EXTRA_VECS - s->max_ethqsets - + s->rdmaqs - s->rdmaciqs; s->ofldqsets = (i / nchan) * nchan; /* round down */ } - for (i = 0; i < want; ++i) + for (i = 0; i < allocated; ++i) adap->msix_info[i].vec = entries[i].vector; + kfree(entries); return 0; } -- GitLab From da293700568ed3d96fcf062ac15d7d7c41377f11 Mon Sep 17 00:00:00 2001 From: Brian King Date: Wed, 4 Mar 2015 08:09:44 -0600 Subject: [PATCH 02846/11651] bnx2x: Force fundamental reset for EEH recovery EEH recovery for bnx2x based adapters is not reliable on all Power systems using the default hot reset, which can result in an unrecoverable EEH error. Forcing the use of fundamental reset during EEH recovery fixes this. Cc: stable Signed-off-by: Brian King Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 7155e1d2c208..bef750a09027 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -12722,6 +12722,9 @@ static int bnx2x_init_dev(struct bnx2x *bp, struct pci_dev *pdev, pci_write_config_dword(bp->pdev, PCICFG_GRC_ADDRESS, PCICFG_VENDOR_ID_OFFSET); + /* Set PCIe reset type to fundamental for EEH recovery */ + pdev->needs_freset = 1; + /* AER (Advanced Error reporting) configuration */ rc = pci_enable_pcie_error_reporting(pdev); if (!rc) -- GitLab From b0ab0afaebc88158c02755d2d9a09f1406c82406 Mon Sep 17 00:00:00 2001 From: Mark Salter Date: Wed, 4 Mar 2015 11:51:57 -0500 Subject: [PATCH 02847/11651] net: eth: xgene: fix booting with devicetree Commit de7b5b3d790a ("net: eth: xgene: change APM X-Gene SoC platform ethernet to support ACPI") breaks booting with devicetree with UEFI firmware. In that case, I get: Unhandled fault: synchronous external abort (0x96000010) at 0xfffffc0000620010 Internal error: : 96000010 [#1] SMP Modules linked in: vfat fat xfs libcrc32c ahci_xgene libahci_platform libahci CPU: 7 PID: 634 Comm: NetworkManager Not tainted 4.0.0-rc1+ #4 Hardware name: AppliedMicro Mustang/Mustang, BIOS 1.1.0-rh-0.14 Mar 1 2015 task: fffffe03d4c7e100 ti: fffffe03d4e24000 task.ti: fffffe03d4e24000 PC is at xgene_enet_rd_mcx_mac.isra.11+0x58/0xd4 LR is at xgene_gmac_tx_enable+0x2c/0x50 pc : [] lr : [] pstate: 80000145 sp : fffffe03d4e27590 x29: fffffe03d4e27590 x28: 0000000000000000 x27: fffffe03d4e277c0 x26: fffffe03da8fda10 x25: fffffe03d4e2760c x24: fffffe03d49e28c0 x23: fffffc0000620004 x22: 0000000000000000 x21: fffffc0000620000 x20: fffffc0000620010 x19: 000000000000000b x18: 000003ffd4a96020 x17: 000003ff7fc1f7a0 x16: fffffe000079b9cc x15: 0000000000000000 x14: 0000000000000000 x13: 0000000000000000 x12: fffffe03d4e24000 x11: fffffe03d4e27da0 x10: 0000000000000001 x9 : 0000000000000000 x8 : fffffe03d4e27a20 x7 : 0000000000000000 x6 : 00000000ffffffef x5 : fffffe000105f7d0 x4 : fffffe00007ca8c8 x3 : fffffe03d4e2760c x2 : 0000000000000000 x1 : fffffc0000620000 x0 : 0000000040000000 Process NetworkManager (pid: 634, stack limit = 0xfffffe03d4e24028) Stack: (0xfffffe03d4e27590 to 0xfffffe03d4e28000) ... Call trace: [] xgene_enet_rd_mcx_mac.isra.11+0x58/0xd4 [] xgene_gmac_tx_enable+0x28/0x50 [] xgene_enet_open+0x2c/0x130 [] __dev_open+0xc8/0x148 [] __dev_change_flags+0x90/0x158 [] dev_change_flags+0x30/0x70 [] do_setlink+0x278/0x870 [] rtnl_newlink+0x404/0x6a8 [] rtnetlink_rcv_msg+0x98/0x218 [] netlink_rcv_skb+0xe0/0xf8 [] rtnetlink_rcv+0x30/0x44 [] netlink_unicast+0xfc/0x210 [] netlink_sendmsg+0x498/0x5ac [] do_sock_sendmsg+0xa4/0xcc [] ___sys_sendmsg+0x1fc/0x208 [] __sys_sendmsg+0x4c/0x94 [] SyS_sendmsg+0x2c/0x3c The problem here is that the enet hw clocks are not getting initialized because of a test to avoid the initialization if UEFI is used to boot. This is an incorrect test. When booting with UEFI and devicetree, the kernel must still initialize the enet hw clocks. If booting with ACPI, the clock hw is not exposed to the kernel and it is that case where we want to avoid initializing clocks. Signed-off-by: Mark Salter Acked-by: Feng Kan Signed-off-by: David S. Miller --- drivers/net/ethernet/apm/xgene/xgene_enet_hw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c index 869d97fcf781..b927021c6c40 100644 --- a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c +++ b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c @@ -593,7 +593,7 @@ static int xgene_enet_reset(struct xgene_enet_pdata *pdata) if (!xgene_ring_mgr_init(pdata)) return -ENODEV; - if (!efi_enabled(EFI_BOOT)) { + if (pdata->clk) { clk_prepare_enable(pdata->clk); clk_disable_unprepare(pdata->clk); clk_prepare_enable(pdata->clk); -- GitLab From ef2b22ac540c018bd574d1846ab95b9bfcf38702 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 2 Mar 2015 22:26:55 +0100 Subject: [PATCH 02848/11651] cpuidle / sleep: Use broadcast timer for states that stop local timer Commit 381063133246 (PM / sleep: Re-implement suspend-to-idle handling) overlooked the fact that entering some sufficiently deep idle states by CPUs may cause their local timers to stop and in those cases it is necessary to switch over to a broadcast timer prior to entering the idle state. If the cpuidle driver in use does not provide the new ->enter_freeze callback for any of the idle states, that problem affects suspend-to-idle too, but it is not taken into account after the changes made by commit 381063133246. Fix that by changing the definition of cpuidle_enter_freeze() and re-arranging of the code in cpuidle_idle_call(), so the former does not call cpuidle_enter() any more and the fallback case is handled by cpuidle_idle_call() directly. Fixes: 381063133246 (PM / sleep: Re-implement suspend-to-idle handling) Reported-and-tested-by: Lorenzo Pieralisi Signed-off-by: Rafael J. Wysocki Acked-by: Peter Zijlstra (Intel) --- drivers/cpuidle/cpuidle.c | 62 ++++++++++++++------------------------- include/linux/cpuidle.h | 17 +++++++++-- kernel/sched/idle.c | 30 +++++++++++++------ 3 files changed, 58 insertions(+), 51 deletions(-) diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index 8b3e132b6a01..080bd2dbde4b 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c @@ -44,8 +44,8 @@ void disable_cpuidle(void) off = 1; } -static bool cpuidle_not_available(struct cpuidle_driver *drv, - struct cpuidle_device *dev) +bool cpuidle_not_available(struct cpuidle_driver *drv, + struct cpuidle_device *dev) { return off || !initialized || !drv || !dev || !dev->enabled; } @@ -72,14 +72,8 @@ int cpuidle_play_dead(void) return -ENODEV; } -/** - * cpuidle_find_deepest_state - Find deepest state meeting specific conditions. - * @drv: cpuidle driver for the given CPU. - * @dev: cpuidle device for the given CPU. - * @freeze: Whether or not the state should be suitable for suspend-to-idle. - */ -static int cpuidle_find_deepest_state(struct cpuidle_driver *drv, - struct cpuidle_device *dev, bool freeze) +static int find_deepest_state(struct cpuidle_driver *drv, + struct cpuidle_device *dev, bool freeze) { unsigned int latency_req = 0; int i, ret = freeze ? -1 : CPUIDLE_DRIVER_STATE_START - 1; @@ -98,6 +92,17 @@ static int cpuidle_find_deepest_state(struct cpuidle_driver *drv, return ret; } +/** + * cpuidle_find_deepest_state - Find the deepest available idle state. + * @drv: cpuidle driver for the given CPU. + * @dev: cpuidle device for the given CPU. + */ +int cpuidle_find_deepest_state(struct cpuidle_driver *drv, + struct cpuidle_device *dev) +{ + return find_deepest_state(drv, dev, false); +} + static void enter_freeze_proper(struct cpuidle_driver *drv, struct cpuidle_device *dev, int index) { @@ -119,46 +124,26 @@ static void enter_freeze_proper(struct cpuidle_driver *drv, /** * cpuidle_enter_freeze - Enter an idle state suitable for suspend-to-idle. + * @drv: cpuidle driver for the given CPU. + * @dev: cpuidle device for the given CPU. * * If there are states with the ->enter_freeze callback, find the deepest of - * them and enter it with frozen tick. Otherwise, find the deepest state - * available and enter it normally. - * - * Returns with enabled interrupts. + * them and enter it with frozen tick. */ -void cpuidle_enter_freeze(void) +int cpuidle_enter_freeze(struct cpuidle_driver *drv, struct cpuidle_device *dev) { - struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices); - struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev); int index; - if (cpuidle_not_available(drv, dev)) - goto fallback; - /* * Find the deepest state with ->enter_freeze present, which guarantees * that interrupts won't be enabled when it exits and allows the tick to * be frozen safely. */ - index = cpuidle_find_deepest_state(drv, dev, true); - if (index >= 0) { + index = find_deepest_state(drv, dev, true); + if (index >= 0) enter_freeze_proper(drv, dev, index); - local_irq_enable(); - return; - } - /* - * It is not safe to freeze the tick, find the deepest state available - * at all and try to enter it normally. - */ - index = cpuidle_find_deepest_state(drv, dev, false); - if (index >= 0) { - cpuidle_enter(drv, dev, index); - return; - } - - fallback: - arch_cpu_idle(); + return index; } /** @@ -217,9 +202,6 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv, */ int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) { - if (cpuidle_not_available(drv, dev)) - return -ENODEV; - return cpuidle_curr_governor->select(drv, dev); } diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h index f551a9299ac9..306178d7309f 100644 --- a/include/linux/cpuidle.h +++ b/include/linux/cpuidle.h @@ -126,6 +126,8 @@ struct cpuidle_driver { #ifdef CONFIG_CPU_IDLE extern void disable_cpuidle(void); +extern bool cpuidle_not_available(struct cpuidle_driver *drv, + struct cpuidle_device *dev); extern int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev); @@ -150,11 +152,17 @@ extern void cpuidle_resume(void); extern int cpuidle_enable_device(struct cpuidle_device *dev); extern void cpuidle_disable_device(struct cpuidle_device *dev); extern int cpuidle_play_dead(void); -extern void cpuidle_enter_freeze(void); +extern int cpuidle_find_deepest_state(struct cpuidle_driver *drv, + struct cpuidle_device *dev); +extern int cpuidle_enter_freeze(struct cpuidle_driver *drv, + struct cpuidle_device *dev); extern struct cpuidle_driver *cpuidle_get_cpu_driver(struct cpuidle_device *dev); #else static inline void disable_cpuidle(void) { } +static inline bool cpuidle_not_available(struct cpuidle_driver *drv, + struct cpuidle_device *dev) +{return true; } static inline int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) {return -ENODEV; } @@ -183,7 +191,12 @@ static inline int cpuidle_enable_device(struct cpuidle_device *dev) {return -ENODEV; } static inline void cpuidle_disable_device(struct cpuidle_device *dev) { } static inline int cpuidle_play_dead(void) {return -ENODEV; } -static inline void cpuidle_enter_freeze(void) { } +static inline int cpuidle_find_deepest_state(struct cpuidle_driver *drv, + struct cpuidle_device *dev) +{return -ENODEV; } +static inline int cpuidle_enter_freeze(struct cpuidle_driver *drv, + struct cpuidle_device *dev) +{return -ENODEV; } static inline struct cpuidle_driver *cpuidle_get_cpu_driver( struct cpuidle_device *dev) {return NULL; } #endif diff --git a/kernel/sched/idle.c b/kernel/sched/idle.c index 84b93b68482a..80014a178342 100644 --- a/kernel/sched/idle.c +++ b/kernel/sched/idle.c @@ -82,6 +82,7 @@ static void cpuidle_idle_call(void) struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev); int next_state, entered_state; unsigned int broadcast; + bool reflect; /* * Check if the idle task must be rescheduled. If it is the @@ -105,6 +106,9 @@ static void cpuidle_idle_call(void) */ rcu_idle_enter(); + if (cpuidle_not_available(drv, dev)) + goto use_default; + /* * Suspend-to-idle ("freeze") is a system state in which all user space * has been frozen, all I/O devices have been suspended and the only @@ -115,15 +119,22 @@ static void cpuidle_idle_call(void) * until a proper wakeup interrupt happens. */ if (idle_should_freeze()) { - cpuidle_enter_freeze(); - goto exit_idle; - } + entered_state = cpuidle_enter_freeze(drv, dev); + if (entered_state >= 0) { + local_irq_enable(); + goto exit_idle; + } - /* - * Ask the cpuidle framework to choose a convenient idle state. - * Fall back to the default arch idle method on errors. - */ - next_state = cpuidle_select(drv, dev); + reflect = false; + next_state = cpuidle_find_deepest_state(drv, dev); + } else { + reflect = true; + /* + * Ask the cpuidle framework to choose a convenient idle state. + */ + next_state = cpuidle_select(drv, dev); + } + /* Fall back to the default arch idle method on errors. */ if (next_state < 0) goto use_default; @@ -170,7 +181,8 @@ static void cpuidle_idle_call(void) /* * Give the governor an opportunity to reflect on the outcome */ - cpuidle_reflect(dev, entered_state); + if (reflect) + cpuidle_reflect(dev, entered_state); exit_idle: __current_set_polling(); -- GitLab From 6da2517ddb03cb12c6e8bbe449b5ed1b51878642 Mon Sep 17 00:00:00 2001 From: "jmlatten@linux.vnet.ibm.com" Date: Fri, 20 Feb 2015 18:11:24 -0600 Subject: [PATCH 02849/11651] tpm/ibmvtpm: Additional LE support for tpm_ibmvtpm_send Problem: When IMA and VTPM are both enabled in kernel config, kernel hangs during bootup on LE OS. Why?: IMA calls tpm_pcr_read() which results in tpm_ibmvtpm_send and tpm_ibmtpm_recv getting called. A trace showed that tpm_ibmtpm_recv was hanging. Resolution: tpm_ibmtpm_recv was hanging because tpm_ibmvtpm_send was sending CRQ message that probably did not make much sense to phype because of Endianness. The fix below sends correctly converted CRQ for LE. This was not caught before because it seems IMA is not enabled by default in kernel config and IMA exercises this particular code path in vtpm. Tested with IMA and VTPM enabled in kernel config and VTPM enabled on both a BE OS and a LE OS ppc64 lpar. This exercised CRQ and TPM command code paths in vtpm. Patch is against Peter's tpmdd tree on github which included Vicky's previous vtpm le patches. Signed-off-by: Joy Latten Cc: # eb71f8a5e33f: "Added Little Endian support to vtpm module" Cc: Reviewed-by: Ashley Lai Signed-off-by: Peter Huewe --- drivers/char/tpm/tpm_ibmvtpm.c | 10 +++++----- drivers/char/tpm/tpm_ibmvtpm.h | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/char/tpm/tpm_ibmvtpm.c b/drivers/char/tpm/tpm_ibmvtpm.c index b1e53e3aece5..42ffa5e7a1e0 100644 --- a/drivers/char/tpm/tpm_ibmvtpm.c +++ b/drivers/char/tpm/tpm_ibmvtpm.c @@ -124,7 +124,7 @@ static int tpm_ibmvtpm_send(struct tpm_chip *chip, u8 *buf, size_t count) { struct ibmvtpm_dev *ibmvtpm; struct ibmvtpm_crq crq; - u64 *word = (u64 *) &crq; + __be64 *word = (__be64 *)&crq; int rc; ibmvtpm = (struct ibmvtpm_dev *)TPM_VPRIV(chip); @@ -145,11 +145,11 @@ static int tpm_ibmvtpm_send(struct tpm_chip *chip, u8 *buf, size_t count) memcpy((void *)ibmvtpm->rtce_buf, (void *)buf, count); crq.valid = (u8)IBMVTPM_VALID_CMD; crq.msg = (u8)VTPM_TPM_COMMAND; - crq.len = (u16)count; - crq.data = ibmvtpm->rtce_dma_handle; + crq.len = cpu_to_be16(count); + crq.data = cpu_to_be32(ibmvtpm->rtce_dma_handle); - rc = ibmvtpm_send_crq(ibmvtpm->vdev, cpu_to_be64(word[0]), - cpu_to_be64(word[1])); + rc = ibmvtpm_send_crq(ibmvtpm->vdev, be64_to_cpu(word[0]), + be64_to_cpu(word[1])); if (rc != H_SUCCESS) { dev_err(ibmvtpm->dev, "tpm_ibmvtpm_send failed rc=%d\n", rc); rc = 0; diff --git a/drivers/char/tpm/tpm_ibmvtpm.h b/drivers/char/tpm/tpm_ibmvtpm.h index f595f14426bf..6af92890518f 100644 --- a/drivers/char/tpm/tpm_ibmvtpm.h +++ b/drivers/char/tpm/tpm_ibmvtpm.h @@ -22,9 +22,9 @@ struct ibmvtpm_crq { u8 valid; u8 msg; - u16 len; - u32 data; - u64 reserved; + __be16 len; + __be32 data; + __be64 reserved; } __attribute__((packed, aligned(8))); struct ibmvtpm_crq_queue { -- GitLab From d972b0523fa99358b2a0bafd85fe913b5d4b150a Mon Sep 17 00:00:00 2001 From: Jarkko Sakkinen Date: Sun, 1 Mar 2015 23:55:47 +0200 Subject: [PATCH 02850/11651] tpm: fix call order in tpm-chip.c - tpm_dev_add_device(): cdev_add() must be done before uevent is propagated in order to avoid races. - tpm_chip_register(): tpm_dev_add_device() must be done as the last step before exposing device to the user space in order to avoid races. In addition clarified description in tpm_chip_register(). Fixes: 313d21eeab92 ("tpm: device class for tpm") Fixes: afb5abc262e9 ("tpm: two-phase chip management functions") Signed-off-by: Jarkko Sakkinen Reviewed-by: Peter Huewe Signed-off-by: Peter Huewe --- drivers/char/tpm/tpm-chip.c | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c index 1d278ccd751f..e096e9cddb40 100644 --- a/drivers/char/tpm/tpm-chip.c +++ b/drivers/char/tpm/tpm-chip.c @@ -140,24 +140,24 @@ static int tpm_dev_add_device(struct tpm_chip *chip) { int rc; - rc = device_add(&chip->dev); + rc = cdev_add(&chip->cdev, chip->dev.devt, 1); if (rc) { dev_err(&chip->dev, - "unable to device_register() %s, major %d, minor %d, err=%d\n", + "unable to cdev_add() %s, major %d, minor %d, err=%d\n", chip->devname, MAJOR(chip->dev.devt), MINOR(chip->dev.devt), rc); + device_unregister(&chip->dev); return rc; } - rc = cdev_add(&chip->cdev, chip->dev.devt, 1); + rc = device_add(&chip->dev); if (rc) { dev_err(&chip->dev, - "unable to cdev_add() %s, major %d, minor %d, err=%d\n", + "unable to device_register() %s, major %d, minor %d, err=%d\n", chip->devname, MAJOR(chip->dev.devt), MINOR(chip->dev.devt), rc); - device_unregister(&chip->dev); return rc; } @@ -174,27 +174,17 @@ static void tpm_dev_del_device(struct tpm_chip *chip) * tpm_chip_register() - create a character device for the TPM chip * @chip: TPM chip to use. * - * Creates a character device for the TPM chip and adds sysfs interfaces for - * the device, PPI and TCPA. As the last step this function adds the - * chip to the list of TPM chips available for use. + * Creates a character device for the TPM chip and adds sysfs attributes for + * the device. As the last step this function adds the chip to the list of TPM + * chips available for in-kernel use. * - * NOTE: This function should be only called after the chip initialization - * is complete. - * - * Called from tpm_.c probe function only for devices - * the driver has determined it should claim. Prior to calling - * this function the specific probe function has called pci_enable_device - * upon errant exit from this function specific probe function should call - * pci_disable_device + * This function should be only called after the chip initialization is + * complete. */ int tpm_chip_register(struct tpm_chip *chip) { int rc; - rc = tpm_dev_add_device(chip); - if (rc) - return rc; - /* Populate sysfs for TPM1 devices. */ if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) { rc = tpm_sysfs_add_device(chip); @@ -208,6 +198,10 @@ int tpm_chip_register(struct tpm_chip *chip) chip->bios_dir = tpm_bios_log_setup(chip->devname); } + rc = tpm_dev_add_device(chip); + if (rc) + return rc; + /* Make the chip available. */ spin_lock(&driver_lock); list_add_rcu(&chip->list, &tpm_chip_list); -- GitLab From d677772e1358924bf487cd833bdc4d50f3f6f64d Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Mon, 2 Mar 2015 10:18:17 +0100 Subject: [PATCH 02851/11651] watchdog: at91sam9: request the irq with IRQF_NO_SUSPEND The watchdog interrupt (only used when activating software watchdog) shouldn't be suspended when entering suspend mode, because it is shared with a timer device (which request the line with IRQF_NO_SUSPEND) and once the watchdog "Mode Register" has been written, it cannot be changed (which means we cannot disable the watchdog interrupt when entering suspend). Signed-off-by: Boris Brezillon Reviewed-by: Alexandre Belloni Acked-by: Guenter Roeck Acked-by: Nicolas Ferre Signed-off-by: Rafael J. Wysocki --- drivers/watchdog/at91sam9_wdt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c index 6df940528fd2..1443b3c391de 100644 --- a/drivers/watchdog/at91sam9_wdt.c +++ b/drivers/watchdog/at91sam9_wdt.c @@ -208,7 +208,8 @@ static int at91_wdt_init(struct platform_device *pdev, struct at91wdt *wdt) if ((tmp & AT91_WDT_WDFIEN) && wdt->irq) { err = request_irq(wdt->irq, wdt_interrupt, - IRQF_SHARED | IRQF_IRQPOLL, + IRQF_SHARED | IRQF_IRQPOLL | + IRQF_NO_SUSPEND, pdev->name, wdt); if (err) return err; -- GitLab From 2c7af5ba65cfb0145ad8e11f856035c10ba0d22c Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Mon, 2 Mar 2015 10:18:18 +0100 Subject: [PATCH 02852/11651] tty: serial: atmel: rework interrupt and wakeup handling The IRQ line connected to the DBGU UART is often shared with a timer device which request the IRQ with IRQF_NO_SUSPEND. Since the UART driver is correctly disabling IRQs when entering suspend we can safely request the IRQ with IRQF_COND_SUSPEND so that irq core will not complain about mixing IRQF_NO_SUSPEND and !IRQF_NO_SUSPEND. Rework the interrupt handler to wake the system up when an interrupt happens on the DEBUG_UART while the system is suspended. Signed-off-by: Boris Brezillon Reviewed-by: Alexandre Belloni Acked-by: Nicolas Ferre Acked-by: Mark Rutland Signed-off-by: Rafael J. Wysocki --- drivers/tty/serial/atmel_serial.c | 49 ++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 4 deletions(-) diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index 846552bff67d..4e959c43f680 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include @@ -173,6 +174,12 @@ struct atmel_uart_port { bool ms_irq_enabled; bool is_usart; /* usart or uart */ struct timer_list uart_timer; /* uart timer */ + + bool suspended; + unsigned int pending; + unsigned int pending_status; + spinlock_t lock_suspended; + int (*prepare_rx)(struct uart_port *port); int (*prepare_tx)(struct uart_port *port); void (*schedule_rx)(struct uart_port *port); @@ -1179,12 +1186,15 @@ static irqreturn_t atmel_interrupt(int irq, void *dev_id) { struct uart_port *port = dev_id; struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); - unsigned int status, pending, pass_counter = 0; + unsigned int status, pending, mask, pass_counter = 0; bool gpio_handled = false; + spin_lock(&atmel_port->lock_suspended); + do { status = atmel_get_lines_status(port); - pending = status & UART_GET_IMR(port); + mask = UART_GET_IMR(port); + pending = status & mask; if (!gpio_handled) { /* * Dealing with GPIO interrupt @@ -1206,11 +1216,21 @@ static irqreturn_t atmel_interrupt(int irq, void *dev_id) if (!pending) break; + if (atmel_port->suspended) { + atmel_port->pending |= pending; + atmel_port->pending_status = status; + UART_PUT_IDR(port, mask); + pm_system_wakeup(); + break; + } + atmel_handle_receive(port, pending); atmel_handle_status(port, pending, status); atmel_handle_transmit(port, pending); } while (pass_counter++ < ATMEL_ISR_PASS_LIMIT); + spin_unlock(&atmel_port->lock_suspended); + return pass_counter ? IRQ_HANDLED : IRQ_NONE; } @@ -1742,7 +1762,8 @@ static int atmel_startup(struct uart_port *port) /* * Allocate the IRQ */ - retval = request_irq(port->irq, atmel_interrupt, IRQF_SHARED, + retval = request_irq(port->irq, atmel_interrupt, + IRQF_SHARED | IRQF_COND_SUSPEND, tty ? tty->name : "atmel_serial", port); if (retval) { dev_err(port->dev, "atmel_startup - Can't get irq\n"); @@ -2513,8 +2534,14 @@ static int atmel_serial_suspend(struct platform_device *pdev, /* we can not wake up if we're running on slow clock */ atmel_port->may_wakeup = device_may_wakeup(&pdev->dev); - if (atmel_serial_clk_will_stop()) + if (atmel_serial_clk_will_stop()) { + unsigned long flags; + + spin_lock_irqsave(&atmel_port->lock_suspended, flags); + atmel_port->suspended = true; + spin_unlock_irqrestore(&atmel_port->lock_suspended, flags); device_set_wakeup_enable(&pdev->dev, 0); + } uart_suspend_port(&atmel_uart, port); @@ -2525,6 +2552,18 @@ static int atmel_serial_resume(struct platform_device *pdev) { struct uart_port *port = platform_get_drvdata(pdev); struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); + unsigned long flags; + + spin_lock_irqsave(&atmel_port->lock_suspended, flags); + if (atmel_port->pending) { + atmel_handle_receive(port, atmel_port->pending); + atmel_handle_status(port, atmel_port->pending, + atmel_port->pending_status); + atmel_handle_transmit(port, atmel_port->pending); + atmel_port->pending = 0; + } + atmel_port->suspended = false; + spin_unlock_irqrestore(&atmel_port->lock_suspended, flags); uart_resume_port(&atmel_uart, port); device_set_wakeup_enable(&pdev->dev, atmel_port->may_wakeup); @@ -2593,6 +2632,8 @@ static int atmel_serial_probe(struct platform_device *pdev) port->backup_imr = 0; port->uart.line = ret; + spin_lock_init(&port->lock_suspended); + ret = atmel_init_gpios(port, &pdev->dev); if (ret < 0) dev_err(&pdev->dev, "%s", -- GitLab From 43270b1bc5f1e33522dacf3d3b9175c29404c36c Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Mon, 2 Mar 2015 14:40:39 +0100 Subject: [PATCH 02853/11651] netfilter: ipt_CLUSTERIP: deprecate it in favour of xt_cluster xt_cluster supersedes ipt_CLUSTERIP since it can be also used in gateway configurations (not only from the backend side). ipt_CLUSTER is also known to leak the netdev that it uses on device removal, which requires a rather large fix to workaround the problem: http://patchwork.ozlabs.org/patch/358629/ So let's deprecate this so we can probably kill code this in the future. Signed-off-by: Pablo Neira Ayuso --- include/net/netns/x_tables.h | 1 + net/ipv4/netfilter/ipt_CLUSTERIP.c | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/include/net/netns/x_tables.h b/include/net/netns/x_tables.h index c24060ee411e..4d6597ad6067 100644 --- a/include/net/netns/x_tables.h +++ b/include/net/netns/x_tables.h @@ -9,6 +9,7 @@ struct ebt_table; struct netns_xt { struct list_head tables[NFPROTO_NUMPROTO]; bool notrack_deprecated_warning; + bool clusterip_deprecated_warning; #if defined(CONFIG_BRIDGE_NF_EBTABLES) || \ defined(CONFIG_BRIDGE_NF_EBTABLES_MODULE) struct ebt_table *broute_table; diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c index e90f83a3415b..f75e9df5e017 100644 --- a/net/ipv4/netfilter/ipt_CLUSTERIP.c +++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c @@ -418,6 +418,13 @@ static int clusterip_tg_check(const struct xt_tgchk_param *par) if (ret < 0) pr_info("cannot load conntrack support for proto=%u\n", par->family); + + if (!par->net->xt.clusterip_deprecated_warning) { + pr_info("ipt_CLUSTERIP is deprecated and it will removed soon, " + "use xt_cluster instead\n"); + par->net->xt.clusterip_deprecated_warning = true; + } + return ret; } -- GitLab From 01ef16c2dd2e9a77fbd94eb0314c4787ab8f7113 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Tue, 3 Mar 2015 20:10:04 +0000 Subject: [PATCH 02854/11651] netfilter: nf_tables: minor tracing cleanups The tracing code is squeezed between multiple related parts of the evaluation code, move it out. Also add an inline wrapper for the reoccuring test for skb->nf_trace. Small code savings in nft_do_chain(): nft_trace_packet | -137 nft_do_chain | -8 2 functions changed, 145 bytes removed, diff: -145 net/netfilter/nf_tables_core.c: __nft_trace_packet | +137 1 function changed, 137 bytes added, diff: +137 net/netfilter/nf_tables_core.o: 3 functions changed, 137 bytes added, 145 bytes removed, diff: -8 Signed-off-by: Patrick McHardy Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nf_tables_core.c | 98 +++++++++++++++++----------------- 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/net/netfilter/nf_tables_core.c b/net/netfilter/nf_tables_core.c index 3b90eb2b2c55..074067d4fc1e 100644 --- a/net/netfilter/nf_tables_core.c +++ b/net/netfilter/nf_tables_core.c @@ -21,6 +21,48 @@ #include #include +enum nft_trace { + NFT_TRACE_RULE, + NFT_TRACE_RETURN, + NFT_TRACE_POLICY, +}; + +static const char *const comments[] = { + [NFT_TRACE_RULE] = "rule", + [NFT_TRACE_RETURN] = "return", + [NFT_TRACE_POLICY] = "policy", +}; + +static struct nf_loginfo trace_loginfo = { + .type = NF_LOG_TYPE_LOG, + .u = { + .log = { + .level = 4, + .logflags = NF_LOG_MASK, + }, + }, +}; + +static void __nft_trace_packet(const struct nft_pktinfo *pkt, + const struct nft_chain *chain, + int rulenum, enum nft_trace type) +{ + struct net *net = dev_net(pkt->in ? pkt->in : pkt->out); + + nf_log_packet(net, pkt->xt.family, pkt->ops->hooknum, pkt->skb, pkt->in, + pkt->out, &trace_loginfo, "TRACE: %s:%s:%s:%u ", + chain->table->name, chain->name, comments[type], + rulenum); +} + +static inline void nft_trace_packet(const struct nft_pktinfo *pkt, + const struct nft_chain *chain, + int rulenum, enum nft_trace type) +{ + if (unlikely(pkt->skb->nf_trace)) + __nft_trace_packet(pkt, chain, rulenum, type); +} + static void nft_cmp_fast_eval(const struct nft_expr *expr, struct nft_data data[NFT_REG_MAX + 1]) { @@ -66,40 +108,6 @@ struct nft_jumpstack { int rulenum; }; -enum nft_trace { - NFT_TRACE_RULE, - NFT_TRACE_RETURN, - NFT_TRACE_POLICY, -}; - -static const char *const comments[] = { - [NFT_TRACE_RULE] = "rule", - [NFT_TRACE_RETURN] = "return", - [NFT_TRACE_POLICY] = "policy", -}; - -static struct nf_loginfo trace_loginfo = { - .type = NF_LOG_TYPE_LOG, - .u = { - .log = { - .level = 4, - .logflags = NF_LOG_MASK, - }, - }, -}; - -static void nft_trace_packet(const struct nft_pktinfo *pkt, - const struct nft_chain *chain, - int rulenum, enum nft_trace type) -{ - struct net *net = dev_net(pkt->in ? pkt->in : pkt->out); - - nf_log_packet(net, pkt->xt.family, pkt->ops->hooknum, pkt->skb, pkt->in, - pkt->out, &trace_loginfo, "TRACE: %s:%s:%s:%u ", - chain->table->name, chain->name, comments[type], - rulenum); -} - unsigned int nft_do_chain(struct nft_pktinfo *pkt, const struct nf_hook_ops *ops) { @@ -146,8 +154,7 @@ next_rule: data[NFT_REG_VERDICT].verdict = NFT_CONTINUE; continue; case NFT_CONTINUE: - if (unlikely(pkt->skb->nf_trace)) - nft_trace_packet(pkt, chain, rulenum, NFT_TRACE_RULE); + nft_trace_packet(pkt, chain, rulenum, NFT_TRACE_RULE); continue; } break; @@ -157,16 +164,13 @@ next_rule: case NF_ACCEPT: case NF_DROP: case NF_QUEUE: - if (unlikely(pkt->skb->nf_trace)) - nft_trace_packet(pkt, chain, rulenum, NFT_TRACE_RULE); - + nft_trace_packet(pkt, chain, rulenum, NFT_TRACE_RULE); return data[NFT_REG_VERDICT].verdict; } switch (data[NFT_REG_VERDICT].verdict) { case NFT_JUMP: - if (unlikely(pkt->skb->nf_trace)) - nft_trace_packet(pkt, chain, rulenum, NFT_TRACE_RULE); + nft_trace_packet(pkt, chain, rulenum, NFT_TRACE_RULE); BUG_ON(stackptr >= NFT_JUMP_STACK_SIZE); jumpstack[stackptr].chain = chain; @@ -176,18 +180,15 @@ next_rule: chain = data[NFT_REG_VERDICT].chain; goto do_chain; case NFT_GOTO: - if (unlikely(pkt->skb->nf_trace)) - nft_trace_packet(pkt, chain, rulenum, NFT_TRACE_RULE); + nft_trace_packet(pkt, chain, rulenum, NFT_TRACE_RULE); chain = data[NFT_REG_VERDICT].chain; goto do_chain; case NFT_RETURN: - if (unlikely(pkt->skb->nf_trace)) - nft_trace_packet(pkt, chain, rulenum, NFT_TRACE_RETURN); + nft_trace_packet(pkt, chain, rulenum, NFT_TRACE_RETURN); break; case NFT_CONTINUE: - if (unlikely(pkt->skb->nf_trace && !(chain->flags & NFT_BASE_CHAIN))) - nft_trace_packet(pkt, chain, ++rulenum, NFT_TRACE_RETURN); + nft_trace_packet(pkt, chain, ++rulenum, NFT_TRACE_RETURN); break; default: WARN_ON(1); @@ -201,8 +202,7 @@ next_rule: goto next_rule; } - if (unlikely(pkt->skb->nf_trace)) - nft_trace_packet(pkt, basechain, -1, NFT_TRACE_POLICY); + nft_trace_packet(pkt, basechain, -1, NFT_TRACE_POLICY); rcu_read_lock_bh(); stats = this_cpu_ptr(rcu_dereference(nft_base_chain(basechain)->stats)); -- GitLab From 354bf5a0d794a34dc98ed25e72f460b3b360c174 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Tue, 3 Mar 2015 20:10:05 +0000 Subject: [PATCH 02855/11651] netfilter: nf_tables: consolidate tracing invocations * JUMP and GOTO are equivalent except for JUMP pushing the current context to the stack * RETURN and implicit RETURN (CONTINUE) are equivalent except that the logged rule number differs Result: nft_do_chain | -112 1 function changed, 112 bytes removed, diff: -112 Signed-off-by: Patrick McHardy Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nf_tables_core.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/net/netfilter/nf_tables_core.c b/net/netfilter/nf_tables_core.c index 074067d4fc1e..77165bf023f3 100644 --- a/net/netfilter/nf_tables_core.c +++ b/net/netfilter/nf_tables_core.c @@ -170,26 +170,23 @@ next_rule: switch (data[NFT_REG_VERDICT].verdict) { case NFT_JUMP: - nft_trace_packet(pkt, chain, rulenum, NFT_TRACE_RULE); - BUG_ON(stackptr >= NFT_JUMP_STACK_SIZE); jumpstack[stackptr].chain = chain; jumpstack[stackptr].rule = rule; jumpstack[stackptr].rulenum = rulenum; stackptr++; - chain = data[NFT_REG_VERDICT].chain; - goto do_chain; + /* fall through */ case NFT_GOTO: nft_trace_packet(pkt, chain, rulenum, NFT_TRACE_RULE); chain = data[NFT_REG_VERDICT].chain; goto do_chain; + case NFT_CONTINUE: + rulenum++; + /* fall through */ case NFT_RETURN: nft_trace_packet(pkt, chain, rulenum, NFT_TRACE_RETURN); break; - case NFT_CONTINUE: - nft_trace_packet(pkt, chain, ++rulenum, NFT_TRACE_RETURN); - break; default: WARN_ON(1); } -- GitLab From 1a1e1a12199ca27cebe87677b4c2153a3d2bacf2 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Tue, 3 Mar 2015 20:10:06 +0000 Subject: [PATCH 02856/11651] netfilter: nf_tables: cleanup nf_tables.h The transaction related definitions are squeezed in between the rule and expression definitions, which are closely related and should be next to each other. The transaction definitions actually don't belong into that file at all since it defines the global objects and API and transactions are internal to nf_tables_api, but for now simply move them to a seperate section. Similar, the chain types are in between a set of registration functions, they belong to the chain section. Signed-off-by: Patrick McHardy Signed-off-by: Pablo Neira Ayuso --- include/net/netfilter/nf_tables.h | 174 +++++++++++++++--------------- 1 file changed, 87 insertions(+), 87 deletions(-) diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h index 9eaaa7884586..04188b47629d 100644 --- a/include/net/netfilter/nf_tables.h +++ b/include/net/netfilter/nf_tables.h @@ -393,74 +393,6 @@ struct nft_rule { __attribute__((aligned(__alignof__(struct nft_expr)))); }; -/** - * struct nft_trans - nf_tables object update in transaction - * - * @list: used internally - * @msg_type: message type - * @ctx: transaction context - * @data: internal information related to the transaction - */ -struct nft_trans { - struct list_head list; - int msg_type; - struct nft_ctx ctx; - char data[0]; -}; - -struct nft_trans_rule { - struct nft_rule *rule; -}; - -#define nft_trans_rule(trans) \ - (((struct nft_trans_rule *)trans->data)->rule) - -struct nft_trans_set { - struct nft_set *set; - u32 set_id; -}; - -#define nft_trans_set(trans) \ - (((struct nft_trans_set *)trans->data)->set) -#define nft_trans_set_id(trans) \ - (((struct nft_trans_set *)trans->data)->set_id) - -struct nft_trans_chain { - bool update; - char name[NFT_CHAIN_MAXNAMELEN]; - struct nft_stats __percpu *stats; - u8 policy; -}; - -#define nft_trans_chain_update(trans) \ - (((struct nft_trans_chain *)trans->data)->update) -#define nft_trans_chain_name(trans) \ - (((struct nft_trans_chain *)trans->data)->name) -#define nft_trans_chain_stats(trans) \ - (((struct nft_trans_chain *)trans->data)->stats) -#define nft_trans_chain_policy(trans) \ - (((struct nft_trans_chain *)trans->data)->policy) - -struct nft_trans_table { - bool update; - bool enable; -}; - -#define nft_trans_table_update(trans) \ - (((struct nft_trans_table *)trans->data)->update) -#define nft_trans_table_enable(trans) \ - (((struct nft_trans_table *)trans->data)->enable) - -struct nft_trans_elem { - struct nft_set *set; - struct nft_set_elem elem; -}; - -#define nft_trans_elem_set(trans) \ - (((struct nft_trans_elem *)trans->data)->set) -#define nft_trans_elem(trans) \ - (((struct nft_trans_elem *)trans->data)->elem) - static inline struct nft_expr *nft_expr_first(const struct nft_rule *rule) { return (struct nft_expr *)&rule->data[0]; @@ -528,6 +460,25 @@ enum nft_chain_type { NFT_CHAIN_T_MAX }; +/** + * struct nf_chain_type - nf_tables chain type info + * + * @name: name of the type + * @type: numeric identifier + * @family: address family + * @owner: module owner + * @hook_mask: mask of valid hooks + * @hooks: hookfn overrides + */ +struct nf_chain_type { + const char *name; + enum nft_chain_type type; + int family; + struct module *owner; + unsigned int hook_mask; + nf_hookfn *hooks[NF_MAX_HOOKS]; +}; + int nft_chain_validate_dependency(const struct nft_chain *chain, enum nft_chain_type type); int nft_chain_validate_hooks(const struct nft_chain *chain, @@ -614,25 +565,6 @@ struct nft_af_info { int nft_register_afinfo(struct net *, struct nft_af_info *); void nft_unregister_afinfo(struct nft_af_info *); -/** - * struct nf_chain_type - nf_tables chain type info - * - * @name: name of the type - * @type: numeric identifier - * @family: address family - * @owner: module owner - * @hook_mask: mask of valid hooks - * @hooks: hookfn overrides - */ -struct nf_chain_type { - const char *name; - enum nft_chain_type type; - int family; - struct module *owner; - unsigned int hook_mask; - nf_hookfn *hooks[NF_MAX_HOOKS]; -}; - int nft_register_chain_type(const struct nf_chain_type *); void nft_unregister_chain_type(const struct nf_chain_type *); @@ -657,4 +589,72 @@ void nft_unregister_expr(struct nft_expr_type *); #define MODULE_ALIAS_NFT_SET() \ MODULE_ALIAS("nft-set") +/** + * struct nft_trans - nf_tables object update in transaction + * + * @list: used internally + * @msg_type: message type + * @ctx: transaction context + * @data: internal information related to the transaction + */ +struct nft_trans { + struct list_head list; + int msg_type; + struct nft_ctx ctx; + char data[0]; +}; + +struct nft_trans_rule { + struct nft_rule *rule; +}; + +#define nft_trans_rule(trans) \ + (((struct nft_trans_rule *)trans->data)->rule) + +struct nft_trans_set { + struct nft_set *set; + u32 set_id; +}; + +#define nft_trans_set(trans) \ + (((struct nft_trans_set *)trans->data)->set) +#define nft_trans_set_id(trans) \ + (((struct nft_trans_set *)trans->data)->set_id) + +struct nft_trans_chain { + bool update; + char name[NFT_CHAIN_MAXNAMELEN]; + struct nft_stats __percpu *stats; + u8 policy; +}; + +#define nft_trans_chain_update(trans) \ + (((struct nft_trans_chain *)trans->data)->update) +#define nft_trans_chain_name(trans) \ + (((struct nft_trans_chain *)trans->data)->name) +#define nft_trans_chain_stats(trans) \ + (((struct nft_trans_chain *)trans->data)->stats) +#define nft_trans_chain_policy(trans) \ + (((struct nft_trans_chain *)trans->data)->policy) + +struct nft_trans_table { + bool update; + bool enable; +}; + +#define nft_trans_table_update(trans) \ + (((struct nft_trans_table *)trans->data)->update) +#define nft_trans_table_enable(trans) \ + (((struct nft_trans_table *)trans->data)->enable) + +struct nft_trans_elem { + struct nft_set *set; + struct nft_set_elem elem; +}; + +#define nft_trans_elem_set(trans) \ + (((struct nft_trans_elem *)trans->data)->set) +#define nft_trans_elem(trans) \ + (((struct nft_trans_elem *)trans->data)->elem) + #endif /* _NET_NF_TABLES_H */ -- GitLab From f04e599e20d7ee9b9e5069c7d1ff59c21b9bf4c2 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Thu, 5 Mar 2015 14:56:15 +0100 Subject: [PATCH 02857/11651] netfilter: nf_tables: consolidate Kconfig options Signed-off-by: Pablo Neira Ayuso --- net/ipv4/netfilter/Kconfig | 38 +++++++++++++++++++++----------------- net/ipv6/netfilter/Kconfig | 18 +++++++++++------- net/netfilter/Kconfig | 20 +++++--------------- 3 files changed, 37 insertions(+), 39 deletions(-) diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig index 59f883d9cadf..fb20f363151f 100644 --- a/net/ipv4/netfilter/Kconfig +++ b/net/ipv4/netfilter/Kconfig @@ -36,24 +36,16 @@ config NF_CONNTRACK_PROC_COMPAT If unsure, say Y. -config NF_LOG_ARP - tristate "ARP packet logging" - default m if NETFILTER_ADVANCED=n - select NF_LOG_COMMON - -config NF_LOG_IPV4 - tristate "IPv4 packet logging" - default m if NETFILTER_ADVANCED=n - select NF_LOG_COMMON +if NF_TABLES config NF_TABLES_IPV4 - depends on NF_TABLES tristate "IPv4 nf_tables support" help This option enables the IPv4 support for nf_tables. +if NF_TABLES_IPV4 + config NFT_CHAIN_ROUTE_IPV4 - depends on NF_TABLES_IPV4 tristate "IPv4 nf_tables route chain support" help This option enables the "route" chain for IPv4 in nf_tables. This @@ -61,22 +53,34 @@ config NFT_CHAIN_ROUTE_IPV4 fields such as the source, destination, type of service and the packet mark. -config NF_REJECT_IPV4 - tristate "IPv4 packet rejection" - default m if NETFILTER_ADVANCED=n - config NFT_REJECT_IPV4 - depends on NF_TABLES_IPV4 select NF_REJECT_IPV4 default NFT_REJECT tristate +endif # NF_TABLES_IPV4 + config NF_TABLES_ARP - depends on NF_TABLES tristate "ARP nf_tables support" help This option enables the ARP support for nf_tables. +endif # NF_TABLES + +config NF_LOG_ARP + tristate "ARP packet logging" + default m if NETFILTER_ADVANCED=n + select NF_LOG_COMMON + +config NF_LOG_IPV4 + tristate "IPv4 packet logging" + default m if NETFILTER_ADVANCED=n + select NF_LOG_COMMON + +config NF_REJECT_IPV4 + tristate "IPv4 packet rejection" + default m if NETFILTER_ADVANCED=n + config NF_NAT_IPV4 tristate "IPv4 NAT" depends on NF_CONNTRACK_IPV4 diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig index a069822936e6..ca6998345b42 100644 --- a/net/ipv6/netfilter/Kconfig +++ b/net/ipv6/netfilter/Kconfig @@ -25,14 +25,16 @@ config NF_CONNTRACK_IPV6 To compile it as a module, choose M here. If unsure, say N. +if NF_TABLES + config NF_TABLES_IPV6 - depends on NF_TABLES tristate "IPv6 nf_tables support" help This option enables the IPv6 support for nf_tables. +if NF_TABLES_IPV6 + config NFT_CHAIN_ROUTE_IPV6 - depends on NF_TABLES_IPV6 tristate "IPv6 nf_tables route chain support" help This option enables the "route" chain for IPv6 in nf_tables. This @@ -40,16 +42,18 @@ config NFT_CHAIN_ROUTE_IPV6 fields such as the source, destination, flowlabel, hop-limit and the packet mark. -config NF_REJECT_IPV6 - tristate "IPv6 packet rejection" - default m if NETFILTER_ADVANCED=n - config NFT_REJECT_IPV6 - depends on NF_TABLES_IPV6 select NF_REJECT_IPV6 default NFT_REJECT tristate +endif # NF_TABLES_IPV6 +endif # NF_TABLES + +config NF_REJECT_IPV6 + tristate "IPv6 packet rejection" + default m if NETFILTER_ADVANCED=n + config NF_LOG_IPV6 tristate "IPv6 packet logging" default m if NETFILTER_ADVANCED=n diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig index c68c3b441381..971cd7526f4b 100644 --- a/net/netfilter/Kconfig +++ b/net/netfilter/Kconfig @@ -438,8 +438,10 @@ config NF_TABLES To compile it as a module, choose M here. +if NF_TABLES + config NF_TABLES_INET - depends on NF_TABLES && IPV6 + depends on IPV6 select NF_TABLES_IPV4 select NF_TABLES_IPV6 tristate "Netfilter nf_tables mixed IPv4/IPv6 tables support" @@ -447,21 +449,18 @@ config NF_TABLES_INET This option enables support for a mixed IPv4/IPv6 "inet" table. config NFT_EXTHDR - depends on NF_TABLES tristate "Netfilter nf_tables IPv6 exthdr module" help This option adds the "exthdr" expression that you can use to match IPv6 extension headers. config NFT_META - depends on NF_TABLES tristate "Netfilter nf_tables meta module" help This option adds the "meta" expression that you can use to match and to set packet metainformation such as the packet mark. config NFT_CT - depends on NF_TABLES depends on NF_CONNTRACK tristate "Netfilter nf_tables conntrack module" help @@ -469,42 +468,36 @@ config NFT_CT connection tracking information such as the flow state. config NFT_RBTREE - depends on NF_TABLES tristate "Netfilter nf_tables rbtree set module" help This option adds the "rbtree" set type (Red Black tree) that is used to build interval-based sets. config NFT_HASH - depends on NF_TABLES tristate "Netfilter nf_tables hash set module" help This option adds the "hash" set type that is used to build one-way mappings between matchings and actions. config NFT_COUNTER - depends on NF_TABLES tristate "Netfilter nf_tables counter module" help This option adds the "counter" expression that you can use to include packet and byte counters in a rule. config NFT_LOG - depends on NF_TABLES tristate "Netfilter nf_tables log module" help This option adds the "log" expression that you can use to log packets matching some criteria. config NFT_LIMIT - depends on NF_TABLES tristate "Netfilter nf_tables limit module" help This option adds the "limit" expression that you can use to ratelimit rule matchings. config NFT_MASQ - depends on NF_TABLES depends on NF_CONNTRACK depends on NF_NAT tristate "Netfilter nf_tables masquerade support" @@ -513,7 +506,6 @@ config NFT_MASQ to perform NAT in the masquerade flavour. config NFT_REDIR - depends on NF_TABLES depends on NF_CONNTRACK depends on NF_NAT tristate "Netfilter nf_tables redirect support" @@ -522,7 +514,6 @@ config NFT_REDIR to perform NAT in the redirect flavour. config NFT_NAT - depends on NF_TABLES depends on NF_CONNTRACK select NF_NAT tristate "Netfilter nf_tables nat module" @@ -531,7 +522,6 @@ config NFT_NAT typical Network Address Translation (NAT) packet transformations. config NFT_QUEUE - depends on NF_TABLES depends on NETFILTER_XTABLES depends on NETFILTER_NETLINK_QUEUE tristate "Netfilter nf_tables queue module" @@ -540,7 +530,6 @@ config NFT_QUEUE infrastructure (also known as NFQUEUE) from nftables. config NFT_REJECT - depends on NF_TABLES default m if NETFILTER_ADVANCED=n tristate "Netfilter nf_tables reject support" help @@ -554,7 +543,6 @@ config NFT_REJECT_INET tristate config NFT_COMPAT - depends on NF_TABLES depends on NETFILTER_XTABLES tristate "Netfilter x_tables over nf_tables module" help @@ -562,6 +550,8 @@ config NFT_COMPAT x_tables match/target extensions over the nf_tables framework. +endif # NF_TABLES + config NETFILTER_XTABLES tristate "Netfilter Xtables support (required for ip_tables)" default m if NETFILTER_ADVANCED=n -- GitLab From 1cae565e8b746f484f1ff1b71d2a1c89d7cf0668 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Thu, 5 Mar 2015 15:05:36 +0100 Subject: [PATCH 02858/11651] netfilter: nf_tables: limit maximum table name length to 32 bytes Set the same as we use for chain names, it should be enough. Signed-off-by: Pablo Neira Ayuso --- include/net/netfilter/nf_tables.h | 2 +- include/uapi/linux/netfilter/nf_tables.h | 1 + net/netfilter/nf_tables_api.c | 7 ++++--- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h index 04188b47629d..a143acafa5d9 100644 --- a/include/net/netfilter/nf_tables.h +++ b/include/net/netfilter/nf_tables.h @@ -535,7 +535,7 @@ struct nft_table { u64 hgenerator; u32 use; u16 flags; - char name[]; + char name[NFT_TABLE_MAXNAMELEN]; }; /** diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h index 832bc46db78b..b9783931503b 100644 --- a/include/uapi/linux/netfilter/nf_tables.h +++ b/include/uapi/linux/netfilter/nf_tables.h @@ -1,6 +1,7 @@ #ifndef _LINUX_NF_TABLES_H #define _LINUX_NF_TABLES_H +#define NFT_TABLE_MAXNAMELEN 32 #define NFT_CHAIN_MAXNAMELEN 32 #define NFT_USERDATA_MAXLEN 256 diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 199fd0f27b0e..284b20ce566b 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -401,7 +401,8 @@ nf_tables_chain_type_lookup(const struct nft_af_info *afi, } static const struct nla_policy nft_table_policy[NFTA_TABLE_MAX + 1] = { - [NFTA_TABLE_NAME] = { .type = NLA_STRING }, + [NFTA_TABLE_NAME] = { .type = NLA_STRING, + .len = NFT_TABLE_MAXNAMELEN - 1 }, [NFTA_TABLE_FLAGS] = { .type = NLA_U32 }, }; @@ -686,13 +687,13 @@ static int nf_tables_newtable(struct sock *nlsk, struct sk_buff *skb, if (!try_module_get(afi->owner)) return -EAFNOSUPPORT; - table = kzalloc(sizeof(*table) + nla_len(name), GFP_KERNEL); + table = kzalloc(sizeof(*table), GFP_KERNEL); if (table == NULL) { module_put(afi->owner); return -ENOMEM; } - nla_strlcpy(table->name, name, nla_len(name)); + nla_strlcpy(table->name, name, NFT_TABLE_MAXNAMELEN); INIT_LIST_HEAD(&table->chains); INIT_LIST_HEAD(&table->sets); table->flags = flags; -- GitLab From 7438b633a6b073d66a3fa3678ec0dd5928caa4af Mon Sep 17 00:00:00 2001 From: Mark Rutland Date: Wed, 4 Mar 2015 20:00:40 +0000 Subject: [PATCH 02859/11651] genirq / PM: describe IRQF_COND_SUSPEND With certain restrictions it is possible for a wakeup device to share an IRQ with an IRQF_NO_SUSPEND user, and the warnings introduced by commit cab303be91dc47942bc25de33dc1140123540800 are spurious. The new IRQF_COND_SUSPEND flag allows drivers to tell the core when these restrictions are met, allowing spurious warnings to be silenced. This patch documents how IRQF_COND_SUSPEND is expected to be used, updating some of the text now made invalid by its addition. Signed-off-by: Mark Rutland Signed-off-by: Rafael J. Wysocki --- Documentation/power/suspend-and-interrupts.txt | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/Documentation/power/suspend-and-interrupts.txt b/Documentation/power/suspend-and-interrupts.txt index 50493c9284b4..8afb29a8604a 100644 --- a/Documentation/power/suspend-and-interrupts.txt +++ b/Documentation/power/suspend-and-interrupts.txt @@ -112,8 +112,9 @@ any special interrupt handling logic for it to work. IRQF_NO_SUSPEND and enable_irq_wake() ------------------------------------- -There are no valid reasons to use both enable_irq_wake() and the IRQF_NO_SUSPEND -flag on the same IRQ. +There are very few valid reasons to use both enable_irq_wake() and the +IRQF_NO_SUSPEND flag on the same IRQ, and it is never valid to use both for the +same device. First of all, if the IRQ is not shared, the rules for handling IRQF_NO_SUSPEND interrupts (interrupt handlers are invoked after suspend_device_irqs()) are @@ -122,4 +123,13 @@ handlers are not invoked after suspend_device_irqs()). Second, both enable_irq_wake() and IRQF_NO_SUSPEND apply to entire IRQs and not to individual interrupt handlers, so sharing an IRQ between a system wakeup -interrupt source and an IRQF_NO_SUSPEND interrupt source does not make sense. +interrupt source and an IRQF_NO_SUSPEND interrupt source does not generally +make sense. + +In rare cases an IRQ can be shared between a wakeup device driver and an +IRQF_NO_SUSPEND user. In order for this to be safe, the wakeup device driver +must be able to discern spurious IRQs from genuine wakeup events (signalling +the latter to the core with pm_system_wakeup()), must use enable_irq_wake() to +ensure that the IRQ will function as a wakeup source, and must request the IRQ +with IRQF_COND_SUSPEND to tell the core that it meets these requirements. If +these requirements are not met, it is not valid to use IRQF_COND_SUSPEND. -- GitLab From f5c0a122800c301eecef93275b0c5d58bb4c15d9 Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Mon, 2 Mar 2015 12:51:02 -0500 Subject: [PATCH 02860/11651] Btrfs: remove extra run_delayed_refs in update_cowonly_root This got added with my dirty_bgs patch, it's not needed. Thanks, Signed-off-by: Josef Bacik Signed-off-by: Chris Mason --- fs/btrfs/transaction.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 038fcf6051e0..323c6541d3dc 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c @@ -1052,9 +1052,6 @@ static int update_cowonly_root(struct btrfs_trans_handle *trans, ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1); if (ret) return ret; - ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1); - if (ret) - return ret; } return 0; -- GitLab From 3a8b36f378060d20062a0918e99fae39ff077bf0 Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Sun, 1 Mar 2015 20:36:00 +0000 Subject: [PATCH 02861/11651] Btrfs: fix data loss in the fast fsync path When using the fast file fsync code path we can miss the fact that new writes happened since the last file fsync and therefore return without waiting for the IO to finish and write the new extents to the fsync log. Here's an example scenario where the fsync will miss the fact that new file data exists that wasn't yet durably persisted: 1. fs_info->last_trans_committed == N - 1 and current transaction is transaction N (fs_info->generation == N); 2. do a buffered write; 3. fsync our inode, this clears our inode's full sync flag, starts an ordered extent and waits for it to complete - when it completes at btrfs_finish_ordered_io(), the inode's last_trans is set to the value N (via btrfs_update_inode_fallback -> btrfs_update_inode -> btrfs_set_inode_last_trans); 4. transaction N is committed, so fs_info->last_trans_committed is now set to the value N and fs_info->generation remains with the value N; 5. do another buffered write, when this happens btrfs_file_write_iter sets our inode's last_trans to the value N + 1 (that is fs_info->generation + 1 == N + 1); 6. transaction N + 1 is started and fs_info->generation now has the value N + 1; 7. transaction N + 1 is committed, so fs_info->last_trans_committed is set to the value N + 1; 8. fsync our inode - because it doesn't have the full sync flag set, we only start the ordered extent, we don't wait for it to complete (only in a later phase) therefore its last_trans field has the value N + 1 set previously by btrfs_file_write_iter(), and so we have: inode->last_trans <= fs_info->last_trans_committed (N + 1) (N + 1) Which made us not log the last buffered write and exit the fsync handler immediately, returning success (0) to user space and resulting in data loss after a crash. This can actually be triggered deterministically and the following excerpt from a testcase I made for xfstests triggers the issue. It moves a dummy file across directories and then fsyncs the old parent directory - this is just to trigger a transaction commit, so moving files around isn't directly related to the issue but it was chosen because running 'sync' for example does more than just committing the current transaction, as it flushes/waits for all file data to be persisted. The issue can also happen at random periods, since the transaction kthread periodicaly commits the current transaction (about every 30 seconds by default). The body of the test is: _scratch_mkfs >> $seqres.full 2>&1 _init_flakey _mount_flakey # Create our main test file 'foo', the one we check for data loss. # By doing an fsync against our file, it makes btrfs clear the 'needs_full_sync' # bit from its flags (btrfs inode specific flags). $XFS_IO_PROG -f -c "pwrite -S 0xaa 0 8K" \ -c "fsync" $SCRATCH_MNT/foo | _filter_xfs_io # Now create one other file and 2 directories. We will move this second file # from one directory to the other later because it forces btrfs to commit its # currently open transaction if we fsync the old parent directory. This is # necessary to trigger the data loss bug that affected btrfs. mkdir $SCRATCH_MNT/testdir_1 touch $SCRATCH_MNT/testdir_1/bar mkdir $SCRATCH_MNT/testdir_2 # Make sure everything is durably persisted. sync # Write more 8Kb of data to our file. $XFS_IO_PROG -c "pwrite -S 0xbb 8K 8K" $SCRATCH_MNT/foo | _filter_xfs_io # Move our 'bar' file into a new directory. mv $SCRATCH_MNT/testdir_1/bar $SCRATCH_MNT/testdir_2/bar # Fsync our first directory. Because it had a file moved into some other # directory, this made btrfs commit the currently open transaction. This is # a condition necessary to trigger the data loss bug. $XFS_IO_PROG -c "fsync" $SCRATCH_MNT/testdir_1 # Now fsync our main test file. If the fsync succeeds, we expect the 8Kb of # data we wrote previously to be persisted and available if a crash happens. # This did not happen with btrfs, because of the transaction commit that # happened when we fsynced the parent directory. $XFS_IO_PROG -c "fsync" $SCRATCH_MNT/foo # Simulate a crash/power loss. _load_flakey_table $FLAKEY_DROP_WRITES _unmount_flakey _load_flakey_table $FLAKEY_ALLOW_WRITES _mount_flakey # Now check that all data we wrote before are available. echo "File content after log replay:" od -t x1 $SCRATCH_MNT/foo status=0 exit The expected golden output for the test, which is what we get with this fix applied (or when running against ext3/4 and xfs), is: wrote 8192/8192 bytes at offset 0 XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) wrote 8192/8192 bytes at offset 8192 XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) File content after log replay: 0000000 aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa * 0020000 bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb * 0040000 Without this fix applied, the output shows the test file does not have the second 8Kb extent that we successfully fsynced: wrote 8192/8192 bytes at offset 0 XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) wrote 8192/8192 bytes at offset 8192 XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) File content after log replay: 0000000 aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa * 0020000 So fix this by skipping the fsync only if we're doing a full sync and if the inode's last_trans is <= fs_info->last_trans_committed, or if the inode is already in the log. Also remove setting the inode's last_trans in btrfs_file_write_iter since it's useless/unreliable. Also because btrfs_file_write_iter no longer sets inode->last_trans to fs_info->generation + 1, don't set last_trans to 0 if we bail out and don't bail out if last_trans is 0, otherwise something as simple as the following example wouldn't log the second write on the last fsync: 1. write to file 2. fsync file 3. fsync file |--> btrfs_inode_in_log() returns true and it set last_trans to 0 4. write to file |--> btrfs_file_write_iter() no longers sets last_trans, so it remained with a value of 0 5. fsync |--> inode->last_trans == 0, so it bails out without logging the second write A test case for xfstests will be sent soon. CC: Signed-off-by: Filipe Manana Signed-off-by: Chris Mason --- fs/btrfs/file.c | 56 ++++++++++++++++++++++++------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index b476e5645034..6351947c9bb0 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -1811,22 +1811,10 @@ static ssize_t btrfs_file_write_iter(struct kiocb *iocb, mutex_unlock(&inode->i_mutex); /* - * we want to make sure fsync finds this change - * but we haven't joined a transaction running right now. - * - * Later on, someone is sure to update the inode and get the - * real transid recorded. - * - * We set last_trans now to the fs_info generation + 1, - * this will either be one more than the running transaction - * or the generation used for the next transaction if there isn't - * one running right now. - * * We also have to set last_sub_trans to the current log transid, * otherwise subsequent syncs to a file that's been synced in this * transaction will appear to have already occured. */ - BTRFS_I(inode)->last_trans = root->fs_info->generation + 1; BTRFS_I(inode)->last_sub_trans = root->log_transid; if (num_written > 0) { err = generic_write_sync(file, pos, num_written); @@ -1959,25 +1947,37 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) atomic_inc(&root->log_batch); /* - * check the transaction that last modified this inode - * and see if its already been committed - */ - if (!BTRFS_I(inode)->last_trans) { - mutex_unlock(&inode->i_mutex); - goto out; - } - - /* - * if the last transaction that changed this file was before - * the current transaction, we can bail out now without any - * syncing + * If the last transaction that changed this file was before the current + * transaction and we have the full sync flag set in our inode, we can + * bail out now without any syncing. + * + * Note that we can't bail out if the full sync flag isn't set. This is + * because when the full sync flag is set we start all ordered extents + * and wait for them to fully complete - when they complete they update + * the inode's last_trans field through: + * + * btrfs_finish_ordered_io() -> + * btrfs_update_inode_fallback() -> + * btrfs_update_inode() -> + * btrfs_set_inode_last_trans() + * + * So we are sure that last_trans is up to date and can do this check to + * bail out safely. For the fast path, when the full sync flag is not + * set in our inode, we can not do it because we start only our ordered + * extents and don't wait for them to complete (that is when + * btrfs_finish_ordered_io runs), so here at this point their last_trans + * value might be less than or equals to fs_info->last_trans_committed, + * and setting a speculative last_trans for an inode when a buffered + * write is made (such as fs_info->generation + 1 for example) would not + * be reliable since after setting the value and before fsync is called + * any number of transactions can start and commit (transaction kthread + * commits the current transaction periodically), and a transaction + * commit does not start nor waits for ordered extents to complete. */ smp_mb(); if (btrfs_inode_in_log(inode, root->fs_info->generation) || - BTRFS_I(inode)->last_trans <= - root->fs_info->last_trans_committed) { - BTRFS_I(inode)->last_trans = 0; - + (full_sync && BTRFS_I(inode)->last_trans <= + root->fs_info->last_trans_committed)) { /* * We'v had everything committed since the last time we were * modified so clear this flag in case it was set for whatever -- GitLab From dd9ef135e3542ffc621c4eb7f0091870ec7a1504 Mon Sep 17 00:00:00 2001 From: Quentin Casasnovas Date: Tue, 3 Mar 2015 16:31:38 +0100 Subject: [PATCH 02862/11651] Btrfs:__add_inode_ref: out of bounds memory read when looking for extended ref. Improper arithmetics when calculting the address of the extended ref could lead to an out of bounds memory read and kernel panic. Signed-off-by: Quentin Casasnovas Reviewed-by: David Sterba cc: stable@vger.kernel.org # v3.7+ Signed-off-by: Chris Mason --- fs/btrfs/tree-log.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index f96996a1b70c..9a1c1711f360 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -1012,7 +1012,7 @@ again: base = btrfs_item_ptr_offset(leaf, path->slots[0]); while (cur_offset < item_size) { - extref = (struct btrfs_inode_extref *)base + cur_offset; + extref = (struct btrfs_inode_extref *)(base + cur_offset); victim_name_len = btrfs_inode_extref_name_len(leaf, extref); -- GitLab From 4b5edb2f4a57dd0da85b9e2cbace06447e02e097 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Thu, 5 Mar 2015 13:37:05 +1100 Subject: [PATCH 02863/11651] mpls: using vzalloc requires including vmalloc.h Fixes this build error: net/mpls/af_mpls.c: In function 'resize_platform_label_table': net/mpls/af_mpls.c:767:4: error: implicit declaration of function 'vzalloc' [-Werror=implicit-function-declaration] labels = vzalloc(size); ^ Fixes: 7720c01f3f59 ("mpls: Add a sysctl to control the size of the mpls label table") Signed-off-by: Stephen Rothwell Signed-off-by: David S. Miller --- net/mpls/af_mpls.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c index 23e51d13b0ff..20cf48a8593d 100644 --- a/net/mpls/af_mpls.c +++ b/net/mpls/af_mpls.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include -- GitLab From 386668a61f90412a61a12719d15dfec58d0ece1c Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Wed, 4 Mar 2015 11:43:03 -0800 Subject: [PATCH 02864/11651] net: bcmgenet: properly disable password matching bcmgenet_set_wol() correctly sets MPD_PW_EN when a password is specified to match magic packets against, however, when we switch from a password-matching to a matching without password we would leave this bit turned on, and GENET would only match magic packets with passwords. This can be reproduced using the following sequence: ethtool -s eth0 wol g ethtool -s eth0 wol s sopass 00:11:22:33:44:55 ethtool -s eth0 wol g The simple fix is to clear the MPD_PWD_EN bit when WAKE_MAGICSECURE is not set. Fixes: c51de7f3976b ("net: bcmgenet: add Wake-on-LAN support code") Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c b/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c index 149a0d70c108..b97122926d3a 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c @@ -73,15 +73,17 @@ int bcmgenet_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) if (wol->wolopts & ~(WAKE_MAGIC | WAKE_MAGICSECURE)) return -EINVAL; + reg = bcmgenet_umac_readl(priv, UMAC_MPD_CTRL); if (wol->wolopts & WAKE_MAGICSECURE) { bcmgenet_umac_writel(priv, get_unaligned_be16(&wol->sopass[0]), UMAC_MPD_PW_MS); bcmgenet_umac_writel(priv, get_unaligned_be32(&wol->sopass[2]), UMAC_MPD_PW_LS); - reg = bcmgenet_umac_readl(priv, UMAC_MPD_CTRL); reg |= MPD_PW_EN; - bcmgenet_umac_writel(priv, reg, UMAC_MPD_CTRL); + } else { + reg &= ~MPD_PW_EN; } + bcmgenet_umac_writel(priv, reg, UMAC_MPD_CTRL); /* Flag the device and relevant IRQ as wakeup capable */ if (wol->wolopts) { -- GitLab From a05c2d112c0c4a768bfad47c33f28a15f8cf1193 Mon Sep 17 00:00:00 2001 From: WANG Cong Date: Wed, 4 Mar 2015 20:11:43 -0800 Subject: [PATCH 02865/11651] net_sched: move tp->root allocation into route4_init() Cc: Jamal Hadi Salim Signed-off-by: Cong Wang Acked-by: Jamal Hadi Salim Signed-off-by: David S. Miller --- net/sched/cls_route.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c index 2ecd24688554..bb8a60235d01 100644 --- a/net/sched/cls_route.c +++ b/net/sched/cls_route.c @@ -258,6 +258,13 @@ static unsigned long route4_get(struct tcf_proto *tp, u32 handle) static int route4_init(struct tcf_proto *tp) { + struct route4_head *head; + + head = kzalloc(sizeof(struct route4_head), GFP_KERNEL); + if (head == NULL) + return -ENOBUFS; + + rcu_assign_pointer(tp->root, head); return 0; } @@ -484,13 +491,6 @@ static int route4_change(struct net *net, struct sk_buff *in_skb, return -EINVAL; err = -ENOBUFS; - if (head == NULL) { - head = kzalloc(sizeof(struct route4_head), GFP_KERNEL); - if (head == NULL) - goto errout; - rcu_assign_pointer(tp->root, head); - } - f = kzalloc(sizeof(struct route4_filter), GFP_KERNEL); if (!f) goto errout; -- GitLab From 33f8b9ecdb15bc8a3c6be0072a7e0f7a345856f1 Mon Sep 17 00:00:00 2001 From: WANG Cong Date: Wed, 4 Mar 2015 20:11:44 -0800 Subject: [PATCH 02866/11651] net_sched: move tp->root allocation into fw_init() Cc: Jamal Hadi Salim Signed-off-by: Cong Wang Acked-by: Jamal Hadi Salim Signed-off-by: David S. Miller --- net/sched/cls_fw.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c index a5269f76004c..9d9aa3e82b10 100644 --- a/net/sched/cls_fw.c +++ b/net/sched/cls_fw.c @@ -33,6 +33,7 @@ struct fw_head { u32 mask; + bool mask_set; struct fw_filter __rcu *ht[HTSIZE]; struct rcu_head rcu; }; @@ -113,6 +114,14 @@ static unsigned long fw_get(struct tcf_proto *tp, u32 handle) static int fw_init(struct tcf_proto *tp) { + struct fw_head *head; + + head = kzalloc(sizeof(struct fw_head), GFP_KERNEL); + if (head == NULL) + return -ENOBUFS; + + head->mask_set = false; + rcu_assign_pointer(tp->root, head); return 0; } @@ -286,17 +295,11 @@ static int fw_change(struct net *net, struct sk_buff *in_skb, if (!handle) return -EINVAL; - if (head == NULL) { - u32 mask = 0xFFFFFFFF; + if (!head->mask_set) { + head->mask = 0xFFFFFFFF; if (tb[TCA_FW_MASK]) - mask = nla_get_u32(tb[TCA_FW_MASK]); - - head = kzalloc(sizeof(struct fw_head), GFP_KERNEL); - if (head == NULL) - return -ENOBUFS; - head->mask = mask; - - rcu_assign_pointer(tp->root, head); + head->mask = nla_get_u32(tb[TCA_FW_MASK]); + head->mask_set = true; } f = kzalloc(sizeof(struct fw_filter), GFP_KERNEL); -- GitLab From 3e32e733d1bbb3f227259dc782ef01d5706bdae0 Mon Sep 17 00:00:00 2001 From: Alexander Drozdov Date: Thu, 5 Mar 2015 10:29:39 +0300 Subject: [PATCH 02867/11651] ipv4: ip_check_defrag should not assume that skb_network_offset is zero ip_check_defrag() may be used by af_packet to defragment outgoing packets. skb_network_offset() of af_packet's outgoing packets is not zero. Signed-off-by: Alexander Drozdov Signed-off-by: David S. Miller --- net/ipv4/ip_fragment.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index 2c8d98e728c0..145a50c4d566 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c @@ -659,27 +659,30 @@ EXPORT_SYMBOL(ip_defrag); struct sk_buff *ip_check_defrag(struct sk_buff *skb, u32 user) { struct iphdr iph; + int netoff; u32 len; if (skb->protocol != htons(ETH_P_IP)) return skb; - if (skb_copy_bits(skb, 0, &iph, sizeof(iph)) < 0) + netoff = skb_network_offset(skb); + + if (skb_copy_bits(skb, netoff, &iph, sizeof(iph)) < 0) return skb; if (iph.ihl < 5 || iph.version != 4) return skb; len = ntohs(iph.tot_len); - if (skb->len < len || len < (iph.ihl * 4)) + if (skb->len < netoff + len || len < (iph.ihl * 4)) return skb; if (ip_is_fragment(&iph)) { skb = skb_share_check(skb, GFP_ATOMIC); if (skb) { - if (!pskb_may_pull(skb, iph.ihl*4)) + if (!pskb_may_pull(skb, netoff + iph.ihl * 4)) return skb; - if (pskb_trim_rcsum(skb, len)) + if (pskb_trim_rcsum(skb, netoff + len)) return skb; memset(IPCB(skb), 0, sizeof(struct inet_skb_parm)); if (ip_defrag(skb, user)) -- GitLab From 948fa2d115c553ae32aced66e0f00f89245dc05e Mon Sep 17 00:00:00 2001 From: Erik Hugne Date: Thu, 5 Mar 2015 10:23:48 +0100 Subject: [PATCH 02868/11651] tipc: increase size of tipc discovery messages The payload area following the TIPC discovery message header is an opaque area defined by the media. INT_H_SIZE was enough for Ethernet/IB/IPv4 but needs to be expanded to carry IPv6 addressing information. Signed-off-by: Erik Hugne Signed-off-by: David S. Miller --- net/tipc/discover.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/net/tipc/discover.c b/net/tipc/discover.c index feef3753615d..5967506833ce 100644 --- a/net/tipc/discover.c +++ b/net/tipc/discover.c @@ -86,7 +86,7 @@ static void tipc_disc_init_msg(struct net *net, struct sk_buff *buf, u32 type, msg = buf_msg(buf); tipc_msg_init(tn->own_addr, msg, LINK_CONFIG, type, - INT_H_SIZE, dest_domain); + MAX_H_SIZE, dest_domain); msg_set_non_seq(msg, 1); msg_set_node_sig(msg, tn->random); msg_set_dest_domain(msg, dest_domain); @@ -249,7 +249,7 @@ void tipc_disc_rcv(struct net *net, struct sk_buff *buf, /* Send response, if necessary */ if (respond && (mtyp == DSC_REQ_MSG)) { - rbuf = tipc_buf_acquire(INT_H_SIZE); + rbuf = tipc_buf_acquire(MAX_H_SIZE); if (rbuf) { tipc_disc_init_msg(net, rbuf, DSC_RESP_MSG, bearer); tipc_bearer_send(net, bearer->identity, rbuf, &maddr); @@ -359,8 +359,7 @@ int tipc_disc_create(struct net *net, struct tipc_bearer *b_ptr, req = kmalloc(sizeof(*req), GFP_ATOMIC); if (!req) return -ENOMEM; - - req->buf = tipc_buf_acquire(INT_H_SIZE); + req->buf = tipc_buf_acquire(MAX_H_SIZE); if (!req->buf) { kfree(req); return -ENOMEM; -- GitLab From d0f91938bede204a343473792529e0db7d599836 Mon Sep 17 00:00:00 2001 From: Erik Hugne Date: Thu, 5 Mar 2015 10:23:49 +0100 Subject: [PATCH 02869/11651] tipc: add ip/udp media type The ip/udp bearer can be configured in a point-to-point mode by specifying both local and remote ip/hostname, or it can be enabled in multicast mode, where links are established to all tipc nodes that have joined the same multicast group. The multicast IP address is generated based on the TIPC network ID, but can be overridden by using another multicast address as remote ip. Signed-off-by: Erik Hugne Reviewed-by: Jon Maloy Reviewed-by: Ying Xue Signed-off-by: David S. Miller --- include/uapi/linux/tipc_netlink.h | 9 + net/tipc/Kconfig | 8 + net/tipc/Makefile | 1 + net/tipc/bearer.c | 13 +- net/tipc/bearer.h | 12 +- net/tipc/msg.h | 2 +- net/tipc/udp_media.c | 442 ++++++++++++++++++++++++++++++ 7 files changed, 479 insertions(+), 8 deletions(-) create mode 100644 net/tipc/udp_media.c diff --git a/include/uapi/linux/tipc_netlink.h b/include/uapi/linux/tipc_netlink.h index 8d723824ad69..d4c8f142ba63 100644 --- a/include/uapi/linux/tipc_netlink.h +++ b/include/uapi/linux/tipc_netlink.h @@ -83,11 +83,20 @@ enum { TIPC_NLA_BEARER_NAME, /* string */ TIPC_NLA_BEARER_PROP, /* nest */ TIPC_NLA_BEARER_DOMAIN, /* u32 */ + TIPC_NLA_BEARER_UDP_OPTS, /* nest */ __TIPC_NLA_BEARER_MAX, TIPC_NLA_BEARER_MAX = __TIPC_NLA_BEARER_MAX - 1 }; +enum { + TIPC_NLA_UDP_UNSPEC, + TIPC_NLA_UDP_LOCAL, /* sockaddr_storage */ + TIPC_NLA_UDP_REMOTE, /* sockaddr_storage */ + + __TIPC_NLA_UDP_MAX, + TIPC_NLA_UDP_MAX = __TIPC_NLA_UDP_MAX - 1 +}; /* Socket info */ enum { TIPC_NLA_SOCK_UNSPEC, diff --git a/net/tipc/Kconfig b/net/tipc/Kconfig index 91c8a8e031db..c25a3a149dc4 100644 --- a/net/tipc/Kconfig +++ b/net/tipc/Kconfig @@ -26,3 +26,11 @@ config TIPC_MEDIA_IB help Saying Y here will enable support for running TIPC on IP-over-InfiniBand devices. +config TIPC_MEDIA_UDP + bool "IP/UDP media type support" + depends on TIPC + select NET_UDP_TUNNEL + help + Saying Y here will enable support for running TIPC over IP/UDP + bool + default y diff --git a/net/tipc/Makefile b/net/tipc/Makefile index 599b1a540d2b..57e460be4692 100644 --- a/net/tipc/Makefile +++ b/net/tipc/Makefile @@ -10,5 +10,6 @@ tipc-y += addr.o bcast.o bearer.o \ netlink.o netlink_compat.o node.o socket.o eth_media.o \ server.o socket.o +tipc-$(CONFIG_TIPC_MEDIA_UDP) += udp_media.o tipc-$(CONFIG_TIPC_MEDIA_IB) += ib_media.o tipc-$(CONFIG_SYSCTL) += sysctl.o diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index af6deeb397a8..840db89e4283 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c @@ -47,6 +47,9 @@ static struct tipc_media * const media_info_array[] = { ð_media_info, #ifdef CONFIG_TIPC_MEDIA_IB &ib_media_info, +#endif +#ifdef CONFIG_TIPC_MEDIA_UDP + &udp_media_info, #endif NULL }; @@ -216,7 +219,8 @@ void tipc_bearer_remove_dest(struct net *net, u32 bearer_id, u32 dest) * tipc_enable_bearer - enable bearer with the given name */ static int tipc_enable_bearer(struct net *net, const char *name, - u32 disc_domain, u32 priority) + u32 disc_domain, u32 priority, + struct nlattr *attr[]) { struct tipc_net *tn = net_generic(net, tipc_net_id); struct tipc_bearer *b_ptr; @@ -304,7 +308,7 @@ restart: strcpy(b_ptr->name, name); b_ptr->media = m_ptr; - res = m_ptr->enable_media(net, b_ptr); + res = m_ptr->enable_media(net, b_ptr, attr); if (res) { pr_warn("Bearer <%s> rejected, enable failure (%d)\n", name, -res); @@ -372,7 +376,8 @@ static void bearer_disable(struct net *net, struct tipc_bearer *b_ptr, kfree_rcu(b_ptr, rcu); } -int tipc_enable_l2_media(struct net *net, struct tipc_bearer *b) +int tipc_enable_l2_media(struct net *net, struct tipc_bearer *b, + struct nlattr *attr[]) { struct net_device *dev; char *driver_name = strchr((const char *)b->name, ':') + 1; @@ -791,7 +796,7 @@ int tipc_nl_bearer_enable(struct sk_buff *skb, struct genl_info *info) } rtnl_lock(); - err = tipc_enable_bearer(net, bearer, domain, prio); + err = tipc_enable_bearer(net, bearer, domain, prio, attrs); if (err) { rtnl_unlock(); return err; diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h index 097aff08ad5b..5cad243ee8fc 100644 --- a/net/tipc/bearer.h +++ b/net/tipc/bearer.h @@ -41,7 +41,7 @@ #include #define MAX_BEARERS 2 -#define MAX_MEDIA 2 +#define MAX_MEDIA 3 #define MAX_NODES 4096 #define WSIZE 32 @@ -59,6 +59,7 @@ */ #define TIPC_MEDIA_TYPE_ETH 1 #define TIPC_MEDIA_TYPE_IB 2 +#define TIPC_MEDIA_TYPE_UDP 3 /** * struct tipc_node_map - set of node identifiers @@ -104,7 +105,8 @@ struct tipc_media { int (*send_msg)(struct net *net, struct sk_buff *buf, struct tipc_bearer *b_ptr, struct tipc_media_addr *dest); - int (*enable_media)(struct net *net, struct tipc_bearer *b_ptr); + int (*enable_media)(struct net *net, struct tipc_bearer *b_ptr, + struct nlattr *attr[]); void (*disable_media)(struct tipc_bearer *b_ptr); int (*addr2str)(struct tipc_media_addr *addr, char *strbuf, @@ -183,6 +185,9 @@ extern struct tipc_media eth_media_info; #ifdef CONFIG_TIPC_MEDIA_IB extern struct tipc_media ib_media_info; #endif +#ifdef CONFIG_TIPC_MEDIA_UDP +extern struct tipc_media udp_media_info; +#endif int tipc_nl_bearer_disable(struct sk_buff *skb, struct genl_info *info); int tipc_nl_bearer_enable(struct sk_buff *skb, struct genl_info *info); @@ -197,7 +202,8 @@ int tipc_nl_media_set(struct sk_buff *skb, struct genl_info *info); int tipc_media_set_priority(const char *name, u32 new_value); int tipc_media_set_window(const char *name, u32 new_value); void tipc_media_addr_printf(char *buf, int len, struct tipc_media_addr *a); -int tipc_enable_l2_media(struct net *net, struct tipc_bearer *b); +int tipc_enable_l2_media(struct net *net, struct tipc_bearer *b, + struct nlattr *attrs[]); void tipc_disable_l2_media(struct tipc_bearer *b); int tipc_l2_send_msg(struct net *net, struct sk_buff *buf, struct tipc_bearer *b, struct tipc_media_addr *dest); diff --git a/net/tipc/msg.h b/net/tipc/msg.h index c1cc8d7a5d52..fa167846d1ab 100644 --- a/net/tipc/msg.h +++ b/net/tipc/msg.h @@ -87,7 +87,7 @@ struct plist; * Note: Headroom should be a multiple of 4 to ensure the TIPC header fields * are word aligned for quicker access */ -#define BUF_HEADROOM LL_MAX_HEADER +#define BUF_HEADROOM (LL_MAX_HEADER + 48) struct tipc_skb_cb { void *handle; diff --git a/net/tipc/udp_media.c b/net/tipc/udp_media.c new file mode 100644 index 000000000000..0d10001db40d --- /dev/null +++ b/net/tipc/udp_media.c @@ -0,0 +1,442 @@ +/* net/tipc/udp_media.c: IP bearer support for TIPC + * + * Copyright (c) 2015, Ericsson AB + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the names of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "core.h" +#include "bearer.h" + +/* IANA assigned UDP port */ +#define UDP_PORT_DEFAULT 6118 + +static const struct nla_policy tipc_nl_udp_policy[TIPC_NLA_UDP_MAX + 1] = { + [TIPC_NLA_UDP_UNSPEC] = {.type = NLA_UNSPEC}, + [TIPC_NLA_UDP_LOCAL] = {.type = NLA_BINARY, + .len = sizeof(struct sockaddr_storage)}, + [TIPC_NLA_UDP_REMOTE] = {.type = NLA_BINARY, + .len = sizeof(struct sockaddr_storage)}, +}; + +/** + * struct udp_media_addr - IP/UDP addressing information + * + * This is the bearer level originating address used in neighbor discovery + * messages, and all fields should be in network byte order + */ +struct udp_media_addr { + __be16 proto; + __be16 udp_port; + union { + struct in_addr ipv4; + struct in6_addr ipv6; + }; +}; + +/** + * struct udp_bearer - ip/udp bearer data structure + * @bearer: associated generic tipc bearer + * @ubsock: bearer associated socket + * @ifindex: local address scope + * @work: used to schedule deferred work on a bearer + */ +struct udp_bearer { + struct tipc_bearer __rcu *bearer; + struct socket *ubsock; + u32 ifindex; + struct work_struct work; +}; + +/* udp_media_addr_set - convert a ip/udp address to a TIPC media address */ +static void tipc_udp_media_addr_set(struct tipc_media_addr *addr, + struct udp_media_addr *ua) +{ + memset(addr, 0, sizeof(struct tipc_media_addr)); + addr->media_id = TIPC_MEDIA_TYPE_UDP; + memcpy(addr->value, ua, sizeof(struct udp_media_addr)); + if (ntohs(ua->proto) == ETH_P_IP) { + if (ipv4_is_multicast(ua->ipv4.s_addr)) + addr->broadcast = 1; + } else if (ntohs(ua->proto) == ETH_P_IPV6) { + if (ipv6_addr_type(&ua->ipv6) & IPV6_ADDR_MULTICAST) + addr->broadcast = 1; + } else { + pr_err("Invalid UDP media address\n"); + } +} + +/* tipc_udp_addr2str - convert ip/udp address to string */ +static int tipc_udp_addr2str(struct tipc_media_addr *a, char *buf, int size) +{ + struct udp_media_addr *ua = (struct udp_media_addr *)&a->value; + + if (ntohs(ua->proto) == ETH_P_IP) + snprintf(buf, size, "%pI4:%u", &ua->ipv4, ntohs(ua->udp_port)); + else if (ntohs(ua->proto) == ETH_P_IPV6) + snprintf(buf, size, "%pI6:%u", &ua->ipv6, ntohs(ua->udp_port)); + else + pr_err("Invalid UDP media address\n"); + return 0; +} + +/* tipc_udp_msg2addr - extract an ip/udp address from a TIPC ndisc message */ +static int tipc_udp_msg2addr(struct tipc_bearer *b, struct tipc_media_addr *a, + char *msg) +{ + struct udp_media_addr *ua; + + ua = (struct udp_media_addr *) (msg + TIPC_MEDIA_ADDR_OFFSET); + if (msg[TIPC_MEDIA_TYPE_OFFSET] != TIPC_MEDIA_TYPE_UDP) + return -EINVAL; + tipc_udp_media_addr_set(a, ua); + return 0; +} + +/* tipc_udp_addr2msg - write an ip/udp address to a TIPC ndisc message */ +static int tipc_udp_addr2msg(char *msg, struct tipc_media_addr *a) +{ + memset(msg, 0, TIPC_MEDIA_INFO_SIZE); + msg[TIPC_MEDIA_TYPE_OFFSET] = TIPC_MEDIA_TYPE_UDP; + memcpy(msg + TIPC_MEDIA_ADDR_OFFSET, a->value, + sizeof(struct udp_media_addr)); + return 0; +} + +/* tipc_send_msg - enqueue a send request */ +static int tipc_udp_send_msg(struct net *net, struct sk_buff *skb, + struct tipc_bearer *b, + struct tipc_media_addr *dest) +{ + int ttl, err = 0; + struct udp_bearer *ub; + struct udp_media_addr *dst = (struct udp_media_addr *)&dest->value; + struct udp_media_addr *src = (struct udp_media_addr *)&b->addr.value; + struct sk_buff *clone; + struct rtable *rt; + + clone = skb_clone(skb, GFP_ATOMIC); + skb_set_inner_protocol(clone, htons(ETH_P_TIPC)); + ub = rcu_dereference_rtnl(b->media_ptr); + if (!ub) { + err = -ENODEV; + goto tx_error; + } + if (htons(dst->proto) == ETH_P_IP) { + struct flowi4 fl = { + .daddr = dst->ipv4.s_addr, + .saddr = src->ipv4.s_addr, + .flowi4_mark = clone->mark, + .flowi4_proto = IPPROTO_UDP + }; + rt = ip_route_output_key(net, &fl); + if (IS_ERR(rt)) { + err = PTR_ERR(rt); + goto tx_error; + } + ttl = ip4_dst_hoplimit(&rt->dst); + err = udp_tunnel_xmit_skb(rt, clone, src->ipv4.s_addr, + dst->ipv4.s_addr, 0, ttl, 0, + src->udp_port, dst->udp_port, + false, true); + if (err < 0) { + ip_rt_put(rt); + goto tx_error; + } +#if IS_ENABLED(CONFIG_IPV6) + } else { + struct dst_entry *ndst; + struct flowi6 fl6 = { + .flowi6_oif = ub->ifindex, + .daddr = dst->ipv6, + .saddr = src->ipv6, + .flowi6_proto = IPPROTO_UDP + }; + err = ip6_dst_lookup(ub->ubsock->sk, &ndst, &fl6); + if (err) + goto tx_error; + ttl = ip6_dst_hoplimit(ndst); + err = udp_tunnel6_xmit_skb(ndst, clone, ndst->dev, &src->ipv6, + &dst->ipv6, 0, ttl, src->udp_port, + dst->udp_port, false); +#endif + } + return err; + +tx_error: + kfree_skb(clone); + return err; +} + +/* tipc_udp_recv - read data from bearer socket */ +static int tipc_udp_recv(struct sock *sk, struct sk_buff *skb) +{ + struct udp_bearer *ub; + struct tipc_bearer *b; + + ub = rcu_dereference_sk_user_data(sk); + if (!ub) { + pr_err_ratelimited("Failed to get UDP bearer reference"); + kfree_skb(skb); + return 0; + } + + skb_pull(skb, sizeof(struct udphdr)); + rcu_read_lock(); + b = rcu_dereference_rtnl(ub->bearer); + + if (b) { + tipc_rcv(sock_net(sk), skb, b); + rcu_read_unlock(); + return 0; + } + rcu_read_unlock(); + kfree_skb(skb); + return 0; +} + +static int enable_mcast(struct udp_bearer *ub, struct udp_media_addr *remote) +{ + int err = 0; + struct ip_mreqn mreqn; + struct sock *sk = ub->ubsock->sk; + + if (ntohs(remote->proto) == ETH_P_IP) { + if (!ipv4_is_multicast(remote->ipv4.s_addr)) + return 0; + mreqn.imr_multiaddr = remote->ipv4; + mreqn.imr_ifindex = ub->ifindex; + err = __ip_mc_join_group(sk, &mreqn); + } else { + if (!ipv6_addr_is_multicast(&remote->ipv6)) + return 0; + err = __ipv6_sock_mc_join(sk, ub->ifindex, &remote->ipv6); + } + return err; +} + +/** + * parse_options - build local/remote addresses from configuration + * @attrs: netlink config data + * @ub: UDP bearer instance + * @local: local bearer IP address/port + * @remote: peer or multicast IP/port + */ +static int parse_options(struct nlattr *attrs[], struct udp_bearer *ub, + struct udp_media_addr *local, + struct udp_media_addr *remote) +{ + struct nlattr *opts[TIPC_NLA_UDP_MAX + 1]; + struct sockaddr_storage *sa_local, *sa_remote; + + if (!attrs[TIPC_NLA_BEARER_UDP_OPTS]) + goto err; + if (nla_parse_nested(opts, TIPC_NLA_UDP_MAX, + attrs[TIPC_NLA_BEARER_UDP_OPTS], + tipc_nl_udp_policy)) + goto err; + if (opts[TIPC_NLA_UDP_LOCAL] && opts[TIPC_NLA_UDP_REMOTE]) { + sa_local = nla_data(opts[TIPC_NLA_UDP_LOCAL]); + sa_remote = nla_data(opts[TIPC_NLA_UDP_REMOTE]); + } else { +err: + pr_err("Invalid UDP bearer configuration"); + return -EINVAL; + } + if ((sa_local->ss_family & sa_remote->ss_family) == AF_INET) { + struct sockaddr_in *ip4; + + ip4 = (struct sockaddr_in *)sa_local; + local->proto = htons(ETH_P_IP); + local->udp_port = ip4->sin_port; + local->ipv4.s_addr = ip4->sin_addr.s_addr; + + ip4 = (struct sockaddr_in *)sa_remote; + remote->proto = htons(ETH_P_IP); + remote->udp_port = ip4->sin_port; + remote->ipv4.s_addr = ip4->sin_addr.s_addr; + return 0; + +#if IS_ENABLED(CONFIG_IPV6) + } else if ((sa_local->ss_family & sa_remote->ss_family) == AF_INET6) { + struct sockaddr_in6 *ip6; + + ip6 = (struct sockaddr_in6 *)sa_local; + local->proto = htons(ETH_P_IPV6); + local->udp_port = ip6->sin6_port; + local->ipv6 = ip6->sin6_addr; + ub->ifindex = ip6->sin6_scope_id; + + ip6 = (struct sockaddr_in6 *)sa_remote; + remote->proto = htons(ETH_P_IPV6); + remote->udp_port = ip6->sin6_port; + remote->ipv6 = ip6->sin6_addr; + return 0; +#endif + } + return -EADDRNOTAVAIL; +} + +/** + * tipc_udp_enable - callback to create a new udp bearer instance + * @net: network namespace + * @b: pointer to generic tipc_bearer + * @attrs: netlink bearer configuration + * + * validate the bearer parameters and initialize the udp bearer + * rtnl_lock should be held + */ +static int tipc_udp_enable(struct net *net, struct tipc_bearer *b, + struct nlattr *attrs[]) +{ + int err = -EINVAL; + struct udp_bearer *ub; + struct udp_media_addr *remote; + struct udp_media_addr local = {0}; + struct udp_port_cfg udp_conf = {0}; + struct udp_tunnel_sock_cfg tuncfg = {0}; + + ub = kzalloc(sizeof(*ub), GFP_ATOMIC); + if (!ub) + return -ENOMEM; + + remote = (struct udp_media_addr *)&b->bcast_addr.value; + memset(remote, 0, sizeof(struct udp_media_addr)); + err = parse_options(attrs, ub, &local, remote); + if (err) + goto err; + + b->bcast_addr.media_id = TIPC_MEDIA_TYPE_UDP; + b->bcast_addr.broadcast = 1; + rcu_assign_pointer(b->media_ptr, ub); + rcu_assign_pointer(ub->bearer, b); + tipc_udp_media_addr_set(&b->addr, &local); + if (htons(local.proto) == ETH_P_IP) { + struct net_device *dev; + + dev = __ip_dev_find(net, local.ipv4.s_addr, false); + if (!dev) { + err = -ENODEV; + goto err; + } + udp_conf.family = AF_INET; + udp_conf.local_ip.s_addr = htonl(INADDR_ANY); + udp_conf.use_udp_checksums = false; + ub->ifindex = dev->ifindex; + b->mtu = dev->mtu - sizeof(struct iphdr) + - sizeof(struct udphdr); +#if IS_ENABLED(CONFIG_IPV6) + } else if (htons(local.proto) == ETH_P_IPV6) { + udp_conf.family = AF_INET6; + udp_conf.use_udp6_tx_checksums = true; + udp_conf.use_udp6_rx_checksums = true; + udp_conf.local_ip6 = in6addr_any; + b->mtu = 1280; +#endif + } else { + err = -EAFNOSUPPORT; + goto err; + } + udp_conf.local_udp_port = local.udp_port; + err = udp_sock_create(net, &udp_conf, &ub->ubsock); + if (err) + goto err; + tuncfg.sk_user_data = ub; + tuncfg.encap_type = 1; + tuncfg.encap_rcv = tipc_udp_recv; + tuncfg.encap_destroy = NULL; + setup_udp_tunnel_sock(net, ub->ubsock, &tuncfg); + + if (enable_mcast(ub, remote)) + goto err; + return 0; +err: + kfree(ub); + return err; +} + +/* cleanup_bearer - break the socket/bearer association */ +static void cleanup_bearer(struct work_struct *work) +{ + struct udp_bearer *ub = container_of(work, struct udp_bearer, work); + + if (ub->ubsock) + udp_tunnel_sock_release(ub->ubsock); + synchronize_net(); + kfree(ub); +} + +/* tipc_udp_disable - detach bearer from socket */ +static void tipc_udp_disable(struct tipc_bearer *b) +{ + struct udp_bearer *ub; + + ub = rcu_dereference_rtnl(b->media_ptr); + if (!ub) { + pr_err("UDP bearer instance not found\n"); + return; + } + if (ub->ubsock) + sock_set_flag(ub->ubsock->sk, SOCK_DEAD); + RCU_INIT_POINTER(b->media_ptr, NULL); + RCU_INIT_POINTER(ub->bearer, NULL); + + /* sock_release need to be done outside of rtnl lock */ + INIT_WORK(&ub->work, cleanup_bearer); + schedule_work(&ub->work); +} + +struct tipc_media udp_media_info = { + .send_msg = tipc_udp_send_msg, + .enable_media = tipc_udp_enable, + .disable_media = tipc_udp_disable, + .addr2str = tipc_udp_addr2str, + .addr2msg = tipc_udp_addr2msg, + .msg2addr = tipc_udp_msg2addr, + .priority = TIPC_DEF_LINK_PRI, + .tolerance = TIPC_DEF_LINK_TOL, + .window = TIPC_DEF_LINK_WIN, + .type_id = TIPC_MEDIA_TYPE_UDP, + .hwaddr_len = 0, + .name = "udp" +}; -- GitLab From e815665e1a8ca1525900377f74021c8cac390e8d Mon Sep 17 00:00:00 2001 From: Jeff Kirsher Date: Thu, 5 Mar 2015 19:02:35 -0800 Subject: [PATCH 02870/11651] i40e: Fix mismatching type for ioremap_len As pointed out by Ben Hutchings, ioremap uses unsigned long as its parameter type, so we should be using that instead of u32 or int. Reported-by: Ben Hutchings Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ethernet/intel/i40e/i40e_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index fb369f773780..0937cf325e00 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -9456,10 +9456,10 @@ static void i40e_print_features(struct i40e_pf *pf) static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { struct i40e_aq_get_phy_abilities_resp abilities; + unsigned long ioremap_len; struct i40e_pf *pf; struct i40e_hw *hw; static u16 pfs_found; - u32 ioremap_len; u16 link_status; int err = 0; u32 len; @@ -9509,7 +9509,7 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent) hw = &pf->hw; hw->back = pf; - ioremap_len = min_t(int, pci_resource_len(pdev, 0), + ioremap_len = min_t(unsigned long, pci_resource_len(pdev, 0), I40E_MAX_CSR_SPACE); hw->hw_addr = ioremap(pci_resource_start(pdev, 0), ioremap_len); -- GitLab From f50724cdfeea37ddbd969e1445be7c85329d7d09 Mon Sep 17 00:00:00 2001 From: Tobias Waldekranz Date: Thu, 5 Mar 2015 14:48:23 +0100 Subject: [PATCH 02871/11651] net: gianfar: correctly determine the number of queue groups eTSEC of-nodes may have children which are not queue-group nodes. For example new-style fixed-phy declarations. These where incorrectly assumed to be additional queue-groups. Change the search to filter out any nodes which are not queue-groups, or have been disabled. Signed-off-by: Tobias Waldekranz Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/gianfar.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index 178e54028d10..7bf3682cdf47 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c @@ -747,6 +747,18 @@ static int gfar_parse_group(struct device_node *np, return 0; } +static int gfar_of_group_count(struct device_node *np) +{ + struct device_node *child; + int num = 0; + + for_each_available_child_of_node(np, child) + if (!of_node_cmp(child->name, "queue-group")) + num++; + + return num; +} + static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev) { const char *model; @@ -784,7 +796,7 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev) num_rx_qs = 1; } else { /* MQ_MG_MODE */ /* get the actual number of supported groups */ - unsigned int num_grps = of_get_available_child_count(np); + unsigned int num_grps = gfar_of_group_count(np); if (num_grps == 0 || num_grps > MAXGROUPS) { dev_err(&ofdev->dev, "Invalid # of int groups(%d)\n", @@ -851,7 +863,10 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev) /* Parse and initialize group specific information */ if (priv->mode == MQ_MG_MODE) { - for_each_child_of_node(np, child) { + for_each_available_child_of_node(np, child) { + if (of_node_cmp(child->name, "queue-group")) + continue; + err = gfar_parse_group(child, priv, model); if (err) goto err_grp_init; -- GitLab From d941bebf5e89478f480038ea30d194537eb64311 Mon Sep 17 00:00:00 2001 From: Punnaiah Choudary Kalluri Date: Thu, 5 Mar 2015 15:02:10 +0100 Subject: [PATCH 02872/11651] net: macb: Correct the MID field length value The latest spec "I-IPA01-0266-USR Rev 10" limit the MID field length to 12 bit value. For previous versions it is 16 bit value. This change will not break the backward compatibility as the latest ID value is 7 and with in the 12 bit value limit. Signed-off-by: Punnaiah Choudary Kalluri Signed-off-by: Michal Simek Signed-off-by: David S. Miller --- drivers/net/ethernet/cadence/macb.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h index 31dc080f2437..ff85619a9732 100644 --- a/drivers/net/ethernet/cadence/macb.h +++ b/drivers/net/ethernet/cadence/macb.h @@ -351,7 +351,7 @@ /* Bitfields in MID */ #define MACB_IDNUM_OFFSET 16 -#define MACB_IDNUM_SIZE 16 +#define MACB_IDNUM_SIZE 12 #define MACB_REV_OFFSET 0 #define MACB_REV_SIZE 16 -- GitLab From e9647d1e74a9778539ad3232e58833210c1935f5 Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Thu, 5 Mar 2015 15:09:29 +0100 Subject: [PATCH 02873/11651] net: fec: fix unbalanced clk disable on driver unbind When the driver is removed (e.g. using unbind through sysfs), the clocks get disabled twice, once on fec_enet_close and once on fec_drv_remove. Since the clocks are enabled only once, this leads to a warning: WARNING: CPU: 0 PID: 402 at drivers/clk/clk.c:992 clk_core_disable+0x64/0x68() Remove the call to fec_enet_clk_enable in fec_drv_remove to balance the clock enable/disable calls again. This has been introduce by e8fcfcd5684a ("net: fec: optimize the clock management to save power"). Signed-off-by: Stefan Agner Acked-by: Fugang Duan Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/fec_main.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index 5ff8fee3850f..99492b7e3713 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -3383,7 +3383,6 @@ fec_drv_remove(struct platform_device *pdev) regulator_disable(fep->reg_phy); if (fep->ptp_clock) ptp_clock_unregister(fep->ptp_clock); - fec_enet_clk_enable(ndev, false); of_node_put(fep->phy_node); free_netdev(ndev); -- GitLab From 6c09fa09d468d730eecd7122122175da772d3b09 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 5 Mar 2015 08:03:06 -0800 Subject: [PATCH 02874/11651] tcp: align tcp_xmit_size_goal() on tcp_tso_autosize() With some mss values, it is possible tcp_xmit_size_goal() puts one segment more in TSO packet than tcp_tso_autosize(). We send then one TSO packet followed by one single MSS. It is not a serious bug, but we can do slightly better, especially for drivers using netif_set_gso_max_size() to lower gso_max_size. Using same formula avoids these corner cases and makes tcp_xmit_size_goal() a bit faster. Signed-off-by: Eric Dumazet Fixes: 605ad7f184b6 ("tcp: refine TSO autosizing") Acked-by: Neal Cardwell Signed-off-by: David S. Miller --- net/ipv4/tcp.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 9d72a0fcd928..995a2259bcfc 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -835,17 +835,13 @@ static unsigned int tcp_xmit_size_goal(struct sock *sk, u32 mss_now, int large_allowed) { struct tcp_sock *tp = tcp_sk(sk); - u32 new_size_goal, size_goal, hlen; + u32 new_size_goal, size_goal; if (!large_allowed || !sk_can_gso(sk)) return mss_now; - /* Maybe we should/could use sk->sk_prot->max_header here ? */ - hlen = inet_csk(sk)->icsk_af_ops->net_header_len + - inet_csk(sk)->icsk_ext_hdr_len + - tp->tcp_header_len; - - new_size_goal = sk->sk_gso_max_size - 1 - hlen; + /* Note : tcp_tso_autosize() will eventually split this later */ + new_size_goal = sk->sk_gso_max_size - 1 - MAX_TCP_HEADER; new_size_goal = tcp_bound_to_half_wnd(tp, new_size_goal); /* We try hard to avoid divides here */ -- GitLab From 496127290f298d839918a14728b653b43ef02708 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 5 Mar 2015 10:18:14 -0800 Subject: [PATCH 02875/11651] inet_diag: remove duplicate code from inet_twsk_diag_dump() timewait sockets now share a common base with established sockets. inet_twsk_diag_dump() can use inet_diag_bc_sk() instead of duplicating code, granted that inet_diag_bc_sk() does proper userlocks initialization. twsk_build_assert() will catch any future changes that could break the assumptions. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/inet_diag.c | 55 +++++++++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 24 deletions(-) diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index 81751f12645f..0c974d3499ed 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c @@ -508,7 +508,7 @@ int inet_diag_bc_sk(const struct nlattr *bc, struct sock *sk) } entry.sport = inet->inet_num; entry.dport = ntohs(inet->inet_dport); - entry.userlocks = sk->sk_userlocks; + entry.userlocks = (sk->sk_state != TCP_TIME_WAIT) ? sk->sk_userlocks : 0; return inet_diag_bc_run(bc, &entry); } @@ -642,37 +642,44 @@ static int inet_csk_diag_dump(struct sock *sk, cb->nlh->nlmsg_seq, NLM_F_MULTI, cb->nlh); } +static void twsk_build_assert(void) +{ + BUILD_BUG_ON(offsetof(struct inet_timewait_sock, tw_family) != + offsetof(struct sock, sk_family)); + + BUILD_BUG_ON(offsetof(struct inet_timewait_sock, tw_num) != + offsetof(struct inet_sock, inet_num)); + + BUILD_BUG_ON(offsetof(struct inet_timewait_sock, tw_dport) != + offsetof(struct inet_sock, inet_dport)); + + BUILD_BUG_ON(offsetof(struct inet_timewait_sock, tw_rcv_saddr) != + offsetof(struct inet_sock, inet_rcv_saddr)); + + BUILD_BUG_ON(offsetof(struct inet_timewait_sock, tw_daddr) != + offsetof(struct inet_sock, inet_daddr)); + +#if IS_ENABLED(CONFIG_IPV6) + BUILD_BUG_ON(offsetof(struct inet_timewait_sock, tw_v6_rcv_saddr) != + offsetof(struct sock, sk_v6_rcv_saddr)); + + BUILD_BUG_ON(offsetof(struct inet_timewait_sock, tw_v6_daddr) != + offsetof(struct sock, sk_v6_daddr)); +#endif +} + static int inet_twsk_diag_dump(struct sock *sk, struct sk_buff *skb, struct netlink_callback *cb, struct inet_diag_req_v2 *r, const struct nlattr *bc) { - struct inet_timewait_sock *tw = inet_twsk(sk); + twsk_build_assert(); - if (bc != NULL) { - struct inet_diag_entry entry; - - entry.family = tw->tw_family; -#if IS_ENABLED(CONFIG_IPV6) - if (tw->tw_family == AF_INET6) { - entry.saddr = tw->tw_v6_rcv_saddr.s6_addr32; - entry.daddr = tw->tw_v6_daddr.s6_addr32; - } else -#endif - { - entry.saddr = &tw->tw_rcv_saddr; - entry.daddr = &tw->tw_daddr; - } - entry.sport = tw->tw_num; - entry.dport = ntohs(tw->tw_dport); - entry.userlocks = 0; - - if (!inet_diag_bc_run(bc, &entry)) - return 0; - } + if (!inet_diag_bc_sk(bc, sk)) + return 0; - return inet_twsk_diag_fill(tw, skb, r, + return inet_twsk_diag_fill(inet_twsk(sk), skb, r, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, NLM_F_MULTI, cb->nlh); } -- GitLab From 085a68d0010ffa57603b93c2b09fdf98bf74218c Mon Sep 17 00:00:00 2001 From: Feng Kan Date: Tue, 17 Feb 2015 15:14:00 -0800 Subject: [PATCH 02876/11651] PCI: xgene: Add register offset to config space base address In xgene_pcie_map_bus(), we neglected to add in the register offset when calculating the config space address. This means all config accesses operated on the first four bytes of config space. Add the register offset to the config space base address. Also correct the xgene_pcie_map_bus() prototype to fix a compiler warning. [bhelgaas: changelog] Fixes: 350f8be5bb40 ("PCI: xgene: Convert to use generic config accessors") Posting: http://lkml.kernel.org/r/1424214840-26498-1-git-send-email-fkan@apm.com Signed-off-by: Feng Kan Signed-off-by: Bjorn Helgaas Acked-by: Tanmay Inamdar Acked-by: Rob Herring --- drivers/pci/host/pci-xgene.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pci/host/pci-xgene.c b/drivers/pci/host/pci-xgene.c index aab55474dd0d..ee082c0366ec 100644 --- a/drivers/pci/host/pci-xgene.c +++ b/drivers/pci/host/pci-xgene.c @@ -127,7 +127,7 @@ static bool xgene_pcie_hide_rc_bars(struct pci_bus *bus, int offset) return false; } -static int xgene_pcie_map_bus(struct pci_bus *bus, unsigned int devfn, +static void __iomem *xgene_pcie_map_bus(struct pci_bus *bus, unsigned int devfn, int offset) { struct xgene_pcie_port *port = bus->sysdata; @@ -137,7 +137,7 @@ static int xgene_pcie_map_bus(struct pci_bus *bus, unsigned int devfn, return NULL; xgene_pcie_set_rtdid_reg(bus, devfn); - return xgene_pcie_get_cfg_base(bus); + return xgene_pcie_get_cfg_base(bus) + offset; } static struct pci_ops xgene_pcie_ops = { -- GitLab From f027e601f8f7903ac6f33741f9e513aaf8391bc8 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Fri, 6 Mar 2015 01:57:31 -0300 Subject: [PATCH 02877/11651] ARM: mx25: Remove mach-mx25_3ds board file imx25-pdk.dts provides a more complete support than the board file version, so let's get rid of the board file. Signed-off-by: Fabio Estevam Signed-off-by: Shawn Guo --- arch/arm/mach-imx/Kconfig | 15 -- arch/arm/mach-imx/Makefile | 1 - arch/arm/mach-imx/mach-mx25_3ds.c | 270 ------------------------------ 3 files changed, 286 deletions(-) delete mode 100644 arch/arm/mach-imx/mach-mx25_3ds.c diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index f9d17f3daf3b..247a465eb203 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -151,21 +151,6 @@ config MACH_MX21ADS comment "MX25 platforms:" -config MACH_MX25_3DS - bool "Support MX25PDK (3DS) Platform" - select IMX_HAVE_PLATFORM_FLEXCAN - select IMX_HAVE_PLATFORM_FSL_USB2_UDC - select IMX_HAVE_PLATFORM_IMX2_WDT - select IMX_HAVE_PLATFORM_IMXDI_RTC - select IMX_HAVE_PLATFORM_IMX_FB - select IMX_HAVE_PLATFORM_IMX_I2C - select IMX_HAVE_PLATFORM_IMX_KEYPAD - select IMX_HAVE_PLATFORM_IMX_UART - select IMX_HAVE_PLATFORM_MXC_EHCI - select IMX_HAVE_PLATFORM_MXC_NAND - select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX - select SOC_IMX25 - config MACH_EUKREA_CPUIMX25SD bool "Support Eukrea CPUIMX25 Platform" select IMX_HAVE_PLATFORM_FLEXCAN diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index 8d1b10180908..e92ede9b1ad1 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -49,7 +49,6 @@ obj-$(CONFIG_MACH_IMX1_DT) += imx1-dt.o obj-$(CONFIG_MACH_MX21ADS) += mach-mx21ads.o # i.MX25 based machines -obj-$(CONFIG_MACH_MX25_3DS) += mach-mx25_3ds.o obj-$(CONFIG_MACH_EUKREA_CPUIMX25SD) += mach-eukrea_cpuimx25.o obj-$(CONFIG_MACH_EUKREA_MBIMXSD25_BASEBOARD) += eukrea_mbimxsd25-baseboard.o obj-$(CONFIG_MACH_IMX25_DT) += imx25-dt.o diff --git a/arch/arm/mach-imx/mach-mx25_3ds.c b/arch/arm/mach-imx/mach-mx25_3ds.c deleted file mode 100644 index 584248a5e1e9..000000000000 --- a/arch/arm/mach-imx/mach-mx25_3ds.c +++ /dev/null @@ -1,270 +0,0 @@ -/* - * Copyright 2009 Sascha Hauer, - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * 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 Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/* - * This machine is known as: - * - i.MX25 3-Stack Development System - * - i.MX25 Platform Development Kit (i.MX25 PDK) - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "common.h" -#include "devices-imx25.h" -#include "ehci.h" -#include "hardware.h" -#include "iomux-mx25.h" -#include "mx25.h" - -#define MX25PDK_CAN_PWDN IMX_GPIO_NR(4, 6) - -static const struct imxuart_platform_data uart_pdata __initconst = { - .flags = IMXUART_HAVE_RTSCTS, -}; - -static const iomux_v3_cfg_t mx25pdk_pads[] __initconst = { - MX25_PAD_FEC_MDC__FEC_MDC, - MX25_PAD_FEC_MDIO__FEC_MDIO, - MX25_PAD_FEC_TDATA0__FEC_TDATA0, - MX25_PAD_FEC_TDATA1__FEC_TDATA1, - MX25_PAD_FEC_TX_EN__FEC_TX_EN, - MX25_PAD_FEC_RDATA0__FEC_RDATA0, - MX25_PAD_FEC_RDATA1__FEC_RDATA1, - MX25_PAD_FEC_RX_DV__FEC_RX_DV, - MX25_PAD_FEC_TX_CLK__FEC_TX_CLK, - MX25_PAD_A17__GPIO_2_3, /* FEC_EN, GPIO 35 */ - MX25_PAD_D12__GPIO_4_8, /* FEC_RESET_B, GPIO 104 */ - - /* LCD */ - MX25_PAD_LD0__LD0, - MX25_PAD_LD1__LD1, - MX25_PAD_LD2__LD2, - MX25_PAD_LD3__LD3, - MX25_PAD_LD4__LD4, - MX25_PAD_LD5__LD5, - MX25_PAD_LD6__LD6, - MX25_PAD_LD7__LD7, - MX25_PAD_LD8__LD8, - MX25_PAD_LD9__LD9, - MX25_PAD_LD10__LD10, - MX25_PAD_LD11__LD11, - MX25_PAD_LD12__LD12, - MX25_PAD_LD13__LD13, - MX25_PAD_LD14__LD14, - MX25_PAD_LD15__LD15, - MX25_PAD_GPIO_E__LD16, - MX25_PAD_GPIO_F__LD17, - MX25_PAD_HSYNC__HSYNC, - MX25_PAD_VSYNC__VSYNC, - MX25_PAD_LSCLK__LSCLK, - MX25_PAD_OE_ACD__OE_ACD, - MX25_PAD_CONTRAST__CONTRAST, - - /* Keypad */ - MX25_PAD_KPP_ROW0__KPP_ROW0, - MX25_PAD_KPP_ROW1__KPP_ROW1, - MX25_PAD_KPP_ROW2__KPP_ROW2, - MX25_PAD_KPP_ROW3__KPP_ROW3, - MX25_PAD_KPP_COL0__KPP_COL0, - MX25_PAD_KPP_COL1__KPP_COL1, - MX25_PAD_KPP_COL2__KPP_COL2, - MX25_PAD_KPP_COL3__KPP_COL3, - - /* SD1 */ - MX25_PAD_SD1_CMD__SD1_CMD, - MX25_PAD_SD1_CLK__SD1_CLK, - MX25_PAD_SD1_DATA0__SD1_DATA0, - MX25_PAD_SD1_DATA1__SD1_DATA1, - MX25_PAD_SD1_DATA2__SD1_DATA2, - MX25_PAD_SD1_DATA3__SD1_DATA3, - MX25_PAD_A14__GPIO_2_0, /* WriteProtect */ - MX25_PAD_A15__GPIO_2_1, /* CardDetect */ - - /* I2C1 */ - MX25_PAD_I2C1_CLK__I2C1_CLK, - MX25_PAD_I2C1_DAT__I2C1_DAT, - - /* CAN1 */ - MX25_PAD_GPIO_A__CAN1_TX, - MX25_PAD_GPIO_B__CAN1_RX, - MX25_PAD_D14__GPIO_4_6, /* CAN_PWDN */ -}; - -static const struct fec_platform_data mx25_fec_pdata __initconst = { - .phy = PHY_INTERFACE_MODE_RMII, -}; - -#define FEC_ENABLE_GPIO IMX_GPIO_NR(2, 3) -#define FEC_RESET_B_GPIO IMX_GPIO_NR(4, 8) - -static void __init mx25pdk_fec_reset(void) -{ - gpio_request(FEC_ENABLE_GPIO, "FEC PHY enable"); - gpio_request(FEC_RESET_B_GPIO, "FEC PHY reset"); - - gpio_direction_output(FEC_ENABLE_GPIO, 0); /* drop PHY power */ - gpio_direction_output(FEC_RESET_B_GPIO, 0); /* assert reset */ - udelay(2); - - /* turn on PHY power and lift reset */ - gpio_set_value(FEC_ENABLE_GPIO, 1); - gpio_set_value(FEC_RESET_B_GPIO, 1); -} - -static const struct mxc_nand_platform_data -mx25pdk_nand_board_info __initconst = { - .width = 1, - .hw_ecc = 1, - .flash_bbt = 1, -}; - -static struct imx_fb_videomode mx25pdk_modes[] = { - { - .mode = { - .name = "CRT-VGA", - .refresh = 60, - .xres = 640, - .yres = 480, - .pixclock = 39683, - .left_margin = 45, - .right_margin = 114, - .upper_margin = 33, - .lower_margin = 11, - .hsync_len = 1, - .vsync_len = 1, - }, - .bpp = 16, - .pcr = 0xFA208B80, - }, -}; - -static const struct imx_fb_platform_data mx25pdk_fb_pdata __initconst = { - .mode = mx25pdk_modes, - .num_modes = ARRAY_SIZE(mx25pdk_modes), - .pwmr = 0x00A903FF, - .lscr1 = 0x00120300, - .dmacr = 0x00020010, -}; - -static const uint32_t mx25pdk_keymap[] = { - KEY(0, 0, KEY_UP), - KEY(0, 1, KEY_DOWN), - KEY(0, 2, KEY_VOLUMEDOWN), - KEY(0, 3, KEY_HOME), - KEY(1, 0, KEY_RIGHT), - KEY(1, 1, KEY_LEFT), - KEY(1, 2, KEY_ENTER), - KEY(1, 3, KEY_VOLUMEUP), - KEY(2, 0, KEY_F6), - KEY(2, 1, KEY_F8), - KEY(2, 2, KEY_F9), - KEY(2, 3, KEY_F10), - KEY(3, 0, KEY_F1), - KEY(3, 1, KEY_F2), - KEY(3, 2, KEY_F3), - KEY(3, 3, KEY_POWER), -}; - -static const struct matrix_keymap_data mx25pdk_keymap_data __initconst = { - .keymap = mx25pdk_keymap, - .keymap_size = ARRAY_SIZE(mx25pdk_keymap), -}; - -static int mx25pdk_usbh2_init(struct platform_device *pdev) -{ - return mx25_initialize_usb_hw(pdev->id, MXC_EHCI_INTERNAL_PHY); -} - -static const struct mxc_usbh_platform_data usbh2_pdata __initconst = { - .init = mx25pdk_usbh2_init, - .portsc = MXC_EHCI_MODE_SERIAL, -}; - -static const struct fsl_usb2_platform_data otg_device_pdata __initconst = { - .operating_mode = FSL_USB2_DR_DEVICE, - .phy_mode = FSL_USB2_PHY_UTMI, -}; - -static const struct imxi2c_platform_data mx25_3ds_i2c0_data __initconst = { - .bitrate = 100000, -}; - -#define SD1_GPIO_WP IMX_GPIO_NR(2, 0) -#define SD1_GPIO_CD IMX_GPIO_NR(2, 1) - -static const struct esdhc_platform_data mx25pdk_esdhc_pdata __initconst = { - .wp_gpio = SD1_GPIO_WP, - .cd_gpio = SD1_GPIO_CD, - .wp_type = ESDHC_WP_GPIO, - .cd_type = ESDHC_CD_GPIO, -}; - -static void __init mx25pdk_init(void) -{ - imx25_soc_init(); - - mxc_iomux_v3_setup_multiple_pads(mx25pdk_pads, - ARRAY_SIZE(mx25pdk_pads)); - - imx25_add_imx_uart0(&uart_pdata); - imx25_add_fsl_usb2_udc(&otg_device_pdata); - imx25_add_mxc_ehci_hs(&usbh2_pdata); - imx25_add_mxc_nand(&mx25pdk_nand_board_info); - imx25_add_imxdi_rtc(); - imx25_add_imx_fb(&mx25pdk_fb_pdata); - imx25_add_imx2_wdt(); - - mx25pdk_fec_reset(); - imx25_add_fec(&mx25_fec_pdata); - imx25_add_imx_keypad(&mx25pdk_keymap_data); - - imx25_add_sdhci_esdhc_imx(0, &mx25pdk_esdhc_pdata); - imx25_add_imx_i2c0(&mx25_3ds_i2c0_data); - - gpio_request_one(MX25PDK_CAN_PWDN, GPIOF_OUT_INIT_LOW, "can-pwdn"); - imx25_add_flexcan0(); -} - -static void __init mx25pdk_timer_init(void) -{ - mx25_clocks_init(); -} - -MACHINE_START(MX25_3DS, "Freescale MX25PDK (3DS)") - /* Maintainer: Freescale Semiconductor, Inc. */ - .atag_offset = 0x100, - .map_io = mx25_map_io, - .init_early = imx25_init_early, - .init_irq = mx25_init_irq, - .init_time = mx25pdk_timer_init, - .init_machine = mx25pdk_init, - .restart = mxc_restart, -MACHINE_END -- GitLab From f1a26a062f03b27fa52f62487897fe205303fa7f Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Thu, 5 Mar 2015 12:35:04 -0800 Subject: [PATCH 02878/11651] net: dsa: update dsa_of_{probe, remove} to use a device pointer In preparation for allowing a different mechanism to register DSA switch devices and driver, update dsa_of_probe and dsa_of_remove to take a struct device pointer since neither of these two functions uses the struct platform_device pointer. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- net/dsa/dsa.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c index a1d1f0775bea..d804364150bd 100644 --- a/net/dsa/dsa.c +++ b/net/dsa/dsa.c @@ -563,9 +563,9 @@ static void dsa_of_free_platform_data(struct dsa_platform_data *pd) kfree(pd->chip); } -static int dsa_of_probe(struct platform_device *pdev) +static int dsa_of_probe(struct device *dev) { - struct device_node *np = pdev->dev.of_node; + struct device_node *np = dev->of_node; struct device_node *child, *mdio, *ethernet, *port, *link; struct mii_bus *mdio_bus; struct platform_device *ethernet_dev; @@ -597,7 +597,7 @@ static int dsa_of_probe(struct platform_device *pdev) if (!pd) return -ENOMEM; - pdev->dev.platform_data = pd; + dev->platform_data = pd; pd->netdev = ðernet_dev->dev; pd->nr_chips = of_get_available_child_count(np); if (pd->nr_chips > DSA_MAX_SWITCHES) @@ -670,27 +670,27 @@ out_free_chip: dsa_of_free_platform_data(pd); out_free: kfree(pd); - pdev->dev.platform_data = NULL; + dev->platform_data = NULL; return ret; } -static void dsa_of_remove(struct platform_device *pdev) +static void dsa_of_remove(struct device *dev) { - struct dsa_platform_data *pd = pdev->dev.platform_data; + struct dsa_platform_data *pd = dev->platform_data; - if (!pdev->dev.of_node) + if (!dev->of_node) return; dsa_of_free_platform_data(pd); kfree(pd); } #else -static inline int dsa_of_probe(struct platform_device *pdev) +static inline int dsa_of_probe(struct device *dev) { return 0; } -static inline void dsa_of_remove(struct platform_device *pdev) +static inline void dsa_of_remove(struct device *dev) { } #endif @@ -706,7 +706,7 @@ static int dsa_probe(struct platform_device *pdev) dsa_driver_version); if (pdev->dev.of_node) { - ret = dsa_of_probe(pdev); + ret = dsa_of_probe(&pdev->dev); if (ret) return ret; @@ -777,7 +777,7 @@ static int dsa_probe(struct platform_device *pdev) return 0; out: - dsa_of_remove(pdev); + dsa_of_remove(&pdev->dev); return ret; } @@ -799,7 +799,7 @@ static int dsa_remove(struct platform_device *pdev) dsa_switch_destroy(ds); } - dsa_of_remove(pdev); + dsa_of_remove(&pdev->dev); return 0; } -- GitLab From b324c07ac4771a6ac8f57a3e1897e1b36b0a9ff0 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Thu, 5 Mar 2015 12:35:05 -0800 Subject: [PATCH 02879/11651] net: dsa: allow deferred probing In preparation for allowing a different model to register DSA switches, update dsa_of_probe() and dsa_probe() to return -EPROBE_DEFER where appropriate. Failure to find a phandle or Device Tree property is still fatal, but looking up the internal device structure associated with a Device Tree node is something that might need to be delayed based on driver probe ordering. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- net/dsa/dsa.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c index d804364150bd..79879d01488a 100644 --- a/net/dsa/dsa.c +++ b/net/dsa/dsa.c @@ -583,7 +583,7 @@ static int dsa_of_probe(struct device *dev) mdio_bus = of_mdio_find_bus(mdio); if (!mdio_bus) - return -EINVAL; + return -EPROBE_DEFER; ethernet = of_parse_phandle(np, "dsa,ethernet", 0); if (!ethernet) @@ -591,7 +591,7 @@ static int dsa_of_probe(struct device *dev) ethernet_dev = of_find_device_by_node(ethernet); if (!ethernet_dev) - return -ENODEV; + return -EPROBE_DEFER; pd = kzalloc(sizeof(*pd), GFP_KERNEL); if (!pd) @@ -718,7 +718,7 @@ static int dsa_probe(struct platform_device *pdev) dev = dev_to_net_device(pd->netdev); if (dev == NULL) { - ret = -EINVAL; + ret = -EPROBE_DEFER; goto out; } -- GitLab From df197195a5248164df0709fbadc61133897281f5 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Thu, 5 Mar 2015 12:35:06 -0800 Subject: [PATCH 02880/11651] net: dsa: split dsa_switch_setup into two functions Split the part of dsa_switch_setup() which is responsible for allocating and initializing a 'struct dsa_switch' and the part which is doing a given switch device setup and slave network device creation. This is a preliminary change to allow a separate caller of dsa_switch_setup_one() which may have externally initialized the dsa_switch structure, outside of dsa_switch_setup(). Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- net/dsa/dsa.c | 88 +++++++++++++++++++++++++++++---------------------- 1 file changed, 51 insertions(+), 37 deletions(-) diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c index 79879d01488a..6f02ccc57593 100644 --- a/net/dsa/dsa.c +++ b/net/dsa/dsa.c @@ -175,43 +175,14 @@ __ATTRIBUTE_GROUPS(dsa_hwmon); #endif /* CONFIG_NET_DSA_HWMON */ /* basic switch operations **************************************************/ -static struct dsa_switch * -dsa_switch_setup(struct dsa_switch_tree *dst, int index, - struct device *parent, struct device *host_dev) +static int dsa_switch_setup_one(struct dsa_switch *ds, struct device *parent) { - struct dsa_chip_data *pd = dst->pd->chip + index; - struct dsa_switch_driver *drv; - struct dsa_switch *ds; - int ret; - char *name; - int i; + struct dsa_switch_driver *drv = ds->drv; + struct dsa_switch_tree *dst = ds->dst; + struct dsa_chip_data *pd = ds->pd; bool valid_name_found = false; - - /* - * Probe for switch model. - */ - drv = dsa_switch_probe(host_dev, pd->sw_addr, &name); - if (drv == NULL) { - netdev_err(dst->master_netdev, "[%d]: could not detect attached switch\n", - index); - return ERR_PTR(-EINVAL); - } - netdev_info(dst->master_netdev, "[%d]: detected a %s switch\n", - index, name); - - - /* - * Allocate and initialise switch state. - */ - ds = kzalloc(sizeof(*ds) + drv->priv_size, GFP_KERNEL); - if (ds == NULL) - return ERR_PTR(-ENOMEM); - - ds->dst = dst; - ds->index = index; - ds->pd = dst->pd->chip + index; - ds->drv = drv; - ds->master_dev = host_dev; + int index = ds->index; + int i, ret; /* * Validate supplied switch configuration. @@ -350,13 +321,56 @@ dsa_switch_setup(struct dsa_switch_tree *dst, int index, } #endif /* CONFIG_NET_DSA_HWMON */ - return ds; + return ret; out_free: mdiobus_free(ds->slave_mii_bus); out: kfree(ds); - return ERR_PTR(ret); + return ret; +} + +static struct dsa_switch * +dsa_switch_setup(struct dsa_switch_tree *dst, int index, + struct device *parent, struct device *host_dev) +{ + struct dsa_chip_data *pd = dst->pd->chip + index; + struct dsa_switch_driver *drv; + struct dsa_switch *ds; + int ret; + char *name; + + /* + * Probe for switch model. + */ + drv = dsa_switch_probe(host_dev, pd->sw_addr, &name); + if (drv == NULL) { + netdev_err(dst->master_netdev, "[%d]: could not detect attached switch\n", + index); + return ERR_PTR(-EINVAL); + } + netdev_info(dst->master_netdev, "[%d]: detected a %s switch\n", + index, name); + + + /* + * Allocate and initialise switch state. + */ + ds = kzalloc(sizeof(*ds) + drv->priv_size, GFP_KERNEL); + if (ds == NULL) + return NULL; + + ds->dst = dst; + ds->index = index; + ds->pd = pd; + ds->drv = drv; + ds->master_dev = host_dev; + + ret = dsa_switch_setup_one(ds, parent); + if (ret) + return NULL; + + return ds; } static void dsa_switch_destroy(struct dsa_switch *ds) -- GitLab From 59299031038f3ea92cf484bc4a68d16ad4bb3050 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Thu, 5 Mar 2015 12:35:07 -0800 Subject: [PATCH 02881/11651] net: dsa: let switches specify their tagging protocol In order to support the new DSA device driver model, a dsa_switch should be able to advertise the type of tagging protocol supported by the underlying switch device. This also removes constraints on how tagging can be stacked to each other. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- include/net/dsa.h | 5 +++++ net/dsa/dsa.c | 5 +++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/include/net/dsa.h b/include/net/dsa.h index c542c131d551..b525ac516559 100644 --- a/include/net/dsa.h +++ b/include/net/dsa.h @@ -127,6 +127,11 @@ struct dsa_switch { struct dsa_switch_tree *dst; int index; + /* + * Tagging protocol understood by this switch + */ + enum dsa_tag_protocol tag_protocol; + /* * Configuration data for this switch. */ diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c index 6f02ccc57593..4cc995664fdf 100644 --- a/net/dsa/dsa.c +++ b/net/dsa/dsa.c @@ -227,7 +227,7 @@ static int dsa_switch_setup_one(struct dsa_switch *ds, struct device *parent) * switch. */ if (dst->cpu_switch == index) { - switch (drv->tag_protocol) { + switch (ds->tag_protocol) { #ifdef CONFIG_NET_DSA_TAG_DSA case DSA_TAG_PROTO_DSA: dst->rcv = dsa_netdev_ops.rcv; @@ -255,7 +255,7 @@ static int dsa_switch_setup_one(struct dsa_switch *ds, struct device *parent) goto out; } - dst->tag_protocol = drv->tag_protocol; + dst->tag_protocol = ds->tag_protocol; } /* @@ -364,6 +364,7 @@ dsa_switch_setup(struct dsa_switch_tree *dst, int index, ds->index = index; ds->pd = pd; ds->drv = drv; + ds->tag_protocol = drv->tag_protocol; ds->master_dev = host_dev; ret = dsa_switch_setup_one(ds, parent); -- GitLab From c86e59b9e63659bb7fc2ba1781aabe2f37aaf10b Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Thu, 5 Mar 2015 12:35:08 -0800 Subject: [PATCH 02882/11651] net: dsa: extract dsa switch tree setup and removal Extract the core logic that setups a 'struct dsa_switch_tree' and removes it, update dsa_probe() and dsa_remove() to use the two helper functions. This will be useful to allow for other callers to setup this structure differently. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- net/dsa/dsa.c | 91 +++++++++++++++++++++++++++++---------------------- 1 file changed, 52 insertions(+), 39 deletions(-) diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c index 4cc995664fdf..b40f11bb419c 100644 --- a/net/dsa/dsa.c +++ b/net/dsa/dsa.c @@ -710,12 +710,55 @@ static inline void dsa_of_remove(struct device *dev) } #endif +static void dsa_setup_dst(struct dsa_switch_tree *dst, struct net_device *dev, + struct device *parent, struct dsa_platform_data *pd) +{ + int i; + + dst->pd = pd; + dst->master_netdev = dev; + dst->cpu_switch = -1; + dst->cpu_port = -1; + + for (i = 0; i < pd->nr_chips; i++) { + struct dsa_switch *ds; + + ds = dsa_switch_setup(dst, i, parent, pd->chip[i].host_dev); + if (IS_ERR(ds)) { + netdev_err(dev, "[%d]: couldn't create dsa switch instance (error %ld)\n", + i, PTR_ERR(ds)); + continue; + } + + dst->ds[i] = ds; + if (ds->drv->poll_link != NULL) + dst->link_poll_needed = 1; + } + + /* + * If we use a tagging format that doesn't have an ethertype + * field, make sure that all packets from this point on get + * sent to the tag format's receive function. + */ + wmb(); + dev->dsa_ptr = (void *)dst; + + if (dst->link_poll_needed) { + INIT_WORK(&dst->link_poll_work, dsa_link_poll_work); + init_timer(&dst->link_poll_timer); + dst->link_poll_timer.data = (unsigned long)dst; + dst->link_poll_timer.function = dsa_link_poll_timer; + dst->link_poll_timer.expires = round_jiffies(jiffies + HZ); + add_timer(&dst->link_poll_timer); + } +} + static int dsa_probe(struct platform_device *pdev) { struct dsa_platform_data *pd = pdev->dev.platform_data; struct net_device *dev; struct dsa_switch_tree *dst; - int i, ret; + int ret; pr_notice_once("Distributed Switch Architecture driver version %s\n", dsa_driver_version); @@ -752,42 +795,7 @@ static int dsa_probe(struct platform_device *pdev) platform_set_drvdata(pdev, dst); - dst->pd = pd; - dst->master_netdev = dev; - dst->cpu_switch = -1; - dst->cpu_port = -1; - - for (i = 0; i < pd->nr_chips; i++) { - struct dsa_switch *ds; - - ds = dsa_switch_setup(dst, i, &pdev->dev, pd->chip[i].host_dev); - if (IS_ERR(ds)) { - netdev_err(dev, "[%d]: couldn't create dsa switch instance (error %ld)\n", - i, PTR_ERR(ds)); - continue; - } - - dst->ds[i] = ds; - if (ds->drv->poll_link != NULL) - dst->link_poll_needed = 1; - } - - /* - * If we use a tagging format that doesn't have an ethertype - * field, make sure that all packets from this point on get - * sent to the tag format's receive function. - */ - wmb(); - dev->dsa_ptr = (void *)dst; - - if (dst->link_poll_needed) { - INIT_WORK(&dst->link_poll_work, dsa_link_poll_work); - init_timer(&dst->link_poll_timer); - dst->link_poll_timer.data = (unsigned long)dst; - dst->link_poll_timer.function = dsa_link_poll_timer; - dst->link_poll_timer.expires = round_jiffies(jiffies + HZ); - add_timer(&dst->link_poll_timer); - } + dsa_setup_dst(dst, dev, &pdev->dev, pd); return 0; @@ -797,9 +805,8 @@ out: return ret; } -static int dsa_remove(struct platform_device *pdev) +static void dsa_remove_dst(struct dsa_switch_tree *dst) { - struct dsa_switch_tree *dst = platform_get_drvdata(pdev); int i; if (dst->link_poll_needed) @@ -813,7 +820,13 @@ static int dsa_remove(struct platform_device *pdev) if (ds != NULL) dsa_switch_destroy(ds); } +} + +static int dsa_remove(struct platform_device *pdev) +{ + struct dsa_switch_tree *dst = platform_get_drvdata(pdev); + dsa_remove_dst(dst); dsa_of_remove(&pdev->dev); return 0; -- GitLab From 24d2e4a50737867aba1e96a587ef0d90c17e3035 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 5 Mar 2015 10:41:34 -0800 Subject: [PATCH 02883/11651] tg3: use napi_complete_done() Using napi_complete_done() instead of napi_complete() allows us to use /sys/class/net/ethX/gro_flush_timeout GRO layer can aggregate more packets if the flush is delayed a bit, without having to set too big coalescing parameters that impact latencies. Tested: lpx:~# echo 0 >/sys/class/net/eth1/gro_flush_timeout lpx:~# sar -n DEV 1 10 | grep eth1 10:36:25 AM eth1 81290.00 40617.00 120479.67 2777.01 0.00 0.00 0.00 10:36:26 AM eth1 81283.00 40608.00 120481.81 2778.13 0.00 0.00 1.00 10:36:27 AM eth1 81304.00 40639.00 120518.42 2778.28 0.00 0.00 0.00 10:36:28 AM eth1 81255.00 40605.00 120437.34 2775.95 0.00 0.00 1.00 10:36:29 AM eth1 81306.00 40630.00 120521.44 2777.70 0.00 0.00 0.00 10:36:30 AM eth1 81286.00 40564.00 120480.20 2773.31 0.00 0.00 0.00 10:36:31 AM eth1 81256.00 40599.00 120438.81 2776.27 0.00 0.00 0.00 10:36:32 AM eth1 81287.00 40594.00 120480.69 2776.69 0.00 0.00 0.00 10:36:33 AM eth1 81279.00 40601.00 120478.53 2775.84 0.00 0.00 0.00 10:36:34 AM eth1 81277.00 40610.00 120476.94 2776.25 0.00 0.00 0.00 Average: eth1 81282.30 40606.70 120479.39 2776.54 0.00 0.00 0.20 lpx:~# echo 13000 >/sys/class/net/eth1/gro_flush_timeout lpx:~# sar -n DEV 1 10 | grep eth1 10:36:43 AM eth1 81257.00 7747.00 120437.44 530.00 0.00 0.00 0.00 10:36:44 AM eth1 81278.00 7748.00 120480.00 529.85 0.00 0.00 0.00 10:36:45 AM eth1 81282.00 7752.00 120479.09 531.09 0.00 0.00 0.00 10:36:46 AM eth1 81282.00 7751.00 120478.80 530.90 0.00 0.00 0.00 10:36:47 AM eth1 81276.00 7745.00 120478.31 529.64 0.00 0.00 0.00 10:36:48 AM eth1 81278.00 7747.00 120478.50 529.81 0.00 0.00 0.00 10:36:49 AM eth1 81282.00 7749.00 120478.88 530.01 0.00 0.00 0.00 10:36:50 AM eth1 81284.00 7751.00 120481.52 530.20 0.00 0.00 0.00 10:36:51 AM eth1 81299.00 7769.00 120481.74 533.81 0.00 0.00 0.00 10:36:52 AM eth1 81281.00 7748.00 120478.62 529.96 0.00 0.00 0.00 Average: eth1 81279.90 7750.70 120475.29 530.53 0.00 0.00 0.00 Signed-off-by: Eric Dumazet Acked-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/tg3.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 23a019cee279..22b33da32ba4 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -7244,7 +7244,7 @@ static int tg3_poll_msix(struct napi_struct *napi, int budget) if (tnapi == &tp->napi[1] && tp->rx_refill) continue; - napi_complete(napi); + napi_complete_done(napi, work_done); /* Reenable interrupts. */ tw32_mailbox(tnapi->int_mbox, tnapi->last_tag << 24); @@ -7337,7 +7337,7 @@ static int tg3_poll(struct napi_struct *napi, int budget) sblk->status &= ~SD_STATUS_UPDATED; if (likely(!tg3_has_work(tnapi))) { - napi_complete(napi); + napi_complete_done(napi, work_done); tg3_int_reenable(tnapi); break; } -- GitLab From 37ed9493699cc5dafe1b8725858ef73176fdc9d2 Mon Sep 17 00:00:00 2001 From: Scott Feldman Date: Thu, 5 Mar 2015 21:21:13 -0800 Subject: [PATCH 02884/11651] rtnetlink: add RTNH_F_EXTERNAL flag for fib offload Add new RTNH_F_EXTERNAL flag to mark fib entries offloaded externally, for example to a switchdev switch device. Signed-off-by: Scott Feldman Signed-off-by: David S. Miller --- include/uapi/linux/rtnetlink.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/uapi/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h index 06f75a407f74..c3722b024e73 100644 --- a/include/uapi/linux/rtnetlink.h +++ b/include/uapi/linux/rtnetlink.h @@ -334,6 +334,7 @@ struct rtnexthop { #define RTNH_F_DEAD 1 /* Nexthop is dead (used by multipath) */ #define RTNH_F_PERVASIVE 2 /* Do recursive gateway lookup */ #define RTNH_F_ONLINK 4 /* Gateway is forced on link */ +#define RTNH_F_EXTERNAL 8 /* Route installed externally */ /* Macros to handle hexthops */ -- GitLab From 4586f1bb911ce219a4bc1c2a9d6eee2e058b2b51 Mon Sep 17 00:00:00 2001 From: Scott Feldman Date: Thu, 5 Mar 2015 21:21:14 -0800 Subject: [PATCH 02885/11651] netdevice: add IPv4 fib add/del ops Add two new ndo ops for IPv4 fib offload support, add and del. Add uses modifiy semantics if fib entry already offloaded. Drivers implementing the new ndo ops will return err<0 if programming device fails, for example if device's tables are full. Signed-off-by: Scott Feldman Signed-off-by: David S. Miller --- include/linux/netdevice.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 625c8d71511b..45413784a3b1 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -768,6 +768,8 @@ struct netdev_phys_item_id { typedef u16 (*select_queue_fallback_t)(struct net_device *dev, struct sk_buff *skb); +struct fib_info; + /* * This structure defines the management hooks for network devices. * The following hooks can be defined; unless noted otherwise, they are @@ -1031,6 +1033,14 @@ typedef u16 (*select_queue_fallback_t)(struct net_device *dev, * int (*ndo_switch_port_stp_update)(struct net_device *dev, u8 state); * Called to notify switch device port of bridge port STP * state change. + * int (*ndo_sw_parent_fib_ipv4_add)(struct net_device *dev, __be32 dst, + * int dst_len, struct fib_info *fi, + * u8 tos, u8 type, u32 tb_id); + * Called to add/modify IPv4 route to switch device. + * int (*ndo_sw_parent_fib_ipv4_del)(struct net_device *dev, __be32 dst, + * int dst_len, struct fib_info *fi, + * u8 tos, u8 type, u32 tb_id); + * Called to delete IPv4 route from switch device. */ struct net_device_ops { int (*ndo_init)(struct net_device *dev); @@ -1192,6 +1202,18 @@ struct net_device_ops { struct netdev_phys_item_id *psid); int (*ndo_switch_port_stp_update)(struct net_device *dev, u8 state); + int (*ndo_switch_fib_ipv4_add)(struct net_device *dev, + __be32 dst, + int dst_len, + struct fib_info *fi, + u8 tos, u8 type, + u32 tb_id); + int (*ndo_switch_fib_ipv4_del)(struct net_device *dev, + __be32 dst, + int dst_len, + struct fib_info *fi, + u8 tos, u8 type, + u32 tb_id); #endif }; -- GitLab From 5e8d90497d65f528c54015644095ace6e330fd8e Mon Sep 17 00:00:00 2001 From: Scott Feldman Date: Thu, 5 Mar 2015 21:21:15 -0800 Subject: [PATCH 02886/11651] switchdev: add IPv4 fib ndo ops wrappers Add IPv4 fib ndo wrapper funcs and stub them out for now. Signed-off-by: Scott Feldman Signed-off-by: David S. Miller --- include/net/switchdev.h | 19 +++++++++++++++++++ net/switchdev/switchdev.c | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/include/net/switchdev.h b/include/net/switchdev.h index cfcdac2e5d25..8d2ac663325a 100644 --- a/include/net/switchdev.h +++ b/include/net/switchdev.h @@ -51,6 +51,11 @@ int ndo_dflt_netdev_switch_port_bridge_dellink(struct net_device *dev, struct nlmsghdr *nlh, u16 flags); int ndo_dflt_netdev_switch_port_bridge_setlink(struct net_device *dev, struct nlmsghdr *nlh, u16 flags); +int netdev_switch_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi, + u8 tos, u8 type, u32 tb_id); +int netdev_switch_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi, + u8 tos, u8 type, u32 tb_id); + #else static inline int netdev_switch_parent_id_get(struct net_device *dev, @@ -109,6 +114,20 @@ static inline int ndo_dflt_netdev_switch_port_bridge_setlink(struct net_device * return 0; } +static inline int netdev_switch_fib_ipv4_add(u32 dst, int dst_len, + struct fib_info *fi, + u8 tos, u8 type, u32 tb_id) +{ + return 0; +} + +static inline int netdev_switch_fib_ipv4_del(u32 dst, int dst_len, + struct fib_info *fi, + u8 tos, u8 type, u32 tb_id) +{ + return 0; +} + #endif #endif /* _LINUX_SWITCHDEV_H_ */ diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c index 8c1e558db118..3c090f8d071b 100644 --- a/net/switchdev/switchdev.c +++ b/net/switchdev/switchdev.c @@ -14,6 +14,7 @@ #include #include #include +#include #include /** @@ -225,3 +226,41 @@ int ndo_dflt_netdev_switch_port_bridge_dellink(struct net_device *dev, return ret; } EXPORT_SYMBOL(ndo_dflt_netdev_switch_port_bridge_dellink); + +/** + * netdev_switch_fib_ipv4_add - Add IPv4 route entry to switch + * + * @dst: route's IPv4 destination address + * @dst_len: destination address length (prefix length) + * @fi: route FIB info structure + * @tos: route TOS + * @type: route type + * @tb_id: route table ID + * + * Add IPv4 route entry to switch device. + */ +int netdev_switch_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi, + u8 tos, u8 type, u32 tb_id) +{ + return 0; +} +EXPORT_SYMBOL(netdev_switch_fib_ipv4_add); + +/** + * netdev_switch_fib_ipv4_del - Delete IPv4 route entry from switch + * + * @dst: route's IPv4 destination address + * @dst_len: destination address length (prefix length) + * @fi: route FIB info structure + * @tos: route TOS + * @type: route type + * @tb_id: route table ID + * + * Delete IPv4 route entry from switch device. + */ +int netdev_switch_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi, + u8 tos, u8 type, u32 tb_id) +{ + return 0; +} +EXPORT_SYMBOL(netdev_switch_fib_ipv4_del); -- GitLab From 104616e74e0b464d449fdd2ee2f547d2fad71610 Mon Sep 17 00:00:00 2001 From: Scott Feldman Date: Thu, 5 Mar 2015 21:21:16 -0800 Subject: [PATCH 02887/11651] switchdev: don't support custom ip rules, for now Keep switchdev FIB offload model simple for now and don't allow custom ip rules. Signed-off-by: Scott Feldman Signed-off-by: David S. Miller --- include/net/ip_fib.h | 2 ++ net/ipv4/fib_frontend.c | 13 +++++++++ net/ipv4/fib_rules.c | 3 ++ net/ipv4/fib_trie.c | 61 +++++++++++++++++++++++++++++++++++++++ net/switchdev/switchdev.c | 4 +++ 5 files changed, 83 insertions(+) diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h index 825cb2800908..1657604c5dd3 100644 --- a/include/net/ip_fib.h +++ b/include/net/ip_fib.h @@ -196,6 +196,7 @@ int fib_table_delete(struct fib_table *, struct fib_config *); int fib_table_dump(struct fib_table *table, struct sk_buff *skb, struct netlink_callback *cb); int fib_table_flush(struct fib_table *table); +void fib_table_flush_external(struct fib_table *table); void fib_free_table(struct fib_table *tb); @@ -308,6 +309,7 @@ static inline int fib_num_tclassid_users(struct net *net) return 0; } #endif +void fib_flush_external(struct net *net); /* Exported by fib_semantics.c */ int ip_fib_check_default(__be32 gw, struct net_device *dev); diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 220c4b4af4cf..e067770235bf 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -144,6 +144,19 @@ static void fib_flush(struct net *net) rt_cache_flush(net); } +void fib_flush_external(struct net *net) +{ + struct fib_table *tb; + struct hlist_head *head; + unsigned int h; + + for (h = 0; h < FIB_TABLE_HASHSZ; h++) { + head = &net->ipv4.fib_table_hash[h]; + hlist_for_each_entry(tb, head, tb_hlist) + fib_table_flush_external(tb); + } +} + /* * Find address type as if only "dev" was present in the system. If * on_dev is NULL then all interfaces are taken into consideration. diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c index d3db718be51d..190d0d00d744 100644 --- a/net/ipv4/fib_rules.c +++ b/net/ipv4/fib_rules.c @@ -209,6 +209,8 @@ static int fib4_rule_configure(struct fib_rule *rule, struct sk_buff *skb, rule4->tos = frh->tos; net->ipv4.fib_has_custom_rules = true; + fib_flush_external(rule->fr_net); + err = 0; errout: return err; @@ -224,6 +226,7 @@ static void fib4_rule_delete(struct fib_rule *rule) net->ipv4.fib_num_tclassid_users--; #endif net->ipv4.fib_has_custom_rules = true; + fib_flush_external(rule->fr_net); } static int fib4_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh, diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index fae34ad4bb1a..2de43956c9d0 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -1536,6 +1536,67 @@ found: return n; } +/* Caller must hold RTNL */ +void fib_table_flush_external(struct fib_table *tb) +{ + struct trie *t = (struct trie *)tb->tb_data; + struct fib_alias *fa; + struct tnode *n, *pn; + unsigned long cindex; + unsigned char slen; + int found = 0; + + n = rcu_dereference(t->trie); + if (!n) + return; + + pn = NULL; + cindex = 0; + + while (IS_TNODE(n)) { + /* record pn and cindex for leaf walking */ + pn = n; + cindex = 1ul << n->bits; +backtrace: + /* walk trie in reverse order */ + do { + while (!(cindex--)) { + t_key pkey = pn->key; + + n = pn; + pn = node_parent(n); + + /* resize completed node */ + resize(t, n); + + /* if we got the root we are done */ + if (!pn) + return; + + cindex = get_index(pkey, pn); + } + + /* grab the next available node */ + n = tnode_get_child(pn, cindex); + } while (!n); + } + + hlist_for_each_entry(fa, &n->leaf, fa_list) { + struct fib_info *fi = fa->fa_info; + + if (fi && (fi->fib_flags & RTNH_F_EXTERNAL)) { + netdev_switch_fib_ipv4_del(n->key, + KEYLENGTH - fa->fa_slen, + fi, fa->fa_tos, + fa->fa_type, tb->tb_id); + } + } + + /* if trie is leaf only loop is completed */ + if (pn) + goto backtrace; +} + /* Caller must hold RTNL. */ int fib_table_flush(struct fib_table *tb) { diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c index 3c090f8d071b..81c4c0274b9b 100644 --- a/net/switchdev/switchdev.c +++ b/net/switchdev/switchdev.c @@ -242,6 +242,10 @@ EXPORT_SYMBOL(ndo_dflt_netdev_switch_port_bridge_dellink); int netdev_switch_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi, u8 tos, u8 type, u32 tb_id) { + /* Don't offload route if using custom ip rules */ + if (fi->fib_net->ipv4.fib_has_custom_rules) + return 0; + return 0; } EXPORT_SYMBOL(netdev_switch_fib_ipv4_add); -- GitLab From b5d6fbdeede861b52d67b9a4ea3fdfcc6e6865cd Mon Sep 17 00:00:00 2001 From: Scott Feldman Date: Thu, 5 Mar 2015 21:21:17 -0800 Subject: [PATCH 02888/11651] switchdev: implement IPv4 fib ndo wrappers Flesh out ndo wrappers to call into device driver. To call into device driver, the wrapper must interate over route's nexthops to ensure all nexthop devs belong to the same switch device. Currently, there is no support for route's nexthops spanning offloaded and non-offloaded devices, or spanning ports of multiple offload devices. Since switch device ports may be stacked under virtual interfaces (bonds and/or bridges), and the route's nexthop may be on the virtual interface, the wrapper will traverse the nexthop dev down to the base dev. It's the base dev that's passed to the switchdev driver's ndo ops. Signed-off-by: Scott Feldman Signed-off-by: David S. Miller --- net/switchdev/switchdev.c | 98 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 96 insertions(+), 2 deletions(-) diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c index 81c4c0274b9b..99907d829419 100644 --- a/net/switchdev/switchdev.c +++ b/net/switchdev/switchdev.c @@ -227,6 +227,65 @@ int ndo_dflt_netdev_switch_port_bridge_dellink(struct net_device *dev, } EXPORT_SYMBOL(ndo_dflt_netdev_switch_port_bridge_dellink); +static struct net_device *netdev_switch_get_lowest_dev(struct net_device *dev) +{ + const struct net_device_ops *ops = dev->netdev_ops; + struct net_device *lower_dev; + struct net_device *port_dev; + struct list_head *iter; + + /* Recusively search down until we find a sw port dev. + * (A sw port dev supports ndo_switch_parent_id_get). + */ + + if (dev->features & NETIF_F_HW_SWITCH_OFFLOAD && + ops->ndo_switch_parent_id_get) + return dev; + + netdev_for_each_lower_dev(dev, lower_dev, iter) { + port_dev = netdev_switch_get_lowest_dev(lower_dev); + if (port_dev) + return port_dev; + } + + return NULL; +} + +static struct net_device *netdev_switch_get_dev_by_nhs(struct fib_info *fi) +{ + struct netdev_phys_item_id psid; + struct netdev_phys_item_id prev_psid; + struct net_device *dev = NULL; + int nhsel; + + /* For this route, all nexthop devs must be on the same switch. */ + + for (nhsel = 0; nhsel < fi->fib_nhs; nhsel++) { + const struct fib_nh *nh = &fi->fib_nh[nhsel]; + + if (!nh->nh_dev) + return NULL; + + dev = netdev_switch_get_lowest_dev(nh->nh_dev); + if (!dev) + return NULL; + + if (netdev_switch_parent_id_get(dev, &psid)) + return NULL; + + if (nhsel > 0) { + if (prev_psid.id_len != psid.id_len) + return NULL; + if (memcmp(prev_psid.id, psid.id, psid.id_len)) + return NULL; + } + + prev_psid = psid; + } + + return dev; +} + /** * netdev_switch_fib_ipv4_add - Add IPv4 route entry to switch * @@ -242,11 +301,27 @@ EXPORT_SYMBOL(ndo_dflt_netdev_switch_port_bridge_dellink); int netdev_switch_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi, u8 tos, u8 type, u32 tb_id) { + struct net_device *dev; + const struct net_device_ops *ops; + int err = 0; + /* Don't offload route if using custom ip rules */ if (fi->fib_net->ipv4.fib_has_custom_rules) return 0; - return 0; + dev = netdev_switch_get_dev_by_nhs(fi); + if (!dev) + return 0; + ops = dev->netdev_ops; + + if (ops->ndo_switch_fib_ipv4_add) { + err = ops->ndo_switch_fib_ipv4_add(dev, htonl(dst), dst_len, + fi, tos, type, tb_id); + if (!err) + fi->fib_flags |= RTNH_F_EXTERNAL; + } + + return err; } EXPORT_SYMBOL(netdev_switch_fib_ipv4_add); @@ -265,6 +340,25 @@ EXPORT_SYMBOL(netdev_switch_fib_ipv4_add); int netdev_switch_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi, u8 tos, u8 type, u32 tb_id) { - return 0; + struct net_device *dev; + const struct net_device_ops *ops; + int err = 0; + + if (!(fi->fib_flags & RTNH_F_EXTERNAL)) + return 0; + + dev = netdev_switch_get_dev_by_nhs(fi); + if (!dev) + return 0; + ops = dev->netdev_ops; + + if (ops->ndo_switch_fib_ipv4_del) { + err = ops->ndo_switch_fib_ipv4_del(dev, htonl(dst), dst_len, + fi, tos, type, tb_id); + if (!err) + fi->fib_flags &= ~RTNH_F_EXTERNAL; + } + + return err; } EXPORT_SYMBOL(netdev_switch_fib_ipv4_del); -- GitLab From 448b128a14501543748514a4f9adedd3c0da2e85 Mon Sep 17 00:00:00 2001 From: Scott Feldman Date: Thu, 5 Mar 2015 21:21:18 -0800 Subject: [PATCH 02889/11651] ipv4: add net bool fib_offload_disabled If something goes wrong with IPv4 FIB offload, mark entire net offload disabled. This is brute force policy to basically shut down IPv4 FIB offload permanently if there is a problem offloading any route to an external device. We can refine the policy in the future, to handle failures on a per-device or per-route basis, but for now, this policy is per-net. What we're trying to avoid is an inconsistent split between the kernel's FIB and the offload device's FIB. We don't want the device to fwd a pkt inconsitent with what the kernel would do. An example of a split is if device has 10.0.0.0/16 and kernel has 10.0.0.0/16 and 10.0.0.0/24, the device wouldn't see the longest prefix 10.0.0.0/24 and potentially forward pkts incorrectly. Limited capacity or limited capability are two ways a route may fail to install to the offload device. We'll not differentiate between failures at this time, and treat any failure as fatal and mark the net as fib_offload_disabled. Signed-off-by: Scott Feldman Signed-off-by: David S. Miller --- include/net/netns/ipv4.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h index db1db158a00e..1085e12f940f 100644 --- a/include/net/netns/ipv4.h +++ b/include/net/netns/ipv4.h @@ -47,6 +47,7 @@ struct netns_ipv4 { int fib_num_tclassid_users; #endif struct hlist_head *fib_table_hash; + bool fib_offload_disabled; struct sock *fibnl; struct sock * __percpu *icmp_sk; -- GitLab From 8e05fd7166c6123334b7a739a697d677747aa462 Mon Sep 17 00:00:00 2001 From: Scott Feldman Date: Thu, 5 Mar 2015 21:21:19 -0800 Subject: [PATCH 02890/11651] fib: hook IPv4 fib for hardware offload Call into the switchdev driver any time an IPv4 fib entry is added/modified/deleted from the kernel's FIB. The switchdev driver may or may not install the route to the offload device. In the case where the driver tries to install the route and something goes wrong (device's routing table is full, etc), then all of the offloaded routes will be flushed from the device, route forwarding falls back to the kernel, and no more routes are offloading. We can refine this logic later. For now, use the simplist model of offloading routes up to the point of failure, and then on failure, undo everything and mark IPv4 offloading disabled. Signed-off-by: Scott Feldman Signed-off-by: David S. Miller --- include/net/switchdev.h | 5 +++++ net/ipv4/fib_trie.c | 31 ++++++++++++++++++++++++++++++- net/switchdev/switchdev.c | 28 ++++++++++++++++++++++++++-- 3 files changed, 61 insertions(+), 3 deletions(-) diff --git a/include/net/switchdev.h b/include/net/switchdev.h index 8d2ac663325a..dc0a5cc7c2c5 100644 --- a/include/net/switchdev.h +++ b/include/net/switchdev.h @@ -55,6 +55,7 @@ int netdev_switch_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi, u8 tos, u8 type, u32 tb_id); int netdev_switch_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi, u8 tos, u8 type, u32 tb_id); +void netdev_switch_fib_ipv4_abort(struct fib_info *fi); #else @@ -128,6 +129,10 @@ static inline int netdev_switch_fib_ipv4_del(u32 dst, int dst_len, return 0; } +void netdev_switch_fib_ipv4_abort(struct fib_info *fi) +{ +} + #endif #endif /* _LINUX_SWITCHDEV_H_ */ diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 2de43956c9d0..6544f1a0cfa1 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -79,6 +79,7 @@ #include #include #include +#include #include "fib_lookup.h" #define MAX_STAT_DEPTH 32 @@ -1135,7 +1136,18 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg) new_fa->fa_state = state & ~FA_S_ACCESSED; new_fa->fa_slen = fa->fa_slen; + err = netdev_switch_fib_ipv4_add(key, plen, fi, + new_fa->fa_tos, + cfg->fc_type, + tb->tb_id); + if (err) { + netdev_switch_fib_ipv4_abort(fi); + kmem_cache_free(fn_alias_kmem, new_fa); + goto out; + } + hlist_replace_rcu(&fa->fa_list, &new_fa->fa_list); + alias_free_mem_rcu(fa); fib_release_info(fi_drop); @@ -1171,10 +1183,18 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg) new_fa->fa_state = 0; new_fa->fa_slen = slen; + /* (Optionally) offload fib entry to switch hardware. */ + err = netdev_switch_fib_ipv4_add(key, plen, fi, tos, + cfg->fc_type, tb->tb_id); + if (err) { + netdev_switch_fib_ipv4_abort(fi); + goto out_free_new_fa; + } + /* Insert new entry to the list. */ err = fib_insert_alias(t, tp, l, new_fa, fa, key); if (err) - goto out_free_new_fa; + goto out_sw_fib_del; if (!plen) tb->tb_num_default++; @@ -1185,6 +1205,8 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg) succeeded: return 0; +out_sw_fib_del: + netdev_switch_fib_ipv4_del(key, plen, fi, tos, cfg->fc_type, tb->tb_id); out_free_new_fa: kmem_cache_free(fn_alias_kmem, new_fa); out: @@ -1456,6 +1478,9 @@ int fib_table_delete(struct fib_table *tb, struct fib_config *cfg) if (!fa_to_delete) return -ESRCH; + netdev_switch_fib_ipv4_del(key, plen, fa_to_delete->fa_info, tos, + cfg->fc_type, tb->tb_id); + rtmsg_fib(RTM_DELROUTE, htonl(key), fa_to_delete, plen, tb->tb_id, &cfg->fc_nlinfo, 0); @@ -1650,6 +1675,10 @@ backtrace: struct fib_info *fi = fa->fa_info; if (fi && (fi->fib_flags & RTNH_F_DEAD)) { + netdev_switch_fib_ipv4_del(n->key, + KEYLENGTH - fa->fa_slen, + fi, fa->fa_tos, + fa->fa_type, tb->tb_id); hlist_del_rcu(&fa->fa_list); fib_release_info(fa->fa_info); alias_free_mem_rcu(fa); diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c index 99907d829419..f4fd575aa2a3 100644 --- a/net/switchdev/switchdev.c +++ b/net/switchdev/switchdev.c @@ -305,8 +305,12 @@ int netdev_switch_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi, const struct net_device_ops *ops; int err = 0; - /* Don't offload route if using custom ip rules */ - if (fi->fib_net->ipv4.fib_has_custom_rules) + /* Don't offload route if using custom ip rules or if + * IPv4 FIB offloading has been disabled completely. + */ + + if (fi->fib_net->ipv4.fib_has_custom_rules | + fi->fib_net->ipv4.fib_offload_disabled) return 0; dev = netdev_switch_get_dev_by_nhs(fi); @@ -362,3 +366,23 @@ int netdev_switch_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi, return err; } EXPORT_SYMBOL(netdev_switch_fib_ipv4_del); + +/** + * netdev_switch_fib_ipv4_abort - Abort an IPv4 FIB operation + * + * @fi: route FIB info structure + */ +void netdev_switch_fib_ipv4_abort(struct fib_info *fi) +{ + /* There was a problem installing this route to the offload + * device. For now, until we come up with more refined + * policy handling, abruptly end IPv4 fib offloading for + * for entire net by flushing offload device(s) of all + * IPv4 routes, and mark IPv4 fib offloading broken from + * this point forward. + */ + + fib_flush_external(fi->fib_net); + fi->fib_net->ipv4.fib_offload_disabled = true; +} +EXPORT_SYMBOL(netdev_switch_fib_ipv4_abort); -- GitLab From c1beeef7a32a791a60e2adcc217d4461cd1e25d1 Mon Sep 17 00:00:00 2001 From: Scott Feldman Date: Thu, 5 Mar 2015 21:21:20 -0800 Subject: [PATCH 02891/11651] rocker: implement IPv4 fib offloading The driver implements ndo_switch_fib_ipv4_add/del ops to add/del/mod IPv4 routes to/from switchdev device. Once a route is added to the device, and the route's nexthops are resolved to neighbor MAC address, the device will forward matching pkts rather than the kernel. This offloads the L3 forwarding path from the kernel to the device. Note that control and management planes are still mananged by Linux; only the data plane is offloaded. Standard routing control protocols such as OSPF and BGP run on Linux and manage the kernel's FIB via standard rtm netlink msgs...nothing changes here. A new hash table is added to rocker to track neighbors. The driver listens for neighbor updates events using netevent notifier NETEVENT_NEIGH_UPDATE. Any ARP table updates for ports on this device are recorded in this table. Routes installed to the device with nexthops that reference neighbors in this table are "qualified". In the case of a route with nexthops not resolved in the table, the kernel is asked to resolve the nexthop. The driver uses fib_info->fib_priority for the priority field in rocker's unicast routing table. The device can only forward to pkts matching route dst to resolved nexthops. Currently, the device only supports single-path routes (i.e. routes with one nexthop). Equal Cost Multipath (ECMP) route support will be added in followup patches. This patch is driver support for unicast IPv4 routing only. Followup patches will add driver and infrastructure for IPv6 routing and multicast routing. Signed-off-by: Scott Feldman Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/ethernet/rocker/rocker.c | 483 ++++++++++++++++++++++++--- 1 file changed, 436 insertions(+), 47 deletions(-) diff --git a/drivers/net/ethernet/rocker/rocker.c b/drivers/net/ethernet/rocker/rocker.c index a5d1e6ea7d58..d04d3b374e31 100644 --- a/drivers/net/ethernet/rocker/rocker.c +++ b/drivers/net/ethernet/rocker/rocker.c @@ -32,6 +32,9 @@ #include #include #include +#include +#include +#include #include #include @@ -111,9 +114,10 @@ struct rocker_flow_tbl_key { struct rocker_flow_tbl_entry { struct hlist_node entry; - u32 ref_count; + u32 cmd; u64 cookie; struct rocker_flow_tbl_key key; + size_t key_len; u32 key_crc32; /* key */ }; @@ -161,6 +165,16 @@ struct rocker_internal_vlan_tbl_entry { __be16 vlan_id; }; +struct rocker_neigh_tbl_entry { + struct hlist_node entry; + __be32 ip_addr; /* key */ + struct net_device *dev; + u32 ref_count; + u32 index; + u8 eth_dst[ETH_ALEN]; + bool ttl_check; +}; + struct rocker_desc_info { char *data; /* mapped */ size_t data_size; @@ -234,6 +248,9 @@ struct rocker { unsigned long internal_vlan_bitmap[ROCKER_INTERNAL_VLAN_BITMAP_LEN]; DECLARE_HASHTABLE(internal_vlan_tbl, 8); spinlock_t internal_vlan_tbl_lock; + DECLARE_HASHTABLE(neigh_tbl, 16); + spinlock_t neigh_tbl_lock; + u32 neigh_tbl_next_index; }; static const u8 zero_mac[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; @@ -256,7 +273,6 @@ enum { ROCKER_PRIORITY_VLAN = 1, ROCKER_PRIORITY_TERM_MAC_UCAST = 0, ROCKER_PRIORITY_TERM_MAC_MCAST = 1, - ROCKER_PRIORITY_UNICAST_ROUTING = 1, ROCKER_PRIORITY_BRIDGING_VLAN_DFLT_EXACT = 1, ROCKER_PRIORITY_BRIDGING_VLAN_DFLT_WILD = 2, ROCKER_PRIORITY_BRIDGING_VLAN = 3, @@ -1940,8 +1956,7 @@ static int rocker_cmd_flow_tbl_add(struct rocker *rocker, struct rocker_tlv *cmd_info; int err = 0; - if (rocker_tlv_put_u16(desc_info, ROCKER_TLV_CMD_TYPE, - ROCKER_TLV_CMD_TYPE_OF_DPA_FLOW_ADD)) + if (rocker_tlv_put_u16(desc_info, ROCKER_TLV_CMD_TYPE, entry->cmd)) return -EMSGSIZE; cmd_info = rocker_tlv_nest_start(desc_info, ROCKER_TLV_CMD_INFO); if (!cmd_info) @@ -1998,8 +2013,7 @@ static int rocker_cmd_flow_tbl_del(struct rocker *rocker, const struct rocker_flow_tbl_entry *entry = priv; struct rocker_tlv *cmd_info; - if (rocker_tlv_put_u16(desc_info, ROCKER_TLV_CMD_TYPE, - ROCKER_TLV_CMD_TYPE_OF_DPA_FLOW_DEL)) + if (rocker_tlv_put_u16(desc_info, ROCKER_TLV_CMD_TYPE, entry->cmd)) return -EMSGSIZE; cmd_info = rocker_tlv_nest_start(desc_info, ROCKER_TLV_CMD_INFO); if (!cmd_info) @@ -2168,9 +2182,9 @@ static int rocker_cmd_group_tbl_del(struct rocker *rocker, return 0; } -/***************************************** - * Flow, group, FDB, internal VLAN tables - *****************************************/ +/*************************************************** + * Flow, group, FDB, internal VLAN and neigh tables + ***************************************************/ static int rocker_init_tbls(struct rocker *rocker) { @@ -2186,6 +2200,9 @@ static int rocker_init_tbls(struct rocker *rocker) hash_init(rocker->internal_vlan_tbl); spin_lock_init(&rocker->internal_vlan_tbl_lock); + hash_init(rocker->neigh_tbl); + spin_lock_init(&rocker->neigh_tbl_lock); + return 0; } @@ -2196,6 +2213,7 @@ static void rocker_free_tbls(struct rocker *rocker) struct rocker_group_tbl_entry *group_entry; struct rocker_fdb_tbl_entry *fdb_entry; struct rocker_internal_vlan_tbl_entry *internal_vlan_entry; + struct rocker_neigh_tbl_entry *neigh_entry; struct hlist_node *tmp; int bkt; @@ -2219,16 +2237,22 @@ static void rocker_free_tbls(struct rocker *rocker) tmp, internal_vlan_entry, entry) hash_del(&internal_vlan_entry->entry); spin_unlock_irqrestore(&rocker->internal_vlan_tbl_lock, flags); + + spin_lock_irqsave(&rocker->neigh_tbl_lock, flags); + hash_for_each_safe(rocker->neigh_tbl, bkt, tmp, neigh_entry, entry) + hash_del(&neigh_entry->entry); + spin_unlock_irqrestore(&rocker->neigh_tbl_lock, flags); } static struct rocker_flow_tbl_entry * rocker_flow_tbl_find(struct rocker *rocker, struct rocker_flow_tbl_entry *match) { struct rocker_flow_tbl_entry *found; + size_t key_len = match->key_len ? match->key_len : sizeof(found->key); hash_for_each_possible(rocker->flow_tbl, found, entry, match->key_crc32) { - if (memcmp(&found->key, &match->key, sizeof(found->key)) == 0) + if (memcmp(&found->key, &match->key, key_len) == 0) return found; } @@ -2241,42 +2265,34 @@ static int rocker_flow_tbl_add(struct rocker_port *rocker_port, { struct rocker *rocker = rocker_port->rocker; struct rocker_flow_tbl_entry *found; + size_t key_len = match->key_len ? match->key_len : sizeof(found->key); unsigned long flags; - bool add_to_hw = false; - int err = 0; - match->key_crc32 = crc32(~0, &match->key, sizeof(match->key)); + match->key_crc32 = crc32(~0, &match->key, key_len); spin_lock_irqsave(&rocker->flow_tbl_lock, flags); found = rocker_flow_tbl_find(rocker, match); if (found) { - kfree(match); + match->cookie = found->cookie; + hash_del(&found->entry); + kfree(found); + found = match; + found->cmd = ROCKER_TLV_CMD_TYPE_OF_DPA_FLOW_MOD; } else { found = match; found->cookie = rocker->flow_tbl_next_cookie++; - hash_add(rocker->flow_tbl, &found->entry, found->key_crc32); - add_to_hw = true; + found->cmd = ROCKER_TLV_CMD_TYPE_OF_DPA_FLOW_ADD; } - found->ref_count++; + hash_add(rocker->flow_tbl, &found->entry, found->key_crc32); spin_unlock_irqrestore(&rocker->flow_tbl_lock, flags); - if (add_to_hw) { - err = rocker_cmd_exec(rocker, rocker_port, - rocker_cmd_flow_tbl_add, - found, NULL, NULL, nowait); - if (err) { - spin_lock_irqsave(&rocker->flow_tbl_lock, flags); - hash_del(&found->entry); - spin_unlock_irqrestore(&rocker->flow_tbl_lock, flags); - kfree(found); - } - } - - return err; + return rocker_cmd_exec(rocker, rocker_port, + rocker_cmd_flow_tbl_add, + found, NULL, NULL, nowait); } static int rocker_flow_tbl_del(struct rocker_port *rocker_port, @@ -2285,29 +2301,26 @@ static int rocker_flow_tbl_del(struct rocker_port *rocker_port, { struct rocker *rocker = rocker_port->rocker; struct rocker_flow_tbl_entry *found; + size_t key_len = match->key_len ? match->key_len : sizeof(found->key); unsigned long flags; - bool del_from_hw = false; int err = 0; - match->key_crc32 = crc32(~0, &match->key, sizeof(match->key)); + match->key_crc32 = crc32(~0, &match->key, key_len); spin_lock_irqsave(&rocker->flow_tbl_lock, flags); found = rocker_flow_tbl_find(rocker, match); if (found) { - found->ref_count--; - if (found->ref_count == 0) { - hash_del(&found->entry); - del_from_hw = true; - } + hash_del(&found->entry); + found->cmd = ROCKER_TLV_CMD_TYPE_OF_DPA_FLOW_DEL; } spin_unlock_irqrestore(&rocker->flow_tbl_lock, flags); kfree(match); - if (del_from_hw) { + if (found) { err = rocker_cmd_exec(rocker, rocker_port, rocker_cmd_flow_tbl_del, found, NULL, NULL, nowait); @@ -2467,6 +2480,31 @@ static int rocker_flow_tbl_bridge(struct rocker_port *rocker_port, return rocker_flow_tbl_do(rocker_port, flags, entry); } +static int rocker_flow_tbl_ucast4_routing(struct rocker_port *rocker_port, + __be16 eth_type, __be32 dst, + __be32 dst_mask, u32 priority, + enum rocker_of_dpa_table_id goto_tbl, + u32 group_id, int flags) +{ + struct rocker_flow_tbl_entry *entry; + + entry = kzalloc(sizeof(*entry), rocker_op_flags_gfp(flags)); + if (!entry) + return -ENOMEM; + + entry->key.tbl_id = ROCKER_OF_DPA_TABLE_ID_UNICAST_ROUTING; + entry->key.priority = priority; + entry->key.ucast_routing.eth_type = eth_type; + entry->key.ucast_routing.dst4 = dst; + entry->key.ucast_routing.dst4_mask = dst_mask; + entry->key.ucast_routing.goto_tbl = goto_tbl; + entry->key.ucast_routing.group_id = group_id; + entry->key_len = offsetof(struct rocker_flow_tbl_key, + ucast_routing.group_id); + + return rocker_flow_tbl_do(rocker_port, flags, entry); +} + static int rocker_flow_tbl_acl(struct rocker_port *rocker_port, int flags, u32 in_pport, u32 in_pport_mask, @@ -2554,7 +2592,6 @@ static int rocker_group_tbl_add(struct rocker_port *rocker_port, struct rocker *rocker = rocker_port->rocker; struct rocker_group_tbl_entry *found; unsigned long flags; - int err = 0; spin_lock_irqsave(&rocker->group_tbl_lock, flags); @@ -2574,12 +2611,9 @@ static int rocker_group_tbl_add(struct rocker_port *rocker_port, spin_unlock_irqrestore(&rocker->group_tbl_lock, flags); - if (found->cmd) - err = rocker_cmd_exec(rocker, rocker_port, - rocker_cmd_group_tbl_add, - found, NULL, NULL, nowait); - - return err; + return rocker_cmd_exec(rocker, rocker_port, + rocker_cmd_group_tbl_add, + found, NULL, NULL, nowait); } static int rocker_group_tbl_del(struct rocker_port *rocker_port, @@ -2675,6 +2709,244 @@ static int rocker_group_l2_flood(struct rocker_port *rocker_port, group_id); } +static int rocker_group_l3_unicast(struct rocker_port *rocker_port, + int flags, u32 index, u8 *src_mac, + u8 *dst_mac, __be16 vlan_id, + bool ttl_check, u32 pport) +{ + struct rocker_group_tbl_entry *entry; + + entry = kzalloc(sizeof(*entry), rocker_op_flags_gfp(flags)); + if (!entry) + return -ENOMEM; + + entry->group_id = ROCKER_GROUP_L3_UNICAST(index); + if (src_mac) + ether_addr_copy(entry->l3_unicast.eth_src, src_mac); + if (dst_mac) + ether_addr_copy(entry->l3_unicast.eth_dst, dst_mac); + entry->l3_unicast.vlan_id = vlan_id; + entry->l3_unicast.ttl_check = ttl_check; + entry->l3_unicast.group_id = ROCKER_GROUP_L2_INTERFACE(vlan_id, pport); + + return rocker_group_tbl_do(rocker_port, flags, entry); +} + +static struct rocker_neigh_tbl_entry * + rocker_neigh_tbl_find(struct rocker *rocker, __be32 ip_addr) +{ + struct rocker_neigh_tbl_entry *found; + + hash_for_each_possible(rocker->neigh_tbl, found, entry, ip_addr) + if (found->ip_addr == ip_addr) + return found; + + return NULL; +} + +static void _rocker_neigh_add(struct rocker *rocker, + struct rocker_neigh_tbl_entry *entry) +{ + entry->index = rocker->neigh_tbl_next_index++; + entry->ref_count++; + hash_add(rocker->neigh_tbl, &entry->entry, entry->ip_addr); +} + +static void _rocker_neigh_del(struct rocker *rocker, + struct rocker_neigh_tbl_entry *entry) +{ + if (--entry->ref_count == 0) { + hash_del(&entry->entry); + kfree(entry); + } +} + +static void _rocker_neigh_update(struct rocker *rocker, + struct rocker_neigh_tbl_entry *entry, + u8 *eth_dst, bool ttl_check) +{ + if (eth_dst) { + ether_addr_copy(entry->eth_dst, eth_dst); + entry->ttl_check = ttl_check; + } else { + entry->ref_count++; + } +} + +static int rocker_port_ipv4_neigh(struct rocker_port *rocker_port, + int flags, __be32 ip_addr, u8 *eth_dst) +{ + struct rocker *rocker = rocker_port->rocker; + struct rocker_neigh_tbl_entry *entry; + struct rocker_neigh_tbl_entry *found; + unsigned long lock_flags; + __be16 eth_type = htons(ETH_P_IP); + enum rocker_of_dpa_table_id goto_tbl = + ROCKER_OF_DPA_TABLE_ID_ACL_POLICY; + u32 group_id; + u32 priority = 0; + bool adding = !(flags & ROCKER_OP_FLAG_REMOVE); + bool updating; + bool removing; + int err = 0; + + entry = kzalloc(sizeof(*entry), rocker_op_flags_gfp(flags)); + if (!entry) + return -ENOMEM; + + spin_lock_irqsave(&rocker->neigh_tbl_lock, lock_flags); + + found = rocker_neigh_tbl_find(rocker, ip_addr); + + updating = found && adding; + removing = found && !adding; + adding = !found && adding; + + if (adding) { + entry->ip_addr = ip_addr; + entry->dev = rocker_port->dev; + ether_addr_copy(entry->eth_dst, eth_dst); + entry->ttl_check = true; + _rocker_neigh_add(rocker, entry); + } else if (removing) { + memcpy(entry, found, sizeof(*entry)); + _rocker_neigh_del(rocker, found); + } else if (updating) { + _rocker_neigh_update(rocker, found, eth_dst, true); + memcpy(entry, found, sizeof(*entry)); + } else { + err = -ENOENT; + } + + spin_unlock_irqrestore(&rocker->neigh_tbl_lock, lock_flags); + + if (err) + goto err_out; + + /* For each active neighbor, we have an L3 unicast group and + * a /32 route to the neighbor, which uses the L3 unicast + * group. The L3 unicast group can also be referred to by + * other routes' nexthops. + */ + + err = rocker_group_l3_unicast(rocker_port, flags, + entry->index, + rocker_port->dev->dev_addr, + entry->eth_dst, + rocker_port->internal_vlan_id, + entry->ttl_check, + rocker_port->pport); + if (err) { + netdev_err(rocker_port->dev, + "Error (%d) L3 unicast group index %d\n", + err, entry->index); + goto err_out; + } + + if (adding || removing) { + group_id = ROCKER_GROUP_L3_UNICAST(entry->index); + err = rocker_flow_tbl_ucast4_routing(rocker_port, + eth_type, ip_addr, + inet_make_mask(32), + priority, goto_tbl, + group_id, flags); + + if (err) + netdev_err(rocker_port->dev, + "Error (%d) /32 unicast route %pI4 group 0x%08x\n", + err, &entry->ip_addr, group_id); + } + +err_out: + if (!adding) + kfree(entry); + + return err; +} + +static int rocker_port_ipv4_resolve(struct rocker_port *rocker_port, + __be32 ip_addr) +{ + struct net_device *dev = rocker_port->dev; + struct neighbour *n = __ipv4_neigh_lookup(dev, ip_addr); + int err = 0; + + if (!n) + n = neigh_create(&arp_tbl, &ip_addr, dev); + if (!n) + return -ENOMEM; + + /* If the neigh is already resolved, then go ahead and + * install the entry, otherwise start the ARP process to + * resolve the neigh. + */ + + if (n->nud_state & NUD_VALID) + err = rocker_port_ipv4_neigh(rocker_port, 0, ip_addr, n->ha); + else + neigh_event_send(n, NULL); + + return err; +} + +static int rocker_port_ipv4_nh(struct rocker_port *rocker_port, int flags, + __be32 ip_addr, u32 *index) +{ + struct rocker *rocker = rocker_port->rocker; + struct rocker_neigh_tbl_entry *entry; + struct rocker_neigh_tbl_entry *found; + unsigned long lock_flags; + bool adding = !(flags & ROCKER_OP_FLAG_REMOVE); + bool updating; + bool removing; + bool resolved = true; + int err = 0; + + entry = kzalloc(sizeof(*entry), rocker_op_flags_gfp(flags)); + if (!entry) + return -ENOMEM; + + spin_lock_irqsave(&rocker->neigh_tbl_lock, lock_flags); + + found = rocker_neigh_tbl_find(rocker, ip_addr); + if (found) + *index = found->index; + + updating = found && adding; + removing = found && !adding; + adding = !found && adding; + + if (adding) { + entry->ip_addr = ip_addr; + entry->dev = rocker_port->dev; + _rocker_neigh_add(rocker, entry); + *index = entry->index; + resolved = false; + } else if (removing) { + _rocker_neigh_del(rocker, found); + } else if (updating) { + _rocker_neigh_update(rocker, found, NULL, false); + resolved = !is_zero_ether_addr(found->eth_dst); + } else { + err = -ENOENT; + } + + spin_unlock_irqrestore(&rocker->neigh_tbl_lock, lock_flags); + + if (!adding) + kfree(entry); + + if (err) + return err; + + /* Resolved means neigh ip_addr is resolved to neigh mac. */ + + if (!resolved) + err = rocker_port_ipv4_resolve(rocker_port, ip_addr); + + return err; +} + static int rocker_port_vlan_flood_group(struct rocker_port *rocker_port, int flags, __be16 vlan_id) { @@ -3429,6 +3701,51 @@ not_found: spin_unlock_irqrestore(&rocker->internal_vlan_tbl_lock, lock_flags); } +static int rocker_port_fib_ipv4(struct rocker_port *rocker_port, __be32 dst, + int dst_len, struct fib_info *fi, u32 tb_id, + int flags) +{ + struct fib_nh *nh; + __be16 eth_type = htons(ETH_P_IP); + __be32 dst_mask = inet_make_mask(dst_len); + __be16 internal_vlan_id = rocker_port->internal_vlan_id; + u32 priority = fi->fib_priority; + enum rocker_of_dpa_table_id goto_tbl = + ROCKER_OF_DPA_TABLE_ID_ACL_POLICY; + u32 group_id; + bool nh_on_port; + bool has_gw; + u32 index; + int err; + + /* XXX support ECMP */ + + nh = fi->fib_nh; + nh_on_port = (fi->fib_dev == rocker_port->dev); + has_gw = !!nh->nh_gw; + + if (has_gw && nh_on_port) { + err = rocker_port_ipv4_nh(rocker_port, flags, + nh->nh_gw, &index); + if (err) + return err; + + group_id = ROCKER_GROUP_L3_UNICAST(index); + } else { + /* Send to CPU for processing */ + group_id = ROCKER_GROUP_L2_INTERFACE(internal_vlan_id, 0); + } + + err = rocker_flow_tbl_ucast4_routing(rocker_port, eth_type, dst, + dst_mask, priority, goto_tbl, + group_id, flags); + if (err) + netdev_err(rocker_port->dev, "Error (%d) IPv4 route %pI4\n", + err, &dst); + + return err; +} + /***************** * Net device ops *****************/ @@ -3830,6 +4147,30 @@ static int rocker_port_switch_port_stp_update(struct net_device *dev, u8 state) return rocker_port_stp_update(rocker_port, state); } +static int rocker_port_switch_fib_ipv4_add(struct net_device *dev, + __be32 dst, int dst_len, + struct fib_info *fi, + u8 tos, u8 type, u32 tb_id) +{ + struct rocker_port *rocker_port = netdev_priv(dev); + int flags = 0; + + return rocker_port_fib_ipv4(rocker_port, dst, dst_len, + fi, tb_id, flags); +} + +static int rocker_port_switch_fib_ipv4_del(struct net_device *dev, + __be32 dst, int dst_len, + struct fib_info *fi, + u8 tos, u8 type, u32 tb_id) +{ + struct rocker_port *rocker_port = netdev_priv(dev); + int flags = ROCKER_OP_FLAG_REMOVE; + + return rocker_port_fib_ipv4(rocker_port, dst, dst_len, + fi, tb_id, flags); +} + static const struct net_device_ops rocker_port_netdev_ops = { .ndo_open = rocker_port_open, .ndo_stop = rocker_port_stop, @@ -3844,6 +4185,8 @@ static const struct net_device_ops rocker_port_netdev_ops = { .ndo_bridge_getlink = rocker_port_bridge_getlink, .ndo_switch_parent_id_get = rocker_port_switch_parent_id_get, .ndo_switch_port_stp_update = rocker_port_switch_port_stp_update, + .ndo_switch_fib_ipv4_add = rocker_port_switch_fib_ipv4_add, + .ndo_switch_fib_ipv4_del = rocker_port_switch_fib_ipv4_del, }; /******************** @@ -4204,8 +4547,9 @@ static int rocker_probe_port(struct rocker *rocker, unsigned int port_number) NAPI_POLL_WEIGHT); rocker_carrier_init(rocker_port); - dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | - NETIF_F_HW_SWITCH_OFFLOAD; + dev->features |= NETIF_F_NETNS_LOCAL | + NETIF_F_HW_VLAN_CTAG_FILTER | + NETIF_F_HW_SWITCH_OFFLOAD; err = register_netdev(dev); if (err) { @@ -4546,6 +4890,48 @@ static struct notifier_block rocker_netdevice_nb __read_mostly = { .notifier_call = rocker_netdevice_event, }; +/************************************ + * Net event notifier event handler + ************************************/ + +static int rocker_neigh_update(struct net_device *dev, struct neighbour *n) +{ + struct rocker_port *rocker_port = netdev_priv(dev); + int flags = (n->nud_state & NUD_VALID) ? 0 : ROCKER_OP_FLAG_REMOVE; + __be32 ip_addr = *(__be32 *)n->primary_key; + + return rocker_port_ipv4_neigh(rocker_port, flags, ip_addr, n->ha); +} + +static int rocker_netevent_event(struct notifier_block *unused, + unsigned long event, void *ptr) +{ + struct net_device *dev; + struct neighbour *n = ptr; + int err; + + switch (event) { + case NETEVENT_NEIGH_UPDATE: + if (n->tbl != &arp_tbl) + return NOTIFY_DONE; + dev = n->dev; + if (!rocker_port_dev_check(dev)) + return NOTIFY_DONE; + err = rocker_neigh_update(dev, n); + if (err) + netdev_warn(dev, + "failed to handle neigh update (err %d)\n", + err); + break; + } + + return NOTIFY_DONE; +} + +static struct notifier_block rocker_netevent_nb __read_mostly = { + .notifier_call = rocker_netevent_event, +}; + /*********************** * Module init and exit ***********************/ @@ -4555,18 +4941,21 @@ static int __init rocker_module_init(void) int err; register_netdevice_notifier(&rocker_netdevice_nb); + register_netevent_notifier(&rocker_netevent_nb); err = pci_register_driver(&rocker_pci_driver); if (err) goto err_pci_register_driver; return 0; err_pci_register_driver: + unregister_netdevice_notifier(&rocker_netevent_nb); unregister_netdevice_notifier(&rocker_netdevice_nb); return err; } static void __exit rocker_module_exit(void) { + unregister_netevent_notifier(&rocker_netevent_nb); unregister_netdevice_notifier(&rocker_netdevice_nb); pci_unregister_driver(&rocker_pci_driver); } -- GitLab From 23375a0fd549aa0a8c96b9f56a0b8120ae1389dd Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 6 Mar 2015 00:38:35 -0500 Subject: [PATCH 02892/11651] ipv4: Fix unused variable warnings in fib_table_flush_external. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit net/ipv4/fib_trie.c: In function ‘fib_table_flush_external’: net/ipv4/fib_trie.c:1572:6: warning: unused variable ‘found’ [-Wunused-variable] int found = 0; ^ net/ipv4/fib_trie.c:1571:16: warning: unused variable ‘slen’ [-Wunused-variable] unsigned char slen; ^ Signed-off-by: David S. Miller --- net/ipv4/fib_trie.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 6544f1a0cfa1..0131f369f5c9 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -1568,8 +1568,6 @@ void fib_table_flush_external(struct fib_table *tb) struct fib_alias *fa; struct tnode *n, *pn; unsigned long cindex; - unsigned char slen; - int found = 0; n = rcu_dereference(t->trie); if (!n) -- GitLab From 8ef46a672a7d852709561d10672b6eaa8a4acd82 Mon Sep 17 00:00:00 2001 From: Andy Lutomirski Date: Thu, 5 Mar 2015 19:19:02 -0800 Subject: [PATCH 02893/11651] x86/asm/entry: Add this_cpu_sp0() to read sp0 for the current cpu We currently store references to the top of the kernel stack in multiple places: kernel_stack (with an offset) and init_tss.x86_tss.sp0 (no offset). The latter is defined by hardware and is a clean canonical way to find the top of the stack. Add an accessor so we can start using it. This needs minor paravirt tweaks. On native, sp0 defines the top of the kernel stack and is therefore always correct. On Xen and lguest, the hypervisor tracks the top of the stack, but we want to start reading sp0 in the kernel. Fixing this is simple: just update our local copy of sp0 as well as the hypervisor's copy on task switches. Signed-off-by: Andy Lutomirski Cc: Boris Ostrovsky Cc: Borislav Petkov Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Konrad Rzeszutek Wilk Cc: Linus Torvalds Cc: Oleg Nesterov Cc: Rusty Russell Cc: Thomas Gleixner Link: http://lkml.kernel.org/r/8d675581859712bee09a055ed8f785d80dac1eca.1425611534.git.luto@amacapital.net Signed-off-by: Ingo Molnar --- arch/x86/include/asm/processor.h | 5 +++++ arch/x86/kernel/process.c | 1 + arch/x86/lguest/boot.c | 1 + arch/x86/xen/enlighten.c | 1 + 4 files changed, 8 insertions(+) diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 7be2c9a6caba..71c3a826a690 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -564,6 +564,11 @@ static inline void native_swapgs(void) #endif } +static inline unsigned long this_cpu_sp0(void) +{ + return this_cpu_read_stable(init_tss.x86_tss.sp0); +} + #ifdef CONFIG_PARAVIRT #include #else diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 046e2d620bbe..ff5c9088b1c5 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -38,6 +38,7 @@ * on exact cacheline boundaries, to eliminate cacheline ping-pong. */ __visible DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss) = INIT_TSS; +EXPORT_PER_CPU_SYMBOL_GPL(init_tss); #ifdef CONFIG_X86_64 static DEFINE_PER_CPU(unsigned char, is_idle); diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c index ac4453d8520e..8561585ee2c6 100644 --- a/arch/x86/lguest/boot.c +++ b/arch/x86/lguest/boot.c @@ -1076,6 +1076,7 @@ static void lguest_load_sp0(struct tss_struct *tss, { lazy_hcall3(LHCALL_SET_STACK, __KERNEL_DS | 0x1, thread->sp0, THREAD_SIZE / PAGE_SIZE); + tss->x86_tss.sp0 = thread->sp0; } /* Let's just say, I wouldn't do debugging under a Guest. */ diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 5240f563076d..81665c9f2132 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -912,6 +912,7 @@ static void xen_load_sp0(struct tss_struct *tss, mcs = xen_mc_entry(0); MULTI_stack_switch(mcs.mc, __KERNEL_DS, thread->sp0); xen_mc_issue(PARAVIRT_LAZY_CPU); + tss->x86_tss.sp0 = thread->sp0; } static void xen_set_iopl_mask(unsigned mask) -- GitLab From 75182b1632a89f12540baa1806a7c5c180db620c Mon Sep 17 00:00:00 2001 From: Andy Lutomirski Date: Thu, 5 Mar 2015 19:19:03 -0800 Subject: [PATCH 02894/11651] x86/asm/entry: Switch all C consumers of kernel_stack to this_cpu_sp0() This will make modifying the semantics of kernel_stack easier. The change to ist_begin_non_atomic() is necessary because sp0 no longer points to the same THREAD_SIZE-aligned region as RSP; it's one byte too high for that. At Denys' suggestion, rather than offsetting it, just check explicitly that we're in the correct range ending at sp0. This has the added benefit that we no longer assume that the thread stack is aligned to THREAD_SIZE. Suggested-by: Denys Vlasenko Signed-off-by: Andy Lutomirski Cc: Borislav Petkov Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Oleg Nesterov Cc: Thomas Gleixner Link: http://lkml.kernel.org/r/ef8254ad414cbb8034c9a56396eeb24f5dd5b0de.1425611534.git.luto@amacapital.net Signed-off-by: Ingo Molnar --- arch/x86/include/asm/thread_info.h | 3 +-- arch/x86/kernel/traps.c | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h index 1d4e4f279a32..a2fa1899494e 100644 --- a/arch/x86/include/asm/thread_info.h +++ b/arch/x86/include/asm/thread_info.h @@ -159,8 +159,7 @@ DECLARE_PER_CPU(unsigned long, kernel_stack); static inline struct thread_info *current_thread_info(void) { struct thread_info *ti; - ti = (void *)(this_cpu_read_stable(kernel_stack) + - KERNEL_STACK_OFFSET - THREAD_SIZE); + ti = (void *)(this_cpu_sp0() - THREAD_SIZE); return ti; } diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 9965bd1916db..fa290586ed37 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -174,8 +174,8 @@ void ist_begin_non_atomic(struct pt_regs *regs) * will catch asm bugs and any attempt to use ist_preempt_enable * from double_fault. */ - BUG_ON(((current_stack_pointer() ^ this_cpu_read_stable(kernel_stack)) - & ~(THREAD_SIZE - 1)) != 0); + BUG_ON((unsigned long)(this_cpu_sp0() - current_stack_pointer()) >= + THREAD_SIZE); preempt_count_sub(HARDIRQ_OFFSET); } -- GitLab From 9d0c914c60f4d3123debb653340dc1f7cf44939d Mon Sep 17 00:00:00 2001 From: Andy Lutomirski Date: Thu, 5 Mar 2015 19:19:04 -0800 Subject: [PATCH 02895/11651] x86/asm/entry/64/compat: Change the 32-bit sysenter code to use sp0 The ia32 sysenter code loaded the top of the kernel stack into rsp by loading kernel_stack and then adjusting it. It can be simplified to just read sp0 directly. This requires the addition of a new asm-offsets entry for sp0. Signed-off-by: Andy Lutomirski Cc: Borislav Petkov Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Oleg Nesterov Cc: Thomas Gleixner Link: http://lkml.kernel.org/r/88ff9006163d296a0665338585c36d9bfb85235d.1425611534.git.luto@amacapital.net Signed-off-by: Ingo Molnar --- arch/x86/ia32/ia32entry.S | 3 +-- arch/x86/kernel/asm-offsets_64.c | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S index ed9746340363..719db63b35c4 100644 --- a/arch/x86/ia32/ia32entry.S +++ b/arch/x86/ia32/ia32entry.S @@ -113,8 +113,7 @@ ENTRY(ia32_sysenter_target) CFI_DEF_CFA rsp,0 CFI_REGISTER rsp,rbp SWAPGS_UNSAFE_STACK - movq PER_CPU_VAR(kernel_stack), %rsp - addq $(KERNEL_STACK_OFFSET),%rsp + movq PER_CPU_VAR(init_tss + TSS_sp0), %rsp /* * No need to follow this irqs on/off section: the syscall * disabled irqs, here we enable it straight after entry: diff --git a/arch/x86/kernel/asm-offsets_64.c b/arch/x86/kernel/asm-offsets_64.c index fdcbb4d27c9f..5ce6f2da8763 100644 --- a/arch/x86/kernel/asm-offsets_64.c +++ b/arch/x86/kernel/asm-offsets_64.c @@ -81,6 +81,7 @@ int main(void) #undef ENTRY OFFSET(TSS_ist, tss_struct, x86_tss.ist); + OFFSET(TSS_sp0, tss_struct, x86_tss.sp0); BLANK(); DEFINE(__NR_syscall_max, sizeof(syscalls_64) - 1); -- GitLab From 24933b82c0d9a711475a5ef7904eb733f561e637 Mon Sep 17 00:00:00 2001 From: Andy Lutomirski Date: Thu, 5 Mar 2015 19:19:05 -0800 Subject: [PATCH 02896/11651] x86/asm/entry: Rename 'init_tss' to 'cpu_tss' It has nothing to do with init -- there's only one TSS per cpu. Other names considered include: - current_tss: Confusing because we never switch the tss. - singleton_tss: Too long. This patch was generated with 's/init_tss/cpu_tss/g'. Followup patches will fix INIT_TSS and INIT_TSS_IST by hand. Signed-off-by: Andy Lutomirski Cc: Borislav Petkov Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Oleg Nesterov Cc: Thomas Gleixner Link: http://lkml.kernel.org/r/da29fb2a793e4f649d93ce2d1ed320ebe8516262.1425611534.git.luto@amacapital.net Signed-off-by: Ingo Molnar --- arch/x86/ia32/ia32entry.S | 2 +- arch/x86/include/asm/processor.h | 4 ++-- arch/x86/kernel/cpu/common.c | 6 +++--- arch/x86/kernel/entry_64.S | 2 +- arch/x86/kernel/ioport.c | 2 +- arch/x86/kernel/process.c | 6 +++--- arch/x86/kernel/process_32.c | 2 +- arch/x86/kernel/process_64.c | 2 +- arch/x86/kernel/vm86_32.c | 4 ++-- arch/x86/power/cpu.c | 2 +- 10 files changed, 16 insertions(+), 16 deletions(-) diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S index 719db63b35c4..ad9efef65a6b 100644 --- a/arch/x86/ia32/ia32entry.S +++ b/arch/x86/ia32/ia32entry.S @@ -113,7 +113,7 @@ ENTRY(ia32_sysenter_target) CFI_DEF_CFA rsp,0 CFI_REGISTER rsp,rbp SWAPGS_UNSAFE_STACK - movq PER_CPU_VAR(init_tss + TSS_sp0), %rsp + movq PER_CPU_VAR(cpu_tss + TSS_sp0), %rsp /* * No need to follow this irqs on/off section: the syscall * disabled irqs, here we enable it straight after entry: diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 71c3a826a690..117ee65473e2 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -282,7 +282,7 @@ struct tss_struct { } ____cacheline_aligned; -DECLARE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss); +DECLARE_PER_CPU_SHARED_ALIGNED(struct tss_struct, cpu_tss); /* * Save the original ist values for checking stack pointers during debugging @@ -566,7 +566,7 @@ static inline void native_swapgs(void) static inline unsigned long this_cpu_sp0(void) { - return this_cpu_read_stable(init_tss.x86_tss.sp0); + return this_cpu_read_stable(cpu_tss.x86_tss.sp0); } #ifdef CONFIG_PARAVIRT diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 2346c95c6ab1..5d0f0cc7ea26 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -979,7 +979,7 @@ static void syscall32_cpu_init(void) void enable_sep_cpu(void) { int cpu = get_cpu(); - struct tss_struct *tss = &per_cpu(init_tss, cpu); + struct tss_struct *tss = &per_cpu(cpu_tss, cpu); if (!boot_cpu_has(X86_FEATURE_SEP)) { put_cpu(); @@ -1307,7 +1307,7 @@ void cpu_init(void) */ load_ucode_ap(); - t = &per_cpu(init_tss, cpu); + t = &per_cpu(cpu_tss, cpu); oist = &per_cpu(orig_ist, cpu); #ifdef CONFIG_NUMA @@ -1391,7 +1391,7 @@ void cpu_init(void) { int cpu = smp_processor_id(); struct task_struct *curr = current; - struct tss_struct *t = &per_cpu(init_tss, cpu); + struct tss_struct *t = &per_cpu(cpu_tss, cpu); struct thread_struct *thread = &curr->thread; wait_for_master_cpu(cpu); diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index 622ce4254893..0c00fd80249a 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -959,7 +959,7 @@ apicinterrupt IRQ_WORK_VECTOR \ /* * Exception entry points. */ -#define INIT_TSS_IST(x) PER_CPU_VAR(init_tss) + (TSS_ist + ((x) - 1) * 8) +#define INIT_TSS_IST(x) PER_CPU_VAR(cpu_tss) + (TSS_ist + ((x) - 1) * 8) .macro idtentry sym do_sym has_error_code:req paranoid=0 shift_ist=-1 ENTRY(\sym) diff --git a/arch/x86/kernel/ioport.c b/arch/x86/kernel/ioport.c index 4ddaf66ea35f..37dae792dbbe 100644 --- a/arch/x86/kernel/ioport.c +++ b/arch/x86/kernel/ioport.c @@ -54,7 +54,7 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on) * because the ->io_bitmap_max value must match the bitmap * contents: */ - tss = &per_cpu(init_tss, get_cpu()); + tss = &per_cpu(cpu_tss, get_cpu()); if (turn_on) bitmap_clear(t->io_bitmap_ptr, from, num); diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index ff5c9088b1c5..6f6087349231 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -37,8 +37,8 @@ * section. Since TSS's are completely CPU-local, we want them * on exact cacheline boundaries, to eliminate cacheline ping-pong. */ -__visible DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss) = INIT_TSS; -EXPORT_PER_CPU_SYMBOL_GPL(init_tss); +__visible DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, cpu_tss) = INIT_TSS; +EXPORT_PER_CPU_SYMBOL_GPL(cpu_tss); #ifdef CONFIG_X86_64 static DEFINE_PER_CPU(unsigned char, is_idle); @@ -110,7 +110,7 @@ void exit_thread(void) unsigned long *bp = t->io_bitmap_ptr; if (bp) { - struct tss_struct *tss = &per_cpu(init_tss, get_cpu()); + struct tss_struct *tss = &per_cpu(cpu_tss, get_cpu()); t->io_bitmap_ptr = NULL; clear_thread_flag(TIF_IO_BITMAP); diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index 603c4f99cb5a..d3460af3d27a 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c @@ -248,7 +248,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) struct thread_struct *prev = &prev_p->thread, *next = &next_p->thread; int cpu = smp_processor_id(); - struct tss_struct *tss = &per_cpu(init_tss, cpu); + struct tss_struct *tss = &per_cpu(cpu_tss, cpu); fpu_switch_t fpu; /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */ diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 854b5981b327..2cd562f96c1f 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -277,7 +277,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) struct thread_struct *prev = &prev_p->thread; struct thread_struct *next = &next_p->thread; int cpu = smp_processor_id(); - struct tss_struct *tss = &per_cpu(init_tss, cpu); + struct tss_struct *tss = &per_cpu(cpu_tss, cpu); unsigned fsindex, gsindex; fpu_switch_t fpu; diff --git a/arch/x86/kernel/vm86_32.c b/arch/x86/kernel/vm86_32.c index e8edcf52e069..fc9db6ef2a95 100644 --- a/arch/x86/kernel/vm86_32.c +++ b/arch/x86/kernel/vm86_32.c @@ -150,7 +150,7 @@ struct pt_regs *save_v86_state(struct kernel_vm86_regs *regs) do_exit(SIGSEGV); } - tss = &per_cpu(init_tss, get_cpu()); + tss = &per_cpu(cpu_tss, get_cpu()); current->thread.sp0 = current->thread.saved_sp0; current->thread.sysenter_cs = __KERNEL_CS; load_sp0(tss, ¤t->thread); @@ -318,7 +318,7 @@ static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk tsk->thread.saved_fs = info->regs32->fs; tsk->thread.saved_gs = get_user_gs(info->regs32); - tss = &per_cpu(init_tss, get_cpu()); + tss = &per_cpu(cpu_tss, get_cpu()); tsk->thread.sp0 = (unsigned long) &info->VM86_TSS_ESP0; if (cpu_has_sep) tsk->thread.sysenter_cs = 0; diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c index 3e32ed5648a0..757678fb26e1 100644 --- a/arch/x86/power/cpu.c +++ b/arch/x86/power/cpu.c @@ -134,7 +134,7 @@ static void do_fpu_end(void) static void fix_processor_context(void) { int cpu = smp_processor_id(); - struct tss_struct *t = &per_cpu(init_tss, cpu); + struct tss_struct *t = &per_cpu(cpu_tss, cpu); #ifdef CONFIG_X86_64 struct desc_struct *desc = get_cpu_gdt_table(cpu); tss_desc tss; -- GitLab From d0a0de21f82bbc1737ea3c831f018d0c2bc6b9c2 Mon Sep 17 00:00:00 2001 From: Andy Lutomirski Date: Thu, 5 Mar 2015 19:19:06 -0800 Subject: [PATCH 02897/11651] x86/asm/entry: Remove INIT_TSS and fold the definitions into 'cpu_tss' The INIT_TSS is unnecessary. Just define the initial TSS where 'cpu_tss' is defined. While we're at it, merge the 32-bit and 64-bit definitions. The only syntactic change is that 32-bit kernels were computing sp0 as long, but now they compute it as unsigned long. Verified by objdump: the contents and relocations of .data..percpu..shared_aligned are unchanged on 32-bit and 64-bit kernels. Signed-off-by: Andy Lutomirski Cc: Borislav Petkov Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Oleg Nesterov Cc: Thomas Gleixner Link: http://lkml.kernel.org/r/8fc39fa3f6c5d635e93afbdd1a0fe0678a6d7913.1425611534.git.luto@amacapital.net Signed-off-by: Ingo Molnar --- arch/x86/include/asm/processor.h | 20 -------------------- arch/x86/kernel/process.c | 20 +++++++++++++++++++- 2 files changed, 19 insertions(+), 21 deletions(-) diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 117ee65473e2..f5e3ec63767d 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -818,22 +818,6 @@ static inline void spin_lock_prefetch(const void *x) .io_bitmap_ptr = NULL, \ } -/* - * Note that the .io_bitmap member must be extra-big. This is because - * the CPU will access an additional byte beyond the end of the IO - * permission bitmap. The extra byte must be all 1 bits, and must - * be within the limit. - */ -#define INIT_TSS { \ - .x86_tss = { \ - .sp0 = sizeof(init_stack) + (long)&init_stack, \ - .ss0 = __KERNEL_DS, \ - .ss1 = __KERNEL_CS, \ - .io_bitmap_base = INVALID_IO_BITMAP_OFFSET, \ - }, \ - .io_bitmap = { [0 ... IO_BITMAP_LONGS] = ~0 }, \ -} - extern unsigned long thread_saved_pc(struct task_struct *tsk); #define THREAD_SIZE_LONGS (THREAD_SIZE/sizeof(unsigned long)) @@ -892,10 +876,6 @@ extern unsigned long thread_saved_pc(struct task_struct *tsk); .sp0 = (unsigned long)&init_stack + sizeof(init_stack) \ } -#define INIT_TSS { \ - .x86_tss.sp0 = (unsigned long)&init_stack + sizeof(init_stack) \ -} - /* * Return saved PC of a blocked thread. * What is this good for? it will be always the scheduler or ret_from_fork. diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 6f6087349231..f4c0af7fc3a0 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -37,7 +37,25 @@ * section. Since TSS's are completely CPU-local, we want them * on exact cacheline boundaries, to eliminate cacheline ping-pong. */ -__visible DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, cpu_tss) = INIT_TSS; +__visible DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, cpu_tss) = { + .x86_tss = { + .sp0 = (unsigned long)&init_stack + sizeof(init_stack), +#ifdef CONFIG_X86_32 + .ss0 = __KERNEL_DS, + .ss1 = __KERNEL_CS, + .io_bitmap_base = INVALID_IO_BITMAP_OFFSET, +#endif + }, +#ifdef CONFIG_X86_32 + /* + * Note that the .io_bitmap member must be extra-big. This is because + * the CPU will access an additional byte beyond the end of the IO + * permission bitmap. The extra byte must be all 1 bits, and must + * be within the limit. + */ + .io_bitmap = { [0 ... IO_BITMAP_LONGS] = ~0 }, +#endif +}; EXPORT_PER_CPU_SYMBOL_GPL(cpu_tss); #ifdef CONFIG_X86_64 -- GitLab From 9b47668843d800ed57f6f6bfd6f5c4cffdf201c6 Mon Sep 17 00:00:00 2001 From: Andy Lutomirski Date: Thu, 5 Mar 2015 19:19:07 -0800 Subject: [PATCH 02898/11651] x86/asm/entry: Rename 'INIT_TSS_IST' to 'CPU_TSS_IST' This has nothing to do with the init thread or the initial anything. It's just the CPU's TSS. Signed-off-by: Andy Lutomirski Cc: Borislav Petkov Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Oleg Nesterov Cc: Thomas Gleixner Link: http://lkml.kernel.org/r/a0bd5e26b32a2e1f08ff99017d0997118fbb2485.1425611534.git.luto@amacapital.net Signed-off-by: Ingo Molnar --- arch/x86/kernel/entry_64.S | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index 0c00fd80249a..5117a2baefe9 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -959,7 +959,7 @@ apicinterrupt IRQ_WORK_VECTOR \ /* * Exception entry points. */ -#define INIT_TSS_IST(x) PER_CPU_VAR(cpu_tss) + (TSS_ist + ((x) - 1) * 8) +#define CPU_TSS_IST(x) PER_CPU_VAR(cpu_tss) + (TSS_ist + ((x) - 1) * 8) .macro idtentry sym do_sym has_error_code:req paranoid=0 shift_ist=-1 ENTRY(\sym) @@ -1015,13 +1015,13 @@ ENTRY(\sym) .endif .if \shift_ist != -1 - subq $EXCEPTION_STKSZ, INIT_TSS_IST(\shift_ist) + subq $EXCEPTION_STKSZ, CPU_TSS_IST(\shift_ist) .endif call \do_sym .if \shift_ist != -1 - addq $EXCEPTION_STKSZ, INIT_TSS_IST(\shift_ist) + addq $EXCEPTION_STKSZ, CPU_TSS_IST(\shift_ist) .endif /* these procedures expect "no swapgs" flag in ebx */ -- GitLab From e893286918d2cde3a94850d8f7101cd1039e0c62 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 5 Mar 2015 09:13:31 +0100 Subject: [PATCH 02899/11651] x86/vdso: Fix the build on GCC5 On gcc5 the kernel does not link: ld: .eh_frame_hdr table[4] FDE at 0000000000000648 overlaps table[5] FDE at 0000000000000670. Because prior GCC versions always emitted NOPs on ALIGN directives, but gcc5 started omitting them. .LSTARTFDEDLSI1 says: /* HACK: The dwarf2 unwind routines will subtract 1 from the return address to get an address in the middle of the presumed call instruction. Since we didn't get here via a call, we need to include the nop before the real start to make up for it. */ .long .LSTART_sigreturn-1-. /* PC-relative start address */ But commit 69d0627a7f6e ("x86 vDSO: reorder vdso32 code") from 2.6.25 replaced .org __kernel_vsyscall+32,0x90 by ALIGN right before __kernel_sigreturn. Of course, ALIGN need not generate any NOP in there. Esp. gcc5 collapses vclock_gettime.o and int80.o together with no generated NOPs as "ALIGN". So fix this by adding to that point at least a single NOP and make the function ALIGN possibly with more NOPs then. Kudos for reporting and diagnosing should go to Richard. Reported-by: Richard Biener Signed-off-by: Jiri Slaby Acked-by: Andy Lutomirski Cc: Cc: Borislav Petkov Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Thomas Gleixner Link: http://lkml.kernel.org/r/1425543211-12542-1-git-send-email-jslaby@suse.cz Signed-off-by: Ingo Molnar --- arch/x86/vdso/vdso32/sigreturn.S | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/vdso/vdso32/sigreturn.S b/arch/x86/vdso/vdso32/sigreturn.S index 31776d0efc8c..d7ec4e251c0a 100644 --- a/arch/x86/vdso/vdso32/sigreturn.S +++ b/arch/x86/vdso/vdso32/sigreturn.S @@ -17,6 +17,7 @@ .text .globl __kernel_sigreturn .type __kernel_sigreturn,@function + nop /* this guy is needed for .LSTARTFDEDLSI1 below (watch for HACK) */ ALIGN __kernel_sigreturn: .LSTART_sigreturn: -- GitLab From 0c4ddcd214f5bc72713473e8383041ab7a2c6bb7 Mon Sep 17 00:00:00 2001 From: Ilan peer Date: Wed, 4 Mar 2015 00:32:05 -0500 Subject: [PATCH 02900/11651] cfg80211: Simplify the handling of regulatory indoor setting Directly update the indoor setting without wrapping it as a regulatory request, to simplify the processing. Acked-by: Luis R. Rodriguez Signed-off-by: Ilan Peer Signed-off-by: Johannes Berg --- net/wireless/reg.c | 34 +++------------------------------- 1 file changed, 3 insertions(+), 31 deletions(-) diff --git a/net/wireless/reg.c b/net/wireless/reg.c index b586d0dcb09e..c24c8bf3c988 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -82,17 +82,12 @@ * be intersected with the current one. * @REG_REQ_ALREADY_SET: the regulatory request will not change the current * regulatory settings, and no further processing is required. - * @REG_REQ_USER_HINT_HANDLED: a non alpha2 user hint was handled and no - * further processing is required, i.e., not need to update last_request - * etc. This should be used for user hints that do not provide an alpha2 - * but some other type of regulatory hint, i.e., indoor operation. */ enum reg_request_treatment { REG_REQ_OK, REG_REQ_IGNORE, REG_REQ_INTERSECT, REG_REQ_ALREADY_SET, - REG_REQ_USER_HINT_HANDLED, }; static struct regulatory_request core_request_world = { @@ -1248,13 +1243,6 @@ static bool reg_request_cell_base(struct regulatory_request *request) return request->user_reg_hint_type == NL80211_USER_REG_HINT_CELL_BASE; } -static bool reg_request_indoor(struct regulatory_request *request) -{ - if (request->initiator != NL80211_REGDOM_SET_BY_USER) - return false; - return request->user_reg_hint_type == NL80211_USER_REG_HINT_INDOOR; -} - bool reg_last_request_cell_base(void) { return reg_request_cell_base(get_last_request()); @@ -1833,11 +1821,6 @@ __reg_process_hint_user(struct regulatory_request *user_request) { struct regulatory_request *lr = get_last_request(); - if (reg_request_indoor(user_request)) { - reg_is_indoor = true; - return REG_REQ_USER_HINT_HANDLED; - } - if (reg_request_cell_base(user_request)) return reg_ignore_cell_hint(user_request); @@ -1885,8 +1868,7 @@ reg_process_hint_user(struct regulatory_request *user_request) treatment = __reg_process_hint_user(user_request); if (treatment == REG_REQ_IGNORE || - treatment == REG_REQ_ALREADY_SET || - treatment == REG_REQ_USER_HINT_HANDLED) { + treatment == REG_REQ_ALREADY_SET) { reg_free_request(user_request); return treatment; } @@ -1947,7 +1929,6 @@ reg_process_hint_driver(struct wiphy *wiphy, case REG_REQ_OK: break; case REG_REQ_IGNORE: - case REG_REQ_USER_HINT_HANDLED: reg_free_request(driver_request); return treatment; case REG_REQ_INTERSECT: @@ -2047,7 +2028,6 @@ reg_process_hint_country_ie(struct wiphy *wiphy, case REG_REQ_OK: break; case REG_REQ_IGNORE: - case REG_REQ_USER_HINT_HANDLED: /* fall through */ case REG_REQ_ALREADY_SET: reg_free_request(country_ie_request); @@ -2086,8 +2066,7 @@ static void reg_process_hint(struct regulatory_request *reg_request) case NL80211_REGDOM_SET_BY_USER: treatment = reg_process_hint_user(reg_request); if (treatment == REG_REQ_IGNORE || - treatment == REG_REQ_ALREADY_SET || - treatment == REG_REQ_USER_HINT_HANDLED) + treatment == REG_REQ_ALREADY_SET) return; queue_delayed_work(system_power_efficient_wq, ®_timeout, msecs_to_jiffies(3142)); @@ -2311,16 +2290,9 @@ int regulatory_hint_user(const char *alpha2, int regulatory_hint_indoor_user(void) { - struct regulatory_request *request; - request = kzalloc(sizeof(struct regulatory_request), GFP_KERNEL); - if (!request) - return -ENOMEM; - request->wiphy_idx = WIPHY_IDX_INVALID; - request->initiator = NL80211_REGDOM_SET_BY_USER; - request->user_reg_hint_type = NL80211_USER_REG_HINT_INDOOR; - queue_regulatory_request(request); + reg_is_indoor = true; return 0; } -- GitLab From 05050753602626ed4c46271c689929b625f409e7 Mon Sep 17 00:00:00 2001 From: Ilan peer Date: Wed, 4 Mar 2015 00:32:06 -0500 Subject: [PATCH 02901/11651] cfg80211: Add API to change the indoor regulatory setting Previously, the indoor setting configuration assumed that as long as a station interface is connected, the indoor environment setting does not change. However, this assumption is problematic as: - It is possible that a station interface is connected to a mobile AP, e.g., softAP or a P2P GO, where it is possible that both the station and the mobile AP move out of the indoor environment making the indoor setting invalid. In such a case, user space has no way to invalidate the setting. - A station interface disconnection does not necessarily imply that the device is no longer operating in an indoor environment, e.g., it is possible that the station interface is roaming but is still stays indoor. To handle the above, extend the indoor configuration API to allow user space to indicate a change of indoor settings, and allow it to indicate weather it controls the indoor setting, such that: 1. If the user space process explicitly indicates that it is going to control the indoor setting, do not clear the indoor setting internally, unless the socket is released. The user space process should use the NL80211_ATTR_SOCKET_OWNER attribute in the command to state that it is going to control the indoor setting. 2. Reset the indoor setting when restoring the regulatory settings in case it is not owned by a user space process. Based on the above, a user space tool that continuously monitors the indoor settings, i.e., tracking power setting, location etc., can indicate environment changes to the regulatory core. It should be noted that currently user space is the only provided mechanism used to hint to the regulatory core over the indoor/outdoor environment -- while the country IEs do have an environment setting this has been completely ignored by the regulatory core by design for a while now since country IEs typically can contain bogus data. Acked-by: Luis R. Rodriguez Signed-off-by: ArikX Nemtsov Signed-off-by: Ilan Peer Signed-off-by: Johannes Berg --- include/uapi/linux/nl80211.h | 9 ++++++ net/wireless/nl80211.c | 19 +++++++++++- net/wireless/reg.c | 57 +++++++++++++++++++++++++++++++++--- net/wireless/reg.h | 15 +++++++++- 4 files changed, 94 insertions(+), 6 deletions(-) diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index 37e7f39441e5..ae16ba9cb1e3 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -1697,6 +1697,10 @@ enum nl80211_commands { * If set during scheduled scan start then the new scan req will be * owned by the netlink socket that created it and the scheduled scan will * be stopped when the socket is closed. + * If set during configuration of regulatory indoor operation then the + * regulatory indoor configuration would be owned by the netlink socket + * that configured the indoor setting, and the indoor operation would be + * cleared when the socket is closed. * * @NL80211_ATTR_TDLS_INITIATOR: flag attribute indicating the current end is * the TDLS link initiator. @@ -1752,6 +1756,9 @@ enum nl80211_commands { * * @NL80211_ATTR_SCHED_SCAN_DELAY: delay before a scheduled scan (or a * WoWLAN net-detect scan) is started, u32 in seconds. + + * @NL80211_ATTR_REG_INDOOR: flag attribute, if set indicates that the device + * is operating in an indoor environment. * * @NUM_NL80211_ATTR: total number of nl80211_attrs available * @NL80211_ATTR_MAX: highest attribute number currently defined @@ -2120,6 +2127,8 @@ enum nl80211_attrs { NL80211_ATTR_SCHED_SCAN_DELAY, + NL80211_ATTR_REG_INDOOR, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 07cef3d7653e..b02085301785 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -399,6 +399,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = { [NL80211_ATTR_WIPHY_SELF_MANAGED_REG] = { .type = NLA_FLAG }, [NL80211_ATTR_NETNS_FD] = { .type = NLA_U32 }, [NL80211_ATTR_SCHED_SCAN_DELAY] = { .type = NLA_U32 }, + [NL80211_ATTR_REG_INDOOR] = { .type = NLA_FLAG }, }; /* policy for the key attributes */ @@ -4958,7 +4959,10 @@ static int parse_reg_rule(struct nlattr *tb[], static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info) { char *data = NULL; + bool is_indoor; enum nl80211_user_reg_hint_type user_reg_hint_type; + u32 owner_nlportid; + /* * You should only get this when cfg80211 hasn't yet initialized @@ -4984,7 +4988,15 @@ static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info) data = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]); return regulatory_hint_user(data, user_reg_hint_type); case NL80211_USER_REG_HINT_INDOOR: - return regulatory_hint_indoor_user(); + if (info->attrs[NL80211_ATTR_SOCKET_OWNER]) { + owner_nlportid = info->snd_portid; + is_indoor = !!info->attrs[NL80211_ATTR_REG_INDOOR]; + } else { + owner_nlportid = 0; + is_indoor = true; + } + + return regulatory_hint_indoor(is_indoor, owner_nlportid); default: return -EINVAL; } @@ -12810,6 +12822,11 @@ static int nl80211_netlink_notify(struct notifier_block * nb, rcu_read_unlock(); + /* + * It is possible that the user space process that is controlling the + * indoor setting disappeared, so notify the regulatory core. + */ + regulatory_netlink_notify(notify->portid); return NOTIFY_OK; } diff --git a/net/wireless/reg.c b/net/wireless/reg.c index c24c8bf3c988..4239dd408137 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -128,9 +128,12 @@ static int reg_num_devs_support_basehint; * State variable indicating if the platform on which the devices * are attached is operating in an indoor environment. The state variable * is relevant for all registered devices. - * (protected by RTNL) */ static bool reg_is_indoor; +static spinlock_t reg_indoor_lock; + +/* Used to track the userspace process controlling the indoor setting */ +static u32 reg_is_indoor_portid; static const struct ieee80211_regdomain *get_cfg80211_regdom(void) { @@ -2288,15 +2291,50 @@ int regulatory_hint_user(const char *alpha2, return 0; } -int regulatory_hint_indoor_user(void) +int regulatory_hint_indoor(bool is_indoor, u32 portid) { + spin_lock(®_indoor_lock); + + /* It is possible that more than one user space process is trying to + * configure the indoor setting. To handle such cases, clear the indoor + * setting in case that some process does not think that the device + * is operating in an indoor environment. In addition, if a user space + * process indicates that it is controlling the indoor setting, save its + * portid, i.e., make it the owner. + */ + reg_is_indoor = is_indoor; + if (reg_is_indoor) { + if (!reg_is_indoor_portid) + reg_is_indoor_portid = portid; + } else { + reg_is_indoor_portid = 0; + } + spin_unlock(®_indoor_lock); - reg_is_indoor = true; + if (!is_indoor) + reg_check_channels(); return 0; } +void regulatory_netlink_notify(u32 portid) +{ + spin_lock(®_indoor_lock); + + if (reg_is_indoor_portid != portid) { + spin_unlock(®_indoor_lock); + return; + } + + reg_is_indoor = false; + reg_is_indoor_portid = 0; + + spin_unlock(®_indoor_lock); + + reg_check_channels(); +} + /* Driver hints */ int regulatory_hint(struct wiphy *wiphy, const char *alpha2) { @@ -2464,7 +2502,17 @@ static void restore_regulatory_settings(bool reset_user) ASSERT_RTNL(); - reg_is_indoor = false; + /* + * Clear the indoor setting in case that it is not controlled by user + * space, as otherwise there is no guarantee that the device is still + * operating in an indoor environment. + */ + spin_lock(®_indoor_lock); + if (reg_is_indoor && !reg_is_indoor_portid) { + reg_is_indoor = false; + reg_check_channels(); + } + spin_unlock(®_indoor_lock); reset_regdomains(true, &world_regdom); restore_alpha2(alpha2, reset_user); @@ -3061,6 +3109,7 @@ int __init regulatory_init(void) spin_lock_init(®_requests_lock); spin_lock_init(®_pending_beacons_lock); + spin_lock_init(®_indoor_lock); reg_regdb_size_check(); diff --git a/net/wireless/reg.h b/net/wireless/reg.h index 4b45d6e61d24..a2c4e16459da 100644 --- a/net/wireless/reg.h +++ b/net/wireless/reg.h @@ -25,7 +25,20 @@ enum nl80211_dfs_regions reg_get_dfs_region(struct wiphy *wiphy); int regulatory_hint_user(const char *alpha2, enum nl80211_user_reg_hint_type user_reg_hint_type); -int regulatory_hint_indoor_user(void); + +/** + * regulatory_hint_indoor - hint operation in indoor env. or not + * @is_indoor: if true indicates that user space thinks that the + * device is operating in an indoor environment. + * @portid: the netlink port ID on which the hint was given. + */ +int regulatory_hint_indoor(bool is_indoor, u32 portid); + +/** + * regulatory_netlink_notify - notify on released netlink socket + * @portid: the netlink socket port ID + */ +void regulatory_netlink_notify(u32 portid); void wiphy_regulatory_register(struct wiphy *wiphy); void wiphy_regulatory_deregister(struct wiphy *wiphy); -- GitLab From eeca9fce1d71a4955855ceb0c3b13c1eb9db27c1 Mon Sep 17 00:00:00 2001 From: Ilan peer Date: Wed, 4 Mar 2015 00:32:07 -0500 Subject: [PATCH 02902/11651] cfg80211: Schedule timeout for all CRDA calls Timeout was scheduled only in case CRDA was called due to user hints, but was not scheduled for other cases. This can result in regulatory hint processing getting stuck in case that there is no CRDA configured. Change this by scheduling a timeout every time CRDA is called. In addition, in restore_regulatory_settings() all pending requests are restored (and not only the user ones). Signed-off-by: Ilan Peer Acked-by: Luis R. Rodriguez Signed-off-by: Johannes Berg --- net/wireless/reg.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 4239dd408137..d8671036c264 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -552,6 +552,9 @@ reg_call_crda(struct regulatory_request *request) { if (call_crda(request->alpha2)) return REG_REQ_IGNORE; + + queue_delayed_work(system_power_efficient_wq, + ®_timeout, msecs_to_jiffies(3142)); return REG_REQ_OK; } @@ -1791,8 +1794,7 @@ static void reg_set_request_processed(void) need_more_processing = true; spin_unlock(®_requests_lock); - if (lr->initiator == NL80211_REGDOM_SET_BY_USER) - cancel_delayed_work(®_timeout); + cancel_delayed_work(®_timeout); if (need_more_processing) schedule_work(®_work); @@ -2071,8 +2073,6 @@ static void reg_process_hint(struct regulatory_request *reg_request) if (treatment == REG_REQ_IGNORE || treatment == REG_REQ_ALREADY_SET) return; - queue_delayed_work(system_power_efficient_wq, - ®_timeout, msecs_to_jiffies(3142)); return; case NL80211_REGDOM_SET_BY_DRIVER: if (!wiphy) @@ -2496,7 +2496,6 @@ static void restore_regulatory_settings(bool reset_user) char alpha2[2]; char world_alpha2[2]; struct reg_beacon *reg_beacon, *btmp; - struct regulatory_request *reg_request, *tmp; LIST_HEAD(tmp_reg_req_list); struct cfg80211_registered_device *rdev; @@ -2524,11 +2523,7 @@ static void restore_regulatory_settings(bool reset_user) * settings. */ spin_lock(®_requests_lock); - list_for_each_entry_safe(reg_request, tmp, ®_requests_list, list) { - if (reg_request->initiator != NL80211_REGDOM_SET_BY_USER) - continue; - list_move_tail(®_request->list, &tmp_reg_req_list); - } + list_splice_tail_init(®_requests_list, &tmp_reg_req_list); spin_unlock(®_requests_lock); /* Clear beacon hints */ -- GitLab From 5e9444d9a00f4b22ad676f2d9d4b69312871e429 Mon Sep 17 00:00:00 2001 From: Robert ABEL Date: Fri, 27 Feb 2015 16:56:48 +0100 Subject: [PATCH 02903/11651] ARM OMAP2+ GPMC: don't undef DEBUG OMAP2+ GPMC driver undefines DEBUG, which makes it unnecessarily hard to turn DEBUG on. Remove the offending lines. Signed-off-by: Robert ABEL Acked-by: Tony Lindgren Signed-off-by: Roger Quadros --- drivers/memory/omap-gpmc.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c index db77adb236ae..624dccb0f002 100644 --- a/drivers/memory/omap-gpmc.c +++ b/drivers/memory/omap-gpmc.c @@ -12,8 +12,6 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ -#undef DEBUG - #include #include #include -- GitLab From d32efe37966474b9d18a9110c89c091abef75602 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 13 Feb 2015 21:04:42 +0800 Subject: [PATCH 02904/11651] gpio: vf610: Replaces comma between expression statements by semicolon Signed-off-by: Axel Lin Signed-off-by: Linus Walleij --- drivers/gpio/gpio-vf610.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/gpio/gpio-vf610.c b/drivers/gpio/gpio-vf610.c index 971c73964ef1..7bd9f209ffa8 100644 --- a/drivers/gpio/gpio-vf610.c +++ b/drivers/gpio/gpio-vf610.c @@ -244,16 +244,16 @@ static int vf610_gpio_probe(struct platform_device *pdev) gc = &port->gc; gc->of_node = np; gc->dev = dev; - gc->label = "vf610-gpio", - gc->ngpio = VF610_GPIO_PER_PORT, + gc->label = "vf610-gpio"; + gc->ngpio = VF610_GPIO_PER_PORT; gc->base = of_alias_get_id(np, "gpio") * VF610_GPIO_PER_PORT; - gc->request = vf610_gpio_request, - gc->free = vf610_gpio_free, - gc->direction_input = vf610_gpio_direction_input, - gc->get = vf610_gpio_get, - gc->direction_output = vf610_gpio_direction_output, - gc->set = vf610_gpio_set, + gc->request = vf610_gpio_request; + gc->free = vf610_gpio_free; + gc->direction_input = vf610_gpio_direction_input; + gc->get = vf610_gpio_get; + gc->direction_output = vf610_gpio_direction_output; + gc->set = vf610_gpio_set; ret = gpiochip_add(gc); if (ret < 0) -- GitLab From b1dc1ca9d4673dac43b8a77a8b695ffb2918de2a Mon Sep 17 00:00:00 2001 From: Robert ABEL Date: Fri, 27 Feb 2015 16:56:49 +0100 Subject: [PATCH 02905/11651] ARM OMAP2+ GPMC: add bus children This patch adds support for spawning buses as children of the GPMC. Signed-off-by: Robert ABEL Acked-by: Tony Lindgren Signed-off-by: Roger Quadros --- drivers/memory/omap-gpmc.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c index 624dccb0f002..91b5a1b9b9c2 100644 --- a/drivers/memory/omap-gpmc.c +++ b/drivers/memory/omap-gpmc.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -1812,8 +1813,21 @@ static int gpmc_probe_generic_child(struct platform_device *pdev, gpmc_cs_enable_mem(cs); no_timings: - if (of_platform_device_create(child, NULL, &pdev->dev)) - return 0; + + /* create platform device, NULL on error or when disabled */ + if (!of_platform_device_create(child, NULL, &pdev->dev)) + goto err_child_fail; + + /* is child a common bus? */ + if (of_match_node(of_default_bus_match_table, child)) + /* create children and other common bus children */ + if (of_platform_populate(child, of_default_bus_match_table, + NULL, &pdev->dev)) + goto err_child_fail; + + return 0; + +err_child_fail: dev_err(&pdev->dev, "failed to create gpmc child %s\n", child->name); ret = -ENODEV; -- GitLab From 2affc816df6163c063d47f722191aa3bc542c22a Mon Sep 17 00:00:00 2001 From: Robert ABEL Date: Fri, 27 Feb 2015 16:56:50 +0100 Subject: [PATCH 02906/11651] ARM OMAP2+ GPMC: fix debug output alignment GPMC debug output is aligned to 10 characters for field names. However, some fields have bigger names, screwing up the alignment. Consequently, alignment was changed to longest field name (17 chars) for now. Signed-off-by: Robert ABEL Acked-by: Tony Lindgren Signed-off-by: Roger Quadros --- drivers/memory/omap-gpmc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c index 91b5a1b9b9c2..92898687181c 100644 --- a/drivers/memory/omap-gpmc.c +++ b/drivers/memory/omap-gpmc.c @@ -491,7 +491,7 @@ static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit, l = gpmc_cs_read_reg(cs, reg); #ifdef DEBUG printk(KERN_INFO - "GPMC CS%d: %-10s: %3d ticks, %3lu ns (was %3i ticks) %3d ns\n", + "GPMC CS%d: %-17s: %3d ticks, %3lu ns (was %3i ticks) %3d ns\n", cs, name, ticks, gpmc_get_fclk_period() * ticks / 1000, (l >> st_bit) & mask, time); #endif -- GitLab From 66e618857ca46433741bf97ceca1b425387400b1 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 6 Mar 2015 09:07:32 +0200 Subject: [PATCH 02907/11651] ASoC: davinci-mcasp: Fix compilation error Introduced by commit: 6afda7f50754 ASoC: davinci-mcasp: Allow complete shutdown of McASP when not in use I'm really sorry for this... Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/davinci/davinci-mcasp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 33cea0728cd2..d40b392b3da2 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -1058,7 +1058,7 @@ static int davinci_mcasp_suspend(struct snd_soc_dai *dai) u32 reg; int i; - context->pm_state = pm_runtime_enabled(mcasp->dev) + context->pm_state = pm_runtime_enabled(mcasp->dev); if (!context->pm_state) pm_runtime_get_sync(mcasp->dev); -- GitLab From 563dbb260d74dbd49d66f9a07e0311563c62c8ff Mon Sep 17 00:00:00 2001 From: Robert ABEL Date: Fri, 27 Feb 2015 16:56:51 +0100 Subject: [PATCH 02908/11651] ARM OMAP2+ GPMC: change get_gpmc_timing_reg output for DTS DTS output was formatted to require additional work when copy-pasting into DTS. Nano-second timings were replaced with interval of values that produce the same number of clock ticks. Signed-off-by: Robert ABEL Acked-by: Tony Lindgren Signed-off-by: Roger Quadros --- drivers/memory/omap-gpmc.c | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c index 92898687181c..6a35971cb724 100644 --- a/drivers/memory/omap-gpmc.c +++ b/drivers/memory/omap-gpmc.c @@ -346,32 +346,50 @@ static void gpmc_cs_bool_timings(int cs, const struct gpmc_bool_timings *p) } #ifdef DEBUG +/** + * get_gpmc_timing_reg - read a timing parameter and print DTS settings for it. + * @cs: Chip Select Region + * @reg: GPMC_CS_CONFIGn register offset. + * @st_bit: Start Bit + * @end_bit: End Bit. Must be >= @st_bit. + * @name: DTS node name, w/o "gpmc," + * @raw: Raw Format Option. + * raw format: gpmc,name = + * tick format: gpmc,name = /‍* x ns -- y ns; x ticks *‍/ + * Where x ns -- y ns result in the same tick value. + * @noval: Parameter values equal to 0 are not printed. + * @shift: Parameter value left shifts @shift, which is then printed instead of value. + * @return: Specified timing parameter (after optional @shift). + * + */ static int get_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit, bool raw, bool noval, int shift, const char *name) { u32 l; - int nr_bits, max_value, mask; + int nr_bits; + int mask; l = gpmc_cs_read_reg(cs, reg); nr_bits = end_bit - st_bit + 1; - max_value = (1 << nr_bits) - 1; - mask = max_value << st_bit; - l = (l & mask) >> st_bit; + mask = (1 << nr_bits) - 1; + l = (l >> st_bit) & mask; if (shift) l = (shift << l); if (noval && (l == 0)) return 0; if (!raw) { - unsigned int time_ns_min, time_ns, time_ns_max; + /* DTS tick format for timings in ns */ + unsigned int time_ns; + unsigned int time_ns_min = 0; - time_ns_min = gpmc_ticks_to_ns(l ? l - 1 : 0); + if (l) + time_ns_min = gpmc_ticks_to_ns(l - 1) + 1; time_ns = gpmc_ticks_to_ns(l); - time_ns_max = gpmc_ticks_to_ns(l + 1 > max_value ? - max_value : l + 1); - pr_info("gpmc,%s = <%u> (%u - %u ns, %i ticks)\n", - name, time_ns, time_ns_min, time_ns_max, l); + pr_info("gpmc,%s = <%u> /* %u ns - %u ns; %i ticks */\n", + name, time_ns, time_ns_min, time_ns, l); } else { + /* raw format */ pr_info("gpmc,%s = <%u>\n", name, l); } -- GitLab From f585070b91950a0269eb20f497cceeee0aeefe0e Mon Sep 17 00:00:00 2001 From: Robert ABEL Date: Fri, 27 Feb 2015 16:56:52 +0100 Subject: [PATCH 02909/11651] ARM OMAP2+ GPMC: always program GPMCFCLKDIVIDER The WAITMONITORINGTIME is expressed as a number of GPMC_CLK clock cycles, even though the access is defined as asynchronous, and no GPMC_CLK clock is provided to the external device. Still, GPMCFCLKDIVIDER is used as a divider for the GPMC clock, so it must be programmed to define the correct WAITMONITORINGTIME delay. Signed-off-by: Robert ABEL Acked-by: Tony Lindgren Signed-off-by: Roger Quadros --- drivers/memory/omap-gpmc.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c index 6a35971cb724..5c36ff397b73 100644 --- a/drivers/memory/omap-gpmc.c +++ b/drivers/memory/omap-gpmc.c @@ -508,7 +508,7 @@ static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit, l = gpmc_cs_read_reg(cs, reg); #ifdef DEBUG - printk(KERN_INFO + pr_info( "GPMC CS%d: %-17s: %3d ticks, %3lu ns (was %3i ticks) %3d ns\n", cs, name, ticks, gpmc_get_fclk_period() * ticks / 1000, (l >> st_bit) & mask, time); @@ -580,19 +580,14 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t) if (gpmc_capability & GPMC_HAS_WR_ACCESS) GPMC_SET_ONE(GPMC_CS_CONFIG6, 24, 28, wr_access); - /* caller is expected to have initialized CONFIG1 to cover - * at least sync vs async - */ l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); - if (l & (GPMC_CONFIG1_READTYPE_SYNC | GPMC_CONFIG1_WRITETYPE_SYNC)) { #ifdef DEBUG - printk(KERN_INFO "GPMC CS%d CLK period is %lu ns (div %d)\n", - cs, (div * gpmc_get_fclk_period()) / 1000, div); + pr_info("GPMC CS%d CLK period is %lu ns (div %d)\n", + cs, (div * gpmc_get_fclk_period()) / 1000, div); #endif - l &= ~0x03; - l |= (div - 1); - gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, l); - } + l &= ~0x03; + l |= (div - 1); + gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, l); gpmc_cs_bool_timings(cs, &t->bool_timings); gpmc_cs_show_timings(cs, "after gpmc_cs_set_timings"); -- GitLab From 2e67690137f3a7bac660edd548f8846709c55381 Mon Sep 17 00:00:00 2001 From: Robert ABEL Date: Fri, 27 Feb 2015 16:56:53 +0100 Subject: [PATCH 02910/11651] ARM OMAP2+ GPMC: calculate GPMCFCLKDIVIDER based on WAITMONITORINGTIME The WAITMONITORINGTIME is expressed as a number of GPMC_CLK clock cycles, even though the access is defined as asynchronous, and no GPMC_CLK clock is provided to the external device. Still, GPMCFCLKDIVIDER is used as a divider for the GPMC clock, so it must be programmed to define the correct WAITMONITORINGTIME delay. Calculate GPMCFCLKDIVIDER independent of gpmc,sync-clk-ps in DT for pure asynchronous accesses, i.e. both read and write asynchronous. Signed-off-by: Robert ABEL Acked-by: Tony Lindgren Signed-off-by: Roger Quadros --- arch/arm/mach-omap2/gpmc-nand.c | 18 ++++--- arch/arm/mach-omap2/gpmc-onenand.c | 4 +- arch/arm/mach-omap2/usb-tusb6010.c | 4 +- drivers/memory/omap-gpmc.c | 86 +++++++++++++++++++++++++++--- include/linux/omap-gpmc.h | 3 +- 5 files changed, 95 insertions(+), 20 deletions(-) diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c index d5951b17b736..72918c4973ea 100644 --- a/arch/arm/mach-omap2/gpmc-nand.c +++ b/arch/arm/mach-omap2/gpmc-nand.c @@ -96,14 +96,6 @@ int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data, gpmc_nand_res[1].start = gpmc_get_client_irq(GPMC_IRQ_FIFOEVENTENABLE); gpmc_nand_res[2].start = gpmc_get_client_irq(GPMC_IRQ_COUNT_EVENT); - if (gpmc_t) { - err = gpmc_cs_set_timings(gpmc_nand_data->cs, gpmc_t); - if (err < 0) { - pr_err("omap2-gpmc: Unable to set gpmc timings: %d\n", err); - return err; - } - } - memset(&s, 0, sizeof(struct gpmc_settings)); if (gpmc_nand_data->of_node) gpmc_read_settings_dt(gpmc_nand_data->of_node, &s); @@ -111,6 +103,16 @@ int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data, gpmc_set_legacy(gpmc_nand_data, &s); s.device_nand = true; + + if (gpmc_t) { + err = gpmc_cs_set_timings(gpmc_nand_data->cs, gpmc_t, &s); + if (err < 0) { + pr_err("omap2-gpmc: Unable to set gpmc timings: %d\n", + err); + return err; + } + } + err = gpmc_cs_program_settings(gpmc_nand_data->cs, &s); if (err < 0) goto out_free_cs; diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c index 53d197e0c1f3..f899e77ff5e6 100644 --- a/arch/arm/mach-omap2/gpmc-onenand.c +++ b/arch/arm/mach-omap2/gpmc-onenand.c @@ -293,7 +293,7 @@ static int omap2_onenand_setup_async(void __iomem *onenand_base) if (ret < 0) return ret; - ret = gpmc_cs_set_timings(gpmc_onenand_data->cs, &t); + ret = gpmc_cs_set_timings(gpmc_onenand_data->cs, &t, &onenand_async); if (ret < 0) return ret; @@ -331,7 +331,7 @@ static int omap2_onenand_setup_sync(void __iomem *onenand_base, int *freq_ptr) if (ret < 0) return ret; - ret = gpmc_cs_set_timings(gpmc_onenand_data->cs, &t); + ret = gpmc_cs_set_timings(gpmc_onenand_data->cs, &t, &onenand_sync); if (ret < 0) return ret; diff --git a/arch/arm/mach-omap2/usb-tusb6010.c b/arch/arm/mach-omap2/usb-tusb6010.c index 8333400898fb..e554d9e66a1c 100644 --- a/arch/arm/mach-omap2/usb-tusb6010.c +++ b/arch/arm/mach-omap2/usb-tusb6010.c @@ -71,7 +71,7 @@ static int tusb_set_async_mode(unsigned sysclk_ps) gpmc_calc_timings(&t, &tusb_async, &dev_t); - return gpmc_cs_set_timings(async_cs, &t); + return gpmc_cs_set_timings(async_cs, &t, &tusb_async); } static int tusb_set_sync_mode(unsigned sysclk_ps) @@ -98,7 +98,7 @@ static int tusb_set_sync_mode(unsigned sysclk_ps) gpmc_calc_timings(&t, &tusb_sync, &dev_t); - return gpmc_cs_set_timings(sync_cs, &t); + return gpmc_cs_set_timings(sync_cs, &t, &tusb_sync); } /* tusb driver calls this when it changes the chip's clocking */ diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c index 5c36ff397b73..768bab233196 100644 --- a/drivers/memory/omap-gpmc.c +++ b/drivers/memory/omap-gpmc.c @@ -138,7 +138,9 @@ #define GPMC_CONFIG1_PAGE_LEN(val) ((val & 3) << 23) #define GPMC_CONFIG1_WAIT_READ_MON (1 << 22) #define GPMC_CONFIG1_WAIT_WRITE_MON (1 << 21) -#define GPMC_CONFIG1_WAIT_MON_IIME(val) ((val & 3) << 18) +#define GPMC_CONFIG1_WAIT_MON_TIME(val) ((val & 3) << 18) +/** WAITMONITORINGTIME Max Ticks */ +#define GPMC_CONFIG1_WAITMONITORINGTIME_MAX 2 #define GPMC_CONFIG1_WAIT_PIN_SEL(val) ((val & 3) << 16) #define GPMC_CONFIG1_DEVICESIZE(val) ((val & 3) << 12) #define GPMC_CONFIG1_DEVICESIZE_16 GPMC_CONFIG1_DEVICESIZE(1) @@ -525,13 +527,48 @@ static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit, t->field, #field) < 0) \ return -1 +/** + * gpmc_calc_waitmonitoring_divider - calculate proper GPMCFCLKDIVIDER based on WAITMONITORINGTIME + * WAITMONITORINGTIME will be _at least_ as long as desired, i.e. + * read --> don't sample bus too early + * write --> data is longer on bus + * + * Formula: + * gpmc_clk_div + 1 = ceil(ceil(waitmonitoringtime_ns / gpmc_fclk_ns) + * / waitmonitoring_ticks) + * WAITMONITORINGTIME resulting in 0 or 1 tick with div = 1 are caught by + * div <= 0 check. + * + * @wait_monitoring: WAITMONITORINGTIME in ns. + * @return: -1 on failure to scale, else proper divider > 0. + */ +static int gpmc_calc_waitmonitoring_divider(unsigned int wait_monitoring) +{ + + int div = gpmc_ns_to_ticks(wait_monitoring); + + div += GPMC_CONFIG1_WAITMONITORINGTIME_MAX - 1; + div /= GPMC_CONFIG1_WAITMONITORINGTIME_MAX; + + if (div > 4) + return -1; + if (div <= 0) + div = 1; + + return div; + +} + +/** + * gpmc_calc_divider - calculate GPMC_FCLK divider for sync_clk GPMC_CLK period. + * @sync_clk: GPMC_CLK period in ps. + * @return: Returns at least 1 if GPMC_FCLK can be divided to GPMC_CLK. + * Else, returns -1. + */ int gpmc_calc_divider(unsigned int sync_clk) { - int div; - u32 l; + int div = gpmc_ps_to_ticks(sync_clk); - l = sync_clk + (gpmc_get_fclk_period() - 1); - div = l / gpmc_get_fclk_period(); if (div > 4) return -1; if (div <= 0) @@ -540,7 +577,15 @@ int gpmc_calc_divider(unsigned int sync_clk) return div; } -int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t) +/** + * gpmc_cs_set_timings - program timing parameters for Chip Select Region. + * @cs: Chip Select Region. + * @t: GPMC timing parameters. + * @s: GPMC timing settings. + * @return: 0 on success, -1 on error. + */ +int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t, + const struct gpmc_settings *s) { int div; u32 l; @@ -550,6 +595,33 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t) if (div < 0) return div; + /* + * See if we need to change the divider for waitmonitoringtime. + * + * Calculate GPMCFCLKDIVIDER independent of gpmc,sync-clk-ps in DT for + * pure asynchronous accesses, i.e. both read and write asynchronous. + * However, only do so if WAITMONITORINGTIME is actually used, i.e. + * either WAITREADMONITORING or WAITWRITEMONITORING is set. + * + * This statement must not change div to scale async WAITMONITORINGTIME + * to protect mixed synchronous and asynchronous accesses. + * + * We raise an error later if WAITMONITORINGTIME does not fit. + */ + if (!s->sync_read && !s->sync_write && + (s->wait_on_read || s->wait_on_write) + ) { + + div = gpmc_calc_waitmonitoring_divider(t->wait_monitoring); + if (div < 0) { + pr_err("%s: waitmonitoringtime %3d ns too large for greatest gpmcfclkdivider.\n", + __func__, + t->wait_monitoring + ); + return -1; + } + } + GPMC_SET_ONE(GPMC_CS_CONFIG2, 0, 3, cs_on); GPMC_SET_ONE(GPMC_CS_CONFIG2, 8, 12, cs_rd_off); GPMC_SET_ONE(GPMC_CS_CONFIG2, 16, 20, cs_wr_off); @@ -1810,7 +1882,7 @@ static int gpmc_probe_generic_child(struct platform_device *pdev, if (ret < 0) goto err; - ret = gpmc_cs_set_timings(cs, &gpmc_t); + ret = gpmc_cs_set_timings(cs, &gpmc_t, &gpmc_s); if (ret) { dev_err(&pdev->dev, "failed to set gpmc timings for: %s\n", child->name); diff --git a/include/linux/omap-gpmc.h b/include/linux/omap-gpmc.h index c2080eebbb47..7dee00143afd 100644 --- a/include/linux/omap-gpmc.h +++ b/include/linux/omap-gpmc.h @@ -163,7 +163,8 @@ extern unsigned int gpmc_ticks_to_ns(unsigned int ticks); extern void gpmc_cs_write_reg(int cs, int idx, u32 val); extern int gpmc_calc_divider(unsigned int sync_clk); -extern int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t); +extern int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t, + const struct gpmc_settings *s); extern int gpmc_cs_program_settings(int cs, struct gpmc_settings *p); extern int gpmc_cs_request(int cs, unsigned long size, unsigned long *base); extern void gpmc_cs_free(int cs); -- GitLab From 7f2e8c58ae9e35240e5924c63163c07a506d0d12 Mon Sep 17 00:00:00 2001 From: Robert ABEL Date: Fri, 27 Feb 2015 16:56:54 +0100 Subject: [PATCH 02911/11651] ARM OMAP2+ GPMC: fix WAITMONITORINGTIME divider bug The WAITMONITORINGTIME is expressed as a number of GPMC_CLK clock cycles, even though the access is defined as asynchronous, and no GPMC_CLK clock is provided to the external device. Still, GPMCFCLKDIVIDER is used as a divider for the GPMC clock, so it must be programmed to define the correct WAITMONITORINGTIME delay. This patch correctly computes WAITMONITORINGTIME in GPMC_CLK cycles instead of GPMC_FCLK cycles, both during programming (gpmc_cs_set_timings) and during retrieval (gpmc_cs_show_timings). Signed-off-by: Robert ABEL Acked-by: Tony Lindgren Signed-off-by: Roger Quadros --- drivers/memory/omap-gpmc.c | 130 +++++++++++++++++++++++++++++-------- 1 file changed, 103 insertions(+), 27 deletions(-) diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c index 768bab233196..6c076b7c9b6f 100644 --- a/drivers/memory/omap-gpmc.c +++ b/drivers/memory/omap-gpmc.c @@ -179,6 +179,11 @@ */ #define GPMC_NR_IRQ 2 +enum gpmc_clk_domain { + GPMC_CD_FCLK, + GPMC_CD_CLK +}; + struct gpmc_cs_data { const char *name; @@ -277,16 +282,55 @@ static unsigned long gpmc_get_fclk_period(void) return rate; } -static unsigned int gpmc_ns_to_ticks(unsigned int time_ns) +/** + * gpmc_get_clk_period - get period of selected clock domain in ps + * @cs Chip Select Region. + * @cd Clock Domain. + * + * GPMC_CS_CONFIG1 GPMCFCLKDIVIDER for cs has to be setup + * prior to calling this function with GPMC_CD_CLK. + */ +static unsigned long gpmc_get_clk_period(int cs, enum gpmc_clk_domain cd) +{ + + unsigned long tick_ps = gpmc_get_fclk_period(); + u32 l; + int div; + + switch (cd) { + case GPMC_CD_CLK: + /* get current clk divider */ + l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); + div = (l & 0x03) + 1; + /* get GPMC_CLK period */ + tick_ps *= div; + break; + case GPMC_CD_FCLK: + /* FALL-THROUGH */ + default: + break; + } + + return tick_ps; + +} + +static unsigned int gpmc_ns_to_clk_ticks(unsigned int time_ns, int cs, + enum gpmc_clk_domain cd) { unsigned long tick_ps; /* Calculate in picosecs to yield more exact results */ - tick_ps = gpmc_get_fclk_period(); + tick_ps = gpmc_get_clk_period(cs, cd); return (time_ns * 1000 + tick_ps - 1) / tick_ps; } +static unsigned int gpmc_ns_to_ticks(unsigned int time_ns) +{ + return gpmc_ns_to_clk_ticks(time_ns, /* any CS */ 0, GPMC_CD_FCLK); +} + static unsigned int gpmc_ps_to_ticks(unsigned int time_ps) { unsigned long tick_ps; @@ -297,9 +341,15 @@ static unsigned int gpmc_ps_to_ticks(unsigned int time_ps) return (time_ps + tick_ps - 1) / tick_ps; } +unsigned int gpmc_clk_ticks_to_ns(unsigned ticks, int cs, + enum gpmc_clk_domain cd) +{ + return ticks * gpmc_get_clk_period(cs, cd) / 1000; +} + unsigned int gpmc_ticks_to_ns(unsigned int ticks) { - return ticks * gpmc_get_fclk_period() / 1000; + return gpmc_clk_ticks_to_ns(ticks, /* any CS */ 0, GPMC_CD_FCLK); } static unsigned int gpmc_ticks_to_ps(unsigned int ticks) @@ -355,18 +405,24 @@ static void gpmc_cs_bool_timings(int cs, const struct gpmc_bool_timings *p) * @st_bit: Start Bit * @end_bit: End Bit. Must be >= @st_bit. * @name: DTS node name, w/o "gpmc," + * @cd: Clock Domain of timing parameter. + * @shift: Parameter value left shifts @shift, which is then printed instead of value. * @raw: Raw Format Option. * raw format: gpmc,name = * tick format: gpmc,name = /‍* x ns -- y ns; x ticks *‍/ * Where x ns -- y ns result in the same tick value. * @noval: Parameter values equal to 0 are not printed. - * @shift: Parameter value left shifts @shift, which is then printed instead of value. * @return: Specified timing parameter (after optional @shift). * */ -static int get_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit, - bool raw, bool noval, int shift, - const char *name) +static int get_gpmc_timing_reg( + /* timing specifiers */ + int cs, int reg, int st_bit, int end_bit, + const char *name, const enum gpmc_clk_domain cd, + /* value transform */ + int shift, + /* format specifiers */ + bool raw, bool noval) { u32 l; int nr_bits; @@ -386,8 +442,8 @@ static int get_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit, unsigned int time_ns_min = 0; if (l) - time_ns_min = gpmc_ticks_to_ns(l - 1) + 1; - time_ns = gpmc_ticks_to_ns(l); + time_ns_min = gpmc_clk_ticks_to_ns(l - 1, cs, cd) + 1; + time_ns = gpmc_clk_ticks_to_ns(l, cs, cd); pr_info("gpmc,%s = <%u> /* %u ns - %u ns; %i ticks */\n", name, time_ns, time_ns_min, time_ns, l); } else { @@ -402,13 +458,15 @@ static int get_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit, pr_info("cs%i %s: 0x%08x\n", cs, #config, \ gpmc_cs_read_reg(cs, config)) #define GPMC_GET_RAW(reg, st, end, field) \ - get_gpmc_timing_reg(cs, (reg), (st), (end), 1, 0, 0, field) + get_gpmc_timing_reg(cs, (reg), (st), (end), field, GPMC_CD_FCLK, 0, 1, 0) #define GPMC_GET_RAW_BOOL(reg, st, end, field) \ - get_gpmc_timing_reg(cs, (reg), (st), (end), 1, 1, 0, field) + get_gpmc_timing_reg(cs, (reg), (st), (end), field, GPMC_CD_FCLK, 0, 1, 1) #define GPMC_GET_RAW_SHIFT(reg, st, end, shift, field) \ - get_gpmc_timing_reg(cs, (reg), (st), (end), 1, 1, (shift), field) + get_gpmc_timing_reg(cs, (reg), (st), (end), field, GPMC_CD_FCLK, (shift), 1, 1) #define GPMC_GET_TICKS(reg, st, end, field) \ - get_gpmc_timing_reg(cs, (reg), (st), (end), 0, 0, 0, field) + get_gpmc_timing_reg(cs, (reg), (st), (end), field, GPMC_CD_FCLK, 0, 0, 0) +#define GPMC_GET_TICKS_CD(reg, st, end, field, cd) \ + get_gpmc_timing_reg(cs, (reg), (st), (end), field, (cd), 0, 0, 0) static void gpmc_show_regs(int cs, const char *desc) { @@ -476,7 +534,7 @@ static void gpmc_cs_show_timings(int cs, const char *desc) GPMC_GET_TICKS(GPMC_CS_CONFIG6, 0, 3, "bus-turnaround-ns"); GPMC_GET_TICKS(GPMC_CS_CONFIG6, 8, 11, "cycle2cycle-delay-ns"); - GPMC_GET_TICKS(GPMC_CS_CONFIG1, 18, 19, "wait-monitoring-ns"); + GPMC_GET_TICKS_CD(GPMC_CS_CONFIG1, 18, 19, "wait-monitoring-ns", GPMC_CD_CLK); GPMC_GET_TICKS(GPMC_CS_CONFIG1, 25, 26, "clk-activation-ns"); GPMC_GET_TICKS(GPMC_CS_CONFIG6, 16, 19, "wr-data-mux-bus-ns"); @@ -488,8 +546,22 @@ static inline void gpmc_cs_show_timings(int cs, const char *desc) } #endif +/** + * set_gpmc_timing_reg - set a single timing parameter for Chip Select Region. + * Caller is expected to have initialized CONFIG1 GPMCFCLKDIVIDER + * prior to calling this function with @cd equal to GPMC_CD_CLK. + * + * @cs: Chip Select Region. + * @reg: GPMC_CS_CONFIGn register offset. + * @st_bit: Start Bit + * @end_bit: End Bit. Must be >= @st_bit. + * @time: Timing parameter in ns. + * @cd: Timing parameter clock domain. + * @name: Timing parameter name. + * @return: 0 on success, -1 on error. + */ static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit, - int time, const char *name) + int time, enum gpmc_clk_domain cd, const char *name) { u32 l; int ticks, mask, nr_bits; @@ -497,12 +569,12 @@ static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit, if (time == 0) ticks = 0; else - ticks = gpmc_ns_to_ticks(time); + ticks = gpmc_ns_to_clk_ticks(time, cs, cd); nr_bits = end_bit - st_bit + 1; mask = (1 << nr_bits) - 1; if (ticks > mask) { - pr_err("%s: GPMC error! CS%d: %s: %d ns, %d ticks > %d\n", + pr_err("%s: GPMC CS%d: %s %d ns, %d ticks > %d ticks\n", __func__, cs, name, time, ticks, mask); return -1; @@ -512,7 +584,7 @@ static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit, #ifdef DEBUG pr_info( "GPMC CS%d: %-17s: %3d ticks, %3lu ns (was %3i ticks) %3d ns\n", - cs, name, ticks, gpmc_get_fclk_period() * ticks / 1000, + cs, name, ticks, gpmc_get_clk_period(cs, cd) * ticks / 1000, (l >> st_bit) & mask, time); #endif l &= ~(mask << st_bit); @@ -522,11 +594,14 @@ static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit, return 0; } -#define GPMC_SET_ONE(reg, st, end, field) \ - if (set_gpmc_timing_reg(cs, (reg), (st), (end), \ - t->field, #field) < 0) \ +#define GPMC_SET_ONE_CD(reg, st, end, field, cd) \ + if (set_gpmc_timing_reg(cs, (reg), (st), (end), \ + t->field, (cd), #field) < 0) \ return -1 +#define GPMC_SET_ONE(reg, st, end, field) \ + GPMC_SET_ONE_CD(reg, st, end, field, GPMC_CD_FCLK) + /** * gpmc_calc_waitmonitoring_divider - calculate proper GPMCFCLKDIVIDER based on WAITMONITORINGTIME * WAITMONITORINGTIME will be _at least_ as long as desired, i.e. @@ -644,22 +719,23 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t, GPMC_SET_ONE(GPMC_CS_CONFIG6, 0, 3, bus_turnaround); GPMC_SET_ONE(GPMC_CS_CONFIG6, 8, 11, cycle2cycle_delay); - GPMC_SET_ONE(GPMC_CS_CONFIG1, 18, 19, wait_monitoring); - GPMC_SET_ONE(GPMC_CS_CONFIG1, 25, 26, clk_activation); - if (gpmc_capability & GPMC_HAS_WR_DATA_MUX_BUS) GPMC_SET_ONE(GPMC_CS_CONFIG6, 16, 19, wr_data_mux_bus); if (gpmc_capability & GPMC_HAS_WR_ACCESS) GPMC_SET_ONE(GPMC_CS_CONFIG6, 24, 28, wr_access); l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); + l &= ~0x03; + l |= (div - 1); + gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, l); + + GPMC_SET_ONE_CD(GPMC_CS_CONFIG1, 18, 19, wait_monitoring, GPMC_CD_CLK); + GPMC_SET_ONE(GPMC_CS_CONFIG1, 25, 26, clk_activation); + #ifdef DEBUG pr_info("GPMC CS%d CLK period is %lu ns (div %d)\n", cs, (div * gpmc_get_fclk_period()) / 1000, div); #endif - l &= ~0x03; - l |= (div - 1); - gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, l); gpmc_cs_bool_timings(cs, &t->bool_timings); gpmc_cs_show_timings(cs, "after gpmc_cs_set_timings"); -- GitLab From 9d17ce493a3ef1b140a4c831ba72fb435576c75a Mon Sep 17 00:00:00 2001 From: Yanir Lubetkin Date: Sat, 28 Feb 2015 10:09:34 +0000 Subject: [PATCH 02912/11651] e1000e: fix obscure comments The interface to the device flash was modified in i219 and later HW. This patch better describes the change and the impact on the driver. CC: John W Linville Reported-by: John W Linville Signed-off-by: Yanir Lubetkin Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/ich8lan.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index 7523f510c7e4..9d81c0317433 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c @@ -603,12 +603,15 @@ static s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw) u16 i; u32 nvm_size; - /* Can't read flash registers if the register set isn't mapped. */ nvm->type = e1000_nvm_flash_sw; - /* in SPT, gfpreg doesn't exist. NVM size is taken from the - * STRAP register - */ + if (hw->mac.type == e1000_pch_spt) { + /* in SPT, gfpreg doesn't exist. NVM size is taken from the + * STRAP register. This is because in SPT the GbE Flash region + * is no longer accessed through the flash registers. Instead, + * the mechanism has changed, and the Flash region access + * registers are now implemented in GbE memory space. + */ nvm->flash_base_addr = 0; nvm_size = (((er32(STRAP) >> 1) & 0x1F) + 1) * NVM_SIZE_MULTIPLIER; @@ -618,6 +621,7 @@ static s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw) /* Set the base address for flash register access */ hw->flash_address = hw->hw_addr + E1000_FLASH_BASE_ADDR; } else { + /* Can't read flash registers if register set isn't mapped. */ if (!hw->flash_address) { e_dbg("ERROR: Flash registers not mapped\n"); return -E1000_ERR_CONFIG; -- GitLab From 1103a631a83408733849b47fa2170cda984df2a3 Mon Sep 17 00:00:00 2001 From: Yanir Lubetkin Date: Sat, 28 Feb 2015 10:10:06 +0000 Subject: [PATCH 02913/11651] e1000e: remove calls to ioremap/unmap for NVM addr Starting I219, the NVM will not be mapped to its own BAR, but to an address region in another bar. The mapping/unmapping is relevant to older HW only. CC: John W Linville Reported-by: John W Linville Signed-off-by: Yanir Lubetkin Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/netdev.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 6fa4fc05709e..4be4576d71aa 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -6833,7 +6833,8 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto err_ioremap; if ((adapter->flags & FLAG_HAS_FLASH) && - (pci_resource_flags(pdev, 1) & IORESOURCE_MEM)) { + (pci_resource_flags(pdev, 1) & IORESOURCE_MEM) && + (hw->mac.type < e1000_pch_spt)) { flash_start = pci_resource_start(pdev, 1); flash_len = pci_resource_len(pdev, 1); adapter->hw.flash_address = ioremap(flash_start, flash_len); @@ -7069,7 +7070,7 @@ err_hw_init: kfree(adapter->tx_ring); kfree(adapter->rx_ring); err_sw_init: - if (adapter->hw.flash_address) + if ((adapter->hw.flash_address) && (hw->mac.type < e1000_pch_spt)) iounmap(adapter->hw.flash_address); e1000e_reset_interrupt_capability(adapter); err_flashmap: @@ -7142,7 +7143,8 @@ static void e1000_remove(struct pci_dev *pdev) kfree(adapter->rx_ring); iounmap(adapter->hw.hw_addr); - if (adapter->hw.flash_address) + if ((adapter->hw.flash_address) && + (adapter->hw.mac.type < e1000_pch_spt)) iounmap(adapter->hw.flash_address); pci_release_selected_regions(pdev, pci_select_bars(pdev, IORESOURCE_MEM)); -- GitLab From e357f0aae447009c053795e26a322fb15d3348a7 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Fri, 6 Mar 2015 03:34:09 +0000 Subject: [PATCH 02914/11651] igb: Fix warning pin may be used uninitialized MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When building the kernel using the gcc 4.8.3 compiler included in Fedora 20 I was repeatedly seeing the warning: drivers/net/ethernet/intel/igb/igb_ptp.c: In function ‘igb_ptp_feature_enable_i210’: drivers/net/ethernet/intel/igb/igb_ptp.c:395:21: warning: ‘pin’ may be used uninitialized in this function [-Wmaybe-uninitialized] tssdp &= ~ts_sdp_en[pin]; ^ drivers/net/ethernet/intel/igb/igb_ptp.c:471:6: note: ‘pin’ was declared here int pin; ^ To resolve it I am assigning the pin a value of -1 when it is instantiated. Signed-off-by: Alexander Duyck Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/igb/igb_ptp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/igb/igb_ptp.c b/drivers/net/ethernet/intel/igb/igb_ptp.c index d20fc8ed11f1..525e5c461e79 100644 --- a/drivers/net/ethernet/intel/igb/igb_ptp.c +++ b/drivers/net/ethernet/intel/igb/igb_ptp.c @@ -468,7 +468,7 @@ static int igb_ptp_feature_enable_i210(struct ptp_clock_info *ptp, u32 tsauxc, tsim, tsauxc_mask, tsim_mask, trgttiml, trgttimh; unsigned long flags; struct timespec ts; - int pin; + int pin = -1; s64 ns; switch (rq->type) { -- GitLab From b23c0cc5e8b7c31f831c03b74f8e79c958c41d1e Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Fri, 6 Mar 2015 03:34:14 +0000 Subject: [PATCH 02915/11651] igb: Make arrays on stack static const to avoid reallocation While addressing the pin problem I noticed that all of the pin register values where having to be pushed onto the stack each time the function was called. To avoid that I am making them static const so that they should only need to be allocated once and we can avoid all the instructions to get them onto the stack.. size before: text data bss dec hex filename 161477 10512 8 171997 29fdd drivers/net/ethernet/intel/igb/igb.ko size after: text data bss dec hex filename 161205 10512 8 171725 29ecd drivers/net/ethernet/intel/igb/igb.ko Signed-off-by: Alexander Duyck Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/igb/igb_ptp.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/net/ethernet/intel/igb/igb_ptp.c b/drivers/net/ethernet/intel/igb/igb_ptp.c index 525e5c461e79..d6be4c69172d 100644 --- a/drivers/net/ethernet/intel/igb/igb_ptp.c +++ b/drivers/net/ethernet/intel/igb/igb_ptp.c @@ -358,7 +358,7 @@ static int igb_ptp_settime_i210(struct ptp_clock_info *ptp, static void igb_pin_direction(int pin, int input, u32 *ctrl, u32 *ctrl_ext) { u32 *ptr = pin < 2 ? ctrl : ctrl_ext; - u32 mask[IGB_N_SDP] = { + static const u32 mask[IGB_N_SDP] = { E1000_CTRL_SDP0_DIR, E1000_CTRL_SDP1_DIR, E1000_CTRL_EXT_SDP2_DIR, @@ -373,16 +373,16 @@ static void igb_pin_direction(int pin, int input, u32 *ctrl, u32 *ctrl_ext) static void igb_pin_extts(struct igb_adapter *igb, int chan, int pin) { - struct e1000_hw *hw = &igb->hw; - u32 aux0_sel_sdp[IGB_N_SDP] = { + static const u32 aux0_sel_sdp[IGB_N_SDP] = { AUX0_SEL_SDP0, AUX0_SEL_SDP1, AUX0_SEL_SDP2, AUX0_SEL_SDP3, }; - u32 aux1_sel_sdp[IGB_N_SDP] = { + static const u32 aux1_sel_sdp[IGB_N_SDP] = { AUX1_SEL_SDP0, AUX1_SEL_SDP1, AUX1_SEL_SDP2, AUX1_SEL_SDP3, }; - u32 ts_sdp_en[IGB_N_SDP] = { + static const u32 ts_sdp_en[IGB_N_SDP] = { TS_SDP0_EN, TS_SDP1_EN, TS_SDP2_EN, TS_SDP3_EN, }; + struct e1000_hw *hw = &igb->hw; u32 ctrl, ctrl_ext, tssdp = 0; ctrl = rd32(E1000_CTRL); @@ -409,28 +409,28 @@ static void igb_pin_extts(struct igb_adapter *igb, int chan, int pin) static void igb_pin_perout(struct igb_adapter *igb, int chan, int pin) { - struct e1000_hw *hw = &igb->hw; - u32 aux0_sel_sdp[IGB_N_SDP] = { + static const u32 aux0_sel_sdp[IGB_N_SDP] = { AUX0_SEL_SDP0, AUX0_SEL_SDP1, AUX0_SEL_SDP2, AUX0_SEL_SDP3, }; - u32 aux1_sel_sdp[IGB_N_SDP] = { + static const u32 aux1_sel_sdp[IGB_N_SDP] = { AUX1_SEL_SDP0, AUX1_SEL_SDP1, AUX1_SEL_SDP2, AUX1_SEL_SDP3, }; - u32 ts_sdp_en[IGB_N_SDP] = { + static const u32 ts_sdp_en[IGB_N_SDP] = { TS_SDP0_EN, TS_SDP1_EN, TS_SDP2_EN, TS_SDP3_EN, }; - u32 ts_sdp_sel_tt0[IGB_N_SDP] = { + static const u32 ts_sdp_sel_tt0[IGB_N_SDP] = { TS_SDP0_SEL_TT0, TS_SDP1_SEL_TT0, TS_SDP2_SEL_TT0, TS_SDP3_SEL_TT0, }; - u32 ts_sdp_sel_tt1[IGB_N_SDP] = { + static const u32 ts_sdp_sel_tt1[IGB_N_SDP] = { TS_SDP0_SEL_TT1, TS_SDP1_SEL_TT1, TS_SDP2_SEL_TT1, TS_SDP3_SEL_TT1, }; - u32 ts_sdp_sel_clr[IGB_N_SDP] = { + static const u32 ts_sdp_sel_clr[IGB_N_SDP] = { TS_SDP0_SEL_FC1, TS_SDP1_SEL_FC1, TS_SDP2_SEL_FC1, TS_SDP3_SEL_FC1, }; + struct e1000_hw *hw = &igb->hw; u32 ctrl, ctrl_ext, tssdp = 0; ctrl = rd32(E1000_CTRL); -- GitLab From f9c029db70880a66cf03c34aa6d4d5c9b2d13281 Mon Sep 17 00:00:00 2001 From: Eliezer Tamir Date: Wed, 25 Feb 2015 15:52:49 +0000 Subject: [PATCH 02916/11651] e1000: call netif_carrier_off early on down When bringing down an interface netif_carrier_off() should be one the first things we do, since this will prevent the stack from queuing more packets to this interface. This operation is very fast, and should make the device behave much nicer when trying to bring down an interface under load. Also, this would Do The Right Thing (TM) if this device has some sort of fail-over teaming and redirect traffic to the other IF. Move netif_carrier_off as early as possible. Signed-off-by: Eliezer Tamir Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000/e1000_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c index 7f997d36948f..26dcb44ea0c8 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_main.c +++ b/drivers/net/ethernet/intel/e1000/e1000_main.c @@ -516,6 +516,7 @@ void e1000_down(struct e1000_adapter *adapter) struct net_device *netdev = adapter->netdev; u32 rctl, tctl; + netif_carrier_off(netdev); /* disable receives in the hardware */ rctl = er32(RCTL); @@ -544,7 +545,6 @@ void e1000_down(struct e1000_adapter *adapter) adapter->link_speed = 0; adapter->link_duplex = 0; - netif_carrier_off(netdev); e1000_reset(adapter); e1000_clean_all_tx_rings(adapter); -- GitLab From 08e8331654d1d7b2c58045e549005bc356aa7810 Mon Sep 17 00:00:00 2001 From: Sabrina Dubroca Date: Thu, 26 Feb 2015 05:35:41 +0000 Subject: [PATCH 02917/11651] e1000: add dummy allocator to fix race condition between mtu change and netpoll There is a race condition between e1000_change_mtu's cleanups and netpoll, when we change the MTU across jumbo size: Changing MTU frees all the rx buffers: e1000_change_mtu -> e1000_down -> e1000_clean_all_rx_rings -> e1000_clean_rx_ring Then, close to the end of e1000_change_mtu: pr_info -> ... -> netpoll_poll_dev -> e1000_clean -> e1000_clean_rx_irq -> e1000_alloc_rx_buffers -> e1000_alloc_frag And when we come back to do the rest of the MTU change: e1000_up -> e1000_configure -> e1000_configure_rx -> e1000_alloc_jumbo_rx_buffers alloc_jumbo finds the buffers already != NULL, since data (shared with page in e1000_rx_buffer->rxbuf) has been re-alloc'd, but it's garbage, or at least not what is expected when in jumbo state. This results in an unusable adapter (packets don't get through), and a NULL pointer dereference on the next call to e1000_clean_rx_ring (other mtu change, link down, shutdown): BUG: unable to handle kernel NULL pointer dereference at (null) IP: [] put_compound_page+0x7e/0x330 [...] Call Trace: [] put_page+0x55/0x60 [] e1000_clean_rx_ring+0x134/0x200 [] e1000_clean_all_rx_rings+0x45/0x60 [] e1000_down+0x1c0/0x1d0 [] ? deactivate_slab+0x7f0/0x840 [] e1000_change_mtu+0xdc/0x170 [] dev_set_mtu+0xa0/0x140 [] do_setlink+0x218/0xac0 [] ? nla_parse+0xb9/0x120 [] rtnl_newlink+0x6d0/0x890 [] ? kvm_clock_read+0x20/0x40 [] ? sched_clock_cpu+0xa8/0x100 [] rtnetlink_rcv_msg+0x92/0x260 By setting the allocator to a dummy version, netpoll can't mess up our rx buffers. The allocator is set back to a sane value in e1000_configure_rx. Fixes: edbbb3ca1077 ("e1000: implement jumbo receive with partial descriptors") Signed-off-by: Sabrina Dubroca Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000/e1000_main.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c index 26dcb44ea0c8..73c98d34fa1f 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_main.c +++ b/drivers/net/ethernet/intel/e1000/e1000_main.c @@ -144,6 +144,11 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter, static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter, struct e1000_rx_ring *rx_ring, int *work_done, int work_to_do); +static void e1000_alloc_dummy_rx_buffers(struct e1000_adapter *adapter, + struct e1000_rx_ring *rx_ring, + int cleaned_count) +{ +} static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter, struct e1000_rx_ring *rx_ring, int cleaned_count); @@ -3552,8 +3557,11 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu) msleep(1); /* e1000_down has a dependency on max_frame_size */ hw->max_frame_size = max_frame; - if (netif_running(netdev)) + if (netif_running(netdev)) { + /* prevent buffers from being reallocated */ + adapter->alloc_rx_buf = e1000_alloc_dummy_rx_buffers; e1000_down(adapter); + } /* NOTE: netdev_alloc_skb reserves 16 bytes, and typically NET_IP_ALIGN * means we reserve 2 more, this pushes us to allocate from the next -- GitLab From 4b613e9b4bbe94545a588a100e09006d827a7ebe Mon Sep 17 00:00:00 2001 From: Robert ABEL Date: Fri, 27 Feb 2015 16:56:55 +0100 Subject: [PATCH 02918/11651] ARM OMAP2+ GPMC: fix programming/showing reserved timing parameters GPMC_CONFIG1_i parameters CLKACTIVATIONTIME and WAITMONITORINGTIME have reserved values. Raise an error if calculated timings try to program reserved values. GPMC_CONFIG1_i ATTACHEDDEVICEPAGELENGTH and DEVICESIZE were already checked when parsing the DT. Explicitly comment invalid values on gpmc_cs_show_timings for -CLKACTIVATIONTIME -WAITMONITORINGTIME -DEVICESIZE -ATTACHEDDEVICEPAGELENGTH Signed-off-by: Robert ABEL Acked-by: Tony Lindgren Signed-off-by: Roger Quadros --- drivers/memory/omap-gpmc.c | 81 +++++++++++++++++++++++++++----------- 1 file changed, 58 insertions(+), 23 deletions(-) diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c index 6c076b7c9b6f..c94ea0d68746 100644 --- a/drivers/memory/omap-gpmc.c +++ b/drivers/memory/omap-gpmc.c @@ -135,7 +135,11 @@ #define GPMC_CONFIG1_WRITETYPE_ASYNC (0 << 27) #define GPMC_CONFIG1_WRITETYPE_SYNC (1 << 27) #define GPMC_CONFIG1_CLKACTIVATIONTIME(val) ((val & 3) << 25) +/** CLKACTIVATIONTIME Max Ticks */ +#define GPMC_CONFIG1_CLKACTIVATIONTIME_MAX 2 #define GPMC_CONFIG1_PAGE_LEN(val) ((val & 3) << 23) +/** ATTACHEDDEVICEPAGELENGTH Max Value */ +#define GPMC_CONFIG1_ATTACHEDDEVICEPAGELENGTH_MAX 2 #define GPMC_CONFIG1_WAIT_READ_MON (1 << 22) #define GPMC_CONFIG1_WAIT_WRITE_MON (1 << 21) #define GPMC_CONFIG1_WAIT_MON_TIME(val) ((val & 3) << 18) @@ -144,6 +148,8 @@ #define GPMC_CONFIG1_WAIT_PIN_SEL(val) ((val & 3) << 16) #define GPMC_CONFIG1_DEVICESIZE(val) ((val & 3) << 12) #define GPMC_CONFIG1_DEVICESIZE_16 GPMC_CONFIG1_DEVICESIZE(1) +/** DEVICESIZE Max Value */ +#define GPMC_CONFIG1_DEVICESIZE_MAX 1 #define GPMC_CONFIG1_DEVICETYPE(val) ((val & 3) << 10) #define GPMC_CONFIG1_DEVICETYPE_NOR GPMC_CONFIG1_DEVICETYPE(0) #define GPMC_CONFIG1_MUXTYPE(val) ((val & 3) << 8) @@ -404,6 +410,8 @@ static void gpmc_cs_bool_timings(int cs, const struct gpmc_bool_timings *p) * @reg: GPMC_CS_CONFIGn register offset. * @st_bit: Start Bit * @end_bit: End Bit. Must be >= @st_bit. + * @ma:x Maximum parameter value (before optional @shift). + * If 0, maximum is as high as @st_bit and @end_bit allow. * @name: DTS node name, w/o "gpmc," * @cd: Clock Domain of timing parameter. * @shift: Parameter value left shifts @shift, which is then printed instead of value. @@ -411,13 +419,14 @@ static void gpmc_cs_bool_timings(int cs, const struct gpmc_bool_timings *p) * raw format: gpmc,name = * tick format: gpmc,name = /‍* x ns -- y ns; x ticks *‍/ * Where x ns -- y ns result in the same tick value. + * When @max is exceeded, "invalid" is printed inside comment. * @noval: Parameter values equal to 0 are not printed. * @return: Specified timing parameter (after optional @shift). * */ static int get_gpmc_timing_reg( /* timing specifiers */ - int cs, int reg, int st_bit, int end_bit, + int cs, int reg, int st_bit, int end_bit, int max, const char *name, const enum gpmc_clk_domain cd, /* value transform */ int shift, @@ -427,11 +436,15 @@ static int get_gpmc_timing_reg( u32 l; int nr_bits; int mask; + bool invalid; l = gpmc_cs_read_reg(cs, reg); nr_bits = end_bit - st_bit + 1; mask = (1 << nr_bits) - 1; l = (l >> st_bit) & mask; + if (!max) + max = mask; + invalid = l > max; if (shift) l = (shift << l); if (noval && (l == 0)) @@ -444,11 +457,13 @@ static int get_gpmc_timing_reg( if (l) time_ns_min = gpmc_clk_ticks_to_ns(l - 1, cs, cd) + 1; time_ns = gpmc_clk_ticks_to_ns(l, cs, cd); - pr_info("gpmc,%s = <%u> /* %u ns - %u ns; %i ticks */\n", - name, time_ns, time_ns_min, time_ns, l); + pr_info("gpmc,%s = <%u> /* %u ns - %u ns; %i ticks%s*/\n", + name, time_ns, time_ns_min, time_ns, l, + invalid ? "; invalid " : " "); } else { /* raw format */ - pr_info("gpmc,%s = <%u>\n", name, l); + pr_info("gpmc,%s = <%u>%s\n", name, l, + invalid ? " /* invalid */" : ""); } return l; @@ -458,15 +473,19 @@ static int get_gpmc_timing_reg( pr_info("cs%i %s: 0x%08x\n", cs, #config, \ gpmc_cs_read_reg(cs, config)) #define GPMC_GET_RAW(reg, st, end, field) \ - get_gpmc_timing_reg(cs, (reg), (st), (end), field, GPMC_CD_FCLK, 0, 1, 0) + get_gpmc_timing_reg(cs, (reg), (st), (end), 0, field, GPMC_CD_FCLK, 0, 1, 0) +#define GPMC_GET_RAW_MAX(reg, st, end, max, field) \ + get_gpmc_timing_reg(cs, (reg), (st), (end), (max), field, GPMC_CD_FCLK, 0, 1, 0) #define GPMC_GET_RAW_BOOL(reg, st, end, field) \ - get_gpmc_timing_reg(cs, (reg), (st), (end), field, GPMC_CD_FCLK, 0, 1, 1) -#define GPMC_GET_RAW_SHIFT(reg, st, end, shift, field) \ - get_gpmc_timing_reg(cs, (reg), (st), (end), field, GPMC_CD_FCLK, (shift), 1, 1) + get_gpmc_timing_reg(cs, (reg), (st), (end), 0, field, GPMC_CD_FCLK, 0, 1, 1) +#define GPMC_GET_RAW_SHIFT_MAX(reg, st, end, shift, max, field) \ + get_gpmc_timing_reg(cs, (reg), (st), (end), (max), field, GPMC_CD_FCLK, (shift), 1, 1) #define GPMC_GET_TICKS(reg, st, end, field) \ - get_gpmc_timing_reg(cs, (reg), (st), (end), field, GPMC_CD_FCLK, 0, 0, 0) + get_gpmc_timing_reg(cs, (reg), (st), (end), 0, field, GPMC_CD_FCLK, 0, 0, 0) #define GPMC_GET_TICKS_CD(reg, st, end, field, cd) \ - get_gpmc_timing_reg(cs, (reg), (st), (end), field, (cd), 0, 0, 0) + get_gpmc_timing_reg(cs, (reg), (st), (end), 0, field, (cd), 0, 0, 0) +#define GPMC_GET_TICKS_CD_MAX(reg, st, end, max, field, cd) \ + get_gpmc_timing_reg(cs, (reg), (st), (end), (max), field, (cd), 0, 0, 0) static void gpmc_show_regs(int cs, const char *desc) { @@ -490,11 +509,14 @@ static void gpmc_cs_show_timings(int cs, const char *desc) pr_info("gpmc cs%i access configuration:\n", cs); GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 4, 4, "time-para-granularity"); GPMC_GET_RAW(GPMC_CS_CONFIG1, 8, 9, "mux-add-data"); - GPMC_GET_RAW(GPMC_CS_CONFIG1, 12, 13, "device-width"); + GPMC_GET_RAW_MAX(GPMC_CS_CONFIG1, 12, 13, + GPMC_CONFIG1_DEVICESIZE_MAX, "device-width"); GPMC_GET_RAW(GPMC_CS_CONFIG1, 16, 17, "wait-pin"); GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 21, 21, "wait-on-write"); GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 22, 22, "wait-on-read"); - GPMC_GET_RAW_SHIFT(GPMC_CS_CONFIG1, 23, 24, 4, "burst-length"); + GPMC_GET_RAW_SHIFT_MAX(GPMC_CS_CONFIG1, 23, 24, 4, + GPMC_CONFIG1_ATTACHEDDEVICEPAGELENGTH_MAX, + "burst-length"); GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 27, 27, "sync-write"); GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 28, 28, "burst-write"); GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 29, 29, "gpmc,sync-read"); @@ -534,8 +556,12 @@ static void gpmc_cs_show_timings(int cs, const char *desc) GPMC_GET_TICKS(GPMC_CS_CONFIG6, 0, 3, "bus-turnaround-ns"); GPMC_GET_TICKS(GPMC_CS_CONFIG6, 8, 11, "cycle2cycle-delay-ns"); - GPMC_GET_TICKS_CD(GPMC_CS_CONFIG1, 18, 19, "wait-monitoring-ns", GPMC_CD_CLK); - GPMC_GET_TICKS(GPMC_CS_CONFIG1, 25, 26, "clk-activation-ns"); + GPMC_GET_TICKS_CD_MAX(GPMC_CS_CONFIG1, 18, 19, + GPMC_CONFIG1_WAITMONITORINGTIME_MAX, + "wait-monitoring-ns", GPMC_CD_CLK); + GPMC_GET_TICKS_CD_MAX(GPMC_CS_CONFIG1, 25, 26, + GPMC_CONFIG1_CLKACTIVATIONTIME_MAX, + "clk-activation-ns", GPMC_CD_FCLK); GPMC_GET_TICKS(GPMC_CS_CONFIG6, 16, 19, "wr-data-mux-bus-ns"); GPMC_GET_TICKS(GPMC_CS_CONFIG6, 24, 28, "wr-access-ns"); @@ -555,12 +581,14 @@ static inline void gpmc_cs_show_timings(int cs, const char *desc) * @reg: GPMC_CS_CONFIGn register offset. * @st_bit: Start Bit * @end_bit: End Bit. Must be >= @st_bit. + * @max: Maximum parameter value. + * If 0, maximum is as high as @st_bit and @end_bit allow. * @time: Timing parameter in ns. * @cd: Timing parameter clock domain. * @name: Timing parameter name. * @return: 0 on success, -1 on error. */ -static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit, +static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit, int max, int time, enum gpmc_clk_domain cd, const char *name) { u32 l; @@ -573,9 +601,12 @@ static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit, nr_bits = end_bit - st_bit + 1; mask = (1 << nr_bits) - 1; - if (ticks > mask) { + if (!max) + max = mask; + + if (ticks > max) { pr_err("%s: GPMC CS%d: %s %d ns, %d ticks > %d ticks\n", - __func__, cs, name, time, ticks, mask); + __func__, cs, name, time, ticks, max); return -1; } @@ -594,13 +625,13 @@ static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit, return 0; } -#define GPMC_SET_ONE_CD(reg, st, end, field, cd) \ - if (set_gpmc_timing_reg(cs, (reg), (st), (end), \ - t->field, (cd), #field) < 0) \ +#define GPMC_SET_ONE_CD_MAX(reg, st, end, max, field, cd) \ + if (set_gpmc_timing_reg(cs, (reg), (st), (end), (max), \ + t->field, (cd), #field) < 0) \ return -1 #define GPMC_SET_ONE(reg, st, end, field) \ - GPMC_SET_ONE_CD(reg, st, end, field, GPMC_CD_FCLK) + GPMC_SET_ONE_CD_MAX(reg, st, end, 0, field, GPMC_CD_FCLK) /** * gpmc_calc_waitmonitoring_divider - calculate proper GPMCFCLKDIVIDER based on WAITMONITORINGTIME @@ -729,8 +760,12 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t, l |= (div - 1); gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, l); - GPMC_SET_ONE_CD(GPMC_CS_CONFIG1, 18, 19, wait_monitoring, GPMC_CD_CLK); - GPMC_SET_ONE(GPMC_CS_CONFIG1, 25, 26, clk_activation); + GPMC_SET_ONE_CD_MAX(GPMC_CS_CONFIG1, 18, 19, + GPMC_CONFIG1_WAITMONITORINGTIME_MAX, + wait_monitoring, GPMC_CD_CLK); + GPMC_SET_ONE_CD_MAX(GPMC_CS_CONFIG1, 25, 26, + GPMC_CONFIG1_CLKACTIVATIONTIME_MAX, + clk_activation, GPMC_CD_FCLK); #ifdef DEBUG pr_info("GPMC CS%d CLK period is %lu ns (div %d)\n", -- GitLab From f8323b6bb2cc7d26941d4838dd4375952980a88a Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Mon, 23 Feb 2015 14:53:10 +0200 Subject: [PATCH 02919/11651] pinctrl: baytrail: Relax GPIO request rules Zotac ZBOX PI320, a Baytrail based mini-PC, has power button connected to a GPIO pin and it is exposed to the operating system as Windows 8 button array. This is implemented in Linux as a driver using gpio_keys. However, BIOS on this particula machine forgot to mux the pin to be a GPIO instead of native function, which results following message to be seen on the console: byt_gpio INT33FC:02: pin 16 cannot be used as GPIO. This causes power button to not work as the driver was not able to request the GPIO it needs. So instead of completely preventing this we allow turning the pin as GPIO but issue warning that something might be wrong. Reported-by: Benjamin Adler Signed-off-by: Mika Westerberg Signed-off-by: Linus Walleij --- drivers/pinctrl/intel/pinctrl-baytrail.c | 35 +++++++++++++++--------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c index 5afe03e28b91..e44f2fd6753f 100644 --- a/drivers/pinctrl/intel/pinctrl-baytrail.c +++ b/drivers/pinctrl/intel/pinctrl-baytrail.c @@ -158,40 +158,49 @@ static void __iomem *byt_gpio_reg(struct gpio_chip *chip, unsigned offset, return vg->reg_base + reg_offset + reg; } -static bool is_special_pin(struct byt_gpio *vg, unsigned offset) +static u32 byt_get_gpio_mux(struct byt_gpio *vg, unsigned offset) { /* SCORE pin 92-93 */ if (!strcmp(vg->range->name, BYT_SCORE_ACPI_UID) && offset >= 92 && offset <= 93) - return true; + return 1; /* SUS pin 11-21 */ if (!strcmp(vg->range->name, BYT_SUS_ACPI_UID) && offset >= 11 && offset <= 21) - return true; + return 1; - return false; + return 0; } static int byt_gpio_request(struct gpio_chip *chip, unsigned offset) { struct byt_gpio *vg = to_byt_gpio(chip); void __iomem *reg = byt_gpio_reg(chip, offset, BYT_CONF0_REG); - u32 value; - bool special; + u32 value, gpio_mux; /* * In most cases, func pin mux 000 means GPIO function. * But, some pins may have func pin mux 001 represents - * GPIO function. Only allow user to export pin with - * func pin mux preset as GPIO function by BIOS/FW. + * GPIO function. + * + * Because there are devices out there where some pins were not + * configured correctly we allow changing the mux value from + * request (but print out warning about that). */ value = readl(reg) & BYT_PIN_MUX; - special = is_special_pin(vg, offset); - if ((special && value != 1) || (!special && value)) { - dev_err(&vg->pdev->dev, - "pin %u cannot be used as GPIO.\n", offset); - return -EINVAL; + gpio_mux = byt_get_gpio_mux(vg, offset); + if (WARN_ON(gpio_mux != value)) { + unsigned long flags; + + spin_lock_irqsave(&vg->lock, flags); + value = readl(reg) & ~BYT_PIN_MUX; + value |= gpio_mux; + writel(value, reg); + spin_unlock_irqrestore(&vg->lock, flags); + + dev_warn(&vg->pdev->dev, + "pin %u forcibly re-configured as GPIO\n", offset); } pm_runtime_get(&vg->pdev->dev); -- GitLab From 95f0972c7e4cbf3fc68160131c5ac2f033481d00 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Mon, 23 Feb 2015 14:53:11 +0200 Subject: [PATCH 02920/11651] pinctrl: baytrail: Clear interrupt triggering from pins that are in GPIO mode If the pin is already configured as GPIO and it has any of the triggering flags set, we may get spurious interrupts depending on the state of the pin. Prevent this by clearing the triggering flags on such pins. However, if the pin is also configured as "direct IRQ" we leave the flags as is. Otherwise it will prevent interrupts that are routed directly to IO-APIC. Signed-off-by: Mika Westerberg Signed-off-by: Linus Walleij --- drivers/pinctrl/intel/pinctrl-baytrail.c | 36 +++++++++++++++++++----- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c index e44f2fd6753f..d264b099182d 100644 --- a/drivers/pinctrl/intel/pinctrl-baytrail.c +++ b/drivers/pinctrl/intel/pinctrl-baytrail.c @@ -158,6 +158,19 @@ static void __iomem *byt_gpio_reg(struct gpio_chip *chip, unsigned offset, return vg->reg_base + reg_offset + reg; } +static void byt_gpio_clear_triggering(struct byt_gpio *vg, unsigned offset) +{ + void __iomem *reg = byt_gpio_reg(&vg->chip, offset, BYT_CONF0_REG); + unsigned long flags; + u32 value; + + spin_lock_irqsave(&vg->lock, flags); + value = readl(reg); + value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL); + writel(value, reg); + spin_unlock_irqrestore(&vg->lock, flags); +} + static u32 byt_get_gpio_mux(struct byt_gpio *vg, unsigned offset) { /* SCORE pin 92-93 */ @@ -211,14 +224,8 @@ static int byt_gpio_request(struct gpio_chip *chip, unsigned offset) static void byt_gpio_free(struct gpio_chip *chip, unsigned offset) { struct byt_gpio *vg = to_byt_gpio(chip); - void __iomem *reg = byt_gpio_reg(&vg->chip, offset, BYT_CONF0_REG); - u32 value; - - /* clear interrupt triggering */ - value = readl(reg); - value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL); - writel(value, reg); + byt_gpio_clear_triggering(vg, offset); pm_runtime_put(&vg->pdev->dev); } @@ -481,6 +488,21 @@ static void byt_gpio_irq_init_hw(struct byt_gpio *vg) { void __iomem *reg; u32 base, value; + int i; + + /* + * Clear interrupt triggers for all pins that are GPIOs and + * do not use direct IRQ mode. This will prevent spurious + * interrupts from misconfigured pins. + */ + for (i = 0; i < vg->chip.ngpio; i++) { + value = readl(byt_gpio_reg(&vg->chip, i, BYT_CONF0_REG)); + if ((value & BYT_PIN_MUX) == byt_get_gpio_mux(vg, i) && + !(value & BYT_DIRECT_IRQ_EN)) { + byt_gpio_clear_triggering(vg, i); + dev_dbg(&vg->pdev->dev, "disabling GPIO %d\n", i); + } + } /* clear interrupt status trigger registers */ for (base = 0; base < vg->chip.ngpio; base += 32) { -- GitLab From 31e4329f99062a06dca5a493bb4495a63b2dc6ba Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Mon, 23 Feb 2015 14:53:12 +0200 Subject: [PATCH 02921/11651] pinctrl: baytrail: Rework interrupt handling Instead of handling everything in the driver's first level interrupt handler, we can take advantage of already existing flow handlers that are provided by the IRQ core. This changes the functionality a bit also. Previously the driver looped over pending interrupts in a single loop, restarting the loop if some interrupt changed state. This caused problem with Lenovo Thinkpad 10 digitizer that it was not able to deassert the interrupt before the driver disabled the interrupt for good (looplimit was exhausted). Rework the interrupt handling logic a bit so that we provide proper mask, ack and unmask operations in terms of Baytrail GPIO hardware and loop over pending interrupts only once. If the interrupt remains asserted the first level handler will be re-triggered automatically. Signed-off-by: Mika Westerberg Signed-off-by: Linus Walleij --- drivers/pinctrl/intel/pinctrl-baytrail.c | 100 +++++++++++++---------- 1 file changed, 56 insertions(+), 44 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c index d264b099182d..2318057a309b 100644 --- a/drivers/pinctrl/intel/pinctrl-baytrail.c +++ b/drivers/pinctrl/intel/pinctrl-baytrail.c @@ -252,23 +252,13 @@ static int byt_irq_type(struct irq_data *d, unsigned type) value &= ~(BYT_DIRECT_IRQ_EN | BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL); - switch (type) { - case IRQ_TYPE_LEVEL_HIGH: - value |= BYT_TRIG_LVL; - case IRQ_TYPE_EDGE_RISING: - value |= BYT_TRIG_POS; - break; - case IRQ_TYPE_LEVEL_LOW: - value |= BYT_TRIG_LVL; - case IRQ_TYPE_EDGE_FALLING: - value |= BYT_TRIG_NEG; - break; - case IRQ_TYPE_EDGE_BOTH: - value |= (BYT_TRIG_NEG | BYT_TRIG_POS); - break; - } writel(value, reg); + if (type & IRQ_TYPE_EDGE_BOTH) + __irq_set_handler_locked(d->irq, handle_edge_irq); + else if (type & IRQ_TYPE_LEVEL_MASK) + __irq_set_handler_locked(d->irq, handle_level_irq); + spin_unlock_irqrestore(&vg->lock, flags); return 0; @@ -426,58 +416,80 @@ static void byt_gpio_irq_handler(unsigned irq, struct irq_desc *desc) struct irq_data *data = irq_desc_get_irq_data(desc); struct byt_gpio *vg = to_byt_gpio(irq_desc_get_handler_data(desc)); struct irq_chip *chip = irq_data_get_irq_chip(data); - u32 base, pin, mask; + u32 base, pin; void __iomem *reg; - u32 pending; + unsigned long pending; unsigned virq; - int looplimit = 0; /* check from GPIO controller which pin triggered the interrupt */ for (base = 0; base < vg->chip.ngpio; base += 32) { - reg = byt_gpio_reg(&vg->chip, base, BYT_INT_STAT_REG); - - while ((pending = readl(reg))) { - pin = __ffs(pending); - mask = BIT(pin); - /* Clear before handling so we can't lose an edge */ - writel(mask, reg); - + pending = readl(reg); + for_each_set_bit(pin, &pending, 32) { virq = irq_find_mapping(vg->chip.irqdomain, base + pin); generic_handle_irq(virq); - - /* In case bios or user sets triggering incorretly a pin - * might remain in "interrupt triggered" state. - */ - if (looplimit++ > 32) { - dev_err(&vg->pdev->dev, - "Gpio %d interrupt flood, disabling\n", - base + pin); - - reg = byt_gpio_reg(&vg->chip, base + pin, - BYT_CONF0_REG); - mask = readl(reg); - mask &= ~(BYT_TRIG_NEG | BYT_TRIG_POS | - BYT_TRIG_LVL); - writel(mask, reg); - mask = readl(reg); /* flush */ - break; - } } } chip->irq_eoi(data); } +static void byt_irq_ack(struct irq_data *d) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct byt_gpio *vg = to_byt_gpio(gc); + unsigned offset = irqd_to_hwirq(d); + void __iomem *reg; + + reg = byt_gpio_reg(&vg->chip, offset, BYT_INT_STAT_REG); + writel(BIT(offset % 32), reg); +} + static void byt_irq_unmask(struct irq_data *d) { + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct byt_gpio *vg = to_byt_gpio(gc); + unsigned offset = irqd_to_hwirq(d); + unsigned long flags; + void __iomem *reg; + u32 value; + + spin_lock_irqsave(&vg->lock, flags); + + reg = byt_gpio_reg(&vg->chip, offset, BYT_CONF0_REG); + value = readl(reg); + + switch (irqd_get_trigger_type(d)) { + case IRQ_TYPE_LEVEL_HIGH: + value |= BYT_TRIG_LVL; + case IRQ_TYPE_EDGE_RISING: + value |= BYT_TRIG_POS; + break; + case IRQ_TYPE_LEVEL_LOW: + value |= BYT_TRIG_LVL; + case IRQ_TYPE_EDGE_FALLING: + value |= BYT_TRIG_NEG; + break; + case IRQ_TYPE_EDGE_BOTH: + value |= (BYT_TRIG_NEG | BYT_TRIG_POS); + break; + } + + writel(value, reg); + + spin_unlock_irqrestore(&vg->lock, flags); } static void byt_irq_mask(struct irq_data *d) { + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct byt_gpio *vg = to_byt_gpio(gc); + + byt_gpio_clear_triggering(vg, irqd_to_hwirq(d)); } static struct irq_chip byt_irqchip = { .name = "BYT-GPIO", + .irq_ack = byt_irq_ack, .irq_mask = byt_irq_mask, .irq_unmask = byt_irq_unmask, .irq_set_type = byt_irq_type, -- GitLab From c9dafb27c84412fe4b17c3b94cc4ffeef5df1833 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 2 Mar 2015 20:15:58 +0200 Subject: [PATCH 02922/11651] spi: dw-mid: avoid potential NULL dereference When DMA descriptor allocation fails we should not try to assign any fields in the bad descriptor. The patch adds the necessary checks for that. Fixes: 7063c0d942a1 (spi/dw_spi: add DMA support) Signed-off-by: Andy Shevchenko Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- drivers/spi/spi-dw-mid.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/spi/spi-dw-mid.c b/drivers/spi/spi-dw-mid.c index a0197fd4e95c..3ce39d10fafb 100644 --- a/drivers/spi/spi-dw-mid.c +++ b/drivers/spi/spi-dw-mid.c @@ -139,6 +139,9 @@ static struct dma_async_tx_descriptor *dw_spi_dma_prepare_tx(struct dw_spi *dws) 1, DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + if (!txdesc) + return NULL; + txdesc->callback = dw_spi_dma_tx_done; txdesc->callback_param = dws; @@ -184,6 +187,9 @@ static struct dma_async_tx_descriptor *dw_spi_dma_prepare_rx(struct dw_spi *dws) 1, DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + if (!rxdesc) + return NULL; + rxdesc->callback = dw_spi_dma_rx_done; rxdesc->callback_param = dws; -- GitLab From fcc18deb7682dafcf6176b4af81d1554ffabd8b1 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Mon, 23 Feb 2015 14:53:13 +0200 Subject: [PATCH 02923/11651] pinctrl: baytrail: Save pin context over system sleep The BIOS might reconfigure pins as it needs when S3 is entered. This might cause drivers using the GPIOs to fail because the state was wrong or interrupts stopped working. Fix this by saving and restoring enough pin context over system sleep. Reported-by: Hans Holmberg Signed-off-by: Mika Westerberg Signed-off-by: Linus Walleij --- drivers/pinctrl/intel/pinctrl-baytrail.c | 83 +++++++++++++++++++++++- 1 file changed, 81 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c index 2318057a309b..2062c224e32f 100644 --- a/drivers/pinctrl/intel/pinctrl-baytrail.c +++ b/drivers/pinctrl/intel/pinctrl-baytrail.c @@ -66,6 +66,10 @@ #define BYT_DIR_MASK (BIT(1) | BIT(2)) #define BYT_TRIG_MASK (BIT(26) | BIT(25) | BIT(24)) +#define BYT_CONF0_RESTORE_MASK (BYT_DIRECT_IRQ_EN | BYT_TRIG_MASK | \ + BYT_PIN_MUX) +#define BYT_VAL_RESTORE_MASK (BYT_DIR_MASK | BYT_LEVEL) + #define BYT_NGPIO_SCORE 102 #define BYT_NGPIO_NCORE 28 #define BYT_NGPIO_SUS 44 @@ -134,12 +138,18 @@ static struct pinctrl_gpio_range byt_ranges[] = { }, }; +struct byt_gpio_pin_context { + u32 conf0; + u32 val; +}; + struct byt_gpio { struct gpio_chip chip; struct platform_device *pdev; spinlock_t lock; void __iomem *reg_base; struct pinctrl_gpio_range *range; + struct byt_gpio_pin_context *saved_context; }; #define to_byt_gpio(c) container_of(c, struct byt_gpio, chip) @@ -584,6 +594,11 @@ static int byt_gpio_probe(struct platform_device *pdev) gc->can_sleep = false; gc->dev = dev; +#ifdef CONFIG_PM_SLEEP + vg->saved_context = devm_kcalloc(&pdev->dev, gc->ngpio, + sizeof(*vg->saved_context), GFP_KERNEL); +#endif + ret = gpiochip_add(gc); if (ret) { dev_err(&pdev->dev, "failed adding byt-gpio chip\n"); @@ -612,6 +627,69 @@ static int byt_gpio_probe(struct platform_device *pdev) return 0; } +#ifdef CONFIG_PM_SLEEP +static int byt_gpio_suspend(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct byt_gpio *vg = platform_get_drvdata(pdev); + int i; + + for (i = 0; i < vg->chip.ngpio; i++) { + void __iomem *reg; + u32 value; + + reg = byt_gpio_reg(&vg->chip, i, BYT_CONF0_REG); + value = readl(reg) & BYT_CONF0_RESTORE_MASK; + vg->saved_context[i].conf0 = value; + + reg = byt_gpio_reg(&vg->chip, i, BYT_VAL_REG); + value = readl(reg) & BYT_VAL_RESTORE_MASK; + vg->saved_context[i].val = value; + } + + return 0; +} + +static int byt_gpio_resume(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct byt_gpio *vg = platform_get_drvdata(pdev); + int i; + + for (i = 0; i < vg->chip.ngpio; i++) { + void __iomem *reg; + u32 value; + + reg = byt_gpio_reg(&vg->chip, i, BYT_CONF0_REG); + value = readl(reg); + if ((value & BYT_CONF0_RESTORE_MASK) != + vg->saved_context[i].conf0) { + value &= ~BYT_CONF0_RESTORE_MASK; + value |= vg->saved_context[i].conf0; + writel(value, reg); + dev_info(dev, "restored pin %d conf0 %#08x", i, value); + } + + reg = byt_gpio_reg(&vg->chip, i, BYT_VAL_REG); + value = readl(reg); + if ((value & BYT_VAL_RESTORE_MASK) != + vg->saved_context[i].val) { + u32 v; + + v = value & ~BYT_VAL_RESTORE_MASK; + v |= vg->saved_context[i].val; + if (v != value) { + writel(v, reg); + dev_dbg(dev, "restored pin %d val %#08x\n", + i, v); + } + } + } + + return 0; +} +#endif + static int byt_gpio_runtime_suspend(struct device *dev) { return 0; @@ -623,8 +701,9 @@ static int byt_gpio_runtime_resume(struct device *dev) } static const struct dev_pm_ops byt_gpio_pm_ops = { - .runtime_suspend = byt_gpio_runtime_suspend, - .runtime_resume = byt_gpio_runtime_resume, + SET_LATE_SYSTEM_SLEEP_PM_OPS(byt_gpio_suspend, byt_gpio_resume) + SET_RUNTIME_PM_OPS(byt_gpio_runtime_suspend, byt_gpio_runtime_resume, + NULL) }; static const struct acpi_device_id byt_gpio_acpi_match[] = { -- GitLab From f641ddddc3ad139a91b9a1f9cea84ea657f75a6b Mon Sep 17 00:00:00 2001 From: Martin Hicks Date: Tue, 3 Mar 2015 08:21:33 -0500 Subject: [PATCH 02924/11651] crypto: talitos - Simplify per-channel initialization There were multiple loops in a row, for each separate step of the initialization of the channels. Simplify to a single loop. Signed-off-by: Martin Hicks Acked-by: Kim Phillips Signed-off-by: Herbert Xu --- drivers/crypto/talitos.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index ebbae8d3ce0d..20ae97a919df 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c @@ -2706,20 +2706,16 @@ static int talitos_probe(struct platform_device *ofdev) goto err_out; } + priv->fifo_len = roundup_pow_of_two(priv->chfifo_len); + for (i = 0; i < priv->num_channels; i++) { priv->chan[i].reg = priv->reg + TALITOS_CH_STRIDE * (i + 1); if (!priv->irq[1] || !(i & 1)) priv->chan[i].reg += TALITOS_CH_BASE_OFFSET; - } - for (i = 0; i < priv->num_channels; i++) { spin_lock_init(&priv->chan[i].head_lock); spin_lock_init(&priv->chan[i].tail_lock); - } - priv->fifo_len = roundup_pow_of_two(priv->chfifo_len); - - for (i = 0; i < priv->num_channels; i++) { priv->chan[i].fifo = kzalloc(sizeof(struct talitos_request) * priv->fifo_len, GFP_KERNEL); if (!priv->chan[i].fifo) { @@ -2727,11 +2723,10 @@ static int talitos_probe(struct platform_device *ofdev) err = -ENOMEM; goto err_out; } - } - for (i = 0; i < priv->num_channels; i++) atomic_set(&priv->chan[i].submit_count, -(priv->chfifo_len - 1)); + } dma_set_mask(dev, DMA_BIT_MASK(36)); -- GitLab From b3988618e0463cf9af30ac1b42b2601993be7c70 Mon Sep 17 00:00:00 2001 From: Martin Hicks Date: Tue, 3 Mar 2015 08:21:34 -0500 Subject: [PATCH 02925/11651] crypto: talitos - Remove MD5_BLOCK_SIZE This is properly defined in the md5 header file. Signed-off-by: Martin Hicks Acked-by: Kim Phillips Signed-off-by: Herbert Xu --- drivers/crypto/talitos.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index 20ae97a919df..857414afa29a 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c @@ -637,8 +637,6 @@ static void talitos_unregister_rng(struct device *dev) #define TALITOS_MAX_KEY_SIZE 96 #define TALITOS_MAX_IV_LENGTH 16 /* max of AES_BLOCK_SIZE, DES3_EDE_BLOCK_SIZE */ -#define MD5_BLOCK_SIZE 64 - struct talitos_ctx { struct device *dev; int ch; @@ -2195,7 +2193,7 @@ static struct talitos_alg_template driver_algs[] = { .halg.base = { .cra_name = "md5", .cra_driver_name = "md5-talitos", - .cra_blocksize = MD5_BLOCK_SIZE, + .cra_blocksize = MD5_HMAC_BLOCK_SIZE, .cra_flags = CRYPTO_ALG_TYPE_AHASH | CRYPTO_ALG_ASYNC, } @@ -2285,7 +2283,7 @@ static struct talitos_alg_template driver_algs[] = { .halg.base = { .cra_name = "hmac(md5)", .cra_driver_name = "hmac-md5-talitos", - .cra_blocksize = MD5_BLOCK_SIZE, + .cra_blocksize = MD5_HMAC_BLOCK_SIZE, .cra_flags = CRYPTO_ALG_TYPE_AHASH | CRYPTO_ALG_ASYNC, } -- GitLab From 8e2e2769042f08eb49f630b5db87fce03696a415 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 4 Mar 2015 10:19:30 +0100 Subject: [PATCH 02926/11651] crypto: ux500 - Update error message for dmaengine_prep_slave_sg() API Commit 7e933d3b1e25b250 ("crypto: ux500: use dmaengine_prep_slave_sg API") changed the code to use the new API, but forgot to update an error message. Signed-off-by: Geert Uytterhoeven Signed-off-by: Herbert Xu --- drivers/crypto/ux500/hash/hash_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/crypto/ux500/hash/hash_core.c b/drivers/crypto/ux500/hash/hash_core.c index 187a8fd7eee7..5f5f360628fc 100644 --- a/drivers/crypto/ux500/hash/hash_core.c +++ b/drivers/crypto/ux500/hash/hash_core.c @@ -184,7 +184,7 @@ static int hash_set_dma_transfer(struct hash_ctx *ctx, struct scatterlist *sg, direction, DMA_CTRL_ACK | DMA_PREP_INTERRUPT); if (!desc) { dev_err(ctx->device->dev, - "%s: device_prep_slave_sg() failed!\n", __func__); + "%s: dmaengine_prep_slave_sg() failed!\n", __func__); return -EFAULT; } -- GitLab From 259d317f8d584503c5e3c43bbb96d80149390939 Mon Sep 17 00:00:00 2001 From: Scott Branden Date: Wed, 4 Mar 2015 12:42:13 -0800 Subject: [PATCH 02927/11651] hwrng: iproc-rng200 - Add device tree bindings Documents the IPROC random number generator device tree bindings used in some Broadcom chipsets. Reviewed-by: Ray Jui Signed-off-by: Scott Branden Signed-off-by: Herbert Xu --- .../devicetree/bindings/hwrng/brcm,iproc-rng200.txt | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 Documentation/devicetree/bindings/hwrng/brcm,iproc-rng200.txt diff --git a/Documentation/devicetree/bindings/hwrng/brcm,iproc-rng200.txt b/Documentation/devicetree/bindings/hwrng/brcm,iproc-rng200.txt new file mode 100644 index 000000000000..e25a456664b9 --- /dev/null +++ b/Documentation/devicetree/bindings/hwrng/brcm,iproc-rng200.txt @@ -0,0 +1,12 @@ +HWRNG support for the iproc-rng200 driver + +Required properties: +- compatible : "brcm,iproc-rng200" +- reg : base address and size of control register block + +Example: + +rng { + compatible = "brcm,iproc-rng200"; + reg = <0x18032000 0x28>; +}; -- GitLab From c83d45d5685f63e02f4b038e20450a28232d4da2 Mon Sep 17 00:00:00 2001 From: Scott Branden Date: Wed, 4 Mar 2015 12:42:14 -0800 Subject: [PATCH 02928/11651] hwrng: iproc-rng200 - Add Broadcom IPROC RNG driver This adds a driver for random number generator present on Broadcom IPROC devices. Reviewed-by: Ray Jui Signed-off-by: Scott Branden Signed-off-by: Herbert Xu --- drivers/char/hw_random/Kconfig | 13 ++ drivers/char/hw_random/Makefile | 1 + drivers/char/hw_random/iproc-rng200.c | 254 ++++++++++++++++++++++++++ 3 files changed, 268 insertions(+) create mode 100644 drivers/char/hw_random/iproc-rng200.c diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig index de57b38809c7..f48cf11c655e 100644 --- a/drivers/char/hw_random/Kconfig +++ b/drivers/char/hw_random/Kconfig @@ -101,6 +101,19 @@ config HW_RANDOM_BCM2835 If unsure, say Y. +config HW_RANDOM_IPROC_RNG200 + tristate "Broadcom iProc RNG200 support" + depends on ARCH_BCM_IPROC + default HW_RANDOM + ---help--- + This driver provides kernel-side support for the RNG200 + hardware found on the Broadcom iProc SoCs. + + To compile this driver as a module, choose M here: the + module will be called iproc-rng200 + + If unsure, say Y. + config HW_RANDOM_GEODE tristate "AMD Geode HW Random Number Generator support" depends on X86_32 && PCI diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile index 0b4cd57f4e24..055bb01510ad 100644 --- a/drivers/char/hw_random/Makefile +++ b/drivers/char/hw_random/Makefile @@ -28,5 +28,6 @@ obj-$(CONFIG_HW_RANDOM_POWERNV) += powernv-rng.o obj-$(CONFIG_HW_RANDOM_EXYNOS) += exynos-rng.o obj-$(CONFIG_HW_RANDOM_TPM) += tpm-rng.o obj-$(CONFIG_HW_RANDOM_BCM2835) += bcm2835-rng.o +obj-$(CONFIG_HW_RANDOM_IPROC_RNG200) += iproc-rng200.o obj-$(CONFIG_HW_RANDOM_MSM) += msm-rng.o obj-$(CONFIG_HW_RANDOM_XGENE) += xgene-rng.o diff --git a/drivers/char/hw_random/iproc-rng200.c b/drivers/char/hw_random/iproc-rng200.c new file mode 100644 index 000000000000..276cb8a93bac --- /dev/null +++ b/drivers/char/hw_random/iproc-rng200.c @@ -0,0 +1,254 @@ +/* +* Copyright (C) 2015 Broadcom Corporation +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License as +* published by the Free Software Foundation version 2. +* +* This program is distributed "as is" WITHOUT ANY WARRANTY of any +* kind, whether express or implied; without even the implied warranty +* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +*/ +/* + * DESCRIPTION: The Broadcom iProc RNG200 Driver + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Registers */ +#define RNG_CTRL_OFFSET 0x00 +#define RNG_CTRL_RNG_RBGEN_MASK 0x00001FFF +#define RNG_CTRL_RNG_RBGEN_ENABLE 0x00000001 +#define RNG_CTRL_RNG_RBGEN_DISABLE 0x00000000 + +#define RNG_SOFT_RESET_OFFSET 0x04 +#define RNG_SOFT_RESET 0x00000001 + +#define RBG_SOFT_RESET_OFFSET 0x08 +#define RBG_SOFT_RESET 0x00000001 + +#define RNG_INT_STATUS_OFFSET 0x18 +#define RNG_INT_STATUS_MASTER_FAIL_LOCKOUT_IRQ_MASK 0x80000000 +#define RNG_INT_STATUS_STARTUP_TRANSITIONS_MET_IRQ_MASK 0x00020000 +#define RNG_INT_STATUS_NIST_FAIL_IRQ_MASK 0x00000020 +#define RNG_INT_STATUS_TOTAL_BITS_COUNT_IRQ_MASK 0x00000001 + +#define RNG_FIFO_DATA_OFFSET 0x20 + +#define RNG_FIFO_COUNT_OFFSET 0x24 +#define RNG_FIFO_COUNT_RNG_FIFO_COUNT_MASK 0x000000FF + +struct iproc_rng200_dev { + void __iomem *base; +}; + +static void iproc_rng200_restart(void __iomem *rng_base) +{ + uint32_t val; + + /* Disable RBG */ + val = ioread32(rng_base + RNG_CTRL_OFFSET); + val &= ~RNG_CTRL_RNG_RBGEN_MASK; + val |= RNG_CTRL_RNG_RBGEN_DISABLE; + iowrite32(val, rng_base + RNG_CTRL_OFFSET); + + /* Clear all interrupt status */ + iowrite32(0xFFFFFFFFUL, rng_base + RNG_INT_STATUS_OFFSET); + + /* Reset RNG and RBG */ + val = ioread32(rng_base + RBG_SOFT_RESET_OFFSET); + val |= RBG_SOFT_RESET; + iowrite32(val, rng_base + RBG_SOFT_RESET_OFFSET); + + val = ioread32(rng_base + RNG_SOFT_RESET_OFFSET); + val |= RNG_SOFT_RESET; + iowrite32(val, rng_base + RNG_SOFT_RESET_OFFSET); + + val = ioread32(rng_base + RNG_SOFT_RESET_OFFSET); + val &= ~RNG_SOFT_RESET; + iowrite32(val, rng_base + RNG_SOFT_RESET_OFFSET); + + val = ioread32(rng_base + RBG_SOFT_RESET_OFFSET); + val &= ~RBG_SOFT_RESET; + iowrite32(val, rng_base + RBG_SOFT_RESET_OFFSET); + + /* Enable RBG */ + val = ioread32(rng_base + RNG_CTRL_OFFSET); + val &= ~RNG_CTRL_RNG_RBGEN_MASK; + val |= RNG_CTRL_RNG_RBGEN_ENABLE; + iowrite32(val, rng_base + RNG_CTRL_OFFSET); +} + +static int iproc_rng200_read(struct hwrng *rng, void *buf, size_t max, + bool wait) +{ + uint32_t status; + uint32_t num_remaining = max; + struct iproc_rng200_dev *priv = (struct iproc_rng200_dev *)rng->priv; + + #define MAX_RESETS_PER_READ 1 + uint32_t num_resets = 0; + + #define MAX_IDLE_TIME (1 * HZ) + unsigned long idle_endtime = jiffies + MAX_IDLE_TIME; + + while ((num_remaining > 0) && time_before(jiffies, idle_endtime)) { + + /* Is RNG sane? If not, reset it. */ + status = ioread32(priv->base + RNG_INT_STATUS_OFFSET); + if ((status & (RNG_INT_STATUS_MASTER_FAIL_LOCKOUT_IRQ_MASK | + RNG_INT_STATUS_NIST_FAIL_IRQ_MASK)) != 0) { + + if (num_resets >= MAX_RESETS_PER_READ) + return max - num_remaining; + + iproc_rng200_restart(priv->base); + num_resets++; + } + + /* Are there any random numbers available? */ + if ((ioread32(priv->base + RNG_FIFO_COUNT_OFFSET) & + RNG_FIFO_COUNT_RNG_FIFO_COUNT_MASK) > 0) { + + if (num_remaining >= sizeof(uint32_t)) { + /* Buffer has room to store entire word */ + *(uint32_t *)buf = ioread32(priv->base + + RNG_FIFO_DATA_OFFSET); + buf += sizeof(uint32_t); + num_remaining -= sizeof(uint32_t); + } else { + /* Buffer can only store partial word */ + uint32_t rnd_number = ioread32(priv->base + + RNG_FIFO_DATA_OFFSET); + memcpy(buf, &rnd_number, num_remaining); + buf += num_remaining; + num_remaining = 0; + } + + /* Reset the IDLE timeout */ + idle_endtime = jiffies + MAX_IDLE_TIME; + } else { + if (!wait) + /* Cannot wait, return immediately */ + return max - num_remaining; + + /* Can wait, give others chance to run */ + usleep_range(min(num_remaining * 10, 500U), 500); + } + } + + return max - num_remaining; +} + +static int iproc_rng200_init(struct hwrng *rng) +{ + uint32_t val; + struct iproc_rng200_dev *priv; + + priv = (struct iproc_rng200_dev *)rng->priv; + + /* Setup RNG. */ + val = ioread32(priv->base + RNG_CTRL_OFFSET); + val &= ~RNG_CTRL_RNG_RBGEN_MASK; + val |= RNG_CTRL_RNG_RBGEN_ENABLE; + iowrite32(val, priv->base + RNG_CTRL_OFFSET); + + return 0; +} + +static void iproc_rng200_cleanup(struct hwrng *rng) +{ + uint32_t val; + struct iproc_rng200_dev *priv; + + priv = (struct iproc_rng200_dev *)rng->priv; + + /* Disable RNG hardware */ + val = ioread32(priv->base + RNG_CTRL_OFFSET); + val &= ~RNG_CTRL_RNG_RBGEN_MASK; + val |= RNG_CTRL_RNG_RBGEN_DISABLE; + iowrite32(val, priv->base + RNG_CTRL_OFFSET); +} + +static struct hwrng iproc_rng200_ops = { + .name = "iproc-rng200", + .read = iproc_rng200_read, + .init = iproc_rng200_init, + .cleanup = iproc_rng200_cleanup, +}; + +static int iproc_rng200_probe(struct platform_device *pdev) +{ + struct iproc_rng200_dev *priv; + struct resource *res; + struct device *dev = &pdev->dev; + int ret; + + priv = devm_kzalloc(dev, sizeof(struct iproc_rng200_dev), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + iproc_rng200_ops.priv = (unsigned long)priv; + platform_set_drvdata(pdev, priv); + + /* Map peripheral */ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(dev, "failed to get rng resources\n"); + return -EINVAL; + } + + priv->base = devm_ioremap_resource(dev, res); + if (IS_ERR(priv->base)) { + dev_err(dev, "failed to remap rng regs\n"); + return PTR_ERR(priv->base); + } + + /* Register driver */ + ret = hwrng_register(&iproc_rng200_ops); + if (ret) { + dev_err(dev, "hwrng registration failed\n"); + return ret; + } + + dev_info(dev, "hwrng registered\n"); + + return 0; +} + +static int iproc_rng200_remove(struct platform_device *pdev) +{ + /* Unregister driver */ + hwrng_unregister(&iproc_rng200_ops); + + return 0; +} + +static const struct of_device_id iproc_rng200_of_match[] = { + { .compatible = "brcm,iproc-rng200", }, + {}, +}; +MODULE_DEVICE_TABLE(of, iproc_rng200_of_match); + +static struct platform_driver iproc_rng200_driver = { + .driver = { + .name = "iproc-rng200", + .of_match_table = iproc_rng200_of_match, + }, + .probe = iproc_rng200_probe, + .remove = iproc_rng200_remove, +}; +module_platform_driver(iproc_rng200_driver); + +MODULE_AUTHOR("Broadcom"); +MODULE_DESCRIPTION("iProc RNG200 Random Number Generator driver"); +MODULE_LICENSE("GPL v2"); -- GitLab From 8b5f5a073fda33bbe96b3eb1bffca32010ccaf0e Mon Sep 17 00:00:00 2001 From: Laura Abbott Date: Wed, 25 Feb 2015 14:14:55 -0800 Subject: [PATCH 02929/11651] arm64: Don't use is_module_addr in setting page attributes The set_memory_* functions currently only support module addresses. The addresses are validated using is_module_addr. That function is special though and relies on internal state in the module subsystem to work properly. At the time of module initialization and calling set_memory_*, it's too early for is_module_addr to work properly so it always returns false. Rather than be subject to the whims of the module state, just bounds check against the module virtual address range. Signed-off-by: Laura Abbott Signed-off-by: Catalin Marinas --- arch/arm64/mm/pageattr.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c index bb0ea94c4ba1..1d3ec3ddd84b 100644 --- a/arch/arm64/mm/pageattr.c +++ b/arch/arm64/mm/pageattr.c @@ -51,7 +51,10 @@ static int change_memory_common(unsigned long addr, int numpages, WARN_ON_ONCE(1); } - if (!is_module_address(start) || !is_module_address(end - 1)) + if (start < MODULES_VADDR || start >= MODULES_END) + return -EINVAL; + + if (end < MODULES_VADDR || end >= MODULES_END) return -EINVAL; data.set_mask = set_mask; -- GitLab From 168e47f2a6581fdbc5bb1845aeca1e50e2bc5c4b Mon Sep 17 00:00:00 2001 From: Laura Abbott Date: Wed, 25 Feb 2015 14:14:57 -0800 Subject: [PATCH 02930/11651] kernel/module.c: Update debug alignment after symtable generation When CONFIG_DEBUG_SET_MODULE_RONX is enabled, the sizes of module sections are aligned up so appropriate permissions can be applied. Adjusting for the symbol table may cause them to become unaligned. Make sure to re-align the sizes afterward. Signed-off-by: Laura Abbott Acked-by: Rusty Russell Signed-off-by: Catalin Marinas --- kernel/module.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/module.c b/kernel/module.c index b34813f725e9..cc93cf68653c 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -2313,11 +2313,13 @@ static void layout_symtab(struct module *mod, struct load_info *info) info->symoffs = ALIGN(mod->core_size, symsect->sh_addralign ?: 1); info->stroffs = mod->core_size = info->symoffs + ndst * sizeof(Elf_Sym); mod->core_size += strtab_size; + mod->core_size = debug_align(mod->core_size); /* Put string table section at end of init part of module. */ strsect->sh_flags |= SHF_ALLOC; strsect->sh_entsize = get_offset(mod, &mod->init_size, strsect, info->index.str) | INIT_OFFSET_MASK; + mod->init_size = debug_align(mod->init_size); pr_debug("\t%s\n", info->secstrings + strsect->sh_name); } -- GitLab From d124380674b58f62d0ef974630d74d67bb8afeb0 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 5 Mar 2015 20:49:06 +0300 Subject: [PATCH 02931/11651] ALSA: opl3: small array underflow There is a missing lower bound check on "pitchbend" so it means we can read up to 6 elements before the start of the opl3_note_table[] array. Thanks to Clemens Ladisch for his help with this patch. Signed-off-by: Dan Carpenter Signed-off-by: Takashi Iwai --- sound/drivers/opl3/opl3_midi.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/drivers/opl3/opl3_midi.c b/sound/drivers/opl3/opl3_midi.c index f62780ed64ad..7821b07415a7 100644 --- a/sound/drivers/opl3/opl3_midi.c +++ b/sound/drivers/opl3/opl3_midi.c @@ -105,6 +105,8 @@ static void snd_opl3_calc_pitch(unsigned char *fnum, unsigned char *blocknum, int pitchbend = chan->midi_pitchbend; int segment; + if (pitchbend < -0x2000) + pitchbend = -0x2000; if (pitchbend > 0x1FFF) pitchbend = 0x1FFF; -- GitLab From 70658b99490dd86cfdbf4fca117bbe2ef9a80d03 Mon Sep 17 00:00:00 2001 From: Hui Wang Date: Fri, 6 Mar 2015 14:03:57 +0800 Subject: [PATCH 02932/11651] ALSA: hda - One more Dell macine needs DELL1_MIC_NO_PRESENCE quirk Cc: BugLink: https://bugs.launchpad.net/bugs/1428947 Signed-off-by: Hui Wang Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index b2b24a8b3dac..526398a4a442 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -5209,6 +5209,13 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { {0x17, 0x40000000}, {0x1d, 0x40700001}, {0x21, 0x02211040}), + SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, + ALC255_STANDARD_PINS, + {0x12, 0x90a60170}, + {0x14, 0x90170140}, + {0x17, 0x40000000}, + {0x1d, 0x40700001}, + {0x21, 0x02211050}), SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4, {0x12, 0x90a60130}, {0x13, 0x40000000}, -- GitLab From e6f219b8ec5e4227c8b87b758afb48ed102b4210 Mon Sep 17 00:00:00 2001 From: Hongzhou Yang Date: Wed, 21 Jan 2015 13:28:17 +0800 Subject: [PATCH 02933/11651] ARM: dts: mt8135: Add pinctrl/GPIO/EINT node for mt8135. Add pinctrl,GPIO and EINT node to mt8135.dtsi. Signed-off-by: Hongzhou Yang Acked-by: Linus Walleij Singed-off-by: Matthias Brugger --- arch/arm/boot/dts/mt8135-pinfunc.h | 1302 ++++++++++++++++++++++++++++ arch/arm/boot/dts/mt8135.dtsi | 25 + 2 files changed, 1327 insertions(+) create mode 100644 arch/arm/boot/dts/mt8135-pinfunc.h diff --git a/arch/arm/boot/dts/mt8135-pinfunc.h b/arch/arm/boot/dts/mt8135-pinfunc.h new file mode 100644 index 000000000000..5a609875cb18 --- /dev/null +++ b/arch/arm/boot/dts/mt8135-pinfunc.h @@ -0,0 +1,1302 @@ +/* + * Copyright (c) 2014 MediaTek Inc. + * Author: Hongzhou.Yang + * + * 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. + */ + +#ifndef __DTS_MT8135_PINFUNC_H +#define __DTS_MT8135_PINFUNC_H + +#include + +#define MT8135_PIN_0_MSDC0_DAT7__FUNC_GPIO0 (MTK_PIN_NO(0) | 0) +#define MT8135_PIN_0_MSDC0_DAT7__FUNC_MSDC0_DAT7 (MTK_PIN_NO(0) | 1) +#define MT8135_PIN_0_MSDC0_DAT7__FUNC_EINT49 (MTK_PIN_NO(0) | 2) +#define MT8135_PIN_0_MSDC0_DAT7__FUNC_I2SOUT_DAT (MTK_PIN_NO(0) | 3) +#define MT8135_PIN_0_MSDC0_DAT7__FUNC_DAC_DAT_OUT (MTK_PIN_NO(0) | 4) +#define MT8135_PIN_0_MSDC0_DAT7__FUNC_PCM1_DO (MTK_PIN_NO(0) | 5) +#define MT8135_PIN_0_MSDC0_DAT7__FUNC_SPI1_MO (MTK_PIN_NO(0) | 6) +#define MT8135_PIN_0_MSDC0_DAT7__FUNC_NALE (MTK_PIN_NO(0) | 7) + +#define MT8135_PIN_1_MSDC0_DAT6__FUNC_GPIO1 (MTK_PIN_NO(1) | 0) +#define MT8135_PIN_1_MSDC0_DAT6__FUNC_MSDC0_DAT6 (MTK_PIN_NO(1) | 1) +#define MT8135_PIN_1_MSDC0_DAT6__FUNC_EINT48 (MTK_PIN_NO(1) | 2) +#define MT8135_PIN_1_MSDC0_DAT6__FUNC_I2SIN_WS (MTK_PIN_NO(1) | 3) +#define MT8135_PIN_1_MSDC0_DAT6__FUNC_DAC_WS (MTK_PIN_NO(1) | 4) +#define MT8135_PIN_1_MSDC0_DAT6__FUNC_PCM1_WS (MTK_PIN_NO(1) | 5) +#define MT8135_PIN_1_MSDC0_DAT6__FUNC_SPI1_CSN (MTK_PIN_NO(1) | 6) +#define MT8135_PIN_1_MSDC0_DAT6__FUNC_NCLE (MTK_PIN_NO(1) | 7) + +#define MT8135_PIN_2_MSDC0_DAT5__FUNC_GPIO2 (MTK_PIN_NO(2) | 0) +#define MT8135_PIN_2_MSDC0_DAT5__FUNC_MSDC0_DAT5 (MTK_PIN_NO(2) | 1) +#define MT8135_PIN_2_MSDC0_DAT5__FUNC_EINT47 (MTK_PIN_NO(2) | 2) +#define MT8135_PIN_2_MSDC0_DAT5__FUNC_I2SIN_CK (MTK_PIN_NO(2) | 3) +#define MT8135_PIN_2_MSDC0_DAT5__FUNC_DAC_CK (MTK_PIN_NO(2) | 4) +#define MT8135_PIN_2_MSDC0_DAT5__FUNC_PCM1_CK (MTK_PIN_NO(2) | 5) +#define MT8135_PIN_2_MSDC0_DAT5__FUNC_SPI1_CLK (MTK_PIN_NO(2) | 6) +#define MT8135_PIN_2_MSDC0_DAT5__FUNC_NLD4 (MTK_PIN_NO(2) | 7) + +#define MT8135_PIN_3_MSDC0_DAT4__FUNC_GPIO3 (MTK_PIN_NO(3) | 0) +#define MT8135_PIN_3_MSDC0_DAT4__FUNC_MSDC0_DAT4 (MTK_PIN_NO(3) | 1) +#define MT8135_PIN_3_MSDC0_DAT4__FUNC_EINT46 (MTK_PIN_NO(3) | 2) +#define MT8135_PIN_3_MSDC0_DAT4__FUNC_A_FUNC_CK (MTK_PIN_NO(3) | 3) +#define MT8135_PIN_3_MSDC0_DAT4__FUNC_LSCE1B_2X (MTK_PIN_NO(3) | 6) +#define MT8135_PIN_3_MSDC0_DAT4__FUNC_NLD5 (MTK_PIN_NO(3) | 7) + +#define MT8135_PIN_4_MSDC0_CMD__FUNC_GPIO4 (MTK_PIN_NO(4) | 0) +#define MT8135_PIN_4_MSDC0_CMD__FUNC_MSDC0_CMD (MTK_PIN_NO(4) | 1) +#define MT8135_PIN_4_MSDC0_CMD__FUNC_EINT41 (MTK_PIN_NO(4) | 2) +#define MT8135_PIN_4_MSDC0_CMD__FUNC_A_FUNC_DOUT_0 (MTK_PIN_NO(4) | 3) +#define MT8135_PIN_4_MSDC0_CMD__FUNC_USB_TEST_IO_0 (MTK_PIN_NO(4) | 5) +#define MT8135_PIN_4_MSDC0_CMD__FUNC_LRSTB_2X (MTK_PIN_NO(4) | 6) +#define MT8135_PIN_4_MSDC0_CMD__FUNC_NRNB (MTK_PIN_NO(4) | 7) + +#define MT8135_PIN_5_MSDC0_CLK__FUNC_GPIO5 (MTK_PIN_NO(5) | 0) +#define MT8135_PIN_5_MSDC0_CLK__FUNC_MSDC0_CLK (MTK_PIN_NO(5) | 1) +#define MT8135_PIN_5_MSDC0_CLK__FUNC_EINT40 (MTK_PIN_NO(5) | 2) +#define MT8135_PIN_5_MSDC0_CLK__FUNC_A_FUNC_DOUT_1 (MTK_PIN_NO(5) | 3) +#define MT8135_PIN_5_MSDC0_CLK__FUNC_USB_TEST_IO_1 (MTK_PIN_NO(5) | 5) +#define MT8135_PIN_5_MSDC0_CLK__FUNC_LPTE (MTK_PIN_NO(5) | 6) +#define MT8135_PIN_5_MSDC0_CLK__FUNC_NREB (MTK_PIN_NO(5) | 7) + +#define MT8135_PIN_6_MSDC0_DAT3__FUNC_GPIO6 (MTK_PIN_NO(6) | 0) +#define MT8135_PIN_6_MSDC0_DAT3__FUNC_MSDC0_DAT3 (MTK_PIN_NO(6) | 1) +#define MT8135_PIN_6_MSDC0_DAT3__FUNC_EINT45 (MTK_PIN_NO(6) | 2) +#define MT8135_PIN_6_MSDC0_DAT3__FUNC_A_FUNC_DOUT_2 (MTK_PIN_NO(6) | 3) +#define MT8135_PIN_6_MSDC0_DAT3__FUNC_USB_TEST_IO_2 (MTK_PIN_NO(6) | 5) +#define MT8135_PIN_6_MSDC0_DAT3__FUNC_LSCE0B_2X (MTK_PIN_NO(6) | 6) +#define MT8135_PIN_6_MSDC0_DAT3__FUNC_NLD7 (MTK_PIN_NO(6) | 7) + +#define MT8135_PIN_7_MSDC0_DAT2__FUNC_GPIO7 (MTK_PIN_NO(7) | 0) +#define MT8135_PIN_7_MSDC0_DAT2__FUNC_MSDC0_DAT2 (MTK_PIN_NO(7) | 1) +#define MT8135_PIN_7_MSDC0_DAT2__FUNC_EINT44 (MTK_PIN_NO(7) | 2) +#define MT8135_PIN_7_MSDC0_DAT2__FUNC_A_FUNC_DOUT_3 (MTK_PIN_NO(7) | 3) +#define MT8135_PIN_7_MSDC0_DAT2__FUNC_USB_TEST_IO_3 (MTK_PIN_NO(7) | 5) +#define MT8135_PIN_7_MSDC0_DAT2__FUNC_LSA0_2X (MTK_PIN_NO(7) | 6) +#define MT8135_PIN_7_MSDC0_DAT2__FUNC_NLD14 (MTK_PIN_NO(7) | 7) + +#define MT8135_PIN_8_MSDC0_DAT1__FUNC_GPIO8 (MTK_PIN_NO(8) | 0) +#define MT8135_PIN_8_MSDC0_DAT1__FUNC_MSDC0_DAT1 (MTK_PIN_NO(8) | 1) +#define MT8135_PIN_8_MSDC0_DAT1__FUNC_EINT43 (MTK_PIN_NO(8) | 2) +#define MT8135_PIN_8_MSDC0_DAT1__FUNC_USB_TEST_IO_4 (MTK_PIN_NO(8) | 5) +#define MT8135_PIN_8_MSDC0_DAT1__FUNC_LSCK_2X (MTK_PIN_NO(8) | 6) +#define MT8135_PIN_8_MSDC0_DAT1__FUNC_NLD11 (MTK_PIN_NO(8) | 7) + +#define MT8135_PIN_9_MSDC0_DAT0__FUNC_GPIO9 (MTK_PIN_NO(9) | 0) +#define MT8135_PIN_9_MSDC0_DAT0__FUNC_MSDC0_DAT0 (MTK_PIN_NO(9) | 1) +#define MT8135_PIN_9_MSDC0_DAT0__FUNC_EINT42 (MTK_PIN_NO(9) | 2) +#define MT8135_PIN_9_MSDC0_DAT0__FUNC_USB_TEST_IO_5 (MTK_PIN_NO(9) | 5) +#define MT8135_PIN_9_MSDC0_DAT0__FUNC_LSDA_2X (MTK_PIN_NO(9) | 6) + +#define MT8135_PIN_10_NCEB0__FUNC_GPIO10 (MTK_PIN_NO(10) | 0) +#define MT8135_PIN_10_NCEB0__FUNC_NCEB0 (MTK_PIN_NO(10) | 1) +#define MT8135_PIN_10_NCEB0__FUNC_EINT139 (MTK_PIN_NO(10) | 2) +#define MT8135_PIN_10_NCEB0__FUNC_TESTA_OUT4 (MTK_PIN_NO(10) | 7) + +#define MT8135_PIN_11_NCEB1__FUNC_GPIO11 (MTK_PIN_NO(11) | 0) +#define MT8135_PIN_11_NCEB1__FUNC_NCEB1 (MTK_PIN_NO(11) | 1) +#define MT8135_PIN_11_NCEB1__FUNC_EINT140 (MTK_PIN_NO(11) | 2) +#define MT8135_PIN_11_NCEB1__FUNC_USB_DRVVBUS (MTK_PIN_NO(11) | 6) +#define MT8135_PIN_11_NCEB1__FUNC_TESTA_OUT5 (MTK_PIN_NO(11) | 7) + +#define MT8135_PIN_12_NRNB__FUNC_GPIO12 (MTK_PIN_NO(12) | 0) +#define MT8135_PIN_12_NRNB__FUNC_NRNB (MTK_PIN_NO(12) | 1) +#define MT8135_PIN_12_NRNB__FUNC_EINT141 (MTK_PIN_NO(12) | 2) +#define MT8135_PIN_12_NRNB__FUNC_A_FUNC_DOUT_4 (MTK_PIN_NO(12) | 3) +#define MT8135_PIN_12_NRNB__FUNC_TESTA_OUT6 (MTK_PIN_NO(12) | 7) + +#define MT8135_PIN_13_NCLE__FUNC_GPIO13 (MTK_PIN_NO(13) | 0) +#define MT8135_PIN_13_NCLE__FUNC_NCLE (MTK_PIN_NO(13) | 1) +#define MT8135_PIN_13_NCLE__FUNC_EINT142 (MTK_PIN_NO(13) | 2) +#define MT8135_PIN_13_NCLE__FUNC_A_FUNC_DOUT_5 (MTK_PIN_NO(13) | 3) +#define MT8135_PIN_13_NCLE__FUNC_CM2PDN_1X (MTK_PIN_NO(13) | 4) +#define MT8135_PIN_13_NCLE__FUNC_NALE (MTK_PIN_NO(13) | 6) +#define MT8135_PIN_13_NCLE__FUNC_TESTA_OUT7 (MTK_PIN_NO(13) | 7) + +#define MT8135_PIN_14_NALE__FUNC_GPIO14 (MTK_PIN_NO(14) | 0) +#define MT8135_PIN_14_NALE__FUNC_NALE (MTK_PIN_NO(14) | 1) +#define MT8135_PIN_14_NALE__FUNC_EINT143 (MTK_PIN_NO(14) | 2) +#define MT8135_PIN_14_NALE__FUNC_A_FUNC_DOUT_6 (MTK_PIN_NO(14) | 3) +#define MT8135_PIN_14_NALE__FUNC_CM2MCLK_1X (MTK_PIN_NO(14) | 4) +#define MT8135_PIN_14_NALE__FUNC_IRDA_RXD (MTK_PIN_NO(14) | 5) +#define MT8135_PIN_14_NALE__FUNC_NCLE (MTK_PIN_NO(14) | 6) +#define MT8135_PIN_14_NALE__FUNC_TESTA_OUT8 (MTK_PIN_NO(14) | 7) + +#define MT8135_PIN_15_NREB__FUNC_GPIO15 (MTK_PIN_NO(15) | 0) +#define MT8135_PIN_15_NREB__FUNC_NREB (MTK_PIN_NO(15) | 1) +#define MT8135_PIN_15_NREB__FUNC_EINT144 (MTK_PIN_NO(15) | 2) +#define MT8135_PIN_15_NREB__FUNC_A_FUNC_DOUT_7 (MTK_PIN_NO(15) | 3) +#define MT8135_PIN_15_NREB__FUNC_CM2RST_1X (MTK_PIN_NO(15) | 4) +#define MT8135_PIN_15_NREB__FUNC_IRDA_TXD (MTK_PIN_NO(15) | 5) +#define MT8135_PIN_15_NREB__FUNC_TESTA_OUT9 (MTK_PIN_NO(15) | 7) + +#define MT8135_PIN_16_NWEB__FUNC_GPIO16 (MTK_PIN_NO(16) | 0) +#define MT8135_PIN_16_NWEB__FUNC_NWEB (MTK_PIN_NO(16) | 1) +#define MT8135_PIN_16_NWEB__FUNC_EINT145 (MTK_PIN_NO(16) | 2) +#define MT8135_PIN_16_NWEB__FUNC_A_FUNC_DIN_0 (MTK_PIN_NO(16) | 3) +#define MT8135_PIN_16_NWEB__FUNC_CM2PCLK_1X (MTK_PIN_NO(16) | 4) +#define MT8135_PIN_16_NWEB__FUNC_IRDA_PDN (MTK_PIN_NO(16) | 5) +#define MT8135_PIN_16_NWEB__FUNC_TESTA_OUT10 (MTK_PIN_NO(16) | 7) + +#define MT8135_PIN_17_NLD0__FUNC_GPIO17 (MTK_PIN_NO(17) | 0) +#define MT8135_PIN_17_NLD0__FUNC_NLD0 (MTK_PIN_NO(17) | 1) +#define MT8135_PIN_17_NLD0__FUNC_EINT146 (MTK_PIN_NO(17) | 2) +#define MT8135_PIN_17_NLD0__FUNC_A_FUNC_DIN_1 (MTK_PIN_NO(17) | 3) +#define MT8135_PIN_17_NLD0__FUNC_CM2DAT_1X_0 (MTK_PIN_NO(17) | 4) +#define MT8135_PIN_17_NLD0__FUNC_I2SIN_CK (MTK_PIN_NO(17) | 5) +#define MT8135_PIN_17_NLD0__FUNC_DAC_CK (MTK_PIN_NO(17) | 6) +#define MT8135_PIN_17_NLD0__FUNC_TESTA_OUT11 (MTK_PIN_NO(17) | 7) + +#define MT8135_PIN_18_NLD1__FUNC_GPIO18 (MTK_PIN_NO(18) | 0) +#define MT8135_PIN_18_NLD1__FUNC_NLD1 (MTK_PIN_NO(18) | 1) +#define MT8135_PIN_18_NLD1__FUNC_EINT147 (MTK_PIN_NO(18) | 2) +#define MT8135_PIN_18_NLD1__FUNC_A_FUNC_DIN_2 (MTK_PIN_NO(18) | 3) +#define MT8135_PIN_18_NLD1__FUNC_CM2DAT_1X_1 (MTK_PIN_NO(18) | 4) +#define MT8135_PIN_18_NLD1__FUNC_I2SIN_WS (MTK_PIN_NO(18) | 5) +#define MT8135_PIN_18_NLD1__FUNC_DAC_WS (MTK_PIN_NO(18) | 6) +#define MT8135_PIN_18_NLD1__FUNC_TESTA_OUT12 (MTK_PIN_NO(18) | 7) + +#define MT8135_PIN_19_NLD2__FUNC_GPIO19 (MTK_PIN_NO(19) | 0) +#define MT8135_PIN_19_NLD2__FUNC_NLD2 (MTK_PIN_NO(19) | 1) +#define MT8135_PIN_19_NLD2__FUNC_EINT148 (MTK_PIN_NO(19) | 2) +#define MT8135_PIN_19_NLD2__FUNC_A_FUNC_DIN_3 (MTK_PIN_NO(19) | 3) +#define MT8135_PIN_19_NLD2__FUNC_CM2DAT_1X_2 (MTK_PIN_NO(19) | 4) +#define MT8135_PIN_19_NLD2__FUNC_I2SOUT_DAT (MTK_PIN_NO(19) | 5) +#define MT8135_PIN_19_NLD2__FUNC_DAC_DAT_OUT (MTK_PIN_NO(19) | 6) +#define MT8135_PIN_19_NLD2__FUNC_TESTA_OUT13 (MTK_PIN_NO(19) | 7) + +#define MT8135_PIN_20_NLD3__FUNC_GPIO20 (MTK_PIN_NO(20) | 0) +#define MT8135_PIN_20_NLD3__FUNC_NLD3 (MTK_PIN_NO(20) | 1) +#define MT8135_PIN_20_NLD3__FUNC_EINT149 (MTK_PIN_NO(20) | 2) +#define MT8135_PIN_20_NLD3__FUNC_A_FUNC_DIN_4 (MTK_PIN_NO(20) | 3) +#define MT8135_PIN_20_NLD3__FUNC_CM2DAT_1X_3 (MTK_PIN_NO(20) | 4) +#define MT8135_PIN_20_NLD3__FUNC_TESTA_OUT14 (MTK_PIN_NO(20) | 7) + +#define MT8135_PIN_21_NLD4__FUNC_GPIO21 (MTK_PIN_NO(21) | 0) +#define MT8135_PIN_21_NLD4__FUNC_NLD4 (MTK_PIN_NO(21) | 1) +#define MT8135_PIN_21_NLD4__FUNC_EINT150 (MTK_PIN_NO(21) | 2) +#define MT8135_PIN_21_NLD4__FUNC_A_FUNC_DIN_5 (MTK_PIN_NO(21) | 3) +#define MT8135_PIN_21_NLD4__FUNC_CM2DAT_1X_4 (MTK_PIN_NO(21) | 4) +#define MT8135_PIN_21_NLD4__FUNC_TESTA_OUT15 (MTK_PIN_NO(21) | 7) + +#define MT8135_PIN_22_NLD5__FUNC_GPIO22 (MTK_PIN_NO(22) | 0) +#define MT8135_PIN_22_NLD5__FUNC_NLD5 (MTK_PIN_NO(22) | 1) +#define MT8135_PIN_22_NLD5__FUNC_EINT151 (MTK_PIN_NO(22) | 2) +#define MT8135_PIN_22_NLD5__FUNC_A_FUNC_DIN_6 (MTK_PIN_NO(22) | 3) +#define MT8135_PIN_22_NLD5__FUNC_CM2DAT_1X_5 (MTK_PIN_NO(22) | 4) +#define MT8135_PIN_22_NLD5__FUNC_TESTA_OUT16 (MTK_PIN_NO(22) | 7) + +#define MT8135_PIN_23_NLD6__FUNC_GPIO23 (MTK_PIN_NO(23) | 0) +#define MT8135_PIN_23_NLD6__FUNC_NLD6 (MTK_PIN_NO(23) | 1) +#define MT8135_PIN_23_NLD6__FUNC_EINT152 (MTK_PIN_NO(23) | 2) +#define MT8135_PIN_23_NLD6__FUNC_A_FUNC_DIN_7 (MTK_PIN_NO(23) | 3) +#define MT8135_PIN_23_NLD6__FUNC_CM2DAT_1X_6 (MTK_PIN_NO(23) | 4) +#define MT8135_PIN_23_NLD6__FUNC_TESTA_OUT17 (MTK_PIN_NO(23) | 7) + +#define MT8135_PIN_24_NLD7__FUNC_GPIO24 (MTK_PIN_NO(24) | 0) +#define MT8135_PIN_24_NLD7__FUNC_NLD7 (MTK_PIN_NO(24) | 1) +#define MT8135_PIN_24_NLD7__FUNC_EINT153 (MTK_PIN_NO(24) | 2) +#define MT8135_PIN_24_NLD7__FUNC_A_FUNC_DIN_8 (MTK_PIN_NO(24) | 3) +#define MT8135_PIN_24_NLD7__FUNC_CM2DAT_1X_7 (MTK_PIN_NO(24) | 4) +#define MT8135_PIN_24_NLD7__FUNC_TESTA_OUT18 (MTK_PIN_NO(24) | 7) + +#define MT8135_PIN_25_NLD8__FUNC_GPIO25 (MTK_PIN_NO(25) | 0) +#define MT8135_PIN_25_NLD8__FUNC_NLD8 (MTK_PIN_NO(25) | 1) +#define MT8135_PIN_25_NLD8__FUNC_EINT154 (MTK_PIN_NO(25) | 2) +#define MT8135_PIN_25_NLD8__FUNC_CM2DAT_1X_8 (MTK_PIN_NO(25) | 4) + +#define MT8135_PIN_26_NLD9__FUNC_GPIO26 (MTK_PIN_NO(26) | 0) +#define MT8135_PIN_26_NLD9__FUNC_NLD9 (MTK_PIN_NO(26) | 1) +#define MT8135_PIN_26_NLD9__FUNC_EINT155 (MTK_PIN_NO(26) | 2) +#define MT8135_PIN_26_NLD9__FUNC_CM2DAT_1X_9 (MTK_PIN_NO(26) | 4) +#define MT8135_PIN_26_NLD9__FUNC_PWM1 (MTK_PIN_NO(26) | 5) + +#define MT8135_PIN_27_NLD10__FUNC_GPIO27 (MTK_PIN_NO(27) | 0) +#define MT8135_PIN_27_NLD10__FUNC_NLD10 (MTK_PIN_NO(27) | 1) +#define MT8135_PIN_27_NLD10__FUNC_EINT156 (MTK_PIN_NO(27) | 2) +#define MT8135_PIN_27_NLD10__FUNC_CM2VSYNC_1X (MTK_PIN_NO(27) | 4) +#define MT8135_PIN_27_NLD10__FUNC_PWM2 (MTK_PIN_NO(27) | 5) + +#define MT8135_PIN_28_NLD11__FUNC_GPIO28 (MTK_PIN_NO(28) | 0) +#define MT8135_PIN_28_NLD11__FUNC_NLD11 (MTK_PIN_NO(28) | 1) +#define MT8135_PIN_28_NLD11__FUNC_EINT157 (MTK_PIN_NO(28) | 2) +#define MT8135_PIN_28_NLD11__FUNC_CM2HSYNC_1X (MTK_PIN_NO(28) | 4) +#define MT8135_PIN_28_NLD11__FUNC_PWM3 (MTK_PIN_NO(28) | 5) + +#define MT8135_PIN_29_NLD12__FUNC_GPIO29 (MTK_PIN_NO(29) | 0) +#define MT8135_PIN_29_NLD12__FUNC_NLD12 (MTK_PIN_NO(29) | 1) +#define MT8135_PIN_29_NLD12__FUNC_EINT158 (MTK_PIN_NO(29) | 2) +#define MT8135_PIN_29_NLD12__FUNC_I2SIN_CK (MTK_PIN_NO(29) | 3) +#define MT8135_PIN_29_NLD12__FUNC_DAC_CK (MTK_PIN_NO(29) | 4) +#define MT8135_PIN_29_NLD12__FUNC_PCM1_CK (MTK_PIN_NO(29) | 5) + +#define MT8135_PIN_30_NLD13__FUNC_GPIO30 (MTK_PIN_NO(30) | 0) +#define MT8135_PIN_30_NLD13__FUNC_NLD13 (MTK_PIN_NO(30) | 1) +#define MT8135_PIN_30_NLD13__FUNC_EINT159 (MTK_PIN_NO(30) | 2) +#define MT8135_PIN_30_NLD13__FUNC_I2SIN_WS (MTK_PIN_NO(30) | 3) +#define MT8135_PIN_30_NLD13__FUNC_DAC_WS (MTK_PIN_NO(30) | 4) +#define MT8135_PIN_30_NLD13__FUNC_PCM1_WS (MTK_PIN_NO(30) | 5) + +#define MT8135_PIN_31_NLD14__FUNC_GPIO31 (MTK_PIN_NO(31) | 0) +#define MT8135_PIN_31_NLD14__FUNC_NLD14 (MTK_PIN_NO(31) | 1) +#define MT8135_PIN_31_NLD14__FUNC_EINT160 (MTK_PIN_NO(31) | 2) +#define MT8135_PIN_31_NLD14__FUNC_I2SOUT_DAT (MTK_PIN_NO(31) | 3) +#define MT8135_PIN_31_NLD14__FUNC_DAC_DAT_OUT (MTK_PIN_NO(31) | 4) +#define MT8135_PIN_31_NLD14__FUNC_PCM1_DO (MTK_PIN_NO(31) | 5) + +#define MT8135_PIN_32_NLD15__FUNC_GPIO32 (MTK_PIN_NO(32) | 0) +#define MT8135_PIN_32_NLD15__FUNC_NLD15 (MTK_PIN_NO(32) | 1) +#define MT8135_PIN_32_NLD15__FUNC_EINT161 (MTK_PIN_NO(32) | 2) +#define MT8135_PIN_32_NLD15__FUNC_DISP_PWM (MTK_PIN_NO(32) | 3) +#define MT8135_PIN_32_NLD15__FUNC_PWM4 (MTK_PIN_NO(32) | 4) +#define MT8135_PIN_32_NLD15__FUNC_PCM1_DI (MTK_PIN_NO(32) | 5) + +#define MT8135_PIN_33_MSDC0_RSTB__FUNC_GPIO33 (MTK_PIN_NO(33) | 0) +#define MT8135_PIN_33_MSDC0_RSTB__FUNC_MSDC0_RSTB (MTK_PIN_NO(33) | 1) +#define MT8135_PIN_33_MSDC0_RSTB__FUNC_EINT50 (MTK_PIN_NO(33) | 2) +#define MT8135_PIN_33_MSDC0_RSTB__FUNC_I2SIN_DAT (MTK_PIN_NO(33) | 3) +#define MT8135_PIN_33_MSDC0_RSTB__FUNC_PCM1_DI (MTK_PIN_NO(33) | 5) +#define MT8135_PIN_33_MSDC0_RSTB__FUNC_SPI1_MI (MTK_PIN_NO(33) | 6) +#define MT8135_PIN_33_MSDC0_RSTB__FUNC_NLD10 (MTK_PIN_NO(33) | 7) + +#define MT8135_PIN_34_IDDIG__FUNC_GPIO34 (MTK_PIN_NO(34) | 0) +#define MT8135_PIN_34_IDDIG__FUNC_IDDIG (MTK_PIN_NO(34) | 1) +#define MT8135_PIN_34_IDDIG__FUNC_EINT34 (MTK_PIN_NO(34) | 2) + +#define MT8135_PIN_35_SCL3__FUNC_GPIO35 (MTK_PIN_NO(35) | 0) +#define MT8135_PIN_35_SCL3__FUNC_SCL3 (MTK_PIN_NO(35) | 1) +#define MT8135_PIN_35_SCL3__FUNC_EINT96 (MTK_PIN_NO(35) | 2) +#define MT8135_PIN_35_SCL3__FUNC_CLKM6 (MTK_PIN_NO(35) | 3) +#define MT8135_PIN_35_SCL3__FUNC_PWM6 (MTK_PIN_NO(35) | 4) + +#define MT8135_PIN_36_SDA3__FUNC_GPIO36 (MTK_PIN_NO(36) | 0) +#define MT8135_PIN_36_SDA3__FUNC_SDA3 (MTK_PIN_NO(36) | 1) +#define MT8135_PIN_36_SDA3__FUNC_EINT97 (MTK_PIN_NO(36) | 2) + +#define MT8135_PIN_37_AUD_CLK_MOSI__FUNC_GPIO37 (MTK_PIN_NO(37) | 0) +#define MT8135_PIN_37_AUD_CLK_MOSI__FUNC_AUD_CLK (MTK_PIN_NO(37) | 1) +#define MT8135_PIN_37_AUD_CLK_MOSI__FUNC_ADC_CK (MTK_PIN_NO(37) | 2) +#define MT8135_PIN_37_AUD_CLK_MOSI__FUNC_HDMI_SDATA0 (MTK_PIN_NO(37) | 3) +#define MT8135_PIN_37_AUD_CLK_MOSI__FUNC_EINT19 (MTK_PIN_NO(37) | 4) +#define MT8135_PIN_37_AUD_CLK_MOSI__FUNC_USB_TEST_IO_6 (MTK_PIN_NO(37) | 5) +#define MT8135_PIN_37_AUD_CLK_MOSI__FUNC_TESTA_OUT19 (MTK_PIN_NO(37) | 7) + +#define MT8135_PIN_38_AUD_DAT_MOSI__FUNC_GPIO38 (MTK_PIN_NO(38) | 0) +#define MT8135_PIN_38_AUD_DAT_MOSI__FUNC_AUD_DAT_MOSI (MTK_PIN_NO(38) | 1) +#define MT8135_PIN_38_AUD_DAT_MOSI__FUNC_ADC_WS (MTK_PIN_NO(38) | 2) +#define MT8135_PIN_38_AUD_DAT_MOSI__FUNC_AUD_DAT_MISO (MTK_PIN_NO(38) | 3) +#define MT8135_PIN_38_AUD_DAT_MOSI__FUNC_EINT21 (MTK_PIN_NO(38) | 4) +#define MT8135_PIN_38_AUD_DAT_MOSI__FUNC_USB_TEST_IO_7 (MTK_PIN_NO(38) | 5) +#define MT8135_PIN_38_AUD_DAT_MOSI__FUNC_TESTA_OUT20 (MTK_PIN_NO(38) | 7) + +#define MT8135_PIN_39_AUD_DAT_MISO__FUNC_GPIO39 (MTK_PIN_NO(39) | 0) +#define MT8135_PIN_39_AUD_DAT_MISO__FUNC_AUD_DAT_MISO (MTK_PIN_NO(39) | 1) +#define MT8135_PIN_39_AUD_DAT_MISO__FUNC_ADC_DAT_IN (MTK_PIN_NO(39) | 2) +#define MT8135_PIN_39_AUD_DAT_MISO__FUNC_AUD_DAT_MOSI (MTK_PIN_NO(39) | 3) +#define MT8135_PIN_39_AUD_DAT_MISO__FUNC_EINT20 (MTK_PIN_NO(39) | 4) +#define MT8135_PIN_39_AUD_DAT_MISO__FUNC_USB_TEST_IO_8 (MTK_PIN_NO(39) | 5) +#define MT8135_PIN_39_AUD_DAT_MISO__FUNC_TESTA_OUT21 (MTK_PIN_NO(39) | 7) + +#define MT8135_PIN_40_DAC_CLK__FUNC_GPIO40 (MTK_PIN_NO(40) | 0) +#define MT8135_PIN_40_DAC_CLK__FUNC_DAC_CK (MTK_PIN_NO(40) | 1) +#define MT8135_PIN_40_DAC_CLK__FUNC_EINT22 (MTK_PIN_NO(40) | 2) +#define MT8135_PIN_40_DAC_CLK__FUNC_HDMI_SDATA1 (MTK_PIN_NO(40) | 3) +#define MT8135_PIN_40_DAC_CLK__FUNC_USB_TEST_IO_9 (MTK_PIN_NO(40) | 5) +#define MT8135_PIN_40_DAC_CLK__FUNC_TESTA_OUT22 (MTK_PIN_NO(40) | 7) + +#define MT8135_PIN_41_DAC_WS__FUNC_GPIO41 (MTK_PIN_NO(41) | 0) +#define MT8135_PIN_41_DAC_WS__FUNC_DAC_WS (MTK_PIN_NO(41) | 1) +#define MT8135_PIN_41_DAC_WS__FUNC_EINT24 (MTK_PIN_NO(41) | 2) +#define MT8135_PIN_41_DAC_WS__FUNC_HDMI_SDATA2 (MTK_PIN_NO(41) | 3) +#define MT8135_PIN_41_DAC_WS__FUNC_USB_TEST_IO_10 (MTK_PIN_NO(41) | 5) +#define MT8135_PIN_41_DAC_WS__FUNC_TESTA_OUT23 (MTK_PIN_NO(41) | 7) + +#define MT8135_PIN_42_DAC_DAT_OUT__FUNC_GPIO42 (MTK_PIN_NO(42) | 0) +#define MT8135_PIN_42_DAC_DAT_OUT__FUNC_DAC_DAT_OUT (MTK_PIN_NO(42) | 1) +#define MT8135_PIN_42_DAC_DAT_OUT__FUNC_EINT23 (MTK_PIN_NO(42) | 2) +#define MT8135_PIN_42_DAC_DAT_OUT__FUNC_HDMI_SDATA3 (MTK_PIN_NO(42) | 3) +#define MT8135_PIN_42_DAC_DAT_OUT__FUNC_USB_TEST_IO_11 (MTK_PIN_NO(42) | 5) +#define MT8135_PIN_42_DAC_DAT_OUT__FUNC_TESTA_OUT24 (MTK_PIN_NO(42) | 7) + +#define MT8135_PIN_43_PWRAP_SPI0_MO__FUNC_GPIO43 (MTK_PIN_NO(43) | 0) +#define MT8135_PIN_43_PWRAP_SPI0_MO__FUNC_PWRAP_SPIDI (MTK_PIN_NO(43) | 1) +#define MT8135_PIN_43_PWRAP_SPI0_MO__FUNC_EINT29 (MTK_PIN_NO(43) | 2) + +#define MT8135_PIN_44_PWRAP_SPI0_MI__FUNC_GPIO44 (MTK_PIN_NO(44) | 0) +#define MT8135_PIN_44_PWRAP_SPI0_MI__FUNC_PWRAP_SPIDO (MTK_PIN_NO(44) | 1) +#define MT8135_PIN_44_PWRAP_SPI0_MI__FUNC_EINT28 (MTK_PIN_NO(44) | 2) + +#define MT8135_PIN_45_PWRAP_SPI0_CSN__FUNC_GPIO45 (MTK_PIN_NO(45) | 0) +#define MT8135_PIN_45_PWRAP_SPI0_CSN__FUNC_PWRAP_SPICS_B_I (MTK_PIN_NO(45) | 1) +#define MT8135_PIN_45_PWRAP_SPI0_CSN__FUNC_EINT27 (MTK_PIN_NO(45) | 2) + +#define MT8135_PIN_46_PWRAP_SPI0_CLK__FUNC_GPIO46 (MTK_PIN_NO(46) | 0) +#define MT8135_PIN_46_PWRAP_SPI0_CLK__FUNC_PWRAP_SPICK_I (MTK_PIN_NO(46) | 1) +#define MT8135_PIN_46_PWRAP_SPI0_CLK__FUNC_EINT26 (MTK_PIN_NO(46) | 2) + +#define MT8135_PIN_47_PWRAP_EVENT__FUNC_GPIO47 (MTK_PIN_NO(47) | 0) +#define MT8135_PIN_47_PWRAP_EVENT__FUNC_PWRAP_EVENT_IN (MTK_PIN_NO(47) | 1) +#define MT8135_PIN_47_PWRAP_EVENT__FUNC_EINT25 (MTK_PIN_NO(47) | 2) +#define MT8135_PIN_47_PWRAP_EVENT__FUNC_TESTA_OUT2 (MTK_PIN_NO(47) | 7) + +#define MT8135_PIN_48_RTC32K_CK__FUNC_GPIO48 (MTK_PIN_NO(48) | 0) +#define MT8135_PIN_48_RTC32K_CK__FUNC_RTC32K_CK (MTK_PIN_NO(48) | 1) + +#define MT8135_PIN_49_WATCHDOG__FUNC_GPIO49 (MTK_PIN_NO(49) | 0) +#define MT8135_PIN_49_WATCHDOG__FUNC_WATCHDOG (MTK_PIN_NO(49) | 1) +#define MT8135_PIN_49_WATCHDOG__FUNC_EINT36 (MTK_PIN_NO(49) | 2) + +#define MT8135_PIN_50_SRCLKENA__FUNC_GPIO50 (MTK_PIN_NO(50) | 0) +#define MT8135_PIN_50_SRCLKENA__FUNC_SRCLKENA (MTK_PIN_NO(50) | 1) +#define MT8135_PIN_50_SRCLKENA__FUNC_EINT38 (MTK_PIN_NO(50) | 2) + +#define MT8135_PIN_51_SRCVOLTEN__FUNC_GPIO51 (MTK_PIN_NO(51) | 0) +#define MT8135_PIN_51_SRCVOLTEN__FUNC_SRCVOLTEN (MTK_PIN_NO(51) | 1) +#define MT8135_PIN_51_SRCVOLTEN__FUNC_EINT37 (MTK_PIN_NO(51) | 2) + +#define MT8135_PIN_52_EINT0__FUNC_GPIO52 (MTK_PIN_NO(52) | 0) +#define MT8135_PIN_52_EINT0__FUNC_EINT0 (MTK_PIN_NO(52) | 1) +#define MT8135_PIN_52_EINT0__FUNC_PWM1 (MTK_PIN_NO(52) | 2) +#define MT8135_PIN_52_EINT0__FUNC_CLKM0 (MTK_PIN_NO(52) | 3) +#define MT8135_PIN_52_EINT0__FUNC_SPDIF_OUT (MTK_PIN_NO(52) | 4) +#define MT8135_PIN_52_EINT0__FUNC_USB_TEST_IO_12 (MTK_PIN_NO(52) | 5) +#define MT8135_PIN_52_EINT0__FUNC_USB_SCL (MTK_PIN_NO(52) | 7) + +#define MT8135_PIN_53_URXD2__FUNC_GPIO53 (MTK_PIN_NO(53) | 0) +#define MT8135_PIN_53_URXD2__FUNC_URXD2 (MTK_PIN_NO(53) | 1) +#define MT8135_PIN_53_URXD2__FUNC_EINT83 (MTK_PIN_NO(53) | 2) +#define MT8135_PIN_53_URXD2__FUNC_HDMI_LRCK (MTK_PIN_NO(53) | 4) +#define MT8135_PIN_53_URXD2__FUNC_CLKM3 (MTK_PIN_NO(53) | 5) +#define MT8135_PIN_53_URXD2__FUNC_UTXD2 (MTK_PIN_NO(53) | 7) + +#define MT8135_PIN_54_UTXD2__FUNC_GPIO54 (MTK_PIN_NO(54) | 0) +#define MT8135_PIN_54_UTXD2__FUNC_UTXD2 (MTK_PIN_NO(54) | 1) +#define MT8135_PIN_54_UTXD2__FUNC_EINT82 (MTK_PIN_NO(54) | 2) +#define MT8135_PIN_54_UTXD2__FUNC_HDMI_BCK_OUT (MTK_PIN_NO(54) | 4) +#define MT8135_PIN_54_UTXD2__FUNC_CLKM2 (MTK_PIN_NO(54) | 5) +#define MT8135_PIN_54_UTXD2__FUNC_URXD2 (MTK_PIN_NO(54) | 7) + +#define MT8135_PIN_55_UCTS2__FUNC_GPIO55 (MTK_PIN_NO(55) | 0) +#define MT8135_PIN_55_UCTS2__FUNC_UCTS2 (MTK_PIN_NO(55) | 1) +#define MT8135_PIN_55_UCTS2__FUNC_EINT84 (MTK_PIN_NO(55) | 2) +#define MT8135_PIN_55_UCTS2__FUNC_PWM1 (MTK_PIN_NO(55) | 5) +#define MT8135_PIN_55_UCTS2__FUNC_URTS2 (MTK_PIN_NO(55) | 7) + +#define MT8135_PIN_56_URTS2__FUNC_GPIO56 (MTK_PIN_NO(56) | 0) +#define MT8135_PIN_56_URTS2__FUNC_URTS2 (MTK_PIN_NO(56) | 1) +#define MT8135_PIN_56_URTS2__FUNC_EINT85 (MTK_PIN_NO(56) | 2) +#define MT8135_PIN_56_URTS2__FUNC_PWM2 (MTK_PIN_NO(56) | 5) +#define MT8135_PIN_56_URTS2__FUNC_UCTS2 (MTK_PIN_NO(56) | 7) + +#define MT8135_PIN_57_JTCK__FUNC_GPIO57 (MTK_PIN_NO(57) | 0) +#define MT8135_PIN_57_JTCK__FUNC_JTCK (MTK_PIN_NO(57) | 1) +#define MT8135_PIN_57_JTCK__FUNC_EINT188 (MTK_PIN_NO(57) | 2) +#define MT8135_PIN_57_JTCK__FUNC_DSP1_ICK (MTK_PIN_NO(57) | 3) + +#define MT8135_PIN_58_JTDO__FUNC_GPIO58 (MTK_PIN_NO(58) | 0) +#define MT8135_PIN_58_JTDO__FUNC_JTDO (MTK_PIN_NO(58) | 1) +#define MT8135_PIN_58_JTDO__FUNC_EINT190 (MTK_PIN_NO(58) | 2) +#define MT8135_PIN_58_JTDO__FUNC_DSP2_IMS (MTK_PIN_NO(58) | 3) + +#define MT8135_PIN_59_JTRST_B__FUNC_GPIO59 (MTK_PIN_NO(59) | 0) +#define MT8135_PIN_59_JTRST_B__FUNC_JTRST_B (MTK_PIN_NO(59) | 1) +#define MT8135_PIN_59_JTRST_B__FUNC_EINT0 (MTK_PIN_NO(59) | 2) +#define MT8135_PIN_59_JTRST_B__FUNC_DSP2_ICK (MTK_PIN_NO(59) | 3) + +#define MT8135_PIN_60_JTDI__FUNC_GPIO60 (MTK_PIN_NO(60) | 0) +#define MT8135_PIN_60_JTDI__FUNC_JTDI (MTK_PIN_NO(60) | 1) +#define MT8135_PIN_60_JTDI__FUNC_EINT189 (MTK_PIN_NO(60) | 2) +#define MT8135_PIN_60_JTDI__FUNC_DSP1_IMS (MTK_PIN_NO(60) | 3) + +#define MT8135_PIN_61_JRTCK__FUNC_GPIO61 (MTK_PIN_NO(61) | 0) +#define MT8135_PIN_61_JRTCK__FUNC_JRTCK (MTK_PIN_NO(61) | 1) +#define MT8135_PIN_61_JRTCK__FUNC_EINT187 (MTK_PIN_NO(61) | 2) +#define MT8135_PIN_61_JRTCK__FUNC_DSP1_ID (MTK_PIN_NO(61) | 3) + +#define MT8135_PIN_62_JTMS__FUNC_GPIO62 (MTK_PIN_NO(62) | 0) +#define MT8135_PIN_62_JTMS__FUNC_JTMS (MTK_PIN_NO(62) | 1) +#define MT8135_PIN_62_JTMS__FUNC_EINT191 (MTK_PIN_NO(62) | 2) +#define MT8135_PIN_62_JTMS__FUNC_DSP2_ID (MTK_PIN_NO(62) | 3) + +#define MT8135_PIN_63_MSDC1_INSI__FUNC_GPIO63 (MTK_PIN_NO(63) | 0) +#define MT8135_PIN_63_MSDC1_INSI__FUNC_MSDC1_INSI (MTK_PIN_NO(63) | 1) +#define MT8135_PIN_63_MSDC1_INSI__FUNC_SCL5 (MTK_PIN_NO(63) | 3) +#define MT8135_PIN_63_MSDC1_INSI__FUNC_PWM6 (MTK_PIN_NO(63) | 4) +#define MT8135_PIN_63_MSDC1_INSI__FUNC_CLKM5 (MTK_PIN_NO(63) | 5) +#define MT8135_PIN_63_MSDC1_INSI__FUNC_TESTB_OUT6 (MTK_PIN_NO(63) | 7) + +#define MT8135_PIN_64_MSDC1_SDWPI__FUNC_GPIO64 (MTK_PIN_NO(64) | 0) +#define MT8135_PIN_64_MSDC1_SDWPI__FUNC_MSDC1_SDWPI (MTK_PIN_NO(64) | 1) +#define MT8135_PIN_64_MSDC1_SDWPI__FUNC_EINT58 (MTK_PIN_NO(64) | 2) +#define MT8135_PIN_64_MSDC1_SDWPI__FUNC_SDA5 (MTK_PIN_NO(64) | 3) +#define MT8135_PIN_64_MSDC1_SDWPI__FUNC_PWM7 (MTK_PIN_NO(64) | 4) +#define MT8135_PIN_64_MSDC1_SDWPI__FUNC_CLKM6 (MTK_PIN_NO(64) | 5) +#define MT8135_PIN_64_MSDC1_SDWPI__FUNC_TESTB_OUT7 (MTK_PIN_NO(64) | 7) + +#define MT8135_PIN_65_MSDC2_INSI__FUNC_GPIO65 (MTK_PIN_NO(65) | 0) +#define MT8135_PIN_65_MSDC2_INSI__FUNC_MSDC2_INSI (MTK_PIN_NO(65) | 1) +#define MT8135_PIN_65_MSDC2_INSI__FUNC_USB_TEST_IO_27 (MTK_PIN_NO(65) | 5) +#define MT8135_PIN_65_MSDC2_INSI__FUNC_TESTA_OUT3 (MTK_PIN_NO(65) | 7) + +#define MT8135_PIN_66_MSDC2_SDWPI__FUNC_GPIO66 (MTK_PIN_NO(66) | 0) +#define MT8135_PIN_66_MSDC2_SDWPI__FUNC_MSDC2_SDWPI (MTK_PIN_NO(66) | 1) +#define MT8135_PIN_66_MSDC2_SDWPI__FUNC_EINT66 (MTK_PIN_NO(66) | 2) +#define MT8135_PIN_66_MSDC2_SDWPI__FUNC_USB_TEST_IO_28 (MTK_PIN_NO(66) | 5) + +#define MT8135_PIN_67_URXD4__FUNC_GPIO67 (MTK_PIN_NO(67) | 0) +#define MT8135_PIN_67_URXD4__FUNC_URXD4 (MTK_PIN_NO(67) | 1) +#define MT8135_PIN_67_URXD4__FUNC_EINT89 (MTK_PIN_NO(67) | 2) +#define MT8135_PIN_67_URXD4__FUNC_URXD1 (MTK_PIN_NO(67) | 3) +#define MT8135_PIN_67_URXD4__FUNC_UTXD4 (MTK_PIN_NO(67) | 6) +#define MT8135_PIN_67_URXD4__FUNC_TESTB_OUT10 (MTK_PIN_NO(67) | 7) + +#define MT8135_PIN_68_UTXD4__FUNC_GPIO68 (MTK_PIN_NO(68) | 0) +#define MT8135_PIN_68_UTXD4__FUNC_UTXD4 (MTK_PIN_NO(68) | 1) +#define MT8135_PIN_68_UTXD4__FUNC_EINT88 (MTK_PIN_NO(68) | 2) +#define MT8135_PIN_68_UTXD4__FUNC_UTXD1 (MTK_PIN_NO(68) | 3) +#define MT8135_PIN_68_UTXD4__FUNC_URXD4 (MTK_PIN_NO(68) | 6) +#define MT8135_PIN_68_UTXD4__FUNC_TESTB_OUT11 (MTK_PIN_NO(68) | 7) + +#define MT8135_PIN_69_URXD1__FUNC_GPIO69 (MTK_PIN_NO(69) | 0) +#define MT8135_PIN_69_URXD1__FUNC_URXD1 (MTK_PIN_NO(69) | 1) +#define MT8135_PIN_69_URXD1__FUNC_EINT79 (MTK_PIN_NO(69) | 2) +#define MT8135_PIN_69_URXD1__FUNC_URXD4 (MTK_PIN_NO(69) | 3) +#define MT8135_PIN_69_URXD1__FUNC_UTXD1 (MTK_PIN_NO(69) | 6) +#define MT8135_PIN_69_URXD1__FUNC_TESTB_OUT24 (MTK_PIN_NO(69) | 7) + +#define MT8135_PIN_70_UTXD1__FUNC_GPIO70 (MTK_PIN_NO(70) | 0) +#define MT8135_PIN_70_UTXD1__FUNC_UTXD1 (MTK_PIN_NO(70) | 1) +#define MT8135_PIN_70_UTXD1__FUNC_EINT78 (MTK_PIN_NO(70) | 2) +#define MT8135_PIN_70_UTXD1__FUNC_UTXD4 (MTK_PIN_NO(70) | 3) +#define MT8135_PIN_70_UTXD1__FUNC_URXD1 (MTK_PIN_NO(70) | 6) +#define MT8135_PIN_70_UTXD1__FUNC_TESTB_OUT25 (MTK_PIN_NO(70) | 7) + +#define MT8135_PIN_71_UCTS1__FUNC_GPIO71 (MTK_PIN_NO(71) | 0) +#define MT8135_PIN_71_UCTS1__FUNC_UCTS1 (MTK_PIN_NO(71) | 1) +#define MT8135_PIN_71_UCTS1__FUNC_EINT80 (MTK_PIN_NO(71) | 2) +#define MT8135_PIN_71_UCTS1__FUNC_CLKM0 (MTK_PIN_NO(71) | 5) +#define MT8135_PIN_71_UCTS1__FUNC_URTS1 (MTK_PIN_NO(71) | 6) +#define MT8135_PIN_71_UCTS1__FUNC_TESTB_OUT31 (MTK_PIN_NO(71) | 7) + +#define MT8135_PIN_72_URTS1__FUNC_GPIO72 (MTK_PIN_NO(72) | 0) +#define MT8135_PIN_72_URTS1__FUNC_URTS1 (MTK_PIN_NO(72) | 1) +#define MT8135_PIN_72_URTS1__FUNC_EINT81 (MTK_PIN_NO(72) | 2) +#define MT8135_PIN_72_URTS1__FUNC_CLKM1 (MTK_PIN_NO(72) | 5) +#define MT8135_PIN_72_URTS1__FUNC_UCTS1 (MTK_PIN_NO(72) | 6) +#define MT8135_PIN_72_URTS1__FUNC_TESTB_OUT21 (MTK_PIN_NO(72) | 7) + +#define MT8135_PIN_73_PWM1__FUNC_GPIO73 (MTK_PIN_NO(73) | 0) +#define MT8135_PIN_73_PWM1__FUNC_PWM1 (MTK_PIN_NO(73) | 1) +#define MT8135_PIN_73_PWM1__FUNC_EINT73 (MTK_PIN_NO(73) | 2) +#define MT8135_PIN_73_PWM1__FUNC_USB_DRVVBUS (MTK_PIN_NO(73) | 5) +#define MT8135_PIN_73_PWM1__FUNC_DISP_PWM (MTK_PIN_NO(73) | 6) +#define MT8135_PIN_73_PWM1__FUNC_TESTB_OUT8 (MTK_PIN_NO(73) | 7) + +#define MT8135_PIN_74_PWM2__FUNC_GPIO74 (MTK_PIN_NO(74) | 0) +#define MT8135_PIN_74_PWM2__FUNC_PWM2 (MTK_PIN_NO(74) | 1) +#define MT8135_PIN_74_PWM2__FUNC_EINT74 (MTK_PIN_NO(74) | 2) +#define MT8135_PIN_74_PWM2__FUNC_DPI33_CK (MTK_PIN_NO(74) | 3) +#define MT8135_PIN_74_PWM2__FUNC_PWM5 (MTK_PIN_NO(74) | 4) +#define MT8135_PIN_74_PWM2__FUNC_URXD2 (MTK_PIN_NO(74) | 5) +#define MT8135_PIN_74_PWM2__FUNC_DISP_PWM (MTK_PIN_NO(74) | 6) +#define MT8135_PIN_74_PWM2__FUNC_TESTB_OUT9 (MTK_PIN_NO(74) | 7) + +#define MT8135_PIN_75_PWM3__FUNC_GPIO75 (MTK_PIN_NO(75) | 0) +#define MT8135_PIN_75_PWM3__FUNC_PWM3 (MTK_PIN_NO(75) | 1) +#define MT8135_PIN_75_PWM3__FUNC_EINT75 (MTK_PIN_NO(75) | 2) +#define MT8135_PIN_75_PWM3__FUNC_DPI33_D0 (MTK_PIN_NO(75) | 3) +#define MT8135_PIN_75_PWM3__FUNC_PWM6 (MTK_PIN_NO(75) | 4) +#define MT8135_PIN_75_PWM3__FUNC_UTXD2 (MTK_PIN_NO(75) | 5) +#define MT8135_PIN_75_PWM3__FUNC_DISP_PWM (MTK_PIN_NO(75) | 6) +#define MT8135_PIN_75_PWM3__FUNC_TESTB_OUT12 (MTK_PIN_NO(75) | 7) + +#define MT8135_PIN_76_PWM4__FUNC_GPIO76 (MTK_PIN_NO(76) | 0) +#define MT8135_PIN_76_PWM4__FUNC_PWM4 (MTK_PIN_NO(76) | 1) +#define MT8135_PIN_76_PWM4__FUNC_EINT76 (MTK_PIN_NO(76) | 2) +#define MT8135_PIN_76_PWM4__FUNC_DPI33_D1 (MTK_PIN_NO(76) | 3) +#define MT8135_PIN_76_PWM4__FUNC_PWM7 (MTK_PIN_NO(76) | 4) +#define MT8135_PIN_76_PWM4__FUNC_DISP_PWM (MTK_PIN_NO(76) | 6) +#define MT8135_PIN_76_PWM4__FUNC_TESTB_OUT13 (MTK_PIN_NO(76) | 7) + +#define MT8135_PIN_77_MSDC2_DAT2__FUNC_GPIO77 (MTK_PIN_NO(77) | 0) +#define MT8135_PIN_77_MSDC2_DAT2__FUNC_MSDC2_DAT2 (MTK_PIN_NO(77) | 1) +#define MT8135_PIN_77_MSDC2_DAT2__FUNC_EINT63 (MTK_PIN_NO(77) | 2) +#define MT8135_PIN_77_MSDC2_DAT2__FUNC_DSP2_IMS (MTK_PIN_NO(77) | 4) +#define MT8135_PIN_77_MSDC2_DAT2__FUNC_DPI33_D6 (MTK_PIN_NO(77) | 6) +#define MT8135_PIN_77_MSDC2_DAT2__FUNC_TESTA_OUT25 (MTK_PIN_NO(77) | 7) + +#define MT8135_PIN_78_MSDC2_DAT3__FUNC_GPIO78 (MTK_PIN_NO(78) | 0) +#define MT8135_PIN_78_MSDC2_DAT3__FUNC_MSDC2_DAT3 (MTK_PIN_NO(78) | 1) +#define MT8135_PIN_78_MSDC2_DAT3__FUNC_EINT64 (MTK_PIN_NO(78) | 2) +#define MT8135_PIN_78_MSDC2_DAT3__FUNC_DSP2_ID (MTK_PIN_NO(78) | 4) +#define MT8135_PIN_78_MSDC2_DAT3__FUNC_DPI33_D7 (MTK_PIN_NO(78) | 6) +#define MT8135_PIN_78_MSDC2_DAT3__FUNC_TESTA_OUT26 (MTK_PIN_NO(78) | 7) + +#define MT8135_PIN_79_MSDC2_CMD__FUNC_GPIO79 (MTK_PIN_NO(79) | 0) +#define MT8135_PIN_79_MSDC2_CMD__FUNC_MSDC2_CMD (MTK_PIN_NO(79) | 1) +#define MT8135_PIN_79_MSDC2_CMD__FUNC_EINT60 (MTK_PIN_NO(79) | 2) +#define MT8135_PIN_79_MSDC2_CMD__FUNC_DSP1_IMS (MTK_PIN_NO(79) | 4) +#define MT8135_PIN_79_MSDC2_CMD__FUNC_PCM1_WS (MTK_PIN_NO(79) | 5) +#define MT8135_PIN_79_MSDC2_CMD__FUNC_DPI33_D3 (MTK_PIN_NO(79) | 6) +#define MT8135_PIN_79_MSDC2_CMD__FUNC_TESTA_OUT0 (MTK_PIN_NO(79) | 7) + +#define MT8135_PIN_80_MSDC2_CLK__FUNC_GPIO80 (MTK_PIN_NO(80) | 0) +#define MT8135_PIN_80_MSDC2_CLK__FUNC_MSDC2_CLK (MTK_PIN_NO(80) | 1) +#define MT8135_PIN_80_MSDC2_CLK__FUNC_EINT59 (MTK_PIN_NO(80) | 2) +#define MT8135_PIN_80_MSDC2_CLK__FUNC_DSP1_ICK (MTK_PIN_NO(80) | 4) +#define MT8135_PIN_80_MSDC2_CLK__FUNC_PCM1_CK (MTK_PIN_NO(80) | 5) +#define MT8135_PIN_80_MSDC2_CLK__FUNC_DPI33_D2 (MTK_PIN_NO(80) | 6) +#define MT8135_PIN_80_MSDC2_CLK__FUNC_TESTA_OUT1 (MTK_PIN_NO(80) | 7) + +#define MT8135_PIN_81_MSDC2_DAT1__FUNC_GPIO81 (MTK_PIN_NO(81) | 0) +#define MT8135_PIN_81_MSDC2_DAT1__FUNC_MSDC2_DAT1 (MTK_PIN_NO(81) | 1) +#define MT8135_PIN_81_MSDC2_DAT1__FUNC_EINT62 (MTK_PIN_NO(81) | 2) +#define MT8135_PIN_81_MSDC2_DAT1__FUNC_DSP2_ICK (MTK_PIN_NO(81) | 4) +#define MT8135_PIN_81_MSDC2_DAT1__FUNC_PCM1_DO (MTK_PIN_NO(81) | 5) +#define MT8135_PIN_81_MSDC2_DAT1__FUNC_DPI33_D5 (MTK_PIN_NO(81) | 6) + +#define MT8135_PIN_82_MSDC2_DAT0__FUNC_GPIO82 (MTK_PIN_NO(82) | 0) +#define MT8135_PIN_82_MSDC2_DAT0__FUNC_MSDC2_DAT0 (MTK_PIN_NO(82) | 1) +#define MT8135_PIN_82_MSDC2_DAT0__FUNC_EINT61 (MTK_PIN_NO(82) | 2) +#define MT8135_PIN_82_MSDC2_DAT0__FUNC_DSP1_ID (MTK_PIN_NO(82) | 4) +#define MT8135_PIN_82_MSDC2_DAT0__FUNC_PCM1_DI (MTK_PIN_NO(82) | 5) +#define MT8135_PIN_82_MSDC2_DAT0__FUNC_DPI33_D4 (MTK_PIN_NO(82) | 6) + +#define MT8135_PIN_83_MSDC1_DAT0__FUNC_GPIO83 (MTK_PIN_NO(83) | 0) +#define MT8135_PIN_83_MSDC1_DAT0__FUNC_MSDC1_DAT0 (MTK_PIN_NO(83) | 1) +#define MT8135_PIN_83_MSDC1_DAT0__FUNC_EINT53 (MTK_PIN_NO(83) | 2) +#define MT8135_PIN_83_MSDC1_DAT0__FUNC_SCL1 (MTK_PIN_NO(83) | 3) +#define MT8135_PIN_83_MSDC1_DAT0__FUNC_PWM2 (MTK_PIN_NO(83) | 4) +#define MT8135_PIN_83_MSDC1_DAT0__FUNC_CLKM1 (MTK_PIN_NO(83) | 5) +#define MT8135_PIN_83_MSDC1_DAT0__FUNC_TESTB_OUT2 (MTK_PIN_NO(83) | 7) + +#define MT8135_PIN_84_MSDC1_DAT1__FUNC_GPIO84 (MTK_PIN_NO(84) | 0) +#define MT8135_PIN_84_MSDC1_DAT1__FUNC_MSDC1_DAT1 (MTK_PIN_NO(84) | 1) +#define MT8135_PIN_84_MSDC1_DAT1__FUNC_EINT54 (MTK_PIN_NO(84) | 2) +#define MT8135_PIN_84_MSDC1_DAT1__FUNC_SDA1 (MTK_PIN_NO(84) | 3) +#define MT8135_PIN_84_MSDC1_DAT1__FUNC_PWM3 (MTK_PIN_NO(84) | 4) +#define MT8135_PIN_84_MSDC1_DAT1__FUNC_CLKM2 (MTK_PIN_NO(84) | 5) +#define MT8135_PIN_84_MSDC1_DAT1__FUNC_TESTB_OUT3 (MTK_PIN_NO(84) | 7) + +#define MT8135_PIN_85_MSDC1_CMD__FUNC_GPIO85 (MTK_PIN_NO(85) | 0) +#define MT8135_PIN_85_MSDC1_CMD__FUNC_MSDC1_CMD (MTK_PIN_NO(85) | 1) +#define MT8135_PIN_85_MSDC1_CMD__FUNC_EINT52 (MTK_PIN_NO(85) | 2) +#define MT8135_PIN_85_MSDC1_CMD__FUNC_SDA0 (MTK_PIN_NO(85) | 3) +#define MT8135_PIN_85_MSDC1_CMD__FUNC_PWM1 (MTK_PIN_NO(85) | 4) +#define MT8135_PIN_85_MSDC1_CMD__FUNC_CLKM0 (MTK_PIN_NO(85) | 5) +#define MT8135_PIN_85_MSDC1_CMD__FUNC_TESTB_OUT1 (MTK_PIN_NO(85) | 7) + +#define MT8135_PIN_86_MSDC1_CLK__FUNC_GPIO86 (MTK_PIN_NO(86) | 0) +#define MT8135_PIN_86_MSDC1_CLK__FUNC_MSDC1_CLK (MTK_PIN_NO(86) | 1) +#define MT8135_PIN_86_MSDC1_CLK__FUNC_EINT51 (MTK_PIN_NO(86) | 2) +#define MT8135_PIN_86_MSDC1_CLK__FUNC_SCL0 (MTK_PIN_NO(86) | 3) +#define MT8135_PIN_86_MSDC1_CLK__FUNC_DISP_PWM (MTK_PIN_NO(86) | 4) +#define MT8135_PIN_86_MSDC1_CLK__FUNC_TESTB_OUT0 (MTK_PIN_NO(86) | 7) + +#define MT8135_PIN_87_MSDC1_DAT2__FUNC_GPIO87 (MTK_PIN_NO(87) | 0) +#define MT8135_PIN_87_MSDC1_DAT2__FUNC_MSDC1_DAT2 (MTK_PIN_NO(87) | 1) +#define MT8135_PIN_87_MSDC1_DAT2__FUNC_EINT55 (MTK_PIN_NO(87) | 2) +#define MT8135_PIN_87_MSDC1_DAT2__FUNC_SCL4 (MTK_PIN_NO(87) | 3) +#define MT8135_PIN_87_MSDC1_DAT2__FUNC_PWM4 (MTK_PIN_NO(87) | 4) +#define MT8135_PIN_87_MSDC1_DAT2__FUNC_CLKM3 (MTK_PIN_NO(87) | 5) +#define MT8135_PIN_87_MSDC1_DAT2__FUNC_TESTB_OUT4 (MTK_PIN_NO(87) | 7) + +#define MT8135_PIN_88_MSDC1_DAT3__FUNC_GPIO88 (MTK_PIN_NO(88) | 0) +#define MT8135_PIN_88_MSDC1_DAT3__FUNC_MSDC1_DAT3 (MTK_PIN_NO(88) | 1) +#define MT8135_PIN_88_MSDC1_DAT3__FUNC_EINT56 (MTK_PIN_NO(88) | 2) +#define MT8135_PIN_88_MSDC1_DAT3__FUNC_SDA4 (MTK_PIN_NO(88) | 3) +#define MT8135_PIN_88_MSDC1_DAT3__FUNC_PWM5 (MTK_PIN_NO(88) | 4) +#define MT8135_PIN_88_MSDC1_DAT3__FUNC_CLKM4 (MTK_PIN_NO(88) | 5) +#define MT8135_PIN_88_MSDC1_DAT3__FUNC_TESTB_OUT5 (MTK_PIN_NO(88) | 7) + +#define MT8135_PIN_89_MSDC4_DAT0__FUNC_GPIO89 (MTK_PIN_NO(89) | 0) +#define MT8135_PIN_89_MSDC4_DAT0__FUNC_MSDC4_DAT0 (MTK_PIN_NO(89) | 1) +#define MT8135_PIN_89_MSDC4_DAT0__FUNC_EINT133 (MTK_PIN_NO(89) | 2) +#define MT8135_PIN_89_MSDC4_DAT0__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(89) | 4) +#define MT8135_PIN_89_MSDC4_DAT0__FUNC_USB_DRVVBUS (MTK_PIN_NO(89) | 5) +#define MT8135_PIN_89_MSDC4_DAT0__FUNC_A_FUNC_DIN_9 (MTK_PIN_NO(89) | 6) +#define MT8135_PIN_89_MSDC4_DAT0__FUNC_LPTE (MTK_PIN_NO(89) | 7) + +#define MT8135_PIN_90_MSDC4_DAT1__FUNC_GPIO90 (MTK_PIN_NO(90) | 0) +#define MT8135_PIN_90_MSDC4_DAT1__FUNC_MSDC4_DAT1 (MTK_PIN_NO(90) | 1) +#define MT8135_PIN_90_MSDC4_DAT1__FUNC_EINT134 (MTK_PIN_NO(90) | 2) +#define MT8135_PIN_90_MSDC4_DAT1__FUNC_A_FUNC_DIN_10 (MTK_PIN_NO(90) | 6) +#define MT8135_PIN_90_MSDC4_DAT1__FUNC_LRSTB_1X (MTK_PIN_NO(90) | 7) + +#define MT8135_PIN_91_MSDC4_DAT5__FUNC_GPIO91 (MTK_PIN_NO(91) | 0) +#define MT8135_PIN_91_MSDC4_DAT5__FUNC_MSDC4_DAT5 (MTK_PIN_NO(91) | 1) +#define MT8135_PIN_91_MSDC4_DAT5__FUNC_EINT136 (MTK_PIN_NO(91) | 2) +#define MT8135_PIN_91_MSDC4_DAT5__FUNC_I2SIN_WS (MTK_PIN_NO(91) | 3) +#define MT8135_PIN_91_MSDC4_DAT5__FUNC_DAC_WS (MTK_PIN_NO(91) | 4) +#define MT8135_PIN_91_MSDC4_DAT5__FUNC_PCM1_WS (MTK_PIN_NO(91) | 5) +#define MT8135_PIN_91_MSDC4_DAT5__FUNC_A_FUNC_DIN_11 (MTK_PIN_NO(91) | 6) +#define MT8135_PIN_91_MSDC4_DAT5__FUNC_SPI1_CSN (MTK_PIN_NO(91) | 7) + +#define MT8135_PIN_92_MSDC4_DAT6__FUNC_GPIO92 (MTK_PIN_NO(92) | 0) +#define MT8135_PIN_92_MSDC4_DAT6__FUNC_MSDC4_DAT6 (MTK_PIN_NO(92) | 1) +#define MT8135_PIN_92_MSDC4_DAT6__FUNC_EINT137 (MTK_PIN_NO(92) | 2) +#define MT8135_PIN_92_MSDC4_DAT6__FUNC_I2SOUT_DAT (MTK_PIN_NO(92) | 3) +#define MT8135_PIN_92_MSDC4_DAT6__FUNC_DAC_DAT_OUT (MTK_PIN_NO(92) | 4) +#define MT8135_PIN_92_MSDC4_DAT6__FUNC_PCM1_DO (MTK_PIN_NO(92) | 5) +#define MT8135_PIN_92_MSDC4_DAT6__FUNC_A_FUNC_DIN_12 (MTK_PIN_NO(92) | 6) +#define MT8135_PIN_92_MSDC4_DAT6__FUNC_SPI1_MO (MTK_PIN_NO(92) | 7) + +#define MT8135_PIN_93_MSDC4_DAT7__FUNC_GPIO93 (MTK_PIN_NO(93) | 0) +#define MT8135_PIN_93_MSDC4_DAT7__FUNC_MSDC4_DAT7 (MTK_PIN_NO(93) | 1) +#define MT8135_PIN_93_MSDC4_DAT7__FUNC_EINT138 (MTK_PIN_NO(93) | 2) +#define MT8135_PIN_93_MSDC4_DAT7__FUNC_I2SIN_DAT (MTK_PIN_NO(93) | 3) +#define MT8135_PIN_93_MSDC4_DAT7__FUNC_PCM1_DI (MTK_PIN_NO(93) | 5) +#define MT8135_PIN_93_MSDC4_DAT7__FUNC_A_FUNC_DIN_13 (MTK_PIN_NO(93) | 6) +#define MT8135_PIN_93_MSDC4_DAT7__FUNC_SPI1_MI (MTK_PIN_NO(93) | 7) + +#define MT8135_PIN_94_MSDC4_DAT4__FUNC_GPIO94 (MTK_PIN_NO(94) | 0) +#define MT8135_PIN_94_MSDC4_DAT4__FUNC_MSDC4_DAT4 (MTK_PIN_NO(94) | 1) +#define MT8135_PIN_94_MSDC4_DAT4__FUNC_EINT135 (MTK_PIN_NO(94) | 2) +#define MT8135_PIN_94_MSDC4_DAT4__FUNC_I2SIN_CK (MTK_PIN_NO(94) | 3) +#define MT8135_PIN_94_MSDC4_DAT4__FUNC_DAC_CK (MTK_PIN_NO(94) | 4) +#define MT8135_PIN_94_MSDC4_DAT4__FUNC_PCM1_CK (MTK_PIN_NO(94) | 5) +#define MT8135_PIN_94_MSDC4_DAT4__FUNC_A_FUNC_DIN_14 (MTK_PIN_NO(94) | 6) +#define MT8135_PIN_94_MSDC4_DAT4__FUNC_SPI1_CLK (MTK_PIN_NO(94) | 7) + +#define MT8135_PIN_95_MSDC4_DAT2__FUNC_GPIO95 (MTK_PIN_NO(95) | 0) +#define MT8135_PIN_95_MSDC4_DAT2__FUNC_MSDC4_DAT2 (MTK_PIN_NO(95) | 1) +#define MT8135_PIN_95_MSDC4_DAT2__FUNC_EINT131 (MTK_PIN_NO(95) | 2) +#define MT8135_PIN_95_MSDC4_DAT2__FUNC_I2SIN_WS (MTK_PIN_NO(95) | 3) +#define MT8135_PIN_95_MSDC4_DAT2__FUNC_CM2PDN_2X (MTK_PIN_NO(95) | 4) +#define MT8135_PIN_95_MSDC4_DAT2__FUNC_DAC_WS (MTK_PIN_NO(95) | 5) +#define MT8135_PIN_95_MSDC4_DAT2__FUNC_PCM1_WS (MTK_PIN_NO(95) | 6) +#define MT8135_PIN_95_MSDC4_DAT2__FUNC_LSCE0B_1X (MTK_PIN_NO(95) | 7) + +#define MT8135_PIN_96_MSDC4_CLK__FUNC_GPIO96 (MTK_PIN_NO(96) | 0) +#define MT8135_PIN_96_MSDC4_CLK__FUNC_MSDC4_CLK (MTK_PIN_NO(96) | 1) +#define MT8135_PIN_96_MSDC4_CLK__FUNC_EINT129 (MTK_PIN_NO(96) | 2) +#define MT8135_PIN_96_MSDC4_CLK__FUNC_DPI1_CK_2X (MTK_PIN_NO(96) | 3) +#define MT8135_PIN_96_MSDC4_CLK__FUNC_CM2PCLK_2X (MTK_PIN_NO(96) | 4) +#define MT8135_PIN_96_MSDC4_CLK__FUNC_PWM4 (MTK_PIN_NO(96) | 5) +#define MT8135_PIN_96_MSDC4_CLK__FUNC_PCM1_DI (MTK_PIN_NO(96) | 6) +#define MT8135_PIN_96_MSDC4_CLK__FUNC_LSCK_1X (MTK_PIN_NO(96) | 7) + +#define MT8135_PIN_97_MSDC4_DAT3__FUNC_GPIO97 (MTK_PIN_NO(97) | 0) +#define MT8135_PIN_97_MSDC4_DAT3__FUNC_MSDC4_DAT3 (MTK_PIN_NO(97) | 1) +#define MT8135_PIN_97_MSDC4_DAT3__FUNC_EINT132 (MTK_PIN_NO(97) | 2) +#define MT8135_PIN_97_MSDC4_DAT3__FUNC_I2SOUT_DAT (MTK_PIN_NO(97) | 3) +#define MT8135_PIN_97_MSDC4_DAT3__FUNC_CM2RST_2X (MTK_PIN_NO(97) | 4) +#define MT8135_PIN_97_MSDC4_DAT3__FUNC_DAC_DAT_OUT (MTK_PIN_NO(97) | 5) +#define MT8135_PIN_97_MSDC4_DAT3__FUNC_PCM1_DO (MTK_PIN_NO(97) | 6) +#define MT8135_PIN_97_MSDC4_DAT3__FUNC_LSCE1B_1X (MTK_PIN_NO(97) | 7) + +#define MT8135_PIN_98_MSDC4_CMD__FUNC_GPIO98 (MTK_PIN_NO(98) | 0) +#define MT8135_PIN_98_MSDC4_CMD__FUNC_MSDC4_CMD (MTK_PIN_NO(98) | 1) +#define MT8135_PIN_98_MSDC4_CMD__FUNC_EINT128 (MTK_PIN_NO(98) | 2) +#define MT8135_PIN_98_MSDC4_CMD__FUNC_DPI1_DE_2X (MTK_PIN_NO(98) | 3) +#define MT8135_PIN_98_MSDC4_CMD__FUNC_PWM3 (MTK_PIN_NO(98) | 5) +#define MT8135_PIN_98_MSDC4_CMD__FUNC_LSDA_1X (MTK_PIN_NO(98) | 7) + +#define MT8135_PIN_99_MSDC4_RSTB__FUNC_GPIO99 (MTK_PIN_NO(99) | 0) +#define MT8135_PIN_99_MSDC4_RSTB__FUNC_MSDC4_RSTB (MTK_PIN_NO(99) | 1) +#define MT8135_PIN_99_MSDC4_RSTB__FUNC_EINT130 (MTK_PIN_NO(99) | 2) +#define MT8135_PIN_99_MSDC4_RSTB__FUNC_I2SIN_CK (MTK_PIN_NO(99) | 3) +#define MT8135_PIN_99_MSDC4_RSTB__FUNC_CM2MCLK_2X (MTK_PIN_NO(99) | 4) +#define MT8135_PIN_99_MSDC4_RSTB__FUNC_DAC_CK (MTK_PIN_NO(99) | 5) +#define MT8135_PIN_99_MSDC4_RSTB__FUNC_PCM1_CK (MTK_PIN_NO(99) | 6) +#define MT8135_PIN_99_MSDC4_RSTB__FUNC_LSA0_1X (MTK_PIN_NO(99) | 7) + +#define MT8135_PIN_100_SDA0__FUNC_GPIO100 (MTK_PIN_NO(100) | 0) +#define MT8135_PIN_100_SDA0__FUNC_SDA0 (MTK_PIN_NO(100) | 1) +#define MT8135_PIN_100_SDA0__FUNC_EINT91 (MTK_PIN_NO(100) | 2) +#define MT8135_PIN_100_SDA0__FUNC_CLKM1 (MTK_PIN_NO(100) | 3) +#define MT8135_PIN_100_SDA0__FUNC_PWM1 (MTK_PIN_NO(100) | 4) +#define MT8135_PIN_100_SDA0__FUNC_A_FUNC_DIN_15 (MTK_PIN_NO(100) | 7) + +#define MT8135_PIN_101_SCL0__FUNC_GPIO101 (MTK_PIN_NO(101) | 0) +#define MT8135_PIN_101_SCL0__FUNC_SCL0 (MTK_PIN_NO(101) | 1) +#define MT8135_PIN_101_SCL0__FUNC_EINT90 (MTK_PIN_NO(101) | 2) +#define MT8135_PIN_101_SCL0__FUNC_CLKM0 (MTK_PIN_NO(101) | 3) +#define MT8135_PIN_101_SCL0__FUNC_DISP_PWM (MTK_PIN_NO(101) | 4) +#define MT8135_PIN_101_SCL0__FUNC_A_FUNC_DIN_16 (MTK_PIN_NO(101) | 7) + +#define MT8135_PIN_102_EINT10_AUXIN2__FUNC_GPIO102 (MTK_PIN_NO(102) | 0) +#define MT8135_PIN_102_EINT10_AUXIN2__FUNC_EINT10 (MTK_PIN_NO(102) | 1) +#define MT8135_PIN_102_EINT10_AUXIN2__FUNC_USB_TEST_IO_16 (MTK_PIN_NO(102) | 5) +#define MT8135_PIN_102_EINT10_AUXIN2__FUNC_TESTB_OUT16 (MTK_PIN_NO(102) | 6) +#define MT8135_PIN_102_EINT10_AUXIN2__FUNC_A_FUNC_DIN_17 (MTK_PIN_NO(102) | 7) + +#define MT8135_PIN_103_EINT11_AUXIN3__FUNC_GPIO103 (MTK_PIN_NO(103) | 0) +#define MT8135_PIN_103_EINT11_AUXIN3__FUNC_EINT11 (MTK_PIN_NO(103) | 1) +#define MT8135_PIN_103_EINT11_AUXIN3__FUNC_USB_TEST_IO_17 (MTK_PIN_NO(103) | 5) +#define MT8135_PIN_103_EINT11_AUXIN3__FUNC_TESTB_OUT17 (MTK_PIN_NO(103) | 6) +#define MT8135_PIN_103_EINT11_AUXIN3__FUNC_A_FUNC_DIN_18 (MTK_PIN_NO(103) | 7) + +#define MT8135_PIN_104_EINT16_AUXIN4__FUNC_GPIO104 (MTK_PIN_NO(104) | 0) +#define MT8135_PIN_104_EINT16_AUXIN4__FUNC_EINT16 (MTK_PIN_NO(104) | 1) +#define MT8135_PIN_104_EINT16_AUXIN4__FUNC_USB_TEST_IO_18 (MTK_PIN_NO(104) | 5) +#define MT8135_PIN_104_EINT16_AUXIN4__FUNC_TESTB_OUT18 (MTK_PIN_NO(104) | 6) +#define MT8135_PIN_104_EINT16_AUXIN4__FUNC_A_FUNC_DIN_19 (MTK_PIN_NO(104) | 7) + +#define MT8135_PIN_105_I2S_CLK__FUNC_GPIO105 (MTK_PIN_NO(105) | 0) +#define MT8135_PIN_105_I2S_CLK__FUNC_I2SIN_CK (MTK_PIN_NO(105) | 1) +#define MT8135_PIN_105_I2S_CLK__FUNC_EINT10 (MTK_PIN_NO(105) | 2) +#define MT8135_PIN_105_I2S_CLK__FUNC_DAC_CK (MTK_PIN_NO(105) | 3) +#define MT8135_PIN_105_I2S_CLK__FUNC_PCM1_CK (MTK_PIN_NO(105) | 4) +#define MT8135_PIN_105_I2S_CLK__FUNC_USB_TEST_IO_19 (MTK_PIN_NO(105) | 5) +#define MT8135_PIN_105_I2S_CLK__FUNC_TESTB_OUT19 (MTK_PIN_NO(105) | 6) +#define MT8135_PIN_105_I2S_CLK__FUNC_A_FUNC_DIN_20 (MTK_PIN_NO(105) | 7) + +#define MT8135_PIN_106_I2S_WS__FUNC_GPIO106 (MTK_PIN_NO(106) | 0) +#define MT8135_PIN_106_I2S_WS__FUNC_I2SIN_WS (MTK_PIN_NO(106) | 1) +#define MT8135_PIN_106_I2S_WS__FUNC_EINT13 (MTK_PIN_NO(106) | 2) +#define MT8135_PIN_106_I2S_WS__FUNC_DAC_WS (MTK_PIN_NO(106) | 3) +#define MT8135_PIN_106_I2S_WS__FUNC_PCM1_WS (MTK_PIN_NO(106) | 4) +#define MT8135_PIN_106_I2S_WS__FUNC_USB_TEST_IO_20 (MTK_PIN_NO(106) | 5) +#define MT8135_PIN_106_I2S_WS__FUNC_TESTB_OUT20 (MTK_PIN_NO(106) | 6) +#define MT8135_PIN_106_I2S_WS__FUNC_A_FUNC_DIN_21 (MTK_PIN_NO(106) | 7) + +#define MT8135_PIN_107_I2S_DATA_IN__FUNC_GPIO107 (MTK_PIN_NO(107) | 0) +#define MT8135_PIN_107_I2S_DATA_IN__FUNC_I2SIN_DAT (MTK_PIN_NO(107) | 1) +#define MT8135_PIN_107_I2S_DATA_IN__FUNC_EINT11 (MTK_PIN_NO(107) | 2) +#define MT8135_PIN_107_I2S_DATA_IN__FUNC_PCM1_DI (MTK_PIN_NO(107) | 4) +#define MT8135_PIN_107_I2S_DATA_IN__FUNC_USB_TEST_IO_21 (MTK_PIN_NO(107) | 5) +#define MT8135_PIN_107_I2S_DATA_IN__FUNC_TESTB_OUT22 (MTK_PIN_NO(107) | 6) +#define MT8135_PIN_107_I2S_DATA_IN__FUNC_A_FUNC_DIN_22 (MTK_PIN_NO(107) | 7) + +#define MT8135_PIN_108_I2S_DATA_OUT__FUNC_GPIO108 (MTK_PIN_NO(108) | 0) +#define MT8135_PIN_108_I2S_DATA_OUT__FUNC_I2SOUT_DAT (MTK_PIN_NO(108) | 1) +#define MT8135_PIN_108_I2S_DATA_OUT__FUNC_EINT12 (MTK_PIN_NO(108) | 2) +#define MT8135_PIN_108_I2S_DATA_OUT__FUNC_DAC_DAT_OUT (MTK_PIN_NO(108) | 3) +#define MT8135_PIN_108_I2S_DATA_OUT__FUNC_PCM1_DO (MTK_PIN_NO(108) | 4) +#define MT8135_PIN_108_I2S_DATA_OUT__FUNC_USB_TEST_IO_22 (MTK_PIN_NO(108) | 5) +#define MT8135_PIN_108_I2S_DATA_OUT__FUNC_TESTB_OUT23 (MTK_PIN_NO(108) | 6) +#define MT8135_PIN_108_I2S_DATA_OUT__FUNC_A_FUNC_DIN_23 (MTK_PIN_NO(108) | 7) + +#define MT8135_PIN_109_EINT5__FUNC_GPIO109 (MTK_PIN_NO(109) | 0) +#define MT8135_PIN_109_EINT5__FUNC_EINT5 (MTK_PIN_NO(109) | 1) +#define MT8135_PIN_109_EINT5__FUNC_PWM5 (MTK_PIN_NO(109) | 2) +#define MT8135_PIN_109_EINT5__FUNC_CLKM3 (MTK_PIN_NO(109) | 3) +#define MT8135_PIN_109_EINT5__FUNC_GPU_JTRSTB (MTK_PIN_NO(109) | 4) +#define MT8135_PIN_109_EINT5__FUNC_USB_TEST_IO_23 (MTK_PIN_NO(109) | 5) +#define MT8135_PIN_109_EINT5__FUNC_TESTB_OUT26 (MTK_PIN_NO(109) | 6) +#define MT8135_PIN_109_EINT5__FUNC_A_FUNC_DIN_24 (MTK_PIN_NO(109) | 7) + +#define MT8135_PIN_110_EINT6__FUNC_GPIO110 (MTK_PIN_NO(110) | 0) +#define MT8135_PIN_110_EINT6__FUNC_EINT6 (MTK_PIN_NO(110) | 1) +#define MT8135_PIN_110_EINT6__FUNC_PWM6 (MTK_PIN_NO(110) | 2) +#define MT8135_PIN_110_EINT6__FUNC_CLKM4 (MTK_PIN_NO(110) | 3) +#define MT8135_PIN_110_EINT6__FUNC_GPU_JTMS (MTK_PIN_NO(110) | 4) +#define MT8135_PIN_110_EINT6__FUNC_USB_TEST_IO_24 (MTK_PIN_NO(110) | 5) +#define MT8135_PIN_110_EINT6__FUNC_TESTB_OUT27 (MTK_PIN_NO(110) | 6) +#define MT8135_PIN_110_EINT6__FUNC_A_FUNC_DIN_25 (MTK_PIN_NO(110) | 7) + +#define MT8135_PIN_111_EINT7__FUNC_GPIO111 (MTK_PIN_NO(111) | 0) +#define MT8135_PIN_111_EINT7__FUNC_EINT7 (MTK_PIN_NO(111) | 1) +#define MT8135_PIN_111_EINT7__FUNC_PWM7 (MTK_PIN_NO(111) | 2) +#define MT8135_PIN_111_EINT7__FUNC_CLKM5 (MTK_PIN_NO(111) | 3) +#define MT8135_PIN_111_EINT7__FUNC_GPU_JTDO (MTK_PIN_NO(111) | 4) +#define MT8135_PIN_111_EINT7__FUNC_USB_TEST_IO_25 (MTK_PIN_NO(111) | 5) +#define MT8135_PIN_111_EINT7__FUNC_TESTB_OUT28 (MTK_PIN_NO(111) | 6) +#define MT8135_PIN_111_EINT7__FUNC_A_FUNC_DIN_26 (MTK_PIN_NO(111) | 7) + +#define MT8135_PIN_112_EINT8__FUNC_GPIO112 (MTK_PIN_NO(112) | 0) +#define MT8135_PIN_112_EINT8__FUNC_EINT8 (MTK_PIN_NO(112) | 1) +#define MT8135_PIN_112_EINT8__FUNC_DISP_PWM (MTK_PIN_NO(112) | 2) +#define MT8135_PIN_112_EINT8__FUNC_CLKM6 (MTK_PIN_NO(112) | 3) +#define MT8135_PIN_112_EINT8__FUNC_GPU_JTDI (MTK_PIN_NO(112) | 4) +#define MT8135_PIN_112_EINT8__FUNC_USB_TEST_IO_26 (MTK_PIN_NO(112) | 5) +#define MT8135_PIN_112_EINT8__FUNC_TESTB_OUT29 (MTK_PIN_NO(112) | 6) +#define MT8135_PIN_112_EINT8__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(112) | 7) + +#define MT8135_PIN_113_EINT9__FUNC_GPIO113 (MTK_PIN_NO(113) | 0) +#define MT8135_PIN_113_EINT9__FUNC_EINT9 (MTK_PIN_NO(113) | 1) +#define MT8135_PIN_113_EINT9__FUNC_GPU_JTCK (MTK_PIN_NO(113) | 4) +#define MT8135_PIN_113_EINT9__FUNC_USB_DRVVBUS (MTK_PIN_NO(113) | 5) +#define MT8135_PIN_113_EINT9__FUNC_TESTB_OUT30 (MTK_PIN_NO(113) | 6) +#define MT8135_PIN_113_EINT9__FUNC_A_FUNC_DIN_27 (MTK_PIN_NO(113) | 7) + +#define MT8135_PIN_114_LPCE1B__FUNC_GPIO114 (MTK_PIN_NO(114) | 0) +#define MT8135_PIN_114_LPCE1B__FUNC_LPCE1B (MTK_PIN_NO(114) | 1) +#define MT8135_PIN_114_LPCE1B__FUNC_EINT127 (MTK_PIN_NO(114) | 2) +#define MT8135_PIN_114_LPCE1B__FUNC_PWM2 (MTK_PIN_NO(114) | 5) +#define MT8135_PIN_114_LPCE1B__FUNC_TESTB_OUT14 (MTK_PIN_NO(114) | 6) +#define MT8135_PIN_114_LPCE1B__FUNC_A_FUNC_DIN_28 (MTK_PIN_NO(114) | 7) + +#define MT8135_PIN_115_LPCE0B__FUNC_GPIO115 (MTK_PIN_NO(115) | 0) +#define MT8135_PIN_115_LPCE0B__FUNC_LPCE0B (MTK_PIN_NO(115) | 1) +#define MT8135_PIN_115_LPCE0B__FUNC_EINT126 (MTK_PIN_NO(115) | 2) +#define MT8135_PIN_115_LPCE0B__FUNC_PWM1 (MTK_PIN_NO(115) | 5) +#define MT8135_PIN_115_LPCE0B__FUNC_TESTB_OUT15 (MTK_PIN_NO(115) | 6) +#define MT8135_PIN_115_LPCE0B__FUNC_A_FUNC_DIN_29 (MTK_PIN_NO(115) | 7) + +#define MT8135_PIN_116_DISP_PWM__FUNC_GPIO116 (MTK_PIN_NO(116) | 0) +#define MT8135_PIN_116_DISP_PWM__FUNC_DISP_PWM (MTK_PIN_NO(116) | 1) +#define MT8135_PIN_116_DISP_PWM__FUNC_EINT77 (MTK_PIN_NO(116) | 2) +#define MT8135_PIN_116_DISP_PWM__FUNC_LSDI (MTK_PIN_NO(116) | 3) +#define MT8135_PIN_116_DISP_PWM__FUNC_PWM1 (MTK_PIN_NO(116) | 4) +#define MT8135_PIN_116_DISP_PWM__FUNC_PWM2 (MTK_PIN_NO(116) | 5) +#define MT8135_PIN_116_DISP_PWM__FUNC_PWM3 (MTK_PIN_NO(116) | 7) + +#define MT8135_PIN_117_EINT1__FUNC_GPIO117 (MTK_PIN_NO(117) | 0) +#define MT8135_PIN_117_EINT1__FUNC_EINT1 (MTK_PIN_NO(117) | 1) +#define MT8135_PIN_117_EINT1__FUNC_PWM2 (MTK_PIN_NO(117) | 2) +#define MT8135_PIN_117_EINT1__FUNC_CLKM1 (MTK_PIN_NO(117) | 3) +#define MT8135_PIN_117_EINT1__FUNC_USB_TEST_IO_13 (MTK_PIN_NO(117) | 5) +#define MT8135_PIN_117_EINT1__FUNC_USB_SDA (MTK_PIN_NO(117) | 7) + +#define MT8135_PIN_118_EINT2__FUNC_GPIO118 (MTK_PIN_NO(118) | 0) +#define MT8135_PIN_118_EINT2__FUNC_EINT2 (MTK_PIN_NO(118) | 1) +#define MT8135_PIN_118_EINT2__FUNC_PWM3 (MTK_PIN_NO(118) | 2) +#define MT8135_PIN_118_EINT2__FUNC_CLKM2 (MTK_PIN_NO(118) | 3) +#define MT8135_PIN_118_EINT2__FUNC_USB_TEST_IO_14 (MTK_PIN_NO(118) | 5) +#define MT8135_PIN_118_EINT2__FUNC_SRCLKENAI2 (MTK_PIN_NO(118) | 6) +#define MT8135_PIN_118_EINT2__FUNC_A_FUNC_DIN_30 (MTK_PIN_NO(118) | 7) + +#define MT8135_PIN_119_EINT3__FUNC_GPIO119 (MTK_PIN_NO(119) | 0) +#define MT8135_PIN_119_EINT3__FUNC_EINT3 (MTK_PIN_NO(119) | 1) +#define MT8135_PIN_119_EINT3__FUNC_USB_TEST_IO_15 (MTK_PIN_NO(119) | 5) +#define MT8135_PIN_119_EINT3__FUNC_SRCLKENAI1 (MTK_PIN_NO(119) | 6) +#define MT8135_PIN_119_EINT3__FUNC_EXT_26M_CK (MTK_PIN_NO(119) | 7) + +#define MT8135_PIN_120_EINT4__FUNC_GPIO120 (MTK_PIN_NO(120) | 0) +#define MT8135_PIN_120_EINT4__FUNC_EINT4 (MTK_PIN_NO(120) | 1) +#define MT8135_PIN_120_EINT4__FUNC_PWM4 (MTK_PIN_NO(120) | 2) +#define MT8135_PIN_120_EINT4__FUNC_USB_DRVVBUS (MTK_PIN_NO(120) | 5) +#define MT8135_PIN_120_EINT4__FUNC_A_FUNC_DIN_31 (MTK_PIN_NO(120) | 7) + +#define MT8135_PIN_121_DPIDE__FUNC_GPIO121 (MTK_PIN_NO(121) | 0) +#define MT8135_PIN_121_DPIDE__FUNC_DPI0_DE (MTK_PIN_NO(121) | 1) +#define MT8135_PIN_121_DPIDE__FUNC_EINT100 (MTK_PIN_NO(121) | 2) +#define MT8135_PIN_121_DPIDE__FUNC_I2SOUT_DAT (MTK_PIN_NO(121) | 3) +#define MT8135_PIN_121_DPIDE__FUNC_DAC_DAT_OUT (MTK_PIN_NO(121) | 4) +#define MT8135_PIN_121_DPIDE__FUNC_PCM1_DO (MTK_PIN_NO(121) | 5) +#define MT8135_PIN_121_DPIDE__FUNC_IRDA_TXD (MTK_PIN_NO(121) | 6) + +#define MT8135_PIN_122_DPICK__FUNC_GPIO122 (MTK_PIN_NO(122) | 0) +#define MT8135_PIN_122_DPICK__FUNC_DPI0_CK (MTK_PIN_NO(122) | 1) +#define MT8135_PIN_122_DPICK__FUNC_EINT101 (MTK_PIN_NO(122) | 2) +#define MT8135_PIN_122_DPICK__FUNC_I2SIN_DAT (MTK_PIN_NO(122) | 3) +#define MT8135_PIN_122_DPICK__FUNC_PCM1_DI (MTK_PIN_NO(122) | 5) +#define MT8135_PIN_122_DPICK__FUNC_IRDA_PDN (MTK_PIN_NO(122) | 6) + +#define MT8135_PIN_123_DPIG4__FUNC_GPIO123 (MTK_PIN_NO(123) | 0) +#define MT8135_PIN_123_DPIG4__FUNC_DPI0_G4 (MTK_PIN_NO(123) | 1) +#define MT8135_PIN_123_DPIG4__FUNC_EINT114 (MTK_PIN_NO(123) | 2) +#define MT8135_PIN_123_DPIG4__FUNC_CM2DAT_2X_0 (MTK_PIN_NO(123) | 4) +#define MT8135_PIN_123_DPIG4__FUNC_DSP2_ID (MTK_PIN_NO(123) | 5) + +#define MT8135_PIN_124_DPIG5__FUNC_GPIO124 (MTK_PIN_NO(124) | 0) +#define MT8135_PIN_124_DPIG5__FUNC_DPI0_G5 (MTK_PIN_NO(124) | 1) +#define MT8135_PIN_124_DPIG5__FUNC_EINT115 (MTK_PIN_NO(124) | 2) +#define MT8135_PIN_124_DPIG5__FUNC_CM2DAT_2X_1 (MTK_PIN_NO(124) | 4) +#define MT8135_PIN_124_DPIG5__FUNC_DSP2_ICK (MTK_PIN_NO(124) | 5) + +#define MT8135_PIN_125_DPIR3__FUNC_GPIO125 (MTK_PIN_NO(125) | 0) +#define MT8135_PIN_125_DPIR3__FUNC_DPI0_R3 (MTK_PIN_NO(125) | 1) +#define MT8135_PIN_125_DPIR3__FUNC_EINT121 (MTK_PIN_NO(125) | 2) +#define MT8135_PIN_125_DPIR3__FUNC_CM2DAT_2X_7 (MTK_PIN_NO(125) | 4) + +#define MT8135_PIN_126_DPIG1__FUNC_GPIO126 (MTK_PIN_NO(126) | 0) +#define MT8135_PIN_126_DPIG1__FUNC_DPI0_G1 (MTK_PIN_NO(126) | 1) +#define MT8135_PIN_126_DPIG1__FUNC_EINT111 (MTK_PIN_NO(126) | 2) +#define MT8135_PIN_126_DPIG1__FUNC_DSP1_ICK (MTK_PIN_NO(126) | 5) + +#define MT8135_PIN_127_DPIVSYNC__FUNC_GPIO127 (MTK_PIN_NO(127) | 0) +#define MT8135_PIN_127_DPIVSYNC__FUNC_DPI0_VSYNC (MTK_PIN_NO(127) | 1) +#define MT8135_PIN_127_DPIVSYNC__FUNC_EINT98 (MTK_PIN_NO(127) | 2) +#define MT8135_PIN_127_DPIVSYNC__FUNC_I2SIN_CK (MTK_PIN_NO(127) | 3) +#define MT8135_PIN_127_DPIVSYNC__FUNC_DAC_CK (MTK_PIN_NO(127) | 4) +#define MT8135_PIN_127_DPIVSYNC__FUNC_PCM1_CK (MTK_PIN_NO(127) | 5) + +#define MT8135_PIN_128_DPIHSYNC__FUNC_GPIO128 (MTK_PIN_NO(128) | 0) +#define MT8135_PIN_128_DPIHSYNC__FUNC_DPI0_HSYNC (MTK_PIN_NO(128) | 1) +#define MT8135_PIN_128_DPIHSYNC__FUNC_EINT99 (MTK_PIN_NO(128) | 2) +#define MT8135_PIN_128_DPIHSYNC__FUNC_I2SIN_WS (MTK_PIN_NO(128) | 3) +#define MT8135_PIN_128_DPIHSYNC__FUNC_DAC_WS (MTK_PIN_NO(128) | 4) +#define MT8135_PIN_128_DPIHSYNC__FUNC_PCM1_WS (MTK_PIN_NO(128) | 5) +#define MT8135_PIN_128_DPIHSYNC__FUNC_IRDA_RXD (MTK_PIN_NO(128) | 6) + +#define MT8135_PIN_129_DPIB0__FUNC_GPIO129 (MTK_PIN_NO(129) | 0) +#define MT8135_PIN_129_DPIB0__FUNC_DPI0_B0 (MTK_PIN_NO(129) | 1) +#define MT8135_PIN_129_DPIB0__FUNC_EINT102 (MTK_PIN_NO(129) | 2) +#define MT8135_PIN_129_DPIB0__FUNC_SCL0 (MTK_PIN_NO(129) | 4) +#define MT8135_PIN_129_DPIB0__FUNC_DISP_PWM (MTK_PIN_NO(129) | 5) + +#define MT8135_PIN_130_DPIB1__FUNC_GPIO130 (MTK_PIN_NO(130) | 0) +#define MT8135_PIN_130_DPIB1__FUNC_DPI0_B1 (MTK_PIN_NO(130) | 1) +#define MT8135_PIN_130_DPIB1__FUNC_EINT103 (MTK_PIN_NO(130) | 2) +#define MT8135_PIN_130_DPIB1__FUNC_CLKM0 (MTK_PIN_NO(130) | 3) +#define MT8135_PIN_130_DPIB1__FUNC_SDA0 (MTK_PIN_NO(130) | 4) +#define MT8135_PIN_130_DPIB1__FUNC_PWM1 (MTK_PIN_NO(130) | 5) + +#define MT8135_PIN_131_DPIB2__FUNC_GPIO131 (MTK_PIN_NO(131) | 0) +#define MT8135_PIN_131_DPIB2__FUNC_DPI0_B2 (MTK_PIN_NO(131) | 1) +#define MT8135_PIN_131_DPIB2__FUNC_EINT104 (MTK_PIN_NO(131) | 2) +#define MT8135_PIN_131_DPIB2__FUNC_CLKM1 (MTK_PIN_NO(131) | 3) +#define MT8135_PIN_131_DPIB2__FUNC_SCL1 (MTK_PIN_NO(131) | 4) +#define MT8135_PIN_131_DPIB2__FUNC_PWM2 (MTK_PIN_NO(131) | 5) + +#define MT8135_PIN_132_DPIB3__FUNC_GPIO132 (MTK_PIN_NO(132) | 0) +#define MT8135_PIN_132_DPIB3__FUNC_DPI0_B3 (MTK_PIN_NO(132) | 1) +#define MT8135_PIN_132_DPIB3__FUNC_EINT105 (MTK_PIN_NO(132) | 2) +#define MT8135_PIN_132_DPIB3__FUNC_CLKM2 (MTK_PIN_NO(132) | 3) +#define MT8135_PIN_132_DPIB3__FUNC_SDA1 (MTK_PIN_NO(132) | 4) +#define MT8135_PIN_132_DPIB3__FUNC_PWM3 (MTK_PIN_NO(132) | 5) + +#define MT8135_PIN_133_DPIB4__FUNC_GPIO133 (MTK_PIN_NO(133) | 0) +#define MT8135_PIN_133_DPIB4__FUNC_DPI0_B4 (MTK_PIN_NO(133) | 1) +#define MT8135_PIN_133_DPIB4__FUNC_EINT106 (MTK_PIN_NO(133) | 2) +#define MT8135_PIN_133_DPIB4__FUNC_CLKM3 (MTK_PIN_NO(133) | 3) +#define MT8135_PIN_133_DPIB4__FUNC_SCL2 (MTK_PIN_NO(133) | 4) +#define MT8135_PIN_133_DPIB4__FUNC_PWM4 (MTK_PIN_NO(133) | 5) + +#define MT8135_PIN_134_DPIB5__FUNC_GPIO134 (MTK_PIN_NO(134) | 0) +#define MT8135_PIN_134_DPIB5__FUNC_DPI0_B5 (MTK_PIN_NO(134) | 1) +#define MT8135_PIN_134_DPIB5__FUNC_EINT107 (MTK_PIN_NO(134) | 2) +#define MT8135_PIN_134_DPIB5__FUNC_CLKM4 (MTK_PIN_NO(134) | 3) +#define MT8135_PIN_134_DPIB5__FUNC_SDA2 (MTK_PIN_NO(134) | 4) +#define MT8135_PIN_134_DPIB5__FUNC_PWM5 (MTK_PIN_NO(134) | 5) + +#define MT8135_PIN_135_DPIB6__FUNC_GPIO135 (MTK_PIN_NO(135) | 0) +#define MT8135_PIN_135_DPIB6__FUNC_DPI0_B6 (MTK_PIN_NO(135) | 1) +#define MT8135_PIN_135_DPIB6__FUNC_EINT108 (MTK_PIN_NO(135) | 2) +#define MT8135_PIN_135_DPIB6__FUNC_CLKM5 (MTK_PIN_NO(135) | 3) +#define MT8135_PIN_135_DPIB6__FUNC_SCL3 (MTK_PIN_NO(135) | 4) +#define MT8135_PIN_135_DPIB6__FUNC_PWM6 (MTK_PIN_NO(135) | 5) + +#define MT8135_PIN_136_DPIB7__FUNC_GPIO136 (MTK_PIN_NO(136) | 0) +#define MT8135_PIN_136_DPIB7__FUNC_DPI0_B7 (MTK_PIN_NO(136) | 1) +#define MT8135_PIN_136_DPIB7__FUNC_EINT109 (MTK_PIN_NO(136) | 2) +#define MT8135_PIN_136_DPIB7__FUNC_CLKM6 (MTK_PIN_NO(136) | 3) +#define MT8135_PIN_136_DPIB7__FUNC_SDA3 (MTK_PIN_NO(136) | 4) +#define MT8135_PIN_136_DPIB7__FUNC_PWM7 (MTK_PIN_NO(136) | 5) + +#define MT8135_PIN_137_DPIG0__FUNC_GPIO137 (MTK_PIN_NO(137) | 0) +#define MT8135_PIN_137_DPIG0__FUNC_DPI0_G0 (MTK_PIN_NO(137) | 1) +#define MT8135_PIN_137_DPIG0__FUNC_EINT110 (MTK_PIN_NO(137) | 2) +#define MT8135_PIN_137_DPIG0__FUNC_DSP1_ID (MTK_PIN_NO(137) | 5) + +#define MT8135_PIN_138_DPIG2__FUNC_GPIO138 (MTK_PIN_NO(138) | 0) +#define MT8135_PIN_138_DPIG2__FUNC_DPI0_G2 (MTK_PIN_NO(138) | 1) +#define MT8135_PIN_138_DPIG2__FUNC_EINT112 (MTK_PIN_NO(138) | 2) +#define MT8135_PIN_138_DPIG2__FUNC_DSP1_IMS (MTK_PIN_NO(138) | 5) + +#define MT8135_PIN_139_DPIG3__FUNC_GPIO139 (MTK_PIN_NO(139) | 0) +#define MT8135_PIN_139_DPIG3__FUNC_DPI0_G3 (MTK_PIN_NO(139) | 1) +#define MT8135_PIN_139_DPIG3__FUNC_EINT113 (MTK_PIN_NO(139) | 2) +#define MT8135_PIN_139_DPIG3__FUNC_DSP2_IMS (MTK_PIN_NO(139) | 5) + +#define MT8135_PIN_140_DPIG6__FUNC_GPIO140 (MTK_PIN_NO(140) | 0) +#define MT8135_PIN_140_DPIG6__FUNC_DPI0_G6 (MTK_PIN_NO(140) | 1) +#define MT8135_PIN_140_DPIG6__FUNC_EINT116 (MTK_PIN_NO(140) | 2) +#define MT8135_PIN_140_DPIG6__FUNC_CM2DAT_2X_2 (MTK_PIN_NO(140) | 4) + +#define MT8135_PIN_141_DPIG7__FUNC_GPIO141 (MTK_PIN_NO(141) | 0) +#define MT8135_PIN_141_DPIG7__FUNC_DPI0_G7 (MTK_PIN_NO(141) | 1) +#define MT8135_PIN_141_DPIG7__FUNC_EINT117 (MTK_PIN_NO(141) | 2) +#define MT8135_PIN_141_DPIG7__FUNC_CM2DAT_2X_3 (MTK_PIN_NO(141) | 4) + +#define MT8135_PIN_142_DPIR0__FUNC_GPIO142 (MTK_PIN_NO(142) | 0) +#define MT8135_PIN_142_DPIR0__FUNC_DPI0_R0 (MTK_PIN_NO(142) | 1) +#define MT8135_PIN_142_DPIR0__FUNC_EINT118 (MTK_PIN_NO(142) | 2) +#define MT8135_PIN_142_DPIR0__FUNC_CM2DAT_2X_4 (MTK_PIN_NO(142) | 4) + +#define MT8135_PIN_143_DPIR1__FUNC_GPIO143 (MTK_PIN_NO(143) | 0) +#define MT8135_PIN_143_DPIR1__FUNC_DPI0_R1 (MTK_PIN_NO(143) | 1) +#define MT8135_PIN_143_DPIR1__FUNC_EINT119 (MTK_PIN_NO(143) | 2) +#define MT8135_PIN_143_DPIR1__FUNC_CM2DAT_2X_5 (MTK_PIN_NO(143) | 4) + +#define MT8135_PIN_144_DPIR2__FUNC_GPIO144 (MTK_PIN_NO(144) | 0) +#define MT8135_PIN_144_DPIR2__FUNC_DPI0_R2 (MTK_PIN_NO(144) | 1) +#define MT8135_PIN_144_DPIR2__FUNC_EINT120 (MTK_PIN_NO(144) | 2) +#define MT8135_PIN_144_DPIR2__FUNC_CM2DAT_2X_6 (MTK_PIN_NO(144) | 4) + +#define MT8135_PIN_145_DPIR4__FUNC_GPIO145 (MTK_PIN_NO(145) | 0) +#define MT8135_PIN_145_DPIR4__FUNC_DPI0_R4 (MTK_PIN_NO(145) | 1) +#define MT8135_PIN_145_DPIR4__FUNC_EINT122 (MTK_PIN_NO(145) | 2) +#define MT8135_PIN_145_DPIR4__FUNC_CM2DAT_2X_8 (MTK_PIN_NO(145) | 4) + +#define MT8135_PIN_146_DPIR5__FUNC_GPIO146 (MTK_PIN_NO(146) | 0) +#define MT8135_PIN_146_DPIR5__FUNC_DPI0_R5 (MTK_PIN_NO(146) | 1) +#define MT8135_PIN_146_DPIR5__FUNC_EINT123 (MTK_PIN_NO(146) | 2) +#define MT8135_PIN_146_DPIR5__FUNC_CM2DAT_2X_9 (MTK_PIN_NO(146) | 4) + +#define MT8135_PIN_147_DPIR6__FUNC_GPIO147 (MTK_PIN_NO(147) | 0) +#define MT8135_PIN_147_DPIR6__FUNC_DPI0_R6 (MTK_PIN_NO(147) | 1) +#define MT8135_PIN_147_DPIR6__FUNC_EINT124 (MTK_PIN_NO(147) | 2) +#define MT8135_PIN_147_DPIR6__FUNC_CM2VSYNC_2X (MTK_PIN_NO(147) | 4) + +#define MT8135_PIN_148_DPIR7__FUNC_GPIO148 (MTK_PIN_NO(148) | 0) +#define MT8135_PIN_148_DPIR7__FUNC_DPI0_R7 (MTK_PIN_NO(148) | 1) +#define MT8135_PIN_148_DPIR7__FUNC_EINT125 (MTK_PIN_NO(148) | 2) +#define MT8135_PIN_148_DPIR7__FUNC_CM2HSYNC_2X (MTK_PIN_NO(148) | 4) + +#define MT8135_PIN_149_TDN3__FUNC_GPIO149 (MTK_PIN_NO(149) | 0) +#define MT8135_PIN_149_TDN3__FUNC_EINT36 (MTK_PIN_NO(149) | 2) + +#define MT8135_PIN_150_TDP3__FUNC_GPIO150 (MTK_PIN_NO(150) | 0) +#define MT8135_PIN_150_TDP3__FUNC_EINT35 (MTK_PIN_NO(150) | 2) + +#define MT8135_PIN_151_TDN2__FUNC_GPIO151 (MTK_PIN_NO(151) | 0) +#define MT8135_PIN_151_TDN2__FUNC_EINT169 (MTK_PIN_NO(151) | 2) + +#define MT8135_PIN_152_TDP2__FUNC_GPIO152 (MTK_PIN_NO(152) | 0) +#define MT8135_PIN_152_TDP2__FUNC_EINT168 (MTK_PIN_NO(152) | 2) + +#define MT8135_PIN_153_TCN__FUNC_GPIO153 (MTK_PIN_NO(153) | 0) +#define MT8135_PIN_153_TCN__FUNC_EINT163 (MTK_PIN_NO(153) | 2) + +#define MT8135_PIN_154_TCP__FUNC_GPIO154 (MTK_PIN_NO(154) | 0) +#define MT8135_PIN_154_TCP__FUNC_EINT162 (MTK_PIN_NO(154) | 2) + +#define MT8135_PIN_155_TDN1__FUNC_GPIO155 (MTK_PIN_NO(155) | 0) +#define MT8135_PIN_155_TDN1__FUNC_EINT167 (MTK_PIN_NO(155) | 2) + +#define MT8135_PIN_156_TDP1__FUNC_GPIO156 (MTK_PIN_NO(156) | 0) +#define MT8135_PIN_156_TDP1__FUNC_EINT166 (MTK_PIN_NO(156) | 2) + +#define MT8135_PIN_157_TDN0__FUNC_GPIO157 (MTK_PIN_NO(157) | 0) +#define MT8135_PIN_157_TDN0__FUNC_EINT165 (MTK_PIN_NO(157) | 2) + +#define MT8135_PIN_158_TDP0__FUNC_GPIO158 (MTK_PIN_NO(158) | 0) +#define MT8135_PIN_158_TDP0__FUNC_EINT164 (MTK_PIN_NO(158) | 2) + +#define MT8135_PIN_159_RDN3__FUNC_GPIO159 (MTK_PIN_NO(159) | 0) +#define MT8135_PIN_159_RDN3__FUNC_EINT18 (MTK_PIN_NO(159) | 2) + +#define MT8135_PIN_160_RDP3__FUNC_GPIO160 (MTK_PIN_NO(160) | 0) +#define MT8135_PIN_160_RDP3__FUNC_EINT30 (MTK_PIN_NO(160) | 2) + +#define MT8135_PIN_161_RDN2__FUNC_GPIO161 (MTK_PIN_NO(161) | 0) +#define MT8135_PIN_161_RDN2__FUNC_EINT31 (MTK_PIN_NO(161) | 2) + +#define MT8135_PIN_162_RDP2__FUNC_GPIO162 (MTK_PIN_NO(162) | 0) +#define MT8135_PIN_162_RDP2__FUNC_EINT32 (MTK_PIN_NO(162) | 2) + +#define MT8135_PIN_163_RCN__FUNC_GPIO163 (MTK_PIN_NO(163) | 0) +#define MT8135_PIN_163_RCN__FUNC_EINT33 (MTK_PIN_NO(163) | 2) + +#define MT8135_PIN_164_RCP__FUNC_GPIO164 (MTK_PIN_NO(164) | 0) +#define MT8135_PIN_164_RCP__FUNC_EINT39 (MTK_PIN_NO(164) | 2) + +#define MT8135_PIN_165_RDN1__FUNC_GPIO165 (MTK_PIN_NO(165) | 0) + +#define MT8135_PIN_166_RDP1__FUNC_GPIO166 (MTK_PIN_NO(166) | 0) + +#define MT8135_PIN_167_RDN0__FUNC_GPIO167 (MTK_PIN_NO(167) | 0) + +#define MT8135_PIN_168_RDP0__FUNC_GPIO168 (MTK_PIN_NO(168) | 0) + +#define MT8135_PIN_169_RDN1_A__FUNC_GPIO169 (MTK_PIN_NO(169) | 0) +#define MT8135_PIN_169_RDN1_A__FUNC_CMDAT6 (MTK_PIN_NO(169) | 1) +#define MT8135_PIN_169_RDN1_A__FUNC_EINT175 (MTK_PIN_NO(169) | 2) + +#define MT8135_PIN_170_RDP1_A__FUNC_GPIO170 (MTK_PIN_NO(170) | 0) +#define MT8135_PIN_170_RDP1_A__FUNC_CMDAT7 (MTK_PIN_NO(170) | 1) +#define MT8135_PIN_170_RDP1_A__FUNC_EINT174 (MTK_PIN_NO(170) | 2) + +#define MT8135_PIN_171_RCN_A__FUNC_GPIO171 (MTK_PIN_NO(171) | 0) +#define MT8135_PIN_171_RCN_A__FUNC_CMDAT8 (MTK_PIN_NO(171) | 1) +#define MT8135_PIN_171_RCN_A__FUNC_EINT171 (MTK_PIN_NO(171) | 2) + +#define MT8135_PIN_172_RCP_A__FUNC_GPIO172 (MTK_PIN_NO(172) | 0) +#define MT8135_PIN_172_RCP_A__FUNC_CMDAT9 (MTK_PIN_NO(172) | 1) +#define MT8135_PIN_172_RCP_A__FUNC_EINT170 (MTK_PIN_NO(172) | 2) + +#define MT8135_PIN_173_RDN0_A__FUNC_GPIO173 (MTK_PIN_NO(173) | 0) +#define MT8135_PIN_173_RDN0_A__FUNC_CMHSYNC (MTK_PIN_NO(173) | 1) +#define MT8135_PIN_173_RDN0_A__FUNC_EINT173 (MTK_PIN_NO(173) | 2) + +#define MT8135_PIN_174_RDP0_A__FUNC_GPIO174 (MTK_PIN_NO(174) | 0) +#define MT8135_PIN_174_RDP0_A__FUNC_CMVSYNC (MTK_PIN_NO(174) | 1) +#define MT8135_PIN_174_RDP0_A__FUNC_EINT172 (MTK_PIN_NO(174) | 2) + +#define MT8135_PIN_175_RDN1_B__FUNC_GPIO175 (MTK_PIN_NO(175) | 0) +#define MT8135_PIN_175_RDN1_B__FUNC_CMDAT2 (MTK_PIN_NO(175) | 1) +#define MT8135_PIN_175_RDN1_B__FUNC_EINT181 (MTK_PIN_NO(175) | 2) +#define MT8135_PIN_175_RDN1_B__FUNC_CMCSD2 (MTK_PIN_NO(175) | 3) + +#define MT8135_PIN_176_RDP1_B__FUNC_GPIO176 (MTK_PIN_NO(176) | 0) +#define MT8135_PIN_176_RDP1_B__FUNC_CMDAT3 (MTK_PIN_NO(176) | 1) +#define MT8135_PIN_176_RDP1_B__FUNC_EINT180 (MTK_PIN_NO(176) | 2) +#define MT8135_PIN_176_RDP1_B__FUNC_CMCSD3 (MTK_PIN_NO(176) | 3) + +#define MT8135_PIN_177_RCN_B__FUNC_GPIO177 (MTK_PIN_NO(177) | 0) +#define MT8135_PIN_177_RCN_B__FUNC_CMDAT4 (MTK_PIN_NO(177) | 1) +#define MT8135_PIN_177_RCN_B__FUNC_EINT177 (MTK_PIN_NO(177) | 2) + +#define MT8135_PIN_178_RCP_B__FUNC_GPIO178 (MTK_PIN_NO(178) | 0) +#define MT8135_PIN_178_RCP_B__FUNC_CMDAT5 (MTK_PIN_NO(178) | 1) +#define MT8135_PIN_178_RCP_B__FUNC_EINT176 (MTK_PIN_NO(178) | 2) + +#define MT8135_PIN_179_RDN0_B__FUNC_GPIO179 (MTK_PIN_NO(179) | 0) +#define MT8135_PIN_179_RDN0_B__FUNC_CMDAT0 (MTK_PIN_NO(179) | 1) +#define MT8135_PIN_179_RDN0_B__FUNC_EINT179 (MTK_PIN_NO(179) | 2) +#define MT8135_PIN_179_RDN0_B__FUNC_CMCSD0 (MTK_PIN_NO(179) | 3) + +#define MT8135_PIN_180_RDP0_B__FUNC_GPIO180 (MTK_PIN_NO(180) | 0) +#define MT8135_PIN_180_RDP0_B__FUNC_CMDAT1 (MTK_PIN_NO(180) | 1) +#define MT8135_PIN_180_RDP0_B__FUNC_EINT178 (MTK_PIN_NO(180) | 2) +#define MT8135_PIN_180_RDP0_B__FUNC_CMCSD1 (MTK_PIN_NO(180) | 3) + +#define MT8135_PIN_181_CMPCLK__FUNC_GPIO181 (MTK_PIN_NO(181) | 0) +#define MT8135_PIN_181_CMPCLK__FUNC_CMPCLK (MTK_PIN_NO(181) | 1) +#define MT8135_PIN_181_CMPCLK__FUNC_EINT182 (MTK_PIN_NO(181) | 2) +#define MT8135_PIN_181_CMPCLK__FUNC_CMCSK (MTK_PIN_NO(181) | 3) +#define MT8135_PIN_181_CMPCLK__FUNC_CM2MCLK_4X (MTK_PIN_NO(181) | 4) +#define MT8135_PIN_181_CMPCLK__FUNC_TS_AUXADC_SEL_3 (MTK_PIN_NO(181) | 5) +#define MT8135_PIN_181_CMPCLK__FUNC_VENC_TEST_CK (MTK_PIN_NO(181) | 6) +#define MT8135_PIN_181_CMPCLK__FUNC_TESTA_OUT27 (MTK_PIN_NO(181) | 7) + +#define MT8135_PIN_182_CMMCLK__FUNC_GPIO182 (MTK_PIN_NO(182) | 0) +#define MT8135_PIN_182_CMMCLK__FUNC_CMMCLK (MTK_PIN_NO(182) | 1) +#define MT8135_PIN_182_CMMCLK__FUNC_EINT183 (MTK_PIN_NO(182) | 2) +#define MT8135_PIN_182_CMMCLK__FUNC_TS_AUXADC_SEL_2 (MTK_PIN_NO(182) | 5) +#define MT8135_PIN_182_CMMCLK__FUNC_TESTA_OUT28 (MTK_PIN_NO(182) | 7) + +#define MT8135_PIN_183_CMRST__FUNC_GPIO183 (MTK_PIN_NO(183) | 0) +#define MT8135_PIN_183_CMRST__FUNC_CMRST (MTK_PIN_NO(183) | 1) +#define MT8135_PIN_183_CMRST__FUNC_EINT185 (MTK_PIN_NO(183) | 2) +#define MT8135_PIN_183_CMRST__FUNC_TS_AUXADC_SEL_1 (MTK_PIN_NO(183) | 5) +#define MT8135_PIN_183_CMRST__FUNC_TESTA_OUT30 (MTK_PIN_NO(183) | 7) + +#define MT8135_PIN_184_CMPDN__FUNC_GPIO184 (MTK_PIN_NO(184) | 0) +#define MT8135_PIN_184_CMPDN__FUNC_CMPDN (MTK_PIN_NO(184) | 1) +#define MT8135_PIN_184_CMPDN__FUNC_EINT184 (MTK_PIN_NO(184) | 2) +#define MT8135_PIN_184_CMPDN__FUNC_TS_AUXADC_SEL_0 (MTK_PIN_NO(184) | 5) +#define MT8135_PIN_184_CMPDN__FUNC_TESTA_OUT29 (MTK_PIN_NO(184) | 7) + +#define MT8135_PIN_185_CMFLASH__FUNC_GPIO185 (MTK_PIN_NO(185) | 0) +#define MT8135_PIN_185_CMFLASH__FUNC_CMFLASH (MTK_PIN_NO(185) | 1) +#define MT8135_PIN_185_CMFLASH__FUNC_EINT186 (MTK_PIN_NO(185) | 2) +#define MT8135_PIN_185_CMFLASH__FUNC_CM2MCLK_3X (MTK_PIN_NO(185) | 3) +#define MT8135_PIN_185_CMFLASH__FUNC_MFG_TEST_CK_1 (MTK_PIN_NO(185) | 6) +#define MT8135_PIN_185_CMFLASH__FUNC_TESTA_OUT31 (MTK_PIN_NO(185) | 7) + +#define MT8135_PIN_186_MRG_I2S_PCM_CLK__FUNC_GPIO186 (MTK_PIN_NO(186) | 0) +#define MT8135_PIN_186_MRG_I2S_PCM_CLK__FUNC_MRG_I2S_P_CLK (MTK_PIN_NO(186) | 1) +#define MT8135_PIN_186_MRG_I2S_PCM_CLK__FUNC_EINT14 (MTK_PIN_NO(186) | 2) +#define MT8135_PIN_186_MRG_I2S_PCM_CLK__FUNC_I2SIN_CK (MTK_PIN_NO(186) | 3) +#define MT8135_PIN_186_MRG_I2S_PCM_CLK__FUNC_PCM0_CK (MTK_PIN_NO(186) | 4) +#define MT8135_PIN_186_MRG_I2S_PCM_CLK__FUNC_DSP2_ICK (MTK_PIN_NO(186) | 5) +#define MT8135_PIN_186_MRG_I2S_PCM_CLK__FUNC_IMG_TEST_CK (MTK_PIN_NO(186) | 6) +#define MT8135_PIN_186_MRG_I2S_PCM_CLK__FUNC_USB_SCL (MTK_PIN_NO(186) | 7) + +#define MT8135_PIN_187_MRG_I2S_PCM_SYNC__FUNC_GPIO187 (MTK_PIN_NO(187) | 0) +#define MT8135_PIN_187_MRG_I2S_PCM_SYNC__FUNC_MRG_I2S_SYNC (MTK_PIN_NO(187) | 1) +#define MT8135_PIN_187_MRG_I2S_PCM_SYNC__FUNC_EINT16 (MTK_PIN_NO(187) | 2) +#define MT8135_PIN_187_MRG_I2S_PCM_SYNC__FUNC_I2SIN_WS (MTK_PIN_NO(187) | 3) +#define MT8135_PIN_187_MRG_I2S_PCM_SYNC__FUNC_PCM0_WS (MTK_PIN_NO(187) | 4) +#define MT8135_PIN_187_MRG_I2S_PCM_SYNC__FUNC_DISP_TEST_CK (MTK_PIN_NO(187) | 6) + +#define MT8135_PIN_188_MRG_I2S_PCM_RX__FUNC_GPIO188 (MTK_PIN_NO(188) | 0) +#define MT8135_PIN_188_MRG_I2S_PCM_RX__FUNC_MRG_I2S_PCM_RX (MTK_PIN_NO(188) | 1) +#define MT8135_PIN_188_MRG_I2S_PCM_RX__FUNC_EINT15 (MTK_PIN_NO(188) | 2) +#define MT8135_PIN_188_MRG_I2S_PCM_RX__FUNC_I2SIN_DAT (MTK_PIN_NO(188) | 3) +#define MT8135_PIN_188_MRG_I2S_PCM_RX__FUNC_PCM0_DI (MTK_PIN_NO(188) | 4) +#define MT8135_PIN_188_MRG_I2S_PCM_RX__FUNC_DSP2_ID (MTK_PIN_NO(188) | 5) +#define MT8135_PIN_188_MRG_I2S_PCM_RX__FUNC_MFG_TEST_CK (MTK_PIN_NO(188) | 6) +#define MT8135_PIN_188_MRG_I2S_PCM_RX__FUNC_USB_SDA (MTK_PIN_NO(188) | 7) + +#define MT8135_PIN_189_MRG_I2S_PCM_TX__FUNC_GPIO189 (MTK_PIN_NO(189) | 0) +#define MT8135_PIN_189_MRG_I2S_PCM_TX__FUNC_MRG_I2S_PCM_TX (MTK_PIN_NO(189) | 1) +#define MT8135_PIN_189_MRG_I2S_PCM_TX__FUNC_EINT17 (MTK_PIN_NO(189) | 2) +#define MT8135_PIN_189_MRG_I2S_PCM_TX__FUNC_I2SOUT_DAT (MTK_PIN_NO(189) | 3) +#define MT8135_PIN_189_MRG_I2S_PCM_TX__FUNC_PCM0_DO (MTK_PIN_NO(189) | 4) +#define MT8135_PIN_189_MRG_I2S_PCM_TX__FUNC_VDEC_TEST_CK (MTK_PIN_NO(189) | 6) + +#define MT8135_PIN_190_SRCLKENAI__FUNC_GPIO190 (MTK_PIN_NO(190) | 0) +#define MT8135_PIN_190_SRCLKENAI__FUNC_SRCLKENAI (MTK_PIN_NO(190) | 1) + +#define MT8135_PIN_191_URXD3__FUNC_GPIO191 (MTK_PIN_NO(191) | 0) +#define MT8135_PIN_191_URXD3__FUNC_URXD3 (MTK_PIN_NO(191) | 1) +#define MT8135_PIN_191_URXD3__FUNC_EINT87 (MTK_PIN_NO(191) | 2) +#define MT8135_PIN_191_URXD3__FUNC_UTXD3 (MTK_PIN_NO(191) | 3) +#define MT8135_PIN_191_URXD3__FUNC_TS_AUX_ST (MTK_PIN_NO(191) | 5) +#define MT8135_PIN_191_URXD3__FUNC_PWM4 (MTK_PIN_NO(191) | 6) + +#define MT8135_PIN_192_UTXD3__FUNC_GPIO192 (MTK_PIN_NO(192) | 0) +#define MT8135_PIN_192_UTXD3__FUNC_UTXD3 (MTK_PIN_NO(192) | 1) +#define MT8135_PIN_192_UTXD3__FUNC_EINT86 (MTK_PIN_NO(192) | 2) +#define MT8135_PIN_192_UTXD3__FUNC_URXD3 (MTK_PIN_NO(192) | 3) +#define MT8135_PIN_192_UTXD3__FUNC_TS_AUX_CS_B (MTK_PIN_NO(192) | 5) +#define MT8135_PIN_192_UTXD3__FUNC_PWM3 (MTK_PIN_NO(192) | 6) + +#define MT8135_PIN_193_SDA2__FUNC_GPIO193 (MTK_PIN_NO(193) | 0) +#define MT8135_PIN_193_SDA2__FUNC_SDA2 (MTK_PIN_NO(193) | 1) +#define MT8135_PIN_193_SDA2__FUNC_EINT95 (MTK_PIN_NO(193) | 2) +#define MT8135_PIN_193_SDA2__FUNC_CLKM5 (MTK_PIN_NO(193) | 3) +#define MT8135_PIN_193_SDA2__FUNC_PWM5 (MTK_PIN_NO(193) | 4) +#define MT8135_PIN_193_SDA2__FUNC_TS_AUX_PWDB (MTK_PIN_NO(193) | 5) + +#define MT8135_PIN_194_SCL2__FUNC_GPIO194 (MTK_PIN_NO(194) | 0) +#define MT8135_PIN_194_SCL2__FUNC_SCL2 (MTK_PIN_NO(194) | 1) +#define MT8135_PIN_194_SCL2__FUNC_EINT94 (MTK_PIN_NO(194) | 2) +#define MT8135_PIN_194_SCL2__FUNC_CLKM4 (MTK_PIN_NO(194) | 3) +#define MT8135_PIN_194_SCL2__FUNC_PWM4 (MTK_PIN_NO(194) | 4) +#define MT8135_PIN_194_SCL2__FUNC_TS_AUXADC_TEST_CK (MTK_PIN_NO(194) | 5) + +#define MT8135_PIN_195_SDA1__FUNC_GPIO195 (MTK_PIN_NO(195) | 0) +#define MT8135_PIN_195_SDA1__FUNC_SDA1 (MTK_PIN_NO(195) | 1) +#define MT8135_PIN_195_SDA1__FUNC_EINT93 (MTK_PIN_NO(195) | 2) +#define MT8135_PIN_195_SDA1__FUNC_CLKM3 (MTK_PIN_NO(195) | 3) +#define MT8135_PIN_195_SDA1__FUNC_PWM3 (MTK_PIN_NO(195) | 4) +#define MT8135_PIN_195_SDA1__FUNC_TS_AUX_SCLK_PWDB (MTK_PIN_NO(195) | 5) + +#define MT8135_PIN_196_SCL1__FUNC_GPIO196 (MTK_PIN_NO(196) | 0) +#define MT8135_PIN_196_SCL1__FUNC_SCL1 (MTK_PIN_NO(196) | 1) +#define MT8135_PIN_196_SCL1__FUNC_EINT92 (MTK_PIN_NO(196) | 2) +#define MT8135_PIN_196_SCL1__FUNC_CLKM2 (MTK_PIN_NO(196) | 3) +#define MT8135_PIN_196_SCL1__FUNC_PWM2 (MTK_PIN_NO(196) | 4) +#define MT8135_PIN_196_SCL1__FUNC_TS_AUX_DIN (MTK_PIN_NO(196) | 5) + +#define MT8135_PIN_197_MSDC3_DAT2__FUNC_GPIO197 (MTK_PIN_NO(197) | 0) +#define MT8135_PIN_197_MSDC3_DAT2__FUNC_MSDC3_DAT2 (MTK_PIN_NO(197) | 1) +#define MT8135_PIN_197_MSDC3_DAT2__FUNC_EINT71 (MTK_PIN_NO(197) | 2) +#define MT8135_PIN_197_MSDC3_DAT2__FUNC_SCL6 (MTK_PIN_NO(197) | 3) +#define MT8135_PIN_197_MSDC3_DAT2__FUNC_PWM5 (MTK_PIN_NO(197) | 4) +#define MT8135_PIN_197_MSDC3_DAT2__FUNC_CLKM4 (MTK_PIN_NO(197) | 5) +#define MT8135_PIN_197_MSDC3_DAT2__FUNC_MFG_TEST_CK_2 (MTK_PIN_NO(197) | 6) + +#define MT8135_PIN_198_MSDC3_DAT3__FUNC_GPIO198 (MTK_PIN_NO(198) | 0) +#define MT8135_PIN_198_MSDC3_DAT3__FUNC_MSDC3_DAT3 (MTK_PIN_NO(198) | 1) +#define MT8135_PIN_198_MSDC3_DAT3__FUNC_EINT72 (MTK_PIN_NO(198) | 2) +#define MT8135_PIN_198_MSDC3_DAT3__FUNC_SDA6 (MTK_PIN_NO(198) | 3) +#define MT8135_PIN_198_MSDC3_DAT3__FUNC_PWM6 (MTK_PIN_NO(198) | 4) +#define MT8135_PIN_198_MSDC3_DAT3__FUNC_CLKM5 (MTK_PIN_NO(198) | 5) +#define MT8135_PIN_198_MSDC3_DAT3__FUNC_MFG_TEST_CK_3 (MTK_PIN_NO(198) | 6) + +#define MT8135_PIN_199_MSDC3_CMD__FUNC_GPIO199 (MTK_PIN_NO(199) | 0) +#define MT8135_PIN_199_MSDC3_CMD__FUNC_MSDC3_CMD (MTK_PIN_NO(199) | 1) +#define MT8135_PIN_199_MSDC3_CMD__FUNC_EINT68 (MTK_PIN_NO(199) | 2) +#define MT8135_PIN_199_MSDC3_CMD__FUNC_SDA2 (MTK_PIN_NO(199) | 3) +#define MT8135_PIN_199_MSDC3_CMD__FUNC_PWM2 (MTK_PIN_NO(199) | 4) +#define MT8135_PIN_199_MSDC3_CMD__FUNC_CLKM1 (MTK_PIN_NO(199) | 5) +#define MT8135_PIN_199_MSDC3_CMD__FUNC_MFG_TEST_CK_4 (MTK_PIN_NO(199) | 6) + +#define MT8135_PIN_200_MSDC3_CLK__FUNC_GPIO200 (MTK_PIN_NO(200) | 0) +#define MT8135_PIN_200_MSDC3_CLK__FUNC_MSDC3_CLK (MTK_PIN_NO(200) | 1) +#define MT8135_PIN_200_MSDC3_CLK__FUNC_EINT67 (MTK_PIN_NO(200) | 2) +#define MT8135_PIN_200_MSDC3_CLK__FUNC_SCL2 (MTK_PIN_NO(200) | 3) +#define MT8135_PIN_200_MSDC3_CLK__FUNC_PWM1 (MTK_PIN_NO(200) | 4) +#define MT8135_PIN_200_MSDC3_CLK__FUNC_CLKM0 (MTK_PIN_NO(200) | 5) + +#define MT8135_PIN_201_MSDC3_DAT1__FUNC_GPIO201 (MTK_PIN_NO(201) | 0) +#define MT8135_PIN_201_MSDC3_DAT1__FUNC_MSDC3_DAT1 (MTK_PIN_NO(201) | 1) +#define MT8135_PIN_201_MSDC3_DAT1__FUNC_EINT70 (MTK_PIN_NO(201) | 2) +#define MT8135_PIN_201_MSDC3_DAT1__FUNC_SDA3 (MTK_PIN_NO(201) | 3) +#define MT8135_PIN_201_MSDC3_DAT1__FUNC_PWM4 (MTK_PIN_NO(201) | 4) +#define MT8135_PIN_201_MSDC3_DAT1__FUNC_CLKM3 (MTK_PIN_NO(201) | 5) + +#define MT8135_PIN_202_MSDC3_DAT0__FUNC_GPIO202 (MTK_PIN_NO(202) | 0) +#define MT8135_PIN_202_MSDC3_DAT0__FUNC_MSDC3_DAT0 (MTK_PIN_NO(202) | 1) +#define MT8135_PIN_202_MSDC3_DAT0__FUNC_EINT69 (MTK_PIN_NO(202) | 2) +#define MT8135_PIN_202_MSDC3_DAT0__FUNC_SCL3 (MTK_PIN_NO(202) | 3) +#define MT8135_PIN_202_MSDC3_DAT0__FUNC_PWM3 (MTK_PIN_NO(202) | 4) +#define MT8135_PIN_202_MSDC3_DAT0__FUNC_CLKM2 (MTK_PIN_NO(202) | 5) + +#endif /* __DTS_MT8135_PINFUNC_H */ diff --git a/arch/arm/boot/dts/mt8135.dtsi b/arch/arm/boot/dts/mt8135.dtsi index a161e99ffcc4..a069afd30e39 100644 --- a/arch/arm/boot/dts/mt8135.dtsi +++ b/arch/arm/boot/dts/mt8135.dtsi @@ -15,6 +15,7 @@ #include #include #include "skeleton64.dtsi" +#include "mt8135-pinfunc.h" / { compatible = "mediatek,mt8135"; @@ -101,6 +102,30 @@ compatible = "simple-bus"; ranges; + syscfg_pctl_a: syscfg_pctl_a@10005000 { + compatible = "mediatek,mt8135-pctl-a-syscfg", "syscon"; + reg = <0 0x10005000 0 0x1000>; + }; + + syscfg_pctl_b: syscfg_pctl_b@1020C000 { + compatible = "mediatek,mt8135-pctl-b-syscfg", "syscon"; + reg = <0 0x1020C000 0 0x1000>; + }; + + pio: pinctrl@10005000 { + compatible = "mediatek,mt8135-pinctrl"; + reg = <0 0x1000B000 0 0x1000>; + mediatek,pctl-regmap = <&syscfg_pctl_a &syscfg_pctl_b>; + pins-are-numbered; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = , + , + ; + }; + timer: timer@10008000 { compatible = "mediatek,mt8135-timer", "mediatek,mt6577-timer"; -- GitLab From b75f4c9afac2604feb971441116c07a24ecca1ec Mon Sep 17 00:00:00 2001 From: Ekaterina Tumanova Date: Tue, 3 Mar 2015 09:54:41 +0100 Subject: [PATCH 02934/11651] KVM: s390: Zero out current VMDB of STSI before including level3 data. s390 documentation requires words 0 and 10-15 to be reserved and stored as zeros. As we fill out all other fields, we can memset the full structure. Signed-off-by: Ekaterina Tumanova Cc: stable@vger.kernel.org Reviewed-by: David Hildenbrand Signed-off-by: Christian Borntraeger --- arch/s390/kvm/priv.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c index 351116939ea2..c7fee9db332a 100644 --- a/arch/s390/kvm/priv.c +++ b/arch/s390/kvm/priv.c @@ -467,6 +467,7 @@ static void handle_stsi_3_2_2(struct kvm_vcpu *vcpu, struct sysinfo_3_2_2 *mem) for (n = mem->count - 1; n > 0 ; n--) memcpy(&mem->vm[n], &mem->vm[n - 1], sizeof(mem->vm[0])); + memset(&mem->vm[0], 0, sizeof(mem->vm[0])); mem->vm[0].cpus_total = cpus; mem->vm[0].cpus_configured = cpus; mem->vm[0].cpus_standby = 0; -- GitLab From 261520dcfcba93ca5dfe671b88ffab038cd940c8 Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Wed, 4 Feb 2015 15:53:42 +0100 Subject: [PATCH 02935/11651] KVM: s390: fix handling of write errors in the tpi handler If the I/O interrupt could not be written to the guest provided area (e.g. access exception), a program exception was injected into the guest but "inti" wasn't freed, therefore resulting in a memory leak. In addition, the I/O interrupt wasn't reinjected. Therefore the dequeued interrupt is lost. This patch fixes the problem while cleaning up the function and making the cc and rc logic easier to handle. Signed-off-by: David Hildenbrand Cc: stable@vger.kernel.org # 3.16+ Signed-off-by: Christian Borntraeger --- arch/s390/kvm/priv.c | 40 +++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c index c7fee9db332a..be7138e84351 100644 --- a/arch/s390/kvm/priv.c +++ b/arch/s390/kvm/priv.c @@ -229,18 +229,19 @@ static int handle_tpi(struct kvm_vcpu *vcpu) struct kvm_s390_interrupt_info *inti; unsigned long len; u32 tpi_data[3]; - int cc, rc; + int rc; u64 addr; - rc = 0; addr = kvm_s390_get_base_disp_s(vcpu); if (addr & 3) return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); - cc = 0; + inti = kvm_s390_get_io_int(vcpu->kvm, vcpu->arch.sie_block->gcr[6], 0); - if (!inti) - goto no_interrupt; - cc = 1; + if (!inti) { + kvm_s390_set_psw_cc(vcpu, 0); + return 0; + } + tpi_data[0] = inti->io.subchannel_id << 16 | inti->io.subchannel_nr; tpi_data[1] = inti->io.io_int_parm; tpi_data[2] = inti->io.io_int_word; @@ -251,30 +252,35 @@ static int handle_tpi(struct kvm_vcpu *vcpu) */ len = sizeof(tpi_data) - 4; rc = write_guest(vcpu, addr, &tpi_data, len); - if (rc) - return kvm_s390_inject_prog_cond(vcpu, rc); + if (rc) { + rc = kvm_s390_inject_prog_cond(vcpu, rc); + goto reinject_interrupt; + } } else { /* * Store the three-word I/O interruption code into * the appropriate lowcore area. */ len = sizeof(tpi_data); - if (write_guest_lc(vcpu, __LC_SUBCHANNEL_ID, &tpi_data, len)) + if (write_guest_lc(vcpu, __LC_SUBCHANNEL_ID, &tpi_data, len)) { + /* failed writes to the low core are not recoverable */ rc = -EFAULT; + goto reinject_interrupt; + } } + + /* irq was successfully handed to the guest */ + kfree(inti); + kvm_s390_set_psw_cc(vcpu, 1); + return 0; +reinject_interrupt: /* * If we encounter a problem storing the interruption code, the * instruction is suppressed from the guest's view: reinject the * interrupt. */ - if (!rc) - kfree(inti); - else - kvm_s390_reinject_io_int(vcpu->kvm, inti); -no_interrupt: - /* Set condition code and we're done. */ - if (!rc) - kvm_s390_set_psw_cc(vcpu, cc); + kvm_s390_reinject_io_int(vcpu->kvm, inti); + /* don't set the cc, a pgm irq was injected or we drop to user space */ return rc ? -EFAULT : 0; } -- GitLab From 15462e37ca848abac7477dece65f8af25febd744 Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Wed, 4 Feb 2015 15:59:11 +0100 Subject: [PATCH 02936/11651] KVM: s390: reinjection of irqs can fail in the tpi handler The reinjection of an I/O interrupt can fail if the list is at the limit and between the dequeue and the reinjection, another I/O interrupt is injected (e.g. if user space floods kvm with I/O interrupts). This patch avoids this memory leak and returns -EFAULT in this special case. This error is not recoverable, so let's fail hard. This can later be avoided by not dequeuing the interrupt but working directly on the locked list. Signed-off-by: David Hildenbrand Cc: stable@vger.kernel.org # 3.16+ Signed-off-by: Christian Borntraeger --- arch/s390/kvm/interrupt.c | 4 ++-- arch/s390/kvm/kvm-s390.h | 4 ++-- arch/s390/kvm/priv.c | 5 ++++- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c index 073b5f387d1d..e7a46e817874 100644 --- a/arch/s390/kvm/interrupt.c +++ b/arch/s390/kvm/interrupt.c @@ -1332,10 +1332,10 @@ int kvm_s390_inject_vm(struct kvm *kvm, return rc; } -void kvm_s390_reinject_io_int(struct kvm *kvm, +int kvm_s390_reinject_io_int(struct kvm *kvm, struct kvm_s390_interrupt_info *inti) { - __inject_vm(kvm, inti); + return __inject_vm(kvm, inti); } int s390int_to_s390irq(struct kvm_s390_interrupt *s390int, diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h index c34109aa552d..6995a3080a0e 100644 --- a/arch/s390/kvm/kvm-s390.h +++ b/arch/s390/kvm/kvm-s390.h @@ -151,8 +151,8 @@ int __must_check kvm_s390_inject_vcpu(struct kvm_vcpu *vcpu, int __must_check kvm_s390_inject_program_int(struct kvm_vcpu *vcpu, u16 code); struct kvm_s390_interrupt_info *kvm_s390_get_io_int(struct kvm *kvm, u64 cr6, u64 schid); -void kvm_s390_reinject_io_int(struct kvm *kvm, - struct kvm_s390_interrupt_info *inti); +int kvm_s390_reinject_io_int(struct kvm *kvm, + struct kvm_s390_interrupt_info *inti); int kvm_s390_mask_adapter(struct kvm *kvm, unsigned int id, bool masked); /* implemented in intercept.c */ diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c index be7138e84351..b982fbca34df 100644 --- a/arch/s390/kvm/priv.c +++ b/arch/s390/kvm/priv.c @@ -279,7 +279,10 @@ reinject_interrupt: * instruction is suppressed from the guest's view: reinject the * interrupt. */ - kvm_s390_reinject_io_int(vcpu->kvm, inti); + if (kvm_s390_reinject_io_int(vcpu->kvm, inti)) { + kfree(inti); + rc = -EFAULT; + } /* don't set the cc, a pgm irq was injected or we drop to user space */ return rc ? -EFAULT : 0; } -- GitLab From a9a846fd5c1723820c97cef56989ea14eea4b30e Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Thu, 5 Feb 2015 09:06:56 +0100 Subject: [PATCH 02937/11651] KVM: s390: Nullify instruction for certain program exceptions When certain program exceptions (e.g. DAT access exceptions) occur, the current instruction has to be nullified, i.e. the old PSW that gets written into the low-core has to point to the beginning of the instruction again, and not to the beginning of the next instruction. Thus we have to rewind the PSW before writing it into the low-core. The list of nullifying exceptions can be found in the POP, chapter 6, figure 6-1 ("Interruption Action"). Signed-off-by: Thomas Huth Reviewed-by: Jens Freimann Reviewed-by: David Hildenbrand Acked-by: Christian Borntraeger Signed-off-by: Christian Borntraeger --- arch/s390/kvm/interrupt.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c index e7a46e817874..98a313138f83 100644 --- a/arch/s390/kvm/interrupt.c +++ b/arch/s390/kvm/interrupt.c @@ -484,7 +484,7 @@ static int __must_check __deliver_prog(struct kvm_vcpu *vcpu) { struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; struct kvm_s390_pgm_info pgm_info; - int rc = 0; + int rc = 0, nullifying = false; u16 ilc = get_ilc(vcpu); spin_lock(&li->lock); @@ -509,6 +509,8 @@ static int __must_check __deliver_prog(struct kvm_vcpu *vcpu) case PGM_LX_TRANSLATION: case PGM_PRIMARY_AUTHORITY: case PGM_SECONDARY_AUTHORITY: + nullifying = true; + /* fall through */ case PGM_SPACE_SWITCH: rc = put_guest_lc(vcpu, pgm_info.trans_exc_code, (u64 *)__LC_TRANS_EXC_CODE); @@ -521,6 +523,7 @@ static int __must_check __deliver_prog(struct kvm_vcpu *vcpu) case PGM_EXTENDED_AUTHORITY: rc = put_guest_lc(vcpu, pgm_info.exc_access_id, (u8 *)__LC_EXC_ACCESS_ID); + nullifying = true; break; case PGM_ASCE_TYPE: case PGM_PAGE_TRANSLATION: @@ -534,6 +537,7 @@ static int __must_check __deliver_prog(struct kvm_vcpu *vcpu) (u8 *)__LC_EXC_ACCESS_ID); rc |= put_guest_lc(vcpu, pgm_info.op_access_id, (u8 *)__LC_OP_ACCESS_ID); + nullifying = true; break; case PGM_MONITOR: rc = put_guest_lc(vcpu, pgm_info.mon_class_nr, @@ -551,6 +555,15 @@ static int __must_check __deliver_prog(struct kvm_vcpu *vcpu) rc |= put_guest_lc(vcpu, pgm_info.exc_access_id, (u8 *)__LC_EXC_ACCESS_ID); break; + case PGM_STACK_FULL: + case PGM_STACK_EMPTY: + case PGM_STACK_SPECIFICATION: + case PGM_STACK_TYPE: + case PGM_STACK_OPERATION: + case PGM_TRACE_TABEL: + case PGM_CRYPTO_OPERATION: + nullifying = true; + break; } if (pgm_info.code & PGM_PER) { @@ -564,6 +577,9 @@ static int __must_check __deliver_prog(struct kvm_vcpu *vcpu) (u8 *) __LC_PER_ACCESS_ID); } + if (nullifying && vcpu->arch.sie_block->icptcode == ICPT_INST) + kvm_s390_rewind_psw(vcpu, ilc); + rc |= put_guest_lc(vcpu, ilc, (u16 *) __LC_PGM_ILC); rc |= put_guest_lc(vcpu, pgm_info.code, (u16 *)__LC_PGM_INT_CODE); -- GitLab From 492d8642eaefbd47f6fb0e8265f058c02720e5c8 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Tue, 10 Feb 2015 16:11:01 +0100 Subject: [PATCH 02938/11651] KVM: s390: Forward PSW to next instruction for addressing exceptions When the SIE exited by a DAT access exceptions which we can not resolve, the guest tried to access a page which is out of bounds and can not be paged-in. In this case we have to signal the bad access by injecting an address exception. However, address exceptions are either suppressing or terminating, i.e. the PSW has to point to the next instruction when the exception is delivered. Since the originating DAT access exception is nullifying, the PSW still points to the offending instruction instead, so we've got to forward the PSW to the next instruction. Having fixed this issue, we can now also enable the TPROT interpretation facility again which had been disabled because of this problem. Signed-off-by: Thomas Huth Reviewed-by: Christian Borntraeger Signed-off-by: Christian Borntraeger --- arch/s390/kvm/kvm-s390.c | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index f6579cfde2df..7ac40aa70cf8 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -1148,8 +1148,7 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) vcpu->arch.sie_block->eca |= 1; if (sclp_has_sigpif()) vcpu->arch.sie_block->eca |= 0x10000000U; - vcpu->arch.sie_block->ictl |= ICTL_ISKE | ICTL_SSKE | ICTL_RRBE | - ICTL_TPROT; + vcpu->arch.sie_block->ictl |= ICTL_ISKE | ICTL_SSKE | ICTL_RRBE; if (kvm_s390_cmma_enabled(vcpu->kvm)) { rc = kvm_s390_vcpu_setup_cmma(vcpu); @@ -1726,6 +1725,31 @@ static int vcpu_pre_run(struct kvm_vcpu *vcpu) return 0; } +static int vcpu_post_run_fault_in_sie(struct kvm_vcpu *vcpu) +{ + psw_t *psw = &vcpu->arch.sie_block->gpsw; + u8 opcode; + int rc; + + VCPU_EVENT(vcpu, 3, "%s", "fault in sie instruction"); + trace_kvm_s390_sie_fault(vcpu); + + /* + * We want to inject an addressing exception, which is defined as a + * suppressing or terminating exception. However, since we came here + * by a DAT access exception, the PSW still points to the faulting + * instruction since DAT exceptions are nullifying. So we've got + * to look up the current opcode to get the length of the instruction + * to be able to forward the PSW. + */ + rc = read_guest(vcpu, psw->addr, &opcode, 1); + if (rc) + return kvm_s390_inject_prog_cond(vcpu, rc); + psw->addr = __rewind_psw(*psw, -insn_length(opcode)); + + return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING); +} + static int vcpu_post_run(struct kvm_vcpu *vcpu, int exit_reason) { int rc = -1; @@ -1757,11 +1781,8 @@ static int vcpu_post_run(struct kvm_vcpu *vcpu, int exit_reason) } } - if (rc == -1) { - VCPU_EVENT(vcpu, 3, "%s", "fault in sie instruction"); - trace_kvm_s390_sie_fault(vcpu); - rc = kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING); - } + if (rc == -1) + rc = vcpu_post_run_fault_in_sie(vcpu); memcpy(&vcpu->run->s.regs.gprs[14], &vcpu->arch.sie_block->gg14, 16); -- GitLab From 33b412acd32d403a8de9511f236f9b4f31551868 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Wed, 11 Feb 2015 10:38:46 +0100 Subject: [PATCH 02939/11651] KVM: s390: Use insn_length() to calculate length of instruction The common s390 function insn_length() results in slightly smaller (and thus hopefully faster) code than the calculation of the instruction length via a lookup-table. So let's use that function in the interrupt delivery code, too. Signed-off-by: Thomas Huth Reviewed-by: Jens Freimann Reviewed-by: David Hildenbrand Acked-by: Cornelia Huck Signed-off-by: Christian Borntraeger --- arch/s390/kvm/interrupt.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c index 98a313138f83..9561e1dea3e2 100644 --- a/arch/s390/kvm/interrupt.c +++ b/arch/s390/kvm/interrupt.c @@ -1,7 +1,7 @@ /* * handling kvm guest interrupts * - * Copyright IBM Corp. 2008,2014 + * Copyright IBM Corp. 2008, 2015 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License (version 2 only) @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include "kvm-s390.h" @@ -265,8 +266,6 @@ static void __set_intercept_indicator(struct kvm_vcpu *vcpu, static u16 get_ilc(struct kvm_vcpu *vcpu) { - const unsigned short table[] = { 2, 4, 4, 6 }; - switch (vcpu->arch.sie_block->icptcode) { case ICPT_INST: case ICPT_INSTPROGI: @@ -274,7 +273,7 @@ static u16 get_ilc(struct kvm_vcpu *vcpu) case ICPT_PARTEXEC: case ICPT_IOINST: /* last instruction only stored for these icptcodes */ - return table[vcpu->arch.sie_block->ipa >> 14]; + return insn_length(vcpu->arch.sie_block->ipa >> 8); case ICPT_PROGI: return vcpu->arch.sie_block->pgmilc; default: -- GitLab From 91520f1af8a01d349d19911238fc3dbed3fa58d2 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Fri, 27 Feb 2015 14:32:11 +0100 Subject: [PATCH 02940/11651] KVM: s390: perform vcpu model setup in a function The function kvm_s390_vcpu_setup_model() now performs all cpu model realated setup tasks for a vcpu. Besides cpuid and ibc initialization, facility list assignment takes place during the setup step as well. The model setup has been pulled to the begin of vcpu setup to allow kvm facility tests. There is no need to protect the cpu model setup with a lock since the attributes can't be changed anymore as soon the first vcpu is online. Signed-off-by: Michael Mueller Signed-off-by: Christian Borntraeger --- arch/s390/kvm/kvm-s390.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 7ac40aa70cf8..f3517e716fa4 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -1130,6 +1130,15 @@ int kvm_s390_vcpu_setup_cmma(struct kvm_vcpu *vcpu) return 0; } +static void kvm_s390_vcpu_setup_model(struct kvm_vcpu *vcpu) +{ + struct kvm_s390_cpu_model *model = &vcpu->kvm->arch.model; + + vcpu->arch.cpu_id = model->cpu_id; + vcpu->arch.sie_block->ibc = model->ibc; + vcpu->arch.sie_block->fac = (int) (long) model->fac->list; +} + int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) { int rc = 0; @@ -1138,6 +1147,8 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) CPUSTAT_SM | CPUSTAT_STOPPED | CPUSTAT_GED); + kvm_s390_vcpu_setup_model(vcpu); + vcpu->arch.sie_block->ecb = 6; if (test_kvm_facility(vcpu->kvm, 50) && test_kvm_facility(vcpu->kvm, 73)) vcpu->arch.sie_block->ecb |= 0x10; @@ -1158,11 +1169,6 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) hrtimer_init(&vcpu->arch.ckc_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); vcpu->arch.ckc_timer.function = kvm_s390_idle_wakeup; - mutex_lock(&vcpu->kvm->lock); - vcpu->arch.cpu_id = vcpu->kvm->arch.model.cpu_id; - vcpu->arch.sie_block->ibc = vcpu->kvm->arch.model.ibc; - mutex_unlock(&vcpu->kvm->lock); - kvm_s390_vcpu_crypto_setup(vcpu); return rc; @@ -1205,7 +1211,6 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, vcpu->arch.sie_block->scaol = (__u32)(__u64)kvm->arch.sca; set_bit(63 - id, (unsigned long *) &kvm->arch.sca->mcn); } - vcpu->arch.sie_block->fac = (int) (long) kvm->arch.model.fac->list; spin_lock_init(&vcpu->arch.local_int.lock); vcpu->arch.local_int.float_int = &kvm->arch.float_int; -- GitLab From 16b0fc13d60293ce073c8f9baa53469744b4d74a Mon Sep 17 00:00:00 2001 From: Yannick Guerrini Date: Thu, 26 Feb 2015 23:16:44 +0100 Subject: [PATCH 02941/11651] KVM: s390: Fix trivial typo in comments Change 'architecuture' to 'architecture' Signed-off-by: Yannick Guerrini Message-Id: <1424989004-14412-1-git-send-email-yguerrini@tomshardware.fr> Signed-off-by: Christian Borntraeger --- arch/s390/kvm/gaccess.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/s390/kvm/gaccess.c b/arch/s390/kvm/gaccess.c index 267523cac6de..633fe9bd75a9 100644 --- a/arch/s390/kvm/gaccess.c +++ b/arch/s390/kvm/gaccess.c @@ -333,7 +333,7 @@ static int deref_table(struct kvm *kvm, unsigned long gpa, unsigned long *val) * @write: indicates if access is a write access * * Translate a guest virtual address into a guest absolute address by means - * of dynamic address translation as specified by the architecuture. + * of dynamic address translation as specified by the architecture. * If the resulting absolute address is not available in the configuration * an addressing exception is indicated and @gpa will not be changed. * -- GitLab From 16a0c4c3aa68423b306fb82f6b9a2794e76f6fc0 Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Fri, 21 Nov 2014 15:39:06 +0100 Subject: [PATCH 02942/11651] KVM: s390: fix instruction interception trace point trace-cmd fails to parse the instruction interception trace point: "Error: expected type 5 but read 4 failed to read event print fmt for kvm_s390_intercept_instruction" The result is an unformatted string in the output, with a warning: "kvm_s390_intercept_instruction: [FAILED TO PARSE]..." So let's add parentheses around the instruction parser macro to fix the format parsing. Acked-by: Christian Borntraeger Acked-by: Cornelia Huck Signed-off-by: David Hildenbrand Signed-off-by: Christian Borntraeger --- arch/s390/include/uapi/asm/sie.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/s390/include/uapi/asm/sie.h b/arch/s390/include/uapi/asm/sie.h index d4096fdfc6ab..ee69c0854c88 100644 --- a/arch/s390/include/uapi/asm/sie.h +++ b/arch/s390/include/uapi/asm/sie.h @@ -230,7 +230,7 @@ * and returns a key, which can be used to find a mnemonic name * of the instruction in the icpt_insn_codes table. */ -#define icpt_insn_decoder(insn) \ +#define icpt_insn_decoder(insn) ( \ INSN_DECODE_IPA0(0x01, insn, 48, 0xff) \ INSN_DECODE_IPA0(0xaa, insn, 48, 0x0f) \ INSN_DECODE_IPA0(0xb2, insn, 48, 0xff) \ @@ -239,6 +239,6 @@ INSN_DECODE_IPA0(0xe5, insn, 48, 0xff) \ INSN_DECODE_IPA0(0xeb, insn, 16, 0xff) \ INSN_DECODE_IPA0(0xc8, insn, 48, 0x0f) \ - INSN_DECODE(insn) + INSN_DECODE(insn)) #endif /* _UAPI_ASM_S390_SIE_H */ -- GitLab From 1f289a8429022f112be9817a81ff07308eb78a9c Mon Sep 17 00:00:00 2001 From: Alexander Yarygin Date: Tue, 3 Mar 2015 19:05:43 +0300 Subject: [PATCH 02943/11651] KVM: s390: Use the read_guest_abs() in guest debug functions The guest debug functions work on absolute addresses and should use the read_guest_abs() function rather than general read_guest() that works with logical addresses. Cc: David Hildenbrand Signed-off-by: Alexander Yarygin Reviewed-by: David Hildenbrand Reviewed-by: Thomas Huth Signed-off-by: Christian Borntraeger --- arch/s390/kvm/guestdbg.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/s390/kvm/guestdbg.c b/arch/s390/kvm/guestdbg.c index 3e8d4092ce30..e97b3455d7e6 100644 --- a/arch/s390/kvm/guestdbg.c +++ b/arch/s390/kvm/guestdbg.c @@ -191,8 +191,8 @@ static int __import_wp_info(struct kvm_vcpu *vcpu, if (!wp_info->old_data) return -ENOMEM; /* try to backup the original value */ - ret = read_guest(vcpu, wp_info->phys_addr, wp_info->old_data, - wp_info->len); + ret = read_guest_abs(vcpu, wp_info->phys_addr, wp_info->old_data, + wp_info->len); if (ret) { kfree(wp_info->old_data); wp_info->old_data = NULL; @@ -362,8 +362,8 @@ static struct kvm_hw_wp_info_arch *any_wp_changed(struct kvm_vcpu *vcpu) continue; /* refetch the wp data and compare it to the old value */ - if (!read_guest(vcpu, wp_info->phys_addr, temp, - wp_info->len)) { + if (!read_guest_abs(vcpu, wp_info->phys_addr, temp, + wp_info->len)) { if (memcmp(temp, wp_info->old_data, wp_info->len)) { kfree(temp); return wp_info; -- GitLab From 68c557501b008515cb86c9a36c75f4e82e14a819 Mon Sep 17 00:00:00 2001 From: Eric Farman Date: Mon, 9 Jun 2014 10:57:26 -0400 Subject: [PATCH 02944/11651] KVM: s390: Allocate and save/restore vector registers Define and allocate space for both the host and guest views of the vector registers for a given vcpu. The 32 vector registers occupy 128 bits each (512 bytes total), but architecturally are paired with 512 additional bytes of reserved space for future expansion. The kvm_sync_regs structs containing the registers are union'ed with 1024 bytes of padding in the common kvm_run struct. The addition of 1024 bytes of new register information clearly exceeds the existing union, so an expansion of that padding is required. When changing environments, we need to appropriately save and restore the vector registers viewed by both the host and guest, into and out of the sync_regs space. The floating point registers overlay the upper half of vector registers 0-15, so there's a bit of data duplication here that needs to be carefully avoided. Signed-off-by: Eric Farman Reviewed-by: Thomas Huth Acked-by: Christian Borntraeger Signed-off-by: Christian Borntraeger --- Documentation/virtual/kvm/api.txt | 10 ++++++++ arch/s390/include/asm/kvm_host.h | 10 +++++++- arch/s390/include/uapi/asm/kvm.h | 4 ++++ arch/s390/kvm/kvm-s390.c | 39 ++++++++++++++++++++++++++----- include/uapi/linux/kvm.h | 3 ++- 5 files changed, 58 insertions(+), 8 deletions(-) diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt index b112efc816f1..ee47998ec368 100644 --- a/Documentation/virtual/kvm/api.txt +++ b/Documentation/virtual/kvm/api.txt @@ -3248,3 +3248,13 @@ All other orders will be handled completely in user space. Only privileged operation exceptions will be checked for in the kernel (or even in the hardware prior to interception). If this capability is not enabled, the old way of handling SIGP orders is used (partially in kernel and user space). + +7.3 KVM_CAP_S390_VECTOR_REGISTERS + +Architectures: s390 +Parameters: none +Returns: 0 on success, negative value on error + +Allows use of the vector registers introduced with z13 processor, and +provides for the synchronization between host and user space. Will +return -EINVAL if the machine does not support vectors. diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h index f407bbf5ee94..3449a388b169 100644 --- a/arch/s390/include/asm/kvm_host.h +++ b/arch/s390/include/asm/kvm_host.h @@ -183,11 +183,17 @@ struct kvm_s390_itdb { __u8 data[256]; } __packed; +struct kvm_s390_vregs { + __vector128 vrs[32]; + __u8 reserved200[512]; /* for future vector expansion */ +} __packed; + struct sie_page { struct kvm_s390_sie_block sie_block; __u8 reserved200[1024]; /* 0x0200 */ struct kvm_s390_itdb itdb; /* 0x0600 */ - __u8 reserved700[2304]; /* 0x0700 */ + __u8 reserved700[1280]; /* 0x0700 */ + struct kvm_s390_vregs vregs; /* 0x0c00 */ } __packed; struct kvm_vcpu_stat { @@ -465,6 +471,7 @@ struct kvm_vcpu_arch { s390_fp_regs host_fpregs; unsigned int host_acrs[NUM_ACRS]; s390_fp_regs guest_fpregs; + struct kvm_s390_vregs *host_vregs; struct kvm_s390_local_interrupt local_int; struct hrtimer ckc_timer; struct kvm_s390_pgm_info pgm; @@ -551,6 +558,7 @@ struct kvm_arch{ int css_support; int use_irqchip; int use_cmma; + int use_vectors; int user_cpu_state_ctrl; int user_sigp; struct s390_io_adapter *adapters[MAX_S390_IO_ADAPTERS]; diff --git a/arch/s390/include/uapi/asm/kvm.h b/arch/s390/include/uapi/asm/kvm.h index 9c77e60b9a26..ef1a5fcc6c66 100644 --- a/arch/s390/include/uapi/asm/kvm.h +++ b/arch/s390/include/uapi/asm/kvm.h @@ -150,6 +150,7 @@ struct kvm_guest_debug_arch { #define KVM_SYNC_CRS (1UL << 3) #define KVM_SYNC_ARCH0 (1UL << 4) #define KVM_SYNC_PFAULT (1UL << 5) +#define KVM_SYNC_VRS (1UL << 6) /* definition of registers in kvm_run */ struct kvm_sync_regs { __u64 prefix; /* prefix register */ @@ -164,6 +165,9 @@ struct kvm_sync_regs { __u64 pft; /* pfault token [PFAULT] */ __u64 pfs; /* pfault select [PFAULT] */ __u64 pfc; /* pfault compare [PFAULT] */ + __u64 vrs[32][2]; /* vector registers */ + __u8 reserved[512]; /* for future vector expansion */ + __u32 fpc; /* only valid with vector registers */ }; #define KVM_REG_S390_TODPR (KVM_REG_S390 | KVM_REG_SIZE_U32 | 0x1) diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index f3517e716fa4..a8fe3ab76d68 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -185,6 +185,9 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) case KVM_CAP_S390_COW: r = MACHINE_HAS_ESOP; break; + case KVM_CAP_S390_VECTOR_REGISTERS: + r = MACHINE_HAS_VX; + break; default: r = 0; } @@ -265,6 +268,10 @@ static int kvm_vm_ioctl_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap) kvm->arch.user_sigp = 1; r = 0; break; + case KVM_CAP_S390_VECTOR_REGISTERS: + kvm->arch.use_vectors = MACHINE_HAS_VX; + r = MACHINE_HAS_VX ? 0 : -EINVAL; + break; default: r = -EINVAL; break; @@ -942,6 +949,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) kvm->arch.css_support = 0; kvm->arch.use_irqchip = 0; + kvm->arch.use_vectors = 0; kvm->arch.epoch = 0; spin_lock_init(&kvm->arch.start_stop_lock); @@ -1035,6 +1043,8 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) KVM_SYNC_CRS | KVM_SYNC_ARCH0 | KVM_SYNC_PFAULT; + if (test_kvm_facility(vcpu->kvm, 129)) + vcpu->run->kvm_valid_regs |= KVM_SYNC_VRS; if (kvm_is_ucontrol(vcpu->kvm)) return __kvm_ucontrol_vcpu_init(vcpu); @@ -1045,10 +1055,18 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) { save_fp_ctl(&vcpu->arch.host_fpregs.fpc); - save_fp_regs(vcpu->arch.host_fpregs.fprs); + if (vcpu->kvm->arch.use_vectors) + save_vx_regs((__vector128 *)&vcpu->arch.host_vregs->vrs); + else + save_fp_regs(vcpu->arch.host_fpregs.fprs); save_access_regs(vcpu->arch.host_acrs); - restore_fp_ctl(&vcpu->arch.guest_fpregs.fpc); - restore_fp_regs(vcpu->arch.guest_fpregs.fprs); + if (vcpu->kvm->arch.use_vectors) { + restore_fp_ctl(&vcpu->run->s.regs.fpc); + restore_vx_regs((__vector128 *)&vcpu->run->s.regs.vrs); + } else { + restore_fp_ctl(&vcpu->arch.guest_fpregs.fpc); + restore_fp_regs(vcpu->arch.guest_fpregs.fprs); + } restore_access_regs(vcpu->run->s.regs.acrs); gmap_enable(vcpu->arch.gmap); atomic_set_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags); @@ -1058,11 +1076,19 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) { atomic_clear_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags); gmap_disable(vcpu->arch.gmap); - save_fp_ctl(&vcpu->arch.guest_fpregs.fpc); - save_fp_regs(vcpu->arch.guest_fpregs.fprs); + if (vcpu->kvm->arch.use_vectors) { + save_fp_ctl(&vcpu->run->s.regs.fpc); + save_vx_regs((__vector128 *)&vcpu->run->s.regs.vrs); + } else { + save_fp_ctl(&vcpu->arch.guest_fpregs.fpc); + save_fp_regs(vcpu->arch.guest_fpregs.fprs); + } save_access_regs(vcpu->run->s.regs.acrs); restore_fp_ctl(&vcpu->arch.host_fpregs.fpc); - restore_fp_regs(vcpu->arch.host_fpregs.fprs); + if (vcpu->kvm->arch.use_vectors) + restore_vx_regs((__vector128 *)&vcpu->arch.host_vregs->vrs); + else + restore_fp_regs(vcpu->arch.host_fpregs.fprs); restore_access_regs(vcpu->arch.host_acrs); } @@ -1196,6 +1222,7 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, vcpu->arch.sie_block = &sie_page->sie_block; vcpu->arch.sie_block->itdba = (unsigned long) &sie_page->itdb; + vcpu->arch.host_vregs = &sie_page->vregs; vcpu->arch.sie_block->icpua = id; if (!kvm_is_ucontrol(kvm)) { diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index 805570650062..82634a492fe0 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -324,7 +324,7 @@ struct kvm_run { __u64 kvm_dirty_regs; union { struct kvm_sync_regs regs; - char padding[1024]; + char padding[2048]; } s; }; @@ -760,6 +760,7 @@ struct kvm_ppc_smmu_info { #define KVM_CAP_PPC_ENABLE_HCALL 104 #define KVM_CAP_CHECK_EXTENSION_VM 105 #define KVM_CAP_S390_USER_SIGP 106 +#define KVM_CAP_S390_VECTOR_REGISTERS 107 #ifdef KVM_CAP_IRQ_ROUTING -- GitLab From 403c8648cb191ef88555bfa72deaa969c0367f41 Mon Sep 17 00:00:00 2001 From: Eric Farman Date: Mon, 2 Feb 2015 15:01:06 -0500 Subject: [PATCH 02945/11651] KVM: s390: Vector exceptions A new exception type for vector instructions is introduced with the new processor, but is handled exactly like a Data Exception which is already handled by the system. Signed-off-by: Eric Farman Reviewed-by: David Hildenbrand Acked-by: Christian Borntraeger Signed-off-by: Christian Borntraeger --- arch/s390/include/asm/kvm_host.h | 1 + arch/s390/kvm/intercept.c | 1 + arch/s390/kvm/interrupt.c | 1 + 3 files changed, 3 insertions(+) diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h index 3449a388b169..fb1fd39dfacd 100644 --- a/arch/s390/include/asm/kvm_host.h +++ b/arch/s390/include/asm/kvm_host.h @@ -276,6 +276,7 @@ struct kvm_vcpu_stat { #define PGM_SPECIAL_OPERATION 0x13 #define PGM_OPERAND 0x15 #define PGM_TRACE_TABEL 0x16 +#define PGM_VECTOR_PROCESSING 0x1b #define PGM_SPACE_SWITCH 0x1c #define PGM_HFP_SQUARE_ROOT 0x1d #define PGM_PC_TRANSLATION_SPEC 0x1f diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c index bebd2157edd0..08ae10a3b406 100644 --- a/arch/s390/kvm/intercept.c +++ b/arch/s390/kvm/intercept.c @@ -165,6 +165,7 @@ static void __extract_prog_irq(struct kvm_vcpu *vcpu, pgm_info->mon_class_nr = vcpu->arch.sie_block->mcn; pgm_info->mon_code = vcpu->arch.sie_block->tecmc; break; + case PGM_VECTOR_PROCESSING: case PGM_DATA: pgm_info->data_exc_code = vcpu->arch.sie_block->dxc; break; diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c index 9561e1dea3e2..036d3757aca9 100644 --- a/arch/s390/kvm/interrupt.c +++ b/arch/s390/kvm/interrupt.c @@ -544,6 +544,7 @@ static int __must_check __deliver_prog(struct kvm_vcpu *vcpu) rc |= put_guest_lc(vcpu, pgm_info.mon_code, (u64 *)__LC_MON_CODE); break; + case PGM_VECTOR_PROCESSING: case PGM_DATA: rc = put_guest_lc(vcpu, pgm_info.data_exc_code, (u32 *)__LC_DATA_EXC_CODE); -- GitLab From cd7b4b61063eb55ab7a5f96523e028c9e0914694 Mon Sep 17 00:00:00 2001 From: Eric Farman Date: Thu, 12 Feb 2015 09:06:34 -0500 Subject: [PATCH 02946/11651] KVM: s390: Add new SIGP order to kernel counters The new SIGP order Store Additional Status at Address is totally handled by user space, but we should still record the occurrence of this order in the kernel code. Signed-off-by: Eric Farman Reviewed-by: Thomas Huth Reviewed-by: David Hildenbrand Signed-off-by: Christian Borntraeger --- arch/s390/include/asm/kvm_host.h | 1 + arch/s390/kvm/kvm-s390.c | 1 + arch/s390/kvm/sigp.c | 3 +++ 3 files changed, 5 insertions(+) diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h index fb1fd39dfacd..3fe2597e4a4e 100644 --- a/arch/s390/include/asm/kvm_host.h +++ b/arch/s390/include/asm/kvm_host.h @@ -244,6 +244,7 @@ struct kvm_vcpu_stat { u32 instruction_sigp_stop; u32 instruction_sigp_stop_store_status; u32 instruction_sigp_store_status; + u32 instruction_sigp_store_adtl_status; u32 instruction_sigp_arch; u32 instruction_sigp_prefix; u32 instruction_sigp_restart; diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index a8fe3ab76d68..c0ae03aa0dff 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -87,6 +87,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { { "instruction_sigp_stop", VCPU_STAT(instruction_sigp_stop) }, { "instruction_sigp_stop_store_status", VCPU_STAT(instruction_sigp_stop_store_status) }, { "instruction_sigp_store_status", VCPU_STAT(instruction_sigp_store_status) }, + { "instruction_sigp_store_adtl_status", VCPU_STAT(instruction_sigp_store_adtl_status) }, { "instruction_sigp_set_arch", VCPU_STAT(instruction_sigp_arch) }, { "instruction_sigp_set_prefix", VCPU_STAT(instruction_sigp_prefix) }, { "instruction_sigp_restart", VCPU_STAT(instruction_sigp_restart) }, diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c index 23b1e86b2122..755a7330d361 100644 --- a/arch/s390/kvm/sigp.c +++ b/arch/s390/kvm/sigp.c @@ -393,6 +393,9 @@ static int handle_sigp_order_in_user_space(struct kvm_vcpu *vcpu, u8 order_code) case SIGP_STORE_STATUS_AT_ADDRESS: vcpu->stat.instruction_sigp_store_status++; break; + case SIGP_STORE_ADDITIONAL_STATUS: + vcpu->stat.instruction_sigp_store_adtl_status++; + break; case SIGP_SET_PREFIX: vcpu->stat.instruction_sigp_prefix++; break; -- GitLab From bc17de7c966504b287a1dceb76a523d8b7816731 Mon Sep 17 00:00:00 2001 From: Eric Farman Date: Mon, 14 Apr 2014 16:01:09 -0400 Subject: [PATCH 02947/11651] KVM: s390: Machine Check Store additional status in the machine check handler, in order to collect status (such as vector registers) that is not defined by store status. Signed-off-by: Eric Farman Reviewed-by: Thomas Huth Reviewed-by: David Hildenbrand Reviewed-by: Cornelia Huck Signed-off-by: Christian Borntraeger --- arch/s390/kernel/asm-offsets.c | 1 + arch/s390/kvm/interrupt.c | 4 ++++ arch/s390/kvm/kvm-s390.c | 29 +++++++++++++++++++++++++++++ arch/s390/kvm/kvm-s390.h | 3 +++ 4 files changed, 37 insertions(+) diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c index e07e91605353..8dc4db10d160 100644 --- a/arch/s390/kernel/asm-offsets.c +++ b/arch/s390/kernel/asm-offsets.c @@ -171,6 +171,7 @@ int main(void) #else /* CONFIG_32BIT */ DEFINE(__LC_DATA_EXC_CODE, offsetof(struct _lowcore, data_exc_code)); DEFINE(__LC_MCCK_FAIL_STOR_ADDR, offsetof(struct _lowcore, failing_storage_address)); + DEFINE(__LC_VX_SAVE_AREA_ADDR, offsetof(struct _lowcore, vector_save_area_addr)); DEFINE(__LC_EXT_PARAMS2, offsetof(struct _lowcore, ext_params2)); DEFINE(SAVE_AREA_BASE, offsetof(struct _lowcore, floating_pt_save_area)); DEFINE(__LC_PASTE, offsetof(struct _lowcore, paste)); diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c index 036d3757aca9..2afec6006def 100644 --- a/arch/s390/kvm/interrupt.c +++ b/arch/s390/kvm/interrupt.c @@ -351,6 +351,7 @@ static int __must_check __deliver_machine_check(struct kvm_vcpu *vcpu) { struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; struct kvm_s390_mchk_info mchk; + unsigned long adtl_status_addr; int rc; spin_lock(&li->lock); @@ -371,6 +372,9 @@ static int __must_check __deliver_machine_check(struct kvm_vcpu *vcpu) mchk.cr14, mchk.mcic); rc = kvm_s390_vcpu_store_status(vcpu, KVM_S390_STORE_STATUS_PREFIXED); + rc |= read_guest_lc(vcpu, __LC_VX_SAVE_AREA_ADDR, + &adtl_status_addr, sizeof(unsigned long)); + rc |= kvm_s390_vcpu_store_adtl_status(vcpu, adtl_status_addr); rc |= put_guest_lc(vcpu, mchk.mcic, (u64 __user *) __LC_MCCK_CODE); rc |= put_guest_lc(vcpu, mchk.failing_storage_address, diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index c0ae03aa0dff..0c045cfdce9b 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -2031,6 +2031,35 @@ int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr) return kvm_s390_store_status_unloaded(vcpu, addr); } +/* + * store additional status at address + */ +int kvm_s390_store_adtl_status_unloaded(struct kvm_vcpu *vcpu, + unsigned long gpa) +{ + /* Only bits 0-53 are used for address formation */ + if (!(gpa & ~0x3ff)) + return 0; + + return write_guest_abs(vcpu, gpa & ~0x3ff, + (void *)&vcpu->run->s.regs.vrs, 512); +} + +int kvm_s390_vcpu_store_adtl_status(struct kvm_vcpu *vcpu, unsigned long addr) +{ + if (!test_kvm_facility(vcpu->kvm, 129)) + return 0; + + /* + * The guest VXRS are in the host VXRs due to the lazy + * copying in vcpu load/put. Let's update our copies before we save + * it into the save area. + */ + save_vx_regs((__vector128 *)&vcpu->run->s.regs.vrs); + + return kvm_s390_store_adtl_status_unloaded(vcpu, addr); +} + static void __disable_ibs_on_vcpu(struct kvm_vcpu *vcpu) { kvm_check_request(KVM_REQ_ENABLE_IBS, vcpu); diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h index 6995a3080a0e..fda3f3146eb6 100644 --- a/arch/s390/kvm/kvm-s390.h +++ b/arch/s390/kvm/kvm-s390.h @@ -177,7 +177,10 @@ int kvm_s390_handle_sigp_pei(struct kvm_vcpu *vcpu); /* implemented in kvm-s390.c */ long kvm_arch_fault_in_page(struct kvm_vcpu *vcpu, gpa_t gpa, int writable); int kvm_s390_store_status_unloaded(struct kvm_vcpu *vcpu, unsigned long addr); +int kvm_s390_store_adtl_status_unloaded(struct kvm_vcpu *vcpu, + unsigned long addr); int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr); +int kvm_s390_vcpu_store_adtl_status(struct kvm_vcpu *vcpu, unsigned long addr); void kvm_s390_vcpu_start(struct kvm_vcpu *vcpu); void kvm_s390_vcpu_stop(struct kvm_vcpu *vcpu); void s390_vcpu_block(struct kvm_vcpu *vcpu); -- GitLab From 13211ea7b47db3d8ee2ff258a9a973a6d3aa3d43 Mon Sep 17 00:00:00 2001 From: Eric Farman Date: Wed, 30 Apr 2014 13:39:46 -0400 Subject: [PATCH 02948/11651] KVM: s390: Enable vector support for capable guest We finally have all the pieces in place, so let's include the vector facility bit in the mask of available hardware facilities for the guest to recognize. Also, enable the vector functionality in the guest control blocks, to avoid a possible vector data exception that would otherwise occur when a vector instruction is issued by the guest operating system. Signed-off-by: Eric Farman Reviewed-by: Thomas Huth Signed-off-by: Christian Borntraeger --- arch/s390/include/asm/kvm_host.h | 4 +++- arch/s390/kvm/kvm-s390.c | 5 +++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h index 3fe2597e4a4e..347a3333d618 100644 --- a/arch/s390/include/asm/kvm_host.h +++ b/arch/s390/include/asm/kvm_host.h @@ -172,7 +172,9 @@ struct kvm_s390_sie_block { __u32 fac; /* 0x01a0 */ __u8 reserved1a4[20]; /* 0x01a4 */ __u64 cbrlo; /* 0x01b8 */ - __u8 reserved1c0[30]; /* 0x01c0 */ + __u8 reserved1c0[8]; /* 0x01c0 */ + __u32 ecd; /* 0x01c8 */ + __u8 reserved1cc[18]; /* 0x01cc */ __u64 pp; /* 0x01de */ __u8 reserved1e6[2]; /* 0x01e6 */ __u64 itdba; /* 0x01e8 */ diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 0c045cfdce9b..02e03c862a60 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -104,6 +104,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { unsigned long kvm_s390_fac_list_mask[] = { 0xff82fffbf4fc2000UL, 0x005c000000000000UL, + 0x4000000000000000UL, }; unsigned long kvm_s390_fac_list_mask_size(void) @@ -1186,6 +1187,10 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) vcpu->arch.sie_block->eca |= 1; if (sclp_has_sigpif()) vcpu->arch.sie_block->eca |= 0x10000000U; + if (vcpu->kvm->arch.use_vectors) { + vcpu->arch.sie_block->eca |= 0x00020000; + vcpu->arch.sie_block->ecd |= 0x20000000; + } vcpu->arch.sie_block->ictl |= ICTL_ISKE | ICTL_SSKE | ICTL_RRBE; if (kvm_s390_cmma_enabled(vcpu->kvm)) { -- GitLab From 0a233cdf0aeb1d564fe8ae822bc3df70d4cf423b Mon Sep 17 00:00:00 2001 From: Yingjoe Chen Date: Fri, 6 Mar 2015 14:24:50 +0800 Subject: [PATCH 02949/11651] arm64: mediatek: Select PINCTRL for Mediatek platform MediaTek SoC expect to work with a pinctrl driver. Select PINCTRL if ARCH_MEDIATEK is selected. Signed-off-by: Yingjoe Chen Signed-off-by: Matthias Brugger --- arch/arm64/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 1b8e97331ffb..2e5a398c7b96 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -174,6 +174,7 @@ config ARCH_FSL_LS2085A config ARCH_MEDIATEK bool "Mediatek MT65xx & MT81xx ARMv8 SoC" select ARM_GIC + select PINCTRL help Support for Mediatek MT65xx & MT81xx ARMv8 SoCs -- GitLab From 85e40b0539b24518c8bdf63e2605c8522377d00f Mon Sep 17 00:00:00 2001 From: Juergen Gross Date: Thu, 26 Feb 2015 06:52:05 +0100 Subject: [PATCH 02950/11651] xen/events: avoid NULL pointer dereference in dom0 on large machines Using the pvops kernel a NULL pointer dereference was detected on a large machine (144 processors) when booting as dom0 in evtchn_fifo_unmask() during assignment of a pirq. The event channel in question was the first to need a new entry in event_array[] in events_fifo.c. Unfortunately xen_irq_info_pirq_setup() is called with evtchn being 0 for a new pirq and the real event channel number is assigned to the pirq only during __startup_pirq(). It is mandatory to call xen_evtchn_port_setup() after assigning the event channel number to the pirq to make sure all memory needed for the event channel is allocated. Signed-off-by: Juergen Gross Cc: # 3.14+ Signed-off-by: David Vrabel --- drivers/xen/events/events_base.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c index b4bca2d4a7e5..70fba973a107 100644 --- a/drivers/xen/events/events_base.c +++ b/drivers/xen/events/events_base.c @@ -526,20 +526,26 @@ static unsigned int __startup_pirq(unsigned int irq) pirq_query_unmask(irq); rc = set_evtchn_to_irq(evtchn, irq); - if (rc != 0) { - pr_err("irq%d: Failed to set port to irq mapping (%d)\n", - irq, rc); - xen_evtchn_close(evtchn); - return 0; - } + if (rc) + goto err; + bind_evtchn_to_cpu(evtchn, 0); info->evtchn = evtchn; + rc = xen_evtchn_port_setup(info); + if (rc) + goto err; + out: unmask_evtchn(evtchn); eoi_pirq(irq_get_irq_data(irq)); return 0; + +err: + pr_err("irq%d: Failed to set port to irq mapping (%d)\n", irq, rc); + xen_evtchn_close(evtchn); + return 0; } static unsigned int startup_pirq(struct irq_data *data) -- GitLab From d6482288aadcf19e348cbccff7a605790a3b3875 Mon Sep 17 00:00:00 2001 From: "Maciej S. Szmigiero" Date: Fri, 6 Mar 2015 16:59:00 +0100 Subject: [PATCH 02951/11651] ALSA: ac97: Add VT1613 AC97 codec support Patch to add an VT1613 AC97 codec support. This codec has additional DC offset removal control, headphone output and no video input. Signed-off-by: Maciej Szmigiero Signed-off-by: Takashi Iwai --- sound/pci/ac97/ac97_codec.c | 1 + sound/pci/ac97/ac97_patch.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index 5ee2f17c287c..5bca1a33fed6 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c @@ -177,6 +177,7 @@ static const struct ac97_codec_id snd_ac97_codec_ids[] = { { 0x54524123, 0xffffffff, "TR28602", NULL, NULL }, // only guess --jk [TR28023 = eMicro EM28023 (new CT1297)] { 0x54584e03, 0xffffffff, "TLV320AIC27", NULL, NULL }, { 0x54584e20, 0xffffffff, "TLC320AD9xC", NULL, NULL }, +{ 0x56494120, 0xfffffff0, "VIA1613", patch_vt1613, NULL }, { 0x56494161, 0xffffffff, "VIA1612A", NULL, NULL }, // modified ICE1232 with S/PDIF { 0x56494170, 0xffffffff, "VIA1617A", patch_vt1617a, NULL }, // modified VT1616 with S/PDIF { 0x56494182, 0xffffffff, "VIA1618", patch_vt1618, NULL }, diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c index ceaac1c41906..eca22100f70d 100644 --- a/sound/pci/ac97/ac97_patch.c +++ b/sound/pci/ac97/ac97_patch.c @@ -3351,6 +3351,39 @@ static int patch_cm9780(struct snd_ac97 *ac97) return 0; } +/* + * VIA VT1613 codec + */ +static const struct snd_kcontrol_new snd_ac97_controls_vt1613[] = { +AC97_SINGLE("DC Offset removal", 0x5a, 10, 1, 0), +}; + +static int patch_vt1613_specific(struct snd_ac97 *ac97) +{ + int err; + + err = patch_build_controls(ac97, &snd_ac97_controls_vt1613[0], + ARRAY_SIZE(snd_ac97_controls_vt1613)); + if (err) + return err; + + return 0; +}; + +static const struct snd_ac97_build_ops patch_vt1613_ops = { + .build_specific = patch_vt1613_specific +}; + +static int patch_vt1613(struct snd_ac97 *ac97) +{ + ac97->build_ops = &patch_vt1613_ops; + + ac97->flags |= AC97_HAS_NO_VIDEO; + ac97->caps |= AC97_BC_HEADPHONE; + + return 0; +} + /* * VIA VT1616 codec */ -- GitLab From d2192ea09858a8535b056fcede1a41d824e0b3d8 Mon Sep 17 00:00:00 2001 From: Ravikumar Kattekola Date: Sat, 31 Jan 2015 22:36:44 +0530 Subject: [PATCH 02952/11651] ARM: dts: DRA7x: Fix the bypass clock source for dpll_iva and others Fixes: ee6c750761 (ARM: dts: dra7 clock data) On DRA7x, For DPLL_IVA, the ref clock(CLKINP) is connected to sys_clk1 and the bypass input(CLKINPULOW) is connected to iva_dpll_hs_clk_div clock. But the bypass input is not directly routed to bypass clkout instead both CLKINP and CLKINPULOW are connected to bypass clkout via a mux. This mux is controlled by the bit - CM_CLKSEL_DPLL_IVA[23]:DPLL_BYP_CLKSEL and it's POR value is zero which selects the CLKINP as bypass clkout. which means iva_dpll_hs_clk_div is not the bypass clock for dpll_iva_ck Fix this by adding another mux clock as parent in bypass mode. This design is common to most of the PLLs and the rest have only one bypass clock. Below is a list of the DPLLs that need this fix: DPLL_IVA, DPLL_DDR, DPLL_DSP, DPLL_EVE, DPLL_GMAC, DPLL_PER, DPLL_USB and DPLL_CORE Signed-off-by: Ravikumar Kattekola Acked-by: Tero Kristo Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/dra7xx-clocks.dtsi | 90 +++++++++++++++++++++++++--- 1 file changed, 81 insertions(+), 9 deletions(-) diff --git a/arch/arm/boot/dts/dra7xx-clocks.dtsi b/arch/arm/boot/dts/dra7xx-clocks.dtsi index 4bdcbd61ce47..99b09a44e269 100644 --- a/arch/arm/boot/dts/dra7xx-clocks.dtsi +++ b/arch/arm/boot/dts/dra7xx-clocks.dtsi @@ -243,10 +243,18 @@ ti,invert-autoidle-bit; }; + dpll_core_byp_mux: dpll_core_byp_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>; + ti,bit-shift = <23>; + reg = <0x012c>; + }; + dpll_core_ck: dpll_core_ck { #clock-cells = <0>; compatible = "ti,omap4-dpll-core-clock"; - clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>; + clocks = <&sys_clkin1>, <&dpll_core_byp_mux>; reg = <0x0120>, <0x0124>, <0x012c>, <0x0128>; }; @@ -309,10 +317,18 @@ clock-div = <1>; }; + dpll_dsp_byp_mux: dpll_dsp_byp_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&sys_clkin1>, <&dsp_dpll_hs_clk_div>; + ti,bit-shift = <23>; + reg = <0x0240>; + }; + dpll_dsp_ck: dpll_dsp_ck { #clock-cells = <0>; compatible = "ti,omap4-dpll-clock"; - clocks = <&sys_clkin1>, <&dsp_dpll_hs_clk_div>; + clocks = <&sys_clkin1>, <&dpll_dsp_byp_mux>; reg = <0x0234>, <0x0238>, <0x0240>, <0x023c>; }; @@ -335,10 +351,18 @@ clock-div = <1>; }; + dpll_iva_byp_mux: dpll_iva_byp_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&sys_clkin1>, <&iva_dpll_hs_clk_div>; + ti,bit-shift = <23>; + reg = <0x01ac>; + }; + dpll_iva_ck: dpll_iva_ck { #clock-cells = <0>; compatible = "ti,omap4-dpll-clock"; - clocks = <&sys_clkin1>, <&iva_dpll_hs_clk_div>; + clocks = <&sys_clkin1>, <&dpll_iva_byp_mux>; reg = <0x01a0>, <0x01a4>, <0x01ac>, <0x01a8>; }; @@ -361,10 +385,18 @@ clock-div = <1>; }; + dpll_gpu_byp_mux: dpll_gpu_byp_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>; + ti,bit-shift = <23>; + reg = <0x02e4>; + }; + dpll_gpu_ck: dpll_gpu_ck { #clock-cells = <0>; compatible = "ti,omap4-dpll-clock"; - clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>; + clocks = <&sys_clkin1>, <&dpll_gpu_byp_mux>; reg = <0x02d8>, <0x02dc>, <0x02e4>, <0x02e0>; }; @@ -398,10 +430,18 @@ clock-div = <1>; }; + dpll_ddr_byp_mux: dpll_ddr_byp_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>; + ti,bit-shift = <23>; + reg = <0x021c>; + }; + dpll_ddr_ck: dpll_ddr_ck { #clock-cells = <0>; compatible = "ti,omap4-dpll-clock"; - clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>; + clocks = <&sys_clkin1>, <&dpll_ddr_byp_mux>; reg = <0x0210>, <0x0214>, <0x021c>, <0x0218>; }; @@ -416,10 +456,18 @@ ti,invert-autoidle-bit; }; + dpll_gmac_byp_mux: dpll_gmac_byp_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>; + ti,bit-shift = <23>; + reg = <0x02b4>; + }; + dpll_gmac_ck: dpll_gmac_ck { #clock-cells = <0>; compatible = "ti,omap4-dpll-clock"; - clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>; + clocks = <&sys_clkin1>, <&dpll_gmac_byp_mux>; reg = <0x02a8>, <0x02ac>, <0x02b4>, <0x02b0>; }; @@ -482,10 +530,18 @@ clock-div = <1>; }; + dpll_eve_byp_mux: dpll_eve_byp_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&sys_clkin1>, <&eve_dpll_hs_clk_div>; + ti,bit-shift = <23>; + reg = <0x0290>; + }; + dpll_eve_ck: dpll_eve_ck { #clock-cells = <0>; compatible = "ti,omap4-dpll-clock"; - clocks = <&sys_clkin1>, <&eve_dpll_hs_clk_div>; + clocks = <&sys_clkin1>, <&dpll_eve_byp_mux>; reg = <0x0284>, <0x0288>, <0x0290>, <0x028c>; }; @@ -1249,10 +1305,18 @@ clock-div = <1>; }; + dpll_per_byp_mux: dpll_per_byp_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&sys_clkin1>, <&per_dpll_hs_clk_div>; + ti,bit-shift = <23>; + reg = <0x014c>; + }; + dpll_per_ck: dpll_per_ck { #clock-cells = <0>; compatible = "ti,omap4-dpll-clock"; - clocks = <&sys_clkin1>, <&per_dpll_hs_clk_div>; + clocks = <&sys_clkin1>, <&dpll_per_byp_mux>; reg = <0x0140>, <0x0144>, <0x014c>, <0x0148>; }; @@ -1275,10 +1339,18 @@ clock-div = <1>; }; + dpll_usb_byp_mux: dpll_usb_byp_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&sys_clkin1>, <&usb_dpll_hs_clk_div>; + ti,bit-shift = <23>; + reg = <0x018c>; + }; + dpll_usb_ck: dpll_usb_ck { #clock-cells = <0>; compatible = "ti,omap4-dpll-j-type-clock"; - clocks = <&sys_clkin1>, <&usb_dpll_hs_clk_div>; + clocks = <&sys_clkin1>, <&dpll_usb_byp_mux>; reg = <0x0180>, <0x0184>, <0x018c>, <0x0188>; }; -- GitLab From ac92abcb966fd063fdb65343fd2d9d3b75a7a222 Mon Sep 17 00:00:00 2001 From: Ravikumar Kattekola Date: Sat, 31 Jan 2015 22:36:45 +0530 Subject: [PATCH 02953/11651] ARM: dts: OMAP5: Fix the bypass clock source for dpll_iva and others Fixes 85dc74e9 (ARM: dts: omap5 clock data) On OMAP54xx, For DPLL_IVA, the ref clock(CLKINP) is connected to sys_clk1 and the bypass input(CLKINPULOW) is connected to iva_dpll_hs_clk_div clock. But the bypass input is not directly routed to bypass clkout instead both CLKINP and CLKINPULOW are connected to bypass clkout via a mux. This mux is controlled by the bit - CM_CLKSEL_DPLL_IVA[23]:DPLL_BYP_CLKSEL and it's POR value is zero which selects the CLKINP as bypass clkout. which means iva_dpll_hs_clk_div is not the bypass clock for dpll_iva_ck Fix this by adding another mux clock as parent in bypass mode. This design is common to most of the PLLs and the rest have only one bypass clock. Below is a list of the DPLLs that need this fix: DPLL_IVA, DPLL_PER, DPLL_USB and DPLL_CORE Signed-off-by: Ravikumar Kattekola Acked-by: Tero Kristo Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/omap54xx-clocks.dtsi | 41 +++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/arch/arm/boot/dts/omap54xx-clocks.dtsi b/arch/arm/boot/dts/omap54xx-clocks.dtsi index 58c27466f012..83b425fb3ac2 100644 --- a/arch/arm/boot/dts/omap54xx-clocks.dtsi +++ b/arch/arm/boot/dts/omap54xx-clocks.dtsi @@ -167,10 +167,18 @@ ti,index-starts-at-one; }; + dpll_core_byp_mux: dpll_core_byp_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&sys_clkin>, <&dpll_abe_m3x2_ck>; + ti,bit-shift = <23>; + reg = <0x012c>; + }; + dpll_core_ck: dpll_core_ck { #clock-cells = <0>; compatible = "ti,omap4-dpll-core-clock"; - clocks = <&sys_clkin>, <&dpll_abe_m3x2_ck>; + clocks = <&sys_clkin>, <&dpll_core_byp_mux>; reg = <0x0120>, <0x0124>, <0x012c>, <0x0128>; }; @@ -294,10 +302,18 @@ clock-div = <1>; }; + dpll_iva_byp_mux: dpll_iva_byp_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&sys_clkin>, <&iva_dpll_hs_clk_div>; + ti,bit-shift = <23>; + reg = <0x01ac>; + }; + dpll_iva_ck: dpll_iva_ck { #clock-cells = <0>; compatible = "ti,omap4-dpll-clock"; - clocks = <&sys_clkin>, <&iva_dpll_hs_clk_div>; + clocks = <&sys_clkin>, <&dpll_iva_byp_mux>; reg = <0x01a0>, <0x01a4>, <0x01ac>, <0x01a8>; }; @@ -599,10 +615,19 @@ }; }; &cm_core_clocks { + + dpll_per_byp_mux: dpll_per_byp_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&sys_clkin>, <&per_dpll_hs_clk_div>; + ti,bit-shift = <23>; + reg = <0x014c>; + }; + dpll_per_ck: dpll_per_ck { #clock-cells = <0>; compatible = "ti,omap4-dpll-clock"; - clocks = <&sys_clkin>, <&per_dpll_hs_clk_div>; + clocks = <&sys_clkin>, <&dpll_per_byp_mux>; reg = <0x0140>, <0x0144>, <0x014c>, <0x0148>; }; @@ -714,10 +739,18 @@ ti,index-starts-at-one; }; + dpll_usb_byp_mux: dpll_usb_byp_mux { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&sys_clkin>, <&usb_dpll_hs_clk_div>; + ti,bit-shift = <23>; + reg = <0x018c>; + }; + dpll_usb_ck: dpll_usb_ck { #clock-cells = <0>; compatible = "ti,omap4-dpll-j-type-clock"; - clocks = <&sys_clkin>, <&usb_dpll_hs_clk_div>; + clocks = <&sys_clkin>, <&dpll_usb_byp_mux>; reg = <0x0180>, <0x0184>, <0x018c>, <0x0188>; }; -- GitLab From 5371fc0ecdf55b6811ade8a198de8ace2f4e5861 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Fri, 6 Mar 2015 13:41:42 -0300 Subject: [PATCH 02954/11651] ALSA: ac97: ac97_patch: Simplify patch_vt1613_specific() We can simplify the code by returning patch_build_controls() directly. Signed-off-by: Fabio Estevam Signed-off-by: Takashi Iwai --- sound/pci/ac97/ac97_patch.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c index eca22100f70d..f4234edb878c 100644 --- a/sound/pci/ac97/ac97_patch.c +++ b/sound/pci/ac97/ac97_patch.c @@ -3360,14 +3360,8 @@ AC97_SINGLE("DC Offset removal", 0x5a, 10, 1, 0), static int patch_vt1613_specific(struct snd_ac97 *ac97) { - int err; - - err = patch_build_controls(ac97, &snd_ac97_controls_vt1613[0], - ARRAY_SIZE(snd_ac97_controls_vt1613)); - if (err) - return err; - - return 0; + return patch_build_controls(ac97, &snd_ac97_controls_vt1613[0], + ARRAY_SIZE(snd_ac97_controls_vt1613)); }; static const struct snd_ac97_build_ops patch_vt1613_ops = { -- GitLab From 6e22616eba7e25fac5aa6cb6563471afa1815ec2 Mon Sep 17 00:00:00 2001 From: Vignesh R Date: Tue, 10 Feb 2015 11:05:41 +0530 Subject: [PATCH 02955/11651] ARM: dts: am33xx-clocks: Fix ehrpwm tbclk data on am33xx ehrpwm tbclk is wrongly modelled as deriving from dpll_per_m2_ck. The TRM says tbclk is derived from SYSCLKOUT. SYSCLKOUT nothing but the functional clock of pwmss (l4ls_gclk). Fix this by changing source of ehrpwmx_tbclk to l4ls_gclk. Fixes: 9e100ebafb91: ("Fix ehrpwm tbclk data") Signed-off-by: Vignesh R Acked-by: Tero Kristo Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/am33xx-clocks.dtsi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/boot/dts/am33xx-clocks.dtsi b/arch/arm/boot/dts/am33xx-clocks.dtsi index 712edce7d6fb..071b56aa0c7e 100644 --- a/arch/arm/boot/dts/am33xx-clocks.dtsi +++ b/arch/arm/boot/dts/am33xx-clocks.dtsi @@ -99,7 +99,7 @@ ehrpwm0_tbclk: ehrpwm0_tbclk@44e10664 { #clock-cells = <0>; compatible = "ti,gate-clock"; - clocks = <&dpll_per_m2_ck>; + clocks = <&l4ls_gclk>; ti,bit-shift = <0>; reg = <0x0664>; }; @@ -107,7 +107,7 @@ ehrpwm1_tbclk: ehrpwm1_tbclk@44e10664 { #clock-cells = <0>; compatible = "ti,gate-clock"; - clocks = <&dpll_per_m2_ck>; + clocks = <&l4ls_gclk>; ti,bit-shift = <1>; reg = <0x0664>; }; @@ -115,7 +115,7 @@ ehrpwm2_tbclk: ehrpwm2_tbclk@44e10664 { #clock-cells = <0>; compatible = "ti,gate-clock"; - clocks = <&dpll_per_m2_ck>; + clocks = <&l4ls_gclk>; ti,bit-shift = <2>; reg = <0x0664>; }; -- GitLab From 7d53d25578486d65bd7cd242bc7816b40e55e62b Mon Sep 17 00:00:00 2001 From: Vignesh R Date: Tue, 10 Feb 2015 11:05:42 +0530 Subject: [PATCH 02956/11651] ARM: dts: am43xx-clocks: Fix ehrpwm tbclk data on am43xx ehrpwm tbclk is wrongly modelled as deriving from dpll_per_m2_ck. The TRM says tbclk is derived from SYSCLKOUT. SYSCLKOUT nothing but the functional clock of pwmss (l4ls_gclk). Fix this by changing source of ehrpwmx_tbclk to l4ls_gclk. Fixes: 4da1c67719f61 ("add tbclk data for ehrpwm") Signed-off-by: Vignesh R Acked-by: Tero Kristo Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/am43xx-clocks.dtsi | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/arm/boot/dts/am43xx-clocks.dtsi b/arch/arm/boot/dts/am43xx-clocks.dtsi index c7dc9dab93a4..cfb49686ab6a 100644 --- a/arch/arm/boot/dts/am43xx-clocks.dtsi +++ b/arch/arm/boot/dts/am43xx-clocks.dtsi @@ -107,7 +107,7 @@ ehrpwm0_tbclk: ehrpwm0_tbclk { #clock-cells = <0>; compatible = "ti,gate-clock"; - clocks = <&dpll_per_m2_ck>; + clocks = <&l4ls_gclk>; ti,bit-shift = <0>; reg = <0x0664>; }; @@ -115,7 +115,7 @@ ehrpwm1_tbclk: ehrpwm1_tbclk { #clock-cells = <0>; compatible = "ti,gate-clock"; - clocks = <&dpll_per_m2_ck>; + clocks = <&l4ls_gclk>; ti,bit-shift = <1>; reg = <0x0664>; }; @@ -123,7 +123,7 @@ ehrpwm2_tbclk: ehrpwm2_tbclk { #clock-cells = <0>; compatible = "ti,gate-clock"; - clocks = <&dpll_per_m2_ck>; + clocks = <&l4ls_gclk>; ti,bit-shift = <2>; reg = <0x0664>; }; @@ -131,7 +131,7 @@ ehrpwm3_tbclk: ehrpwm3_tbclk { #clock-cells = <0>; compatible = "ti,gate-clock"; - clocks = <&dpll_per_m2_ck>; + clocks = <&l4ls_gclk>; ti,bit-shift = <4>; reg = <0x0664>; }; @@ -139,7 +139,7 @@ ehrpwm4_tbclk: ehrpwm4_tbclk { #clock-cells = <0>; compatible = "ti,gate-clock"; - clocks = <&dpll_per_m2_ck>; + clocks = <&l4ls_gclk>; ti,bit-shift = <5>; reg = <0x0664>; }; @@ -147,7 +147,7 @@ ehrpwm5_tbclk: ehrpwm5_tbclk { #clock-cells = <0>; compatible = "ti,gate-clock"; - clocks = <&dpll_per_m2_ck>; + clocks = <&l4ls_gclk>; ti,bit-shift = <6>; reg = <0x0664>; }; -- GitLab From a43b446dcc228eafb61357feafdda1d1bd0a2aef Mon Sep 17 00:00:00 2001 From: Matt Porter Date: Wed, 25 Feb 2015 13:52:41 -0500 Subject: [PATCH 02957/11651] ARM: dts: am335x-bone-common: enable aes and sham Beaglebone Black doesn't have AES and SHAM enabled like the original Beaglebone White dts. This breaks applications that leverage the crypto blocks so fix this by enabling these nodes in the am335x-bone-common.dtsi. With this change, enabling the nodes in am335x-bone.dts is no longer required so remove them. Signed-off-by: Matt Porter Acked-by: Robert Nelson Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/am335x-bone-common.dtsi | 8 ++++++++ arch/arm/boot/dts/am335x-bone.dts | 8 -------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/arm/boot/dts/am335x-bone-common.dtsi b/arch/arm/boot/dts/am335x-bone-common.dtsi index 2c6248d9a9ef..c3255e0c90aa 100644 --- a/arch/arm/boot/dts/am335x-bone-common.dtsi +++ b/arch/arm/boot/dts/am335x-bone-common.dtsi @@ -301,3 +301,11 @@ cd-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>; cd-inverted; }; + +&aes { + status = "okay"; +}; + +&sham { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/am335x-bone.dts b/arch/arm/boot/dts/am335x-bone.dts index 83d40f7655e5..6b8493720424 100644 --- a/arch/arm/boot/dts/am335x-bone.dts +++ b/arch/arm/boot/dts/am335x-bone.dts @@ -24,11 +24,3 @@ &mmc1 { vmmc-supply = <&ldo3_reg>; }; - -&sham { - status = "okay"; -}; - -&aes { - status = "okay"; -}; -- GitLab From 87be4891d88842ba64d0065e26649d1ec7c4ee47 Mon Sep 17 00:00:00 2001 From: George McCollister Date: Thu, 26 Feb 2015 10:48:14 -0600 Subject: [PATCH 02958/11651] ARM: dts: am335x-lxm: Use rmii-clock-ext Use external clock for RMII since the internal clock doesn't meet the jitter requirements. Signed-off-by: George McCollister Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/am335x-lxm.dts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm/boot/dts/am335x-lxm.dts b/arch/arm/boot/dts/am335x-lxm.dts index 7266a00aab2e..5c5667a3624d 100644 --- a/arch/arm/boot/dts/am335x-lxm.dts +++ b/arch/arm/boot/dts/am335x-lxm.dts @@ -328,6 +328,10 @@ dual_emac_res_vlan = <3>; }; +&phy_sel { + rmii-clock-ext; +}; + &mac { pinctrl-names = "default", "sleep"; pinctrl-0 = <&cpsw_default>; -- GitLab From 38f5c8ba300f8d5d327a14ea4d48522b38baf424 Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Fri, 27 Feb 2015 15:59:03 +0200 Subject: [PATCH 02959/11651] ARM: dts: OMAP5: fix polling intervals for thermal zones OMAP4 has a finer counter granularity, which allows for a delay of 1000ms in the thermal zone polling intervals. OMAP5 has a different counter mechanism, which allows at maximum a 500ms timer. Adjust the cpu thermal zone polling interval accordingly. Without this patch, the polling interval information is simply ignored, and the following thermal warnings are printed during boot (assuming thermal is enabled); [ 1.545343] ti-soc-thermal 4a0021e0.bandgap: Delay 1000 ms is not supported [ 1.552691] ti-soc-thermal 4a0021e0.bandgap: Delay 1000 ms is not supported [ 1.560029] ti-soc-thermal 4a0021e0.bandgap: Delay 1000 ms is not supported Signed-off-by: Tero Kristo Cc: Tony Lindgren Acked-by: Eduardo Valentin Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/omap5-core-thermal.dtsi | 2 +- arch/arm/boot/dts/omap5-gpu-thermal.dtsi | 2 +- arch/arm/boot/dts/omap5.dtsi | 4 ++++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/omap5-core-thermal.dtsi b/arch/arm/boot/dts/omap5-core-thermal.dtsi index 19212ac6eef0..de8a3d456cf7 100644 --- a/arch/arm/boot/dts/omap5-core-thermal.dtsi +++ b/arch/arm/boot/dts/omap5-core-thermal.dtsi @@ -13,7 +13,7 @@ core_thermal: core_thermal { polling-delay-passive = <250>; /* milliseconds */ - polling-delay = <1000>; /* milliseconds */ + polling-delay = <500>; /* milliseconds */ /* sensor ID */ thermal-sensors = <&bandgap 2>; diff --git a/arch/arm/boot/dts/omap5-gpu-thermal.dtsi b/arch/arm/boot/dts/omap5-gpu-thermal.dtsi index 1b87aca88b77..bc3090f2e84b 100644 --- a/arch/arm/boot/dts/omap5-gpu-thermal.dtsi +++ b/arch/arm/boot/dts/omap5-gpu-thermal.dtsi @@ -13,7 +13,7 @@ gpu_thermal: gpu_thermal { polling-delay-passive = <250>; /* milliseconds */ - polling-delay = <1000>; /* milliseconds */ + polling-delay = <500>; /* milliseconds */ /* sensor ID */ thermal-sensors = <&bandgap 1>; diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi index ddff674bd05e..4a485b63a141 100644 --- a/arch/arm/boot/dts/omap5.dtsi +++ b/arch/arm/boot/dts/omap5.dtsi @@ -1079,4 +1079,8 @@ }; }; +&cpu_thermal { + polling-delay = <500>; /* milliseconds */ +}; + /include/ "omap54xx-clocks.dtsi" -- GitLab From 424e0f039bfa8a51fb5c5178b6ece8baa4996469 Mon Sep 17 00:00:00 2001 From: Dave Gerlach Date: Fri, 27 Feb 2015 19:10:26 -0600 Subject: [PATCH 02960/11651] ARM: dts: am33xx: fix SLEWCTRL_FAST pinctrl binding According to AM335x TRM, Document spruh73l, Revised February 2015, Section 9.2.2 Pad Control Registers, setting bit 6 of the pad control registers actually sets the SLEWCTRL value to slow rather than fast as the current macro indicates. Introduce a new macro, SLEWCTRL_SLOW, that sets the bit, and modify SLEWCTRL_FAST to 0 but keep it for completeness. Current users of the macro (i2c and mdio) are left unmodified as SLEWCTRL_FAST was the macro used and actual desired state. Tested on am335x-gp-evm with no difference in software performance seen. Signed-off-by: Dave Gerlach Signed-off-by: Tony Lindgren --- include/dt-bindings/pinctrl/am33xx.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/dt-bindings/pinctrl/am33xx.h b/include/dt-bindings/pinctrl/am33xx.h index 2fbc804e1a45..226f77246a70 100644 --- a/include/dt-bindings/pinctrl/am33xx.h +++ b/include/dt-bindings/pinctrl/am33xx.h @@ -13,7 +13,8 @@ #define PULL_DISABLE (1 << 3) #define INPUT_EN (1 << 5) -#define SLEWCTRL_FAST (1 << 6) +#define SLEWCTRL_SLOW (1 << 6) +#define SLEWCTRL_FAST 0 /* update macro depending on INPUT_EN and PULL_ENA */ #undef PIN_OUTPUT -- GitLab From 10b218551444934b3ed864ec9eb81332d68d21ed Mon Sep 17 00:00:00 2001 From: Dave Gerlach Date: Fri, 27 Feb 2015 19:10:27 -0600 Subject: [PATCH 02961/11651] ARM: dts: am43xx: fix SLEWCTRL_FAST pinctrl binding According to AM437x TRM, Document SPRUHL7B, Revised December 2014, Section 7.2.1 Pad Control Registers, setting bit 19 of the pad control registers actually sets the SLEWCTRL value to slow rather than fast as the current macro indicates. Introduce a new macro, SLEWCTRL_SLOW, that sets the bit, and modify SLEWCTRL_FAST to 0 but keep it for completeness. Current users of the macro (i2c, mdio, and uart) are left unmodified as SLEWCTRL_FAST was the macro used and actual desired state. Tested on am437x-gp-evm with no difference in software performance seen. Signed-off-by: Dave Gerlach Signed-off-by: Tony Lindgren --- include/dt-bindings/pinctrl/am43xx.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/dt-bindings/pinctrl/am43xx.h b/include/dt-bindings/pinctrl/am43xx.h index 9c2e4f82381e..5f4d01898c9c 100644 --- a/include/dt-bindings/pinctrl/am43xx.h +++ b/include/dt-bindings/pinctrl/am43xx.h @@ -18,7 +18,8 @@ #define PULL_DISABLE (1 << 16) #define PULL_UP (1 << 17) #define INPUT_EN (1 << 18) -#define SLEWCTRL_FAST (1 << 19) +#define SLEWCTRL_SLOW (1 << 19) +#define SLEWCTRL_FAST 0 #define DS0_PULL_UP_DOWN_EN (1 << 27) #define PIN_OUTPUT (PULL_DISABLE) -- GitLab From 9b5580854fd75614f817773e96977d07fee8fc4b Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Thu, 5 Mar 2015 15:32:42 +0200 Subject: [PATCH 02962/11651] ARM: dts: dra7x-evm: Don't use dcan1_rx.gpio1_15 in DCAN pinctrl Rev.F onwards ball G19 (dcan1_rx) is used as a GPIO for some other function so don't include it in DCAN pinctrl node. Signed-off-by: Roger Quadros Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/dra7-evm.dts | 2 -- arch/arm/boot/dts/dra72-evm.dts | 2 -- 2 files changed, 4 deletions(-) diff --git a/arch/arm/boot/dts/dra7-evm.dts b/arch/arm/boot/dts/dra7-evm.dts index 3290a96ba586..ddef593c380b 100644 --- a/arch/arm/boot/dts/dra7-evm.dts +++ b/arch/arm/boot/dts/dra7-evm.dts @@ -264,7 +264,6 @@ dcan1_pins_default: dcan1_pins_default { pinctrl-single,pins = < 0x3d0 (PIN_OUTPUT | MUX_MODE0) /* dcan1_tx */ - 0x3d4 (MUX_MODE15) /* dcan1_rx.off */ 0x418 (PULL_DIS | MUX_MODE1) /* wakeup0.dcan1_rx */ >; }; @@ -272,7 +271,6 @@ dcan1_pins_sleep: dcan1_pins_sleep { pinctrl-single,pins = < 0x3d0 (MUX_MODE15) /* dcan1_tx.off */ - 0x3d4 (MUX_MODE15) /* dcan1_rx.off */ 0x418 (MUX_MODE15) /* wakeup0.off */ >; }; diff --git a/arch/arm/boot/dts/dra72-evm.dts b/arch/arm/boot/dts/dra72-evm.dts index e0264d0bf7b9..42ee09ae4d79 100644 --- a/arch/arm/boot/dts/dra72-evm.dts +++ b/arch/arm/boot/dts/dra72-evm.dts @@ -120,7 +120,6 @@ dcan1_pins_default: dcan1_pins_default { pinctrl-single,pins = < 0x3d0 (PIN_OUTPUT | MUX_MODE0) /* dcan1_tx */ - 0x3d4 (MUX_MODE15) /* dcan1_rx.off */ 0x418 (PULL_DIS | MUX_MODE1) /* wakeup0.dcan1_rx */ >; }; @@ -128,7 +127,6 @@ dcan1_pins_sleep: dcan1_pins_sleep { pinctrl-single,pins = < 0x3d0 (MUX_MODE15) /* dcan1_tx.off */ - 0x3d4 (MUX_MODE15) /* dcan1_rx.off */ 0x418 (MUX_MODE15) /* wakeup0.off */ >; }; -- GitLab From d80d581bf307397dfa11454c1e26d5798f9edd0c Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Thu, 5 Mar 2015 15:32:43 +0200 Subject: [PATCH 02963/11651] ARM: dts: dra7x-evm: avoid possible contention while muxing on CAN lines DCAN1 RX and TX lines are internally pulled high according to [1]. While muxing between DCAN mode and SAFE mode we make sure that the same pull direction is set to minimize opposite pull contention during the switching window. [1] in DRA7 data manual, Ball characteristics table 4-2, DSIS colum shows the state driven to the peripheral input while in the deselcted mode. DSIS - De-Selected Input State. Signed-off-by: Roger Quadros Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/dra7-evm.dts | 8 ++++---- arch/arm/boot/dts/dra72-evm.dts | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/arm/boot/dts/dra7-evm.dts b/arch/arm/boot/dts/dra7-evm.dts index ddef593c380b..7563d7ce01bb 100644 --- a/arch/arm/boot/dts/dra7-evm.dts +++ b/arch/arm/boot/dts/dra7-evm.dts @@ -263,15 +263,15 @@ dcan1_pins_default: dcan1_pins_default { pinctrl-single,pins = < - 0x3d0 (PIN_OUTPUT | MUX_MODE0) /* dcan1_tx */ - 0x418 (PULL_DIS | MUX_MODE1) /* wakeup0.dcan1_rx */ + 0x3d0 (PIN_OUTPUT_PULLUP | MUX_MODE0) /* dcan1_tx */ + 0x418 (PULL_UP | MUX_MODE1) /* wakeup0.dcan1_rx */ >; }; dcan1_pins_sleep: dcan1_pins_sleep { pinctrl-single,pins = < - 0x3d0 (MUX_MODE15) /* dcan1_tx.off */ - 0x418 (MUX_MODE15) /* wakeup0.off */ + 0x3d0 (MUX_MODE15 | PULL_UP) /* dcan1_tx.off */ + 0x418 (MUX_MODE15 | PULL_UP) /* wakeup0.off */ >; }; }; diff --git a/arch/arm/boot/dts/dra72-evm.dts b/arch/arm/boot/dts/dra72-evm.dts index 42ee09ae4d79..40ed539ce474 100644 --- a/arch/arm/boot/dts/dra72-evm.dts +++ b/arch/arm/boot/dts/dra72-evm.dts @@ -119,15 +119,15 @@ dcan1_pins_default: dcan1_pins_default { pinctrl-single,pins = < - 0x3d0 (PIN_OUTPUT | MUX_MODE0) /* dcan1_tx */ - 0x418 (PULL_DIS | MUX_MODE1) /* wakeup0.dcan1_rx */ + 0x3d0 (PIN_OUTPUT_PULLUP | MUX_MODE0) /* dcan1_tx */ + 0x418 (PULL_UP | MUX_MODE1) /* wakeup0.dcan1_rx */ >; }; dcan1_pins_sleep: dcan1_pins_sleep { pinctrl-single,pins = < - 0x3d0 (MUX_MODE15) /* dcan1_tx.off */ - 0x418 (MUX_MODE15) /* wakeup0.off */ + 0x3d0 (MUX_MODE15 | PULL_UP) /* dcan1_tx.off */ + 0x418 (MUX_MODE15 | PULL_UP) /* wakeup0.off */ >; }; -- GitLab From 2f7bf4af5c8177f6a27d9b67efdeb48f5bdbf821 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Heiko=20St=C3=BCbner?= Date: Tue, 24 Feb 2015 11:39:25 +0100 Subject: [PATCH 02964/11651] clk: divider: return real rate instead of divider value Commit bca9690b9426 ("clk: divider: Make generic for usage elsewhere") returned only the divider value for read-only dividers instead of the actual rate. Fixes: bca9690b9426 ("clk: divider: Make generic for usage elsewhere") Signed-off-by: Heiko Stuebner Reviewed-by: James Hogan Tested-by: James Hogan Acked-by: Stephen Boyd Signed-off-by: Michael Turquette --- drivers/clk/clk-divider.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c index db7f8bce7467..eff8a862eb08 100644 --- a/drivers/clk/clk-divider.c +++ b/drivers/clk/clk-divider.c @@ -353,7 +353,7 @@ static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate, bestdiv = readl(divider->reg) >> divider->shift; bestdiv &= div_mask(divider->width); bestdiv = _get_div(divider->table, bestdiv, divider->flags); - return bestdiv; + return DIV_ROUND_UP(*prate, bestdiv); } return divider_round_rate(hw, rate, prate, divider->table, -- GitLab From e1315db17dc81238e6eb048b2221ccae88d8ef67 Mon Sep 17 00:00:00 2001 From: Scott Feldman Date: Fri, 6 Mar 2015 01:14:36 -0800 Subject: [PATCH 02965/11651] switchdev: fix CONFIG_IP_MULTIPLE_TABLES compile issue Signed-off-by: Scott Feldman Acked-by: Jiri Pirko Signed-off-by: David S. Miller --- net/switchdev/switchdev.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c index f4fd575aa2a3..19e4e72a1e39 100644 --- a/net/switchdev/switchdev.c +++ b/net/switchdev/switchdev.c @@ -309,8 +309,12 @@ int netdev_switch_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi, * IPv4 FIB offloading has been disabled completely. */ - if (fi->fib_net->ipv4.fib_has_custom_rules | - fi->fib_net->ipv4.fib_offload_disabled) +#ifdef CONFIG_IP_MULTIPLE_TABLES + if (fi->fib_net->ipv4.fib_has_custom_rules) + return 0; +#endif + + if (fi->fib_net->ipv4.fib_offload_disabled) return 0; dev = netdev_switch_get_dev_by_nhs(fi); -- GitLab From 8ea696384a1641048a17d1ed3cee4fabb0bf4e03 Mon Sep 17 00:00:00 2001 From: Scott Feldman Date: Fri, 6 Mar 2015 01:14:37 -0800 Subject: [PATCH 02966/11651] rocker: fix some sparse warnings Signed-off-by: Scott Feldman Acked-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/ethernet/rocker/rocker.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/rocker/rocker.c b/drivers/net/ethernet/rocker/rocker.c index d04d3b374e31..cc1bbfddebfe 100644 --- a/drivers/net/ethernet/rocker/rocker.c +++ b/drivers/net/ethernet/rocker/rocker.c @@ -2737,7 +2737,7 @@ static struct rocker_neigh_tbl_entry * { struct rocker_neigh_tbl_entry *found; - hash_for_each_possible(rocker->neigh_tbl, found, entry, ip_addr) + hash_for_each_possible(rocker->neigh_tbl, found, entry, (u32)ip_addr) if (found->ip_addr == ip_addr) return found; @@ -2749,7 +2749,7 @@ static void _rocker_neigh_add(struct rocker *rocker, { entry->index = rocker->neigh_tbl_next_index++; entry->ref_count++; - hash_add(rocker->neigh_tbl, &entry->entry, entry->ip_addr); + hash_add(rocker->neigh_tbl, &entry->entry, (u32)entry->ip_addr); } static void _rocker_neigh_del(struct rocker *rocker, @@ -2868,7 +2868,7 @@ static int rocker_port_ipv4_resolve(struct rocker_port *rocker_port, __be32 ip_addr) { struct net_device *dev = rocker_port->dev; - struct neighbour *n = __ipv4_neigh_lookup(dev, ip_addr); + struct neighbour *n = __ipv4_neigh_lookup(dev, (u32)ip_addr); int err = 0; if (!n) -- GitLab From a43f32d647273023edddb0dc8f91c4c6378b252b Mon Sep 17 00:00:00 2001 From: "Matwey V. Kornilov" Date: Thu, 19 Feb 2015 20:41:48 +0300 Subject: [PATCH 02967/11651] PCI: spear: Drop __initdata from spear13xx_pcie_driver Struct spear13xx_pcie_driver was in initdata, but we passed a pointer to it to platform_driver_register(), which can use the pointer at arbitrary times in the future, even after the initdata is freed. That leads to crashes. Move spear13xx_pcie_driver and things referenced by it (spear13xx_pcie_probe() and dw_pcie_host_init()) out of initdata. [bhelgaas: changelog] Fixes: 6675ef212dac ("PCI: spear: Fix Section mismatch compilation warning for probe()") Signed-off-by: Matwey V. Kornilov Signed-off-by: Bjorn Helgaas Acked-by: Viresh Kumar CC: stable@vger.kernel.org # v3.17+ --- drivers/pci/host/pcie-designware.c | 2 +- drivers/pci/host/pcie-spear13xx.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c index 1f4ea6f2d910..2e9f84fdd9ce 100644 --- a/drivers/pci/host/pcie-designware.c +++ b/drivers/pci/host/pcie-designware.c @@ -342,7 +342,7 @@ static const struct irq_domain_ops msi_domain_ops = { .map = dw_pcie_msi_map, }; -int __init dw_pcie_host_init(struct pcie_port *pp) +int dw_pcie_host_init(struct pcie_port *pp) { struct device_node *np = pp->dev->of_node; struct platform_device *pdev = to_platform_device(pp->dev); diff --git a/drivers/pci/host/pcie-spear13xx.c b/drivers/pci/host/pcie-spear13xx.c index 866465fd3dbf..020d78890719 100644 --- a/drivers/pci/host/pcie-spear13xx.c +++ b/drivers/pci/host/pcie-spear13xx.c @@ -269,7 +269,7 @@ static struct pcie_host_ops spear13xx_pcie_host_ops = { .host_init = spear13xx_pcie_host_init, }; -static int __init spear13xx_add_pcie_port(struct pcie_port *pp, +static int spear13xx_add_pcie_port(struct pcie_port *pp, struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -299,7 +299,7 @@ static int __init spear13xx_add_pcie_port(struct pcie_port *pp, return 0; } -static int __init spear13xx_pcie_probe(struct platform_device *pdev) +static int spear13xx_pcie_probe(struct platform_device *pdev) { struct spear13xx_pcie *spear13xx_pcie; struct pcie_port *pp; @@ -370,7 +370,7 @@ static const struct of_device_id spear13xx_pcie_of_match[] = { }; MODULE_DEVICE_TABLE(of, spear13xx_pcie_of_match); -static struct platform_driver spear13xx_pcie_driver __initdata = { +static struct platform_driver spear13xx_pcie_driver = { .probe = spear13xx_pcie_probe, .driver = { .name = "spear-pcie", -- GitLab From 45ba2154d12fc43b70312198ec47085f10be801a Mon Sep 17 00:00:00 2001 From: Aleksander Morgado Date: Fri, 6 Mar 2015 17:14:21 +0200 Subject: [PATCH 02968/11651] xhci: fix reporting of 0-sized URBs in control endpoint When a control transfer has a short data stage, the xHCI controller generates two transfer events: a COMP_SHORT_TX event that specifies the untransferred amount, and a COMP_SUCCESS event. But when the data stage is not short, only the COMP_SUCCESS event occurs. Therefore, xhci-hcd must set urb->actual_length to urb->transfer_buffer_length while processing the COMP_SUCCESS event, unless urb->actual_length was set already by a previous COMP_SHORT_TX event. The driver checks this by seeing whether urb->actual_length == 0, but this alone is the wrong test, as it is entirely possible for a short transfer to have an urb->actual_length = 0. This patch changes the xhci driver to rely on a new td->urb_length_set flag, which is set to true when a COMP_SHORT_TX event is received and the URB length updated at that stage. This fixes a bug which affected the HSO plugin, which relies on URBs with urb->actual_length == 0 to halt re-submitting the RX URB in the control endpoint. Cc: Signed-off-by: Aleksander Morgado Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-ring.c | 10 ++++++++-- drivers/usb/host/xhci.h | 3 +++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index b46b5b98a943..5fb66db89e05 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1946,7 +1946,7 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td, if (event_trb != ep_ring->dequeue) { /* The event was for the status stage */ if (event_trb == td->last_trb) { - if (td->urb->actual_length != 0) { + if (td->urb_length_set) { /* Don't overwrite a previously set error code */ if ((*status == -EINPROGRESS || *status == 0) && @@ -1960,7 +1960,13 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td, td->urb->transfer_buffer_length; } } else { - /* Maybe the event was for the data stage? */ + /* + * Maybe the event was for the data stage? If so, update + * already the actual_length of the URB and flag it as + * set, so that it is not overwritten in the event for + * the last TRB. + */ + td->urb_length_set = true; td->urb->actual_length = td->urb->transfer_buffer_length - EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)); diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 3b97f0582155..d0663931e5ba 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1,3 +1,4 @@ + /* * xHCI host controller driver * @@ -1291,6 +1292,8 @@ struct xhci_td { struct xhci_segment *start_seg; union xhci_trb *first_trb; union xhci_trb *last_trb; + /* actual_length of the URB has already been set */ + bool urb_length_set; }; /* xHCI command default timeout value */ -- GitLab From b8cb91e058cd0c0f02059c1207293c5b31d350fa Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Fri, 6 Mar 2015 17:23:19 +0200 Subject: [PATCH 02969/11651] xhci: Workaround for PME stuck issues in Intel xhci The xhci in Intel Sunrisepoint and Cherryview platforms need a driver workaround for a Stuck PME that might either block PME events in suspend, or create spurious PME events preventing runtime suspend. Workaround is to clear a internal PME flag, BIT(28) in a vendor specific PMCTRL register at offset 0x80a4, in both suspend resume callbacks Without this, xhci connected usb devices might never be able to wake up the system from suspend, or prevent device from going to suspend (xhci d3) Cc: Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-pci.c | 30 ++++++++++++++++++++++++++++++ drivers/usb/host/xhci.h | 1 + 2 files changed, 31 insertions(+) diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 7f76c8a12f89..fd53c9ebd662 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -37,6 +37,9 @@ #define PCI_DEVICE_ID_INTEL_LYNXPOINT_XHCI 0x8c31 #define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI 0x9c31 +#define PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI 0x22b5 +#define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_XHCI 0xa12f +#define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI 0x9d2f static const char hcd_name[] = "xhci_hcd"; @@ -133,6 +136,12 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) pdev->device == PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI) { xhci->quirks |= XHCI_SPURIOUS_REBOOT; } + if (pdev->vendor == PCI_VENDOR_ID_INTEL && + (pdev->device == PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI || + pdev->device == PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_XHCI || + pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI)) { + xhci->quirks |= XHCI_PME_STUCK_QUIRK; + } if (pdev->vendor == PCI_VENDOR_ID_ETRON && pdev->device == PCI_DEVICE_ID_EJ168) { xhci->quirks |= XHCI_RESET_ON_RESUME; @@ -159,6 +168,21 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) "QUIRK: Resetting on resume"); } +/* + * Make sure PME works on some Intel xHCI controllers by writing 1 to clear + * the Internal PME flag bit in vendor specific PMCTRL register at offset 0x80a4 + */ +static void xhci_pme_quirk(struct xhci_hcd *xhci) +{ + u32 val; + void __iomem *reg; + + reg = (void __iomem *) xhci->cap_regs + 0x80a4; + val = readl(reg); + writel(val | BIT(28), reg); + readl(reg); +} + /* called during probe() after chip reset completes */ static int xhci_pci_setup(struct usb_hcd *hcd) { @@ -283,6 +307,9 @@ static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup) if (xhci->quirks & XHCI_COMP_MODE_QUIRK) pdev->no_d3cold = true; + if (xhci->quirks & XHCI_PME_STUCK_QUIRK) + xhci_pme_quirk(xhci); + return xhci_suspend(xhci, do_wakeup); } @@ -313,6 +340,9 @@ static int xhci_pci_resume(struct usb_hcd *hcd, bool hibernated) if (pdev->vendor == PCI_VENDOR_ID_INTEL) usb_enable_intel_xhci_ports(pdev); + if (xhci->quirks & XHCI_PME_STUCK_QUIRK) + xhci_pme_quirk(xhci); + retval = xhci_resume(xhci, hibernated); return retval; } diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index d0663931e5ba..265ab1771d24 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1566,6 +1566,7 @@ struct xhci_hcd { #define XHCI_SPURIOUS_WAKEUP (1 << 18) /* For controllers with a broken beyond repair streams implementation */ #define XHCI_BROKEN_STREAMS (1 << 19) +#define XHCI_PME_STUCK_QUIRK (1 << 20) unsigned int num_active_eps; unsigned int limit_active_eps; /* There are two roothubs to keep track of bus suspend info for */ -- GitLab From 2725917fd5e65b4371c090796c186e230d2a7c47 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Thu, 26 Feb 2015 23:07:29 +0200 Subject: [PATCH 02970/11651] ARM: OMAP: enable TWL4030_USB in omap2plus_defconfig Enable TWL4030_USB which is used at least on Nokia N900/N950/N9 (OMAP3) and BeagleBoard. Signed-off-by: Aaro Koskinen [tony@atomide.com: updated comments] Signed-off-by: Tony Lindgren --- arch/arm/configs/omap2plus_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig index a097cffa1231..8e108599e1af 100644 --- a/arch/arm/configs/omap2plus_defconfig +++ b/arch/arm/configs/omap2plus_defconfig @@ -377,6 +377,7 @@ CONFIG_PWM_TWL=m CONFIG_PWM_TWL_LED=m CONFIG_OMAP_USB2=m CONFIG_TI_PIPE3=y +CONFIG_TWL4030_USB=m CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y # CONFIG_EXT3_FS_XATTR is not set -- GitLab From 25094468a195ad02b9d4ebed571c832d8dcce571 Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Mon, 9 Feb 2015 17:52:16 -0500 Subject: [PATCH 02971/11651] staging: rtl8723au: Use RF_AC instead of hardcoded value for RF register write Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/hal/usb_halinit.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/usb_halinit.c b/drivers/staging/rtl8723au/hal/usb_halinit.c index adbf1c2dd383..319170d51def 100644 --- a/drivers/staging/rtl8723au/hal/usb_halinit.c +++ b/drivers/staging/rtl8723au/hal/usb_halinit.c @@ -816,9 +816,10 @@ static void phy_SsPwrSwitch92CU(struct rtw_adapter *Adapter, mode. This is used to re-write the RX idle mode. */ /* We can only prvide a usual value instead and then HW will modify the value by itself. */ - PHY_SetRFReg(Adapter, RF_PATH_A, 0, bRFRegOffsetMask, 0x32D95); + PHY_SetRFReg(Adapter, RF_PATH_A, RF_AC, + bRFRegOffsetMask, 0x32D95); if (pHalData->rf_type == RF_2T2R) { - PHY_SetRFReg(Adapter, RF_PATH_B, 0, + PHY_SetRFReg(Adapter, RF_PATH_B, RF_AC, bRFRegOffsetMask, 0x32D95); } break; @@ -867,9 +868,9 @@ static void phy_SsPwrSwitch92CU(struct rtw_adapter *Adapter, 0x001B25A0); /* 3. issue 3-wire command that RF set to power down.*/ - PHY_SetRFReg(Adapter, RF_PATH_A, 0, bRFRegOffsetMask, 0); + PHY_SetRFReg(Adapter, RF_PATH_A, RF_AC, bRFRegOffsetMask, 0); if (pHalData->rf_type == RF_2T2R) - PHY_SetRFReg(Adapter, RF_PATH_B, 0, + PHY_SetRFReg(Adapter, RF_PATH_B, RF_AC, bRFRegOffsetMask, 0); /* 4. Force PFM , disable SPS18_LDO_Marco_Block */ -- GitLab From b1e4d2f623c41bf89a31f18960d11d4b36ce798e Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Mon, 9 Feb 2015 17:52:17 -0500 Subject: [PATCH 02972/11651] staging: rtl8723au: rates are always set via the firmware interface The only case where fw_ractrl = false was when the firmware failed to load, and in that case we are dead in the water anyway. Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/hal/odm.c | 3 +- .../rtl8723au/hal/rtl8723a_bt-coexist.c | 28 ++++++------------- drivers/staging/rtl8723au/hal/rtl8723a_cmd.c | 16 +---------- .../staging/rtl8723au/hal/rtl8723a_hal_init.c | 1 - drivers/staging/rtl8723au/hal/usb_halinit.c | 28 +++++-------------- .../staging/rtl8723au/include/rtl8723a_hal.h | 1 - 6 files changed, 18 insertions(+), 59 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/odm.c b/drivers/staging/rtl8723au/hal/odm.c index 375f85db2067..82861e716a93 100644 --- a/drivers/staging/rtl8723au/hal/odm.c +++ b/drivers/staging/rtl8723au/hal/odm.c @@ -1289,8 +1289,7 @@ void odm_RSSIMonitorCheck23aCE(struct dm_odm_t *pDM_Odm) for (i = 0; i < sta_cnt; i++) { if (PWDB_rssi[i] != (0)) { - if (pHalData->fw_ractrl) /* Report every sta's RSSI to FW */ - rtl8723a_set_rssi_cmd(Adapter, (u8 *)&PWDB_rssi[i]); + rtl8723a_set_rssi_cmd(Adapter, (u8 *)&PWDB_rssi[i]); } } diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_bt-coexist.c b/drivers/staging/rtl8723au/hal/rtl8723a_bt-coexist.c index 73cfddd6df9a..e46032e0077e 100644 --- a/drivers/staging/rtl8723au/hal/rtl8723a_bt-coexist.c +++ b/drivers/staging/rtl8723au/hal/rtl8723a_bt-coexist.c @@ -5796,7 +5796,7 @@ static void btdm_1AntUpdateHalRAMask(struct rtw_adapter *padapter, u32 mac_id, u32 filter) { u8 init_rate = 0; - u8 raid; + u8 raid, arg; u32 mask; u8 shortGIrate = false; int supportRateNum = 0; @@ -5860,26 +5860,16 @@ btdm_1AntUpdateHalRAMask(struct rtw_adapter *padapter, u32 mac_id, u32 filter) mask &= ~filter; init_rate = get_highest_rate_idx23a(mask)&0x3f; - if (pHalData->fw_ractrl) { - u8 arg = 0; + arg = mac_id&0x1f;/* MACID */ + arg |= BIT(7); + if (true == shortGIrate) + arg |= BIT(5); - arg = mac_id&0x1f;/* MACID */ - arg |= BIT(7); - if (true == shortGIrate) - arg |= BIT(5); - - RTPRINT(FBT, BT_TRACE, - ("[BTCoex], Update FW RAID entry, MASK = 0x%08x, " - "arg = 0x%02x\n", mask, arg)); - - rtl8723a_set_raid_cmd(padapter, mask, arg); - } else { - if (shortGIrate) - init_rate |= BIT(6); + RTPRINT(FBT, BT_TRACE, + ("[BTCoex], Update FW RAID entry, MASK = 0x%08x, " + "arg = 0x%02x\n", mask, arg)); - rtl8723au_write8(padapter, REG_INIDATA_RATE_SEL + mac_id, - init_rate); - } + rtl8723a_set_raid_cmd(padapter, mask, arg); psta->init_rate = init_rate; pdmpriv->INIDATA_RATE[mac_id] = init_rate; diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_cmd.c b/drivers/staging/rtl8723au/hal/rtl8723a_cmd.c index 7b56411cc3c8..0b77ee1eaddf 100644 --- a/drivers/staging/rtl8723au/hal/rtl8723a_cmd.c +++ b/drivers/staging/rtl8723au/hal/rtl8723a_cmd.c @@ -153,21 +153,7 @@ void rtl8723a_add_rateatid(struct rtw_adapter *pAdapter, u32 bitmap, u8 arg, u8 bitmap |= ((raid<<28)&0xf0000000); - if (pHalData->fw_ractrl == true) { - rtl8723a_set_raid_cmd(pAdapter, bitmap, arg); - } else { - u8 init_rate, shortGIrate = false; - - init_rate = get_highest_rate_idx23a(bitmap&0x0fffffff)&0x3f; - - shortGIrate = (arg&BIT(5)) ? true:false; - - if (shortGIrate == true) - init_rate |= BIT(6); - - rtl8723au_write8(pAdapter, REG_INIDATA_RATE_SEL + macid, - init_rate); - } + rtl8723a_set_raid_cmd(pAdapter, bitmap, arg); } void rtl8723a_set_FwPwrMode_cmd(struct rtw_adapter *padapter, u8 Mode) diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c b/drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c index a5eadd4e2580..eb82c0b880d5 100644 --- a/drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c +++ b/drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c @@ -1095,7 +1095,6 @@ void rtl8723a_init_default_value(struct rtw_adapter *padapter) pdmpriv = &pHalData->dmpriv; /* init default value */ - pHalData->fw_ractrl = false; pHalData->bIQKInitialized = false; if (!padapter->pwrctrlpriv.bkeepfwalive) pHalData->LastHMEBoxNum = 0; diff --git a/drivers/staging/rtl8723au/hal/usb_halinit.c b/drivers/staging/rtl8723au/hal/usb_halinit.c index 319170d51def..173893474fd7 100644 --- a/drivers/staging/rtl8723au/hal/usb_halinit.c +++ b/drivers/staging/rtl8723au/hal/usb_halinit.c @@ -572,12 +572,10 @@ int rtl8723au_hal_init(struct rtw_adapter *Adapter) status = rtl8723a_FirmwareDownload(Adapter); if (status != _SUCCESS) { Adapter->bFWReady = false; - pHalData->fw_ractrl = false; DBG_8723A("fw download fail!\n"); goto exit; } else { Adapter->bFWReady = true; - pHalData->fw_ractrl = true; DBG_8723A("fw download ok!\n"); } @@ -1212,7 +1210,7 @@ void rtl8723a_update_ramask(struct rtw_adapter *padapter, struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; struct wlan_bssid_ex *cur_network = &pmlmeinfo->network; - u8 init_rate, networkType, raid; + u8 init_rate, networkType, raid, arg; u32 mask, rate_bitmap; u8 shortGIrate = false; int supportRateNum; @@ -1284,27 +1282,15 @@ void rtl8723a_update_ramask(struct rtw_adapter *padapter, init_rate = get_highest_rate_idx23a(mask) & 0x3f; - if (pHalData->fw_ractrl == true) { - u8 arg = 0; + arg = mac_id & 0x1f;/* MACID */ + arg |= BIT(7); - arg = mac_id & 0x1f;/* MACID */ + if (shortGIrate == true) + arg |= BIT(5); - arg |= BIT(7); + DBG_8723A("update raid entry, mask = 0x%x, arg = 0x%x\n", mask, arg); - if (shortGIrate == true) - arg |= BIT(5); - - DBG_8723A("update raid entry, mask = 0x%x, arg = 0x%x\n", - mask, arg); - - rtl8723a_set_raid_cmd(padapter, mask, arg); - } else { - if (shortGIrate == true) - init_rate |= BIT(6); - - rtl8723au_write8(padapter, (REG_INIDATA_RATE_SEL + mac_id), - init_rate); - } + rtl8723a_set_raid_cmd(padapter, mask, arg); /* set ra_id */ psta->raid = raid; diff --git a/drivers/staging/rtl8723au/include/rtl8723a_hal.h b/drivers/staging/rtl8723au/include/rtl8723a_hal.h index e14633678b52..5841915d34e1 100644 --- a/drivers/staging/rtl8723au/include/rtl8723a_hal.h +++ b/drivers/staging/rtl8723au/include/rtl8723a_hal.h @@ -348,7 +348,6 @@ struct hal_data_8723a { /* for host message to fw */ u8 LastHMEBoxNum; - u8 fw_ractrl; u8 RegTxPause; /* Beacon function related global variable. */ u8 RegFwHwTxQCtrl; -- GitLab From 164b46666d6abdcffbde6590f9f2179cb3c610a5 Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Mon, 9 Feb 2015 17:52:18 -0500 Subject: [PATCH 02973/11651] staging: rtl8723au: rtl8723a_add_rateatid() simplyfy code No point shifting raid right, just to shift it left again before re-adding it. Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/hal/rtl8723a_cmd.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_cmd.c b/drivers/staging/rtl8723au/hal/rtl8723a_cmd.c index 0b77ee1eaddf..3304e55108ee 100644 --- a/drivers/staging/rtl8723au/hal/rtl8723a_cmd.c +++ b/drivers/staging/rtl8723au/hal/rtl8723a_cmd.c @@ -142,16 +142,16 @@ int rtl8723a_set_raid_cmd(struct rtw_adapter *padapter, u32 mask, u8 arg) /* arg[5] = Short GI */ void rtl8723a_add_rateatid(struct rtw_adapter *pAdapter, u32 bitmap, u8 arg, u8 rssi_level) { - struct hal_data_8723a *pHalData = GET_HAL_DATA(pAdapter); - u8 macid = arg&0x1f; - u8 raid = (bitmap>>28) & 0x0f; + struct hal_data_8723a *pHalData = GET_HAL_DATA(pAdapter); + u8 macid = arg & 0x1f; + u32 raid = bitmap & 0xf0000000; bitmap &= 0x0fffffff; if (rssi_level != DM_RATR_STA_INIT) bitmap = ODM_Get_Rate_Bitmap23a(pHalData, macid, bitmap, rssi_level); - bitmap |= ((raid<<28)&0xf0000000); + bitmap |= raid; rtl8723a_set_raid_cmd(pAdapter, bitmap, arg); } -- GitLab From 49361cafe324f58cb6a40a89f3bd45d3900275dc Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Mon, 9 Feb 2015 17:52:19 -0500 Subject: [PATCH 02974/11651] staging: rtl8723au: Remove more unused #defines Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/include/ieee80211.h | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/drivers/staging/rtl8723au/include/ieee80211.h b/drivers/staging/rtl8723au/include/ieee80211.h index cb23cd0349b4..3caf4f502ad8 100644 --- a/drivers/staging/rtl8723au/include/ieee80211.h +++ b/drivers/staging/rtl8723au/include/ieee80211.h @@ -171,20 +171,6 @@ struct ieee80211_snap_hdr { #define WLAN_REASON_JOIN_WRONG_CHANNEL 65534 #define WLAN_REASON_EXPIRATION_CHK 65535 - -#define IEEE80211_STATMASK_SIGNAL (1<<0) -#define IEEE80211_STATMASK_RSSI (1<<1) -#define IEEE80211_STATMASK_NOISE (1<<2) -#define IEEE80211_STATMASK_RATE (1<<3) -#define IEEE80211_STATMASK_WEMASK 0x7 - - -#define IEEE80211_CCK_MODULATION (1<<0) -#define IEEE80211_OFDM_MODULATION (1<<1) - -#define IEEE80211_24GHZ_BAND (1<<0) -#define IEEE80211_52GHZ_BAND (1<<1) - #define IEEE80211_CCK_RATE_LEN 4 #define IEEE80211_NUM_OFDM_RATESLEN 8 -- GitLab From 7ea9039d91f2f4e4a9ae84c178f2ed0d4613c6b8 Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Mon, 9 Feb 2015 17:52:20 -0500 Subject: [PATCH 02975/11651] staging: rtl8723au: hal_com.h: Remove some unused #defines Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/include/hal_com.h | 30 --------------------- 1 file changed, 30 deletions(-) diff --git a/drivers/staging/rtl8723au/include/hal_com.h b/drivers/staging/rtl8723au/include/hal_com.h index 7c31865e9865..e946c4ba9d16 100644 --- a/drivers/staging/rtl8723au/include/hal_com.h +++ b/drivers/staging/rtl8723au/include/hal_com.h @@ -65,36 +65,6 @@ #define RATE_36M BIT(9) #define RATE_48M BIT(10) #define RATE_54M BIT(11) -/* MCS 1 Spatial Stream */ -#define RATE_MCS0 BIT(12) -#define RATE_MCS1 BIT(13) -#define RATE_MCS2 BIT(14) -#define RATE_MCS3 BIT(15) -#define RATE_MCS4 BIT(16) -#define RATE_MCS5 BIT(17) -#define RATE_MCS6 BIT(18) -#define RATE_MCS7 BIT(19) -/* MCS 2 Spatial Stream */ -#define RATE_MCS8 BIT(20) -#define RATE_MCS9 BIT(21) -#define RATE_MCS10 BIT(22) -#define RATE_MCS11 BIT(23) -#define RATE_MCS12 BIT(24) -#define RATE_MCS13 BIT(25) -#define RATE_MCS14 BIT(26) -#define RATE_MCS15 BIT(27) - -/* ALL CCK Rate */ -#define RATE_ALL_CCK (RATR_1M | RATR_2M | RATR_55M | RATR_11M) -#define RATE_ALL_OFDM_AG \ - (RATR_6M | RATR_9M | RATR_12M | RATR_18M | RATR_24M| \ - RATR_36M|RATR_48M|RATR_54M) -#define RATE_ALL_OFDM_1SS \ - (RATR_MCS0 | RATR_MCS1 | RATR_MCS2 | RATR_MCS3 | \ - RATR_MCS4 | RATR_MCS5 | RATR_MCS6 | RATR_MCS7) -#define RATE_ALL_OFDM_2SS \ - (RATR_MCS8 | RATR_MCS9 | RATR_MCS10 | RATR_MCS11| \ - RATR_MCS12 | RATR_MCS13 | RATR_MCS14 | RATR_MCS15) /*------------------------------ Tx Desc definition Macro ------------------------*/ /* pragma mark -- Tx Desc related definition. -- */ -- GitLab From 9939cf9427e7e1a4c71c0d9496351eca4e6c3a96 Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Mon, 9 Feb 2015 17:52:21 -0500 Subject: [PATCH 02976/11651] staging: rtl8723au: Firmware always handles adaptive rates Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/hal/odm.c | 12 ------------ drivers/staging/rtl8723au/include/odm.h | 3 --- 2 files changed, 15 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/odm.c b/drivers/staging/rtl8723au/hal/odm.c index 82861e716a93..2a77fb853166 100644 --- a/drivers/staging/rtl8723au/hal/odm.c +++ b/drivers/staging/rtl8723au/hal/odm.c @@ -1010,10 +1010,6 @@ void odm_RateAdaptiveMaskInit23a(struct dm_odm_t *pDM_Odm) struct odm_rate_adapt *pOdmRA = &pDM_Odm->RateAdaptive; pOdmRA->Type = DM_Type_ByDriver; - if (pOdmRA->Type == DM_Type_ByDriver) - pDM_Odm->bUseRAMask = true; - else - pDM_Odm->bUseRAMask = false; pOdmRA->RATRState = DM_RATR_STA_INIT; pOdmRA->HighRSSIThresh = 50; @@ -1139,14 +1135,6 @@ void odm_RefreshRateAdaptiveMask23aCE23a(struct dm_odm_t *pDM_Odm) return; } - if (!pDM_Odm->bUseRAMask) { - ODM_RT_TRACE(pDM_Odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, - ("<---- odm_RefreshRateAdaptiveMask23a(): driver does not control rate adaptive mask\n")); - return; - } - - /* printk("==> %s \n", __func__); */ - for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) { struct sta_info *pstat = pDM_Odm->pODM_StaInfo[i]; if (pstat) { diff --git a/drivers/staging/rtl8723au/include/odm.h b/drivers/staging/rtl8723au/include/odm.h index 5a0561e092ac..df0915dc9ef6 100644 --- a/drivers/staging/rtl8723au/include/odm.h +++ b/drivers/staging/rtl8723au/include/odm.h @@ -749,9 +749,6 @@ struct dm_odm_t { u8 RSSI_BT; /* come from BT */ bool bPSDinProcess; - /* for rate adaptive, in fact, 88c/92c fw will handle this */ - u8 bUseRAMask; - struct odm_rate_adapt RateAdaptive; -- GitLab From 162904699ab96b3117976a0e4804028199113dd4 Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Fri, 27 Feb 2015 15:45:30 -0500 Subject: [PATCH 02977/11651] staging: rtl8723au: No need for two copies of rf_type Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/hal/odm.c | 12 +++--------- drivers/staging/rtl8723au/hal/rtl8723a_dm.c | 7 ------- drivers/staging/rtl8723au/include/odm.h | 16 ---------------- 3 files changed, 3 insertions(+), 32 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/odm.c b/drivers/staging/rtl8723au/hal/odm.c index 2a77fb853166..1b2baae6f0db 100644 --- a/drivers/staging/rtl8723au/hal/odm.c +++ b/drivers/staging/rtl8723au/hal/odm.c @@ -319,9 +319,6 @@ void ODM_CmnInfoInit23a(struct dm_odm_t *pDM_Odm, case ODM_CMNINFO_FAB_VER: pDM_Odm->FabVersion = (u8)Value; break; - case ODM_CMNINFO_RF_TYPE: - pDM_Odm->RFType = (u8)Value; - break; case ODM_CMNINFO_BOARD_TYPE: pDM_Odm->BoardType = (u8)Value; break; @@ -383,9 +380,6 @@ void ODM_CmnInfoUpdate23a(struct dm_odm_t *pDM_Odm, u32 CmnInfo, u64 Value) { /* This init variable may be changed in run time. */ switch (CmnInfo) { - case ODM_CMNINFO_RF_TYPE: - pDM_Odm->RFType = (u8)Value; - break; case ODM_CMNINFO_WIFI_DIRECT: pDM_Odm->bWIFI_Direct = (bool)Value; break; @@ -460,7 +454,6 @@ void odm_CmnInfoInit_Debug23a(struct dm_odm_t *pDM_Odm) ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("SupportICType = 0x%x\n", pDM_Odm->SupportICType)); ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("CutVersion =%d\n", pDM_Odm->CutVersion)); ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("FabVersion =%d\n", pDM_Odm->FabVersion)); - ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("RFType =%d\n", pDM_Odm->RFType)); ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("BoardType =%d\n", pDM_Odm->BoardType)); ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("ExtLNA =%d\n", pDM_Odm->ExtLNA)); ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("ExtPA =%d\n", pDM_Odm->ExtPA)); @@ -1053,7 +1046,8 @@ u32 ODM_Get_Rate_Bitmap23a(struct hal_data_8723a *pHalData, u32 macid, break; case (ODM_WM_B|ODM_WM_G|ODM_WM_N24G): case (ODM_WM_A|ODM_WM_B|ODM_WM_G|ODM_WM_N24G): - if (pDM_Odm->RFType == ODM_1T2R || pDM_Odm->RFType == ODM_1T1R) { + if (pHalData->rf_type == RF_1T2R || + pHalData->rf_type == RF_1T1R) { if (rssi_level == DM_RATR_STA_HIGH) { rate_bitmap = 0x000f0000; } else if (rssi_level == DM_RATR_STA_MIDDLE) { @@ -1082,7 +1076,7 @@ u32 ODM_Get_Rate_Bitmap23a(struct hal_data_8723a *pHalData, u32 macid, default: /* case WIRELESS_11_24N: */ /* case WIRELESS_11_5N: */ - if (pDM_Odm->RFType == RF_1T2R) + if (pHalData->rf_type == RF_1T2R) rate_bitmap = 0x000fffff; else rate_bitmap = 0x0fffffff; diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_dm.c b/drivers/staging/rtl8723au/hal/rtl8723a_dm.c index fa826b068d11..48edd020c0de 100644 --- a/drivers/staging/rtl8723au/hal/rtl8723a_dm.c +++ b/drivers/staging/rtl8723au/hal/rtl8723a_dm.c @@ -121,13 +121,6 @@ void rtl8723a_init_dm_priv(struct rtw_adapter *Adapter) } ODM_CmnInfoInit23a(pDM_Odm, ODM_CMNINFO_PATCH_ID, pHalData->CustomerID); ODM_CmnInfoInit23a(pDM_Odm, ODM_CMNINFO_BWIFI_TEST, Adapter->registrypriv.wifi_spec); - - if (pHalData->rf_type == RF_1T1R) - ODM_CmnInfoUpdate23a(pDM_Odm, ODM_CMNINFO_RF_TYPE, ODM_1T1R); - else if (pHalData->rf_type == RF_2T2R) - ODM_CmnInfoUpdate23a(pDM_Odm, ODM_CMNINFO_RF_TYPE, ODM_2T2R); - else if (pHalData->rf_type == RF_1T2R) - ODM_CmnInfoUpdate23a(pDM_Odm, ODM_CMNINFO_RF_TYPE, ODM_1T2R); } static void Update_ODM_ComInfo_8723a(struct rtw_adapter *Adapter) diff --git a/drivers/staging/rtl8723au/include/odm.h b/drivers/staging/rtl8723au/include/odm.h index df0915dc9ef6..1b8189b635fb 100644 --- a/drivers/staging/rtl8723au/include/odm.h +++ b/drivers/staging/rtl8723au/include/odm.h @@ -304,7 +304,6 @@ enum odm_cmninfo { ODM_CMNINFO_IC_TYPE, /* enum odm_ic_type_def */ ODM_CMNINFO_CUT_VER, /* enum odm_cut_version */ ODM_CMNINFO_FAB_VER, /* enum odm_fab_version */ - ODM_CMNINFO_RF_TYPE, /* enum rf_path_def or enum odm_rf_type? */ ODM_CMNINFO_BOARD_TYPE, /* enum odm_board_type */ ODM_CMNINFO_EXT_LNA, /* true */ ODM_CMNINFO_EXT_PA, @@ -409,7 +408,6 @@ enum odm_fab_version { ODM_UMC = 1, }; -/* ODM_CMNINFO_RF_TYPE */ /* For example 1T2R (A+AB = BIT0|BIT4|BIT5) */ enum rf_path_def { ODM_RF_TX_A = BIT(0), @@ -422,18 +420,6 @@ enum rf_path_def { ODM_RF_RX_D = BIT(7), }; - -enum odm_rf_type { - ODM_1T1R = 0, - ODM_1T2R = 1, - ODM_2T2R = 2, - ODM_2T3R = 3, - ODM_2T4R = 4, - ODM_3T3R = 5, - ODM_3T4R = 6, - ODM_4T4R = 7, -}; - /* ODM Dynamic common info value definition */ enum odm_mac_phy_mode { @@ -653,8 +639,6 @@ struct dm_odm_t { u8 CutVersion; /* Fab Version TSMC/UMC = 0/1 */ u8 FabVersion; - /* RF Type 4T4R/3T3R/2T2R/1T2R/1T1R/... */ - u8 RFType; /* Board Type Normal/HighPower/MiniCard/SLIM/Combo/... = 0/1/2/3/4/... */ u8 BoardType; /* with external LNA NO/Yes = 0/1 */ -- GitLab From f1508fe3bb77613162524654db5f9fc138920617 Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Fri, 27 Feb 2015 15:45:31 -0500 Subject: [PATCH 02978/11651] staging: rtl8723au: Be more consistent in checking for 2 TX paths Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- .../rtl8723au/hal/HalDMOutSrc8723A_CE.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/HalDMOutSrc8723A_CE.c b/drivers/staging/rtl8723au/hal/HalDMOutSrc8723A_CE.c index 179a1ba03029..00faa6c7264c 100644 --- a/drivers/staging/rtl8723au/hal/HalDMOutSrc8723A_CE.c +++ b/drivers/staging/rtl8723au/hal/HalDMOutSrc8723A_CE.c @@ -23,9 +23,8 @@ #define DPK_DELTA_MAPPING_NUM 13 #define index_mapping_HP_NUM 15 /* 091212 chiyokolin */ -static void -odm_TXPowerTrackingCallback_ThermalMeter_92C( - struct rtw_adapter *Adapter) +static void +odm_TXPowerTrackingCallback_ThermalMeter_92C(struct rtw_adapter *Adapter) { struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); struct dm_priv *pdmpriv = &pHalData->dmpriv; @@ -35,7 +34,6 @@ odm_TXPowerTrackingCallback_ThermalMeter_92C( s8 OFDM_index[2], CCK_index = 0, OFDM_index_old[2] = {0}; s8 CCK_index_old = 0; int i = 0; - bool is2T = IS_92C_SERIAL(pHalData->VersionID); u8 OFDM_min_index = 6, rf; /* OFDM BB Swing should be less than +3.0dB*/ u8 ThermalValue_HP_count = 0; u32 ThermalValue_HP = 0; @@ -60,7 +58,7 @@ odm_TXPowerTrackingCallback_ThermalMeter_92C( rtl8723a_phy_ap_calibrate(Adapter, (ThermalValue - pHalData->EEPROMThermalMeter)); - if (is2T) + if (pHalData->rf_type == RF_2T2R) rf = 2; else rf = 1; @@ -78,7 +76,7 @@ odm_TXPowerTrackingCallback_ThermalMeter_92C( } /* Query OFDM path B default setting */ - if (is2T) { + if (pHalData->rf_type == RF_2T2R) { ele_D = PHY_QueryBBReg(Adapter, rOFDM0_XBTxIQImbalance, bMaskDWord)&bMaskOFDM_D; for (i = 0; i < OFDM_TABLE_SIZE_92C; i++) { /* find the index */ @@ -290,7 +288,7 @@ odm_TXPowerTrackingCallback_ThermalMeter_92C( rtl8723au_write8(Adapter, 0xa29, CCKSwingTable_Ch1423A[CCK_index][7]); } - if (is2T) { + if (pHalData->rf_type == RF_2T2R) { ele_D = (OFDMSwingTable23A[(u8)OFDM_index[1]] & 0xFFC00000)>>22; /* new element A = element D x X */ @@ -660,9 +658,9 @@ static bool _PHY_SimularityCompare(struct rtw_adapter *pAdapter, int result[][8] u32 i, j, diff, SimularityBitMap, bound = 0; struct hal_data_8723a *pHalData = GET_HAL_DATA(pAdapter); u8 final_candidate[2] = {0xFF, 0xFF}; /* for path A and path B */ - bool bResult = true, is2T = IS_92C_SERIAL(pHalData->VersionID); + bool bResult = true; - if (is2T) + if (pHalData->rf_type == RF_2T2R) bound = 8; else bound = 4; @@ -699,7 +697,7 @@ static bool _PHY_SimularityCompare(struct rtw_adapter *pAdapter, int result[][8] for (i = 0; i < 4; i++) result[3][i] = result[c1][i]; return false; - } else if (!(SimularityBitMap & 0xF0) && is2T) { + } else if (!(SimularityBitMap & 0xF0) && pHalData->rf_type == RF_2T2R) { /* path B OK */ for (i = 4; i < 8; i++) result[3][i] = result[c1][i]; -- GitLab From 277c722cd6fb71b0d2aafce4887f32d92c3baca3 Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Fri, 27 Feb 2015 15:45:32 -0500 Subject: [PATCH 02979/11651] staging: rtl8723au: Remove rf type from struct hal_version This gets rid of yet another duplicated copy of the RF type Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- .../rtl8723au/hal/HalDMOutSrc8723A_CE.c | 19 ++++----- drivers/staging/rtl8723au/hal/hal_com.c | 40 ------------------- drivers/staging/rtl8723au/hal/rtl8723a_cmd.c | 4 +- .../staging/rtl8723au/hal/rtl8723a_hal_init.c | 10 +---- .../staging/rtl8723au/hal/rtl8723a_phycfg.c | 4 +- drivers/staging/rtl8723au/hal/usb_halinit.c | 15 +------ drivers/staging/rtl8723au/include/HalVerDef.h | 22 ---------- drivers/staging/rtl8723au/include/hal_com.h | 1 - 8 files changed, 13 insertions(+), 102 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/HalDMOutSrc8723A_CE.c b/drivers/staging/rtl8723au/hal/HalDMOutSrc8723A_CE.c index 00faa6c7264c..2dac6f0cd9c2 100644 --- a/drivers/staging/rtl8723au/hal/HalDMOutSrc8723A_CE.c +++ b/drivers/staging/rtl8723au/hal/HalDMOutSrc8723A_CE.c @@ -978,12 +978,10 @@ void rtl8723a_phy_iq_calibrate(struct rtw_adapter *pAdapter, bool bReCovery) is13simular = false; for (i = 0; i < 3; i++) { - if (IS_92C_SERIAL(pHalData->VersionID)) { - _PHY_IQCalibrate(pAdapter, result, i, true); - } else { - /* For 88C 1T1R */ + if (pHalData->rf_type == RF_2T2R) + _PHY_IQCalibrate(pAdapter, result, i, true); + else /* For 88C 1T1R */ _PHY_IQCalibrate(pAdapter, result, i, false); - } if (i == 1) { is12simular = _PHY_SimularityCompare(pAdapter, result, 0, 1); @@ -1051,9 +1049,10 @@ void rtl8723a_phy_iq_calibrate(struct rtw_adapter *pAdapter, bool bReCovery) if ((RegE94 != 0)/*&&(RegEA4 != 0)*/) _PHY_PathAFillIQKMatrix(pAdapter, bPathAOK, result, final_candidate, (RegEA4 == 0)); - if (IS_92C_SERIAL(pHalData->VersionID)) { + if (pHalData->rf_type == RF_2T2R) { if ((RegEB4 != 0)/*&&(RegEC4 != 0)*/) - _PHY_PathBFillIQKMatrix(pAdapter, bPathBOK, result, final_candidate, (RegEC4 == 0)); + _PHY_PathBFillIQKMatrix(pAdapter, bPathBOK, result, + final_candidate, (RegEC4 == 0)); } _PHY_SaveADDARegisters(pAdapter, IQK_BB_REG_92C, pdmpriv->IQK_BB_backup_recover, 9); @@ -1072,12 +1071,10 @@ void rtl8723a_phy_lc_calibrate(struct rtw_adapter *pAdapter) if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) return; - if (IS_92C_SERIAL(pHalData->VersionID)) { + if (pHalData->rf_type == RF_2T2R) _PHY_LCCalibrate(pAdapter, true); - } else { - /* For 88C 1T1R */ + else /* For 88C 1T1R */ _PHY_LCCalibrate(pAdapter, false); - } } void diff --git a/drivers/staging/rtl8723au/hal/hal_com.c b/drivers/staging/rtl8723au/hal/hal_com.c index c9bb3e1ff0e8..db7d57e28165 100644 --- a/drivers/staging/rtl8723au/hal/hal_com.c +++ b/drivers/staging/rtl8723au/hal/hal_com.c @@ -22,46 +22,6 @@ #define _HAL_INIT_C_ -void dump_chip_info23a(struct hal_version ChipVersion) -{ - int cnt = 0; - u8 buf[128]; - - cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8723A_"); - - cnt += sprintf((buf + cnt), "%s_", IS_NORMAL_CHIP(ChipVersion) ? - "Normal_Chip" : "Test_Chip"); - cnt += sprintf((buf + cnt), "%s_", - IS_CHIP_VENDOR_TSMC(ChipVersion) ? "TSMC" : "UMC"); - if (IS_A_CUT(ChipVersion)) - cnt += sprintf((buf + cnt), "A_CUT_"); - else if (IS_B_CUT(ChipVersion)) - cnt += sprintf((buf + cnt), "B_CUT_"); - else if (IS_C_CUT(ChipVersion)) - cnt += sprintf((buf + cnt), "C_CUT_"); - else if (IS_D_CUT(ChipVersion)) - cnt += sprintf((buf + cnt), "D_CUT_"); - else if (IS_E_CUT(ChipVersion)) - cnt += sprintf((buf + cnt), "E_CUT_"); - else - cnt += sprintf((buf + cnt), "UNKNOWN_CUT(%d)_", - ChipVersion.CUTVersion); - - if (IS_1T1R(ChipVersion)) - cnt += sprintf((buf + cnt), "1T1R_"); - else if (IS_1T2R(ChipVersion)) - cnt += sprintf((buf + cnt), "1T2R_"); - else if (IS_2T2R(ChipVersion)) - cnt += sprintf((buf + cnt), "2T2R_"); - else - cnt += sprintf((buf + cnt), "UNKNOWN_RFTYPE(%d)_", - ChipVersion.RFType); - - cnt += sprintf((buf + cnt), "RomVer(%d)\n", ChipVersion.ROMVer); - - DBG_8723A("%s", buf); -} - #define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80 /* return the final channel plan decision */ diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_cmd.c b/drivers/staging/rtl8723au/hal/rtl8723a_cmd.c index 3304e55108ee..11e1108d0c56 100644 --- a/drivers/staging/rtl8723au/hal/rtl8723a_cmd.c +++ b/drivers/staging/rtl8723au/hal/rtl8723a_cmd.c @@ -169,10 +169,8 @@ void rtl8723a_set_FwPwrMode_cmd(struct rtw_adapter *padapter, u8 Mode) prevent conficting setting in Fw power */ /* saving sequence. 2010.06.07. Added by tynli. Suggested by SD3 yschang. */ - if ((Mode != PS_MODE_ACTIVE) && - (!IS_92C_SERIAL(pHalData->VersionID))) { + if (Mode != PS_MODE_ACTIVE && pHalData->rf_type != RF_2T2R) ODM_RF_Saving23a(&pHalData->odmpriv, true); - } H2CSetPwrMode.Mode = Mode; H2CSetPwrMode.SmartPS = pwrpriv->smart_ps; diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c b/drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c index eb82c0b880d5..a5729d304c85 100644 --- a/drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c +++ b/drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c @@ -744,7 +744,7 @@ void rtl8723a_read_chip_version(struct rtw_adapter *padapter) value32 = rtl8723au_read32(padapter, REG_SYS_CFG); ChipVersion.ICType = CHIP_8723A; ChipVersion.ChipType = ((value32 & RTL_ID) ? TEST_CHIP : NORMAL_CHIP); - ChipVersion.RFType = RF_TYPE_1T1R; + pHalData->rf_type = RF_1T1R; ChipVersion.VendorType = ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : CHIP_VENDOR_TSMC); ChipVersion.CUTVersion = (value32 & CHIP_VER_RTL_MASK) >> CHIP_VER_RTL_SHIFT; /* IC version (CUT) */ @@ -768,16 +768,8 @@ void rtl8723a_read_chip_version(struct rtw_adapter *padapter) pHalData->PolarityCtl = ((value32 & WL_HWPDN_SL) ? RT_POLARITY_HIGH_ACT : RT_POLARITY_LOW_ACT); - dump_chip_info23a(ChipVersion); pHalData->VersionID = ChipVersion; - if (IS_1T2R(ChipVersion)) - pHalData->rf_type = RF_1T2R; - else if (IS_2T2R(ChipVersion)) - pHalData->rf_type = RF_2T2R; - else - pHalData->rf_type = RF_1T1R; - MSG_8723A("RF_Type is %x!!\n", pHalData->rf_type); } diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_phycfg.c b/drivers/staging/rtl8723au/hal/rtl8723a_phycfg.c index 19dc5e3b2e2e..2cdadc27b3d8 100644 --- a/drivers/staging/rtl8723au/hal/rtl8723a_phycfg.c +++ b/drivers/staging/rtl8723au/hal/rtl8723a_phycfg.c @@ -419,7 +419,6 @@ PHY_SetRFReg(struct rtw_adapter *Adapter, enum RF_RADIO_PATH eRFPath, int PHY_MACConfig8723A(struct rtw_adapter *Adapter) { struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); - bool is92C = IS_92C_SERIAL(pHalData->VersionID); /* */ /* Config MAC */ @@ -429,7 +428,8 @@ int PHY_MACConfig8723A(struct rtw_adapter *Adapter) /* 2010.07.13 AMPDU aggregation number 9 */ /* rtw_write16(Adapter, REG_MAX_AGGR_NUM, MAX_AGGR_NUM); */ rtl8723au_write8(Adapter, REG_MAX_AGGR_NUM, 0x0A); - if (is92C && (BOARD_USB_DONGLE == pHalData->BoardType)) + if (pHalData->rf_type == RF_2T2R && + BOARD_USB_DONGLE == pHalData->BoardType) rtl8723au_write8(Adapter, 0x40, 0x04); return _SUCCESS; diff --git a/drivers/staging/rtl8723au/hal/usb_halinit.c b/drivers/staging/rtl8723au/hal/usb_halinit.c index 173893474fd7..a5e881b0da24 100644 --- a/drivers/staging/rtl8723au/hal/usb_halinit.c +++ b/drivers/staging/rtl8723au/hal/usb_halinit.c @@ -447,22 +447,9 @@ static void _InitRetryFunction(struct rtw_adapter *Adapter) static void _InitRFType(struct rtw_adapter *Adapter) { struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); - bool is92CU = IS_92C_SERIAL(pHalData->VersionID); pHalData->rf_chip = RF_6052; - - if (!is92CU) { - pHalData->rf_type = RF_1T1R; - DBG_8723A("Set RF Chip ID to RF_6052 and RF type to 1T1R.\n"); - return; - } - - /* TODO: Consider that EEPROM set 92CU to 1T1R later. */ - /* Force to overwrite setting according to chip version. Ignore - EEPROM setting. */ - /* pHalData->RF_Type = is92CU ? RF_2T2R : RF_1T1R; */ - MSG_8723A("Set RF Chip ID to RF_6052 and RF type to %d.\n", - pHalData->rf_type); + pHalData->rf_type = RF_1T1R; } /* Set CCK and OFDM Block "ON" */ diff --git a/drivers/staging/rtl8723au/include/HalVerDef.h b/drivers/staging/rtl8723au/include/HalVerDef.h index 607b71f6e1e4..2a0e4ea7afad 100644 --- a/drivers/staging/rtl8723au/include/HalVerDef.h +++ b/drivers/staging/rtl8723au/include/HalVerDef.h @@ -51,30 +51,17 @@ enum hal_vendor { CHIP_VENDOR_UMC = 1, }; -enum hal_rf_type { - RF_TYPE_1T1R = 0, - RF_TYPE_1T2R = 1, - RF_TYPE_2T2R = 2, - RF_TYPE_2T3R = 3, - RF_TYPE_2T4R = 4, - RF_TYPE_3T3R = 5, - RF_TYPE_3T4R = 6, - RF_TYPE_4T4R = 7, -}; - struct hal_version { enum hal_ic_type ICType; enum hal_chip_type ChipType; enum hal_cut_version CUTVersion; enum hal_vendor VendorType; - enum hal_rf_type RFType; u8 ROMVer; }; /* Get element */ #define GET_CVID_IC_TYPE(version) ((version).ICType) #define GET_CVID_CHIP_TYPE(version) ((version).ChipType) -#define GET_CVID_RF_TYPE(version) ((version).RFType) #define GET_CVID_MANUFACTUER(version) ((version).VendorType) #define GET_CVID_CUT_VERSION(version) ((version).CUTVersion) #define GET_CVID_ROM_VERSION(version) (((version).ROMVer) & ROM_VERSION_MASK) @@ -108,17 +95,8 @@ struct hal_version { #define IS_CHIP_VENDOR_UMC(version) \ ((GET_CVID_MANUFACTUER(version) == CHIP_VENDOR_UMC) ? true : false) -#define IS_1T1R(version) \ - ((GET_CVID_RF_TYPE(version) == RF_TYPE_1T1R) ? true : false) -#define IS_1T2R(version) \ - ((GET_CVID_RF_TYPE(version) == RF_TYPE_1T2R) ? true : false) -#define IS_2T2R(version) \ - ((GET_CVID_RF_TYPE(version) == RF_TYPE_2T2R) ? true : false) - /* Chip version Macro. -- */ -#define IS_92C_SERIAL(version) \ - ((IS_81XXC(version) && IS_2T2R(version)) ? true : false) #define IS_81xxC_VENDOR_UMC_A_CUT(version) \ (IS_81XXC(version)?(IS_CHIP_VENDOR_UMC(version) ? \ (IS_A_CUT(version) ? true : false) : false) : false) diff --git a/drivers/staging/rtl8723au/include/hal_com.h b/drivers/staging/rtl8723au/include/hal_com.h index e946c4ba9d16..9c50320b2100 100644 --- a/drivers/staging/rtl8723au/include/hal_com.h +++ b/drivers/staging/rtl8723au/include/hal_com.h @@ -116,7 +116,6 @@ #define REG_NOA_DESC_COUNT 0x05EC #include "HalVerDef.h" -void dump_chip_info23a(struct hal_version ChipVersion); u8 /* return the final channel plan decision */ -- GitLab From 929e570ae2bf571b7448dd41a3f37a11f077518e Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Fri, 27 Feb 2015 15:45:33 -0500 Subject: [PATCH 02980/11651] staging: rtl8723au: The RF on an 8723au is always a 6052 Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- .../staging/rtl8723au/hal/rtl8723a_phycfg.c | 34 +------------------ drivers/staging/rtl8723au/hal/usb_halinit.c | 12 ------- .../rtl8723au/include/Hal8723APhyCfg.h | 9 ----- .../staging/rtl8723au/include/rtl8723a_hal.h | 1 - 4 files changed, 1 insertion(+), 55 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_phycfg.c b/drivers/staging/rtl8723au/hal/rtl8723a_phycfg.c index 2cdadc27b3d8..9f0370da6357 100644 --- a/drivers/staging/rtl8723au/hal/rtl8723a_phycfg.c +++ b/drivers/staging/rtl8723au/hal/rtl8723a_phycfg.c @@ -920,10 +920,6 @@ _PHY_SetBWMode23a92C(struct rtw_adapter *Adapter) u8 regBwOpMode; u8 regRRSR_RSC; - /* There is no 40MHz mode in RF_8225. */ - if (pHalData->rf_chip == RF_8225) - return; - if (Adapter->bDriverStopped) return; @@ -997,35 +993,7 @@ _PHY_SetBWMode23a92C(struct rtw_adapter *Adapter) /* RT_TRACE(COMP_SCAN, DBG_LOUD, ("SetBWMode23aCallback8190Pci: time of SetBWMode23a = %I64d us!\n", (EndTime - BeginTime))); */ - /* 3<3>Set RF related register */ - switch (pHalData->rf_chip) { - case RF_8225: - /* PHY_SetRF8225Bandwidth(Adapter, - pHalData->CurrentChannelBW); */ - break; - - case RF_8256: - /* Please implement this function in Hal8190PciPhy8256.c */ - /* PHY_SetRF8256Bandwidth(Adapter, - pHalData->CurrentChannelBW); */ - break; - - case RF_8258: - /* Please implement this function in Hal8190PciPhy8258.c */ - /* PHY_SetRF8258Bandwidth(); */ - break; - - case RF_6052: - rtl8723a_phy_rf6052set_bw(Adapter, pHalData->CurrentChannelBW); - break; - - default: - /* RT_ASSERT(false, ("Unknown RFChipID: %d\n", - pHalData->RFChipID)); */ - break; - } - - /* pHalData->SetBWMode23aInProgress = false; */ + rtl8723a_phy_rf6052set_bw(Adapter, pHalData->CurrentChannelBW); /* RT_TRACE(COMP_SCAN, DBG_LOUD, ("<== PHY_SetBWMode23aCallback8192C() \n")); */ diff --git a/drivers/staging/rtl8723au/hal/usb_halinit.c b/drivers/staging/rtl8723au/hal/usb_halinit.c index a5e881b0da24..57518dc67509 100644 --- a/drivers/staging/rtl8723au/hal/usb_halinit.c +++ b/drivers/staging/rtl8723au/hal/usb_halinit.c @@ -448,7 +448,6 @@ static void _InitRFType(struct rtw_adapter *Adapter) { struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); - pHalData->rf_chip = RF_6052; pHalData->rf_type = RF_1T1R; } @@ -1088,13 +1087,6 @@ static void _ReadPROMContent(struct rtw_adapter *Adapter) readAdapterInfo(Adapter); } -static void _ReadRFType(struct rtw_adapter *Adapter) -{ - struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); - - pHalData->rf_chip = RF_6052; -} - /* */ /* Description: */ /* We should set Efuse cell selection to WiFi cell in default. */ @@ -1124,12 +1116,8 @@ void rtl8723a_read_adapter_info(struct rtw_adapter *Adapter) hal_EfuseCellSel(Adapter); - _ReadRFType(Adapter);/* rf_chip -> _InitRFType() */ _ReadPROMContent(Adapter); - /* MSG_8723A("%s()(done), rf_chip = 0x%x, rf_type = 0x%x\n", - __func__, pHalData->rf_chip, pHalData->rf_type); */ - MSG_8723A("<==== _ReadAdapterInfo8723AU in %d ms\n", jiffies_to_msecs(jiffies - start)); } diff --git a/drivers/staging/rtl8723au/include/Hal8723APhyCfg.h b/drivers/staging/rtl8723au/include/Hal8723APhyCfg.h index 2247d9874719..f1b8f2f8cc9b 100644 --- a/drivers/staging/rtl8723au/include/Hal8723APhyCfg.h +++ b/drivers/staging/rtl8723au/include/Hal8723APhyCfg.h @@ -39,15 +39,6 @@ enum WIRELESS_MODE { WIRELESS_MODE_AC = BIT(6) }; -/* BB/RF related */ -enum rf_type_8190p { - RF_TYPE_MIN, /* 0 */ - RF_8225 = 1, /* 1 11b/g RF for verification only */ - RF_8256 = 2, /* 2 11b/g/n */ - RF_8258 = 3, /* 3 11a/b/g/n RF */ - RF_6052 = 4, /* 4 11b/g/n RF */ -}; - struct bb_reg_define { u32 rfintfs; /* set software control: */ /* 0x870~0x877[8 bytes] */ diff --git a/drivers/staging/rtl8723au/include/rtl8723a_hal.h b/drivers/staging/rtl8723au/include/rtl8723a_hal.h index 5841915d34e1..ad3a442bc000 100644 --- a/drivers/staging/rtl8723au/include/rtl8723a_hal.h +++ b/drivers/staging/rtl8723au/include/rtl8723a_hal.h @@ -270,7 +270,6 @@ struct hal_data_8723a { u16 BasicRateSet; /* rf_ctrl */ - u8 rf_chip; u8 rf_type; u8 NumTotalRFPath; -- GitLab From 19c7b64455d7cfe88844f05025ab40861c12b6b8 Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Fri, 27 Feb 2015 15:45:34 -0500 Subject: [PATCH 02981/11651] staging: rtl8723au: MAX_AGGR_NUM is not used Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/hal/rtl8723a_phycfg.c | 1 - drivers/staging/rtl8723au/include/Hal8723APhyCfg.h | 3 --- 2 files changed, 4 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_phycfg.c b/drivers/staging/rtl8723au/hal/rtl8723a_phycfg.c index 9f0370da6357..6d597169c11c 100644 --- a/drivers/staging/rtl8723au/hal/rtl8723a_phycfg.c +++ b/drivers/staging/rtl8723au/hal/rtl8723a_phycfg.c @@ -426,7 +426,6 @@ int PHY_MACConfig8723A(struct rtw_adapter *Adapter) ODM_ReadAndConfig_MAC_REG_8723A(&pHalData->odmpriv); /* 2010.07.13 AMPDU aggregation number 9 */ - /* rtw_write16(Adapter, REG_MAX_AGGR_NUM, MAX_AGGR_NUM); */ rtl8723au_write8(Adapter, REG_MAX_AGGR_NUM, 0x0A); if (pHalData->rf_type == RF_2T2R && BOARD_USB_DONGLE == pHalData->BoardType) diff --git a/drivers/staging/rtl8723au/include/Hal8723APhyCfg.h b/drivers/staging/rtl8723au/include/Hal8723APhyCfg.h index f1b8f2f8cc9b..bcf36579f43a 100644 --- a/drivers/staging/rtl8723au/include/Hal8723APhyCfg.h +++ b/drivers/staging/rtl8723au/include/Hal8723APhyCfg.h @@ -16,9 +16,6 @@ #ifndef __INC_HAL8723PHYCFG_H__ #define __INC_HAL8723PHYCFG_H__ -/*--------------------------Define Parameters-------------------------------*/ -#define MAX_AGGR_NUM 0x0909 - /*------------------------------Define structure----------------------------*/ enum RF_RADIO_PATH { RF_PATH_A = 0, /* Radio Path A */ -- GitLab From dd03eed307939ffa768ab80488a4968566259d6d Mon Sep 17 00:00:00 2001 From: Daniele Alessandrelli Date: Sun, 22 Feb 2015 20:28:44 +0100 Subject: [PATCH 02982/11651] staging: rtl8723au: rtl8723a_hal_init.c: remove unnecessary braces Fix all checkpatch "braces {} are not necessary" warnings for rtl8723au/hal/rtl8723a_hal_init.c Signed-off-by: Daniele Alessandrelli Acked-by: Larry Finger Acked-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- .../staging/rtl8723au/hal/rtl8723a_hal_init.c | 40 +++++++------------ 1 file changed, 14 insertions(+), 26 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c b/drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c index a5729d304c85..7b3fdc841aac 100644 --- a/drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c +++ b/drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c @@ -424,9 +424,8 @@ hal_ReadEFuse_WiFi(struct rtw_adapter *padapter, offset = GET_HDR_OFFSET_2_0(efuseHeader); ReadEFuseByte23a(padapter, eFuse_Addr++, &efuseExtHdr); - if (ALL_WORDS_DISABLED(efuseExtHdr)) { + if (ALL_WORDS_DISABLED(efuseExtHdr)) continue; - } offset |= ((efuseExtHdr & 0xF0) >> 1); wden = (efuseExtHdr & 0x0F); @@ -524,9 +523,8 @@ hal_ReadEFuse_BT(struct rtw_adapter *padapter, ReadEFuseByte23a(padapter, eFuse_Addr++, &efuseExtHdr); - if (ALL_WORDS_DISABLED(efuseExtHdr)) { + if (ALL_WORDS_DISABLED(efuseExtHdr)) continue; - } offset |= ((efuseExtHdr & 0xF0) >> 1); wden = (efuseExtHdr & 0x0F); @@ -630,9 +628,8 @@ u16 rtl8723a_EfuseGetCurrentSize_WiFi(struct rtw_adapter *padapter) hoffset = GET_HDR_OFFSET_2_0(efuse_data); efuse_addr++; efuse_OneByteRead23a(padapter, efuse_addr, &efuse_data); - if (ALL_WORDS_DISABLED(efuse_data)) { + if (ALL_WORDS_DISABLED(efuse_data)) continue; - } hoffset |= ((efuse_data & 0xF0) >> 1); hworden = efuse_data & 0x0F; @@ -721,9 +718,8 @@ u16 rtl8723a_EfuseGetCurrentSize_BT(struct rtw_adapter *padapter) } /* Check if we need to check next bank efuse */ - if (efuse_addr < retU2) { + if (efuse_addr < retU2) break; /* don't need to check next bank. */ - } } retU2 = ((bank - 1) * EFUSE_BT_REAL_BANK_CONTENT_LEN) + efuse_addr; @@ -1140,9 +1136,8 @@ static int _LLTWrite(struct rtw_adapter *padapter, u32 address, u32 data) /* polling */ do { value = rtl8723au_read32(padapter, LLTReg); - if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value)) { + if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value)) break; - } if (count > POLLING_LLT_THRESHOLD) { RT_TRACE(_module_hal_init_c_, _drv_err_, @@ -1165,16 +1160,14 @@ int InitLLTTable23a(struct rtw_adapter *padapter, u32 boundary) for (i = 0; i < (txpktbuf_bndy - 1); i++) { status = _LLTWrite(padapter, i, i + 1); - if (status != _SUCCESS) { + if (status != _SUCCESS) return status; - } } /* end of list */ status = _LLTWrite(padapter, (txpktbuf_bndy - 1), 0xFF); - if (status != _SUCCESS) { + if (status != _SUCCESS) return status; - } /* Make the other pages as ring buffer */ /* This ring buffer is used as beacon buffer if we config this @@ -1182,16 +1175,14 @@ int InitLLTTable23a(struct rtw_adapter *padapter, u32 boundary) /* Otherwise used as local loopback buffer. */ for (i = txpktbuf_bndy; i < Last_Entry_Of_TxPktBuf; i++) { status = _LLTWrite(padapter, i, (i + 1)); - if (_SUCCESS != status) { + if (_SUCCESS != status) return status; - } } /* Let last entry point to the start entry of ring buffer */ status = _LLTWrite(padapter, Last_Entry_Of_TxPktBuf, txpktbuf_bndy); - if (status != _SUCCESS) { + if (status != _SUCCESS) return status; - } return status; } @@ -1426,9 +1417,9 @@ static void _DisableAnalog(struct rtw_adapter *padapter, bool bWithoutHWSM) /* HW Auto state machine */ int CardDisableHWSM(struct rtw_adapter *padapter, u8 resetMCU) { - if (padapter->bSurpriseRemoved) { + if (padapter->bSurpriseRemoved) return _SUCCESS; - } + /* RF Off Sequence ==== */ _DisableRFAFEAndResetBB8192C(padapter); @@ -1450,9 +1441,8 @@ int CardDisableHWSM(struct rtw_adapter *padapter, u8 resetMCU) /* without HW Auto state machine */ int CardDisableWithoutHWSM(struct rtw_adapter *padapter) { - if (padapter->bSurpriseRemoved) { + if (padapter->bSurpriseRemoved) return _SUCCESS; - } /* RF Off Sequence ==== */ _DisableRFAFEAndResetBB8192C(padapter); @@ -1866,9 +1856,8 @@ static void rtl8723a_cal_txdesc_chksum(struct tx_desc *ptxdesc) /* Clear first */ ptxdesc->txdw7 &= cpu_to_le32(0xffff0000); - for (index = 0; index < count; index++) { + for (index = 0; index < count; index++) checksum ^= le16_to_cpu(*(usPtr + index)); - } ptxdesc->txdw7 |= cpu_to_le32(checksum & 0x0000ffff); } @@ -1916,9 +1905,8 @@ void rtl8723a_fill_fake_txdesc(struct rtw_adapter *padapter, u8 *pDesc, ptxdesc->txdw3 |= cpu_to_le32((8 << 28)); } - if (true == IsBTQosNull) { + if (true == IsBTQosNull) ptxdesc->txdw2 |= cpu_to_le32(BIT(23)); /* BT NULL */ - } /* offset 16 */ ptxdesc->txdw4 |= cpu_to_le32(BIT(8)); /* driver uses rate */ -- GitLab From 6ba67a5a7bca9cb00562127d7410d412d3aa923b Mon Sep 17 00:00:00 2001 From: Yeliz Taneroglu Date: Mon, 2 Mar 2015 17:49:59 +0200 Subject: [PATCH 02983/11651] Staging: fbtft-core: remove unnecessary line continuations This fixes the checkpatch.pl warning: WARNING: Avoid unnecessary line continuations Signed-off-by: Yeliz Taneroglu Signed-off-by: Greg Kroah-Hartman --- drivers/staging/fbtft/fbtft-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/fbtft/fbtft-core.c b/drivers/staging/fbtft/fbtft-core.c index e8d8d07d5f23..9ce929d0e5c2 100644 --- a/drivers/staging/fbtft/fbtft-core.c +++ b/drivers/staging/fbtft/fbtft-core.c @@ -379,7 +379,7 @@ static void fbtft_update_display(struct fbtft_par *par, unsigned start_line, int ret = 0; if (unlikely(par->debug & (DEBUG_TIME_FIRST_UPDATE | DEBUG_TIME_EACH_UPDATE))) { - if ((par->debug & DEBUG_TIME_EACH_UPDATE) || \ + if ((par->debug & DEBUG_TIME_EACH_UPDATE) || ((par->debug & DEBUG_TIME_FIRST_UPDATE) && !par->first_update_done)) { getnstimeofday(&ts_start); timeit = true; @@ -1276,7 +1276,7 @@ static int fbtft_verify_gpios(struct fbtft_par *par) fbtft_par_dbg(DEBUG_VERIFY_GPIOS, par, "%s()\n", __func__); pdata = par->info->device->platform_data; - if (pdata->display.buswidth != 9 && par->startbyte == 0 && \ + if (pdata->display.buswidth != 9 && par->startbyte == 0 && par->gpio.dc < 0) { dev_err(par->info->device, "Missing info about 'dc' gpio. Aborting.\n"); -- GitLab From 6cb624ef71fb267026ace1e2aa91b9861e3c2457 Mon Sep 17 00:00:00 2001 From: Dilek Uzulmez Date: Mon, 2 Mar 2015 22:56:53 +0200 Subject: [PATCH 02984/11651] Staging: fbtft: Remove unnecessary 'out of memory' message. This patch fixes checkpatch.pl warning in file fbtft-core.c WARNING: Possible unnecessary 'out of memory' message Signed-off-by: Dilek Uzulmez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/fbtft/fbtft-core.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/staging/fbtft/fbtft-core.c b/drivers/staging/fbtft/fbtft-core.c index 9ce929d0e5c2..3c4769aab678 100644 --- a/drivers/staging/fbtft/fbtft-core.c +++ b/drivers/staging/fbtft/fbtft-core.c @@ -302,12 +302,8 @@ void fbtft_register_backlight(struct fbtft_par *par) bl_ops = devm_kzalloc(par->info->device, sizeof(struct backlight_ops), GFP_KERNEL); - if (!bl_ops) { - dev_err(par->info->device, - "%s: could not allocate memeory for backlight operations.\n", - __func__); + if (!bl_ops) return; - } bl_ops->get_brightness = fbtft_backlight_get_brightness; bl_ops->update_status = fbtft_backlight_update_status; -- GitLab From fad0d05f7c05d9990e0fe3759511069e9e5e5c9e Mon Sep 17 00:00:00 2001 From: Dilek Uzulmez Date: Mon, 2 Mar 2015 23:28:14 +0200 Subject: [PATCH 02985/11651] Staging: fbtft: Remove unnecessary 'out of memory' message. This patch fixes checkpatch.pl warning in file fb_ssd1351.c WARNING: Possible unnecessary 'out of memory' message Signed-off-by: Dilek Uzulmez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/fbtft/fb_ssd1351.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/staging/fbtft/fb_ssd1351.c b/drivers/staging/fbtft/fb_ssd1351.c index b59120c0eb70..fd492b4eaad6 100644 --- a/drivers/staging/fbtft/fb_ssd1351.c +++ b/drivers/staging/fbtft/fb_ssd1351.c @@ -218,12 +218,8 @@ static void register_onboard_backlight(struct fbtft_par *par) bl_ops = devm_kzalloc(par->info->device, sizeof(struct backlight_ops), GFP_KERNEL); - if (!bl_ops) { - dev_err(par->info->device, - "%s: could not allocate memory for backlight operations.\n", - __func__); + if (!bl_ops) return; - } bl_ops->update_status = update_onboard_backlight; bl_props.type = BACKLIGHT_RAW; -- GitLab From f6ef6c094ebd43e393657f4ae9cc3383dffda303 Mon Sep 17 00:00:00 2001 From: Haneen Mohammed Date: Mon, 2 Mar 2015 20:01:42 +0300 Subject: [PATCH 02986/11651] Staging: emxx_udc: Fix do not add new typedefs and remove volatile This patch fixes the following checkpatch.pl warnings:"do not add new typedefs" and "Use of volatile is usually wrong". Remove typedefs keyword and rename identifiers appropriately. Remove volatile from union usb_regs_access Update related files. Signed-off-by: Haneen Mohammed Signed-off-by: Greg Kroah-Hartman --- drivers/staging/emxx_udc/emxx_udc.c | 60 ++++++++++++++--------------- drivers/staging/emxx_udc/emxx_udc.h | 27 +++++++------ 2 files changed, 43 insertions(+), 44 deletions(-) diff --git a/drivers/staging/emxx_udc/emxx_udc.c b/drivers/staging/emxx_udc/emxx_udc.c index ee8f69f69eac..a9bbf8e3d6ea 100644 --- a/drivers/staging/emxx_udc/emxx_udc.c +++ b/drivers/staging/emxx_udc/emxx_udc.c @@ -201,7 +201,7 @@ static u32 _nbu2ss_get_begin_ram_address(struct nbu2ss_udc *udc) u32 num, buf_type; u32 data, last_ram_adr, use_ram_size; - PT_EP_REGS p_ep_regs; + struct ep_regs *p_ep_regs; last_ram_adr = (D_RAM_SIZE_CTRL / sizeof(u32)) * 2; use_ram_size = 0; @@ -394,7 +394,7 @@ static void _nbu2ss_ep_dma_exit(struct nbu2ss_udc *udc, struct nbu2ss_ep *ep) { u32 num; u32 data; - PT_FC_REGS preg = udc->p_regs; + struct fc_regs *preg = udc->p_regs; if (udc->vbus_active == 0) return; /* VBUS OFF */ @@ -425,7 +425,7 @@ static void _nbu2ss_ep_dma_exit(struct nbu2ss_udc *udc, struct nbu2ss_ep *ep) /* Abort DMA */ static void _nbu2ss_ep_dma_abort(struct nbu2ss_udc *udc, struct nbu2ss_ep *ep) { - PT_FC_REGS preg = udc->p_regs; + struct fc_regs *preg = udc->p_regs; _nbu2ss_bitclr(&preg->EP_DCR[ep->epnum-1].EP_DCR1, DCR1_EPn_REQEN); mdelay(DMA_DISABLE_TIME); /* DCR1_EPn_REQEN Clear */ @@ -443,7 +443,7 @@ static void _nbu2ss_ep_in_end( { u32 data; u32 num; - PT_FC_REGS preg = udc->p_regs; + struct fc_regs *preg = udc->p_regs; if (length >= sizeof(u32)) return; @@ -567,7 +567,7 @@ static int EP0_out_PIO(struct nbu2ss_udc *udc, u8 *pBuf, u32 length) u32 i; int nret = 0; u32 iWordLength = 0; - USB_REG_ACCESS *pBuf32 = (USB_REG_ACCESS *)pBuf; + union usb_reg_access *pBuf32 = (union usb_reg_access *)pBuf; /*------------------------------------------------------------*/ /* Read Length */ @@ -592,8 +592,8 @@ static int EP0_out_OverBytes(struct nbu2ss_udc *udc, u8 *pBuf, u32 length) { u32 i; u32 iReadSize = 0; - USB_REG_ACCESS Temp32; - USB_REG_ACCESS *pBuf32 = (USB_REG_ACCESS *)pBuf; + union usb_reg_access Temp32; + union usb_reg_access *pBuf32 = (union usb_reg_access *)pBuf; if ((0 < length) && (length < sizeof(u32))) { Temp32.dw = _nbu2ss_readl(&udc->p_regs->EP0_READ); @@ -613,7 +613,7 @@ static int EP0_in_PIO(struct nbu2ss_udc *udc, u8 *pBuf, u32 length) u32 iMaxLength = EP0_PACKETSIZE; u32 iWordLength = 0; u32 iWriteLength = 0; - USB_REG_ACCESS *pBuf32 = (USB_REG_ACCESS *)pBuf; + union usb_reg_access *pBuf32 = (union usb_reg_access *)pBuf; /*------------------------------------------------------------*/ /* Transfer Length */ @@ -638,8 +638,8 @@ static int EP0_in_PIO(struct nbu2ss_udc *udc, u8 *pBuf, u32 length) static int EP0_in_OverBytes(struct nbu2ss_udc *udc, u8 *pBuf, u32 iRemainSize) { u32 i; - USB_REG_ACCESS Temp32; - USB_REG_ACCESS *pBuf32 = (USB_REG_ACCESS *)pBuf; + union usb_reg_access Temp32; + union usb_reg_access *pBuf32 = (union usb_reg_access *)pBuf; if ((0 < iRemainSize) && (iRemainSize < sizeof(u32))) { for (i = 0 ; i < iRemainSize ; i++) @@ -840,7 +840,7 @@ static int _nbu2ss_out_dma( u32 burst = 1; u32 data; int result = -EINVAL; - PT_FC_REGS preg = udc->p_regs; + struct fc_regs *preg = udc->p_regs; if (req->dma_flag) return 1; /* DMA is forwarded */ @@ -900,10 +900,10 @@ static int _nbu2ss_epn_out_pio( u32 i; u32 data; u32 iWordLength; - USB_REG_ACCESS Temp32; - USB_REG_ACCESS *pBuf32; + union usb_reg_access Temp32; + union usb_reg_access *pBuf32; int result = 0; - PT_FC_REGS preg = udc->p_regs; + struct fc_regs *preg = udc->p_regs; if (req->dma_flag) return 1; /* DMA is forwarded */ @@ -912,7 +912,7 @@ static int _nbu2ss_epn_out_pio( return 0; pBuffer = (u8 *)req->req.buf; - pBuf32 = (USB_REG_ACCESS *)(pBuffer + req->req.actual); + pBuf32 = (union usb_reg_access *)(pBuffer + req->req.actual); iWordLength = length / sizeof(u32); if (iWordLength > 0) { @@ -988,7 +988,7 @@ static int _nbu2ss_epn_out_transfer( u32 num; u32 iRecvLength; int result = 1; - PT_FC_REGS preg = udc->p_regs; + struct fc_regs *preg = udc->p_regs; if (ep->epnum == 0) return -EINVAL; @@ -1051,7 +1051,7 @@ static int _nbu2ss_in_dma( u32 iWriteLength; u32 data; int result = -EINVAL; - PT_FC_REGS preg = udc->p_regs; + struct fc_regs *preg = udc->p_regs; if (req->dma_flag) return 1; /* DMA is forwarded */ @@ -1123,17 +1123,17 @@ static int _nbu2ss_epn_in_pio( u32 i; u32 data; u32 iWordLength; - USB_REG_ACCESS Temp32; - USB_REG_ACCESS *pBuf32 = NULL; + union usb_reg_access Temp32; + union usb_reg_access *pBuf32 = NULL; int result = 0; - PT_FC_REGS preg = udc->p_regs; + struct fc_regs *preg = udc->p_regs; if (req->dma_flag) return 1; /* DMA is forwarded */ if (length > 0) { pBuffer = (u8 *)req->req.buf; - pBuf32 = (USB_REG_ACCESS *)(pBuffer + req->req.actual); + pBuf32 = (union usb_reg_access *)(pBuffer + req->req.actual); iWordLength = length / sizeof(u32); if (iWordLength > 0) { @@ -1347,7 +1347,7 @@ static void _nbu2ss_set_endpoint_stall( u8 num, epnum; u32 data; struct nbu2ss_ep *ep; - PT_FC_REGS preg = udc->p_regs; + struct fc_regs *preg = udc->p_regs; if ((ep_adrs == 0) || (ep_adrs == 0x80)) { if (bstall) { @@ -1471,7 +1471,7 @@ static int _nbu2ss_get_ep_stall(struct nbu2ss_udc *udc, u8 ep_adrs) { u8 epnum; u32 data = 0, bit_data; - PT_FC_REGS preg = udc->p_regs; + struct fc_regs *preg = udc->p_regs; epnum = ep_adrs & ~USB_ENDPOINT_DIR_MASK; if (epnum == 0) { @@ -1566,7 +1566,7 @@ static void _nbu2ss_epn_set_stall( u32 regdata; int limit_cnt = 0; - PT_FC_REGS preg = udc->p_regs; + struct fc_regs *preg = udc->p_regs; if (ep->direct == USB_DIR_IN) { for (limit_cnt = 0 @@ -1994,7 +1994,7 @@ static inline void _nbu2ss_epn_in_int( int result = 0; u32 status; - PT_FC_REGS preg = udc->p_regs; + struct fc_regs *preg = udc->p_regs; if (req->dma_flag) return; /* DMA is forwarded */ @@ -2090,7 +2090,7 @@ static inline void _nbu2ss_epn_out_dma_int( u32 num; u32 dmacnt, ep_dmacnt; u32 mpkt; - PT_FC_REGS preg = udc->p_regs; + struct fc_regs *preg = udc->p_regs; num = ep->epnum - 1; @@ -2293,7 +2293,7 @@ static int _nbu2ss_pullup(struct nbu2ss_udc *udc, int is_on) /*-------------------------------------------------------------------------*/ static void _nbu2ss_fifo_flush(struct nbu2ss_udc *udc, struct nbu2ss_ep *ep) { - PT_FC_REGS p = udc->p_regs; + struct fc_regs *p = udc->p_regs; if (udc->vbus_active == 0) return; @@ -2536,7 +2536,7 @@ static irqreturn_t _nbu2ss_udc_irq(int irq, void *_udc) u32 epnum, int_bit; struct nbu2ss_udc *udc = (struct nbu2ss_udc *)_udc; - PT_FC_REGS preg = udc->p_regs; + struct fc_regs *preg = udc->p_regs; if (gpio_get_value(VBUS_VALUE) == 0) { _nbu2ss_writel(&preg->USB_INT_STA, ~USB_INT_STA_RW); @@ -2944,7 +2944,7 @@ static int nbu2ss_ep_fifo_status(struct usb_ep *_ep) struct nbu2ss_ep *ep; struct nbu2ss_udc *udc; unsigned long flags; - PT_FC_REGS preg; + struct fc_regs *preg; /* INFO("=== %s()\n", __func__); */ @@ -3341,7 +3341,7 @@ static int nbu2ss_drv_probe(struct platform_device *pdev) 0, driver_name, udc); /* IO Memory */ - udc->p_regs = (PT_FC_REGS)mmio_base; + udc->p_regs = (struct fc_regs *)mmio_base; /* USB Function Controller Interrupt */ if (status != 0) { diff --git a/drivers/staging/emxx_udc/emxx_udc.h b/drivers/staging/emxx_udc/emxx_udc.h index 6f90d5e3cd25..57727c6ed39d 100644 --- a/drivers/staging/emxx_udc/emxx_udc.h +++ b/drivers/staging/emxx_udc/emxx_udc.h @@ -474,8 +474,8 @@ /*===========================================================================*/ /* Struct */ -/*------- T_EP_REGS */ -typedef struct _T_EP_REGS { +/*------- ep_regs */ +struct ep_regs { u32 EP_CONTROL; /* EP Control */ u32 EP_STATUS; /* EP Status */ u32 EP_INT_ENA; /* EP Interrupt Enable */ @@ -484,18 +484,18 @@ typedef struct _T_EP_REGS { u32 EP_LEN_DCNT; /* EP Length & DMA count */ u32 EP_READ; /* EP Read */ u32 EP_WRITE; /* EP Write */ -} T_EP_REGS, *PT_EP_REGS; +}; -/*------- T_EP_DCR */ -typedef struct _T_EP_DCR { +/*------- ep_dcr */ +struct ep_dcr { u32 EP_DCR1; /* EP_DCR1 */ u32 EP_DCR2; /* EP_DCR2 */ u32 EP_TADR; /* EP_TADR */ u32 Reserved; /* Reserved */ -} T_EP_DCR, *PT_EP_DCR; +}; /*------- Function Registers */ -typedef struct _T_FC_REGS { +struct fc_regs { u32 USB_CONTROL; /* (0x0000) USB Control */ u32 USB_STATUS; /* (0x0004) USB Status */ u32 USB_ADDRESS; /* (0x0008) USB Address */ @@ -513,7 +513,7 @@ typedef struct _T_FC_REGS { u32 EP0_READ; /* (0x0038) EP0 Read */ u32 EP0_WRITE; /* (0x003C) EP0 Write */ - T_EP_REGS EP_REGS[REG_EP_NUM]; /* Endpoint Register */ + struct ep_regs EP_REGS[REG_EP_NUM]; /* Endpoint Register */ u8 Reserved220[0x1000-0x220]; /* (0x0220:0x0FFF) Reserved */ @@ -531,11 +531,10 @@ typedef struct _T_FC_REGS { u8 Reserved1028[0x110-0x28]; /* (0x1028:0x110F) Reserved */ - T_EP_DCR EP_DCR[REG_EP_NUM]; /* */ + struct ep_dcr EP_DCR[REG_EP_NUM]; /* */ u8 Reserved1200[0x1000-0x200]; /* Reserved */ - -} __aligned(32) T_FC_REGS, *PT_FC_REGS; +} __aligned(32); @@ -631,16 +630,16 @@ struct nbu2ss_udc { u32 curr_config; /* Current Configuration Number */ - PT_FC_REGS p_regs; + struct fc_regs *p_regs; }; /* USB register access structure */ -typedef volatile union { +union usb_reg_access { struct { unsigned char DATA[4]; } byte; unsigned int dw; -} USB_REG_ACCESS; +}; /*-------------------------------------------------------------------------*/ #define ERR(stuff...) printk(KERN_ERR "udc: " stuff) -- GitLab From d45c4c654d12fee5122e2eead93e5766dfd2259f Mon Sep 17 00:00:00 2001 From: Haneen Mohammed Date: Mon, 2 Mar 2015 21:33:18 +0300 Subject: [PATCH 02987/11651] Staging: emxx_udc: Remove argument test from function This patch removes the test statement for an argument to _nbu2ss_pullup function, for it can't be null due to previous derefrences. Signed-off-by: Haneen Mohammed Signed-off-by: Greg Kroah-Hartman --- drivers/staging/emxx_udc/emxx_udc.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/staging/emxx_udc/emxx_udc.c b/drivers/staging/emxx_udc/emxx_udc.c index a9bbf8e3d6ea..4cc6296ed007 100644 --- a/drivers/staging/emxx_udc/emxx_udc.c +++ b/drivers/staging/emxx_udc/emxx_udc.c @@ -2257,11 +2257,6 @@ static int _nbu2ss_pullup(struct nbu2ss_udc *udc, int is_on) { u32 reg_dt; - if (!udc) { - ERR("%s, bad param\n", __func__); - return -EINVAL; - } - if (udc->vbus_active == 0) return -ESHUTDOWN; -- GitLab From 886892798c9d29d3bb32e6a6d24e09565d71659e Mon Sep 17 00:00:00 2001 From: Haneen Mohammed Date: Mon, 2 Mar 2015 21:37:38 +0300 Subject: [PATCH 02988/11651] Staging: emxx_udc: Replace custom printk macro ERR with dev_err or pr_err This patch removes the use of custom printk macros ERR and replace it with dev_err, or pr_err in the following cases: - if no appropriate struct device *dev field where found for dev_err. - or dev could be null eg. "dev_err(udc->dev" not possible inside "if (udc == null)" Issue addressed by checkpatch.pl. Signed-off-by: Haneen Mohammed Signed-off-by: Greg Kroah-Hartman --- drivers/staging/emxx_udc/emxx_udc.c | 80 +++++++++++++++-------------- 1 file changed, 41 insertions(+), 39 deletions(-) diff --git a/drivers/staging/emxx_udc/emxx_udc.c b/drivers/staging/emxx_udc/emxx_udc.c index 4cc6296ed007..35dc1c444340 100644 --- a/drivers/staging/emxx_udc/emxx_udc.c +++ b/drivers/staging/emxx_udc/emxx_udc.c @@ -115,7 +115,7 @@ static void _nbu2ss_dump_register(struct nbu2ss_udc *udc) pr_info("=== %s()\n", __func__); if (udc == NULL) { - ERR("%s udc == NULL\n", __func__); + pr_err("%s udc == NULL\n", __func__); return; } @@ -808,7 +808,7 @@ static int _nbu2ss_ep0_out_transfer( return 0; /* Short Packet Transfer End */ if (req->req.actual > req->req.length) { - ERR(" *** Overrun Error\n"); + dev_err(udc->dev, " *** Overrun Error\n"); return -EOVERFLOW; } @@ -1026,8 +1026,8 @@ static int _nbu2ss_epn_out_transfer( } if (req->req.actual > req->req.length) { - ERR(" *** Overrun Error\n"); - ERR(" *** actual = %d, length = %d\n", + dev_err(udc->dev, " Overrun Error\n"); + dev_err(udc->dev, " actual = %d, length = %d\n", req->req.actual, req->req.length); result = -EOVERFLOW; } @@ -1638,7 +1638,7 @@ static int std_req_get_status(struct nbu2ss_udc *udc) _nbu2ss_ep0_in_transfer(udc, &udc->ep[0], &udc->ep0_req); } else { - ERR("*** Error GET_STATUS\n"); + dev_err(udc->dev, " Error GET_STATUS\n"); } return result; @@ -2345,7 +2345,7 @@ static int _nbu2ss_enable_controller(struct nbu2ss_udc *udc) waitcnt++; udelay(1); /* 1us wait */ if (waitcnt == EPC_PLL_LOCK_COUNT) { - ERR("*** Reset Cancel failed\n"); + dev_err(udc->dev, "*** Reset Cancel failed\n"); return -EINVAL; } }; @@ -2607,13 +2607,13 @@ static int nbu2ss_ep_enable( struct nbu2ss_udc *udc; if ((_ep == NULL) || (desc == NULL)) { - ERR(" *** %s, bad param\n", __func__); + pr_err(" *** %s, bad param\n", __func__); return -EINVAL; } ep = container_of(_ep, struct nbu2ss_ep, ep); if ((ep == NULL) || (ep->udc == NULL)) { - ERR(" *** %s, ep == NULL !!\n", __func__); + pr_err(" *** %s, ep == NULL !!\n", __func__); return -EINVAL; } @@ -2621,7 +2621,7 @@ static int nbu2ss_ep_enable( if ((ep_type == USB_ENDPOINT_XFER_CONTROL) || (ep_type == USB_ENDPOINT_XFER_ISOC)) { - ERR(" *** %s, bat bmAttributes\n", __func__); + pr_err(" *** %s, bat bmAttributes\n", __func__); return -EINVAL; } @@ -2632,7 +2632,7 @@ static int nbu2ss_ep_enable( if ((udc->driver == NULL) || (udc->gadget.speed == USB_SPEED_UNKNOWN)) { - ERR(" *** %s, udc !!\n", __func__); + dev_err(ep->udc->dev, " *** %s, udc !!\n", __func__); return -ESHUTDOWN; } @@ -2667,13 +2667,13 @@ static int nbu2ss_ep_disable(struct usb_ep *_ep) unsigned long flags; if (_ep == NULL) { - ERR(" *** %s, bad param\n", __func__); + pr_err(" *** %s, bad param\n", __func__); return -EINVAL; } ep = container_of(_ep, struct nbu2ss_ep, ep); if ((ep == NULL) || (ep->udc == NULL)) { - ERR(" *** %s, ep == NULL !!\n", __func__); + pr_err("udc: *** %s, ep == NULL !!\n", __func__); return -EINVAL; } @@ -2737,10 +2737,10 @@ static int nbu2ss_ep_queue( /* catch various bogus parameters */ if ((_ep == NULL) || (_req == NULL)) { if (_ep == NULL) - ERR("*** %s --- _ep == NULL\n", __func__); + pr_err("udc: %s --- _ep == NULL\n", __func__); if (_req == NULL) - ERR("*** %s --- _req == NULL\n", __func__); + pr_err("udc: %s --- _req == NULL\n", __func__); return -EINVAL; } @@ -2751,13 +2751,13 @@ static int nbu2ss_ep_queue( || !list_empty(&req->queue))) { if (!_req->complete) - ERR("*** %s --- !_req->complete\n", __func__); + pr_err("udc: %s --- !_req->complete\n", __func__); if (!_req->buf) - ERR("*** %s --- !_req->buf\n", __func__); + pr_err("udc:%s --- !_req->buf\n", __func__); if (!list_empty(&req->queue)) - ERR("*** %s --- !list_empty(&req->queue)\n", __func__); + pr_err("%s --- !list_empty(&req->queue)\n", __func__); return -EINVAL; } @@ -2773,7 +2773,8 @@ static int nbu2ss_ep_queue( } if (unlikely(!udc->driver)) { - ERR("%s, bogus device state %p\n", __func__, udc->driver); + dev_err(udc->dev, "%s, bogus device state %p\n", __func__, + udc->driver); return -ESHUTDOWN; } @@ -2812,7 +2813,8 @@ static int nbu2ss_ep_queue( result = _nbu2ss_start_transfer(udc, ep, req, FALSE); if (result < 0) { - ERR(" *** %s, result = %d\n", __func__, result); + dev_err(udc->dev, " *** %s, result = %d\n", __func__, + result); list_del(&req->queue); } else if ((ep->epnum > 0) && (ep->direct == USB_DIR_OUT)) { #ifdef USE_DMA @@ -2844,13 +2846,13 @@ static int nbu2ss_ep_dequeue( /* catch various bogus parameters */ if ((_ep == NULL) || (_req == NULL)) { - /* ERR("%s, bad param(1)\n", __func__); */ + /* pr_err("%s, bad param(1)\n", __func__); */ return -EINVAL; } ep = container_of(_ep, struct nbu2ss_ep, ep); if (!ep) { - ERR("%s, ep == NULL !!\n", __func__); + pr_err("%s, ep == NULL !!\n", __func__); return -EINVAL; } @@ -2890,19 +2892,19 @@ static int nbu2ss_ep_set_halt(struct usb_ep *_ep, int value) /* INFO("=== %s()\n", __func__); */ if (!_ep) { - ERR("%s, bad param\n", __func__); + pr_err("%s, bad param\n", __func__); return -EINVAL; } ep = container_of(_ep, struct nbu2ss_ep, ep); if (!ep) { - ERR("%s, bad ep\n", __func__); + pr_err("%s, bad ep\n", __func__); return -EINVAL; } udc = ep->udc; if (!udc) { - ERR(" *** %s, bad udc\n", __func__); + dev_err(ep->udc->dev, " *** %s, bad udc\n", __func__); return -EINVAL; } @@ -2944,19 +2946,19 @@ static int nbu2ss_ep_fifo_status(struct usb_ep *_ep) /* INFO("=== %s()\n", __func__); */ if (!_ep) { - ERR("%s, bad param\n", __func__); + pr_err("%s, bad param\n", __func__); return -EINVAL; } ep = container_of(_ep, struct nbu2ss_ep, ep); if (!ep) { - ERR("%s, bad ep\n", __func__); + pr_err("%s, bad ep\n", __func__); return -EINVAL; } udc = ep->udc; if (!udc) { - ERR("%s, bad udc\n", __func__); + dev_err(ep->udc->dev, "%s, bad udc\n", __func__); return -EINVAL; } @@ -2992,19 +2994,19 @@ static void nbu2ss_ep_fifo_flush(struct usb_ep *_ep) /* INFO("=== %s()\n", __func__); */ if (!_ep) { - ERR("%s, bad param\n", __func__); + pr_err("udc: %s, bad param\n", __func__); return; } ep = container_of(_ep, struct nbu2ss_ep, ep); if (!_ep) { - ERR("%s, bad ep\n", __func__); + pr_err("udc: %s, bad ep\n", __func__); return; } udc = ep->udc; if (!udc) { - ERR("%s, bad udc\n", __func__); + dev_err(ep->udc->dev, "%s, bad udc\n", __func__); return; } @@ -3048,13 +3050,13 @@ static int nbu2ss_gad_get_frame(struct usb_gadget *pgadget) /* INFO("=== %s()\n", __func__); */ if (pgadget == NULL) { - ERR("%s, bad param\n", __func__); + pr_err("udc: %s, bad param\n", __func__); return -EINVAL; } udc = container_of(pgadget, struct nbu2ss_udc, gadget); if (udc == NULL) { - ERR("%s, udc == NULL\n", __func__); + dev_err(&pgadget->dev, "%s, udc == NULL\n", __func__); return -EINVAL; } @@ -3078,13 +3080,13 @@ static int nbu2ss_gad_wakeup(struct usb_gadget *pgadget) /* INFO("=== %s()\n", __func__); */ if (pgadget == NULL) { - ERR("%s, bad param\n", __func__); + pr_err("%s, bad param\n", __func__); return -EINVAL; } udc = container_of(pgadget, struct nbu2ss_udc, gadget); if (udc == NULL) { - ERR("%s, udc == NULL\n", __func__); + dev_err(&pgadget->dev, "%s, udc == NULL\n", __func__); return -EINVAL; } @@ -3118,7 +3120,7 @@ static int nbu2ss_gad_set_selfpowered(struct usb_gadget *pgadget, /* INFO("=== %s()\n", __func__); */ if (pgadget == NULL) { - ERR("%s, bad param\n", __func__); + pr_err("%s, bad param\n", __func__); return -EINVAL; } @@ -3147,7 +3149,7 @@ static int nbu2ss_gad_vbus_draw(struct usb_gadget *pgadget, unsigned mA) /* INFO("=== %s()\n", __func__); */ if (pgadget == NULL) { - ERR("%s, bad param\n", __func__); + pr_err("%s, bad param\n", __func__); return -EINVAL; } @@ -3169,7 +3171,7 @@ static int nbu2ss_gad_pullup(struct usb_gadget *pgadget, int is_on) /* INFO("=== %s()\n", __func__); */ if (pgadget == NULL) { - ERR("%s, bad param\n", __func__); + pr_err("%s, bad param\n", __func__); return -EINVAL; } @@ -3340,7 +3342,7 @@ static int nbu2ss_drv_probe(struct platform_device *pdev) /* USB Function Controller Interrupt */ if (status != 0) { - ERR("request_irq(USB_UDC_IRQ_1) failed\n"); + dev_err(udc->dev, "request_irq(USB_UDC_IRQ_1) failed\n"); goto cleanup1; } @@ -3360,7 +3362,7 @@ static int nbu2ss_drv_probe(struct platform_device *pdev) udc); if (status != 0) { - ERR("request_irq(INT_VBUS) failed\n"); + dev_err(udc->dev, "request_irq(INT_VBUS) failed\n"); goto cleanup1; } -- GitLab From f737ea50bac2f6a06835a3180bdbeae59dc9d735 Mon Sep 17 00:00:00 2001 From: Haneen Mohammed Date: Mon, 2 Mar 2015 21:38:22 +0300 Subject: [PATCH 02989/11651] Staging: emxx_udc: Remove custom printk macro ERR This patch removes custom printk macro ERR. All the calls to this macro were replaced by de_err and pr_err. Signed-off-by: Haneen Mohammed Signed-off-by: Greg Kroah-Hartman --- drivers/staging/emxx_udc/emxx_udc.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/emxx_udc/emxx_udc.h b/drivers/staging/emxx_udc/emxx_udc.h index 57727c6ed39d..c19168f78354 100644 --- a/drivers/staging/emxx_udc/emxx_udc.h +++ b/drivers/staging/emxx_udc/emxx_udc.h @@ -642,6 +642,5 @@ union usb_reg_access { }; /*-------------------------------------------------------------------------*/ -#define ERR(stuff...) printk(KERN_ERR "udc: " stuff) #endif /* _LINUX_EMXX_H */ -- GitLab From daa656b2245d9755f28dfdaf78904088d7b6d3b9 Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Mon, 2 Mar 2015 15:24:36 -0500 Subject: [PATCH 02990/11651] staging: rtl8723au: Variable bbtchange is always false Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/hal/odm.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/odm.c b/drivers/staging/rtl8723au/hal/odm.c index 1b2baae6f0db..2c604da4488a 100644 --- a/drivers/staging/rtl8723au/hal/odm.c +++ b/drivers/staging/rtl8723au/hal/odm.c @@ -1360,7 +1360,6 @@ static void odm_EdcaTurboCheck23a(struct dm_odm_t *pDM_Odm) u32 edca_param; u64 cur_tx_bytes = 0; u64 cur_rx_bytes = 0; - u8 bbtchange = false; /* For AP/ADSL use struct rtl8723a_priv * */ /* For CE/NIC use struct rtw_adapter * */ @@ -1382,7 +1381,7 @@ static void odm_EdcaTurboCheck23a(struct dm_odm_t *pDM_Odm) goto dm_CheckEdcaTurbo_EXIT; /* Check if the status needs to be changed. */ - if ((bbtchange) || (!precvpriv->bIsAnyNonBEPkts)) { + if (!precvpriv->bIsAnyNonBEPkts) { cur_tx_bytes = pxmitpriv->tx_bytes - pxmitpriv->last_tx_bytes; cur_rx_bytes = precvpriv->rx_bytes - precvpriv->last_rx_bytes; -- GitLab From 4b4431ce04bc6f35f09237b3933fc6d5d7eefeef Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Mon, 2 Mar 2015 15:24:37 -0500 Subject: [PATCH 02991/11651] staging: rtl8723au: Avoid zero initializing variables unnecessarily Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/hal/odm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/odm.c b/drivers/staging/rtl8723au/hal/odm.c index 2c604da4488a..a77d151f1f08 100644 --- a/drivers/staging/rtl8723au/hal/odm.c +++ b/drivers/staging/rtl8723au/hal/odm.c @@ -1358,8 +1358,8 @@ static void odm_EdcaTurboCheck23a(struct dm_odm_t *pDM_Odm) struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; u32 trafficIndex; u32 edca_param; - u64 cur_tx_bytes = 0; - u64 cur_rx_bytes = 0; + u64 cur_tx_bytes; + u64 cur_rx_bytes; /* For AP/ADSL use struct rtl8723a_priv * */ /* For CE/NIC use struct rtw_adapter * */ -- GitLab From 6520715ed2ccaeff6b797f358e0e2aa64a472db8 Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Mon, 2 Mar 2015 15:24:38 -0500 Subject: [PATCH 02992/11651] staging: rtl8723au: ODM_MAC_EDCA_TURBO is always set Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/hal/odm.c | 3 --- drivers/staging/rtl8723au/hal/rtl8723a_dm.c | 1 - drivers/staging/rtl8723au/include/odm.h | 1 - 3 files changed, 5 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/odm.c b/drivers/staging/rtl8723au/hal/odm.c index a77d151f1f08..8dcb020e1f18 100644 --- a/drivers/staging/rtl8723au/hal/odm.c +++ b/drivers/staging/rtl8723au/hal/odm.c @@ -1368,9 +1368,6 @@ static void odm_EdcaTurboCheck23a(struct dm_odm_t *pDM_Odm) /* at the same time. In the stage2/3, we need to prive universal interface and merge all */ /* HW dynamic mechanism. */ - if (!(pDM_Odm->SupportAbility & ODM_MAC_EDCA_TURBO)) - return; - if ((pregpriv->wifi_spec == 1))/* (pmlmeinfo->HT_enable == 0)) */ goto dm_CheckEdcaTurbo_EXIT; diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_dm.c b/drivers/staging/rtl8723au/hal/rtl8723a_dm.c index 48edd020c0de..85be3e0d7feb 100644 --- a/drivers/staging/rtl8723au/hal/rtl8723a_dm.c +++ b/drivers/staging/rtl8723au/hal/rtl8723a_dm.c @@ -136,7 +136,6 @@ static void Update_ODM_ComInfo_8723a(struct rtw_adapter *Adapter) ODM_BB_RSSI_MONITOR | ODM_BB_CCK_PD | ODM_BB_PWR_SAVE | - ODM_MAC_EDCA_TURBO | ODM_RF_TX_PWR_TRACK | ODM_RF_CALIBRATION; /* Pointer reference */ diff --git a/drivers/staging/rtl8723au/include/odm.h b/drivers/staging/rtl8723au/include/odm.h index 1b8189b635fb..50459f09dbbb 100644 --- a/drivers/staging/rtl8723au/include/odm.h +++ b/drivers/staging/rtl8723au/include/odm.h @@ -362,7 +362,6 @@ enum { ODM_BB_RXHP = BIT(12), /* MAC DM section BIT 16-23 */ - ODM_MAC_EDCA_TURBO = BIT(16), ODM_MAC_EARLY_MODE = BIT(17), /* RF ODM section BIT 24-31 */ -- GitLab From 79afea1b3003115b2c26bab4041e69b31c2a03c6 Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Mon, 2 Mar 2015 15:24:39 -0500 Subject: [PATCH 02993/11651] staging: rtl8723au: ODM_BB_RA_MASK is always set Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/hal/odm.c | 17 ++--------------- drivers/staging/rtl8723au/hal/rtl8723a_dm.c | 1 - drivers/staging/rtl8723au/include/odm.h | 1 - 3 files changed, 2 insertions(+), 17 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/odm.c b/drivers/staging/rtl8723au/hal/odm.c index 8dcb020e1f18..64dd980a170d 100644 --- a/drivers/staging/rtl8723au/hal/odm.c +++ b/drivers/staging/rtl8723au/hal/odm.c @@ -189,8 +189,6 @@ void odm_DynamicBBPowerSaving23a(struct dm_odm_t *pDM_Odm); /* END---------BB POWER SAVE----------------------- */ -void odm_RefreshRateAdaptiveMask23aCE23a(struct dm_odm_t *pDM_Odm); - void odm_DynamicTxPower23aInit(struct dm_odm_t *pDM_Odm); void odm_RSSIMonitorCheck23aCE(struct dm_odm_t *pDM_Odm); @@ -1107,25 +1105,14 @@ u32 ODM_Get_Rate_Bitmap23a(struct hal_data_8723a *pHalData, u32 macid, * *---------------------------------------------------------------------------*/ void odm_RefreshRateAdaptiveMask23a(struct dm_odm_t *pDM_Odm) -{ - if (!(pDM_Odm->SupportAbility & ODM_BB_RA_MASK)) - return; - /* */ - /* 2011/09/29 MH In HW integration first stage, we provide 4 different handle to operate */ - /* at the same time. In the stage2/3, we need to prive universal interface and merge all */ - /* HW dynamic mechanism. */ - /* */ - odm_RefreshRateAdaptiveMask23aCE23a(pDM_Odm); -} - -void odm_RefreshRateAdaptiveMask23aCE23a(struct dm_odm_t *pDM_Odm) { u8 i; struct rtw_adapter *pAdapter = pDM_Odm->Adapter; if (pAdapter->bDriverStopped) { ODM_RT_TRACE(pDM_Odm, ODM_COMP_RA_MASK, ODM_DBG_TRACE, - ("<---- odm_RefreshRateAdaptiveMask23a(): driver is going to unload\n")); + ("<---- %s: driver is going to unload\n", + __func__)); return; } diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_dm.c b/drivers/staging/rtl8723au/hal/rtl8723a_dm.c index 85be3e0d7feb..61ff14aca365 100644 --- a/drivers/staging/rtl8723au/hal/rtl8723a_dm.c +++ b/drivers/staging/rtl8723au/hal/rtl8723a_dm.c @@ -130,7 +130,6 @@ static void Update_ODM_ComInfo_8723a(struct rtw_adapter *Adapter) struct dm_priv *pdmpriv = &pHalData->dmpriv; int i; pdmpriv->InitODMFlag = ODM_BB_DIG | - ODM_BB_RA_MASK | ODM_BB_DYNAMIC_TXPWR | ODM_BB_FA_CNT | ODM_BB_RSSI_MONITOR | diff --git a/drivers/staging/rtl8723au/include/odm.h b/drivers/staging/rtl8723au/include/odm.h index 50459f09dbbb..4653518f3d7e 100644 --- a/drivers/staging/rtl8723au/include/odm.h +++ b/drivers/staging/rtl8723au/include/odm.h @@ -348,7 +348,6 @@ enum odm_cmninfo { enum { /* BB ODM section BIT 0-15 */ ODM_BB_DIG = BIT(0), - ODM_BB_RA_MASK = BIT(1), ODM_BB_DYNAMIC_TXPWR = BIT(2), ODM_BB_FA_CNT = BIT(3), ODM_BB_RSSI_MONITOR = BIT(4), -- GitLab From 3d51a602dcd4be8989ff459fc0d6f1bb78336d7c Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Mon, 2 Mar 2015 15:24:40 -0500 Subject: [PATCH 02994/11651] staging: rtl8723au: ODM_BB_DIG is always set Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/hal/odm.c | 5 ++--- drivers/staging/rtl8723au/hal/rtl8723a_dm.c | 3 +-- drivers/staging/rtl8723au/include/odm.h | 1 - 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/odm.c b/drivers/staging/rtl8723au/hal/odm.c index 64dd980a170d..406c503343ad 100644 --- a/drivers/staging/rtl8723au/hal/odm.c +++ b/drivers/staging/rtl8723au/hal/odm.c @@ -583,10 +583,9 @@ void odm_DIG23a(struct rtw_adapter *adapter) u8 CurrentIGI = pDM_DigTable->CurIGValue; ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG23a() ==>\n")); - /* if (!(pDM_Odm->SupportAbility & (ODM_BB_DIG|ODM_BB_FA_CNT))) */ - if ((!(pDM_Odm->SupportAbility&ODM_BB_DIG)) || (!(pDM_Odm->SupportAbility&ODM_BB_FA_CNT))) { + if (!(pDM_Odm->SupportAbility & ODM_BB_FA_CNT)) { ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, - ("odm_DIG23a() Return: SupportAbility ODM_BB_DIG or ODM_BB_FA_CNT is disabled\n")); + ("odm_DIG23a() Return: SupportAbility ODM_BB_FA_CNT is disabled\n")); return; } diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_dm.c b/drivers/staging/rtl8723au/hal/rtl8723a_dm.c index 61ff14aca365..16811ffc67f2 100644 --- a/drivers/staging/rtl8723au/hal/rtl8723a_dm.c +++ b/drivers/staging/rtl8723au/hal/rtl8723a_dm.c @@ -129,8 +129,7 @@ static void Update_ODM_ComInfo_8723a(struct rtw_adapter *Adapter) struct dm_odm_t *pDM_Odm = &pHalData->odmpriv; struct dm_priv *pdmpriv = &pHalData->dmpriv; int i; - pdmpriv->InitODMFlag = ODM_BB_DIG | - ODM_BB_DYNAMIC_TXPWR | + pdmpriv->InitODMFlag = ODM_BB_DYNAMIC_TXPWR | ODM_BB_FA_CNT | ODM_BB_RSSI_MONITOR | ODM_BB_CCK_PD | diff --git a/drivers/staging/rtl8723au/include/odm.h b/drivers/staging/rtl8723au/include/odm.h index 4653518f3d7e..7ee874aea776 100644 --- a/drivers/staging/rtl8723au/include/odm.h +++ b/drivers/staging/rtl8723au/include/odm.h @@ -347,7 +347,6 @@ enum odm_cmninfo { /* Define ODM support ability. ODM_CMNINFO_ABILITY */ enum { /* BB ODM section BIT 0-15 */ - ODM_BB_DIG = BIT(0), ODM_BB_DYNAMIC_TXPWR = BIT(2), ODM_BB_FA_CNT = BIT(3), ODM_BB_RSSI_MONITOR = BIT(4), -- GitLab From 6920f3b9688f9808f7c11964774321a8e03c492e Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Mon, 2 Mar 2015 15:24:41 -0500 Subject: [PATCH 02995/11651] staging: rtl8723au: ODM_BB_DYNAMIC_TXPWR isn't used for anything Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/hal/rtl8723a_dm.c | 3 +-- drivers/staging/rtl8723au/include/odm.h | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_dm.c b/drivers/staging/rtl8723au/hal/rtl8723a_dm.c index 16811ffc67f2..65276e2eecc8 100644 --- a/drivers/staging/rtl8723au/hal/rtl8723a_dm.c +++ b/drivers/staging/rtl8723au/hal/rtl8723a_dm.c @@ -129,8 +129,7 @@ static void Update_ODM_ComInfo_8723a(struct rtw_adapter *Adapter) struct dm_odm_t *pDM_Odm = &pHalData->odmpriv; struct dm_priv *pdmpriv = &pHalData->dmpriv; int i; - pdmpriv->InitODMFlag = ODM_BB_DYNAMIC_TXPWR | - ODM_BB_FA_CNT | + pdmpriv->InitODMFlag = ODM_BB_FA_CNT | ODM_BB_RSSI_MONITOR | ODM_BB_CCK_PD | ODM_BB_PWR_SAVE | diff --git a/drivers/staging/rtl8723au/include/odm.h b/drivers/staging/rtl8723au/include/odm.h index 7ee874aea776..af860b3c9f59 100644 --- a/drivers/staging/rtl8723au/include/odm.h +++ b/drivers/staging/rtl8723au/include/odm.h @@ -347,7 +347,6 @@ enum odm_cmninfo { /* Define ODM support ability. ODM_CMNINFO_ABILITY */ enum { /* BB ODM section BIT 0-15 */ - ODM_BB_DYNAMIC_TXPWR = BIT(2), ODM_BB_FA_CNT = BIT(3), ODM_BB_RSSI_MONITOR = BIT(4), ODM_BB_CCK_PD = BIT(5), -- GitLab From 399ec83079a2b281a905b9e943ca2f13f82e02cf Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Mon, 2 Mar 2015 15:24:42 -0500 Subject: [PATCH 02996/11651] staging: rtl8723au: ODM_BB_FA_CNT is always set Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/hal/odm.c | 11 +---------- drivers/staging/rtl8723au/hal/rtl8723a_dm.c | 3 +-- drivers/staging/rtl8723au/include/odm.h | 1 - 3 files changed, 2 insertions(+), 13 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/odm.c b/drivers/staging/rtl8723au/hal/odm.c index 406c503343ad..8ec113fe71ec 100644 --- a/drivers/staging/rtl8723au/hal/odm.c +++ b/drivers/staging/rtl8723au/hal/odm.c @@ -583,12 +583,6 @@ void odm_DIG23a(struct rtw_adapter *adapter) u8 CurrentIGI = pDM_DigTable->CurIGValue; ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG23a() ==>\n")); - if (!(pDM_Odm->SupportAbility & ODM_BB_FA_CNT)) { - ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, - ("odm_DIG23a() Return: SupportAbility ODM_BB_FA_CNT is disabled\n")); - return; - } - if (adapter->mlmepriv.bScanInProcess) { ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG23a() Return: In Scan Progress \n")); return; @@ -757,9 +751,6 @@ void odm_FalseAlarmCounterStatistics23a(struct dm_odm_t *pDM_Odm) u32 ret_value; struct false_alarm_stats *FalseAlmCnt = &pDM_Odm->FalseAlmCnt; - if (!(pDM_Odm->SupportAbility & ODM_BB_FA_CNT)) - return; - /* hold ofdm counter */ /* hold page C counter */ ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_HOLDC_11N, BIT(31), 1); @@ -863,7 +854,7 @@ void odm_CCKPacketDetectionThresh23a(struct dm_odm_t *pDM_Odm) struct false_alarm_stats *FalseAlmCnt = &pDM_Odm->FalseAlmCnt; u8 CurCCK_CCAThres; - if (!(pDM_Odm->SupportAbility & (ODM_BB_CCK_PD|ODM_BB_FA_CNT))) + if (!(pDM_Odm->SupportAbility & ODM_BB_CCK_PD)) return; if (pDM_Odm->ExtLNA) diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_dm.c b/drivers/staging/rtl8723au/hal/rtl8723a_dm.c index 65276e2eecc8..3524e71806b9 100644 --- a/drivers/staging/rtl8723au/hal/rtl8723a_dm.c +++ b/drivers/staging/rtl8723au/hal/rtl8723a_dm.c @@ -129,8 +129,7 @@ static void Update_ODM_ComInfo_8723a(struct rtw_adapter *Adapter) struct dm_odm_t *pDM_Odm = &pHalData->odmpriv; struct dm_priv *pdmpriv = &pHalData->dmpriv; int i; - pdmpriv->InitODMFlag = ODM_BB_FA_CNT | - ODM_BB_RSSI_MONITOR | + pdmpriv->InitODMFlag = ODM_BB_RSSI_MONITOR | ODM_BB_CCK_PD | ODM_BB_PWR_SAVE | ODM_RF_TX_PWR_TRACK | diff --git a/drivers/staging/rtl8723au/include/odm.h b/drivers/staging/rtl8723au/include/odm.h index af860b3c9f59..ab9fe31f1ca0 100644 --- a/drivers/staging/rtl8723au/include/odm.h +++ b/drivers/staging/rtl8723au/include/odm.h @@ -347,7 +347,6 @@ enum odm_cmninfo { /* Define ODM support ability. ODM_CMNINFO_ABILITY */ enum { /* BB ODM section BIT 0-15 */ - ODM_BB_FA_CNT = BIT(3), ODM_BB_RSSI_MONITOR = BIT(4), ODM_BB_CCK_PD = BIT(5), ODM_BB_ANT_DIV = BIT(6), -- GitLab From 01c1ec0057b79472434b1ea6bff3bf3d0bd026df Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Mon, 2 Mar 2015 15:24:43 -0500 Subject: [PATCH 02997/11651] staging: rtl8723au: ODM_BB_RSSI_MONITOR is always set Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/hal/odm.c | 17 +---------------- drivers/staging/rtl8723au/hal/rtl8723a_dm.c | 3 +-- drivers/staging/rtl8723au/include/odm.h | 1 - 3 files changed, 2 insertions(+), 19 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/odm.c b/drivers/staging/rtl8723au/hal/odm.c index 8ec113fe71ec..5d72ec717826 100644 --- a/drivers/staging/rtl8723au/hal/odm.c +++ b/drivers/staging/rtl8723au/hal/odm.c @@ -191,7 +191,6 @@ void odm_DynamicBBPowerSaving23a(struct dm_odm_t *pDM_Odm); void odm_DynamicTxPower23aInit(struct dm_odm_t *pDM_Odm); -void odm_RSSIMonitorCheck23aCE(struct dm_odm_t *pDM_Odm); void odm_RSSIMonitorCheck23a(struct dm_odm_t *pDM_Odm); void odm_DynamicTxPower23a(struct dm_odm_t *pDM_Odm); @@ -1186,20 +1185,6 @@ void odm_DynamicTxPower23aInit(struct dm_odm_t *pDM_Odm) pdmpriv->DynamicTxHighPowerLvl = TxHighPwrLevel_Normal; } -void odm_RSSIMonitorCheck23a(struct dm_odm_t *pDM_Odm) -{ - /* For AP/ADSL use struct rtl8723a_priv * */ - /* For CE/NIC use struct rtw_adapter * */ - - if (!(pDM_Odm->SupportAbility & ODM_BB_RSSI_MONITOR)) - return; - - /* 2011/09/29 MH In HW integration first stage, we provide 4 different handle to operate */ - /* at the same time. In the stage2/3, we need to prive universal interface and merge all */ - /* HW dynamic mechanism. */ - odm_RSSIMonitorCheck23aCE(pDM_Odm); -} /* odm_RSSIMonitorCheck23a */ - static void FindMinimumRSSI( struct rtw_adapter *pAdapter @@ -1218,7 +1203,7 @@ FindMinimumRSSI( pdmpriv->MinUndecoratedPWDBForDM = pdmpriv->EntryMinUndecoratedSmoothedPWDB; } -void odm_RSSIMonitorCheck23aCE(struct dm_odm_t *pDM_Odm) +void odm_RSSIMonitorCheck23a(struct dm_odm_t *pDM_Odm) { struct rtw_adapter *Adapter = pDM_Odm->Adapter; struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_dm.c b/drivers/staging/rtl8723au/hal/rtl8723a_dm.c index 3524e71806b9..93b76bd1785e 100644 --- a/drivers/staging/rtl8723au/hal/rtl8723a_dm.c +++ b/drivers/staging/rtl8723au/hal/rtl8723a_dm.c @@ -129,8 +129,7 @@ static void Update_ODM_ComInfo_8723a(struct rtw_adapter *Adapter) struct dm_odm_t *pDM_Odm = &pHalData->odmpriv; struct dm_priv *pdmpriv = &pHalData->dmpriv; int i; - pdmpriv->InitODMFlag = ODM_BB_RSSI_MONITOR | - ODM_BB_CCK_PD | + pdmpriv->InitODMFlag = ODM_BB_CCK_PD | ODM_BB_PWR_SAVE | ODM_RF_TX_PWR_TRACK | ODM_RF_CALIBRATION; diff --git a/drivers/staging/rtl8723au/include/odm.h b/drivers/staging/rtl8723au/include/odm.h index ab9fe31f1ca0..783b8fed2261 100644 --- a/drivers/staging/rtl8723au/include/odm.h +++ b/drivers/staging/rtl8723au/include/odm.h @@ -347,7 +347,6 @@ enum odm_cmninfo { /* Define ODM support ability. ODM_CMNINFO_ABILITY */ enum { /* BB ODM section BIT 0-15 */ - ODM_BB_RSSI_MONITOR = BIT(4), ODM_BB_CCK_PD = BIT(5), ODM_BB_ANT_DIV = BIT(6), ODM_BB_PWR_SAVE = BIT(7), -- GitLab From 6bdef7a0d402f1a0f4ec26da2170da52d51537dd Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Mon, 2 Mar 2015 15:24:44 -0500 Subject: [PATCH 02998/11651] staging: rtl8723au: ODM_BB_CCK_PD is always set Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/hal/odm.c | 3 --- drivers/staging/rtl8723au/hal/rtl8723a_dm.c | 3 +-- drivers/staging/rtl8723au/include/odm.h | 1 - 3 files changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/odm.c b/drivers/staging/rtl8723au/hal/odm.c index 5d72ec717826..307773570741 100644 --- a/drivers/staging/rtl8723au/hal/odm.c +++ b/drivers/staging/rtl8723au/hal/odm.c @@ -853,9 +853,6 @@ void odm_CCKPacketDetectionThresh23a(struct dm_odm_t *pDM_Odm) struct false_alarm_stats *FalseAlmCnt = &pDM_Odm->FalseAlmCnt; u8 CurCCK_CCAThres; - if (!(pDM_Odm->SupportAbility & ODM_BB_CCK_PD)) - return; - if (pDM_Odm->ExtLNA) return; diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_dm.c b/drivers/staging/rtl8723au/hal/rtl8723a_dm.c index 93b76bd1785e..405317193173 100644 --- a/drivers/staging/rtl8723au/hal/rtl8723a_dm.c +++ b/drivers/staging/rtl8723au/hal/rtl8723a_dm.c @@ -129,8 +129,7 @@ static void Update_ODM_ComInfo_8723a(struct rtw_adapter *Adapter) struct dm_odm_t *pDM_Odm = &pHalData->odmpriv; struct dm_priv *pdmpriv = &pHalData->dmpriv; int i; - pdmpriv->InitODMFlag = ODM_BB_CCK_PD | - ODM_BB_PWR_SAVE | + pdmpriv->InitODMFlag = ODM_BB_PWR_SAVE | ODM_RF_TX_PWR_TRACK | ODM_RF_CALIBRATION; /* Pointer reference */ diff --git a/drivers/staging/rtl8723au/include/odm.h b/drivers/staging/rtl8723au/include/odm.h index 783b8fed2261..e57472bdc699 100644 --- a/drivers/staging/rtl8723au/include/odm.h +++ b/drivers/staging/rtl8723au/include/odm.h @@ -347,7 +347,6 @@ enum odm_cmninfo { /* Define ODM support ability. ODM_CMNINFO_ABILITY */ enum { /* BB ODM section BIT 0-15 */ - ODM_BB_CCK_PD = BIT(5), ODM_BB_ANT_DIV = BIT(6), ODM_BB_PWR_SAVE = BIT(7), ODM_BB_PWR_TRAIN = BIT(8), -- GitLab From 719d3f6cf025c30506c5d37ed6aca27741a89107 Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Mon, 2 Mar 2015 15:24:45 -0500 Subject: [PATCH 02999/11651] staging: rtl8723au: ODM_BB_PWR_SAVE is unused Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/hal/rtl8723a_dm.c | 3 +-- drivers/staging/rtl8723au/include/odm.h | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_dm.c b/drivers/staging/rtl8723au/hal/rtl8723a_dm.c index 405317193173..266e2274601a 100644 --- a/drivers/staging/rtl8723au/hal/rtl8723a_dm.c +++ b/drivers/staging/rtl8723au/hal/rtl8723a_dm.c @@ -129,8 +129,7 @@ static void Update_ODM_ComInfo_8723a(struct rtw_adapter *Adapter) struct dm_odm_t *pDM_Odm = &pHalData->odmpriv; struct dm_priv *pdmpriv = &pHalData->dmpriv; int i; - pdmpriv->InitODMFlag = ODM_BB_PWR_SAVE | - ODM_RF_TX_PWR_TRACK | + pdmpriv->InitODMFlag = ODM_RF_TX_PWR_TRACK | ODM_RF_CALIBRATION; /* Pointer reference */ rtl8723a_odm_support_ability_set(Adapter, DYNAMIC_ALL_FUNC_ENABLE); diff --git a/drivers/staging/rtl8723au/include/odm.h b/drivers/staging/rtl8723au/include/odm.h index e57472bdc699..f59184414d83 100644 --- a/drivers/staging/rtl8723au/include/odm.h +++ b/drivers/staging/rtl8723au/include/odm.h @@ -348,7 +348,6 @@ enum odm_cmninfo { enum { /* BB ODM section BIT 0-15 */ ODM_BB_ANT_DIV = BIT(6), - ODM_BB_PWR_SAVE = BIT(7), ODM_BB_PWR_TRAIN = BIT(8), ODM_BB_RATE_ADAPTIVE = BIT(9), ODM_BB_PATH_DIV = BIT(10), -- GitLab From 4be419e6d3c5019480e60f2340e59cbd602f8af8 Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Mon, 2 Mar 2015 15:24:46 -0500 Subject: [PATCH 03000/11651] staging: rtl8723au: ODM_RF_TX_PWR_TRACK is always set Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/hal/HalDMOutSrc8723A_CE.c | 11 +---------- drivers/staging/rtl8723au/hal/rtl8723a_dm.c | 3 +-- drivers/staging/rtl8723au/include/odm.h | 1 - 3 files changed, 2 insertions(+), 13 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/HalDMOutSrc8723A_CE.c b/drivers/staging/rtl8723au/hal/HalDMOutSrc8723A_CE.c index 2dac6f0cd9c2..163e4d28eef0 100644 --- a/drivers/staging/rtl8723au/hal/HalDMOutSrc8723A_CE.c +++ b/drivers/staging/rtl8723au/hal/HalDMOutSrc8723A_CE.c @@ -359,14 +359,10 @@ static void ODM_TXPowerTracking92CDirectCall(struct rtw_adapter *Adapter) odm_TXPowerTrackingCallback_ThermalMeter_92C(Adapter); } -static void odm_CheckTXPowerTracking_ThermalMeter(struct rtw_adapter *Adapter) +void rtl8723a_odm_check_tx_power_tracking(struct rtw_adapter *Adapter) { struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); struct dm_priv *pdmpriv = &pHalData->dmpriv; - struct dm_odm_t *podmpriv = &pHalData->odmpriv; - - if (!(podmpriv->SupportAbility & ODM_RF_TX_PWR_TRACK)) - return; if (!pdmpriv->TM_Trigger) { /* at least delay 1 sec */ PHY_SetRFReg(Adapter, RF_PATH_A, RF_T_METER, bRFRegOffsetMask, 0x60); @@ -379,11 +375,6 @@ static void odm_CheckTXPowerTracking_ThermalMeter(struct rtw_adapter *Adapter) } } -void rtl8723a_odm_check_tx_power_tracking(struct rtw_adapter *Adapter) -{ - odm_CheckTXPowerTracking_ThermalMeter(Adapter); -} - /* IQK */ #define MAX_TOLERANCE 5 #define IQK_DELAY_TIME 1 /* ms */ diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_dm.c b/drivers/staging/rtl8723au/hal/rtl8723a_dm.c index 266e2274601a..5969ee37f26f 100644 --- a/drivers/staging/rtl8723au/hal/rtl8723a_dm.c +++ b/drivers/staging/rtl8723au/hal/rtl8723a_dm.c @@ -129,8 +129,7 @@ static void Update_ODM_ComInfo_8723a(struct rtw_adapter *Adapter) struct dm_odm_t *pDM_Odm = &pHalData->odmpriv; struct dm_priv *pdmpriv = &pHalData->dmpriv; int i; - pdmpriv->InitODMFlag = ODM_RF_TX_PWR_TRACK | - ODM_RF_CALIBRATION; + pdmpriv->InitODMFlag = ODM_RF_CALIBRATION; /* Pointer reference */ rtl8723a_odm_support_ability_set(Adapter, DYNAMIC_ALL_FUNC_ENABLE); diff --git a/drivers/staging/rtl8723au/include/odm.h b/drivers/staging/rtl8723au/include/odm.h index f59184414d83..bf17262bc31a 100644 --- a/drivers/staging/rtl8723au/include/odm.h +++ b/drivers/staging/rtl8723au/include/odm.h @@ -358,7 +358,6 @@ enum { ODM_MAC_EARLY_MODE = BIT(17), /* RF ODM section BIT 24-31 */ - ODM_RF_TX_PWR_TRACK = BIT(24), ODM_RF_RX_GAIN_TRACK = BIT(25), ODM_RF_CALIBRATION = BIT(26), -- GitLab From fec75cd5f1def0652ff56e649f24256fdfd26b8c Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Mon, 2 Mar 2015 15:24:47 -0500 Subject: [PATCH 03001/11651] staging: rtl8723au: ODM_RF_CALIBRATION is never set Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/hal/rtl8723a_dm.c | 2 +- drivers/staging/rtl8723au/include/odm.h | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_dm.c b/drivers/staging/rtl8723au/hal/rtl8723a_dm.c index 5969ee37f26f..3a904fd4d200 100644 --- a/drivers/staging/rtl8723au/hal/rtl8723a_dm.c +++ b/drivers/staging/rtl8723au/hal/rtl8723a_dm.c @@ -129,7 +129,7 @@ static void Update_ODM_ComInfo_8723a(struct rtw_adapter *Adapter) struct dm_odm_t *pDM_Odm = &pHalData->odmpriv; struct dm_priv *pdmpriv = &pHalData->dmpriv; int i; - pdmpriv->InitODMFlag = ODM_RF_CALIBRATION; + pdmpriv->InitODMFlag = 0; /* Pointer reference */ rtl8723a_odm_support_ability_set(Adapter, DYNAMIC_ALL_FUNC_ENABLE); diff --git a/drivers/staging/rtl8723au/include/odm.h b/drivers/staging/rtl8723au/include/odm.h index bf17262bc31a..7d505cf01838 100644 --- a/drivers/staging/rtl8723au/include/odm.h +++ b/drivers/staging/rtl8723au/include/odm.h @@ -359,8 +359,6 @@ enum { /* RF ODM section BIT 24-31 */ ODM_RF_RX_GAIN_TRACK = BIT(25), - ODM_RF_CALIBRATION = BIT(26), - }; /* ODM_CMNINFO_INTERFACE */ -- GitLab From ea89e2f6b7ae55db9275f631327dc5c07f72871e Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Mon, 2 Mar 2015 15:24:48 -0500 Subject: [PATCH 03002/11651] staging: rtl8723au: Remove unused ODM ability flags Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/include/odm.h | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/drivers/staging/rtl8723au/include/odm.h b/drivers/staging/rtl8723au/include/odm.h index 7d505cf01838..78c17f396c4d 100644 --- a/drivers/staging/rtl8723au/include/odm.h +++ b/drivers/staging/rtl8723au/include/odm.h @@ -348,17 +348,6 @@ enum odm_cmninfo { enum { /* BB ODM section BIT 0-15 */ ODM_BB_ANT_DIV = BIT(6), - ODM_BB_PWR_TRAIN = BIT(8), - ODM_BB_RATE_ADAPTIVE = BIT(9), - ODM_BB_PATH_DIV = BIT(10), - ODM_BB_PSD = BIT(11), - ODM_BB_RXHP = BIT(12), - - /* MAC DM section BIT 16-23 */ - ODM_MAC_EARLY_MODE = BIT(17), - - /* RF ODM section BIT 24-31 */ - ODM_RF_RX_GAIN_TRACK = BIT(25), }; /* ODM_CMNINFO_INTERFACE */ -- GitLab From 8cba07d71d24c6b098723f152091a4292374aa14 Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Mon, 2 Mar 2015 15:24:49 -0500 Subject: [PATCH 03003/11651] staging: rtl8723au: Make odm_PHY_SaveAFERegisters() readable Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/hal/odm.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/odm.c b/drivers/staging/rtl8723au/hal/odm.c index 307773570741..c50b8a59dc93 100644 --- a/drivers/staging/rtl8723au/hal/odm.c +++ b/drivers/staging/rtl8723au/hal/odm.c @@ -1454,16 +1454,11 @@ void ODM_SingleDualAntennaDefaultSetting(struct dm_odm_t *pDM_Odm) /* 2 8723A ANT DETECT */ -static void odm_PHY_SaveAFERegisters( - struct dm_odm_t *pDM_Odm, - u32 *AFEReg, - u32 *AFEBackup, - u32 RegisterNum - ) +static void odm_PHY_SaveAFERegisters(struct dm_odm_t *pDM_Odm, u32 *AFEReg, + u32 *AFEBackup, u32 RegisterNum) { u32 i; - /* RTPRINT(FINIT, INIT_IQK, ("Save ADDA parameters.\n")); */ for (i = 0 ; i < RegisterNum ; i++) AFEBackup[i] = ODM_GetBBReg(pDM_Odm, AFEReg[i], bMaskDWord); } -- GitLab From 8122a8c88ea711fdc72374097aaf7302fc346165 Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Mon, 2 Mar 2015 15:24:50 -0500 Subject: [PATCH 03004/11651] staging: rtl8723au: odm_dtc(): Remove no-op function Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/hal/odm.c | 7 ------- drivers/staging/rtl8723au/include/odm.h | 2 -- 2 files changed, 9 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/odm.c b/drivers/staging/rtl8723au/hal/odm.c index c50b8a59dc93..5a0568be28de 100644 --- a/drivers/staging/rtl8723au/hal/odm.c +++ b/drivers/staging/rtl8723au/hal/odm.c @@ -280,8 +280,6 @@ void ODM_DMWatchdog23a(struct rtw_adapter *adapter) ODM_TXPowerTrackingCheck23a(pDM_Odm); odm_EdcaTurboCheck23a(pDM_Odm); - - odm_dtc(pDM_Odm); } /* */ @@ -1663,8 +1661,3 @@ bool ODM_SingleDualAntennaDetection(struct dm_odm_t *pDM_Odm, u8 mode) } return bResult; } - -/* Justin: According to the current RRSI to adjust Response Frame TX power, 2012/11/05 */ -void odm_dtc(struct dm_odm_t *pDM_Odm) -{ -} diff --git a/drivers/staging/rtl8723au/include/odm.h b/drivers/staging/rtl8723au/include/odm.h index 78c17f396c4d..7be2c074aee8 100644 --- a/drivers/staging/rtl8723au/include/odm.h +++ b/drivers/staging/rtl8723au/include/odm.h @@ -942,6 +942,4 @@ void ODM_SingleDualAntennaDefaultSetting(struct dm_odm_t *pDM_Odm); bool ODM_SingleDualAntennaDetection(struct dm_odm_t *pDM_Odm, u8 mode); -void odm_dtc(struct dm_odm_t *pDM_Odm); - #endif -- GitLab From b9c39d293fd4ae8212ddad3a075af850820ec751 Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Mon, 2 Mar 2015 15:24:51 -0500 Subject: [PATCH 03005/11651] staging: rtl8723au: Remove no-op ODM_CMNINFO_PLATFORM Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/hal/odm.c | 2 -- drivers/staging/rtl8723au/hal/rtl8723a_dm.c | 1 - drivers/staging/rtl8723au/include/odm.h | 15 +++++++-------- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/odm.c b/drivers/staging/rtl8723au/hal/odm.c index 5a0568be28de..e1a26302e0fd 100644 --- a/drivers/staging/rtl8723au/hal/odm.c +++ b/drivers/staging/rtl8723au/hal/odm.c @@ -297,8 +297,6 @@ void ODM_CmnInfoInit23a(struct dm_odm_t *pDM_Odm, /* */ switch (CmnInfo) { /* Fixed ODM value. */ - case ODM_CMNINFO_PLATFORM: - break; case ODM_CMNINFO_INTERFACE: pDM_Odm->SupportInterface = (u8)Value; break; diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_dm.c b/drivers/staging/rtl8723au/hal/rtl8723a_dm.c index 3a904fd4d200..e44d2b478c12 100644 --- a/drivers/staging/rtl8723au/hal/rtl8723a_dm.c +++ b/drivers/staging/rtl8723au/hal/rtl8723a_dm.c @@ -94,7 +94,6 @@ void rtl8723a_init_dm_priv(struct rtw_adapter *Adapter) memset(pDM_Odm, 0, sizeof(*pDM_Odm)); pDM_Odm->Adapter = Adapter; - ODM_CmnInfoInit23a(pDM_Odm, ODM_CMNINFO_PLATFORM, 0x04); ODM_CmnInfoInit23a(pDM_Odm, ODM_CMNINFO_INTERFACE, RTW_USB);/* RTL871X_HCI_TYPE */ ODM_CmnInfoInit23a(pDM_Odm, ODM_CMNINFO_IC_TYPE, ODM_RTL8723A); diff --git a/drivers/staging/rtl8723au/include/odm.h b/drivers/staging/rtl8723au/include/odm.h index 7be2c074aee8..1c1775b8f0a9 100644 --- a/drivers/staging/rtl8723au/include/odm.h +++ b/drivers/staging/rtl8723au/include/odm.h @@ -298,17 +298,16 @@ enum odm_cmninfo { /* Fixed value: */ /* */ - ODM_CMNINFO_PLATFORM = 0, - ODM_CMNINFO_INTERFACE, /* enum odm_interface_def */ + ODM_CMNINFO_INTERFACE = 1, /* enum odm_interface_def */ ODM_CMNINFO_MP_TEST_CHIP, - ODM_CMNINFO_IC_TYPE, /* enum odm_ic_type_def */ - ODM_CMNINFO_CUT_VER, /* enum odm_cut_version */ - ODM_CMNINFO_FAB_VER, /* enum odm_fab_version */ - ODM_CMNINFO_BOARD_TYPE, /* enum odm_board_type */ - ODM_CMNINFO_EXT_LNA, /* true */ + ODM_CMNINFO_IC_TYPE, /* enum odm_ic_type_def */ + ODM_CMNINFO_CUT_VER, /* enum odm_cut_version */ + ODM_CMNINFO_FAB_VER, /* enum odm_fab_version */ + ODM_CMNINFO_BOARD_TYPE, /* enum odm_board_type */ + ODM_CMNINFO_EXT_LNA, /* true */ ODM_CMNINFO_EXT_PA, ODM_CMNINFO_EXT_TRSW, - ODM_CMNINFO_PATCH_ID, /* CUSTOMER ID */ + ODM_CMNINFO_PATCH_ID, /* CUSTOMER ID */ ODM_CMNINFO_BINHCT_TEST, ODM_CMNINFO_BWIFI_TEST, ODM_CMNINFO_SMART_CONCURRENT, -- GitLab From 9d693e3a09fd0b50a39c864e7a260e69efb78896 Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Mon, 2 Mar 2015 15:24:52 -0500 Subject: [PATCH 03006/11651] staging: rtl8723au: SupportInterface is always set to USB Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- .../staging/rtl8723au/hal/HalHWImg8723A_BB.c | 9 ++--- .../staging/rtl8723au/hal/HalHWImg8723A_MAC.c | 3 +- .../staging/rtl8723au/hal/HalHWImg8723A_RF.c | 3 +- drivers/staging/rtl8723au/hal/odm.c | 4 --- drivers/staging/rtl8723au/hal/odm_HWConfig.c | 35 +++++++++---------- drivers/staging/rtl8723au/hal/rtl8723a_dm.c | 1 - drivers/staging/rtl8723au/include/hal_intf.h | 7 ---- drivers/staging/rtl8723au/include/odm.h | 5 +-- 8 files changed, 23 insertions(+), 44 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/HalHWImg8723A_BB.c b/drivers/staging/rtl8723au/hal/HalHWImg8723A_BB.c index 67d985c21712..577b9113b212 100644 --- a/drivers/staging/rtl8723au/hal/HalHWImg8723A_BB.c +++ b/drivers/staging/rtl8723au/hal/HalHWImg8723A_BB.c @@ -219,13 +219,12 @@ void ODM_ReadAndConfig_AGC_TAB_1T_8723A(struct dm_odm_t *pDM_Odm) u32 hex; u32 i; u8 platform = 0x04; - u8 interfaceValue = pDM_Odm->SupportInterface; u8 board = pDM_Odm->BoardType; u32 ArrayLen = sizeof(Array_AGC_TAB_1T_8723A)/sizeof(u32); u32 *Array = Array_AGC_TAB_1T_8723A; hex = board; - hex += interfaceValue << 8; + hex += ODM_ITRF_USB << 8; hex += platform << 16; hex += 0xFF000000; for (i = 0; i < ArrayLen; i += 2) { @@ -467,13 +466,12 @@ void ODM_ReadAndConfig_PHY_REG_1T_8723A(struct dm_odm_t *pDM_Odm) u32 hex = 0; u32 i = 0; u8 platform = 0x04; - u8 interfaceValue = pDM_Odm->SupportInterface; u8 board = pDM_Odm->BoardType; u32 ArrayLen = sizeof(Array_PHY_REG_1T_8723A)/sizeof(u32); u32 *Array = Array_PHY_REG_1T_8723A; hex += board; - hex += interfaceValue << 8; + hex += ODM_ITRF_USB << 8; hex += platform << 16; hex += 0xFF000000; for (i = 0; i < ArrayLen; i += 2) { @@ -523,13 +521,12 @@ void ODM_ReadAndConfig_PHY_REG_MP_8723A(struct dm_odm_t *pDM_Odm) u32 hex = 0; u32 i = 0; u8 platform = 0x04; - u8 interfaceValue = pDM_Odm->SupportInterface; u8 board = pDM_Odm->BoardType; u32 ArrayLen = sizeof(Array_PHY_REG_MP_8723A)/sizeof(u32); u32 *Array = Array_PHY_REG_MP_8723A; hex += board; - hex += interfaceValue << 8; + hex += ODM_ITRF_USB << 8; hex += platform << 16; hex += 0xFF000000; for (i = 0; i < ArrayLen; i += 2) { diff --git a/drivers/staging/rtl8723au/hal/HalHWImg8723A_MAC.c b/drivers/staging/rtl8723au/hal/HalHWImg8723A_MAC.c index 83018301ec27..93b2d183d694 100644 --- a/drivers/staging/rtl8723au/hal/HalHWImg8723A_MAC.c +++ b/drivers/staging/rtl8723au/hal/HalHWImg8723A_MAC.c @@ -144,13 +144,12 @@ void ODM_ReadAndConfig_MAC_REG_8723A(struct dm_odm_t *pDM_Odm) u32 hex = 0; u32 i = 0; u8 platform = 0x04; - u8 interfaceValue = pDM_Odm->SupportInterface; u8 board = pDM_Odm->BoardType; u32 ArrayLen = sizeof(Array_MAC_REG_8723A)/sizeof(u32); u32 *Array = Array_MAC_REG_8723A; hex += board; - hex += interfaceValue << 8; + hex += ODM_ITRF_USB << 8; hex += platform << 16; hex += 0xFF000000; for (i = 0; i < ArrayLen; i += 2) { diff --git a/drivers/staging/rtl8723au/hal/HalHWImg8723A_RF.c b/drivers/staging/rtl8723au/hal/HalHWImg8723A_RF.c index d63c852aa857..dbf571e8b908 100644 --- a/drivers/staging/rtl8723au/hal/HalHWImg8723A_RF.c +++ b/drivers/staging/rtl8723au/hal/HalHWImg8723A_RF.c @@ -214,13 +214,12 @@ void ODM_ReadAndConfig_RadioA_1T_8723A(struct dm_odm_t *pDM_Odm) u32 hex = 0; u32 i = 0; u8 platform = 0x04; - u8 interfaceValue = pDM_Odm->SupportInterface; u8 board = pDM_Odm->BoardType; u32 ArrayLen = sizeof(Array_RadioA_1T_8723A)/sizeof(u32); u32 *Array = Array_RadioA_1T_8723A; hex += board; - hex += interfaceValue << 8; + hex += ODM_ITRF_USB << 8; hex += platform << 16; hex += 0xFF000000; diff --git a/drivers/staging/rtl8723au/hal/odm.c b/drivers/staging/rtl8723au/hal/odm.c index e1a26302e0fd..11c9a36900e3 100644 --- a/drivers/staging/rtl8723au/hal/odm.c +++ b/drivers/staging/rtl8723au/hal/odm.c @@ -297,9 +297,6 @@ void ODM_CmnInfoInit23a(struct dm_odm_t *pDM_Odm, /* */ switch (CmnInfo) { /* Fixed ODM value. */ - case ODM_CMNINFO_INTERFACE: - pDM_Odm->SupportInterface = (u8)Value; - break; case ODM_CMNINFO_MP_TEST_CHIP: pDM_Odm->bIsMPChip = (u8)Value; break; @@ -443,7 +440,6 @@ void odm_CmnInfoInit_Debug23a(struct dm_odm_t *pDM_Odm) { ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("odm_CmnInfoInit_Debug23a ==>\n")); ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("SupportAbility = 0x%x\n", pDM_Odm->SupportAbility)); - ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("SupportInterface =%d\n", pDM_Odm->SupportInterface)); ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("SupportICType = 0x%x\n", pDM_Odm->SupportICType)); ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("CutVersion =%d\n", pDM_Odm->CutVersion)); ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("FabVersion =%d\n", pDM_Odm->FabVersion)); diff --git a/drivers/staging/rtl8723au/hal/odm_HWConfig.c b/drivers/staging/rtl8723au/hal/odm_HWConfig.c index 33aafa01f900..7b9799e3dbda 100644 --- a/drivers/staging/rtl8723au/hal/odm_HWConfig.c +++ b/drivers/staging/rtl8723au/hal/odm_HWConfig.c @@ -33,24 +33,23 @@ static s32 odm_SignalScaleMapping_92CSeries(struct dm_odm_t *pDM_Odm, s32 CurrSi { s32 RetSig = 0; - if ((pDM_Odm->SupportInterface == ODM_ITRF_USB) || (pDM_Odm->SupportInterface == ODM_ITRF_SDIO)) { - if (CurrSig >= 51 && CurrSig <= 100) - RetSig = 100; - else if (CurrSig >= 41 && CurrSig <= 50) - RetSig = 80 + ((CurrSig - 40)*2); - else if (CurrSig >= 31 && CurrSig <= 40) - RetSig = 66 + (CurrSig - 30); - else if (CurrSig >= 21 && CurrSig <= 30) - RetSig = 54 + (CurrSig - 20); - else if (CurrSig >= 10 && CurrSig <= 20) - RetSig = 42 + (((CurrSig - 10) * 2) / 3); - else if (CurrSig >= 5 && CurrSig <= 9) - RetSig = 22 + (((CurrSig - 5) * 3) / 2); - else if (CurrSig >= 1 && CurrSig <= 4) - RetSig = 6 + (((CurrSig - 1) * 3) / 2); - else - RetSig = CurrSig; - } + if (CurrSig >= 51 && CurrSig <= 100) + RetSig = 100; + else if (CurrSig >= 41 && CurrSig <= 50) + RetSig = 80 + ((CurrSig - 40)*2); + else if (CurrSig >= 31 && CurrSig <= 40) + RetSig = 66 + (CurrSig - 30); + else if (CurrSig >= 21 && CurrSig <= 30) + RetSig = 54 + (CurrSig - 20); + else if (CurrSig >= 10 && CurrSig <= 20) + RetSig = 42 + (((CurrSig - 10) * 2) / 3); + else if (CurrSig >= 5 && CurrSig <= 9) + RetSig = 22 + (((CurrSig - 5) * 3) / 2); + else if (CurrSig >= 1 && CurrSig <= 4) + RetSig = 6 + (((CurrSig - 1) * 3) / 2); + else + RetSig = CurrSig; + return RetSig; } diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_dm.c b/drivers/staging/rtl8723au/hal/rtl8723a_dm.c index e44d2b478c12..a341b1b4770d 100644 --- a/drivers/staging/rtl8723au/hal/rtl8723a_dm.c +++ b/drivers/staging/rtl8723au/hal/rtl8723a_dm.c @@ -94,7 +94,6 @@ void rtl8723a_init_dm_priv(struct rtw_adapter *Adapter) memset(pDM_Odm, 0, sizeof(*pDM_Odm)); pDM_Odm->Adapter = Adapter; - ODM_CmnInfoInit23a(pDM_Odm, ODM_CMNINFO_INTERFACE, RTW_USB);/* RTL871X_HCI_TYPE */ ODM_CmnInfoInit23a(pDM_Odm, ODM_CMNINFO_IC_TYPE, ODM_RTL8723A); diff --git a/drivers/staging/rtl8723au/include/hal_intf.h b/drivers/staging/rtl8723au/include/hal_intf.h index 404acb52352d..b924d47fcfbc 100644 --- a/drivers/staging/rtl8723au/include/hal_intf.h +++ b/drivers/staging/rtl8723au/include/hal_intf.h @@ -18,13 +18,6 @@ #include #include -enum RTL871X_HCI_TYPE { - RTW_PCIE = BIT(0), - RTW_USB = BIT(1), - RTW_SDIO = BIT(2), - RTW_GSPI = BIT(3), -}; - enum _CHIP_TYPE { NULL_CHIP_TYPE, RTL8712_8188S_8191S_8192S, diff --git a/drivers/staging/rtl8723au/include/odm.h b/drivers/staging/rtl8723au/include/odm.h index 1c1775b8f0a9..fce9358d090e 100644 --- a/drivers/staging/rtl8723au/include/odm.h +++ b/drivers/staging/rtl8723au/include/odm.h @@ -298,8 +298,7 @@ enum odm_cmninfo { /* Fixed value: */ /* */ - ODM_CMNINFO_INTERFACE = 1, /* enum odm_interface_def */ - ODM_CMNINFO_MP_TEST_CHIP, + ODM_CMNINFO_MP_TEST_CHIP = 2, ODM_CMNINFO_IC_TYPE, /* enum odm_ic_type_def */ ODM_CMNINFO_CUT_VER, /* enum odm_cut_version */ ODM_CMNINFO_FAB_VER, /* enum odm_fab_version */ @@ -608,8 +607,6 @@ struct dm_odm_t { /* HOOK BEFORE REG INIT----------- */ /* ODM Support Ability DIG/RATR/TX_PWR_TRACK/ KK = 1/2/3/K */ u32 SupportAbility; - /* ODM PCIE/USB/SDIO/GSPI = 0/1/2/3 */ - u8 SupportInterface; /* ODM composite or independent. Bit oriented/ 92C+92D+ .... or any other type = 1/2/3/... */ u32 SupportICType; /* Cut Version TestChip/A-cut/B-cut... = 0/1/2/3/... */ -- GitLab From 8d8a61c4b209c26b4e683f9daab1ebb7b97e8e9f Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Mon, 2 Mar 2015 15:24:53 -0500 Subject: [PATCH 03007/11651] staging: rtl8723au: Remove write-only variable ControlChannel Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/hal/odm.c | 9 --------- drivers/staging/rtl8723au/include/odm.h | 1 - 2 files changed, 10 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/odm.c b/drivers/staging/rtl8723au/hal/odm.c index 11c9a36900e3..cb2b7b6d7e45 100644 --- a/drivers/staging/rtl8723au/hal/odm.c +++ b/drivers/staging/rtl8723au/hal/odm.c @@ -416,15 +416,6 @@ static void odm_CommonInfoSelfUpdate(struct hal_data_8723a *pHalData) u8 EntryCnt = 0; u8 i; - if (pHalData->CurrentChannelBW == HT_CHANNEL_WIDTH_40) { - if (pHalData->nCur40MhzPrimeSC == 1) - pDM_Odm->ControlChannel = pHalData->CurrentChannel - 2; - else if (pHalData->nCur40MhzPrimeSC == 2) - pDM_Odm->ControlChannel = pHalData->CurrentChannel + 2; - } else { - pDM_Odm->ControlChannel = pHalData->CurrentChannel; - } - for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) { pEntry = pDM_Odm->pODM_StaInfo[i]; if (pEntry) diff --git a/drivers/staging/rtl8723au/include/odm.h b/drivers/staging/rtl8723au/include/odm.h index fce9358d090e..586ef005bb88 100644 --- a/drivers/staging/rtl8723au/include/odm.h +++ b/drivers/staging/rtl8723au/include/odm.h @@ -598,7 +598,6 @@ struct dm_odm_t { /* ODM HANDLE, DRIVER NEEDS NOT TO HOOK------ */ bool bCckHighPower; u8 RFPathRxEnable; /* ODM_CMNINFO_RFPATH_ENABLE */ - u8 ControlChannel; /* ODM HANDLE, DRIVER NEEDS NOT TO HOOK------ */ /* 1 COMMON INFORMATION */ -- GitLab From 8bf591e5c17c863dd7b290c31e6330612e899a74 Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Mon, 2 Mar 2015 15:24:54 -0500 Subject: [PATCH 03008/11651] staging: rtl8723au: Remove unused Funai TV hack Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/hal/odm.c | 8 -------- drivers/staging/rtl8723au/hal/rtl8723a_dm.c | 1 - drivers/staging/rtl8723au/include/odm.h | 2 -- 3 files changed, 11 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/odm.c b/drivers/staging/rtl8723au/hal/odm.c index cb2b7b6d7e45..d8f20953cb93 100644 --- a/drivers/staging/rtl8723au/hal/odm.c +++ b/drivers/staging/rtl8723au/hal/odm.c @@ -321,9 +321,6 @@ void ODM_CmnInfoInit23a(struct dm_odm_t *pDM_Odm, case ODM_CMNINFO_EXT_TRSW: pDM_Odm->ExtTRSW = (u8)Value; break; - case ODM_CMNINFO_PATCH_ID: - pDM_Odm->PatchID = (u8)Value; - break; case ODM_CMNINFO_BINHCT_TEST: pDM_Odm->bInHctTest = (bool)Value; break; @@ -438,7 +435,6 @@ void odm_CmnInfoInit_Debug23a(struct dm_odm_t *pDM_Odm) ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("ExtLNA =%d\n", pDM_Odm->ExtLNA)); ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("ExtPA =%d\n", pDM_Odm->ExtPA)); ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("ExtTRSW =%d\n", pDM_Odm->ExtTRSW)); - ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("PatchID =%d\n", pDM_Odm->PatchID)); ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("bInHctTest =%d\n", pDM_Odm->bInHctTest)); ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("bWIFITest =%d\n", pDM_Odm->bWIFITest)); ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("bDualMacSmartConcurrent =%d\n", pDM_Odm->bDualMacSmartConcurrent)); @@ -896,10 +892,6 @@ void ODM_RF_Saving23a(struct dm_odm_t *pDM_Odm, u8 bForceInNormal) struct dynamic_pwr_sav *pDM_PSTable = &pDM_Odm->DM_PSTable; u8 Rssi_Up_bound = 30; u8 Rssi_Low_bound = 25; - if (pDM_Odm->PatchID == 40) { /* RT_CID_819x_FUNAI_TV */ - Rssi_Up_bound = 50; - Rssi_Low_bound = 45; - } if (pDM_PSTable->initialize == 0) { pDM_PSTable->Reg874 = (ODM_GetBBReg(pDM_Odm, 0x874, bMaskDWord)&0x1CC000)>>14; diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_dm.c b/drivers/staging/rtl8723au/hal/rtl8723a_dm.c index a341b1b4770d..1e831f2d1caf 100644 --- a/drivers/staging/rtl8723au/hal/rtl8723a_dm.c +++ b/drivers/staging/rtl8723au/hal/rtl8723a_dm.c @@ -117,7 +117,6 @@ void rtl8723a_init_dm_priv(struct rtw_adapter *Adapter) ODM_CmnInfoInit23a(pDM_Odm, ODM_CMNINFO_EXT_LNA, true); ODM_CmnInfoInit23a(pDM_Odm, ODM_CMNINFO_EXT_PA, true); } - ODM_CmnInfoInit23a(pDM_Odm, ODM_CMNINFO_PATCH_ID, pHalData->CustomerID); ODM_CmnInfoInit23a(pDM_Odm, ODM_CMNINFO_BWIFI_TEST, Adapter->registrypriv.wifi_spec); } diff --git a/drivers/staging/rtl8723au/include/odm.h b/drivers/staging/rtl8723au/include/odm.h index 586ef005bb88..3a65195502d8 100644 --- a/drivers/staging/rtl8723au/include/odm.h +++ b/drivers/staging/rtl8723au/include/odm.h @@ -306,7 +306,6 @@ enum odm_cmninfo { ODM_CMNINFO_EXT_LNA, /* true */ ODM_CMNINFO_EXT_PA, ODM_CMNINFO_EXT_TRSW, - ODM_CMNINFO_PATCH_ID, /* CUSTOMER ID */ ODM_CMNINFO_BINHCT_TEST, ODM_CMNINFO_BWIFI_TEST, ODM_CMNINFO_SMART_CONCURRENT, @@ -620,7 +619,6 @@ struct dm_odm_t { u8 ExtPA; /* with external TRSW NO/Yes = 0/1 */ u8 ExtTRSW; - u8 PatchID; /* Customer ID */ bool bInHctTest; bool bWIFITest; -- GitLab From 761b6031a4d181729a0916fae1c36f4ecd1ac13a Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Mon, 2 Mar 2015 15:24:55 -0500 Subject: [PATCH 03009/11651] staging: rtl8723au: Remove unused struct odm_fat_t Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/include/odm.h | 28 ------------------------- 1 file changed, 28 deletions(-) diff --git a/drivers/staging/rtl8723au/include/odm.h b/drivers/staging/rtl8723au/include/odm.h index 3a65195502d8..3f93b3dee5bd 100644 --- a/drivers/staging/rtl8723au/include/odm.h +++ b/drivers/staging/rtl8723au/include/odm.h @@ -548,33 +548,6 @@ struct odm_rf_cal_t { u8 bDPPathBOK; }; -/* ODM Dynamic common info value definition */ -struct odm_fat_t { - u8 Bssid[6]; - u8 antsel_rx_keep_0; - u8 antsel_rx_keep_1; - u8 antsel_rx_keep_2; - u32 antSumRSSI[7]; - u32 antRSSIcnt[7]; - u32 antAveRSSI[7]; - u8 FAT_State; - u32 TrainIdx; - u8 antsel_a[ODM_ASSOCIATE_ENTRY_NUM]; - u8 antsel_b[ODM_ASSOCIATE_ENTRY_NUM]; - u8 antsel_c[ODM_ASSOCIATE_ENTRY_NUM]; - u32 MainAnt_Sum[ODM_ASSOCIATE_ENTRY_NUM]; - u32 AuxAnt_Sum[ODM_ASSOCIATE_ENTRY_NUM]; - u32 MainAnt_Cnt[ODM_ASSOCIATE_ENTRY_NUM]; - u32 AuxAnt_Cnt[ODM_ASSOCIATE_ENTRY_NUM]; - u8 RxIdleAnt; - bool bBecomeLinked; -}; - -enum fat_state { - FAT_NORMAL_STATE = 0, - FAT_TRAINING_STATE = 1, -}; - enum ant_dif_type { NO_ANTDIV = 0xFF, CG_TRX_HW_ANTDIV = 0x01, @@ -683,7 +656,6 @@ struct dm_odm_t { /* */ /* ODM Structure */ /* */ - struct odm_fat_t DM_FatTable; struct dig_t DM_DigTable; struct dynamic_pwr_sav DM_PSTable; struct pri_cca DM_PriCCA; -- GitLab From bb1ede84dfff512b5ac4fc8e45b8e5e8ed4d8d12 Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Mon, 2 Mar 2015 15:24:56 -0500 Subject: [PATCH 03010/11651] staging: rtl8723au: Remove unused struct pri_cca Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/include/odm.h | 9 --------- 1 file changed, 9 deletions(-) diff --git a/drivers/staging/rtl8723au/include/odm.h b/drivers/staging/rtl8723au/include/odm.h index 3f93b3dee5bd..3a68774b33b6 100644 --- a/drivers/staging/rtl8723au/include/odm.h +++ b/drivers/staging/rtl8723au/include/odm.h @@ -158,14 +158,6 @@ struct false_alarm_stats { u32 Cnt_BW_LSC; /* Gary */ }; -struct pri_cca { - u8 PriCCA_flag; - u8 intf_flag; - u8 intf_type; - u8 DupRTS_flag; - u8 Monitor_flag; -}; - struct rx_hp { u8 RXHP_flag; u8 PSD_func_trigger; @@ -658,7 +650,6 @@ struct dm_odm_t { /* */ struct dig_t DM_DigTable; struct dynamic_pwr_sav DM_PSTable; - struct pri_cca DM_PriCCA; struct rx_hp DM_RXHP_Table; struct false_alarm_stats FalseAlmCnt; struct false_alarm_stats FlaseAlmCntBuddyAdapter; -- GitLab From dd42f95cf041b99c440382acc18f9312282fc50f Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Mon, 2 Mar 2015 15:24:57 -0500 Subject: [PATCH 03011/11651] staging: rtl8723au: Remove write only bIsCurRDLState Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/hal/odm.c | 1 - drivers/staging/rtl8723au/include/odm.h | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/odm.c b/drivers/staging/rtl8723au/hal/odm.c index d8f20953cb93..d3d4efc6fe07 100644 --- a/drivers/staging/rtl8723au/hal/odm.c +++ b/drivers/staging/rtl8723au/hal/odm.c @@ -1271,7 +1271,6 @@ static void ODM_EdcaTurboInit23a(struct dm_odm_t *pDM_Odm) struct rtw_adapter *Adapter = pDM_Odm->Adapter; pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA = false; - pDM_Odm->DM_EDCA_Table.bIsCurRDLState = false; Adapter->recvpriv.bIsAnyNonBEPkts = false; ODM_RT_TRACE(pDM_Odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD, ("Orginial VO PARAM: 0x%x\n", ODM_Read4Byte(pDM_Odm, ODM_EDCA_VO_PARAM))); diff --git a/drivers/staging/rtl8723au/include/odm.h b/drivers/staging/rtl8723au/include/odm.h index 3a68774b33b6..0d1285c1bff0 100644 --- a/drivers/staging/rtl8723au/include/odm.h +++ b/drivers/staging/rtl8723au/include/odm.h @@ -219,7 +219,6 @@ struct sw_ant_sw { struct edca_turbo { bool bCurrentTurboEDCA; - bool bIsCurRDLState; u32 prv_traffic_idx; /* edca turbo */ }; -- GitLab From 1a5767e882ae1be5e40ce8dd338761a2f72761dd Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Mon, 2 Mar 2015 15:24:58 -0500 Subject: [PATCH 03012/11651] staging: rtl8723au: ODM_TXPowerTrackingCheck23a(): Remove no-op function Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/hal/odm.c | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/odm.c b/drivers/staging/rtl8723au/hal/odm.c index d3d4efc6fe07..b9f09d9183bf 100644 --- a/drivers/staging/rtl8723au/hal/odm.c +++ b/drivers/staging/rtl8723au/hal/odm.c @@ -196,16 +196,12 @@ void odm_DynamicTxPower23a(struct dm_odm_t *pDM_Odm); void odm_RefreshRateAdaptiveMask23a(struct dm_odm_t *pDM_Odm); -void ODM_TXPowerTrackingCheck23a(struct dm_odm_t *pDM_Odm); - void odm_RateAdaptiveMaskInit23a(struct dm_odm_t *pDM_Odm); void odm_TXPowerTrackingThermalMeterInit23a(struct dm_odm_t *pDM_Odm); void odm_TXPowerTrackingInit23a(struct dm_odm_t *pDM_Odm); -void odm_TXPowerTrackingCheckCE23a(struct dm_odm_t *pDM_Odm); - static void odm_EdcaTurboCheck23a(struct dm_odm_t *pDM_Odm); static void ODM_EdcaTurboInit23a(struct dm_odm_t *pDM_Odm); @@ -278,7 +274,6 @@ void ODM_DMWatchdog23a(struct rtw_adapter *adapter) odm_DynamicBBPowerSaving23a(pDM_Odm); - ODM_TXPowerTrackingCheck23a(pDM_Odm); odm_EdcaTurboCheck23a(pDM_Odm); } @@ -1249,21 +1244,6 @@ void odm_TXPowerTrackingThermalMeterInit23a(struct dm_odm_t *pDM_Odm) pDM_Odm->RFCalibrateInfo.TxPowerTrackControl = true; } -void ODM_TXPowerTrackingCheck23a(struct dm_odm_t *pDM_Odm) -{ - /* For AP/ADSL use struct rtl8723a_priv * */ - /* For CE/NIC use struct rtw_adapter * */ - - /* 2011/09/29 MH In HW integration first stage, we provide 4 different handle to operate */ - /* at the same time. In the stage2/3, we need to prive universal interface and merge all */ - /* HW dynamic mechanism. */ - odm_TXPowerTrackingCheckCE23a(pDM_Odm); -} - -void odm_TXPowerTrackingCheckCE23a(struct dm_odm_t *pDM_Odm) -{ -} - /* EDCA Turbo */ static void ODM_EdcaTurboInit23a(struct dm_odm_t *pDM_Odm) { -- GitLab From 04b7466fa514283438c0adbbca06f799b70c0d5c Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Mon, 2 Mar 2015 15:24:59 -0500 Subject: [PATCH 03013/11651] staging: rtl8723au: Clean up odm_RSSIMonitorCheck() Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/hal/odm.c | 41 +++++++++++++++-------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/odm.c b/drivers/staging/rtl8723au/hal/odm.c index b9f09d9183bf..bfbb1a410798 100644 --- a/drivers/staging/rtl8723au/hal/odm.c +++ b/drivers/staging/rtl8723au/hal/odm.c @@ -191,7 +191,7 @@ void odm_DynamicBBPowerSaving23a(struct dm_odm_t *pDM_Odm); void odm_DynamicTxPower23aInit(struct dm_odm_t *pDM_Odm); -void odm_RSSIMonitorCheck23a(struct dm_odm_t *pDM_Odm); +static void odm_RSSIMonitorCheck(struct dm_odm_t *pDM_Odm); void odm_DynamicTxPower23a(struct dm_odm_t *pDM_Odm); void odm_RefreshRateAdaptiveMask23a(struct dm_odm_t *pDM_Odm); @@ -251,7 +251,7 @@ void ODM_DMWatchdog23a(struct rtw_adapter *adapter) odm_CmnInfoUpdate_Debug23a(pDM_Odm); odm_CommonInfoSelfUpdate(pHalData); odm_FalseAlarmCounterStatistics23a(pDM_Odm); - odm_RSSIMonitorCheck23a(pDM_Odm); + odm_RSSIMonitorCheck(pDM_Odm); /* 8723A or 8189ES platform */ /* NeilChen--2012--08--24-- */ @@ -1170,14 +1170,15 @@ FindMinimumRSSI( pdmpriv->MinUndecoratedPWDBForDM = pdmpriv->EntryMinUndecoratedSmoothedPWDB; } -void odm_RSSIMonitorCheck23a(struct dm_odm_t *pDM_Odm) +static void odm_RSSIMonitorCheck(struct dm_odm_t *pDM_Odm) { struct rtw_adapter *Adapter = pDM_Odm->Adapter; struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); struct dm_priv *pdmpriv = &pHalData->dmpriv; - int i; - int tmpEntryMaxPWDB = 0, tmpEntryMinPWDB = 0xff; + int i; + int MaxDB = 0, MinDB = 0xff; u8 sta_cnt = 0; + u32 tmpdb; u32 PWDB_rssi[NUM_STA] = {0};/* 0~15]:MACID, [16~31]:PWDB_rssi */ struct sta_info *psta; @@ -1187,36 +1188,36 @@ void odm_RSSIMonitorCheck23a(struct dm_odm_t *pDM_Odm) for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) { psta = pDM_Odm->pODM_StaInfo[i]; if (psta) { - if (psta->rssi_stat.UndecoratedSmoothedPWDB < tmpEntryMinPWDB) - tmpEntryMinPWDB = psta->rssi_stat.UndecoratedSmoothedPWDB; + if (psta->rssi_stat.UndecoratedSmoothedPWDB < MinDB) + MinDB = psta->rssi_stat.UndecoratedSmoothedPWDB; - if (psta->rssi_stat.UndecoratedSmoothedPWDB > tmpEntryMaxPWDB) - tmpEntryMaxPWDB = psta->rssi_stat.UndecoratedSmoothedPWDB; + if (psta->rssi_stat.UndecoratedSmoothedPWDB > MaxDB) + MaxDB = psta->rssi_stat.UndecoratedSmoothedPWDB; - if (psta->rssi_stat.UndecoratedSmoothedPWDB != (-1)) - PWDB_rssi[sta_cnt++] = (psta->mac_id | (psta->rssi_stat.UndecoratedSmoothedPWDB<<16)); + if (psta->rssi_stat.UndecoratedSmoothedPWDB != -1) { + tmpdb = psta->rssi_stat.UndecoratedSmoothedPWDB; + PWDB_rssi[sta_cnt++] = psta->mac_id | + (tmpdb << 16); + } } } for (i = 0; i < sta_cnt; i++) { - if (PWDB_rssi[i] != (0)) { + if (PWDB_rssi[i] != (0)) rtl8723a_set_rssi_cmd(Adapter, (u8 *)&PWDB_rssi[i]); - } } - if (tmpEntryMaxPWDB != 0) /* If associated entry is found */ - pdmpriv->EntryMaxUndecoratedSmoothedPWDB = tmpEntryMaxPWDB; - else - pdmpriv->EntryMaxUndecoratedSmoothedPWDB = 0; + pdmpriv->EntryMaxUndecoratedSmoothedPWDB = MaxDB; - if (tmpEntryMinPWDB != 0xff) /* If associated entry is found */ - pdmpriv->EntryMinUndecoratedSmoothedPWDB = tmpEntryMinPWDB; + if (MinDB != 0xff) /* If associated entry is found */ + pdmpriv->EntryMinUndecoratedSmoothedPWDB = MinDB; else pdmpriv->EntryMinUndecoratedSmoothedPWDB = 0; FindMinimumRSSI(Adapter);/* get pdmpriv->MinUndecoratedPWDBForDM */ - ODM_CmnInfoUpdate23a(&pHalData->odmpriv, ODM_CMNINFO_RSSI_MIN, pdmpriv->MinUndecoratedPWDBForDM); + ODM_CmnInfoUpdate23a(&pHalData->odmpriv, ODM_CMNINFO_RSSI_MIN, + pdmpriv->MinUndecoratedPWDBForDM); } /* endif */ -- GitLab From 0305d27d9e0d8f90697d3d8cc2f3aeedeaab44fd Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Mon, 2 Mar 2015 15:25:00 -0500 Subject: [PATCH 03014/11651] staging: rtl8723au: Clean up FindMinimumRSSI() Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/hal/odm.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/odm.c b/drivers/staging/rtl8723au/hal/odm.c index bfbb1a410798..5269c39a1f26 100644 --- a/drivers/staging/rtl8723au/hal/odm.c +++ b/drivers/staging/rtl8723au/hal/odm.c @@ -1153,9 +1153,7 @@ void odm_DynamicTxPower23aInit(struct dm_odm_t *pDM_Odm) } static void -FindMinimumRSSI( - struct rtw_adapter *pAdapter - ) +FindMinimumRSSI(struct rtw_adapter *pAdapter) { struct hal_data_8723a *pHalData = GET_HAL_DATA(pAdapter); struct dm_priv *pdmpriv = &pHalData->dmpriv; @@ -1163,11 +1161,11 @@ FindMinimumRSSI( /* 1 1.Determine the minimum RSSI */ - if ((!pDM_Odm->bLinked) && - (pdmpriv->EntryMinUndecoratedSmoothedPWDB == 0)) + if (!pDM_Odm->bLinked && !pdmpriv->EntryMinUndecoratedSmoothedPWDB) pdmpriv->MinUndecoratedPWDBForDM = 0; else - pdmpriv->MinUndecoratedPWDBForDM = pdmpriv->EntryMinUndecoratedSmoothedPWDB; + pdmpriv->MinUndecoratedPWDBForDM = + pdmpriv->EntryMinUndecoratedSmoothedPWDB; } static void odm_RSSIMonitorCheck(struct dm_odm_t *pDM_Odm) -- GitLab From b58298eee28f055f862d1dc122bf34a1e1ab17ca Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Mon, 2 Mar 2015 15:25:01 -0500 Subject: [PATCH 03015/11651] staging: rtl8723au: Clean up odm_RefreshRateAdaptiveMask() Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/hal/odm.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/odm.c b/drivers/staging/rtl8723au/hal/odm.c index 5269c39a1f26..e4500e913483 100644 --- a/drivers/staging/rtl8723au/hal/odm.c +++ b/drivers/staging/rtl8723au/hal/odm.c @@ -194,7 +194,7 @@ void odm_DynamicTxPower23aInit(struct dm_odm_t *pDM_Odm); static void odm_RSSIMonitorCheck(struct dm_odm_t *pDM_Odm); void odm_DynamicTxPower23a(struct dm_odm_t *pDM_Odm); -void odm_RefreshRateAdaptiveMask23a(struct dm_odm_t *pDM_Odm); +static void odm_RefreshRateAdaptiveMask(struct dm_odm_t *pDM_Odm); void odm_RateAdaptiveMaskInit23a(struct dm_odm_t *pDM_Odm); @@ -270,7 +270,7 @@ void ODM_DMWatchdog23a(struct rtw_adapter *adapter) if (pwrctrlpriv->bpower_saving) return; - odm_RefreshRateAdaptiveMask23a(pDM_Odm); + odm_RefreshRateAdaptiveMask(pDM_Odm); odm_DynamicBBPowerSaving23a(pDM_Odm); @@ -1045,7 +1045,7 @@ u32 ODM_Get_Rate_Bitmap23a(struct hal_data_8723a *pHalData, u32 macid, } /*----------------------------------------------------------------------------- - * Function: odm_RefreshRateAdaptiveMask23a() + * Function: odm_RefreshRateAdaptiveMask() * * Overview: Update rate table mask according to rssi * @@ -1060,10 +1060,11 @@ u32 ODM_Get_Rate_Bitmap23a(struct hal_data_8723a *pHalData, u32 macid, *05/27/2009 hpfan Create Version 0. * *---------------------------------------------------------------------------*/ -void odm_RefreshRateAdaptiveMask23a(struct dm_odm_t *pDM_Odm) +static void odm_RefreshRateAdaptiveMask(struct dm_odm_t *pDM_Odm) { + struct rtw_adapter *pAdapter = pDM_Odm->Adapter; + u32 smoothed; u8 i; - struct rtw_adapter *pAdapter = pDM_Odm->Adapter; if (pAdapter->bDriverStopped) { ODM_RT_TRACE(pDM_Odm, ODM_COMP_RA_MASK, ODM_DBG_TRACE, @@ -1075,17 +1076,19 @@ void odm_RefreshRateAdaptiveMask23a(struct dm_odm_t *pDM_Odm) for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) { struct sta_info *pstat = pDM_Odm->pODM_StaInfo[i]; if (pstat) { - if (ODM_RAStateCheck23a(pDM_Odm, pstat->rssi_stat.UndecoratedSmoothedPWDB, false, &pstat->rssi_level)) { - ODM_RT_TRACE(pDM_Odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, + smoothed = pstat->rssi_stat.UndecoratedSmoothedPWDB; + if (ODM_RAStateCheck23a(pDM_Odm, smoothed, false, + &pstat->rssi_level)) { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_RA_MASK, + ODM_DBG_LOUD, ("RSSI:%d, RSSI_LEVEL:%d\n", - pstat->rssi_stat.UndecoratedSmoothedPWDB, - pstat->rssi_level)); - rtw_hal_update_ra_mask23a(pstat, pstat->rssi_level); + smoothed, + pstat->rssi_level)); + rtw_hal_update_ra_mask23a(pstat, + pstat->rssi_level); } - } } - } /* Return Value: bool */ -- GitLab From c335da572652e984ca7f29a1384f7c3c85fb3a5c Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Mon, 2 Mar 2015 15:25:02 -0500 Subject: [PATCH 03016/11651] staging: rtl8723au: ODM_Write_DIG23A(): Cosmetic cleanups Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/hal/odm.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/odm.c b/drivers/staging/rtl8723au/hal/odm.c index e4500e913483..69072c09e09b 100644 --- a/drivers/staging/rtl8723au/hal/odm.c +++ b/drivers/staging/rtl8723au/hal/odm.c @@ -445,18 +445,19 @@ void odm_CmnInfoUpdate_Debug23a(struct dm_odm_t *pDM_Odm) ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("RSSI_Min =%d\n", pDM_Odm->RSSI_Min)); } -void ODM_Write_DIG23a(struct dm_odm_t *pDM_Odm, - u8 CurrentIGI - ) +void ODM_Write_DIG23a(struct dm_odm_t *pDM_Odm, u8 CurrentIGI) { struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable; - ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("ODM_REG(IGI_A, pDM_Odm) = 0x%x, ODM_BIT(IGI, pDM_Odm) = 0x%x \n", - ODM_REG(IGI_A, pDM_Odm), ODM_BIT(IGI, pDM_Odm))); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, + ("ODM_REG(IGI_A, pDM_Odm) = 0x%x, ODM_BIT(IGI, pDM_Odm) = 0x%x \n", + ODM_REG(IGI_A, pDM_Odm), ODM_BIT(IGI, pDM_Odm))); if (pDM_DigTable->CurIGValue != CurrentIGI) { - ODM_SetBBReg(pDM_Odm, ODM_REG(IGI_A, pDM_Odm), ODM_BIT(IGI, pDM_Odm), CurrentIGI); - ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("CurrentIGI(0x%02x). \n", CurrentIGI)); + ODM_SetBBReg(pDM_Odm, ODM_REG(IGI_A, pDM_Odm), + ODM_BIT(IGI, pDM_Odm), CurrentIGI); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, + ("CurrentIGI(0x%02x). \n", CurrentIGI)); pDM_DigTable->CurIGValue = CurrentIGI; } ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, -- GitLab From fe6e0197ba7a5820419e68cff3879786388e8971 Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Mon, 2 Mar 2015 15:25:03 -0500 Subject: [PATCH 03017/11651] staging: rtl8723au: odm.c: Break some lines down to 80 characters Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/hal/odm.c | 184 ++++++++++++++++++---------- 1 file changed, 117 insertions(+), 67 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/odm.c b/drivers/staging/rtl8723au/hal/odm.c index 69072c09e09b..8d4266100ff0 100644 --- a/drivers/staging/rtl8723au/hal/odm.c +++ b/drivers/staging/rtl8723au/hal/odm.c @@ -480,11 +480,10 @@ void odm_DIG23abyRSSI_LPS(struct dm_odm_t *pDM_Odm) CurrentIGI = CurrentIGI+RSSI_OFFSET_DIG; bFwCurrentInPSMode = pAdapter->pwrctrlpriv.bFwCurrentInPSMode; - /* ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG_LPS, ODM_DBG_LOUD, ("odm_DIG23a() ==>\n")); */ - /* Using FW PS mode to make IGI */ if (bFwCurrentInPSMode) { - ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("---Neil---odm_DIG23a is in LPS mode\n")); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, + ("---Neil---odm_DIG23a is in LPS mode\n")); /* Adjust by FA in LPS MODE */ if (pFalseAlmCnt->Cnt_all > DM_DIG_FA_TH2_LPS) CurrentIGI = CurrentIGI+2; @@ -510,15 +509,16 @@ void odm_DIG23abyRSSI_LPS(struct dm_odm_t *pDM_Odm) else if (CurrentIGI < RSSI_Lower) CurrentIGI = RSSI_Lower; - ODM_Write_DIG23a(pDM_Odm, CurrentIGI);/* ODM_Write_DIG23a(pDM_Odm, pDM_DigTable->CurIGValue); */ - + ODM_Write_DIG23a(pDM_Odm, CurrentIGI); } void odm_DIG23aInit(struct dm_odm_t *pDM_Odm) { struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable; - pDM_DigTable->CurIGValue = (u8) ODM_GetBBReg(pDM_Odm, ODM_REG(IGI_A, pDM_Odm), ODM_BIT(IGI, pDM_Odm)); + pDM_DigTable->CurIGValue = (u8) ODM_GetBBReg(pDM_Odm, + ODM_REG(IGI_A, pDM_Odm), + ODM_BIT(IGI, pDM_Odm)); pDM_DigTable->RssiLowThresh = DM_DIG_THRESH_LOW; pDM_DigTable->RssiHighThresh = DM_DIG_THRESH_HIGH; pDM_DigTable->FALowThresh = DM_FALSEALARM_THRESH_LOW; @@ -556,19 +556,22 @@ void odm_DIG23a(struct rtw_adapter *adapter) u8 dm_dig_max, dm_dig_min; u8 CurrentIGI = pDM_DigTable->CurIGValue; - ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG23a() ==>\n")); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, + ("odm_DIG23a() ==>\n")); if (adapter->mlmepriv.bScanInProcess) { - ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG23a() Return: In Scan Progress \n")); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, + ("odm_DIG23a() Return: In Scan Progress \n")); return; } DIG_Dynamic_MIN = pDM_DigTable->DIG_Dynamic_MIN_0; FirstConnect = (pDM_Odm->bLinked) && (!pDM_DigTable->bMediaConnect_0); - FirstDisConnect = (!pDM_Odm->bLinked) && (pDM_DigTable->bMediaConnect_0); + FirstDisConnect = (!pDM_Odm->bLinked) && + (pDM_DigTable->bMediaConnect_0); /* 1 Boundary Decision */ if ((pDM_Odm->SupportICType & ODM_RTL8723A) && - ((pDM_Odm->BoardType == ODM_BOARD_HIGHPWR) || pDM_Odm->ExtLNA)) { + (pDM_Odm->BoardType == ODM_BOARD_HIGHPWR || pDM_Odm->ExtLNA)) { dm_dig_max = DM_DIG_MAX_NIC_HP; dm_dig_min = DM_DIG_MIN_NIC_HP; DIG_MaxOfMin = DM_DIG_MAX_AP_HP; @@ -814,9 +817,12 @@ void odm_FalseAlarmCounterStatistics23a(struct dm_odm_t *pDM_Odm) ("Cnt_Crc8_fail =%d, Cnt_Mcs_fail =%d\n", FalseAlmCnt->Cnt_Crc8_fail, FalseAlmCnt->Cnt_Mcs_fail)); - ODM_RT_TRACE(pDM_Odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("Cnt_Cck_fail =%d\n", FalseAlmCnt->Cnt_Cck_fail)); - ODM_RT_TRACE(pDM_Odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("Cnt_Ofdm_fail =%d\n", FalseAlmCnt->Cnt_Ofdm_fail)); - ODM_RT_TRACE(pDM_Odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("Total False Alarm =%d\n", FalseAlmCnt->Cnt_all)); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, + ("Cnt_Cck_fail =%d\n", FalseAlmCnt->Cnt_Cck_fail)); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, + ("Cnt_Ofdm_fail =%d\n", FalseAlmCnt->Cnt_Ofdm_fail)); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, + ("Total False Alarm =%d\n", FalseAlmCnt->Cnt_all)); } /* 3 ============================================================ */ @@ -834,7 +840,7 @@ void odm_CCKPacketDetectionThresh23a(struct dm_odm_t *pDM_Odm) if (pDM_Odm->bLinked) { if (pDM_Odm->RSSI_Min > 25) { CurCCK_CCAThres = 0xcd; - } else if ((pDM_Odm->RSSI_Min <= 25) && (pDM_Odm->RSSI_Min > 10)) { + } else if (pDM_Odm->RSSI_Min <= 25 && pDM_Odm->RSSI_Min > 10) { CurCCK_CCAThres = 0x83; } else { if (FalseAlmCnt->Cnt_Cck_fail > 1000) @@ -857,10 +863,10 @@ void ODM_Write_CCK_CCA_Thres23a(struct dm_odm_t *pDM_Odm, u8 CurCCK_CCAThres) struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable; if (pDM_DigTable->CurCCK_CCAThres != CurCCK_CCAThres) - ODM_Write1Byte(pDM_Odm, ODM_REG(CCK_CCA, pDM_Odm), CurCCK_CCAThres); + ODM_Write1Byte(pDM_Odm, ODM_REG(CCK_CCA, pDM_Odm), + CurCCK_CCAThres); pDM_DigTable->PreCCK_CCAThres = pDM_DigTable->CurCCK_CCAThres; pDM_DigTable->CurCCK_CCAThres = CurCCK_CCAThres; - } /* 3 ============================================================ */ @@ -890,11 +896,14 @@ void ODM_RF_Saving23a(struct dm_odm_t *pDM_Odm, u8 bForceInNormal) u8 Rssi_Low_bound = 25; if (pDM_PSTable->initialize == 0) { - pDM_PSTable->Reg874 = (ODM_GetBBReg(pDM_Odm, 0x874, bMaskDWord)&0x1CC000)>>14; + pDM_PSTable->Reg874 = (ODM_GetBBReg(pDM_Odm, 0x874, + bMaskDWord)&0x1CC000) >> 14; pDM_PSTable->RegC70 = (ODM_GetBBReg(pDM_Odm, 0xc70, bMaskDWord) & BIT(3)) >>3; - pDM_PSTable->Reg85C = (ODM_GetBBReg(pDM_Odm, 0x85c, bMaskDWord)&0xFF000000)>>24; - pDM_PSTable->RegA74 = (ODM_GetBBReg(pDM_Odm, 0xa74, bMaskDWord)&0xF000)>>12; + pDM_PSTable->Reg85C = (ODM_GetBBReg(pDM_Odm, 0x85c, + bMaskDWord)&0xFF000000)>>24; + pDM_PSTable->RegA74 = (ODM_GetBBReg(pDM_Odm, 0xa74, + bMaskDWord)&0xF000)>>12; /* Reg818 = PHY_QueryBBReg(pAdapter, 0x818, bMaskDWord); */ pDM_PSTable->initialize = 1; } @@ -921,26 +930,40 @@ void ODM_RF_Saving23a(struct dm_odm_t *pDM_Odm, u8 bForceInNormal) if (pDM_PSTable->PreRFState != pDM_PSTable->CurRFState) { if (pDM_PSTable->CurRFState == RF_Save) { - /* 8723 RSSI report will be wrong. Set 0x874[5]= 1 when enter BB power saving mode. */ + /* 8723 RSSI report will be wrong. + * Set 0x874[5]= 1 when enter BB power saving mode. */ /* Suggested by SD3 Yu-Nan. 2011.01.20. */ + /* Reg874[5]= 1b'1 */ if (pDM_Odm->SupportICType == ODM_RTL8723A) - ODM_SetBBReg(pDM_Odm, 0x874, BIT(5), 0x1); /* Reg874[5]= 1b'1 */ - ODM_SetBBReg(pDM_Odm, 0x874, 0x1C0000, 0x2); /* Reg874[20:18]= 3'b010 */ - ODM_SetBBReg(pDM_Odm, 0xc70, BIT(3), 0); /* RegC70[3]= 1'b0 */ - ODM_SetBBReg(pDM_Odm, 0x85c, 0xFF000000, 0x63); /* Reg85C[31:24]= 0x63 */ - ODM_SetBBReg(pDM_Odm, 0x874, 0xC000, 0x2); /* Reg874[15:14]= 2'b10 */ - ODM_SetBBReg(pDM_Odm, 0xa74, 0xF000, 0x3); /* RegA75[7:4]= 0x3 */ - ODM_SetBBReg(pDM_Odm, 0x818, BIT(28), 0x0); /* Reg818[28]= 1'b0 */ - ODM_SetBBReg(pDM_Odm, 0x818, BIT(28), 0x1); /* Reg818[28]= 1'b1 */ + ODM_SetBBReg(pDM_Odm, 0x874, BIT(5), 0x1); + /* Reg874[20:18]= 3'b010 */ + ODM_SetBBReg(pDM_Odm, 0x874, 0x1C0000, 0x2); + /* RegC70[3]= 1'b0 */ + ODM_SetBBReg(pDM_Odm, 0xc70, BIT(3), 0); + /* Reg85C[31:24]= 0x63 */ + ODM_SetBBReg(pDM_Odm, 0x85c, 0xFF000000, 0x63); + /* Reg874[15:14]= 2'b10 */ + ODM_SetBBReg(pDM_Odm, 0x874, 0xC000, 0x2); + /* RegA75[7:4]= 0x3 */ + ODM_SetBBReg(pDM_Odm, 0xa74, 0xF000, 0x3); + /* Reg818[28]= 1'b0 */ + ODM_SetBBReg(pDM_Odm, 0x818, BIT(28), 0x0); + /* Reg818[28]= 1'b1 */ + ODM_SetBBReg(pDM_Odm, 0x818, BIT(28), 0x1); } else { - ODM_SetBBReg(pDM_Odm, 0x874, 0x1CC000, pDM_PSTable->Reg874); - ODM_SetBBReg(pDM_Odm, 0xc70, BIT(3), pDM_PSTable->RegC70); - ODM_SetBBReg(pDM_Odm, 0x85c, 0xFF000000, pDM_PSTable->Reg85C); - ODM_SetBBReg(pDM_Odm, 0xa74, 0xF000, pDM_PSTable->RegA74); + ODM_SetBBReg(pDM_Odm, 0x874, 0x1CC000, + pDM_PSTable->Reg874); + ODM_SetBBReg(pDM_Odm, 0xc70, BIT(3), + pDM_PSTable->RegC70); + ODM_SetBBReg(pDM_Odm, 0x85c, 0xFF000000, + pDM_PSTable->Reg85C); + ODM_SetBBReg(pDM_Odm, 0xa74, 0xF000, + pDM_PSTable->RegA74); ODM_SetBBReg(pDM_Odm, 0x818, BIT(28), 0x0); + /* Reg874[5]= 1b'0 */ if (pDM_Odm->SupportICType == ODM_RTL8723A) - ODM_SetBBReg(pDM_Odm, 0x874, BIT(5), 0x0); /* Reg874[5]= 1b'0 */ + ODM_SetBBReg(pDM_Odm, 0x874, BIT(5), 0x0); } pDM_PSTable->PreRFState = pDM_PSTable->CurRFState; } @@ -1038,11 +1061,11 @@ u32 ODM_Get_Rate_Bitmap23a(struct hal_data_8723a *pHalData, u32 macid, break; } - /* printk("%s ==> rssi_level:0x%02x, WirelessMode:0x%02x, rate_bitmap:0x%08x \n", __func__, rssi_level, WirelessMode, rate_bitmap); */ - ODM_RT_TRACE(pDM_Odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, (" ==> rssi_level:0x%02x, WirelessMode:0x%02x, rate_bitmap:0x%08x \n", rssi_level, WirelessMode, rate_bitmap)); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, + (" ==> rssi_level:0x%02x, WirelessMode:0x%02x, rate_bitmap:0x%08x \n", + rssi_level, WirelessMode, rate_bitmap)); return rate_bitmap; - } /*----------------------------------------------------------------------------- @@ -1118,7 +1141,8 @@ bool ODM_RAStateCheck23a(struct dm_odm_t *pDM_Odm, s32 RSSI, bool bForceUpdate, LowRSSIThreshForRA += GoUpGap; break; default: - ODM_RT_ASSERT(pDM_Odm, false, ("wrong rssi level setting %d !", *pRATRState)); + ODM_RT_ASSERT(pDM_Odm, false, ("wrong rssi level setting %d !", + *pRATRState)); break; } @@ -1242,7 +1266,8 @@ void odm_TXPowerTrackingThermalMeterInit23a(struct dm_odm_t *pDM_Odm) pdmpriv->TXPowercount = 0; pdmpriv->bTXPowerTrackingInit = false; pdmpriv->TxPowerTrackControl = true; - MSG_8723A("pdmpriv->TxPowerTrackControl = %d\n", pdmpriv->TxPowerTrackControl); + MSG_8723A("pdmpriv->TxPowerTrackControl = %d\n", + pdmpriv->TxPowerTrackControl); pDM_Odm->RFCalibrateInfo.TxPowerTrackControl = true; } @@ -1256,12 +1281,19 @@ static void ODM_EdcaTurboInit23a(struct dm_odm_t *pDM_Odm) pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA = false; Adapter->recvpriv.bIsAnyNonBEPkts = false; - ODM_RT_TRACE(pDM_Odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD, ("Orginial VO PARAM: 0x%x\n", ODM_Read4Byte(pDM_Odm, ODM_EDCA_VO_PARAM))); - ODM_RT_TRACE(pDM_Odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD, ("Orginial VI PARAM: 0x%x\n", ODM_Read4Byte(pDM_Odm, ODM_EDCA_VI_PARAM))); - ODM_RT_TRACE(pDM_Odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD, ("Orginial BE PARAM: 0x%x\n", ODM_Read4Byte(pDM_Odm, ODM_EDCA_BE_PARAM))); - ODM_RT_TRACE(pDM_Odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD, ("Orginial BK PARAM: 0x%x\n", ODM_Read4Byte(pDM_Odm, ODM_EDCA_BK_PARAM))); - -} /* ODM_InitEdcaTurbo */ + ODM_RT_TRACE(pDM_Odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD, + ("Orginial VO PARAM: 0x%x\n", + ODM_Read4Byte(pDM_Odm, ODM_EDCA_VO_PARAM))); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD, + ("Orginial VI PARAM: 0x%x\n", + ODM_Read4Byte(pDM_Odm, ODM_EDCA_VI_PARAM))); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD, + ("Orginial BE PARAM: 0x%x\n", + ODM_Read4Byte(pDM_Odm, ODM_EDCA_BE_PARAM))); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD, + ("Orginial BK PARAM: 0x%x\n", + ODM_Read4Byte(pDM_Odm, ODM_EDCA_BK_PARAM))); +} static void odm_EdcaTurboCheck23a(struct dm_odm_t *pDM_Odm) { @@ -1280,9 +1312,12 @@ static void odm_EdcaTurboCheck23a(struct dm_odm_t *pDM_Odm) /* For AP/ADSL use struct rtl8723a_priv * */ /* For CE/NIC use struct rtw_adapter * */ - /* 2011/09/29 MH In HW integration first stage, we provide 4 different handle to operate */ - /* at the same time. In the stage2/3, we need to prive universal interface and merge all */ - /* HW dynamic mechanism. */ + /* + * 2011/09/29 MH In HW integration first stage, we provide 4 + * different handle to operate at the same time. In the stage2/3, + * we need to prive universal interface and merge all HW dynamic + * mechanism. + */ if ((pregpriv->wifi_spec == 1))/* (pmlmeinfo->HT_enable == 0)) */ goto dm_CheckEdcaTurbo_EXIT; @@ -1362,14 +1397,13 @@ u32 GetPSDData(struct dm_odm_t *pDM_Odm, unsigned int point, u8 initial_gain_psd /* Read PSD report, Reg8B4[15:0] */ psd_report = ODM_GetBBReg(pDM_Odm, 0x8B4, bMaskDWord) & 0x0000FFFF; - psd_report = (u32)(ConvertTo_dB23a(psd_report))+(u32)(initial_gain_psd-0x1c); + psd_report = (u32)(ConvertTo_dB23a(psd_report)) + + (u32)(initial_gain_psd-0x1c); return psd_report; } -u32 -ConvertTo_dB23a( - u32 Value) +u32 ConvertTo_dB23a(u32 Value) { u8 i; u8 j; @@ -1397,7 +1431,8 @@ ConvertTo_dB23a( /* */ /* Description: */ -/*Set Single/Dual Antenna default setting for products that do not do detection in advance. */ +/* Set Single/Dual Antenna default setting for products that do not + * do detection in advance. */ /* */ /* Added by Joseph, 2012.03.22 */ /* */ @@ -1461,9 +1496,11 @@ bool ODM_SingleDualAntennaDetection(struct dm_odm_t *pDM_Odm, u8 mode) return bResult; /* 1 Backup Current RF/BB Settings */ - CurrentChannel = ODM_GetRFReg(pDM_Odm, RF_PATH_A, ODM_CHANNEL, bRFRegOffsetMask); + CurrentChannel = ODM_GetRFReg(pDM_Odm, RF_PATH_A, ODM_CHANNEL, + bRFRegOffsetMask); RfLoopReg = ODM_GetRFReg(pDM_Odm, RF_PATH_A, 0x00, bRFRegOffsetMask); - ODM_SetBBReg(pDM_Odm, rFPGA0_XA_RFInterfaceOE, ODM_DPDT, Antenna_A); /* change to Antenna A */ + /* change to Antenna A */ + ODM_SetBBReg(pDM_Odm, rFPGA0_XA_RFInterfaceOE, ODM_DPDT, Antenna_A); /* Step 1: USE IQK to transmitter single tone */ udelay(10); @@ -1481,7 +1518,7 @@ bool ODM_SingleDualAntennaDetection(struct dm_odm_t *pDM_Odm, u8 mode) ODM_SetBBReg(pDM_Odm, rFPGA0_PSDFunction, BIT(14) | BIT(15), 0x0); /* To SET CH1 to do */ - ODM_SetRFReg(pDM_Odm, RF_PATH_A, ODM_CHANNEL, bRFRegOffsetMask, 0x01); /* Channel 1 */ + ODM_SetRFReg(pDM_Odm, RF_PATH_A, ODM_CHANNEL, bRFRegOffsetMask, 0x01); /* AFE all on step */ ODM_SetBBReg(pDM_Odm, rRx_Wait_CCA, bMaskDWord, 0x6FDB25A4); @@ -1548,7 +1585,8 @@ bool ODM_SingleDualAntennaDetection(struct dm_odm_t *pDM_Odm, u8 mode) } /* change to open case */ - ODM_SetBBReg(pDM_Odm, rFPGA0_XA_RFInterfaceOE, 0x300, 0); /* change to Ant A and B all open case */ + /* change to Ant A and B all open case */ + ODM_SetBBReg(pDM_Odm, rFPGA0_XA_RFInterfaceOE, 0x300, 0); udelay(10); for (n = 0; n < 2; n++) { @@ -1568,15 +1606,19 @@ bool ODM_SingleDualAntennaDetection(struct dm_odm_t *pDM_Odm, u8 mode) ODM_SetBBReg(pDM_Odm, rFPGA0_XCD_RFInterfaceSW, bMaskDWord, Reg874); ODM_SetBBReg(pDM_Odm, rOFDM0_XAAGCCore1, 0x7F, 0x40); ODM_SetBBReg(pDM_Odm, rOFDM0_XAAGCCore1, bMaskDWord, Regc50); - ODM_SetRFReg(pDM_Odm, RF_PATH_A, RF_CHNLBW, bRFRegOffsetMask, CurrentChannel); + ODM_SetRFReg(pDM_Odm, RF_PATH_A, RF_CHNLBW, bRFRegOffsetMask, + CurrentChannel); ODM_SetRFReg(pDM_Odm, RF_PATH_A, 0x00, bRFRegOffsetMask, RfLoopReg); /* Reload AFE Registers */ odm_PHY_ReloadAFERegisters(pDM_Odm, AFE_REG_8723A, AFE_Backup, 16); - ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("psd_report_A[%d]= %d \n", 2416, AntA_report)); - ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("psd_report_B[%d]= %d \n", 2416, AntB_report)); - ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("psd_report_O[%d]= %d \n", 2416, AntO_report)); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, + ("psd_report_A[%d]= %d \n", 2416, AntA_report)); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, + ("psd_report_B[%d]= %d \n", 2416, AntB_report)); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, + ("psd_report_O[%d]= %d \n", 2416, AntO_report)); /* 2 Test Ant B based on Ant A is ON */ if (mode == ANTTESTB) { @@ -1598,25 +1640,33 @@ bool ODM_SingleDualAntennaDetection(struct dm_odm_t *pDM_Odm, u8 mode) if ((AntO_report >= 100) & (AntO_report < 118)) { if (AntA_report > (AntO_report+1)) { pDM_SWAT_Table->ANTA_ON = false; - ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Ant A is OFF")); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, + ODM_DBG_LOUD, ("Ant A is OFF")); } else { pDM_SWAT_Table->ANTA_ON = true; - ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Ant A is ON")); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, + ODM_DBG_LOUD, ("Ant A is ON")); } if (AntB_report > (AntO_report+2)) { pDM_SWAT_Table->ANTB_ON = false; - ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Ant B is OFF")); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, + ODM_DBG_LOUD, ("Ant B is OFF")); } else { pDM_SWAT_Table->ANTB_ON = true; - ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Ant B is ON")); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, + ODM_DBG_LOUD, ("Ant B is ON")); } } } else { - ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ODM_SingleDualAntennaDetection(): Need to check again\n")); - pDM_SWAT_Table->ANTA_ON = true; /* Set Antenna A on as default */ - pDM_SWAT_Table->ANTB_ON = false; /* Set Antenna B off as default */ + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, + ("ODM_SingleDualAntennaDetection(): Need to check again\n")); + /* Set Antenna A on as default */ + pDM_SWAT_Table->ANTA_ON = true; + /* Set Antenna B off as default */ + pDM_SWAT_Table->ANTB_ON = false; bResult = false; } + return bResult; } -- GitLab From 85b7a9de00bde29e3c815474f51bfdf0fbcde9d7 Mon Sep 17 00:00:00 2001 From: Tina Johnson Date: Mon, 2 Mar 2015 23:40:25 +0530 Subject: [PATCH 03018/11651] staging: lustre: lustre: libcfs: Replaced printk() with pr_err() The following checkpatch warning was fixed: Prefer [subsystem eg: netdev]_err([subsystem]dev with the help of Coccinelle. The following semantic patch was used: @a@ expression e; @@ printk(e,...); @script:python b@ e << a.e; y; @@ import re match = re.match('KERN_ERR ', e); if (match == None): cocci.include_match(False) else: m = re.sub('KERN_ERR ', '', e) coccinelle.y = m; @c@ expression a.e; identifier b.y; @@ - printk(e, + pr_err(y, ...); Signed-off-by: Tina Johnson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/libcfs/module.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/staging/lustre/lustre/libcfs/module.c b/drivers/staging/lustre/lustre/libcfs/module.c index 7dc77dd402b8..e35f5981cb43 100644 --- a/drivers/staging/lustre/lustre/libcfs/module.c +++ b/drivers/staging/lustre/lustre/libcfs/module.c @@ -347,7 +347,7 @@ static int init_libcfs_module(void) rc = libcfs_debug_init(5 * 1024 * 1024); if (rc < 0) { - printk(KERN_ERR "LustreError: libcfs_debug_init: %d\n", rc); + pr_err("LustreError: libcfs_debug_init: %d\n", rc); return rc; } @@ -433,8 +433,7 @@ static void exit_libcfs_module(void) rc = libcfs_debug_cleanup(); if (rc) - printk(KERN_ERR "LustreError: libcfs_debug_cleanup: %d\n", - rc); + pr_err("LustreError: libcfs_debug_cleanup: %d\n", rc); libcfs_arch_cleanup(); } -- GitLab From 324588eccc75a3a3d4beac2a0206122b23b90adc Mon Sep 17 00:00:00 2001 From: Tina Johnson Date: Mon, 2 Mar 2015 23:40:26 +0530 Subject: [PATCH 03019/11651] staging: lustre: lustre: libcfs: Replaced printk() with pr_err() and pr_cont() The following checkpatch warning was fixed: Prefer [subsystem eg: netdev]_err([subsystem]dev with the help of Coccinelle. pr_cont() was used to replace those printk statements which followed a printk that did not end with a '\n'. The following semantic patch was used to replace printk() with pr_err(): @a@ expression e; @@ printk(e,...); @script:python b@ e << a.e; y; @@ import re match = re.match('KERN_ERR ', e); if (match == None): cocci.include_match(False) else: m = re.sub('KERN_ERR ', '', e) coccinelle.y = m; @c@ expression a.e; identifier b.y; @@ - printk(e, + pr_err(y, ...); Signed-off-by: Tina Johnson Signed-off-by: Greg Kroah-Hartman --- .../staging/lustre/lustre/libcfs/tracefile.c | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/drivers/staging/lustre/lustre/libcfs/tracefile.c b/drivers/staging/lustre/lustre/libcfs/tracefile.c index eb65b50f832d..f8d8a2f70691 100644 --- a/drivers/staging/lustre/lustre/libcfs/tracefile.c +++ b/drivers/staging/lustre/lustre/libcfs/tracefile.c @@ -224,8 +224,7 @@ static struct cfs_trace_page *cfs_trace_get_tage(struct cfs_trace_cpu_data *tcd, */ if (len > PAGE_CACHE_SIZE) { - printk(KERN_ERR - "cowardly refusing to write %lu bytes in a page\n", len); + pr_err("cowardly refusing to write %lu bytes in a page\n", len); return NULL; } @@ -688,8 +687,8 @@ int cfs_tracefile_dump_all_pages(char *filename) if (IS_ERR(filp)) { rc = PTR_ERR(filp); filp = NULL; - printk(KERN_ERR "LustreError: can't open %s for dump: rc %d\n", - filename, rc); + pr_err("LustreError: can't open %s for dump: rc %d\n", + filename, rc); goto out; } @@ -726,7 +725,7 @@ int cfs_tracefile_dump_all_pages(char *filename) MMSPACE_CLOSE; rc = vfs_fsync(filp, 1); if (rc) - printk(KERN_ERR "sync returns %d\n", rc); + pr_err("sync returns %d\n", rc); close: filp_close(filp, NULL); out: @@ -1048,22 +1047,21 @@ static int tracefiled(void *arg) int i; printk(KERN_ALERT "Lustre: trace pages aren't empty\n"); - printk(KERN_ERR "total cpus(%d): ", - num_possible_cpus()); + pr_err("total cpus(%d): ", + num_possible_cpus()); for (i = 0; i < num_possible_cpus(); i++) if (cpu_online(i)) - printk(KERN_ERR "%d(on) ", i); + pr_cont("%d(on) ", i); else - printk(KERN_ERR "%d(off) ", i); - printk(KERN_ERR "\n"); + pr_cont("%d(off) ", i); + pr_cont("\n"); i = 0; list_for_each_entry_safe(tage, tmp, &pc.pc_pages, linkage) - printk(KERN_ERR "page %d belongs to cpu %d\n", - ++i, tage->cpu); - printk(KERN_ERR "There are %d pages unwritten\n", - i); + pr_err("page %d belongs to cpu %d\n", + ++i, tage->cpu); + pr_err("There are %d pages unwritten\n", i); } __LASSERT(list_empty(&pc.pc_pages)); end_loop: -- GitLab From 82d28561b7e01eccaa36b06c987045f08a77b4f4 Mon Sep 17 00:00:00 2001 From: Navya Sri Nizamkari Date: Tue, 3 Mar 2015 17:08:06 +0530 Subject: [PATCH 03020/11651] staging: comedi: Remove if condition. This patch removes a if condition which has a semicolon after it. As the conditional check is redundant, the comment before it is also changed. The following coccinelle script was used to detect the pattern of a semicolon after if. @r1@ position p; @@ if (...);@p @script:python@ p0 << r1.p; @@ // Emacs org-mode output cocci.print_main("", p0) cocci.print_secs("", p0) Signed-off-by: Navya Sri Nizamkari Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das1800.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c index 3eb02e8d6103..ca4f322c0d2f 100644 --- a/drivers/staging/comedi/drivers/das1800.c +++ b/drivers/staging/comedi/drivers/das1800.c @@ -489,9 +489,7 @@ static void das1800_handle_fifo_not_empty(struct comedi_device *dev, while (inb(dev->iobase + DAS1800_STATUS) & FNE) { dpnt = inw(dev->iobase + DAS1800_FIFO); - /* convert to unsigned type if we are in a bipolar mode */ - if (!unipolar) - ; + /* convert to unsigned type */ dpnt = munge_bipolar_sample(dev, dpnt); comedi_buf_write_samples(s, &dpnt, 1); -- GitLab From e384b69a35ae96055774dbce9dea813043e21142 Mon Sep 17 00:00:00 2001 From: Aya Mahfouz Date: Tue, 3 Mar 2015 16:27:37 +0200 Subject: [PATCH 03021/11651] staging: iio: meter: add check on return variables adds checks on variables that are used to return values. If the value is less than zero, this indicates that an error occurred and hence a message is printed through dev_err. Checks are made on negative values only since spi_* functions return negative error codes. The functions were found using the following script but the aforementioned modification was what was carried out in the end: @@ identifier len,f; @@ -int len; ... when != len when strict -len = +return f(...); -return len; Signed-off-by: Aya Mahfouz Reviewed-by: Daniel Baluta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/meter/ade7758_core.c | 30 +++++++++++++----------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/drivers/staging/iio/meter/ade7758_core.c b/drivers/staging/iio/meter/ade7758_core.c index 70e96b20c2eb..7e287dae7b44 100644 --- a/drivers/staging/iio/meter/ade7758_core.c +++ b/drivers/staging/iio/meter/ade7758_core.c @@ -303,14 +303,15 @@ static int ade7758_reset(struct device *dev) int ret; u8 val; - ade7758_spi_read_reg_8(dev, - ADE7758_OPMODE, - &val); + ret = ade7758_spi_read_reg_8(dev, ADE7758_OPMODE, &val); + if (ret < 0) { + dev_err(dev, "Failed to read opmode reg\n"); + return ret; + } val |= 1 << 6; /* Software Chip Reset */ - ret = ade7758_spi_write_reg_8(dev, - ADE7758_OPMODE, - val); - + ret = ade7758_spi_write_reg_8(dev, ADE7758_OPMODE, val); + if (ret < 0) + dev_err(dev, "Failed to write opmode reg\n"); return ret; } @@ -444,14 +445,15 @@ static int ade7758_stop_device(struct device *dev) int ret; u8 val; - ade7758_spi_read_reg_8(dev, - ADE7758_OPMODE, - &val); + ret = ade7758_spi_read_reg_8(dev, ADE7758_OPMODE, &val); + if (ret < 0) { + dev_err(dev, "Failed to read opmode reg\n"); + return ret; + } val |= 7 << 3; /* ADE7758 powered down */ - ret = ade7758_spi_write_reg_8(dev, - ADE7758_OPMODE, - val); - + ret = ade7758_spi_write_reg_8(dev, ADE7758_OPMODE, val); + if (ret < 0) + dev_err(dev, "Failed to write opmode reg\n"); return ret; } -- GitLab From 37e3be9de378d4775c617b0649ff89a6dc6bf07d Mon Sep 17 00:00:00 2001 From: Cristina Opriceana Date: Wed, 4 Mar 2015 02:37:15 +0200 Subject: [PATCH 03022/11651] Staging: iio: Added define guards where needed The following files were added define guards to prevent multiple inclusion. Signed-off-by: Cristina Opriceana Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/Documentation/iio_utils.h | 4 ++++ drivers/staging/iio/accel/sca3000.h | 5 ++++- drivers/staging/iio/frequency/dds.h | 4 ++++ drivers/staging/iio/meter/meter.h | 4 ++++ drivers/staging/iio/resolver/ad2s1210.h | 3 +++ 5 files changed, 19 insertions(+), 1 deletion(-) diff --git a/drivers/staging/iio/Documentation/iio_utils.h b/drivers/staging/iio/Documentation/iio_utils.h index 568eff06f803..bd6982c12d0d 100644 --- a/drivers/staging/iio/Documentation/iio_utils.h +++ b/drivers/staging/iio/Documentation/iio_utils.h @@ -6,6 +6,8 @@ * under the terms of the GNU General Public License version 2 as published by * the Free Software Foundation. */ +#ifndef _IIO_UTILS_H +#define _IIO_UTILS_H #include #include @@ -681,3 +683,5 @@ error_free: free(temp); return ret; } + +#endif /* _IIO_UTILS_H */ diff --git a/drivers/staging/iio/accel/sca3000.h b/drivers/staging/iio/accel/sca3000.h index b284e5a6cac1..9c8a9587df7d 100644 --- a/drivers/staging/iio/accel/sca3000.h +++ b/drivers/staging/iio/accel/sca3000.h @@ -38,6 +38,9 @@ * Can probably alleviate this by reading the interrupt register on start, but * that is really just brushing the problem under the carpet. */ +#ifndef _SCA3000 +#define _SCA3000 + #define SCA3000_WRITE_REG(a) (((a) << 2) | 0x02) #define SCA3000_READ_REG(a) ((a) << 2) @@ -272,4 +275,4 @@ static inline void sca3000_ring_int_process(u8 val, void *ring) } #endif - +#endif /* _SCA3000 */ diff --git a/drivers/staging/iio/frequency/dds.h b/drivers/staging/iio/frequency/dds.h index 611e2b0cfc4c..fe53e7324c94 100644 --- a/drivers/staging/iio/frequency/dds.h +++ b/drivers/staging/iio/frequency/dds.h @@ -5,6 +5,8 @@ * * Licensed under the GPL-2 or later. */ +#ifndef IIO_DDS_H_ +#define IIO_DDS_H_ /** * /sys/bus/iio/devices/.../out_altvoltageX_frequencyY @@ -108,3 +110,5 @@ #define IIO_CONST_ATTR_OUT_WAVETYPES_AVAILABLE(_channel, _output, _modes)\ IIO_CONST_ATTR( \ out_altvoltage##_channel##_out##_output##_wavetype_available, _modes) + +#endif /* IIO_DDS_H_ */ diff --git a/drivers/staging/iio/meter/meter.h b/drivers/staging/iio/meter/meter.h index 8f0de02839b7..dfba510f29be 100644 --- a/drivers/staging/iio/meter/meter.h +++ b/drivers/staging/iio/meter/meter.h @@ -1,3 +1,6 @@ +#ifndef _METER_H +#define _METER_H + #include /* metering ic types of attribute */ @@ -394,3 +397,4 @@ #define IIO_EVENT_ATTR_VPKLVL_EXC(_evlist, _show, _store, _mask) \ IIO_EVENT_ATTR_SH(vpklvl_exc, _evlist, _show, _store, _mask) +#endif /* _METER_H */ diff --git a/drivers/staging/iio/resolver/ad2s1210.h b/drivers/staging/iio/resolver/ad2s1210.h index aec0bdca16a4..c7158f6e61c2 100644 --- a/drivers/staging/iio/resolver/ad2s1210.h +++ b/drivers/staging/iio/resolver/ad2s1210.h @@ -8,6 +8,8 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ +#ifndef _AD2S1210_H +#define _AD2S1210_H struct ad2s1210_platform_data { unsigned sample; @@ -15,3 +17,4 @@ struct ad2s1210_platform_data { unsigned res[2]; bool gpioin; }; +#endif /* _AD2S1210_H */ -- GitLab From 225f597c60da646a6df1f7ac4152577a0c5fd56c Mon Sep 17 00:00:00 2001 From: Supriya Karanth Date: Tue, 3 Mar 2015 23:48:21 +0900 Subject: [PATCH 03023/11651] staging: lustre: remove initialization of static ints static ints are initialized to 0 by the compiler. Explicit initialization is not necessary. Found by checkpatch.pl - ERROR: do not initialise statics to 0 or NULL changes made using coccinelle script: @@ type T; identifier var; @@ -static T var = 0; +static T var; Signed-off-by: Supriya Karanth Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/libcfs/linux/linux-proc.c | 2 +- drivers/staging/lustre/lustre/libcfs/tracefile.c | 2 +- drivers/staging/lustre/lustre/llite/statahead.c | 2 +- drivers/staging/lustre/lustre/mgc/mgc_request.c | 2 +- drivers/staging/lustre/lustre/obdclass/genops.c | 2 +- drivers/staging/lustre/lustre/obdclass/lprocfs_status.c | 2 +- drivers/staging/lustre/lustre/obdclass/lu_object.c | 2 +- drivers/staging/lustre/lustre/ptlrpc/pack_generic.c | 2 +- drivers/staging/lustre/lustre/ptlrpc/pinger.c | 2 +- drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/staging/lustre/lustre/libcfs/linux/linux-proc.c b/drivers/staging/lustre/lustre/libcfs/linux/linux-proc.c index 0f65929a8524..3100cb138548 100644 --- a/drivers/staging/lustre/lustre/libcfs/linux/linux-proc.c +++ b/drivers/staging/lustre/lustre/libcfs/linux/linux-proc.c @@ -165,7 +165,7 @@ static int proc_dobitmasks(struct ctl_table *table, int write, __proc_dobitmasks); } -static int min_watchdog_ratelimit = 0; /* disable ratelimiting */ +static int min_watchdog_ratelimit; /* disable ratelimiting */ static int max_watchdog_ratelimit = (24*60*60); /* limit to once per day */ static int __proc_dump_kernel(void *data, int write, diff --git a/drivers/staging/lustre/lustre/libcfs/tracefile.c b/drivers/staging/lustre/lustre/libcfs/tracefile.c index f8d8a2f70691..c86394f7f4d9 100644 --- a/drivers/staging/lustre/lustre/libcfs/tracefile.c +++ b/drivers/staging/lustre/lustre/libcfs/tracefile.c @@ -53,7 +53,7 @@ char cfs_tracefile[TRACEFILE_NAME_SIZE]; long long cfs_tracefile_size = CFS_TRACEFILE_SIZE; static struct tracefiled_ctl trace_tctl; struct mutex cfs_trace_thread_mutex; -static int thread_running = 0; +static int thread_running; static atomic_t cfs_tage_allocated = ATOMIC_INIT(0); diff --git a/drivers/staging/lustre/lustre/llite/statahead.c b/drivers/staging/lustre/lustre/llite/statahead.c index 6ad9dd0fe2b3..fe732fa0d01f 100644 --- a/drivers/staging/lustre/lustre/llite/statahead.c +++ b/drivers/staging/lustre/lustre/llite/statahead.c @@ -84,7 +84,7 @@ struct ll_sa_entry { struct qstr se_qstr; }; -static unsigned int sai_generation = 0; +static unsigned int sai_generation; static DEFINE_SPINLOCK(sai_generation_lock); static inline int ll_sa_entry_unhashed(struct ll_sa_entry *entry) diff --git a/drivers/staging/lustre/lustre/mgc/mgc_request.c b/drivers/staging/lustre/lustre/mgc/mgc_request.c index b24457554798..0375bfe29a7d 100644 --- a/drivers/staging/lustre/lustre/mgc/mgc_request.c +++ b/drivers/staging/lustre/lustre/mgc/mgc_request.c @@ -479,7 +479,7 @@ int lprocfs_mgc_rd_ir_state(struct seq_file *m, void *data) #define RQ_NOW 0x2 #define RQ_LATER 0x4 #define RQ_STOP 0x8 -static int rq_state = 0; +static int rq_state; static wait_queue_head_t rq_waitq; static DECLARE_COMPLETION(rq_exit); diff --git a/drivers/staging/lustre/lustre/obdclass/genops.c b/drivers/staging/lustre/lustre/obdclass/genops.c index 82508210465e..6d440b465860 100644 --- a/drivers/staging/lustre/lustre/obdclass/genops.c +++ b/drivers/staging/lustre/lustre/obdclass/genops.c @@ -1559,7 +1559,7 @@ void obd_exports_barrier(struct obd_device *obd) EXPORT_SYMBOL(obd_exports_barrier); /* Total amount of zombies to be destroyed */ -static int zombies_count = 0; +static int zombies_count; /** * kill zombie imports and exports diff --git a/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c b/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c index 55e80818bd5d..c171c6c6c457 100644 --- a/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c +++ b/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c @@ -223,7 +223,7 @@ EXPORT_SYMBOL(lprocfs_write_frac_helper); #if defined (CONFIG_PROC_FS) -static int lprocfs_no_percpu_stats = 0; +static int lprocfs_no_percpu_stats; module_param(lprocfs_no_percpu_stats, int, 0644); MODULE_PARM_DESC(lprocfs_no_percpu_stats, "Do not alloc percpu data for lprocfs stats"); diff --git a/drivers/staging/lustre/lustre/obdclass/lu_object.c b/drivers/staging/lustre/lustre/obdclass/lu_object.c index d2311f246c4a..20c0779951fd 100644 --- a/drivers/staging/lustre/lustre/obdclass/lu_object.c +++ b/drivers/staging/lustre/lustre/obdclass/lu_object.c @@ -1308,7 +1308,7 @@ static DEFINE_SPINLOCK(lu_keys_guard); * lu_context_refill(). No locking is provided, as initialization and shutdown * are supposed to be externally serialized. */ -static unsigned key_set_version = 0; +static unsigned key_set_version; /** * Register new key. diff --git a/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c b/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c index 2f45f7657830..eb6ff902080c 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c +++ b/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c @@ -117,7 +117,7 @@ EXPORT_SYMBOL(lustre_msg_check_version); /* early reply size */ int lustre_msg_early_size(void) { - static int size = 0; + static int size; if (!size) { /* Always reply old ptlrpc_body_v2 to keep interoprability * with the old client (< 2.3) which doesn't have pb_jobid diff --git a/drivers/staging/lustre/lustre/ptlrpc/pinger.c b/drivers/staging/lustre/lustre/ptlrpc/pinger.c index 340d98a64137..9dbda9332dd8 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/pinger.c +++ b/drivers/staging/lustre/lustre/ptlrpc/pinger.c @@ -545,7 +545,7 @@ void ptlrpc_pinger_wake_up(void) #define PET_READY 1 #define PET_TERMINATE 2 -static int pet_refcount = 0; +static int pet_refcount; static int pet_state; static wait_queue_head_t pet_waitq; LIST_HEAD(pet_list); diff --git a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c index 4621b71fe0b6..8f7be84aa187 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c +++ b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c @@ -85,7 +85,7 @@ MODULE_PARM_DESC(ptlrpcd_bind_policy, "Ptlrpcd threads binding mode."); static struct ptlrpcd *ptlrpcds; struct mutex ptlrpcd_mutex; -static int ptlrpcd_users = 0; +static int ptlrpcd_users; void ptlrpcd_wake(struct ptlrpc_request *req) { -- GitLab From 80c598a6abff3713e4a8c31c34f6aec8b342844d Mon Sep 17 00:00:00 2001 From: Dilek Uzulmez Date: Mon, 2 Mar 2015 23:56:54 +0200 Subject: [PATCH 03024/11651] Staging: rtl8192u: Fix quoted string split across lines This patch fixes checkpatch.pl warning in file ieee80211_crypt.c WARNING: "quoted string split across lines warning" Signed-off-by: Dilek Uzulmez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/ieee80211/ieee80211_crypt.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt.c index f80dd08b0668..3995620b3442 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt.c @@ -65,8 +65,8 @@ void ieee80211_crypt_deinit_handler(unsigned long data) spin_lock_irqsave(&ieee->lock, flags); ieee80211_crypt_deinit_entries(ieee, 0); if (!list_empty(&ieee->crypt_deinit_list)) { - netdev_dbg(ieee->dev, "%s: entries remaining in delayed crypt " - "deletion list\n", ieee->dev->name); + netdev_dbg(ieee->dev, "%s: entries remaining in delayed crypt deletion list\n", + ieee->dev->name); ieee->crypt_deinit_timer.expires = jiffies + HZ; add_timer(&ieee->crypt_deinit_timer); } @@ -145,8 +145,8 @@ int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops) spin_unlock_irqrestore(&hcrypt->lock, flags); if (del_alg) { - pr_debug("ieee80211_crypt: unregistered algorithm " - "'%s'\n", ops->name); + pr_debug("ieee80211_crypt: unregistered algorithm '%s'\n", + ops->name); kfree(del_alg); } @@ -231,8 +231,8 @@ void __exit ieee80211_crypto_deinit(void) struct ieee80211_crypto_alg *alg = (struct ieee80211_crypto_alg *) ptr; list_del(ptr); - pr_debug("ieee80211_crypt: unregistered algorithm " - "'%s' (deinit)\n", alg->ops->name); + pr_debug("ieee80211_crypt: unregistered algorithm '%s' (deinit)\n", + alg->ops->name); kfree(alg); } -- GitLab From 5dc42962e1669a7ad222103d485e9af30dd1ffde Mon Sep 17 00:00:00 2001 From: Vaishali Thakkar Date: Tue, 3 Mar 2015 13:08:24 +0530 Subject: [PATCH 03025/11651] Staging: rtl8192e: Eliminate use of macro IS_NIC_DOWN This patch eliminates use of unnecessory macro IS_NIC_DOWN and replaces it with standard code. Signed-off-by: Vaishali Thakkar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c | 10 +++++----- drivers/staging/rtl8192e/rtl8192e/rtl_core.c | 10 +++++----- drivers/staging/rtl8192e/rtl8192e/rtl_core.h | 2 -- drivers/staging/rtl8192e/rtl8192e/rtl_dm.c | 4 ++-- 4 files changed, 12 insertions(+), 14 deletions(-) diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c index 8c08ef6a40a4..cd3c662eba2b 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c +++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c @@ -996,7 +996,7 @@ static void rtl8192_phy_FinishSwChnlNow(struct net_device *dev, u8 channel) &priv->SwChnlStep, &delay)) { if (delay > 0) msleep(delay); - if (IS_NIC_DOWN(priv)) + if (!priv->up) break; } } @@ -1020,7 +1020,7 @@ u8 rtl8192_phy_SwChnl(struct net_device *dev, u8 channel) struct r8192_priv *priv = rtllib_priv(dev); RT_TRACE(COMP_PHY, "=====>%s()\n", __func__); - if (IS_NIC_DOWN(priv)) { + if (!priv->up) { RT_TRACE(COMP_ERR, "%s(): ERR !! driver is not up\n", __func__); return false; } @@ -1060,7 +1060,7 @@ u8 rtl8192_phy_SwChnl(struct net_device *dev, u8 channel) priv->SwChnlStage = 0; priv->SwChnlStep = 0; - if (!IS_NIC_DOWN(priv)) + if (priv->up) rtl8192_SwChnl_WorkItem(dev); priv->SwChnlInProgress = false; return true; @@ -1186,7 +1186,7 @@ void rtl8192_SetBWModeWorkItem(struct net_device *dev) priv->SetBWModeInProgress = false; return; } - if (IS_NIC_DOWN(priv)) { + if (!priv->up) { RT_TRACE(COMP_ERR, "%s(): ERR!! driver is not up\n", __func__); return; } @@ -1309,7 +1309,7 @@ void InitialGain819xPci(struct net_device *dev, u8 Operation) u32 BitMask; u8 initial_gain; - if (!IS_NIC_DOWN(priv)) { + if (priv->up) { switch (Operation) { case IG_Backup: RT_TRACE(COMP_SCAN, "IG_Backup, backup the initial" diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c index 7dda904bb477..a603acc22d92 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c @@ -1506,7 +1506,7 @@ RESET_START: if (priv->rtllib->state == RTLLIB_LINKED) LeisurePSLeave(dev); - if (IS_NIC_DOWN(priv)) { + if (priv->up) { RT_TRACE(COMP_ERR, "%s():the driver is not up! " "return\n", __func__); up(&priv->wx_sem); @@ -1650,7 +1650,7 @@ void rtl819x_watchdog_wqcallback(void *data) bool bHigherBusyRxTraffic = false; bool bEnterPS = false; - if (IS_NIC_DOWN(priv) || priv->bHwRadioOff) + if (!priv->up || priv->bHwRadioOff) return; if (priv->rtllib->state >= RTLLIB_LINKED) { @@ -1882,7 +1882,7 @@ void rtl8192_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, MAX_DEV_ADDR_SIZE); u8 queue_index = tcb_desc->queue_index; - if ((priv->rtllib->eRFPowerState == eRfOff) || IS_NIC_DOWN(priv) || + if ((priv->rtllib->eRFPowerState == eRfOff) || !priv->up || priv->bResetInProgress) { kfree_skb(skb); return; @@ -1916,7 +1916,7 @@ int rtl8192_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) if (queue_index != TXCMD_QUEUE) { if ((priv->rtllib->eRFPowerState == eRfOff) || - IS_NIC_DOWN(priv) || priv->bResetInProgress) { + !priv->up || priv->bResetInProgress) { kfree_skb(skb); return 0; } @@ -3032,7 +3032,7 @@ bool NicIFEnableNIC(struct net_device *dev) struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *) (&(priv->rtllib->PowerSaveControl)); - if (IS_NIC_DOWN(priv)) { + if (!priv->up) { RT_TRACE(COMP_ERR, "ERR!!! %s(): Driver is already down!\n", __func__); priv->bdisable_nic = false; diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h index d1438c2f8980..113174b52a57 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h @@ -98,8 +98,6 @@ #define BIT(_i) (1<<(_i)) #endif -#define IS_NIC_DOWN(priv) (!(priv)->up) - #define IS_ADAPTER_SENDS_BEACON(dev) 0 #define IS_UNDER_11N_AES_MODE(_rtllib) \ diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c index b8891c62af3e..bdb9274486dc 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c @@ -267,7 +267,7 @@ static void dm_check_rate_adaptive(struct net_device *dev) bool bshort_gi_enabled = false; static u8 ping_rssi_state; - if (IS_NIC_DOWN(priv)) { + if (!priv->up) { RT_TRACE(COMP_RATE, "<---- dm_check_rate_adaptive(): driver is going to unload\n"); return; } @@ -1569,7 +1569,7 @@ void dm_restore_dynamic_mechanism_state(struct net_device *dev) u32 reg_ratr = priv->rate_adaptive.last_ratr; u32 ratr_value; - if (IS_NIC_DOWN(priv)) { + if (!priv->up) { RT_TRACE(COMP_RATE, "<---- dm_restore_dynamic_mechanism_state(): driver is going to unload\n"); return; } -- GitLab From c5c15efba8cc3865ff880cbab52ffe6472373921 Mon Sep 17 00:00:00 2001 From: Vaishali Thakkar Date: Tue, 3 Mar 2015 13:09:23 +0530 Subject: [PATCH 03026/11651] Staging: rtl8192u: Fix duplicate conditional branch Replace duplicate branch with correct value. This branch is supposed to work for low thresh value. Signed-off-by: Vaishali Thakkar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/r8192U_dm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rtl8192u/r8192U_dm.c b/drivers/staging/rtl8192u/r8192U_dm.c index 719961643ded..5a01b7d405b1 100644 --- a/drivers/staging/rtl8192u/r8192U_dm.c +++ b/drivers/staging/rtl8192u/r8192U_dm.c @@ -1628,8 +1628,8 @@ void dm_change_dynamic_initgain_thresh(struct net_device *dev, u32 dm_type, dm_digtable.rssi_low_thresh = dm_value; } else if (dm_type == DIG_TYPE_THRESH_HIGHPWR_HIGH) { dm_digtable.rssi_high_power_highthresh = dm_value; - } else if (dm_type == DIG_TYPE_THRESH_HIGHPWR_HIGH) { - dm_digtable.rssi_high_power_highthresh = dm_value; + } else if (dm_type == DIG_TYPE_THRESH_HIGHPWR_LOW) { + dm_digtable.rssi_high_power_lowthresh = dm_value; } else if (dm_type == DIG_TYPE_ENABLE) { dm_digtable.dig_state = DM_STA_DIG_MAX; dm_digtable.dig_enable_flag = true; -- GitLab From cdbaf3f67279e7ee531c1be6da53731461a74237 Mon Sep 17 00:00:00 2001 From: Aya Mahfouz Date: Tue, 3 Mar 2015 16:03:35 +0200 Subject: [PATCH 03027/11651] staging: rtl8192e: replace memset(x,0,ETH_ALEN) by eth_zero_addr(x) eth_zero_addr() is a wrapper function for memset if 0 is going to be assigned to a mac address. The replacement was done by the following coccinelle script: @header@ @@ #include @eth_zero_addr@ expression e; @@ -memset(e,0,ETH_ALEN); +eth_zero_addr(e); @eth_broadcast_addr@ identifier e; @@ -memset(e,\(0xff\|0xFF\|255\),ETH_ALEN); +eth_broadcast_addr(e); @linux_header depends on !header && (eth_zero_addr || eth_broadcast_addr) @ @@ + #include + @special_header depends on !header && !linux_header && (eth_zero_addr || eth_broadcast_addr) @ @@ + + #include + @custom_header depends on !header && !linux_header && !special_header && (eth_zero_addr || eth_broadcast_addr) @ @@ + + #include Signed-off-by: Aya Mahfouz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtllib_softmac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8192e/rtllib_softmac.c b/drivers/staging/rtl8192e/rtllib_softmac.c index d992a754e72d..16aef7cf23b9 100644 --- a/drivers/staging/rtl8192e/rtllib_softmac.c +++ b/drivers/staging/rtl8192e/rtllib_softmac.c @@ -3751,7 +3751,7 @@ void notify_wx_assoc_event(struct rtllib_device *ieee) printk(KERN_INFO "%s(): Tell user space disconnected\n", __func__); - memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN); + eth_zero_addr(wrqu.ap_addr.sa_data); } wireless_send_event(ieee->dev, SIOCGIWAP, &wrqu, NULL); } -- GitLab From 76f73693ca36a13aff719c71236c47a4927c14a0 Mon Sep 17 00:00:00 2001 From: Aya Mahfouz Date: Tue, 3 Mar 2015 16:04:20 +0200 Subject: [PATCH 03028/11651] staging: rtl8192e: replace memset(x,0,ETH_ALEN) by eth_zero_addr(x) eth_zero_addr() is a wrapper function for memset if 0 is going to be assigned to a mac address. The replacement was done by the following coccinelle script: @header@ @@ #include @eth_zero_addr@ expression e; @@ -memset(e,0,ETH_ALEN); +eth_zero_addr(e); @eth_broadcast_addr@ identifier e; @@ -memset(e,\(0xff\|0xFF\|255\),ETH_ALEN); +eth_broadcast_addr(e); @linux_header depends on !header && (eth_zero_addr || eth_broadcast_addr) @ @@ + #include + @special_header depends on !header && !linux_header && (eth_zero_addr || eth_broadcast_addr) @ @@ + + #include + @custom_header depends on !header && !linux_header && !special_header && (eth_zero_addr || eth_broadcast_addr) @ @@ + + #include Signed-off-by: Aya Mahfouz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtllib_softmac_wx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8192e/rtllib_softmac_wx.c b/drivers/staging/rtl8192e/rtllib_softmac_wx.c index 835f3d78a16f..283ba8b20128 100644 --- a/drivers/staging/rtl8192e/rtllib_softmac_wx.c +++ b/drivers/staging/rtl8192e/rtllib_softmac_wx.c @@ -120,7 +120,7 @@ int rtllib_wx_get_wap(struct rtllib_device *ieee, ieee->state != RTLLIB_LINKED_SCANNING && ieee->wap_set == 0) - memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN); + eth_zero_addr(wrqu->ap_addr.sa_data); else memcpy(wrqu->ap_addr.sa_data, ieee->current_network.bssid, ETH_ALEN); -- GitLab From 21f5690ec7f5a5fa278f2b818a7ed722becd6995 Mon Sep 17 00:00:00 2001 From: Aya Mahfouz Date: Tue, 3 Mar 2015 16:06:19 +0200 Subject: [PATCH 03029/11651] staging: rtl8192u: replace memset(x,0,ETH_ALEN) by eth_zero_addr(x) eth_zero_addr() is a wrapper function for memset if 0 is going to be assigned to a mac address. The replacement was done by the following coccinelle script: @header@ @@ #include @eth_zero_addr@ expression e; @@ -memset(e,0,ETH_ALEN); +eth_zero_addr(e); @eth_broadcast_addr@ identifier e; @@ -memset(e,\(0xff\|0xFF\|255\),ETH_ALEN); +eth_broadcast_addr(e); @linux_header depends on !header && (eth_zero_addr || eth_broadcast_addr) @ @@ + #include + @special_header depends on !header && !linux_header && (eth_zero_addr || eth_broadcast_addr) @ @@ + + #include + @custom_header depends on !header && !linux_header && !special_header && (eth_zero_addr || eth_broadcast_addr) @ @@ + + #include Signed-off-by: Aya Mahfouz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c index 3a5407158963..3527edc39064 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c @@ -3208,7 +3208,7 @@ void notify_wx_assoc_event(struct ieee80211_device *ieee) if (ieee->state == IEEE80211_LINKED) memcpy(wrqu.ap_addr.sa_data, ieee->current_network.bssid, ETH_ALEN); else - memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN); + eth_zero_addr(wrqu.ap_addr.sa_data); wireless_send_event(ieee->dev, SIOCGIWAP, &wrqu, NULL); } EXPORT_SYMBOL(notify_wx_assoc_event); -- GitLab From 47f0585a20e28bdd3155823afcff209615c902ff Mon Sep 17 00:00:00 2001 From: Aya Mahfouz Date: Tue, 3 Mar 2015 16:08:38 +0200 Subject: [PATCH 03030/11651] staging: rtl8192u: ieee80211: replace memset(x,0,ETH_ALEN) by eth_zero_addr(x) eth_zero_addr() is a wrapper function for memset if 0 is going to be assigned to a mac address. The replacement was done by the following coccinelle script: @header@ @@ #include @eth_zero_addr@ expression e; @@ -memset(e,0,ETH_ALEN); +eth_zero_addr(e); @eth_broadcast_addr@ identifier e; @@ -memset(e,\(0xff\|0xFF\|255\),ETH_ALEN); +eth_broadcast_addr(e); @linux_header depends on !header && (eth_zero_addr || eth_broadcast_addr) @ @@ + #include + @special_header depends on !header && !linux_header && (eth_zero_addr || eth_broadcast_addr) @ @@ + + #include + @custom_header depends on !header && !linux_header && !special_header && (eth_zero_addr || eth_broadcast_addr) @ @@ + + #include Signed-off-by: Aya Mahfouz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/ieee80211/ieee80211_softmac_wx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac_wx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac_wx.c index 644368df6342..dcfa5abea127 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac_wx.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac_wx.c @@ -121,7 +121,7 @@ int ieee80211_wx_get_wap(struct ieee80211_device *ieee, ieee->state != IEEE80211_LINKED_SCANNING && ieee->wap_set == 0) - memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN); + eth_zero_addr(wrqu->ap_addr.sa_data); else memcpy(wrqu->ap_addr.sa_data, ieee->current_network.bssid, ETH_ALEN); -- GitLab From e922df7d3e946529981860d4bdd707a9cb59fc0d Mon Sep 17 00:00:00 2001 From: Vaishali Thakkar Date: Tue, 3 Mar 2015 22:34:22 +0530 Subject: [PATCH 03031/11651] Staging: rtl8712: Eliminate use of _init_timer This patch introduces the use of API function setup_timer instead of driver specific function _init_timer as it is the preferred and standard way to setup and set the timer. To be compatible with the change, argument types of referenced functions are changed. Also, definition of function _init_timer is removed as it is no longer needed after this change. This is done using Coccinelle and semantic patch used for this is as follows: @@ expression x, y; identifier a, b;@@ - _init_timer (&x, y, a, b); + setup_timer (&x, a, (unsigned long)b); Signed-off-by: Vaishali Thakkar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/mlme_linux.c | 48 +++++++++++----------- drivers/staging/rtl8712/os_intfs.c | 4 +- drivers/staging/rtl8712/osdep_service.h | 9 ---- drivers/staging/rtl8712/recv_linux.c | 11 +++-- drivers/staging/rtl8712/rtl8712_led.c | 3 +- drivers/staging/rtl8712/rtl871x_pwrctrl.c | 8 ++-- drivers/staging/rtl8712/rtl871x_security.c | 4 +- drivers/staging/rtl8712/rtl871x_security.h | 2 +- 8 files changed, 40 insertions(+), 49 deletions(-) diff --git a/drivers/staging/rtl8712/mlme_linux.c b/drivers/staging/rtl8712/mlme_linux.c index 53999e8aa1c1..8c5a475f05e7 100644 --- a/drivers/staging/rtl8712/mlme_linux.c +++ b/drivers/staging/rtl8712/mlme_linux.c @@ -32,39 +32,39 @@ #include "drv_types.h" #include "mlme_osdep.h" -static void sitesurvey_ctrl_handler(void *FunctionContext) +static void sitesurvey_ctrl_handler(unsigned long data) { - struct _adapter *adapter = (struct _adapter *)FunctionContext; + struct _adapter *adapter = (struct _adapter *)data; _r8712_sitesurvey_ctrl_handler(adapter); mod_timer(&adapter->mlmepriv.sitesurveyctrl.sitesurvey_ctrl_timer, jiffies + msecs_to_jiffies(3000)); } -static void join_timeout_handler (void *FunctionContext) +static void join_timeout_handler (unsigned long data) { - struct _adapter *adapter = (struct _adapter *)FunctionContext; + struct _adapter *adapter = (struct _adapter *)data; _r8712_join_timeout_handler(adapter); } -static void _scan_timeout_handler (void *FunctionContext) +static void _scan_timeout_handler (unsigned long data) { - struct _adapter *adapter = (struct _adapter *)FunctionContext; + struct _adapter *adapter = (struct _adapter *)data; r8712_scan_timeout_handler(adapter); } -static void dhcp_timeout_handler (void *FunctionContext) +static void dhcp_timeout_handler (unsigned long data) { - struct _adapter *adapter = (struct _adapter *)FunctionContext; + struct _adapter *adapter = (struct _adapter *)data; _r8712_dhcp_timeout_handler(adapter); } -static void wdg_timeout_handler (void *FunctionContext) +static void wdg_timeout_handler (unsigned long data) { - struct _adapter *adapter = (struct _adapter *)FunctionContext; + struct _adapter *adapter = (struct _adapter *)data; _r8712_wdg_timeout_handler(adapter); @@ -76,17 +76,17 @@ void r8712_init_mlme_timer(struct _adapter *padapter) { struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - _init_timer(&(pmlmepriv->assoc_timer), padapter->pnetdev, - join_timeout_handler, (pmlmepriv->nic_hdl)); - _init_timer(&(pmlmepriv->sitesurveyctrl.sitesurvey_ctrl_timer), - padapter->pnetdev, sitesurvey_ctrl_handler, - (u8 *)(pmlmepriv->nic_hdl)); - _init_timer(&(pmlmepriv->scan_to_timer), padapter->pnetdev, - _scan_timeout_handler, (pmlmepriv->nic_hdl)); - _init_timer(&(pmlmepriv->dhcp_timer), padapter->pnetdev, - dhcp_timeout_handler, (u8 *)(pmlmepriv->nic_hdl)); - _init_timer(&(pmlmepriv->wdg_timer), padapter->pnetdev, - wdg_timeout_handler, (u8 *)(pmlmepriv->nic_hdl)); + setup_timer(&pmlmepriv->assoc_timer, join_timeout_handler, + (unsigned long)padapter); + setup_timer(&pmlmepriv->sitesurveyctrl.sitesurvey_ctrl_timer, + sitesurvey_ctrl_handler, + (unsigned long)padapter); + setup_timer(&pmlmepriv->scan_to_timer, _scan_timeout_handler, + (unsigned long)padapter); + setup_timer(&pmlmepriv->dhcp_timer, dhcp_timeout_handler, + (unsigned long)padapter); + setup_timer(&pmlmepriv->wdg_timer, wdg_timeout_handler, + (unsigned long)padapter); } void r8712_os_indicate_connect(struct _adapter *adapter) @@ -118,9 +118,9 @@ void r8712_os_indicate_disconnect(struct _adapter *adapter) btkip_countermeasure; memset((unsigned char *)&adapter->securitypriv, 0, sizeof(struct security_priv)); - _init_timer(&(adapter->securitypriv.tkip_timer), - adapter->pnetdev, r8712_use_tkipkey_handler, - adapter); + setup_timer(&adapter->securitypriv.tkip_timer, + r8712_use_tkipkey_handler, + (unsigned long)adapter); /* Restore the PMK information to securitypriv structure * for the following connection. */ memcpy(&adapter->securitypriv.PMKIDList[0], diff --git a/drivers/staging/rtl8712/os_intfs.c b/drivers/staging/rtl8712/os_intfs.c index 64cdceead13b..ebfb29ed779a 100644 --- a/drivers/staging/rtl8712/os_intfs.c +++ b/drivers/staging/rtl8712/os_intfs.c @@ -323,8 +323,8 @@ u8 r8712_init_drv_sw(struct _adapter *padapter) _r8712_init_recv_priv(&padapter->recvpriv, padapter); memset((unsigned char *)&padapter->securitypriv, 0, sizeof(struct security_priv)); - _init_timer(&(padapter->securitypriv.tkip_timer), padapter->pnetdev, - r8712_use_tkipkey_handler, padapter); + setup_timer(&padapter->securitypriv.tkip_timer, + r8712_use_tkipkey_handler, (unsigned long)padapter); _r8712_init_sta_priv(&padapter->stapriv); padapter->stapriv.padapter = padapter; r8712_init_bcmc_stainfo(padapter); diff --git a/drivers/staging/rtl8712/osdep_service.h b/drivers/staging/rtl8712/osdep_service.h index 54c4c470cd8e..c6dc3629f4d2 100644 --- a/drivers/staging/rtl8712/osdep_service.h +++ b/drivers/staging/rtl8712/osdep_service.h @@ -60,15 +60,6 @@ struct __queue { #define LIST_CONTAINOR(ptr, type, member) \ ((type *)((char *)(ptr)-(SIZE_T)(&((type *)0)->member))) -static inline void _init_timer(struct timer_list *ptimer, - struct net_device *padapter, - void *pfunc, void *cntx) -{ - ptimer->function = pfunc; - ptimer->data = (addr_t)cntx; - init_timer(ptimer); -} - static inline void _cancel_timer(struct timer_list *ptimer, u8 *bcancelled) { del_timer(ptimer); diff --git a/drivers/staging/rtl8712/recv_linux.c b/drivers/staging/rtl8712/recv_linux.c index 3640dd48febe..799a0f9a5b2d 100644 --- a/drivers/staging/rtl8712/recv_linux.c +++ b/drivers/staging/rtl8712/recv_linux.c @@ -137,18 +137,17 @@ _recv_indicatepkt_drop: precvpriv->rx_drop++; } -static void _r8712_reordering_ctrl_timeout_handler (void *FunctionContext) +static void _r8712_reordering_ctrl_timeout_handler (unsigned long data) { struct recv_reorder_ctrl *preorder_ctrl = - (struct recv_reorder_ctrl *)FunctionContext; + (struct recv_reorder_ctrl *)data; r8712_reordering_ctrl_timeout_handler(preorder_ctrl); } void r8712_init_recv_timer(struct recv_reorder_ctrl *preorder_ctrl) { - struct _adapter *padapter = preorder_ctrl->padapter; - - _init_timer(&(preorder_ctrl->reordering_ctrl_timer), padapter->pnetdev, - _r8712_reordering_ctrl_timeout_handler, preorder_ctrl); + setup_timer(&preorder_ctrl->reordering_ctrl_timer, + _r8712_reordering_ctrl_timeout_handler, + (unsigned long)preorder_ctrl); } diff --git a/drivers/staging/rtl8712/rtl8712_led.c b/drivers/staging/rtl8712/rtl8712_led.c index 0c7dfeebc62e..6085689f0976 100644 --- a/drivers/staging/rtl8712/rtl8712_led.c +++ b/drivers/staging/rtl8712/rtl8712_led.c @@ -97,7 +97,8 @@ static void InitLed871x(struct _adapter *padapter, struct LED_871x *pLed, pLed->bLedBlinkInProgress = false; pLed->BlinkTimes = 0; pLed->BlinkingLedState = LED_UNKNOWN; - _init_timer(&(pLed->BlinkTimer), nic, BlinkTimerCallback, pLed); + setup_timer(&pLed->BlinkTimer, BlinkTimerCallback, + (unsigned long)pLed); INIT_WORK(&pLed->BlinkWorkItem, BlinkWorkItemCallback); } diff --git a/drivers/staging/rtl8712/rtl871x_pwrctrl.c b/drivers/staging/rtl8712/rtl871x_pwrctrl.c index ed2844d2b02a..ea732ee99bbe 100644 --- a/drivers/staging/rtl8712/rtl871x_pwrctrl.c +++ b/drivers/staging/rtl8712/rtl871x_pwrctrl.c @@ -165,9 +165,9 @@ static void rpwm_workitem_callback(struct work_struct *work) } } -static void rpwm_check_handler (void *FunctionContext) +static void rpwm_check_handler (unsigned long data) { - struct _adapter *adapter = (struct _adapter *)FunctionContext; + struct _adapter *adapter = (struct _adapter *)data; _rpwm_check_handler(adapter); } @@ -186,8 +186,8 @@ void r8712_init_pwrctrl_priv(struct _adapter *padapter) r8712_write8(padapter, 0x1025FE58, 0); INIT_WORK(&pwrctrlpriv->SetPSModeWorkItem, SetPSModeWorkItemCallback); INIT_WORK(&pwrctrlpriv->rpwm_workitem, rpwm_workitem_callback); - _init_timer(&(pwrctrlpriv->rpwm_check_timer), - padapter->pnetdev, rpwm_check_handler, (u8 *)padapter); + setup_timer(&pwrctrlpriv->rpwm_check_timer, rpwm_check_handler, + (unsigned long)padapter); } /* diff --git a/drivers/staging/rtl8712/rtl871x_security.c b/drivers/staging/rtl8712/rtl871x_security.c index 743dd93688b5..4d5a2889b775 100644 --- a/drivers/staging/rtl8712/rtl871x_security.c +++ b/drivers/staging/rtl8712/rtl871x_security.c @@ -1392,9 +1392,9 @@ u32 r8712_aes_decrypt(struct _adapter *padapter, u8 *precvframe) return _SUCCESS; } -void r8712_use_tkipkey_handler(void *FunctionContext) +void r8712_use_tkipkey_handler(unsigned long data) { - struct _adapter *padapter = (struct _adapter *)FunctionContext; + struct _adapter *padapter = (struct _adapter *)data; padapter->securitypriv.busetkipkey = true; } diff --git a/drivers/staging/rtl8712/rtl871x_security.h b/drivers/staging/rtl8712/rtl871x_security.h index c732aeab8d2c..2295f0e64dc2 100644 --- a/drivers/staging/rtl8712/rtl871x_security.h +++ b/drivers/staging/rtl8712/rtl871x_security.h @@ -216,7 +216,7 @@ void r8712_wep_encrypt(struct _adapter *padapter, u8 *pxmitframe); u32 r8712_aes_decrypt(struct _adapter *padapter, u8 *precvframe); u32 r8712_tkip_decrypt(struct _adapter *padapter, u8 *precvframe); void r8712_wep_decrypt(struct _adapter *padapter, u8 *precvframe); -void r8712_use_tkipkey_handler(void *FunctionContext); +void r8712_use_tkipkey_handler(unsigned long data); #endif /*__RTL871X_SECURITY_H_ */ -- GitLab From a1b7f2f6367944d445c6853035830a35c6343939 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Thu, 26 Feb 2015 09:55:03 +0100 Subject: [PATCH 03032/11651] PCI/AER: Avoid info leak in __print_tlp_header() Commit fab4c256a58b ("PCI/AER: Add a TLP header print helper") introduced the helper function __print_tlp_header(), but contrary to the intention, the behaviour did change: Since we're taking the address of the parameter t, the first 4 or 8 bytes printed will be the value of the pointer t itself, and the remaining 12 or 8 bytes will be who-knows-what (something from the stack). We want to show the values of the four members of the struct aer_header_log_regs; that can be done without ugly and error-prone casts. On little-endian this should produce the same output as originally intended, and since no-one has complained about getting garbage output so far, I think big-endian should be ok too. Fixes: fab4c256a58b ("PCI/AER: Add a TLP header print helper") Signed-off-by: Rasmus Villemoes Signed-off-by: Bjorn Helgaas Acked-by: Borislav Petkov CC: stable@vger.kernel.org # v3.14+ --- drivers/pci/pcie/aer/aerdrv_errprint.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/drivers/pci/pcie/aer/aerdrv_errprint.c b/drivers/pci/pcie/aer/aerdrv_errprint.c index c6849d9e86ce..167fe411ce2e 100644 --- a/drivers/pci/pcie/aer/aerdrv_errprint.c +++ b/drivers/pci/pcie/aer/aerdrv_errprint.c @@ -132,16 +132,8 @@ static const char *aer_agent_string[] = { static void __print_tlp_header(struct pci_dev *dev, struct aer_header_log_regs *t) { - unsigned char *tlp = (unsigned char *)&t; - - dev_err(&dev->dev, " TLP Header:" - " %02x%02x%02x%02x %02x%02x%02x%02x" - " %02x%02x%02x%02x %02x%02x%02x%02x\n", - *(tlp + 3), *(tlp + 2), *(tlp + 1), *tlp, - *(tlp + 7), *(tlp + 6), *(tlp + 5), *(tlp + 4), - *(tlp + 11), *(tlp + 10), *(tlp + 9), - *(tlp + 8), *(tlp + 15), *(tlp + 14), - *(tlp + 13), *(tlp + 12)); + dev_err(&dev->dev, " TLP Header: %08x %08x %08x %08x\n", + t->dw0, t->dw1, t->dw2, t->dw3); } static void __aer_print_error(struct pci_dev *dev, -- GitLab From 5b7610f235627878617648a99dd1442997f1c889 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Fri, 6 Mar 2015 10:37:34 -0800 Subject: [PATCH 03033/11651] ARM: OMAP2+: Fix wl12xx on dm3730-evm with mainline u-boot I upgraded my u-boot and noticed that wl12xx stopped working. Turns out the kernel is not setting the quirk for the MMC2 copy clock while the eariler bootloader I had was setting it. Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/pdata-quirks.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c index 190fa43e7479..e642b079e9f3 100644 --- a/arch/arm/mach-omap2/pdata-quirks.c +++ b/arch/arm/mach-omap2/pdata-quirks.c @@ -173,6 +173,7 @@ static void __init omap3_igep0030_rev_g_legacy_init(void) static void __init omap3_evm_legacy_init(void) { + hsmmc2_internal_input_clk(); legacy_init_wl12xx(WL12XX_REFCLOCK_38, 0, 149); } -- GitLab From 93690c227acf08a2a19cbaf9acbcd2210fbb8ded Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 6 Mar 2015 10:11:21 -0800 Subject: [PATCH 03034/11651] Bluetooth: Introduce controller setting information for static address Currently it is not possible to determine if the static address is used by the controller. It is also not possible to determine if using a static on a dual-mode controller with disabled BR/EDR is possible or not. To address this issue, introduce a new setting called static-address. If support for this setting is signaled that means that the kernel supports using static addresses. And if used on dual-mode controllers with BR/EDR disabled it means that a configured static address can be used. In addition utilize the same setting for the list of current active settings that indicates if a static address is configured and if that address will be actually used. With this in mind the existing Set Static Address management command has been extended to return the current settings. That way the caller of that command can easily determine if the programmed address will be used or if extra steps are required. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/mgmt.h | 1 + net/bluetooth/mgmt.c | 28 ++++++++++++++++++++++++++-- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h index fe8eef00e9ca..0c737e4b8f57 100644 --- a/include/net/bluetooth/mgmt.h +++ b/include/net/bluetooth/mgmt.h @@ -98,6 +98,7 @@ struct mgmt_rp_read_index_list { #define MGMT_SETTING_DEBUG_KEYS 0x00001000 #define MGMT_SETTING_PRIVACY 0x00002000 #define MGMT_SETTING_CONFIGURATION 0x00004000 +#define MGMT_SETTING_STATIC_ADDRESS 0x00008000 #define MGMT_OP_READ_INFO 0x0004 #define MGMT_READ_INFO_SIZE 0 diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 967f07fdbbbe..d185a9800983 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -583,6 +583,7 @@ static u32 get_supported_settings(struct hci_dev *hdev) settings |= MGMT_SETTING_ADVERTISING; settings |= MGMT_SETTING_SECURE_CONN; settings |= MGMT_SETTING_PRIVACY; + settings |= MGMT_SETTING_STATIC_ADDRESS; } if (test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks) || @@ -638,6 +639,25 @@ static u32 get_current_settings(struct hci_dev *hdev) if (test_bit(HCI_PRIVACY, &hdev->dev_flags)) settings |= MGMT_SETTING_PRIVACY; + /* The current setting for static address has two purposes. The + * first is to indicate if the static address will be used and + * the second is to indicate if it is actually set. + * + * This means if the static address is not configured, this flag + * will never bet set. If the address is configured, then if the + * address is actually used decides if the flag is set or not. + * + * For single mode LE only controllers and dual-mode controllers + * with BR/EDR disabled, the existence of the static address will + * be evaluated. + */ + if (test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags) || + !test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags) || + !bacmp(&hdev->bdaddr, BDADDR_ANY)) { + if (bacmp(&hdev->static_addr, BDADDR_ANY)) + settings |= MGMT_SETTING_STATIC_ADDRESS; + } + return settings; } @@ -4498,10 +4518,14 @@ static int set_static_address(struct sock *sk, struct hci_dev *hdev, bacpy(&hdev->static_addr, &cp->bdaddr); - err = cmd_complete(sk, hdev->id, MGMT_OP_SET_STATIC_ADDRESS, 0, NULL, 0); + err = send_settings_rsp(sk, MGMT_OP_SET_STATIC_ADDRESS, hdev); + if (err < 0) + goto unlock; - hci_dev_unlock(hdev); + err = new_settings(hdev, sk); +unlock: + hci_dev_unlock(hdev); return err; } -- GitLab From 801c1e8da57499a9922223ee1882b2b59debd47c Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Fri, 6 Mar 2015 21:08:50 +0200 Subject: [PATCH 03035/11651] Bluetooth: Add mgmt HCI channel registration API This patch adds an API for registering HCI channels with mgmt-like semantics. For now the only user will be HCI_CHANNEL_CONTROL, but e.g. 6lowpan is intended to use this as well in the future. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- include/net/bluetooth/hci_core.h | 17 +++++++ net/bluetooth/hci_sock.c | 85 ++++++++++++++++++++++++++++++-- 2 files changed, 99 insertions(+), 3 deletions(-) diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 15c761c1f82a..0c84d48e5517 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -1273,6 +1273,23 @@ void hci_send_to_monitor(struct hci_dev *hdev, struct sk_buff *skb); void hci_sock_dev_event(struct hci_dev *hdev, int event); +struct hci_mgmt_handler { + int (*func) (struct sock *sk, struct hci_dev *hdev, void *data, + u16 data_len); + bool var_len; + size_t data_len; +}; + +struct hci_mgmt_chan { + struct list_head list; + unsigned short channel; + size_t handler_count; + const struct hci_mgmt_handler *handlers; +}; + +int hci_mgmt_chan_register(struct hci_mgmt_chan *c); +void hci_mgmt_chan_unregister(struct hci_mgmt_chan *c); + /* Management interface */ #define DISCOV_TYPE_BREDR (BIT(BDADDR_BREDR)) #define DISCOV_TYPE_LE (BIT(BDADDR_LE_PUBLIC) | \ diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index cb4bc4883350..0d5ace8922b1 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c @@ -31,6 +31,9 @@ #include #include +static LIST_HEAD(mgmt_chan_list); +static DEFINE_MUTEX(mgmt_chan_list_lock); + static atomic_t monitor_promisc = ATOMIC_INIT(0); /* ----- HCI socket interface ----- */ @@ -401,6 +404,56 @@ void hci_sock_dev_event(struct hci_dev *hdev, int event) } } +static struct hci_mgmt_chan *__hci_mgmt_chan_find(unsigned short channel) +{ + struct hci_mgmt_chan *c; + + list_for_each_entry(c, &mgmt_chan_list, list) { + if (c->channel == channel) + return c; + } + + return NULL; +} + +static struct hci_mgmt_chan *hci_mgmt_chan_find(unsigned short channel) +{ + struct hci_mgmt_chan *c; + + mutex_lock(&mgmt_chan_list_lock); + c = __hci_mgmt_chan_find(channel); + mutex_unlock(&mgmt_chan_list_lock); + + return c; +} + +int hci_mgmt_chan_register(struct hci_mgmt_chan *c) +{ + if (c->channel < HCI_CHANNEL_CONTROL) + return -EINVAL; + + mutex_lock(&mgmt_chan_list_lock); + if (__hci_mgmt_chan_find(c->channel)) { + mutex_unlock(&mgmt_chan_list_lock); + return -EALREADY; + } + + list_add_tail(&c->list, &mgmt_chan_list); + + mutex_unlock(&mgmt_chan_list_lock); + + return 0; +} +EXPORT_SYMBOL(hci_mgmt_chan_register); + +void hci_mgmt_chan_unregister(struct hci_mgmt_chan *c) +{ + mutex_lock(&mgmt_chan_list_lock); + list_del(&c->list); + mutex_unlock(&mgmt_chan_list_lock); +} +EXPORT_SYMBOL(hci_mgmt_chan_unregister); + static int hci_sock_release(struct socket *sock) { struct sock *sk = sock->sk; @@ -718,8 +771,22 @@ static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, break; default: - err = -EINVAL; - goto done; + if (!hci_mgmt_chan_find(haddr.hci_channel)) { + err = -EINVAL; + goto done; + } + + if (haddr.hci_dev != HCI_DEV_NONE) { + err = -EINVAL; + goto done; + } + + if (!capable(CAP_NET_ADMIN)) { + err = -EPERM; + goto done; + } + + break; } @@ -837,6 +904,10 @@ static int hci_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, case HCI_CHANNEL_MONITOR: sock_recv_timestamp(msg, sk, skb); break; + default: + if (hci_mgmt_chan_find(hci_pi(sk)->channel)) + sock_recv_timestamp(msg, sk, skb); + break; } skb_free_datagram(sk, skb); @@ -848,6 +919,7 @@ static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) { struct sock *sk = sock->sk; + struct hci_mgmt_chan *chan; struct hci_dev *hdev; struct sk_buff *skb; int err; @@ -876,7 +948,14 @@ static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg, err = -EOPNOTSUPP; goto done; default: - err = -EINVAL; + mutex_lock(&mgmt_chan_list_lock); + chan = __hci_mgmt_chan_find(hci_pi(sk)->channel); + if (chan) + err = -ENOSYS; /* FIXME: call handler */ + else + err = -EINVAL; + + mutex_unlock(&mgmt_chan_list_lock); goto done; } -- GitLab From 6d785aa345f525e1fdf098b7c590168f0b00f3f1 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Fri, 6 Mar 2015 21:08:51 +0200 Subject: [PATCH 03036/11651] Bluetooth: Convert mgmt to use HCI chan registration API This patch converts the existing mgmt code to use the newly introduced generic API for registering HCI channels with mgmt-like semantics. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- include/net/bluetooth/bluetooth.h | 3 +++ include/net/bluetooth/hci_core.h | 4 +++- net/bluetooth/af_bluetooth.c | 9 ++++++++ net/bluetooth/hci_sock.c | 19 +---------------- net/bluetooth/mgmt.c | 34 +++++++++++++++++++++---------- 5 files changed, 39 insertions(+), 30 deletions(-) diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index 6bb97df16d2d..e598ca096ec9 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h @@ -354,6 +354,9 @@ void l2cap_exit(void); int sco_init(void); void sco_exit(void); +int mgmt_init(void); +void mgmt_exit(void); + void bt_sock_reclassify_lock(struct sock *sk, int proto); #endif /* __BLUETOOTH_H */ diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 0c84d48e5517..b2a183d201b7 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -1309,7 +1309,9 @@ void hci_mgmt_chan_unregister(struct hci_mgmt_chan *c); #define DISCOV_BREDR_INQUIRY_LEN 0x08 #define DISCOV_LE_RESTART_DELAY msecs_to_jiffies(200) /* msec */ -int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len); +int mgmt_control(struct hci_mgmt_chan *chan, struct sock *sk, + struct msghdr *msg, size_t msglen); + int mgmt_new_settings(struct hci_dev *hdev); void mgmt_index_added(struct hci_dev *hdev); void mgmt_index_removed(struct hci_dev *hdev); diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index 20a4698e2255..70f9d945faf7 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c @@ -749,6 +749,13 @@ static int __init bt_init(void) goto sock_err; } + err = mgmt_init(); + if (err < 0) { + sco_exit(); + l2cap_exit(); + goto sock_err; + } + return 0; sock_err: @@ -763,6 +770,8 @@ error: static void __exit bt_exit(void) { + mgmt_exit(); + sco_exit(); l2cap_exit(); diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index 0d5ace8922b1..aa9ffcb9481f 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c @@ -741,19 +741,6 @@ static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, hci_pi(sk)->hdev = hdev; break; - case HCI_CHANNEL_CONTROL: - if (haddr.hci_dev != HCI_DEV_NONE) { - err = -EINVAL; - goto done; - } - - if (!capable(CAP_NET_ADMIN)) { - err = -EPERM; - goto done; - } - - break; - case HCI_CHANNEL_MONITOR: if (haddr.hci_dev != HCI_DEV_NONE) { err = -EINVAL; @@ -900,7 +887,6 @@ static int hci_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, hci_sock_cmsg(sk, msg, skb); break; case HCI_CHANNEL_USER: - case HCI_CHANNEL_CONTROL: case HCI_CHANNEL_MONITOR: sock_recv_timestamp(msg, sk, skb); break; @@ -941,9 +927,6 @@ static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg, case HCI_CHANNEL_RAW: case HCI_CHANNEL_USER: break; - case HCI_CHANNEL_CONTROL: - err = mgmt_control(sk, msg, len); - goto done; case HCI_CHANNEL_MONITOR: err = -EOPNOTSUPP; goto done; @@ -951,7 +934,7 @@ static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg, mutex_lock(&mgmt_chan_list_lock); chan = __hci_mgmt_chan_find(hci_pi(sk)->channel); if (chan) - err = -ENOSYS; /* FIXME: call handler */ + err = mgmt_control(chan, sk, msg, len); else err = -EINVAL; diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index d185a9800983..bb02dd1b82bf 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -6130,12 +6130,7 @@ unlock: return err; } -static const struct mgmt_handler { - int (*func) (struct sock *sk, struct hci_dev *hdev, void *data, - u16 data_len); - bool var_len; - size_t data_len; -} mgmt_handlers[] = { +static const struct hci_mgmt_handler mgmt_handlers[] = { { NULL }, /* 0x0000 (no command) */ { read_version, false, MGMT_READ_VERSION_SIZE }, { read_commands, false, MGMT_READ_COMMANDS_SIZE }, @@ -6197,14 +6192,15 @@ static const struct mgmt_handler { { start_service_discovery,true, MGMT_START_SERVICE_DISCOVERY_SIZE }, }; -int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) +int mgmt_control(struct hci_mgmt_chan *chan, struct sock *sk, + struct msghdr *msg, size_t msglen) { void *buf; u8 *cp; struct mgmt_hdr *hdr; u16 opcode, index, len; struct hci_dev *hdev = NULL; - const struct mgmt_handler *handler; + const struct hci_mgmt_handler *handler; int err; BT_DBG("got %zu bytes", msglen); @@ -6257,8 +6253,8 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) } } - if (opcode >= ARRAY_SIZE(mgmt_handlers) || - mgmt_handlers[opcode].func == NULL) { + if (opcode >= chan->handler_count || + chan->handlers[opcode].func == NULL) { BT_DBG("Unknown op %u", opcode); err = cmd_status(sk, index, opcode, MGMT_STATUS_UNKNOWN_COMMAND); @@ -6279,7 +6275,7 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) goto done; } - handler = &mgmt_handlers[opcode]; + handler = &chan->handlers[opcode]; if ((handler->var_len && len < handler->data_len) || (!handler->var_len && len != handler->data_len)) { @@ -7470,3 +7466,19 @@ void mgmt_reenable_advertising(struct hci_dev *hdev) enable_advertising(&req); hci_req_run(&req, adv_enable_complete); } + +static struct hci_mgmt_chan chan = { + .channel = HCI_CHANNEL_CONTROL, + .handler_count = ARRAY_SIZE(mgmt_handlers), + .handlers = mgmt_handlers, +}; + +int mgmt_init(void) +{ + return hci_mgmt_chan_register(&chan); +} + +void mgmt_exit(void) +{ + hci_mgmt_chan_unregister(&chan); +} -- GitLab From b9a245fb12315f8c6528b29a991a004859c982d5 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Fri, 6 Mar 2015 21:08:52 +0200 Subject: [PATCH 03037/11651] Bluetooth: Move all mgmt command quirks to handler table In order to completely generalize the mgmt command handling we need to move away command-specific information from mgmt_control() into the actual command table. This patch adds a new 'flags' field to the handler entries which can now contain the following command specific information: - Command takes variable length parameters - Command doesn't target any specific HCI device - Command can be sent when the HCI device is unconfigured After this the mgmt_control() function is completely generic and can potentially be reused by new HCI channels. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- include/net/bluetooth/hci_core.h | 6 +- net/bluetooth/mgmt.c | 170 ++++++++++++++++--------------- 2 files changed, 93 insertions(+), 83 deletions(-) diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index b2a183d201b7..afc641c5e55c 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -1273,11 +1273,15 @@ void hci_send_to_monitor(struct hci_dev *hdev, struct sk_buff *skb); void hci_sock_dev_event(struct hci_dev *hdev, int event); +#define HCI_MGMT_VAR_LEN (1 << 0) +#define HCI_MGMT_NO_HDEV (1 << 1) +#define HCI_MGMT_UNCONFIGURED (1 << 2) + struct hci_mgmt_handler { int (*func) (struct sock *sk, struct hci_dev *hdev, void *data, u16 data_len); - bool var_len; size_t data_len; + unsigned long flags; }; struct hci_mgmt_chan { diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index bb02dd1b82bf..f65516420a31 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -6132,64 +6132,77 @@ unlock: static const struct hci_mgmt_handler mgmt_handlers[] = { { NULL }, /* 0x0000 (no command) */ - { read_version, false, MGMT_READ_VERSION_SIZE }, - { read_commands, false, MGMT_READ_COMMANDS_SIZE }, - { read_index_list, false, MGMT_READ_INDEX_LIST_SIZE }, - { read_controller_info, false, MGMT_READ_INFO_SIZE }, - { set_powered, false, MGMT_SETTING_SIZE }, - { set_discoverable, false, MGMT_SET_DISCOVERABLE_SIZE }, - { set_connectable, false, MGMT_SETTING_SIZE }, - { set_fast_connectable, false, MGMT_SETTING_SIZE }, - { set_bondable, false, MGMT_SETTING_SIZE }, - { set_link_security, false, MGMT_SETTING_SIZE }, - { set_ssp, false, MGMT_SETTING_SIZE }, - { set_hs, false, MGMT_SETTING_SIZE }, - { set_le, false, MGMT_SETTING_SIZE }, - { set_dev_class, false, MGMT_SET_DEV_CLASS_SIZE }, - { set_local_name, false, MGMT_SET_LOCAL_NAME_SIZE }, - { add_uuid, false, MGMT_ADD_UUID_SIZE }, - { remove_uuid, false, MGMT_REMOVE_UUID_SIZE }, - { load_link_keys, true, MGMT_LOAD_LINK_KEYS_SIZE }, - { load_long_term_keys, true, MGMT_LOAD_LONG_TERM_KEYS_SIZE }, - { disconnect, false, MGMT_DISCONNECT_SIZE }, - { get_connections, false, MGMT_GET_CONNECTIONS_SIZE }, - { pin_code_reply, false, MGMT_PIN_CODE_REPLY_SIZE }, - { pin_code_neg_reply, false, MGMT_PIN_CODE_NEG_REPLY_SIZE }, - { set_io_capability, false, MGMT_SET_IO_CAPABILITY_SIZE }, - { pair_device, false, MGMT_PAIR_DEVICE_SIZE }, - { cancel_pair_device, false, MGMT_CANCEL_PAIR_DEVICE_SIZE }, - { unpair_device, false, MGMT_UNPAIR_DEVICE_SIZE }, - { user_confirm_reply, false, MGMT_USER_CONFIRM_REPLY_SIZE }, - { user_confirm_neg_reply, false, MGMT_USER_CONFIRM_NEG_REPLY_SIZE }, - { user_passkey_reply, false, MGMT_USER_PASSKEY_REPLY_SIZE }, - { user_passkey_neg_reply, false, MGMT_USER_PASSKEY_NEG_REPLY_SIZE }, - { read_local_oob_data, false, MGMT_READ_LOCAL_OOB_DATA_SIZE }, - { add_remote_oob_data, true, MGMT_ADD_REMOTE_OOB_DATA_SIZE }, - { remove_remote_oob_data, false, MGMT_REMOVE_REMOTE_OOB_DATA_SIZE }, - { start_discovery, false, MGMT_START_DISCOVERY_SIZE }, - { stop_discovery, false, MGMT_STOP_DISCOVERY_SIZE }, - { confirm_name, false, MGMT_CONFIRM_NAME_SIZE }, - { block_device, false, MGMT_BLOCK_DEVICE_SIZE }, - { unblock_device, false, MGMT_UNBLOCK_DEVICE_SIZE }, - { set_device_id, false, MGMT_SET_DEVICE_ID_SIZE }, - { set_advertising, false, MGMT_SETTING_SIZE }, - { set_bredr, false, MGMT_SETTING_SIZE }, - { set_static_address, false, MGMT_SET_STATIC_ADDRESS_SIZE }, - { set_scan_params, false, MGMT_SET_SCAN_PARAMS_SIZE }, - { set_secure_conn, false, MGMT_SETTING_SIZE }, - { set_debug_keys, false, MGMT_SETTING_SIZE }, - { set_privacy, false, MGMT_SET_PRIVACY_SIZE }, - { load_irks, true, MGMT_LOAD_IRKS_SIZE }, - { get_conn_info, false, MGMT_GET_CONN_INFO_SIZE }, - { get_clock_info, false, MGMT_GET_CLOCK_INFO_SIZE }, - { add_device, false, MGMT_ADD_DEVICE_SIZE }, - { remove_device, false, MGMT_REMOVE_DEVICE_SIZE }, - { load_conn_param, true, MGMT_LOAD_CONN_PARAM_SIZE }, - { read_unconf_index_list, false, MGMT_READ_UNCONF_INDEX_LIST_SIZE }, - { read_config_info, false, MGMT_READ_CONFIG_INFO_SIZE }, - { set_external_config, false, MGMT_SET_EXTERNAL_CONFIG_SIZE }, - { set_public_address, false, MGMT_SET_PUBLIC_ADDRESS_SIZE }, - { start_service_discovery,true, MGMT_START_SERVICE_DISCOVERY_SIZE }, + { read_version, MGMT_READ_VERSION_SIZE, + HCI_MGMT_NO_HDEV }, + { read_commands, MGMT_READ_COMMANDS_SIZE, + HCI_MGMT_NO_HDEV }, + { read_index_list, MGMT_READ_INDEX_LIST_SIZE, + HCI_MGMT_NO_HDEV }, + { read_controller_info, MGMT_READ_INFO_SIZE, 0 }, + { set_powered, MGMT_SETTING_SIZE, 0 }, + { set_discoverable, MGMT_SET_DISCOVERABLE_SIZE, 0 }, + { set_connectable, MGMT_SETTING_SIZE, 0 }, + { set_fast_connectable, MGMT_SETTING_SIZE, 0 }, + { set_bondable, MGMT_SETTING_SIZE, 0 }, + { set_link_security, MGMT_SETTING_SIZE, 0 }, + { set_ssp, MGMT_SETTING_SIZE, 0 }, + { set_hs, MGMT_SETTING_SIZE, 0 }, + { set_le, MGMT_SETTING_SIZE, 0 }, + { set_dev_class, MGMT_SET_DEV_CLASS_SIZE, 0 }, + { set_local_name, MGMT_SET_LOCAL_NAME_SIZE, 0 }, + { add_uuid, MGMT_ADD_UUID_SIZE, 0 }, + { remove_uuid, MGMT_REMOVE_UUID_SIZE, 0 }, + { load_link_keys, MGMT_LOAD_LINK_KEYS_SIZE, + HCI_MGMT_VAR_LEN }, + { load_long_term_keys, MGMT_LOAD_LONG_TERM_KEYS_SIZE, + HCI_MGMT_VAR_LEN }, + { disconnect, MGMT_DISCONNECT_SIZE, 0 }, + { get_connections, MGMT_GET_CONNECTIONS_SIZE, 0 }, + { pin_code_reply, MGMT_PIN_CODE_REPLY_SIZE, 0 }, + { pin_code_neg_reply, MGMT_PIN_CODE_NEG_REPLY_SIZE, 0 }, + { set_io_capability, MGMT_SET_IO_CAPABILITY_SIZE, 0 }, + { pair_device, MGMT_PAIR_DEVICE_SIZE, 0 }, + { cancel_pair_device, MGMT_CANCEL_PAIR_DEVICE_SIZE, 0 }, + { unpair_device, MGMT_UNPAIR_DEVICE_SIZE, 0 }, + { user_confirm_reply, MGMT_USER_CONFIRM_REPLY_SIZE, 0 }, + { user_confirm_neg_reply, MGMT_USER_CONFIRM_NEG_REPLY_SIZE, 0 }, + { user_passkey_reply, MGMT_USER_PASSKEY_REPLY_SIZE, 0 }, + { user_passkey_neg_reply, MGMT_USER_PASSKEY_NEG_REPLY_SIZE, 0 }, + { read_local_oob_data, MGMT_READ_LOCAL_OOB_DATA_SIZE }, + { add_remote_oob_data, MGMT_ADD_REMOTE_OOB_DATA_SIZE, + HCI_MGMT_VAR_LEN }, + { remove_remote_oob_data, MGMT_REMOVE_REMOTE_OOB_DATA_SIZE, 0 }, + { start_discovery, MGMT_START_DISCOVERY_SIZE, 0 }, + { stop_discovery, MGMT_STOP_DISCOVERY_SIZE, 0 }, + { confirm_name, MGMT_CONFIRM_NAME_SIZE, 0 }, + { block_device, MGMT_BLOCK_DEVICE_SIZE, 0 }, + { unblock_device, MGMT_UNBLOCK_DEVICE_SIZE, 0 }, + { set_device_id, MGMT_SET_DEVICE_ID_SIZE, 0 }, + { set_advertising, MGMT_SETTING_SIZE, 0 }, + { set_bredr, MGMT_SETTING_SIZE, 0 }, + { set_static_address, MGMT_SET_STATIC_ADDRESS_SIZE, 0 }, + { set_scan_params, MGMT_SET_SCAN_PARAMS_SIZE, 0 }, + { set_secure_conn, MGMT_SETTING_SIZE, 0 }, + { set_debug_keys, MGMT_SETTING_SIZE, 0 }, + { set_privacy, MGMT_SET_PRIVACY_SIZE, 0 }, + { load_irks, MGMT_LOAD_IRKS_SIZE, + HCI_MGMT_VAR_LEN }, + { get_conn_info, MGMT_GET_CONN_INFO_SIZE, 0 }, + { get_clock_info, MGMT_GET_CLOCK_INFO_SIZE, 0 }, + { add_device, MGMT_ADD_DEVICE_SIZE, 0 }, + { remove_device, MGMT_REMOVE_DEVICE_SIZE, 0 }, + { load_conn_param, MGMT_LOAD_CONN_PARAM_SIZE, + HCI_MGMT_VAR_LEN }, + { read_unconf_index_list, MGMT_READ_UNCONF_INDEX_LIST_SIZE, + HCI_MGMT_NO_HDEV }, + { read_config_info, MGMT_READ_CONFIG_INFO_SIZE, + HCI_MGMT_UNCONFIGURED }, + { set_external_config, MGMT_SET_EXTERNAL_CONFIG_SIZE, + HCI_MGMT_UNCONFIGURED }, + { set_public_address, MGMT_SET_PUBLIC_ADDRESS_SIZE, + HCI_MGMT_UNCONFIGURED }, + { start_service_discovery, MGMT_START_SERVICE_DISCOVERY_SIZE, + HCI_MGMT_VAR_LEN }, }; int mgmt_control(struct hci_mgmt_chan *chan, struct sock *sk, @@ -6201,6 +6214,7 @@ int mgmt_control(struct hci_mgmt_chan *chan, struct sock *sk, u16 opcode, index, len; struct hci_dev *hdev = NULL; const struct hci_mgmt_handler *handler; + bool var_len, no_hdev; int err; BT_DBG("got %zu bytes", msglen); @@ -6227,6 +6241,16 @@ int mgmt_control(struct hci_mgmt_chan *chan, struct sock *sk, goto done; } + if (opcode >= chan->handler_count || + chan->handlers[opcode].func == NULL) { + BT_DBG("Unknown op %u", opcode); + err = cmd_status(sk, index, opcode, + MGMT_STATUS_UNKNOWN_COMMAND); + goto done; + } + + handler = &chan->handlers[opcode]; + if (index != MGMT_INDEX_NONE) { hdev = hci_dev_get(index); if (!hdev) { @@ -6244,41 +6268,23 @@ int mgmt_control(struct hci_mgmt_chan *chan, struct sock *sk, } if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) && - opcode != MGMT_OP_READ_CONFIG_INFO && - opcode != MGMT_OP_SET_EXTERNAL_CONFIG && - opcode != MGMT_OP_SET_PUBLIC_ADDRESS) { + !(handler->flags & HCI_MGMT_UNCONFIGURED)) { err = cmd_status(sk, index, opcode, MGMT_STATUS_INVALID_INDEX); goto done; } } - if (opcode >= chan->handler_count || - chan->handlers[opcode].func == NULL) { - BT_DBG("Unknown op %u", opcode); - err = cmd_status(sk, index, opcode, - MGMT_STATUS_UNKNOWN_COMMAND); - goto done; - } - - if (hdev && (opcode <= MGMT_OP_READ_INDEX_LIST || - opcode == MGMT_OP_READ_UNCONF_INDEX_LIST)) { - err = cmd_status(sk, index, opcode, - MGMT_STATUS_INVALID_INDEX); - goto done; - } - - if (!hdev && (opcode > MGMT_OP_READ_INDEX_LIST && - opcode != MGMT_OP_READ_UNCONF_INDEX_LIST)) { + no_hdev = (handler->flags & HCI_MGMT_NO_HDEV); + if (no_hdev != !hdev) { err = cmd_status(sk, index, opcode, MGMT_STATUS_INVALID_INDEX); goto done; } - handler = &chan->handlers[opcode]; - - if ((handler->var_len && len < handler->data_len) || - (!handler->var_len && len != handler->data_len)) { + var_len = (handler->flags & HCI_MGMT_VAR_LEN); + if ((var_len && len < handler->data_len) || + (!var_len && len != handler->data_len)) { err = cmd_status(sk, index, opcode, MGMT_STATUS_INVALID_PARAMS); goto done; -- GitLab From a69e8375a134eb7f42d5de7e14d0816967282757 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Fri, 6 Mar 2015 21:08:53 +0200 Subject: [PATCH 03038/11651] Bluetooth: Rename cmd_status() to mgmt_cmd_status() This patch renames the cmd_status() function to mgmt_cmd_status() in preparation of making it a generic helper for other modules to use too. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- net/bluetooth/mgmt.c | 459 ++++++++++++++++++++++--------------------- 1 file changed, 230 insertions(+), 229 deletions(-) diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index f65516420a31..6f20b78e1965 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -249,7 +249,7 @@ static int mgmt_event(u16 event, struct hci_dev *hdev, void *data, u16 data_len, return 0; } -static int cmd_status(struct sock *sk, u16 index, u16 cmd, u8 status) +static int mgmt_cmd_status(struct sock *sk, u16 index, u16 cmd, u8 status) { struct sk_buff *skb; struct mgmt_hdr *hdr; @@ -1396,14 +1396,14 @@ static int set_powered(struct sock *sk, struct hci_dev *hdev, void *data, BT_DBG("request for %s", hdev->name); if (cp->val != 0x00 && cp->val != 0x01) - return cmd_status(sk, hdev->id, MGMT_OP_SET_POWERED, - MGMT_STATUS_INVALID_PARAMS); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_POWERED, + MGMT_STATUS_INVALID_PARAMS); hci_dev_lock(hdev); if (mgmt_pending_find(MGMT_OP_SET_POWERED, hdev)) { - err = cmd_status(sk, hdev->id, MGMT_OP_SET_POWERED, - MGMT_STATUS_BUSY); + err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_POWERED, + MGMT_STATUS_BUSY); goto failed; } @@ -1492,7 +1492,7 @@ static void cmd_status_rsp(struct pending_cmd *cmd, void *data) { u8 *status = data; - cmd_status(cmd->sk, cmd->index, cmd->opcode, *status); + mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, *status); mgmt_pending_remove(cmd); } @@ -1560,7 +1560,7 @@ static void set_discoverable_complete(struct hci_dev *hdev, u8 status, if (status) { u8 mgmt_err = mgmt_status(status); - cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_err); + mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_err); clear_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags); goto remove_cmd; } @@ -1616,12 +1616,12 @@ static int set_discoverable(struct sock *sk, struct hci_dev *hdev, void *data, if (!test_bit(HCI_LE_ENABLED, &hdev->dev_flags) && !test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) - return cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE, - MGMT_STATUS_REJECTED); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE, + MGMT_STATUS_REJECTED); if (cp->val != 0x00 && cp->val != 0x01 && cp->val != 0x02) - return cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE, - MGMT_STATUS_INVALID_PARAMS); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE, + MGMT_STATUS_INVALID_PARAMS); timeout = __le16_to_cpu(cp->timeout); @@ -1630,27 +1630,27 @@ static int set_discoverable(struct sock *sk, struct hci_dev *hdev, void *data, */ if ((cp->val == 0x00 && timeout > 0) || (cp->val == 0x02 && timeout == 0)) - return cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE, - MGMT_STATUS_INVALID_PARAMS); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE, + MGMT_STATUS_INVALID_PARAMS); hci_dev_lock(hdev); if (!hdev_is_powered(hdev) && timeout > 0) { - err = cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE, - MGMT_STATUS_NOT_POWERED); + err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE, + MGMT_STATUS_NOT_POWERED); goto failed; } if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, hdev) || mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, hdev)) { - err = cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE, - MGMT_STATUS_BUSY); + err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE, + MGMT_STATUS_BUSY); goto failed; } if (!test_bit(HCI_CONNECTABLE, &hdev->dev_flags)) { - err = cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE, - MGMT_STATUS_REJECTED); + err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE, + MGMT_STATUS_REJECTED); goto failed; } @@ -1819,7 +1819,7 @@ static void set_connectable_complete(struct hci_dev *hdev, u8 status, if (status) { u8 mgmt_err = mgmt_status(status); - cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_err); + mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_err); goto remove_cmd; } @@ -1894,12 +1894,12 @@ static int set_connectable(struct sock *sk, struct hci_dev *hdev, void *data, if (!test_bit(HCI_LE_ENABLED, &hdev->dev_flags) && !test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) - return cmd_status(sk, hdev->id, MGMT_OP_SET_CONNECTABLE, - MGMT_STATUS_REJECTED); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_CONNECTABLE, + MGMT_STATUS_REJECTED); if (cp->val != 0x00 && cp->val != 0x01) - return cmd_status(sk, hdev->id, MGMT_OP_SET_CONNECTABLE, - MGMT_STATUS_INVALID_PARAMS); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_CONNECTABLE, + MGMT_STATUS_INVALID_PARAMS); hci_dev_lock(hdev); @@ -1910,8 +1910,8 @@ static int set_connectable(struct sock *sk, struct hci_dev *hdev, void *data, if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, hdev) || mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, hdev)) { - err = cmd_status(sk, hdev->id, MGMT_OP_SET_CONNECTABLE, - MGMT_STATUS_BUSY); + err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_CONNECTABLE, + MGMT_STATUS_BUSY); goto failed; } @@ -1996,8 +1996,8 @@ static int set_bondable(struct sock *sk, struct hci_dev *hdev, void *data, BT_DBG("request for %s", hdev->name); if (cp->val != 0x00 && cp->val != 0x01) - return cmd_status(sk, hdev->id, MGMT_OP_SET_BONDABLE, - MGMT_STATUS_INVALID_PARAMS); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_BONDABLE, + MGMT_STATUS_INVALID_PARAMS); hci_dev_lock(hdev); @@ -2030,12 +2030,12 @@ static int set_link_security(struct sock *sk, struct hci_dev *hdev, void *data, status = mgmt_bredr_support(hdev); if (status) - return cmd_status(sk, hdev->id, MGMT_OP_SET_LINK_SECURITY, - status); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_LINK_SECURITY, + status); if (cp->val != 0x00 && cp->val != 0x01) - return cmd_status(sk, hdev->id, MGMT_OP_SET_LINK_SECURITY, - MGMT_STATUS_INVALID_PARAMS); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_LINK_SECURITY, + MGMT_STATUS_INVALID_PARAMS); hci_dev_lock(hdev); @@ -2059,8 +2059,8 @@ static int set_link_security(struct sock *sk, struct hci_dev *hdev, void *data, } if (mgmt_pending_find(MGMT_OP_SET_LINK_SECURITY, hdev)) { - err = cmd_status(sk, hdev->id, MGMT_OP_SET_LINK_SECURITY, - MGMT_STATUS_BUSY); + err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_LINK_SECURITY, + MGMT_STATUS_BUSY); goto failed; } @@ -2099,15 +2099,15 @@ static int set_ssp(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) status = mgmt_bredr_support(hdev); if (status) - return cmd_status(sk, hdev->id, MGMT_OP_SET_SSP, status); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_SSP, status); if (!lmp_ssp_capable(hdev)) - return cmd_status(sk, hdev->id, MGMT_OP_SET_SSP, - MGMT_STATUS_NOT_SUPPORTED); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_SSP, + MGMT_STATUS_NOT_SUPPORTED); if (cp->val != 0x00 && cp->val != 0x01) - return cmd_status(sk, hdev->id, MGMT_OP_SET_SSP, - MGMT_STATUS_INVALID_PARAMS); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_SSP, + MGMT_STATUS_INVALID_PARAMS); hci_dev_lock(hdev); @@ -2138,8 +2138,8 @@ static int set_ssp(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) } if (mgmt_pending_find(MGMT_OP_SET_SSP, hdev)) { - err = cmd_status(sk, hdev->id, MGMT_OP_SET_SSP, - MGMT_STATUS_BUSY); + err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_SSP, + MGMT_STATUS_BUSY); goto failed; } @@ -2180,25 +2180,25 @@ static int set_hs(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) status = mgmt_bredr_support(hdev); if (status) - return cmd_status(sk, hdev->id, MGMT_OP_SET_HS, status); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_HS, status); if (!lmp_ssp_capable(hdev)) - return cmd_status(sk, hdev->id, MGMT_OP_SET_HS, - MGMT_STATUS_NOT_SUPPORTED); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_HS, + MGMT_STATUS_NOT_SUPPORTED); if (!test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) - return cmd_status(sk, hdev->id, MGMT_OP_SET_HS, - MGMT_STATUS_REJECTED); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_HS, + MGMT_STATUS_REJECTED); if (cp->val != 0x00 && cp->val != 0x01) - return cmd_status(sk, hdev->id, MGMT_OP_SET_HS, - MGMT_STATUS_INVALID_PARAMS); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_HS, + MGMT_STATUS_INVALID_PARAMS); hci_dev_lock(hdev); if (mgmt_pending_find(MGMT_OP_SET_SSP, hdev)) { - err = cmd_status(sk, hdev->id, MGMT_OP_SET_HS, - MGMT_STATUS_BUSY); + err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_HS, + MGMT_STATUS_BUSY); goto unlock; } @@ -2206,8 +2206,8 @@ static int set_hs(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) changed = !test_and_set_bit(HCI_HS_ENABLED, &hdev->dev_flags); } else { if (hdev_is_powered(hdev)) { - err = cmd_status(sk, hdev->id, MGMT_OP_SET_HS, - MGMT_STATUS_REJECTED); + err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_HS, + MGMT_STATUS_REJECTED); goto unlock; } @@ -2278,17 +2278,17 @@ static int set_le(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) BT_DBG("request for %s", hdev->name); if (!lmp_le_capable(hdev)) - return cmd_status(sk, hdev->id, MGMT_OP_SET_LE, - MGMT_STATUS_NOT_SUPPORTED); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_LE, + MGMT_STATUS_NOT_SUPPORTED); if (cp->val != 0x00 && cp->val != 0x01) - return cmd_status(sk, hdev->id, MGMT_OP_SET_LE, - MGMT_STATUS_INVALID_PARAMS); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_LE, + MGMT_STATUS_INVALID_PARAMS); /* LE-only devices do not allow toggling LE on/off */ if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) - return cmd_status(sk, hdev->id, MGMT_OP_SET_LE, - MGMT_STATUS_REJECTED); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_LE, + MGMT_STATUS_REJECTED); hci_dev_lock(hdev); @@ -2320,8 +2320,8 @@ static int set_le(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) if (mgmt_pending_find(MGMT_OP_SET_LE, hdev) || mgmt_pending_find(MGMT_OP_SET_ADVERTISING, hdev)) { - err = cmd_status(sk, hdev->id, MGMT_OP_SET_LE, - MGMT_STATUS_BUSY); + err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_LE, + MGMT_STATUS_BUSY); goto unlock; } @@ -2436,8 +2436,8 @@ static int add_uuid(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) hci_dev_lock(hdev); if (pending_eir_or_class(hdev)) { - err = cmd_status(sk, hdev->id, MGMT_OP_ADD_UUID, - MGMT_STATUS_BUSY); + err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_ADD_UUID, + MGMT_STATUS_BUSY); goto failed; } @@ -2517,8 +2517,8 @@ static int remove_uuid(struct sock *sk, struct hci_dev *hdev, void *data, hci_dev_lock(hdev); if (pending_eir_or_class(hdev)) { - err = cmd_status(sk, hdev->id, MGMT_OP_REMOVE_UUID, - MGMT_STATUS_BUSY); + err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_REMOVE_UUID, + MGMT_STATUS_BUSY); goto unlock; } @@ -2546,8 +2546,8 @@ static int remove_uuid(struct sock *sk, struct hci_dev *hdev, void *data, } if (found == 0) { - err = cmd_status(sk, hdev->id, MGMT_OP_REMOVE_UUID, - MGMT_STATUS_INVALID_PARAMS); + err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_REMOVE_UUID, + MGMT_STATUS_INVALID_PARAMS); goto unlock; } @@ -2598,20 +2598,20 @@ static int set_dev_class(struct sock *sk, struct hci_dev *hdev, void *data, BT_DBG("request for %s", hdev->name); if (!lmp_bredr_capable(hdev)) - return cmd_status(sk, hdev->id, MGMT_OP_SET_DEV_CLASS, - MGMT_STATUS_NOT_SUPPORTED); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_DEV_CLASS, + MGMT_STATUS_NOT_SUPPORTED); hci_dev_lock(hdev); if (pending_eir_or_class(hdev)) { - err = cmd_status(sk, hdev->id, MGMT_OP_SET_DEV_CLASS, - MGMT_STATUS_BUSY); + err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_DEV_CLASS, + MGMT_STATUS_BUSY); goto unlock; } if ((cp->minor & 0x03) != 0 || (cp->major & 0xe0) != 0) { - err = cmd_status(sk, hdev->id, MGMT_OP_SET_DEV_CLASS, - MGMT_STATUS_INVALID_PARAMS); + err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_DEV_CLASS, + MGMT_STATUS_INVALID_PARAMS); goto unlock; } @@ -2671,15 +2671,15 @@ static int load_link_keys(struct sock *sk, struct hci_dev *hdev, void *data, BT_DBG("request for %s", hdev->name); if (!lmp_bredr_capable(hdev)) - return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LINK_KEYS, - MGMT_STATUS_NOT_SUPPORTED); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_LOAD_LINK_KEYS, + MGMT_STATUS_NOT_SUPPORTED); key_count = __le16_to_cpu(cp->key_count); if (key_count > max_key_count) { BT_ERR("load_link_keys: too big key_count value %u", key_count); - return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LINK_KEYS, - MGMT_STATUS_INVALID_PARAMS); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_LOAD_LINK_KEYS, + MGMT_STATUS_INVALID_PARAMS); } expected_len = sizeof(*cp) + key_count * @@ -2687,13 +2687,13 @@ static int load_link_keys(struct sock *sk, struct hci_dev *hdev, void *data, if (expected_len != len) { BT_ERR("load_link_keys: expected %u bytes, got %u bytes", expected_len, len); - return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LINK_KEYS, - MGMT_STATUS_INVALID_PARAMS); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_LOAD_LINK_KEYS, + MGMT_STATUS_INVALID_PARAMS); } if (cp->debug_keys != 0x00 && cp->debug_keys != 0x01) - return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LINK_KEYS, - MGMT_STATUS_INVALID_PARAMS); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_LOAD_LINK_KEYS, + MGMT_STATUS_INVALID_PARAMS); BT_DBG("%s debug_keys %u key_count %u", hdev->name, cp->debug_keys, key_count); @@ -2702,8 +2702,9 @@ static int load_link_keys(struct sock *sk, struct hci_dev *hdev, void *data, struct mgmt_link_key_info *key = &cp->keys[i]; if (key->addr.type != BDADDR_BREDR || key->type > 0x08) - return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LINK_KEYS, - MGMT_STATUS_INVALID_PARAMS); + return mgmt_cmd_status(sk, hdev->id, + MGMT_OP_LOAD_LINK_KEYS, + MGMT_STATUS_INVALID_PARAMS); } hci_dev_lock(hdev); @@ -2961,8 +2962,8 @@ static int get_connections(struct sock *sk, struct hci_dev *hdev, void *data, hci_dev_lock(hdev); if (!hdev_is_powered(hdev)) { - err = cmd_status(sk, hdev->id, MGMT_OP_GET_CONNECTIONS, - MGMT_STATUS_NOT_POWERED); + err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_GET_CONNECTIONS, + MGMT_STATUS_NOT_POWERED); goto unlock; } @@ -3038,15 +3039,15 @@ static int pin_code_reply(struct sock *sk, struct hci_dev *hdev, void *data, hci_dev_lock(hdev); if (!hdev_is_powered(hdev)) { - err = cmd_status(sk, hdev->id, MGMT_OP_PIN_CODE_REPLY, - MGMT_STATUS_NOT_POWERED); + err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_PIN_CODE_REPLY, + MGMT_STATUS_NOT_POWERED); goto failed; } conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->addr.bdaddr); if (!conn) { - err = cmd_status(sk, hdev->id, MGMT_OP_PIN_CODE_REPLY, - MGMT_STATUS_NOT_CONNECTED); + err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_PIN_CODE_REPLY, + MGMT_STATUS_NOT_CONNECTED); goto failed; } @@ -3059,8 +3060,8 @@ static int pin_code_reply(struct sock *sk, struct hci_dev *hdev, void *data, err = send_pin_code_neg_reply(sk, hdev, &ncp); if (err >= 0) - err = cmd_status(sk, hdev->id, MGMT_OP_PIN_CODE_REPLY, - MGMT_STATUS_INVALID_PARAMS); + err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_PIN_CODE_REPLY, + MGMT_STATUS_INVALID_PARAMS); goto failed; } @@ -3344,23 +3345,23 @@ static int cancel_pair_device(struct sock *sk, struct hci_dev *hdev, void *data, hci_dev_lock(hdev); if (!hdev_is_powered(hdev)) { - err = cmd_status(sk, hdev->id, MGMT_OP_CANCEL_PAIR_DEVICE, - MGMT_STATUS_NOT_POWERED); + err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_CANCEL_PAIR_DEVICE, + MGMT_STATUS_NOT_POWERED); goto unlock; } cmd = mgmt_pending_find(MGMT_OP_PAIR_DEVICE, hdev); if (!cmd) { - err = cmd_status(sk, hdev->id, MGMT_OP_CANCEL_PAIR_DEVICE, - MGMT_STATUS_INVALID_PARAMS); + err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_CANCEL_PAIR_DEVICE, + MGMT_STATUS_INVALID_PARAMS); goto unlock; } conn = cmd->user_data; if (bacmp(&addr->bdaddr, &conn->dst) != 0) { - err = cmd_status(sk, hdev->id, MGMT_OP_CANCEL_PAIR_DEVICE, - MGMT_STATUS_INVALID_PARAMS); + err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_CANCEL_PAIR_DEVICE, + MGMT_STATUS_INVALID_PARAMS); goto unlock; } @@ -3464,8 +3465,8 @@ static int user_confirm_reply(struct sock *sk, struct hci_dev *hdev, void *data, BT_DBG(""); if (len != sizeof(*cp)) - return cmd_status(sk, hdev->id, MGMT_OP_USER_CONFIRM_REPLY, - MGMT_STATUS_INVALID_PARAMS); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_USER_CONFIRM_REPLY, + MGMT_STATUS_INVALID_PARAMS); return user_pairing_resp(sk, hdev, &cp->addr, MGMT_OP_USER_CONFIRM_REPLY, @@ -3534,8 +3535,8 @@ static void set_name_complete(struct hci_dev *hdev, u8 status, u16 opcode) cp = cmd->param; if (status) - cmd_status(cmd->sk, hdev->id, MGMT_OP_SET_LOCAL_NAME, - mgmt_status(status)); + mgmt_cmd_status(cmd->sk, hdev->id, MGMT_OP_SET_LOCAL_NAME, + mgmt_status(status)); else cmd_complete(cmd->sk, hdev->id, MGMT_OP_SET_LOCAL_NAME, 0, cp, sizeof(*cp)); @@ -3626,20 +3627,20 @@ static int read_local_oob_data(struct sock *sk, struct hci_dev *hdev, hci_dev_lock(hdev); if (!hdev_is_powered(hdev)) { - err = cmd_status(sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA, - MGMT_STATUS_NOT_POWERED); + err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA, + MGMT_STATUS_NOT_POWERED); goto unlock; } if (!lmp_ssp_capable(hdev)) { - err = cmd_status(sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA, - MGMT_STATUS_NOT_SUPPORTED); + err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA, + MGMT_STATUS_NOT_SUPPORTED); goto unlock; } if (mgmt_pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, hdev)) { - err = cmd_status(sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA, - MGMT_STATUS_BUSY); + err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA, + MGMT_STATUS_BUSY); goto unlock; } @@ -3758,8 +3759,8 @@ static int add_remote_oob_data(struct sock *sk, struct hci_dev *hdev, status, &cp->addr, sizeof(cp->addr)); } else { BT_ERR("add_remote_oob_data: invalid length of %u bytes", len); - err = cmd_status(sk, hdev->id, MGMT_OP_ADD_REMOTE_OOB_DATA, - MGMT_STATUS_INVALID_PARAMS); + err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_ADD_REMOTE_OOB_DATA, + MGMT_STATUS_INVALID_PARAMS); } unlock: @@ -4352,8 +4353,8 @@ static int set_device_id(struct sock *sk, struct hci_dev *hdev, void *data, source = __le16_to_cpu(cp->source); if (source > 0x0002) - return cmd_status(sk, hdev->id, MGMT_OP_SET_DEVICE_ID, - MGMT_STATUS_INVALID_PARAMS); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_DEVICE_ID, + MGMT_STATUS_INVALID_PARAMS); hci_dev_lock(hdev); @@ -4418,12 +4419,12 @@ static int set_advertising(struct sock *sk, struct hci_dev *hdev, void *data, status = mgmt_le_support(hdev); if (status) - return cmd_status(sk, hdev->id, MGMT_OP_SET_ADVERTISING, - status); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_ADVERTISING, + status); if (cp->val != 0x00 && cp->val != 0x01) - return cmd_status(sk, hdev->id, MGMT_OP_SET_ADVERTISING, - MGMT_STATUS_INVALID_PARAMS); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_ADVERTISING, + MGMT_STATUS_INVALID_PARAMS); hci_dev_lock(hdev); @@ -4458,8 +4459,8 @@ static int set_advertising(struct sock *sk, struct hci_dev *hdev, void *data, if (mgmt_pending_find(MGMT_OP_SET_ADVERTISING, hdev) || mgmt_pending_find(MGMT_OP_SET_LE, hdev)) { - err = cmd_status(sk, hdev->id, MGMT_OP_SET_ADVERTISING, - MGMT_STATUS_BUSY); + err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_ADVERTISING, + MGMT_STATUS_BUSY); goto unlock; } @@ -4494,24 +4495,24 @@ static int set_static_address(struct sock *sk, struct hci_dev *hdev, BT_DBG("%s", hdev->name); if (!lmp_le_capable(hdev)) - return cmd_status(sk, hdev->id, MGMT_OP_SET_STATIC_ADDRESS, - MGMT_STATUS_NOT_SUPPORTED); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_STATIC_ADDRESS, + MGMT_STATUS_NOT_SUPPORTED); if (hdev_is_powered(hdev)) - return cmd_status(sk, hdev->id, MGMT_OP_SET_STATIC_ADDRESS, - MGMT_STATUS_REJECTED); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_STATIC_ADDRESS, + MGMT_STATUS_REJECTED); if (bacmp(&cp->bdaddr, BDADDR_ANY)) { if (!bacmp(&cp->bdaddr, BDADDR_NONE)) - return cmd_status(sk, hdev->id, - MGMT_OP_SET_STATIC_ADDRESS, - MGMT_STATUS_INVALID_PARAMS); + return mgmt_cmd_status(sk, hdev->id, + MGMT_OP_SET_STATIC_ADDRESS, + MGMT_STATUS_INVALID_PARAMS); /* Two most significant bits shall be set */ if ((cp->bdaddr.b[5] & 0xc0) != 0xc0) - return cmd_status(sk, hdev->id, - MGMT_OP_SET_STATIC_ADDRESS, - MGMT_STATUS_INVALID_PARAMS); + return mgmt_cmd_status(sk, hdev->id, + MGMT_OP_SET_STATIC_ADDRESS, + MGMT_STATUS_INVALID_PARAMS); } hci_dev_lock(hdev); @@ -4539,24 +4540,24 @@ static int set_scan_params(struct sock *sk, struct hci_dev *hdev, BT_DBG("%s", hdev->name); if (!lmp_le_capable(hdev)) - return cmd_status(sk, hdev->id, MGMT_OP_SET_SCAN_PARAMS, - MGMT_STATUS_NOT_SUPPORTED); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_SCAN_PARAMS, + MGMT_STATUS_NOT_SUPPORTED); interval = __le16_to_cpu(cp->interval); if (interval < 0x0004 || interval > 0x4000) - return cmd_status(sk, hdev->id, MGMT_OP_SET_SCAN_PARAMS, - MGMT_STATUS_INVALID_PARAMS); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_SCAN_PARAMS, + MGMT_STATUS_INVALID_PARAMS); window = __le16_to_cpu(cp->window); if (window < 0x0004 || window > 0x4000) - return cmd_status(sk, hdev->id, MGMT_OP_SET_SCAN_PARAMS, - MGMT_STATUS_INVALID_PARAMS); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_SCAN_PARAMS, + MGMT_STATUS_INVALID_PARAMS); if (window > interval) - return cmd_status(sk, hdev->id, MGMT_OP_SET_SCAN_PARAMS, - MGMT_STATUS_INVALID_PARAMS); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_SCAN_PARAMS, + MGMT_STATUS_INVALID_PARAMS); hci_dev_lock(hdev); @@ -4599,8 +4600,8 @@ static void fast_connectable_complete(struct hci_dev *hdev, u8 status, goto unlock; if (status) { - cmd_status(cmd->sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE, - mgmt_status(status)); + mgmt_cmd_status(cmd->sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE, + mgmt_status(status)); } else { struct mgmt_mode *cp = cmd->param; @@ -4631,26 +4632,26 @@ static int set_fast_connectable(struct sock *sk, struct hci_dev *hdev, if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags) || hdev->hci_ver < BLUETOOTH_VER_1_2) - return cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE, - MGMT_STATUS_NOT_SUPPORTED); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE, + MGMT_STATUS_NOT_SUPPORTED); if (cp->val != 0x00 && cp->val != 0x01) - return cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE, - MGMT_STATUS_INVALID_PARAMS); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE, + MGMT_STATUS_INVALID_PARAMS); if (!hdev_is_powered(hdev)) - return cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE, - MGMT_STATUS_NOT_POWERED); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE, + MGMT_STATUS_NOT_POWERED); if (!test_bit(HCI_CONNECTABLE, &hdev->dev_flags)) - return cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE, - MGMT_STATUS_REJECTED); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE, + MGMT_STATUS_REJECTED); hci_dev_lock(hdev); if (mgmt_pending_find(MGMT_OP_SET_FAST_CONNECTABLE, hdev)) { - err = cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE, - MGMT_STATUS_BUSY); + err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE, + MGMT_STATUS_BUSY); goto unlock; } @@ -4673,8 +4674,8 @@ static int set_fast_connectable(struct sock *sk, struct hci_dev *hdev, err = hci_req_run(&req, fast_connectable_complete); if (err < 0) { - err = cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE, - MGMT_STATUS_FAILED); + err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE, + MGMT_STATUS_FAILED); mgmt_pending_remove(cmd); } @@ -4704,7 +4705,7 @@ static void set_bredr_complete(struct hci_dev *hdev, u8 status, u16 opcode) */ clear_bit(HCI_BREDR_ENABLED, &hdev->dev_flags); - cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_err); + mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_err); } else { send_settings_rsp(cmd->sk, MGMT_OP_SET_BREDR, hdev); new_settings(hdev, cmd->sk); @@ -4726,16 +4727,16 @@ static int set_bredr(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) BT_DBG("request for %s", hdev->name); if (!lmp_bredr_capable(hdev) || !lmp_le_capable(hdev)) - return cmd_status(sk, hdev->id, MGMT_OP_SET_BREDR, - MGMT_STATUS_NOT_SUPPORTED); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_BREDR, + MGMT_STATUS_NOT_SUPPORTED); if (!test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) - return cmd_status(sk, hdev->id, MGMT_OP_SET_BREDR, - MGMT_STATUS_REJECTED); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_BREDR, + MGMT_STATUS_REJECTED); if (cp->val != 0x00 && cp->val != 0x01) - return cmd_status(sk, hdev->id, MGMT_OP_SET_BREDR, - MGMT_STATUS_INVALID_PARAMS); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_BREDR, + MGMT_STATUS_INVALID_PARAMS); hci_dev_lock(hdev); @@ -4765,8 +4766,8 @@ static int set_bredr(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) /* Reject disabling when powered on */ if (!cp->val) { - err = cmd_status(sk, hdev->id, MGMT_OP_SET_BREDR, - MGMT_STATUS_REJECTED); + err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_BREDR, + MGMT_STATUS_REJECTED); goto unlock; } else { /* When configuring a dual-mode controller to operate @@ -4786,15 +4787,15 @@ static int set_bredr(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags) && (bacmp(&hdev->static_addr, BDADDR_ANY) || test_bit(HCI_SC_ENABLED, &hdev->dev_flags))) { - err = cmd_status(sk, hdev->id, MGMT_OP_SET_BREDR, - MGMT_STATUS_REJECTED); + err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_BREDR, + MGMT_STATUS_REJECTED); goto unlock; } } if (mgmt_pending_find(MGMT_OP_SET_BREDR, hdev)) { - err = cmd_status(sk, hdev->id, MGMT_OP_SET_BREDR, - MGMT_STATUS_BUSY); + err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_BREDR, + MGMT_STATUS_BUSY); goto unlock; } @@ -4842,8 +4843,8 @@ static void sc_enable_complete(struct hci_dev *hdev, u8 status, u16 opcode) goto unlock; if (status) { - cmd_status(cmd->sk, cmd->index, cmd->opcode, - mgmt_status(status)); + mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, + mgmt_status(status)); goto remove; } @@ -4886,17 +4887,17 @@ static int set_secure_conn(struct sock *sk, struct hci_dev *hdev, if (!lmp_sc_capable(hdev) && !test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) - return cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN, - MGMT_STATUS_NOT_SUPPORTED); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN, + MGMT_STATUS_NOT_SUPPORTED); if (test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags) && lmp_sc_capable(hdev) && !test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) - return cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN, - MGMT_STATUS_REJECTED); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN, + MGMT_STATUS_REJECTED); if (cp->val != 0x00 && cp->val != 0x01 && cp->val != 0x02) - return cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN, + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN, MGMT_STATUS_INVALID_PARAMS); hci_dev_lock(hdev); @@ -4929,8 +4930,8 @@ static int set_secure_conn(struct sock *sk, struct hci_dev *hdev, } if (mgmt_pending_find(MGMT_OP_SET_SECURE_CONN, hdev)) { - err = cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN, - MGMT_STATUS_BUSY); + err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN, + MGMT_STATUS_BUSY); goto failed; } @@ -4971,8 +4972,8 @@ static int set_debug_keys(struct sock *sk, struct hci_dev *hdev, BT_DBG("request for %s", hdev->name); if (cp->val != 0x00 && cp->val != 0x01 && cp->val != 0x02) - return cmd_status(sk, hdev->id, MGMT_OP_SET_DEBUG_KEYS, - MGMT_STATUS_INVALID_PARAMS); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_DEBUG_KEYS, + MGMT_STATUS_INVALID_PARAMS); hci_dev_lock(hdev); @@ -5019,16 +5020,16 @@ static int set_privacy(struct sock *sk, struct hci_dev *hdev, void *cp_data, BT_DBG("request for %s", hdev->name); if (!lmp_le_capable(hdev)) - return cmd_status(sk, hdev->id, MGMT_OP_SET_PRIVACY, - MGMT_STATUS_NOT_SUPPORTED); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_PRIVACY, + MGMT_STATUS_NOT_SUPPORTED); if (cp->privacy != 0x00 && cp->privacy != 0x01) - return cmd_status(sk, hdev->id, MGMT_OP_SET_PRIVACY, - MGMT_STATUS_INVALID_PARAMS); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_PRIVACY, + MGMT_STATUS_INVALID_PARAMS); if (hdev_is_powered(hdev)) - return cmd_status(sk, hdev->id, MGMT_OP_SET_PRIVACY, - MGMT_STATUS_REJECTED); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_PRIVACY, + MGMT_STATUS_REJECTED); hci_dev_lock(hdev); @@ -5087,22 +5088,22 @@ static int load_irks(struct sock *sk, struct hci_dev *hdev, void *cp_data, BT_DBG("request for %s", hdev->name); if (!lmp_le_capable(hdev)) - return cmd_status(sk, hdev->id, MGMT_OP_LOAD_IRKS, - MGMT_STATUS_NOT_SUPPORTED); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_LOAD_IRKS, + MGMT_STATUS_NOT_SUPPORTED); irk_count = __le16_to_cpu(cp->irk_count); if (irk_count > max_irk_count) { BT_ERR("load_irks: too big irk_count value %u", irk_count); - return cmd_status(sk, hdev->id, MGMT_OP_LOAD_IRKS, - MGMT_STATUS_INVALID_PARAMS); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_LOAD_IRKS, + MGMT_STATUS_INVALID_PARAMS); } expected_len = sizeof(*cp) + irk_count * sizeof(struct mgmt_irk_info); if (expected_len != len) { BT_ERR("load_irks: expected %u bytes, got %u bytes", expected_len, len); - return cmd_status(sk, hdev->id, MGMT_OP_LOAD_IRKS, - MGMT_STATUS_INVALID_PARAMS); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_LOAD_IRKS, + MGMT_STATUS_INVALID_PARAMS); } BT_DBG("%s irk_count %u", hdev->name, irk_count); @@ -5111,9 +5112,9 @@ static int load_irks(struct sock *sk, struct hci_dev *hdev, void *cp_data, struct mgmt_irk_info *key = &cp->irks[i]; if (!irk_is_valid(key)) - return cmd_status(sk, hdev->id, - MGMT_OP_LOAD_IRKS, - MGMT_STATUS_INVALID_PARAMS); + return mgmt_cmd_status(sk, hdev->id, + MGMT_OP_LOAD_IRKS, + MGMT_STATUS_INVALID_PARAMS); } hci_dev_lock(hdev); @@ -5173,14 +5174,14 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev, BT_DBG("request for %s", hdev->name); if (!lmp_le_capable(hdev)) - return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LONG_TERM_KEYS, - MGMT_STATUS_NOT_SUPPORTED); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_LOAD_LONG_TERM_KEYS, + MGMT_STATUS_NOT_SUPPORTED); key_count = __le16_to_cpu(cp->key_count); if (key_count > max_key_count) { BT_ERR("load_ltks: too big key_count value %u", key_count); - return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LONG_TERM_KEYS, - MGMT_STATUS_INVALID_PARAMS); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_LOAD_LONG_TERM_KEYS, + MGMT_STATUS_INVALID_PARAMS); } expected_len = sizeof(*cp) + key_count * @@ -5188,8 +5189,8 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev, if (expected_len != len) { BT_ERR("load_keys: expected %u bytes, got %u bytes", expected_len, len); - return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LONG_TERM_KEYS, - MGMT_STATUS_INVALID_PARAMS); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_LOAD_LONG_TERM_KEYS, + MGMT_STATUS_INVALID_PARAMS); } BT_DBG("%s key_count %u", hdev->name, key_count); @@ -5198,9 +5199,9 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev, struct mgmt_ltk_info *key = &cp->keys[i]; if (!ltk_is_valid(key)) - return cmd_status(sk, hdev->id, - MGMT_OP_LOAD_LONG_TERM_KEYS, - MGMT_STATUS_INVALID_PARAMS); + return mgmt_cmd_status(sk, hdev->id, + MGMT_OP_LOAD_LONG_TERM_KEYS, + MGMT_STATUS_INVALID_PARAMS); } hci_dev_lock(hdev); @@ -5945,15 +5946,15 @@ static int load_conn_param(struct sock *sk, struct hci_dev *hdev, void *data, int i; if (!lmp_le_capable(hdev)) - return cmd_status(sk, hdev->id, MGMT_OP_LOAD_CONN_PARAM, - MGMT_STATUS_NOT_SUPPORTED); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_LOAD_CONN_PARAM, + MGMT_STATUS_NOT_SUPPORTED); param_count = __le16_to_cpu(cp->param_count); if (param_count > max_param_count) { BT_ERR("load_conn_param: too big param_count value %u", param_count); - return cmd_status(sk, hdev->id, MGMT_OP_LOAD_CONN_PARAM, - MGMT_STATUS_INVALID_PARAMS); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_LOAD_CONN_PARAM, + MGMT_STATUS_INVALID_PARAMS); } expected_len = sizeof(*cp) + param_count * @@ -5961,8 +5962,8 @@ static int load_conn_param(struct sock *sk, struct hci_dev *hdev, void *data, if (expected_len != len) { BT_ERR("load_conn_param: expected %u bytes, got %u bytes", expected_len, len); - return cmd_status(sk, hdev->id, MGMT_OP_LOAD_CONN_PARAM, - MGMT_STATUS_INVALID_PARAMS); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_LOAD_CONN_PARAM, + MGMT_STATUS_INVALID_PARAMS); } BT_DBG("%s param_count %u", hdev->name, param_count); @@ -6030,16 +6031,16 @@ static int set_external_config(struct sock *sk, struct hci_dev *hdev, BT_DBG("%s", hdev->name); if (hdev_is_powered(hdev)) - return cmd_status(sk, hdev->id, MGMT_OP_SET_EXTERNAL_CONFIG, - MGMT_STATUS_REJECTED); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_EXTERNAL_CONFIG, + MGMT_STATUS_REJECTED); if (cp->config != 0x00 && cp->config != 0x01) - return cmd_status(sk, hdev->id, MGMT_OP_SET_EXTERNAL_CONFIG, - MGMT_STATUS_INVALID_PARAMS); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_EXTERNAL_CONFIG, + MGMT_STATUS_INVALID_PARAMS); if (!test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks)) - return cmd_status(sk, hdev->id, MGMT_OP_SET_EXTERNAL_CONFIG, - MGMT_STATUS_NOT_SUPPORTED); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_EXTERNAL_CONFIG, + MGMT_STATUS_NOT_SUPPORTED); hci_dev_lock(hdev); @@ -6088,16 +6089,16 @@ static int set_public_address(struct sock *sk, struct hci_dev *hdev, BT_DBG("%s", hdev->name); if (hdev_is_powered(hdev)) - return cmd_status(sk, hdev->id, MGMT_OP_SET_PUBLIC_ADDRESS, - MGMT_STATUS_REJECTED); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_PUBLIC_ADDRESS, + MGMT_STATUS_REJECTED); if (!bacmp(&cp->bdaddr, BDADDR_ANY)) - return cmd_status(sk, hdev->id, MGMT_OP_SET_PUBLIC_ADDRESS, - MGMT_STATUS_INVALID_PARAMS); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_PUBLIC_ADDRESS, + MGMT_STATUS_INVALID_PARAMS); if (!hdev->set_bdaddr) - return cmd_status(sk, hdev->id, MGMT_OP_SET_PUBLIC_ADDRESS, - MGMT_STATUS_NOT_SUPPORTED); + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_PUBLIC_ADDRESS, + MGMT_STATUS_NOT_SUPPORTED); hci_dev_lock(hdev); @@ -6244,8 +6245,8 @@ int mgmt_control(struct hci_mgmt_chan *chan, struct sock *sk, if (opcode >= chan->handler_count || chan->handlers[opcode].func == NULL) { BT_DBG("Unknown op %u", opcode); - err = cmd_status(sk, index, opcode, - MGMT_STATUS_UNKNOWN_COMMAND); + err = mgmt_cmd_status(sk, index, opcode, + MGMT_STATUS_UNKNOWN_COMMAND); goto done; } @@ -6254,39 +6255,39 @@ int mgmt_control(struct hci_mgmt_chan *chan, struct sock *sk, if (index != MGMT_INDEX_NONE) { hdev = hci_dev_get(index); if (!hdev) { - err = cmd_status(sk, index, opcode, - MGMT_STATUS_INVALID_INDEX); + err = mgmt_cmd_status(sk, index, opcode, + MGMT_STATUS_INVALID_INDEX); goto done; } if (test_bit(HCI_SETUP, &hdev->dev_flags) || test_bit(HCI_CONFIG, &hdev->dev_flags) || test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) { - err = cmd_status(sk, index, opcode, - MGMT_STATUS_INVALID_INDEX); + err = mgmt_cmd_status(sk, index, opcode, + MGMT_STATUS_INVALID_INDEX); goto done; } if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) && !(handler->flags & HCI_MGMT_UNCONFIGURED)) { - err = cmd_status(sk, index, opcode, - MGMT_STATUS_INVALID_INDEX); + err = mgmt_cmd_status(sk, index, opcode, + MGMT_STATUS_INVALID_INDEX); goto done; } } no_hdev = (handler->flags & HCI_MGMT_NO_HDEV); if (no_hdev != !hdev) { - err = cmd_status(sk, index, opcode, - MGMT_STATUS_INVALID_INDEX); + err = mgmt_cmd_status(sk, index, opcode, + MGMT_STATUS_INVALID_INDEX); goto done; } var_len = (handler->flags & HCI_MGMT_VAR_LEN); if ((var_len && len < handler->data_len) || (!var_len && len != handler->data_len)) { - err = cmd_status(sk, index, opcode, - MGMT_STATUS_INVALID_PARAMS); + err = mgmt_cmd_status(sk, index, opcode, + MGMT_STATUS_INVALID_PARAMS); goto done; } @@ -6526,7 +6527,7 @@ void mgmt_set_powered_failed(struct hci_dev *hdev, int err) else status = MGMT_STATUS_FAILED; - cmd_status(cmd->sk, hdev->id, MGMT_OP_SET_POWERED, status); + mgmt_cmd_status(cmd->sk, hdev->id, MGMT_OP_SET_POWERED, status); mgmt_pending_remove(cmd); } @@ -7201,8 +7202,8 @@ void mgmt_read_local_oob_data_complete(struct hci_dev *hdev, u8 *hash192, return; if (status) { - cmd_status(cmd->sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA, - mgmt_status(status)); + mgmt_cmd_status(cmd->sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA, + mgmt_status(status)); } else { struct mgmt_rp_read_local_oob_data rp; size_t rp_size = sizeof(rp); -- GitLab From 2a1afb5ac8d580d2013c2ccc548b4f2689c5ad7a Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Fri, 6 Mar 2015 21:08:54 +0200 Subject: [PATCH 03039/11651] Bluetooth: Rename cmd_complete() to mgmt_cmd_complete() This patch renames the cmd_complete() function to mgmt_cmd_complete() in preparation of making it a generic helper for other modules to use too. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- net/bluetooth/mgmt.c | 442 ++++++++++++++++++++++--------------------- 1 file changed, 229 insertions(+), 213 deletions(-) diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 6f20b78e1965..835a459531ab 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -279,8 +279,8 @@ static int mgmt_cmd_status(struct sock *sk, u16 index, u16 cmd, u8 status) return err; } -static int cmd_complete(struct sock *sk, u16 index, u16 cmd, u8 status, - void *rp, size_t rp_len) +static int mgmt_cmd_complete(struct sock *sk, u16 index, u16 cmd, u8 status, + void *rp, size_t rp_len) { struct sk_buff *skb; struct mgmt_hdr *hdr; @@ -323,8 +323,8 @@ static int read_version(struct sock *sk, struct hci_dev *hdev, void *data, rp.version = MGMT_VERSION; rp.revision = cpu_to_le16(MGMT_REVISION); - return cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_VERSION, 0, &rp, - sizeof(rp)); + return mgmt_cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_VERSION, 0, + &rp, sizeof(rp)); } static int read_commands(struct sock *sk, struct hci_dev *hdev, void *data, @@ -354,8 +354,8 @@ static int read_commands(struct sock *sk, struct hci_dev *hdev, void *data, for (i = 0; i < num_events; i++, opcode++) put_unaligned_le16(mgmt_events[i], opcode); - err = cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_COMMANDS, 0, rp, - rp_size); + err = mgmt_cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_COMMANDS, 0, + rp, rp_size); kfree(rp); return err; @@ -413,8 +413,8 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data, read_unlock(&hci_dev_list_lock); - err = cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_INDEX_LIST, 0, rp, - rp_len); + err = mgmt_cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_INDEX_LIST, + 0, rp, rp_len); kfree(rp); @@ -473,8 +473,8 @@ static int read_unconf_index_list(struct sock *sk, struct hci_dev *hdev, read_unlock(&hci_dev_list_lock); - err = cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_UNCONF_INDEX_LIST, - 0, rp, rp_len); + err = mgmt_cmd_complete(sk, MGMT_INDEX_NONE, + MGMT_OP_READ_UNCONF_INDEX_LIST, 0, rp, rp_len); kfree(rp); @@ -521,8 +521,8 @@ static int send_options_rsp(struct sock *sk, u16 opcode, struct hci_dev *hdev) { __le32 options = get_missing_options(hdev); - return cmd_complete(sk, hdev->id, opcode, 0, &options, - sizeof(options)); + return mgmt_cmd_complete(sk, hdev->id, opcode, 0, &options, + sizeof(options)); } static int read_config_info(struct sock *sk, struct hci_dev *hdev, @@ -549,8 +549,8 @@ static int read_config_info(struct sock *sk, struct hci_dev *hdev, hci_dev_unlock(hdev); - return cmd_complete(sk, hdev->id, MGMT_OP_READ_CONFIG_INFO, 0, &rp, - sizeof(rp)); + return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_READ_CONFIG_INFO, 0, + &rp, sizeof(rp)); } static u32 get_supported_settings(struct hci_dev *hdev) @@ -1206,8 +1206,8 @@ static int read_controller_info(struct sock *sk, struct hci_dev *hdev, hci_dev_unlock(hdev); - return cmd_complete(sk, hdev->id, MGMT_OP_READ_INFO, 0, &rp, - sizeof(rp)); + return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_READ_INFO, 0, &rp, + sizeof(rp)); } static void mgmt_pending_free(struct pending_cmd *cmd) @@ -1271,8 +1271,8 @@ static int send_settings_rsp(struct sock *sk, u16 opcode, struct hci_dev *hdev) { __le32 settings = cpu_to_le32(get_current_settings(hdev)); - return cmd_complete(sk, hdev->id, opcode, 0, &settings, - sizeof(settings)); + return mgmt_cmd_complete(sk, hdev->id, opcode, 0, &settings, + sizeof(settings)); } static void clean_up_hci_complete(struct hci_dev *hdev, u8 status, u16 opcode) @@ -1512,14 +1512,14 @@ static void cmd_complete_rsp(struct pending_cmd *cmd, void *data) static int generic_cmd_complete(struct pending_cmd *cmd, u8 status) { - return cmd_complete(cmd->sk, cmd->index, cmd->opcode, status, - cmd->param, cmd->param_len); + return mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, status, + cmd->param, cmd->param_len); } static int addr_cmd_complete(struct pending_cmd *cmd, u8 status) { - return cmd_complete(cmd->sk, cmd->index, cmd->opcode, status, cmd->param, - sizeof(struct mgmt_addr_info)); + return mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, status, + cmd->param, sizeof(struct mgmt_addr_info)); } static u8 mgmt_bredr_support(struct hci_dev *hdev) @@ -2407,8 +2407,8 @@ static void mgmt_class_complete(struct hci_dev *hdev, u16 mgmt_op, u8 status) if (!cmd) goto unlock; - cmd_complete(cmd->sk, cmd->index, cmd->opcode, mgmt_status(status), - hdev->dev_class, 3); + mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, + mgmt_status(status), hdev->dev_class, 3); mgmt_pending_remove(cmd); @@ -2463,8 +2463,8 @@ static int add_uuid(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) if (err != -ENODATA) goto failed; - err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_UUID, 0, - hdev->dev_class, 3); + err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_ADD_UUID, 0, + hdev->dev_class, 3); goto failed; } @@ -2526,8 +2526,9 @@ static int remove_uuid(struct sock *sk, struct hci_dev *hdev, void *data, hci_uuids_clear(hdev); if (enable_service_cache(hdev)) { - err = cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_UUID, - 0, hdev->dev_class, 3); + err = mgmt_cmd_complete(sk, hdev->id, + MGMT_OP_REMOVE_UUID, + 0, hdev->dev_class, 3); goto unlock; } @@ -2562,8 +2563,8 @@ update_class: if (err != -ENODATA) goto unlock; - err = cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_UUID, 0, - hdev->dev_class, 3); + err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_UUID, 0, + hdev->dev_class, 3); goto unlock; } @@ -2619,8 +2620,8 @@ static int set_dev_class(struct sock *sk, struct hci_dev *hdev, void *data, hdev->minor_class = cp->minor; if (!hdev_is_powered(hdev)) { - err = cmd_complete(sk, hdev->id, MGMT_OP_SET_DEV_CLASS, 0, - hdev->dev_class, 3); + err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_SET_DEV_CLASS, 0, + hdev->dev_class, 3); goto unlock; } @@ -2640,8 +2641,8 @@ static int set_dev_class(struct sock *sk, struct hci_dev *hdev, void *data, if (err != -ENODATA) goto unlock; - err = cmd_complete(sk, hdev->id, MGMT_OP_SET_DEV_CLASS, 0, - hdev->dev_class, 3); + err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_SET_DEV_CLASS, 0, + hdev->dev_class, 3); goto unlock; } @@ -2734,7 +2735,7 @@ static int load_link_keys(struct sock *sk, struct hci_dev *hdev, void *data, key->type, key->pin_len, NULL); } - cmd_complete(sk, hdev->id, MGMT_OP_LOAD_LINK_KEYS, 0, NULL, 0); + mgmt_cmd_complete(sk, hdev->id, MGMT_OP_LOAD_LINK_KEYS, 0, NULL, 0); hci_dev_unlock(hdev); @@ -2768,20 +2769,21 @@ static int unpair_device(struct sock *sk, struct hci_dev *hdev, void *data, rp.addr.type = cp->addr.type; if (!bdaddr_type_is_valid(cp->addr.type)) - return cmd_complete(sk, hdev->id, MGMT_OP_UNPAIR_DEVICE, - MGMT_STATUS_INVALID_PARAMS, - &rp, sizeof(rp)); + return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_UNPAIR_DEVICE, + MGMT_STATUS_INVALID_PARAMS, + &rp, sizeof(rp)); if (cp->disconnect != 0x00 && cp->disconnect != 0x01) - return cmd_complete(sk, hdev->id, MGMT_OP_UNPAIR_DEVICE, - MGMT_STATUS_INVALID_PARAMS, - &rp, sizeof(rp)); + return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_UNPAIR_DEVICE, + MGMT_STATUS_INVALID_PARAMS, + &rp, sizeof(rp)); hci_dev_lock(hdev); if (!hdev_is_powered(hdev)) { - err = cmd_complete(sk, hdev->id, MGMT_OP_UNPAIR_DEVICE, - MGMT_STATUS_NOT_POWERED, &rp, sizeof(rp)); + err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_UNPAIR_DEVICE, + MGMT_STATUS_NOT_POWERED, &rp, + sizeof(rp)); goto unlock; } @@ -2831,8 +2833,9 @@ static int unpair_device(struct sock *sk, struct hci_dev *hdev, void *data, } if (err < 0) { - err = cmd_complete(sk, hdev->id, MGMT_OP_UNPAIR_DEVICE, - MGMT_STATUS_NOT_PAIRED, &rp, sizeof(rp)); + err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_UNPAIR_DEVICE, + MGMT_STATUS_NOT_PAIRED, &rp, + sizeof(rp)); goto unlock; } @@ -2840,8 +2843,8 @@ static int unpair_device(struct sock *sk, struct hci_dev *hdev, void *data, * link is requested. */ if (!conn) { - err = cmd_complete(sk, hdev->id, MGMT_OP_UNPAIR_DEVICE, 0, - &rp, sizeof(rp)); + err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_UNPAIR_DEVICE, 0, + &rp, sizeof(rp)); device_unpaired(hdev, &cp->addr.bdaddr, cp->addr.type, sk); goto unlock; } @@ -2882,21 +2885,22 @@ static int disconnect(struct sock *sk, struct hci_dev *hdev, void *data, rp.addr.type = cp->addr.type; if (!bdaddr_type_is_valid(cp->addr.type)) - return cmd_complete(sk, hdev->id, MGMT_OP_DISCONNECT, - MGMT_STATUS_INVALID_PARAMS, - &rp, sizeof(rp)); + return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_DISCONNECT, + MGMT_STATUS_INVALID_PARAMS, + &rp, sizeof(rp)); hci_dev_lock(hdev); if (!test_bit(HCI_UP, &hdev->flags)) { - err = cmd_complete(sk, hdev->id, MGMT_OP_DISCONNECT, - MGMT_STATUS_NOT_POWERED, &rp, sizeof(rp)); + err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_DISCONNECT, + MGMT_STATUS_NOT_POWERED, &rp, + sizeof(rp)); goto failed; } if (mgmt_pending_find(MGMT_OP_DISCONNECT, hdev)) { - err = cmd_complete(sk, hdev->id, MGMT_OP_DISCONNECT, - MGMT_STATUS_BUSY, &rp, sizeof(rp)); + err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_DISCONNECT, + MGMT_STATUS_BUSY, &rp, sizeof(rp)); goto failed; } @@ -2907,8 +2911,9 @@ static int disconnect(struct sock *sk, struct hci_dev *hdev, void *data, conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->addr.bdaddr); if (!conn || conn->state == BT_OPEN || conn->state == BT_CLOSED) { - err = cmd_complete(sk, hdev->id, MGMT_OP_DISCONNECT, - MGMT_STATUS_NOT_CONNECTED, &rp, sizeof(rp)); + err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_DISCONNECT, + MGMT_STATUS_NOT_CONNECTED, &rp, + sizeof(rp)); goto failed; } @@ -2996,8 +3001,8 @@ static int get_connections(struct sock *sk, struct hci_dev *hdev, void *data, /* Recalculate length in case of filtered SCO connections, etc */ rp_len = sizeof(*rp) + (i * sizeof(struct mgmt_addr_info)); - err = cmd_complete(sk, hdev->id, MGMT_OP_GET_CONNECTIONS, 0, rp, - rp_len); + err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_GET_CONNECTIONS, 0, rp, + rp_len); kfree(rp); @@ -3095,8 +3100,8 @@ static int set_io_capability(struct sock *sk, struct hci_dev *hdev, void *data, BT_DBG(""); if (cp->io_capability > SMP_IO_KEYBOARD_DISPLAY) - return cmd_complete(sk, hdev->id, MGMT_OP_SET_IO_CAPABILITY, - MGMT_STATUS_INVALID_PARAMS, NULL, 0); + return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_SET_IO_CAPABILITY, + MGMT_STATUS_INVALID_PARAMS, NULL, 0); hci_dev_lock(hdev); @@ -3107,8 +3112,8 @@ static int set_io_capability(struct sock *sk, struct hci_dev *hdev, void *data, hci_dev_unlock(hdev); - return cmd_complete(sk, hdev->id, MGMT_OP_SET_IO_CAPABILITY, 0, NULL, - 0); + return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_SET_IO_CAPABILITY, 0, + NULL, 0); } static struct pending_cmd *find_pairing(struct hci_conn *conn) @@ -3138,8 +3143,8 @@ static int pairing_complete(struct pending_cmd *cmd, u8 status) bacpy(&rp.addr.bdaddr, &conn->dst); rp.addr.type = link_to_bdaddr(conn->type, conn->dst_type); - err = cmd_complete(cmd->sk, cmd->index, MGMT_OP_PAIR_DEVICE, status, - &rp, sizeof(rp)); + err = mgmt_cmd_complete(cmd->sk, cmd->index, MGMT_OP_PAIR_DEVICE, + status, &rp, sizeof(rp)); /* So we don't get further callbacks for this connection */ conn->connect_cfm_cb = NULL; @@ -3222,20 +3227,21 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data, rp.addr.type = cp->addr.type; if (!bdaddr_type_is_valid(cp->addr.type)) - return cmd_complete(sk, hdev->id, MGMT_OP_PAIR_DEVICE, - MGMT_STATUS_INVALID_PARAMS, - &rp, sizeof(rp)); + return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_PAIR_DEVICE, + MGMT_STATUS_INVALID_PARAMS, + &rp, sizeof(rp)); if (cp->io_cap > SMP_IO_KEYBOARD_DISPLAY) - return cmd_complete(sk, hdev->id, MGMT_OP_PAIR_DEVICE, - MGMT_STATUS_INVALID_PARAMS, - &rp, sizeof(rp)); + return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_PAIR_DEVICE, + MGMT_STATUS_INVALID_PARAMS, + &rp, sizeof(rp)); hci_dev_lock(hdev); if (!hdev_is_powered(hdev)) { - err = cmd_complete(sk, hdev->id, MGMT_OP_PAIR_DEVICE, - MGMT_STATUS_NOT_POWERED, &rp, sizeof(rp)); + err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_PAIR_DEVICE, + MGMT_STATUS_NOT_POWERED, &rp, + sizeof(rp)); goto unlock; } @@ -3283,16 +3289,15 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data, else status = MGMT_STATUS_CONNECT_FAILED; - err = cmd_complete(sk, hdev->id, MGMT_OP_PAIR_DEVICE, - status, &rp, - sizeof(rp)); + err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_PAIR_DEVICE, + status, &rp, sizeof(rp)); goto unlock; } if (conn->connect_cfm_cb) { hci_conn_drop(conn); - err = cmd_complete(sk, hdev->id, MGMT_OP_PAIR_DEVICE, - MGMT_STATUS_BUSY, &rp, sizeof(rp)); + err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_PAIR_DEVICE, + MGMT_STATUS_BUSY, &rp, sizeof(rp)); goto unlock; } @@ -3368,8 +3373,8 @@ static int cancel_pair_device(struct sock *sk, struct hci_dev *hdev, void *data, cmd->cmd_complete(cmd, MGMT_STATUS_CANCELLED); mgmt_pending_remove(cmd); - err = cmd_complete(sk, hdev->id, MGMT_OP_CANCEL_PAIR_DEVICE, 0, - addr, sizeof(*addr)); + err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_CANCEL_PAIR_DEVICE, 0, + addr, sizeof(*addr)); unlock: hci_dev_unlock(hdev); return err; @@ -3386,9 +3391,9 @@ static int user_pairing_resp(struct sock *sk, struct hci_dev *hdev, hci_dev_lock(hdev); if (!hdev_is_powered(hdev)) { - err = cmd_complete(sk, hdev->id, mgmt_op, - MGMT_STATUS_NOT_POWERED, addr, - sizeof(*addr)); + err = mgmt_cmd_complete(sk, hdev->id, mgmt_op, + MGMT_STATUS_NOT_POWERED, addr, + sizeof(*addr)); goto done; } @@ -3398,22 +3403,22 @@ static int user_pairing_resp(struct sock *sk, struct hci_dev *hdev, conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &addr->bdaddr); if (!conn) { - err = cmd_complete(sk, hdev->id, mgmt_op, - MGMT_STATUS_NOT_CONNECTED, addr, - sizeof(*addr)); + err = mgmt_cmd_complete(sk, hdev->id, mgmt_op, + MGMT_STATUS_NOT_CONNECTED, addr, + sizeof(*addr)); goto done; } if (addr->type == BDADDR_LE_PUBLIC || addr->type == BDADDR_LE_RANDOM) { err = smp_user_confirm_reply(conn, mgmt_op, passkey); if (!err) - err = cmd_complete(sk, hdev->id, mgmt_op, - MGMT_STATUS_SUCCESS, addr, - sizeof(*addr)); + err = mgmt_cmd_complete(sk, hdev->id, mgmt_op, + MGMT_STATUS_SUCCESS, addr, + sizeof(*addr)); else - err = cmd_complete(sk, hdev->id, mgmt_op, - MGMT_STATUS_FAILED, addr, - sizeof(*addr)); + err = mgmt_cmd_complete(sk, hdev->id, mgmt_op, + MGMT_STATUS_FAILED, addr, + sizeof(*addr)); goto done; } @@ -3538,8 +3543,8 @@ static void set_name_complete(struct hci_dev *hdev, u8 status, u16 opcode) mgmt_cmd_status(cmd->sk, hdev->id, MGMT_OP_SET_LOCAL_NAME, mgmt_status(status)); else - cmd_complete(cmd->sk, hdev->id, MGMT_OP_SET_LOCAL_NAME, 0, - cp, sizeof(*cp)); + mgmt_cmd_complete(cmd->sk, hdev->id, MGMT_OP_SET_LOCAL_NAME, 0, + cp, sizeof(*cp)); mgmt_pending_remove(cmd); @@ -3565,8 +3570,8 @@ static int set_local_name(struct sock *sk, struct hci_dev *hdev, void *data, if (!memcmp(hdev->dev_name, cp->name, sizeof(hdev->dev_name)) && !memcmp(hdev->short_name, cp->short_name, sizeof(hdev->short_name))) { - err = cmd_complete(sk, hdev->id, MGMT_OP_SET_LOCAL_NAME, 0, - data, len); + err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_SET_LOCAL_NAME, 0, + data, len); goto failed; } @@ -3575,8 +3580,8 @@ static int set_local_name(struct sock *sk, struct hci_dev *hdev, void *data, if (!hdev_is_powered(hdev)) { memcpy(hdev->dev_name, cp->name, sizeof(hdev->dev_name)); - err = cmd_complete(sk, hdev->id, MGMT_OP_SET_LOCAL_NAME, 0, - data, len); + err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_SET_LOCAL_NAME, 0, + data, len); if (err < 0) goto failed; @@ -3673,9 +3678,10 @@ static int add_remote_oob_data(struct sock *sk, struct hci_dev *hdev, BT_DBG("%s ", hdev->name); if (!bdaddr_type_is_valid(addr->type)) - return cmd_complete(sk, hdev->id, MGMT_OP_ADD_REMOTE_OOB_DATA, - MGMT_STATUS_INVALID_PARAMS, addr, - sizeof(*addr)); + return mgmt_cmd_complete(sk, hdev->id, + MGMT_OP_ADD_REMOTE_OOB_DATA, + MGMT_STATUS_INVALID_PARAMS, + addr, sizeof(*addr)); hci_dev_lock(hdev); @@ -3684,10 +3690,10 @@ static int add_remote_oob_data(struct sock *sk, struct hci_dev *hdev, u8 status; if (cp->addr.type != BDADDR_BREDR) { - err = cmd_complete(sk, hdev->id, - MGMT_OP_ADD_REMOTE_OOB_DATA, - MGMT_STATUS_INVALID_PARAMS, - &cp->addr, sizeof(cp->addr)); + err = mgmt_cmd_complete(sk, hdev->id, + MGMT_OP_ADD_REMOTE_OOB_DATA, + MGMT_STATUS_INVALID_PARAMS, + &cp->addr, sizeof(cp->addr)); goto unlock; } @@ -3699,8 +3705,9 @@ static int add_remote_oob_data(struct sock *sk, struct hci_dev *hdev, else status = MGMT_STATUS_SUCCESS; - err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_REMOTE_OOB_DATA, - status, &cp->addr, sizeof(cp->addr)); + err = mgmt_cmd_complete(sk, hdev->id, + MGMT_OP_ADD_REMOTE_OOB_DATA, status, + &cp->addr, sizeof(cp->addr)); } else if (len == MGMT_ADD_REMOTE_OOB_EXT_DATA_SIZE) { struct mgmt_cp_add_remote_oob_ext_data *cp = data; u8 *rand192, *hash192, *rand256, *hash256; @@ -3712,10 +3719,10 @@ static int add_remote_oob_data(struct sock *sk, struct hci_dev *hdev, */ if (memcmp(cp->rand192, ZERO_KEY, 16) || memcmp(cp->hash192, ZERO_KEY, 16)) { - err = cmd_complete(sk, hdev->id, - MGMT_OP_ADD_REMOTE_OOB_DATA, - MGMT_STATUS_INVALID_PARAMS, - addr, sizeof(*addr)); + err = mgmt_cmd_complete(sk, hdev->id, + MGMT_OP_ADD_REMOTE_OOB_DATA, + MGMT_STATUS_INVALID_PARAMS, + addr, sizeof(*addr)); goto unlock; } @@ -3755,8 +3762,9 @@ static int add_remote_oob_data(struct sock *sk, struct hci_dev *hdev, else status = MGMT_STATUS_SUCCESS; - err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_REMOTE_OOB_DATA, - status, &cp->addr, sizeof(cp->addr)); + err = mgmt_cmd_complete(sk, hdev->id, + MGMT_OP_ADD_REMOTE_OOB_DATA, + status, &cp->addr, sizeof(cp->addr)); } else { BT_ERR("add_remote_oob_data: invalid length of %u bytes", len); err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_ADD_REMOTE_OOB_DATA, @@ -3778,9 +3786,10 @@ static int remove_remote_oob_data(struct sock *sk, struct hci_dev *hdev, BT_DBG("%s", hdev->name); if (cp->addr.type != BDADDR_BREDR) - return cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_REMOTE_OOB_DATA, - MGMT_STATUS_INVALID_PARAMS, - &cp->addr, sizeof(cp->addr)); + return mgmt_cmd_complete(sk, hdev->id, + MGMT_OP_REMOVE_REMOTE_OOB_DATA, + MGMT_STATUS_INVALID_PARAMS, + &cp->addr, sizeof(cp->addr)); hci_dev_lock(hdev); @@ -3797,8 +3806,8 @@ static int remove_remote_oob_data(struct sock *sk, struct hci_dev *hdev, status = MGMT_STATUS_SUCCESS; done: - err = cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_REMOTE_OOB_DATA, - status, &cp->addr, sizeof(cp->addr)); + err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_REMOTE_OOB_DATA, + status, &cp->addr, sizeof(cp->addr)); hci_dev_unlock(hdev); return err; @@ -3981,17 +3990,17 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev, hci_dev_lock(hdev); if (!hdev_is_powered(hdev)) { - err = cmd_complete(sk, hdev->id, MGMT_OP_START_DISCOVERY, - MGMT_STATUS_NOT_POWERED, - &cp->type, sizeof(cp->type)); + err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_START_DISCOVERY, + MGMT_STATUS_NOT_POWERED, + &cp->type, sizeof(cp->type)); goto failed; } if (hdev->discovery.state != DISCOVERY_STOPPED || test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags)) { - err = cmd_complete(sk, hdev->id, MGMT_OP_START_DISCOVERY, - MGMT_STATUS_BUSY, &cp->type, - sizeof(cp->type)); + err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_START_DISCOVERY, + MGMT_STATUS_BUSY, &cp->type, + sizeof(cp->type)); goto failed; } @@ -4014,8 +4023,8 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev, hci_req_init(&req, hdev); if (!trigger_discovery(&req, &status)) { - err = cmd_complete(sk, hdev->id, MGMT_OP_START_DISCOVERY, - status, &cp->type, sizeof(cp->type)); + err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_START_DISCOVERY, + status, &cp->type, sizeof(cp->type)); mgmt_pending_remove(cmd); goto failed; } @@ -4035,8 +4044,8 @@ failed: static int service_discovery_cmd_complete(struct pending_cmd *cmd, u8 status) { - return cmd_complete(cmd->sk, cmd->index, cmd->opcode, status, - cmd->param, 1); + return mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, status, + cmd->param, 1); } static int start_service_discovery(struct sock *sk, struct hci_dev *hdev, @@ -4055,19 +4064,19 @@ static int start_service_discovery(struct sock *sk, struct hci_dev *hdev, hci_dev_lock(hdev); if (!hdev_is_powered(hdev)) { - err = cmd_complete(sk, hdev->id, - MGMT_OP_START_SERVICE_DISCOVERY, - MGMT_STATUS_NOT_POWERED, - &cp->type, sizeof(cp->type)); + err = mgmt_cmd_complete(sk, hdev->id, + MGMT_OP_START_SERVICE_DISCOVERY, + MGMT_STATUS_NOT_POWERED, + &cp->type, sizeof(cp->type)); goto failed; } if (hdev->discovery.state != DISCOVERY_STOPPED || test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags)) { - err = cmd_complete(sk, hdev->id, - MGMT_OP_START_SERVICE_DISCOVERY, - MGMT_STATUS_BUSY, &cp->type, - sizeof(cp->type)); + err = mgmt_cmd_complete(sk, hdev->id, + MGMT_OP_START_SERVICE_DISCOVERY, + MGMT_STATUS_BUSY, &cp->type, + sizeof(cp->type)); goto failed; } @@ -4075,10 +4084,10 @@ static int start_service_discovery(struct sock *sk, struct hci_dev *hdev, if (uuid_count > max_uuid_count) { BT_ERR("service_discovery: too big uuid_count value %u", uuid_count); - err = cmd_complete(sk, hdev->id, - MGMT_OP_START_SERVICE_DISCOVERY, - MGMT_STATUS_INVALID_PARAMS, &cp->type, - sizeof(cp->type)); + err = mgmt_cmd_complete(sk, hdev->id, + MGMT_OP_START_SERVICE_DISCOVERY, + MGMT_STATUS_INVALID_PARAMS, &cp->type, + sizeof(cp->type)); goto failed; } @@ -4086,10 +4095,10 @@ static int start_service_discovery(struct sock *sk, struct hci_dev *hdev, if (expected_len != len) { BT_ERR("service_discovery: expected %u bytes, got %u bytes", expected_len, len); - err = cmd_complete(sk, hdev->id, - MGMT_OP_START_SERVICE_DISCOVERY, - MGMT_STATUS_INVALID_PARAMS, &cp->type, - sizeof(cp->type)); + err = mgmt_cmd_complete(sk, hdev->id, + MGMT_OP_START_SERVICE_DISCOVERY, + MGMT_STATUS_INVALID_PARAMS, &cp->type, + sizeof(cp->type)); goto failed; } @@ -4116,10 +4125,10 @@ static int start_service_discovery(struct sock *sk, struct hci_dev *hdev, hdev->discovery.uuids = kmemdup(cp->uuids, uuid_count * 16, GFP_KERNEL); if (!hdev->discovery.uuids) { - err = cmd_complete(sk, hdev->id, - MGMT_OP_START_SERVICE_DISCOVERY, - MGMT_STATUS_FAILED, - &cp->type, sizeof(cp->type)); + err = mgmt_cmd_complete(sk, hdev->id, + MGMT_OP_START_SERVICE_DISCOVERY, + MGMT_STATUS_FAILED, + &cp->type, sizeof(cp->type)); mgmt_pending_remove(cmd); goto failed; } @@ -4128,9 +4137,9 @@ static int start_service_discovery(struct sock *sk, struct hci_dev *hdev, hci_req_init(&req, hdev); if (!trigger_discovery(&req, &status)) { - err = cmd_complete(sk, hdev->id, - MGMT_OP_START_SERVICE_DISCOVERY, - status, &cp->type, sizeof(cp->type)); + err = mgmt_cmd_complete(sk, hdev->id, + MGMT_OP_START_SERVICE_DISCOVERY, + status, &cp->type, sizeof(cp->type)); mgmt_pending_remove(cmd); goto failed; } @@ -4181,16 +4190,16 @@ static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data, hci_dev_lock(hdev); if (!hci_discovery_active(hdev)) { - err = cmd_complete(sk, hdev->id, MGMT_OP_STOP_DISCOVERY, - MGMT_STATUS_REJECTED, &mgmt_cp->type, - sizeof(mgmt_cp->type)); + err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_STOP_DISCOVERY, + MGMT_STATUS_REJECTED, &mgmt_cp->type, + sizeof(mgmt_cp->type)); goto unlock; } if (hdev->discovery.type != mgmt_cp->type) { - err = cmd_complete(sk, hdev->id, MGMT_OP_STOP_DISCOVERY, - MGMT_STATUS_INVALID_PARAMS, &mgmt_cp->type, - sizeof(mgmt_cp->type)); + err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_STOP_DISCOVERY, + MGMT_STATUS_INVALID_PARAMS, + &mgmt_cp->type, sizeof(mgmt_cp->type)); goto unlock; } @@ -4216,8 +4225,8 @@ static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data, /* If no HCI commands were sent we're done */ if (err == -ENODATA) { - err = cmd_complete(sk, hdev->id, MGMT_OP_STOP_DISCOVERY, 0, - &mgmt_cp->type, sizeof(mgmt_cp->type)); + err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_STOP_DISCOVERY, 0, + &mgmt_cp->type, sizeof(mgmt_cp->type)); hci_discovery_set_state(hdev, DISCOVERY_STOPPED); } @@ -4238,17 +4247,17 @@ static int confirm_name(struct sock *sk, struct hci_dev *hdev, void *data, hci_dev_lock(hdev); if (!hci_discovery_active(hdev)) { - err = cmd_complete(sk, hdev->id, MGMT_OP_CONFIRM_NAME, - MGMT_STATUS_FAILED, &cp->addr, - sizeof(cp->addr)); + err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_CONFIRM_NAME, + MGMT_STATUS_FAILED, &cp->addr, + sizeof(cp->addr)); goto failed; } e = hci_inquiry_cache_lookup_unknown(hdev, &cp->addr.bdaddr); if (!e) { - err = cmd_complete(sk, hdev->id, MGMT_OP_CONFIRM_NAME, - MGMT_STATUS_INVALID_PARAMS, &cp->addr, - sizeof(cp->addr)); + err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_CONFIRM_NAME, + MGMT_STATUS_INVALID_PARAMS, &cp->addr, + sizeof(cp->addr)); goto failed; } @@ -4260,8 +4269,8 @@ static int confirm_name(struct sock *sk, struct hci_dev *hdev, void *data, hci_inquiry_cache_update_resolve(hdev, e); } - err = cmd_complete(sk, hdev->id, MGMT_OP_CONFIRM_NAME, 0, &cp->addr, - sizeof(cp->addr)); + err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_CONFIRM_NAME, 0, + &cp->addr, sizeof(cp->addr)); failed: hci_dev_unlock(hdev); @@ -4278,9 +4287,9 @@ static int block_device(struct sock *sk, struct hci_dev *hdev, void *data, BT_DBG("%s", hdev->name); if (!bdaddr_type_is_valid(cp->addr.type)) - return cmd_complete(sk, hdev->id, MGMT_OP_BLOCK_DEVICE, - MGMT_STATUS_INVALID_PARAMS, - &cp->addr, sizeof(cp->addr)); + return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_BLOCK_DEVICE, + MGMT_STATUS_INVALID_PARAMS, + &cp->addr, sizeof(cp->addr)); hci_dev_lock(hdev); @@ -4296,8 +4305,8 @@ static int block_device(struct sock *sk, struct hci_dev *hdev, void *data, status = MGMT_STATUS_SUCCESS; done: - err = cmd_complete(sk, hdev->id, MGMT_OP_BLOCK_DEVICE, status, - &cp->addr, sizeof(cp->addr)); + err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_BLOCK_DEVICE, status, + &cp->addr, sizeof(cp->addr)); hci_dev_unlock(hdev); @@ -4314,9 +4323,9 @@ static int unblock_device(struct sock *sk, struct hci_dev *hdev, void *data, BT_DBG("%s", hdev->name); if (!bdaddr_type_is_valid(cp->addr.type)) - return cmd_complete(sk, hdev->id, MGMT_OP_UNBLOCK_DEVICE, - MGMT_STATUS_INVALID_PARAMS, - &cp->addr, sizeof(cp->addr)); + return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_UNBLOCK_DEVICE, + MGMT_STATUS_INVALID_PARAMS, + &cp->addr, sizeof(cp->addr)); hci_dev_lock(hdev); @@ -4332,8 +4341,8 @@ static int unblock_device(struct sock *sk, struct hci_dev *hdev, void *data, status = MGMT_STATUS_SUCCESS; done: - err = cmd_complete(sk, hdev->id, MGMT_OP_UNBLOCK_DEVICE, status, - &cp->addr, sizeof(cp->addr)); + err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_UNBLOCK_DEVICE, status, + &cp->addr, sizeof(cp->addr)); hci_dev_unlock(hdev); @@ -4363,7 +4372,8 @@ static int set_device_id(struct sock *sk, struct hci_dev *hdev, void *data, hdev->devid_product = __le16_to_cpu(cp->product); hdev->devid_version = __le16_to_cpu(cp->version); - err = cmd_complete(sk, hdev->id, MGMT_OP_SET_DEVICE_ID, 0, NULL, 0); + err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_SET_DEVICE_ID, 0, + NULL, 0); hci_req_init(&req, hdev); update_eir(&req); @@ -4564,7 +4574,8 @@ static int set_scan_params(struct sock *sk, struct hci_dev *hdev, hdev->le_scan_interval = interval; hdev->le_scan_window = window; - err = cmd_complete(sk, hdev->id, MGMT_OP_SET_SCAN_PARAMS, 0, NULL, 0); + err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_SET_SCAN_PARAMS, 0, + NULL, 0); /* If background scan is running, restart it so new parameters are * loaded. @@ -5136,7 +5147,7 @@ static int load_irks(struct sock *sk, struct hci_dev *hdev, void *cp_data, set_bit(HCI_RPA_RESOLVING, &hdev->dev_flags); - err = cmd_complete(sk, hdev->id, MGMT_OP_LOAD_IRKS, 0, NULL, 0); + err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_LOAD_IRKS, 0, NULL, 0); hci_dev_unlock(hdev); @@ -5246,7 +5257,7 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev, key->rand); } - err = cmd_complete(sk, hdev->id, MGMT_OP_LOAD_LONG_TERM_KEYS, 0, + err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_LOAD_LONG_TERM_KEYS, 0, NULL, 0); hci_dev_unlock(hdev); @@ -5272,8 +5283,8 @@ static int conn_info_cmd_complete(struct pending_cmd *cmd, u8 status) rp.max_tx_power = HCI_TX_POWER_INVALID; } - err = cmd_complete(cmd->sk, cmd->index, MGMT_OP_GET_CONN_INFO, status, - &rp, sizeof(rp)); + err = mgmt_cmd_complete(cmd->sk, cmd->index, MGMT_OP_GET_CONN_INFO, + status, &rp, sizeof(rp)); hci_conn_drop(conn); hci_conn_put(conn); @@ -5350,15 +5361,16 @@ static int get_conn_info(struct sock *sk, struct hci_dev *hdev, void *data, rp.addr.type = cp->addr.type; if (!bdaddr_type_is_valid(cp->addr.type)) - return cmd_complete(sk, hdev->id, MGMT_OP_GET_CONN_INFO, - MGMT_STATUS_INVALID_PARAMS, - &rp, sizeof(rp)); + return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_GET_CONN_INFO, + MGMT_STATUS_INVALID_PARAMS, + &rp, sizeof(rp)); hci_dev_lock(hdev); if (!hdev_is_powered(hdev)) { - err = cmd_complete(sk, hdev->id, MGMT_OP_GET_CONN_INFO, - MGMT_STATUS_NOT_POWERED, &rp, sizeof(rp)); + err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_GET_CONN_INFO, + MGMT_STATUS_NOT_POWERED, &rp, + sizeof(rp)); goto unlock; } @@ -5369,14 +5381,15 @@ static int get_conn_info(struct sock *sk, struct hci_dev *hdev, void *data, conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->addr.bdaddr); if (!conn || conn->state != BT_CONNECTED) { - err = cmd_complete(sk, hdev->id, MGMT_OP_GET_CONN_INFO, - MGMT_STATUS_NOT_CONNECTED, &rp, sizeof(rp)); + err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_GET_CONN_INFO, + MGMT_STATUS_NOT_CONNECTED, &rp, + sizeof(rp)); goto unlock; } if (mgmt_pending_find_data(MGMT_OP_GET_CONN_INFO, hdev, conn)) { - err = cmd_complete(sk, hdev->id, MGMT_OP_GET_CONN_INFO, - MGMT_STATUS_BUSY, &rp, sizeof(rp)); + err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_GET_CONN_INFO, + MGMT_STATUS_BUSY, &rp, sizeof(rp)); goto unlock; } @@ -5444,8 +5457,8 @@ static int get_conn_info(struct sock *sk, struct hci_dev *hdev, void *data, rp.tx_power = conn->tx_power; rp.max_tx_power = conn->max_tx_power; - err = cmd_complete(sk, hdev->id, MGMT_OP_GET_CONN_INFO, - MGMT_STATUS_SUCCESS, &rp, sizeof(rp)); + err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_GET_CONN_INFO, + MGMT_STATUS_SUCCESS, &rp, sizeof(rp)); } unlock: @@ -5478,8 +5491,8 @@ static int clock_info_cmd_complete(struct pending_cmd *cmd, u8 status) } complete: - err = cmd_complete(cmd->sk, cmd->index, cmd->opcode, status, &rp, - sizeof(rp)); + err = mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, status, &rp, + sizeof(rp)); if (conn) { hci_conn_drop(conn); @@ -5539,15 +5552,16 @@ static int get_clock_info(struct sock *sk, struct hci_dev *hdev, void *data, rp.addr.type = cp->addr.type; if (cp->addr.type != BDADDR_BREDR) - return cmd_complete(sk, hdev->id, MGMT_OP_GET_CLOCK_INFO, - MGMT_STATUS_INVALID_PARAMS, - &rp, sizeof(rp)); + return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_GET_CLOCK_INFO, + MGMT_STATUS_INVALID_PARAMS, + &rp, sizeof(rp)); hci_dev_lock(hdev); if (!hdev_is_powered(hdev)) { - err = cmd_complete(sk, hdev->id, MGMT_OP_GET_CLOCK_INFO, - MGMT_STATUS_NOT_POWERED, &rp, sizeof(rp)); + err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_GET_CLOCK_INFO, + MGMT_STATUS_NOT_POWERED, &rp, + sizeof(rp)); goto unlock; } @@ -5555,10 +5569,10 @@ static int get_clock_info(struct sock *sk, struct hci_dev *hdev, void *data, conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->addr.bdaddr); if (!conn || conn->state != BT_CONNECTED) { - err = cmd_complete(sk, hdev->id, - MGMT_OP_GET_CLOCK_INFO, - MGMT_STATUS_NOT_CONNECTED, - &rp, sizeof(rp)); + err = mgmt_cmd_complete(sk, hdev->id, + MGMT_OP_GET_CLOCK_INFO, + MGMT_STATUS_NOT_CONNECTED, + &rp, sizeof(rp)); goto unlock; } } else { @@ -5699,14 +5713,14 @@ static int add_device(struct sock *sk, struct hci_dev *hdev, if (!bdaddr_type_is_valid(cp->addr.type) || !bacmp(&cp->addr.bdaddr, BDADDR_ANY)) - return cmd_complete(sk, hdev->id, MGMT_OP_ADD_DEVICE, - MGMT_STATUS_INVALID_PARAMS, - &cp->addr, sizeof(cp->addr)); + return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_ADD_DEVICE, + MGMT_STATUS_INVALID_PARAMS, + &cp->addr, sizeof(cp->addr)); if (cp->action != 0x00 && cp->action != 0x01 && cp->action != 0x02) - return cmd_complete(sk, hdev->id, MGMT_OP_ADD_DEVICE, - MGMT_STATUS_INVALID_PARAMS, - &cp->addr, sizeof(cp->addr)); + return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_ADD_DEVICE, + MGMT_STATUS_INVALID_PARAMS, + &cp->addr, sizeof(cp->addr)); hci_req_init(&req, hdev); @@ -6018,7 +6032,8 @@ static int load_conn_param(struct sock *sk, struct hci_dev *hdev, void *data, hci_dev_unlock(hdev); - return cmd_complete(sk, hdev->id, MGMT_OP_LOAD_CONN_PARAM, 0, NULL, 0); + return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_LOAD_CONN_PARAM, 0, + NULL, 0); } static int set_external_config(struct sock *sk, struct hci_dev *hdev, @@ -7218,8 +7233,9 @@ void mgmt_read_local_oob_data_complete(struct hci_dev *hdev, u8 *hash192, rp_size -= sizeof(rp.hash256) + sizeof(rp.rand256); } - cmd_complete(cmd->sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA, 0, - &rp, rp_size); + mgmt_cmd_complete(cmd->sk, hdev->id, + MGMT_OP_READ_LOCAL_OOB_DATA, 0, + &rp, rp_size); } mgmt_pending_remove(cmd); -- GitLab From 3b0602cd01a571177e169c594e5e52b7b740cf08 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Fri, 6 Mar 2015 21:08:55 +0200 Subject: [PATCH 03040/11651] Bluetooth: Rename pending_cmd to mgmt_pending_cmd This patch renames the pending_cmd struct (used for tracking pending mgmt commands) to mgmt_pending_cmd, so that it can be moved to a more generic place and be used also by other modules using other HCI channels. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- net/bluetooth/mgmt.c | 176 ++++++++++++++++++++++--------------------- 1 file changed, 89 insertions(+), 87 deletions(-) diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 835a459531ab..62c23927684f 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -135,7 +135,7 @@ static const u16 mgmt_events[] = { #define ZERO_KEY "\x00\x00\x00\x00\x00\x00\x00\x00" \ "\x00\x00\x00\x00\x00\x00\x00\x00" -struct pending_cmd { +struct mgmt_pending_cmd { struct list_head list; u16 opcode; int index; @@ -143,7 +143,7 @@ struct pending_cmd { size_t param_len; struct sock *sk; void *user_data; - int (*cmd_complete)(struct pending_cmd *cmd, u8 status); + int (*cmd_complete)(struct mgmt_pending_cmd *cmd, u8 status); }; /* HCI to MGMT error code conversion table */ @@ -771,9 +771,10 @@ static u8 *create_uuid128_list(struct hci_dev *hdev, u8 *data, ptrdiff_t len) return ptr; } -static struct pending_cmd *mgmt_pending_find(u16 opcode, struct hci_dev *hdev) +static struct mgmt_pending_cmd *mgmt_pending_find(u16 opcode, + struct hci_dev *hdev) { - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; list_for_each_entry(cmd, &hdev->mgmt_pending, list) { if (cmd->opcode == opcode) @@ -783,11 +784,11 @@ static struct pending_cmd *mgmt_pending_find(u16 opcode, struct hci_dev *hdev) return NULL; } -static struct pending_cmd *mgmt_pending_find_data(u16 opcode, - struct hci_dev *hdev, - const void *data) +static struct mgmt_pending_cmd *mgmt_pending_find_data(u16 opcode, + struct hci_dev *hdev, + const void *data) { - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; list_for_each_entry(cmd, &hdev->mgmt_pending, list) { if (cmd->user_data != data) @@ -852,7 +853,7 @@ static void update_scan_rsp_data(struct hci_request *req) static u8 get_adv_discov_flags(struct hci_dev *hdev) { - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; /* If there's a pending mgmt command the flags will not yet have * their final values, so check for this first. @@ -1060,7 +1061,7 @@ static void update_class(struct hci_request *req) static bool get_connectable(struct hci_dev *hdev) { - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; /* If there's a pending mgmt command the flag will not yet have * it's final value, so check for this first. @@ -1210,18 +1211,18 @@ static int read_controller_info(struct sock *sk, struct hci_dev *hdev, sizeof(rp)); } -static void mgmt_pending_free(struct pending_cmd *cmd) +static void mgmt_pending_free(struct mgmt_pending_cmd *cmd) { sock_put(cmd->sk); kfree(cmd->param); kfree(cmd); } -static struct pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode, - struct hci_dev *hdev, void *data, - u16 len) +static struct mgmt_pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode, + struct hci_dev *hdev, + void *data, u16 len) { - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); if (!cmd) @@ -1247,11 +1248,11 @@ static struct pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode, } static void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev, - void (*cb)(struct pending_cmd *cmd, + void (*cb)(struct mgmt_pending_cmd *cmd, void *data), void *data) { - struct pending_cmd *cmd, *tmp; + struct mgmt_pending_cmd *cmd, *tmp; list_for_each_entry_safe(cmd, tmp, &hdev->mgmt_pending, list) { if (opcode > 0 && cmd->opcode != opcode) @@ -1261,7 +1262,7 @@ static void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev, } } -static void mgmt_pending_remove(struct pending_cmd *cmd) +static void mgmt_pending_remove(struct mgmt_pending_cmd *cmd) { list_del(&cmd->list); mgmt_pending_free(cmd); @@ -1390,7 +1391,7 @@ static int set_powered(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) { struct mgmt_mode *cp = data; - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; int err; BT_DBG("request for %s", hdev->name); @@ -1472,7 +1473,7 @@ struct cmd_lookup { u8 mgmt_status; }; -static void settings_rsp(struct pending_cmd *cmd, void *data) +static void settings_rsp(struct mgmt_pending_cmd *cmd, void *data) { struct cmd_lookup *match = data; @@ -1488,7 +1489,7 @@ static void settings_rsp(struct pending_cmd *cmd, void *data) mgmt_pending_free(cmd); } -static void cmd_status_rsp(struct pending_cmd *cmd, void *data) +static void cmd_status_rsp(struct mgmt_pending_cmd *cmd, void *data) { u8 *status = data; @@ -1496,7 +1497,7 @@ static void cmd_status_rsp(struct pending_cmd *cmd, void *data) mgmt_pending_remove(cmd); } -static void cmd_complete_rsp(struct pending_cmd *cmd, void *data) +static void cmd_complete_rsp(struct mgmt_pending_cmd *cmd, void *data) { if (cmd->cmd_complete) { u8 *status = data; @@ -1510,13 +1511,13 @@ static void cmd_complete_rsp(struct pending_cmd *cmd, void *data) cmd_status_rsp(cmd, data); } -static int generic_cmd_complete(struct pending_cmd *cmd, u8 status) +static int generic_cmd_complete(struct mgmt_pending_cmd *cmd, u8 status) { return mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, status, cmd->param, cmd->param_len); } -static int addr_cmd_complete(struct pending_cmd *cmd, u8 status) +static int addr_cmd_complete(struct mgmt_pending_cmd *cmd, u8 status) { return mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, status, cmd->param, sizeof(struct mgmt_addr_info)); @@ -1545,7 +1546,7 @@ static u8 mgmt_le_support(struct hci_dev *hdev) static void set_discoverable_complete(struct hci_dev *hdev, u8 status, u16 opcode) { - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; struct mgmt_mode *cp; struct hci_request req; bool changed; @@ -1606,7 +1607,7 @@ static int set_discoverable(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) { struct mgmt_cp_set_discoverable *cp = data; - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; struct hci_request req; u16 timeout; u8 scan; @@ -1805,7 +1806,7 @@ static void write_fast_connectable(struct hci_request *req, bool enable) static void set_connectable_complete(struct hci_dev *hdev, u8 status, u16 opcode) { - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; struct mgmt_mode *cp; bool conn_changed, discov_changed; @@ -1885,7 +1886,7 @@ static int set_connectable(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) { struct mgmt_mode *cp = data; - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; struct hci_request req; u8 scan; int err; @@ -2022,7 +2023,7 @@ static int set_link_security(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) { struct mgmt_mode *cp = data; - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; u8 val, status; int err; @@ -2091,7 +2092,7 @@ failed: static int set_ssp(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) { struct mgmt_mode *cp = data; - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; u8 status; int err; @@ -2270,7 +2271,7 @@ static int set_le(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) { struct mgmt_mode *cp = data; struct hci_cp_write_le_host_supported hci_cp; - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; struct hci_request req; int err; u8 val, enabled; @@ -2363,7 +2364,7 @@ unlock: */ static bool pending_eir_or_class(struct hci_dev *hdev) { - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; list_for_each_entry(cmd, &hdev->mgmt_pending, list) { switch (cmd->opcode) { @@ -2399,7 +2400,7 @@ static u8 get_uuid_size(const u8 *uuid) static void mgmt_class_complete(struct hci_dev *hdev, u16 mgmt_op, u8 status) { - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; hci_dev_lock(hdev); @@ -2426,7 +2427,7 @@ static void add_uuid_complete(struct hci_dev *hdev, u8 status, u16 opcode) static int add_uuid(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) { struct mgmt_cp_add_uuid *cp = data; - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; struct hci_request req; struct bt_uuid *uuid; int err; @@ -2506,7 +2507,7 @@ static int remove_uuid(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) { struct mgmt_cp_remove_uuid *cp = data; - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; struct bt_uuid *match, *tmp; u8 bt_uuid_any[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; struct hci_request req; @@ -2592,7 +2593,7 @@ static int set_dev_class(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) { struct mgmt_cp_set_dev_class *cp = data; - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; struct hci_request req; int err; @@ -2760,7 +2761,7 @@ static int unpair_device(struct sock *sk, struct hci_dev *hdev, void *data, struct mgmt_cp_unpair_device *cp = data; struct mgmt_rp_unpair_device rp; struct hci_cp_disconnect dc; - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; struct hci_conn *conn; int err; @@ -2874,7 +2875,7 @@ static int disconnect(struct sock *sk, struct hci_dev *hdev, void *data, { struct mgmt_cp_disconnect *cp = data; struct mgmt_rp_disconnect rp; - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; struct hci_conn *conn; int err; @@ -3014,7 +3015,7 @@ unlock: static int send_pin_code_neg_reply(struct sock *sk, struct hci_dev *hdev, struct mgmt_cp_pin_code_neg_reply *cp) { - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; int err; cmd = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_NEG_REPLY, hdev, cp, @@ -3036,7 +3037,7 @@ static int pin_code_reply(struct sock *sk, struct hci_dev *hdev, void *data, struct hci_conn *conn; struct mgmt_cp_pin_code_reply *cp = data; struct hci_cp_pin_code_reply reply; - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; int err; BT_DBG(""); @@ -3116,10 +3117,10 @@ static int set_io_capability(struct sock *sk, struct hci_dev *hdev, void *data, NULL, 0); } -static struct pending_cmd *find_pairing(struct hci_conn *conn) +static struct mgmt_pending_cmd *find_pairing(struct hci_conn *conn) { struct hci_dev *hdev = conn->hdev; - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; list_for_each_entry(cmd, &hdev->mgmt_pending, list) { if (cmd->opcode != MGMT_OP_PAIR_DEVICE) @@ -3134,7 +3135,7 @@ static struct pending_cmd *find_pairing(struct hci_conn *conn) return NULL; } -static int pairing_complete(struct pending_cmd *cmd, u8 status) +static int pairing_complete(struct mgmt_pending_cmd *cmd, u8 status) { struct mgmt_rp_pair_device rp; struct hci_conn *conn = cmd->user_data; @@ -3166,7 +3167,7 @@ static int pairing_complete(struct pending_cmd *cmd, u8 status) void mgmt_smp_complete(struct hci_conn *conn, bool complete) { u8 status = complete ? MGMT_STATUS_SUCCESS : MGMT_STATUS_FAILED; - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; cmd = find_pairing(conn); if (cmd) { @@ -3177,7 +3178,7 @@ void mgmt_smp_complete(struct hci_conn *conn, bool complete) static void pairing_complete_cb(struct hci_conn *conn, u8 status) { - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; BT_DBG("status %u", status); @@ -3193,7 +3194,7 @@ static void pairing_complete_cb(struct hci_conn *conn, u8 status) static void le_pairing_complete_cb(struct hci_conn *conn, u8 status) { - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; BT_DBG("status %u", status); @@ -3215,7 +3216,7 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data, { struct mgmt_cp_pair_device *cp = data; struct mgmt_rp_pair_device rp; - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; u8 sec_level, auth_type; struct hci_conn *conn; int err; @@ -3341,7 +3342,7 @@ static int cancel_pair_device(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) { struct mgmt_addr_info *addr = data; - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; struct hci_conn *conn; int err; @@ -3384,7 +3385,7 @@ static int user_pairing_resp(struct sock *sk, struct hci_dev *hdev, struct mgmt_addr_info *addr, u16 mgmt_op, u16 hci_op, __le32 passkey) { - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; struct hci_conn *conn; int err; @@ -3527,7 +3528,7 @@ static void update_name(struct hci_request *req) static void set_name_complete(struct hci_dev *hdev, u8 status, u16 opcode) { struct mgmt_cp_set_local_name *cp; - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; BT_DBG("status 0x%02x", status); @@ -3556,7 +3557,7 @@ static int set_local_name(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) { struct mgmt_cp_set_local_name *cp = data; - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; struct hci_request req; int err; @@ -3624,7 +3625,7 @@ failed: static int read_local_oob_data(struct sock *sk, struct hci_dev *hdev, void *data, u16 data_len) { - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; int err; BT_DBG("%s", hdev->name); @@ -3913,7 +3914,7 @@ static bool trigger_discovery(struct hci_request *req, u8 *status) static void start_discovery_complete(struct hci_dev *hdev, u8 status, u16 opcode) { - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; unsigned long timeout; BT_DBG("status %d", status); @@ -3980,7 +3981,7 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) { struct mgmt_cp_start_discovery *cp = data; - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; struct hci_request req; u8 status; int err; @@ -4042,7 +4043,8 @@ failed: return err; } -static int service_discovery_cmd_complete(struct pending_cmd *cmd, u8 status) +static int service_discovery_cmd_complete(struct mgmt_pending_cmd *cmd, + u8 status) { return mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, status, cmd->param, 1); @@ -4052,7 +4054,7 @@ static int start_service_discovery(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) { struct mgmt_cp_start_service_discovery *cp = data; - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; struct hci_request req; const u16 max_uuid_count = ((U16_MAX - sizeof(*cp)) / 16); u16 uuid_count, expected_len; @@ -4159,7 +4161,7 @@ failed: static void stop_discovery_complete(struct hci_dev *hdev, u8 status, u16 opcode) { - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; BT_DBG("status %d", status); @@ -4181,7 +4183,7 @@ static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) { struct mgmt_cp_stop_discovery *mgmt_cp = data; - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; struct hci_request req; int err; @@ -4420,7 +4422,7 @@ static int set_advertising(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) { struct mgmt_mode *cp = data; - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; struct hci_request req; u8 val, enabled, status; int err; @@ -4600,7 +4602,7 @@ static int set_scan_params(struct sock *sk, struct hci_dev *hdev, static void fast_connectable_complete(struct hci_dev *hdev, u8 status, u16 opcode) { - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; BT_DBG("status 0x%02x", status); @@ -4635,7 +4637,7 @@ static int set_fast_connectable(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) { struct mgmt_mode *cp = data; - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; struct hci_request req; int err; @@ -4698,7 +4700,7 @@ unlock: static void set_bredr_complete(struct hci_dev *hdev, u8 status, u16 opcode) { - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; BT_DBG("status 0x%02x", status); @@ -4731,7 +4733,7 @@ unlock: static int set_bredr(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) { struct mgmt_mode *cp = data; - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; struct hci_request req; int err; @@ -4842,7 +4844,7 @@ unlock: static void sc_enable_complete(struct hci_dev *hdev, u8 status, u16 opcode) { - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; struct mgmt_mode *cp; BT_DBG("%s status %u", hdev->name, status); @@ -4889,7 +4891,7 @@ static int set_secure_conn(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) { struct mgmt_mode *cp = data; - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; struct hci_request req; u8 val; int err; @@ -5265,7 +5267,7 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev, return err; } -static int conn_info_cmd_complete(struct pending_cmd *cmd, u8 status) +static int conn_info_cmd_complete(struct mgmt_pending_cmd *cmd, u8 status) { struct hci_conn *conn = cmd->user_data; struct mgmt_rp_get_conn_info rp; @@ -5296,7 +5298,7 @@ static void conn_info_refresh_complete(struct hci_dev *hdev, u8 hci_status, u16 opcode) { struct hci_cp_read_rssi *cp; - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; struct hci_conn *conn; u16 handle; u8 status; @@ -5409,7 +5411,7 @@ static int get_conn_info(struct sock *sk, struct hci_dev *hdev, void *data, struct hci_request req; struct hci_cp_read_tx_power req_txp_cp; struct hci_cp_read_rssi req_rssi_cp; - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; hci_req_init(&req, hdev); req_rssi_cp.handle = cpu_to_le16(conn->handle); @@ -5466,7 +5468,7 @@ unlock: return err; } -static int clock_info_cmd_complete(struct pending_cmd *cmd, u8 status) +static int clock_info_cmd_complete(struct mgmt_pending_cmd *cmd, u8 status) { struct hci_conn *conn = cmd->user_data; struct mgmt_rp_get_clock_info rp; @@ -5505,7 +5507,7 @@ complete: static void get_clock_info_complete(struct hci_dev *hdev, u8 status, u16 opcode) { struct hci_cp_read_clock *hci_cp; - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; struct hci_conn *conn; BT_DBG("%s status %u", hdev->name, status); @@ -5540,7 +5542,7 @@ static int get_clock_info(struct sock *sk, struct hci_dev *hdev, void *data, struct mgmt_cp_get_clock_info *cp = data; struct mgmt_rp_get_clock_info rp; struct hci_cp_read_clock hci_cp; - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; struct hci_request req; struct hci_conn *conn; int err; @@ -5683,7 +5685,7 @@ static void device_added(struct sock *sk, struct hci_dev *hdev, static void add_device_complete(struct hci_dev *hdev, u8 status, u16 opcode) { - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; BT_DBG("status 0x%02x", status); @@ -5704,7 +5706,7 @@ static int add_device(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) { struct mgmt_cp_add_device *cp = data; - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; struct hci_request req; u8 auto_conn, addr_type; int err; @@ -5806,7 +5808,7 @@ static void device_removed(struct sock *sk, struct hci_dev *hdev, static void remove_device_complete(struct hci_dev *hdev, u8 status, u16 opcode) { - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; BT_DBG("status 0x%02x", status); @@ -5827,7 +5829,7 @@ static int remove_device(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) { struct mgmt_cp_remove_device *cp = data; - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; struct hci_request req; int err; @@ -6530,7 +6532,7 @@ new_settings: void mgmt_set_powered_failed(struct hci_dev *hdev, int err) { - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; u8 status; cmd = mgmt_pending_find(MGMT_OP_SET_POWERED, hdev); @@ -6781,7 +6783,7 @@ void mgmt_device_connected(struct hci_dev *hdev, struct hci_conn *conn, sizeof(*ev) + eir_len, NULL); } -static void disconnect_rsp(struct pending_cmd *cmd, void *data) +static void disconnect_rsp(struct mgmt_pending_cmd *cmd, void *data) { struct sock **sk = data; @@ -6793,7 +6795,7 @@ static void disconnect_rsp(struct pending_cmd *cmd, void *data) mgmt_pending_remove(cmd); } -static void unpair_device_rsp(struct pending_cmd *cmd, void *data) +static void unpair_device_rsp(struct mgmt_pending_cmd *cmd, void *data) { struct hci_dev *hdev = data; struct mgmt_cp_unpair_device *cp = cmd->param; @@ -6806,7 +6808,7 @@ static void unpair_device_rsp(struct pending_cmd *cmd, void *data) bool mgmt_powering_down(struct hci_dev *hdev) { - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; struct mgmt_mode *cp; cmd = mgmt_pending_find(MGMT_OP_SET_POWERED, hdev); @@ -6861,7 +6863,7 @@ void mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, { u8 bdaddr_type = link_to_bdaddr(link_type, addr_type); struct mgmt_cp_disconnect *cp; - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; mgmt_pending_foreach(MGMT_OP_UNPAIR_DEVICE, hdev, unpair_device_rsp, hdev); @@ -6916,7 +6918,7 @@ void mgmt_pin_code_request(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 secure) void mgmt_pin_code_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 status) { - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_REPLY, hdev); if (!cmd) @@ -6929,7 +6931,7 @@ void mgmt_pin_code_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, void mgmt_pin_code_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 status) { - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_NEG_REPLY, hdev); if (!cmd) @@ -6974,7 +6976,7 @@ static int user_pairing_resp_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, u8 addr_type, u8 status, u8 opcode) { - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; cmd = mgmt_pending_find(opcode, hdev); if (!cmd) @@ -7035,7 +7037,7 @@ int mgmt_user_passkey_notify(struct hci_dev *hdev, bdaddr_t *bdaddr, void mgmt_auth_failed(struct hci_conn *conn, u8 hci_status) { struct mgmt_ev_auth_failed ev; - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; u8 status = mgmt_status(hci_status); bacpy(&ev.addr.bdaddr, &conn->dst); @@ -7150,7 +7152,7 @@ void mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 enable, u8 status) hci_req_run(&req, NULL); } -static void sk_lookup(struct pending_cmd *cmd, void *data) +static void sk_lookup(struct mgmt_pending_cmd *cmd, void *data) { struct cmd_lookup *match = data; @@ -7180,7 +7182,7 @@ void mgmt_set_class_of_dev_complete(struct hci_dev *hdev, u8 *dev_class, void mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status) { struct mgmt_cp_set_local_name ev; - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; if (status) return; @@ -7208,7 +7210,7 @@ void mgmt_read_local_oob_data_complete(struct hci_dev *hdev, u8 *hash192, u8 *rand192, u8 *hash256, u8 *rand256, u8 status) { - struct pending_cmd *cmd; + struct mgmt_pending_cmd *cmd; BT_DBG("%s status %u", hdev->name, status); -- GitLab From 7a00ff445f1337bbd0fbf65d3ae468dfbc7ba53e Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Fri, 6 Mar 2015 21:08:56 +0200 Subject: [PATCH 03041/11651] Bluetooth: Add mgmt_send_event() helper to send to any HCI channel Currently the mgmt_event() function is only capable of sending to HCI_CHANNEL_CONTROL. To void having to change all users of it, add a new mgmt_send_event() function that takes a channel parameter, and make the old mgmt_event() a wrapper that passes MGMT_CHANNEL_CONTROL to it. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- net/bluetooth/mgmt.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 62c23927684f..d769b428b630 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -219,8 +219,9 @@ static u8 mgmt_status(u8 hci_status) return MGMT_STATUS_FAILED; } -static int mgmt_event(u16 event, struct hci_dev *hdev, void *data, u16 data_len, - struct sock *skip_sk) +static int mgmt_send_event(u16 event, struct hci_dev *hdev, + unsigned short channel, void *data, u16 data_len, + struct sock *skip_sk) { struct sk_buff *skb; struct mgmt_hdr *hdr; @@ -243,12 +244,19 @@ static int mgmt_event(u16 event, struct hci_dev *hdev, void *data, u16 data_len, /* Time stamp */ __net_timestamp(skb); - hci_send_to_channel(HCI_CHANNEL_CONTROL, skb, skip_sk); + hci_send_to_channel(channel, skb, skip_sk); kfree_skb(skb); return 0; } +static int mgmt_event(u16 event, struct hci_dev *hdev, void *data, u16 len, + struct sock *skip_sk) +{ + return mgmt_send_event(event, hdev, HCI_CHANNEL_CONTROL, data, len, + skip_sk); +} + static int mgmt_cmd_status(struct sock *sk, u16 index, u16 cmd, u8 status) { struct sk_buff *skb; -- GitLab From e5abff1fe2e400bdabd14feb4e69e9ad661ba71a Mon Sep 17 00:00:00 2001 From: Jaewon Kim Date: Wed, 4 Mar 2015 14:43:40 -0800 Subject: [PATCH 03042/11651] Input: add haptic support for max77843 This patch adds support for haptic on max77843 MFD (Multi Function Device) with PMIC, MUIC, LED, CHARGER. This driver supports external pwm and LRA (Linear Resonant Actuator) motor. Signed-off-by: Jaewon Kim [Jim Davis : should depend on REGULATOR not PWM] Signed-off-by: Dmitry Torokhov --- drivers/input/misc/Kconfig | 12 + drivers/input/misc/Makefile | 1 + drivers/input/misc/max77843-haptic.c | 358 +++++++++++++++++++++++++++ 3 files changed, 371 insertions(+) create mode 100644 drivers/input/misc/max77843-haptic.c diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 6deb8dae3205..ef542f7ad944 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -165,6 +165,18 @@ config INPUT_MAX77693_HAPTIC To compile this driver as module, choose M here: the module will be called max77693-haptic. +config INPUT_MAX77843_HAPTIC + tristate "MAXIM MAX77843 haptic controller support" + depends on MFD_MAX77843 && REGULATOR + select INPUT_FF_MEMLESS + help + This option enables support for the haptic controller on + MAXIM MAX77843 chip. The driver supports ff-memless interface + from input framework. + + To compile this driver as module, choose M here: the + module will be called max77843-haptic. + config INPUT_MAX8925_ONKEY tristate "MAX8925 ONKEY support" depends on MFD_MAX8925 diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index 403a1a54a76c..75b58841d5a7 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile @@ -39,6 +39,7 @@ obj-$(CONFIG_INPUT_KEYSPAN_REMOTE) += keyspan_remote.o obj-$(CONFIG_INPUT_KXTJ9) += kxtj9.o obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o obj-$(CONFIG_INPUT_MAX77693_HAPTIC) += max77693-haptic.o +obj-$(CONFIG_INPUT_MAX77843_HAPTIC) += max77843-haptic.o obj-$(CONFIG_INPUT_MAX8925_ONKEY) += max8925_onkey.o obj-$(CONFIG_INPUT_MAX8997_HAPTIC) += max8997_haptic.o obj-$(CONFIG_INPUT_MC13783_PWRBUTTON) += mc13783-pwrbutton.o diff --git a/drivers/input/misc/max77843-haptic.c b/drivers/input/misc/max77843-haptic.c new file mode 100644 index 000000000000..dccbb465a055 --- /dev/null +++ b/drivers/input/misc/max77843-haptic.c @@ -0,0 +1,358 @@ +/* + * MAXIM MAX77693 Haptic device driver + * + * Copyright (C) 2015 Samsung Electronics + * Author: Jaewon Kim + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_MAGNITUDE_SHIFT 16 + +enum max77843_haptic_motor_type { + MAX77843_HAPTIC_ERM = 0, + MAX77843_HAPTIC_LRA, +}; + +enum max77843_haptic_pwm_divisor { + MAX77843_HAPTIC_PWM_DIVISOR_32 = 0, + MAX77843_HAPTIC_PWM_DIVISOR_64, + MAX77843_HAPTIC_PWM_DIVISOR_128, + MAX77843_HAPTIC_PWM_DIVISOR_256, +}; + +struct max77843_haptic { + struct regmap *regmap_haptic; + struct device *dev; + struct input_dev *input_dev; + struct pwm_device *pwm_dev; + struct regulator *motor_reg; + struct work_struct work; + struct mutex mutex; + + unsigned int magnitude; + unsigned int pwm_duty; + + bool active; + bool suspended; + + enum max77843_haptic_motor_type type; + enum max77843_haptic_pwm_divisor pwm_divisor; +}; + +static int max77843_haptic_set_duty_cycle(struct max77843_haptic *haptic) +{ + int delta = (haptic->pwm_dev->period + haptic->pwm_duty) / 2; + int error; + + error = pwm_config(haptic->pwm_dev, delta, haptic->pwm_dev->period); + if (error) { + dev_err(haptic->dev, "failed to configure pwm: %d\n", error); + return error; + } + + return 0; +} + +static int max77843_haptic_bias(struct max77843_haptic *haptic, bool on) +{ + int error; + + error = regmap_update_bits(haptic->regmap_haptic, + MAX77843_SYS_REG_MAINCTRL1, + MAX77843_MAINCTRL1_BIASEN_MASK, + on << MAINCTRL1_BIASEN_SHIFT); + if (error) { + dev_err(haptic->dev, "failed to %s bias: %d\n", + on ? "enable" : "disable", error); + return error; + } + + return 0; +} + +static int max77843_haptic_config(struct max77843_haptic *haptic, bool enable) +{ + unsigned int value; + int error; + + value = (haptic->type << MCONFIG_MODE_SHIFT) | + (enable << MCONFIG_MEN_SHIFT) | + (haptic->pwm_divisor << MCONFIG_PDIV_SHIFT); + + error = regmap_write(haptic->regmap_haptic, + MAX77843_HAP_REG_MCONFIG, value); + if (error) { + dev_err(haptic->dev, + "failed to update haptic config: %d\n", error); + return error; + } + + return 0; +} + +static int max77843_haptic_enable(struct max77843_haptic *haptic) +{ + int error; + + if (haptic->active) + return 0; + + error = pwm_enable(haptic->pwm_dev); + if (error) { + dev_err(haptic->dev, + "failed to enable pwm device: %d\n", error); + return error; + } + + error = max77843_haptic_config(haptic, true); + if (error) + goto err_config; + + haptic->active = true; + + return 0; + +err_config: + pwm_disable(haptic->pwm_dev); + + return error; +} + +static int max77843_haptic_disable(struct max77843_haptic *haptic) +{ + int error; + + if (!haptic->active) + return 0; + + error = max77843_haptic_config(haptic, false); + if (error) + return error; + + pwm_disable(haptic->pwm_dev); + + haptic->active = false; + + return 0; +} + +static void max77843_haptic_play_work(struct work_struct *work) +{ + struct max77843_haptic *haptic = + container_of(work, struct max77843_haptic, work); + int error; + + mutex_lock(&haptic->mutex); + + if (haptic->suspended) + goto out_unlock; + + if (haptic->magnitude) { + error = max77843_haptic_set_duty_cycle(haptic); + if (error) { + dev_err(haptic->dev, + "failed to set duty cycle: %d\n", error); + goto out_unlock; + } + + error = max77843_haptic_enable(haptic); + if (error) + dev_err(haptic->dev, + "cannot enable haptic: %d\n", error); + } else { + error = max77843_haptic_disable(haptic); + if (error) + dev_err(haptic->dev, + "cannot disable haptic: %d\n", error); + } + +out_unlock: + mutex_unlock(&haptic->mutex); +} + +static int max77843_haptic_play_effect(struct input_dev *dev, void *data, + struct ff_effect *effect) +{ + struct max77843_haptic *haptic = input_get_drvdata(dev); + u64 period_mag_multi; + + haptic->magnitude = effect->u.rumble.strong_magnitude; + if (!haptic->magnitude) + haptic->magnitude = effect->u.rumble.weak_magnitude; + + period_mag_multi = (u64)haptic->pwm_dev->period * haptic->magnitude; + haptic->pwm_duty = (unsigned int)(period_mag_multi >> + MAX_MAGNITUDE_SHIFT); + + schedule_work(&haptic->work); + + return 0; +} + +static int max77843_haptic_open(struct input_dev *dev) +{ + struct max77843_haptic *haptic = input_get_drvdata(dev); + int error; + + error = max77843_haptic_bias(haptic, true); + if (error) + return error; + + error = regulator_enable(haptic->motor_reg); + if (error) { + dev_err(haptic->dev, + "failed to enable regulator: %d\n", error); + return error; + } + + return 0; +} + +static void max77843_haptic_close(struct input_dev *dev) +{ + struct max77843_haptic *haptic = input_get_drvdata(dev); + int error; + + cancel_work_sync(&haptic->work); + max77843_haptic_disable(haptic); + + error = regulator_disable(haptic->motor_reg); + if (error) + dev_err(haptic->dev, + "failed to disable regulator: %d\n", error); + + max77843_haptic_bias(haptic, false); +} + +static int max77843_haptic_probe(struct platform_device *pdev) +{ + struct max77843 *max77843 = dev_get_drvdata(pdev->dev.parent); + struct max77843_haptic *haptic; + int error; + + haptic = devm_kzalloc(&pdev->dev, sizeof(*haptic), GFP_KERNEL); + if (!haptic) + return -ENOMEM; + + haptic->regmap_haptic = max77843->regmap; + haptic->dev = &pdev->dev; + haptic->type = MAX77843_HAPTIC_LRA; + haptic->pwm_divisor = MAX77843_HAPTIC_PWM_DIVISOR_128; + + INIT_WORK(&haptic->work, max77843_haptic_play_work); + mutex_init(&haptic->mutex); + + haptic->pwm_dev = devm_pwm_get(&pdev->dev, NULL); + if (IS_ERR(haptic->pwm_dev)) { + dev_err(&pdev->dev, "failed to get pwm device\n"); + return PTR_ERR(haptic->pwm_dev); + } + + haptic->motor_reg = devm_regulator_get_exclusive(&pdev->dev, "haptic"); + if (IS_ERR(haptic->motor_reg)) { + dev_err(&pdev->dev, "failed to get regulator\n"); + return PTR_ERR(haptic->motor_reg); + } + + haptic->input_dev = devm_input_allocate_device(&pdev->dev); + if (!haptic->input_dev) { + dev_err(&pdev->dev, "failed to allocate input device\n"); + return -ENOMEM; + } + + haptic->input_dev->name = "max77843-haptic"; + haptic->input_dev->id.version = 1; + haptic->input_dev->dev.parent = &pdev->dev; + haptic->input_dev->open = max77843_haptic_open; + haptic->input_dev->close = max77843_haptic_close; + input_set_drvdata(haptic->input_dev, haptic); + input_set_capability(haptic->input_dev, EV_FF, FF_RUMBLE); + + error = input_ff_create_memless(haptic->input_dev, NULL, + max77843_haptic_play_effect); + if (error) { + dev_err(&pdev->dev, "failed to create force-feedback\n"); + return error; + } + + error = input_register_device(haptic->input_dev); + if (error) { + dev_err(&pdev->dev, "failed to register input device\n"); + return error; + } + + platform_set_drvdata(pdev, haptic); + + return 0; +} + +static int __maybe_unused max77843_haptic_suspend(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct max77843_haptic *haptic = platform_get_drvdata(pdev); + int error; + + error = mutex_lock_interruptible(&haptic->mutex); + if (error) + return error; + + max77843_haptic_disable(haptic); + + haptic->suspended = true; + + mutex_unlock(&haptic->mutex); + + return 0; +} + +static int __maybe_unused max77843_haptic_resume(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct max77843_haptic *haptic = platform_get_drvdata(pdev); + unsigned int magnitude; + + mutex_lock(&haptic->mutex); + + haptic->suspended = false; + + magnitude = ACCESS_ONCE(haptic->magnitude); + if (magnitude) + max77843_haptic_enable(haptic); + + mutex_unlock(&haptic->mutex); + + return 0; +} + +static SIMPLE_DEV_PM_OPS(max77843_haptic_pm_ops, + max77843_haptic_suspend, max77843_haptic_resume); + +static struct platform_driver max77843_haptic_driver = { + .driver = { + .name = "max77843-haptic", + .pm = &max77843_haptic_pm_ops, + }, + .probe = max77843_haptic_probe, +}; +module_platform_driver(max77843_haptic_driver); + +MODULE_AUTHOR("Jaewon Kim "); +MODULE_DESCRIPTION("MAXIM MAX77843 Haptic driver"); +MODULE_LICENSE("GPL"); -- GitLab From d7535ffa427b8976b2d41f8d9f7fb9f1c97d786c Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 4 Mar 2015 14:47:58 -0800 Subject: [PATCH 03043/11651] Input: driver for microcontroller keys on the iPaq h3xxx This adds a key input driver for the keys found on the h3xxx iPAQ series. Based on a driver from handhelds.org 2.6.21 kernel, written by Alessandro GARDICH. Signed-off-by: Alessandro GARDICH Signed-off-by: Dmitry Artamonow Signed-off-by: Linus Walleij Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/Kconfig | 10 ++ drivers/input/keyboard/Makefile | 1 + drivers/input/keyboard/ipaq-micro-keys.c | 168 +++++++++++++++++++++++ 3 files changed, 179 insertions(+) create mode 100644 drivers/input/keyboard/ipaq-micro-keys.c diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index 17de1dcac637..106fbac7f8c5 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig @@ -588,6 +588,16 @@ config KEYBOARD_DAVINCI To compile this driver as a module, choose M here: the module will be called davinci_keyscan. +config KEYBOARD_IPAQ_MICRO + tristate "Buttons on Micro SoC (iPaq h3100,h3600,h3700)" + depends on MFD_IPAQ_MICRO + help + Say Y to enable support for the buttons attached to + Micro peripheral controller on iPAQ h3100/h3600/h3700 + + To compile this driver as a module, choose M here: the + module will be called ipaq-micro-keys. + config KEYBOARD_OMAP tristate "TI OMAP keypad support" depends on ARCH_OMAP1 diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index a648f6c6bbfa..df28d5553c05 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile @@ -24,6 +24,7 @@ obj-$(CONFIG_KEYBOARD_TCA6416) += tca6416-keypad.o obj-$(CONFIG_KEYBOARD_TCA8418) += tca8418_keypad.o obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o +obj-$(CONFIG_KEYBOARD_IPAQ_MICRO) += ipaq-micro-keys.o obj-$(CONFIG_KEYBOARD_IMX) += imx_keypad.o obj-$(CONFIG_KEYBOARD_HP6XX) += jornada680_kbd.o obj-$(CONFIG_KEYBOARD_HP7XX) += jornada720_kbd.o diff --git a/drivers/input/keyboard/ipaq-micro-keys.c b/drivers/input/keyboard/ipaq-micro-keys.c new file mode 100644 index 000000000000..602900d1f937 --- /dev/null +++ b/drivers/input/keyboard/ipaq-micro-keys.c @@ -0,0 +1,168 @@ +/* + * 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. + * + * h3600 atmel micro companion support, key subdevice + * based on previous kernel 2.4 version + * Author : Alessandro Gardich + * Author : Linus Walleij + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct ipaq_micro_keys { + struct ipaq_micro *micro; + struct input_dev *input; + u16 *codes; +}; + +static const u16 micro_keycodes[] = { + KEY_RECORD, /* 1: Record button */ + KEY_CALENDAR, /* 2: Calendar */ + KEY_ADDRESSBOOK, /* 3: Contacts (looks like Outlook) */ + KEY_MAIL, /* 4: Envelope (Q on older iPAQs) */ + KEY_HOMEPAGE, /* 5: Start (looks like swoopy arrow) */ + KEY_UP, /* 6: Up */ + KEY_RIGHT, /* 7: Right */ + KEY_LEFT, /* 8: Left */ + KEY_DOWN, /* 9: Down */ +}; + +static void micro_key_receive(void *data, int len, unsigned char *msg) +{ + struct ipaq_micro_keys *keys = data; + int key, down; + + down = 0x80 & msg[0]; + key = 0x7f & msg[0]; + + if (key < ARRAY_SIZE(micro_keycodes)) { + input_report_key(keys->input, keys->codes[key], down); + input_sync(keys->input); + } +} + +static void micro_key_start(struct ipaq_micro_keys *keys) +{ + spin_lock(&keys->micro->lock); + keys->micro->key = micro_key_receive; + keys->micro->key_data = keys; + spin_unlock(&keys->micro->lock); +} + +static void micro_key_stop(struct ipaq_micro_keys *keys) +{ + spin_lock(&keys->micro->lock); + keys->micro->key = NULL; + keys->micro->key_data = NULL; + spin_unlock(&keys->micro->lock); +} + +static int micro_key_open(struct input_dev *input) +{ + struct ipaq_micro_keys *keys = input_get_drvdata(input); + + micro_key_start(keys); + + return 0; +} + +static void micro_key_close(struct input_dev *input) +{ + struct ipaq_micro_keys *keys = input_get_drvdata(input); + + micro_key_stop(keys); +} + +static int micro_key_probe(struct platform_device *pdev) +{ + struct ipaq_micro_keys *keys; + int error; + int i; + + keys = devm_kzalloc(&pdev->dev, sizeof(*keys), GFP_KERNEL); + if (!keys) + return -ENOMEM; + + keys->micro = dev_get_drvdata(pdev->dev.parent); + + keys->input = devm_input_allocate_device(&pdev->dev); + if (!keys->input) + return -ENOMEM; + + keys->input->keycodesize = sizeof(micro_keycodes[0]); + keys->input->keycodemax = ARRAY_SIZE(micro_keycodes); + keys->codes = devm_kmemdup(&pdev->dev, micro_keycodes, + keys->input->keycodesize * keys->input->keycodemax, + GFP_KERNEL); + keys->input->keycode = keys->codes; + + __set_bit(EV_KEY, keys->input->evbit); + for (i = 0; i < ARRAY_SIZE(micro_keycodes); i++) + __set_bit(micro_keycodes[i], keys->input->keybit); + + keys->input->name = "h3600 micro keys"; + keys->input->open = micro_key_open; + keys->input->close = micro_key_close; + input_set_drvdata(keys->input, keys); + + error = input_register_device(keys->input); + if (error) + return error; + + platform_set_drvdata(pdev, keys); + return 0; +} + +static int __maybe_unused micro_key_suspend(struct device *dev) +{ + struct ipaq_micro_keys *keys = dev_get_drvdata(dev); + + micro_key_stop(keys); + + return 0; +} + +static int __maybe_unused micro_key_resume(struct device *dev) +{ + struct ipaq_micro_keys *keys = dev_get_drvdata(dev); + struct input_dev *input = keys->input; + + mutex_lock(&input->mutex); + + if (input->users) + micro_key_start(keys); + + mutex_unlock(&input->mutex); + + return 0; +} + +static SIMPLE_DEV_PM_OPS(micro_key_dev_pm_ops, + micro_key_suspend, micro_key_resume); + +static struct platform_driver micro_key_device_driver = { + .driver = { + .name = "ipaq-micro-keys", + .pm = µ_key_dev_pm_ops, + }, + .probe = micro_key_probe, +}; +module_platform_driver(micro_key_device_driver); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("driver for iPAQ Atmel micro keys"); +MODULE_ALIAS("platform:ipaq-micro-keys"); -- GitLab From 99e14c1e23108c34c4216d68c488fcd937310c32 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Fri, 27 Feb 2015 16:17:59 -0800 Subject: [PATCH 03044/11651] Input: psmouse - when comparing PNP IDs ignore case PNP IDs are supposed to be case-insensitive and so we should compare them as such. Acked-by: Hans de Goede Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/psmouse-base.c | 40 ++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 4ccd01d7a48d..bd91a8efa0f1 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c @@ -463,19 +463,45 @@ static int psmouse_poll(struct psmouse *psmouse) PSMOUSE_CMD_POLL | (psmouse->pktsize << 8)); } +static bool psmouse_check_pnp_id(const char *id, const char * const ids[]) +{ + int i; + + for (i = 0; ids[i]; i++) + if (!strcasecmp(id, ids[i])) + return true; + + return false; +} + /* * psmouse_matches_pnp_id - check if psmouse matches one of the passed in ids. */ bool psmouse_matches_pnp_id(struct psmouse *psmouse, const char * const ids[]) { - int i; - - if (!strncmp(psmouse->ps2dev.serio->firmware_id, "PNP:", 4)) - for (i = 0; ids[i]; i++) - if (strstr(psmouse->ps2dev.serio->firmware_id, ids[i])) - return true; + struct serio *serio = psmouse->ps2dev.serio; + char *p, *fw_id_copy, *save_ptr; + bool found = false; + + if (strncmp(serio->firmware_id, "PNP: ", 5)) + return false; + + fw_id_copy = kstrndup(&serio->firmware_id[5], + sizeof(serio->firmware_id) - 5, + GFP_KERNEL); + if (!fw_id_copy) + return false; + + save_ptr = fw_id_copy; + while ((p = strsep(&fw_id_copy, " ")) != NULL) { + if (psmouse_check_pnp_id(p, ids)) { + found = true; + break; + } + } - return false; + kfree(save_ptr); + return found; } /* -- GitLab From de4e374b401a736a2c278babe99b94756060d0e8 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 29 Dec 2014 14:43:44 -0800 Subject: [PATCH 03045/11651] Input: synaptics - switch ForcePad detection to PNP IDs According to Synaptics devices with ForcePads use SYN300D and SYN3014 as PNP IDs, so let's switch from DMI-bases detection scheme to PNP-based one, which should be more reliable. Suggested-by: Hans de Goede Acked-by: Hans de Goede Reviewed-by: Benjamin Tissoires Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/synaptics.c | 35 +++++++++++++-------------------- drivers/input/mouse/synaptics.h | 1 + 2 files changed, 15 insertions(+), 21 deletions(-) diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index f2cceb6493a0..4c69e3304011 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -194,6 +194,13 @@ static const char * const topbuttonpad_pnp_ids[] = { NULL }; +/* This list has been kindly provided by Synaptics. */ +static const char * const forcepad_pnp_ids[] = { + "SYN300D", + "SYN3014", + NULL +}; + /***************************************************************************** * Synaptics communications functions ****************************************************************************/ @@ -605,8 +612,6 @@ static void synaptics_parse_agm(const unsigned char buf[], } } -static bool is_forcepad; - static int synaptics_parse_hw_state(const unsigned char buf[], struct synaptics_data *priv, struct synaptics_hw_state *hw) @@ -636,7 +641,7 @@ static int synaptics_parse_hw_state(const unsigned char buf[], hw->left = (buf[0] & 0x01) ? 1 : 0; hw->right = (buf[0] & 0x02) ? 1 : 0; - if (is_forcepad) { + if (priv->is_forcepad) { /* * ForcePads, like Clickpads, use middle button * bits to report primary button clicks. @@ -1311,29 +1316,11 @@ static const struct dmi_system_id __initconst cr48_dmi_table[] = { { } }; -static const struct dmi_system_id forcepad_dmi_table[] __initconst = { -#if defined(CONFIG_DMI) && defined(CONFIG_X86) - { - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "HP EliteBook Folio 1040 G1"), - }, - }, -#endif - { } -}; - void __init synaptics_module_init(void) { impaired_toshiba_kbc = dmi_check_system(toshiba_dmi_table); broken_olpc_ec = dmi_check_system(olpc_dmi_table); cr48_profile_sensor = dmi_check_system(cr48_dmi_table); - - /* - * Unfortunately ForcePad capability is not exported over PS/2, - * so we have to resort to checking DMI. - */ - is_forcepad = dmi_check_system(forcepad_dmi_table); } static int __synaptics_init(struct psmouse *psmouse, bool absolute_mode) @@ -1368,6 +1355,12 @@ static int __synaptics_init(struct psmouse *psmouse, bool absolute_mode) if (SYN_ID_DISGEST_SUPPORTED(priv->identity)) priv->disable_gesture = true; + /* + * Unfortunately ForcePad capability is not exported over PS/2, + * so we have to resort to checking PNP IDs. + */ + priv->is_forcepad = psmouse_matches_pnp_id(psmouse, forcepad_pnp_ids); + if (synaptics_set_mode(psmouse)) { psmouse_err(psmouse, "Unable to initialize device.\n"); goto init_fail; diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h index aedc3299b14e..fb3838ca28de 100644 --- a/drivers/input/mouse/synaptics.h +++ b/drivers/input/mouse/synaptics.h @@ -168,6 +168,7 @@ struct synaptics_data { unsigned long press_start; bool press; bool report_press; + bool is_forcepad; }; void synaptics_module_init(void); -- GitLab From 616f45416ca0d726d6d3421a296ebc6e2bb82cde Mon Sep 17 00:00:00 2001 From: Mahesh Bandewar Date: Wed, 4 Mar 2015 21:57:52 -0800 Subject: [PATCH 03046/11651] bonding: implement bond_poll_controller() This patches implements the poll_controller support for all bonding driver. If the slaves have poll_controller net_op defined, this implementation calls them. This is mode agnostic implementation and iterates through all slaves (based on mode) and calls respective handler. Signed-off-by: Mahesh Bandewar Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 675b082283d6..c026ce9cd7b6 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -928,6 +928,39 @@ static inline void slave_disable_netpoll(struct slave *slave) static void bond_poll_controller(struct net_device *bond_dev) { + struct bonding *bond = netdev_priv(bond_dev); + struct slave *slave = NULL; + struct list_head *iter; + struct ad_info ad_info; + struct netpoll_info *ni; + const struct net_device_ops *ops; + + if (BOND_MODE(bond) == BOND_MODE_8023AD) + if (bond_3ad_get_active_agg_info(bond, &ad_info)) + return; + + rcu_read_lock_bh(); + bond_for_each_slave_rcu(bond, slave, iter) { + ops = slave->dev->netdev_ops; + if (!bond_slave_is_up(slave) || !ops->ndo_poll_controller) + continue; + + if (BOND_MODE(bond) == BOND_MODE_8023AD) { + struct aggregator *agg = + SLAVE_AD_INFO(slave)->port.aggregator; + + if (agg && + agg->aggregator_identifier != ad_info.aggregator_id) + continue; + } + + ni = rcu_dereference_bh(slave->dev->npinfo); + if (down_trylock(&ni->dev_lock)) + continue; + ops->ndo_poll_controller(slave->dev); + up(&ni->dev_lock); + } + rcu_read_unlock_bh(); } static void bond_netpoll_cleanup(struct net_device *bond_dev) -- GitLab From b716c4ffc6a2b0bfbcf9619880f335be11b65708 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 27 Feb 2015 17:34:15 +0200 Subject: [PATCH 03047/11651] spi: introduce master->handle_err() callback This callback would be useful to handle an error that occurs in the generic implementation of transfer_one_message(). The good candidate for this is to drain FIFO and / or to terminate DMA transfers when timeout happened. Signed-off-by: Andy Shevchenko Signed-off-by: Mark Brown --- drivers/spi/spi.c | 3 +++ include/linux/spi/spi.h | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index c64a3e59fce3..31d4d9d997e2 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -851,6 +851,9 @@ out: if (msg->status == -EINPROGRESS) msg->status = ret; + if (msg->status) + master->handle_err(master, msg); + spi_finalize_current_message(master); return ret; diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index ed9489d893a4..4eaac3a5227b 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -294,6 +294,8 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv) * transfer_one_message are mutually exclusive; when both * are set, the generic subsystem does not call your * transfer_one callback. + * @handle_err: the subsystem calls the driver to handle and error that occurs + * in the generic implementation of transfer_one_message(). * @unprepare_message: undo any work done by prepare_message(). * @cs_gpios: Array of GPIOs to use as chip select lines; one per CS * number. Any individual value may be -ENOENT for CS lines that @@ -448,6 +450,8 @@ struct spi_master { void (*set_cs)(struct spi_device *spi, bool enable); int (*transfer_one)(struct spi_master *master, struct spi_device *spi, struct spi_transfer *transfer); + void (*handle_err)(struct spi_master *master, + struct spi_message *message); /* gpio chip select */ int *cs_gpios; -- GitLab From 2291793cc4c6b1251e28a4ff0f98041147d57e96 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 27 Feb 2015 17:34:16 +0200 Subject: [PATCH 03048/11651] spi/rockchip: do an error handling in proper time There was handle_err() callback introduced that is dedicated for error handling. The patch moves error handling to this callback. Cc: Heiko Stuebner Cc: linux-rockchip@lists.infradead.org Signed-off-by: Andy Shevchenko Signed-off-by: Mark Brown --- drivers/spi/spi-rockchip.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/spi/spi-rockchip.c b/drivers/spi/spi-rockchip.c index 1a777dc261d6..25003c408c92 100644 --- a/drivers/spi/spi-rockchip.c +++ b/drivers/spi/spi-rockchip.c @@ -302,8 +302,8 @@ static int rockchip_spi_prepare_message(struct spi_master *master, return 0; } -static int rockchip_spi_unprepare_message(struct spi_master *master, - struct spi_message *msg) +static void rockchip_spi_handle_err(struct spi_master *master, + struct spi_message *msg) { unsigned long flags; struct rockchip_spi *rs = spi_master_get_devdata(master); @@ -313,8 +313,8 @@ static int rockchip_spi_unprepare_message(struct spi_master *master, /* * For DMA mode, we need terminate DMA channel and flush * fifo for the next transfer if DMA thansfer timeout. - * unprepare_message() was called by core if transfer complete - * or timeout. Maybe it is reasonable for error handling here. + * handle_err() was called by core if transfer failed. + * Maybe it is reasonable for error handling here. */ if (rs->use_dma) { if (rs->state & RXBUSY) { @@ -327,6 +327,12 @@ static int rockchip_spi_unprepare_message(struct spi_master *master, } spin_unlock_irqrestore(&rs->lock, flags); +} + +static int rockchip_spi_unprepare_message(struct spi_master *master, + struct spi_message *msg) +{ + struct rockchip_spi *rs = spi_master_get_devdata(master); spi_enable_chip(rs, 0); @@ -688,6 +694,7 @@ static int rockchip_spi_probe(struct platform_device *pdev) master->prepare_message = rockchip_spi_prepare_message; master->unprepare_message = rockchip_spi_unprepare_message; master->transfer_one = rockchip_spi_transfer_one; + master->handle_err = rockchip_spi_handle_err; rs->dma_tx.ch = dma_request_slave_channel(rs->dev, "tx"); if (!rs->dma_tx.ch) -- GitLab From df3a950e4e7386027fc174566aa5c24781297be8 Mon Sep 17 00:00:00 2001 From: Zubair Lutfullah Kakakhel Date: Fri, 27 Feb 2015 17:04:04 +0000 Subject: [PATCH 03049/11651] regulator: act8865: Add act8600 support This patch adds act8600 support to the act8865 driver. VBUS and USB charger supported by this chip can be added later Tested on MIPS Creator CI20 Signed-off-by: Zubair Lutfullah Kakakhel Signed-off-by: Mark Brown --- .../bindings/regulator/act8865-regulator.txt | 5 +- drivers/regulator/act8865-regulator.c | 120 +++++++++++++++++- include/linux/regulator/act8865.h | 14 ++ 3 files changed, 137 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/regulator/act8865-regulator.txt b/Documentation/devicetree/bindings/regulator/act8865-regulator.txt index dad6358074ac..e170df2357df 100644 --- a/Documentation/devicetree/bindings/regulator/act8865-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/act8865-regulator.txt @@ -2,7 +2,7 @@ ACT88xx regulators ------------------- Required properties: -- compatible: "active-semi,act8846" or "active-semi,act8865" +- compatible: "active-semi,act8846" or "active-semi,act8865" or "active-semi,act8600" - reg: I2C slave address Optional properties: @@ -16,6 +16,9 @@ The valid names for regulators are: REG1, REG2, REG3, REG4, REG5, REG6, REG7, REG8, REG9, REG10, REG11, REG12 - for act8865: DCDC_REG1, DCDC_REG2, DCDC_REG3, LDO_REG1, LDO_REG2, LDO_REG3, LDO_REG4. + - for act8600: + DCDC_REG1, DCDC_REG2, DCDC_REG3, SUDCDC_REG4, LDO_REG5, LDO_REG6, LDO_REG7, + LDO_REG8, LDO_REG9, LDO_REG10, Example: -------- diff --git a/drivers/regulator/act8865-regulator.c b/drivers/regulator/act8865-regulator.c index 9eec453b745d..3781f6e289d8 100644 --- a/drivers/regulator/act8865-regulator.c +++ b/drivers/regulator/act8865-regulator.c @@ -28,6 +28,35 @@ #include #include +/* + * ACT8600 Global Register Map. + */ +#define ACT8600_SYS_MODE 0x00 +#define ACT8600_SYS_CTRL 0x01 +#define ACT8600_DCDC1_VSET 0x10 +#define ACT8600_DCDC1_CTRL 0x12 +#define ACT8600_DCDC2_VSET 0x20 +#define ACT8600_DCDC2_CTRL 0x22 +#define ACT8600_DCDC3_VSET 0x30 +#define ACT8600_DCDC3_CTRL 0x32 +#define ACT8600_SUDCDC4_VSET 0x40 +#define ACT8600_SUDCDC4_CTRL 0x41 +#define ACT8600_LDO5_VSET 0x50 +#define ACT8600_LDO5_CTRL 0x51 +#define ACT8600_LDO6_VSET 0x60 +#define ACT8600_LDO6_CTRL 0x61 +#define ACT8600_LDO7_VSET 0x70 +#define ACT8600_LDO7_CTRL 0x71 +#define ACT8600_LDO8_VSET 0x80 +#define ACT8600_LDO8_CTRL 0x81 +#define ACT8600_LDO910_CTRL 0x91 +#define ACT8600_APCH0 0xA1 +#define ACT8600_APCH1 0xA8 +#define ACT8600_APCH2 0xA9 +#define ACT8600_APCH_STAT 0xAA +#define ACT8600_OTG0 0xB0 +#define ACT8600_OTG1 0xB2 + /* * ACT8846 Global Register Map. */ @@ -94,10 +123,15 @@ #define ACT8865_ENA 0x80 /* ON - [7] */ #define ACT8865_VSEL_MASK 0x3F /* VSET - [5:0] */ + +#define ACT8600_LDO10_ENA 0x40 /* ON - [6] */ +#define ACT8600_SUDCDC_VSEL_MASK 0xFF /* SUDCDC VSET - [7:0] */ + /* * ACT8865 voltage number */ #define ACT8865_VOLTAGE_NUM 64 +#define ACT8600_SUDCDC_VOLTAGE_NUM 255 struct act8865 { struct regmap *regmap; @@ -116,6 +150,13 @@ static const struct regulator_linear_range act8865_voltage_ranges[] = { REGULATOR_LINEAR_RANGE(2400000, 48, 63, 100000), }; +static const struct regulator_linear_range act8600_sudcdc_voltage_ranges[] = { + REGULATOR_LINEAR_RANGE(3000000, 0, 63, 0), + REGULATOR_LINEAR_RANGE(3000000, 64, 159, 100000), + REGULATOR_LINEAR_RANGE(12600000, 160, 191, 200000), + REGULATOR_LINEAR_RANGE(19000000, 191, 255, 400000), +}; + static struct regulator_ops act8865_ops = { .list_voltage = regulator_list_voltage_linear_range, .map_voltage = regulator_map_voltage_linear_range, @@ -126,6 +167,12 @@ static struct regulator_ops act8865_ops = { .is_enabled = regulator_is_enabled_regmap, }; +static struct regulator_ops act8865_ldo_ops = { + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, +}; + #define ACT88xx_REG(_name, _family, _id, _vsel_reg) \ [_family##_ID_##_id] = { \ .name = _name, \ @@ -142,6 +189,52 @@ static struct regulator_ops act8865_ops = { .owner = THIS_MODULE, \ } +static const struct regulator_desc act8600_regulators[] = { + ACT88xx_REG("DCDC1", ACT8600, DCDC1, VSET), + ACT88xx_REG("DCDC2", ACT8600, DCDC2, VSET), + ACT88xx_REG("DCDC3", ACT8600, DCDC3, VSET), + { + .name = "SUDCDC_REG4", + .id = ACT8600_ID_SUDCDC4, + .ops = &act8865_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = ACT8600_SUDCDC_VOLTAGE_NUM, + .linear_ranges = act8600_sudcdc_voltage_ranges, + .n_linear_ranges = ARRAY_SIZE(act8600_sudcdc_voltage_ranges), + .vsel_reg = ACT8600_SUDCDC4_VSET, + .vsel_mask = ACT8600_SUDCDC_VSEL_MASK, + .enable_reg = ACT8600_SUDCDC4_CTRL, + .enable_mask = ACT8865_ENA, + .owner = THIS_MODULE, + }, + ACT88xx_REG("LDO5", ACT8600, LDO5, VSET), + ACT88xx_REG("LDO6", ACT8600, LDO6, VSET), + ACT88xx_REG("LDO7", ACT8600, LDO7, VSET), + ACT88xx_REG("LDO8", ACT8600, LDO8, VSET), + { + .name = "LDO_REG9", + .id = ACT8600_ID_LDO9, + .ops = &act8865_ldo_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = 1, + .fixed_uV = 1800000, + .enable_reg = ACT8600_LDO910_CTRL, + .enable_mask = ACT8865_ENA, + .owner = THIS_MODULE, + }, + { + .name = "LDO_REG10", + .id = ACT8600_ID_LDO10, + .ops = &act8865_ldo_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = 1, + .fixed_uV = 1200000, + .enable_reg = ACT8600_LDO910_CTRL, + .enable_mask = ACT8600_LDO10_ENA, + .owner = THIS_MODULE, + }, +}; + static const struct regulator_desc act8846_regulators[] = { ACT88xx_REG("REG1", ACT8846, REG1, VSET), ACT88xx_REG("REG2", ACT8846, REG2, VSET0), @@ -169,6 +262,7 @@ static const struct regulator_desc act8865_regulators[] = { #ifdef CONFIG_OF static const struct of_device_id act8865_dt_ids[] = { + { .compatible = "active-semi,act8600", .data = (void *)ACT8600 }, { .compatible = "active-semi,act8846", .data = (void *)ACT8846 }, { .compatible = "active-semi,act8865", .data = (void *)ACT8865 }, { } @@ -200,6 +294,19 @@ static struct of_regulator_match act8865_matches[] = { [ACT8865_ID_LDO4] = { .name = "LDO_REG4"}, }; +static struct of_regulator_match act8600_matches[] = { + [ACT8600_ID_DCDC1] = { .name = "DCDC_REG1"}, + [ACT8600_ID_DCDC2] = { .name = "DCDC_REG2"}, + [ACT8600_ID_DCDC3] = { .name = "DCDC_REG3"}, + [ACT8600_ID_SUDCDC4] = { .name = "SUDCDC_REG4"}, + [ACT8600_ID_LDO5] = { .name = "LDO_REG5"}, + [ACT8600_ID_LDO6] = { .name = "LDO_REG6"}, + [ACT8600_ID_LDO7] = { .name = "LDO_REG7"}, + [ACT8600_ID_LDO8] = { .name = "LDO_REG8"}, + [ACT8600_ID_LDO9] = { .name = "LDO_REG9"}, + [ACT8600_ID_LDO10] = { .name = "LDO_REG10"}, +}; + static int act8865_pdata_from_dt(struct device *dev, struct device_node **of_node, struct act8865_platform_data *pdata, @@ -217,6 +324,10 @@ static int act8865_pdata_from_dt(struct device *dev, } switch (type) { + case ACT8600: + matches = act8600_matches; + num_matches = ARRAY_SIZE(act8600_matches); + break; case ACT8846: matches = act8846_matches; num_matches = ARRAY_SIZE(act8846_matches); @@ -317,6 +428,12 @@ static int act8865_pmic_probe(struct i2c_client *client, } switch (type) { + case ACT8600: + regulators = act8600_regulators; + num_regulators = ARRAY_SIZE(act8600_regulators); + off_reg = -1; + off_mask = -1; + break; case ACT8846: regulators = act8846_regulators; num_regulators = ARRAY_SIZE(act8846_regulators); @@ -366,7 +483,7 @@ static int act8865_pmic_probe(struct i2c_client *client, } if (of_device_is_system_power_controller(dev->of_node)) { - if (!pm_power_off) { + if (!pm_power_off && (off_reg > 0)) { act8865_i2c_client = client; act8865->off_reg = off_reg; act8865->off_mask = off_mask; @@ -402,6 +519,7 @@ static int act8865_pmic_probe(struct i2c_client *client, } static const struct i2c_device_id act8865_ids[] = { + { .name = "act8600", .driver_data = ACT8600 }, { .name = "act8846", .driver_data = ACT8846 }, { .name = "act8865", .driver_data = ACT8865 }, { }, diff --git a/include/linux/regulator/act8865.h b/include/linux/regulator/act8865.h index b6c4909b33af..15fa8f2d35c9 100644 --- a/include/linux/regulator/act8865.h +++ b/include/linux/regulator/act8865.h @@ -18,6 +18,19 @@ #include +enum { + ACT8600_ID_DCDC1, + ACT8600_ID_DCDC2, + ACT8600_ID_DCDC3, + ACT8600_ID_SUDCDC4, + ACT8600_ID_LDO5, + ACT8600_ID_LDO6, + ACT8600_ID_LDO7, + ACT8600_ID_LDO8, + ACT8600_ID_LDO9, + ACT8600_ID_LDO10, +}; + enum { ACT8865_ID_DCDC1, ACT8865_ID_DCDC2, @@ -46,6 +59,7 @@ enum { }; enum { + ACT8600, ACT8865, ACT8846, }; -- GitLab From 45b064d73d6a5cfcfa76012b91e2afc98e341664 Mon Sep 17 00:00:00 2001 From: Alexander Sverdlin Date: Fri, 27 Feb 2015 16:30:01 +0100 Subject: [PATCH 03050/11651] spi: pl022: Remove incorrect TxFIFO full reporting According to PL022 specification, TNF bit states for "Transmit FIFO Not full". So the logic here is inverted. But "Receive Overrun Interrupt", which is handled here, is only triggered on Rx errors. So instead of fixing the if statement, remove the whole message. Signed-off-by: Alexander Sverdlin Signed-off-by: Mark Brown --- drivers/spi/spi-pl022.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c index 89ca162801da..4381fcf2389c 100644 --- a/drivers/spi/spi-pl022.c +++ b/drivers/spi/spi-pl022.c @@ -1280,9 +1280,6 @@ static irqreturn_t pl022_interrupt_handler(int irq, void *dev_id) if (readw(SSP_SR(pl022->virtbase)) & SSP_SR_MASK_RFF) dev_err(&pl022->adev->dev, "RXFIFO is full\n"); - if (readw(SSP_SR(pl022->virtbase)) & SSP_SR_MASK_TNF) - dev_err(&pl022->adev->dev, - "TXFIFO is full\n"); /* * Disable and clear interrupts, disable SSP, -- GitLab From 85fa4e1f094183d230c47fa1e83373f692dc05ec Mon Sep 17 00:00:00 2001 From: Alexander Sverdlin Date: Fri, 27 Feb 2015 16:30:07 +0100 Subject: [PATCH 03051/11651] spi: pl022: Don't touch unspecified bits in interrupt mask PL022 Programmers model explicitely states "do not modify undefined register bits". Correct the "all enable" interrupt mask so that it only enables defined ones. Signed-off-by: Alexander Sverdlin Signed-off-by: Mark Brown --- drivers/spi/spi-pl022.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c index 4381fcf2389c..a45406aa2b14 100644 --- a/drivers/spi/spi-pl022.c +++ b/drivers/spi/spi-pl022.c @@ -285,7 +285,12 @@ */ #define DEFAULT_SSP_REG_IMSC 0x0UL #define DISABLE_ALL_INTERRUPTS DEFAULT_SSP_REG_IMSC -#define ENABLE_ALL_INTERRUPTS (~DEFAULT_SSP_REG_IMSC) +#define ENABLE_ALL_INTERRUPTS ( \ + SSP_IMSC_MASK_RORIM | \ + SSP_IMSC_MASK_RTIM | \ + SSP_IMSC_MASK_RXIM | \ + SSP_IMSC_MASK_TXIM \ +) #define CLEAR_ALL_INTERRUPTS 0x3 -- GitLab From 7183d1ebda477c48e5f51f854a766c96b6c0e142 Mon Sep 17 00:00:00 2001 From: Alexander Sverdlin Date: Fri, 27 Feb 2015 16:30:15 +0100 Subject: [PATCH 03052/11651] spi: pl022: Remove dead code "flag" variable does nothing, remove it. Signed-off-by: Alexander Sverdlin Signed-off-by: Mark Brown --- drivers/spi/spi-pl022.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c index a45406aa2b14..e96189c7834c 100644 --- a/drivers/spi/spi-pl022.c +++ b/drivers/spi/spi-pl022.c @@ -1256,7 +1256,6 @@ static irqreturn_t pl022_interrupt_handler(int irq, void *dev_id) struct pl022 *pl022 = dev_id; struct spi_message *msg = pl022->cur_msg; u16 irq_status = 0; - u16 flag = 0; if (unlikely(!msg)) { dev_err(&pl022->adev->dev, @@ -1305,8 +1304,7 @@ static irqreturn_t pl022_interrupt_handler(int irq, void *dev_id) readwriter(pl022); - if ((pl022->tx == pl022->tx_end) && (flag == 0)) { - flag = 1; + if (pl022->tx == pl022->tx_end) { /* Disable Transmit interrupt, enable receive interrupt */ writew((readw(SSP_IMSC(pl022->virtbase)) & ~SSP_IMSC_MASK_TXIM) | SSP_IMSC_MASK_RXIM, -- GitLab From cd6fa8d2ca53cac3226fdcffcf763be390abae32 Mon Sep 17 00:00:00 2001 From: Alexander Sverdlin Date: Fri, 27 Feb 2015 16:30:21 +0100 Subject: [PATCH 03053/11651] spi: pl022: Fix race in giveback() leading to driver lock-up Commit fd316941c ("spi/pl022: disable port when unused") introduced a race, which leads to possible driver lock up (easily reproducible on SMP). The problem happens in giveback() function where the completion of the transfer is signalled to SPI subsystem and then the HW SPI controller is disabled. Another transfer might be setup in between, which brings driver in locked-up state. Exact event sequence on SMP: core0 core1 => pump_transfers() /* message->state == STATE_DONE */ => giveback() => spi_finalize_current_message() => pl022_unprepare_transfer_hardware() => pl022_transfer_one_message => flush() => do_interrupt_dma_transfer() => set_up_next_transfer() /* Enable SSP, turn on interrupts */ writew((readw(SSP_CR1(pl022->virtbase)) | SSP_CR1_MASK_SSE), SSP_CR1(pl022->virtbase)); ... => pl022_interrupt_handler() => readwriter() /* disable the SPI/SSP operation */ => writew((readw(SSP_CR1(pl022->virtbase)) & (~SSP_CR1_MASK_SSE)), SSP_CR1(pl022->virtbase)); Lockup! SPI controller is disabled and the data will never be received. Whole SPI subsystem is waiting for transfer ACK and blocked. So, only signal transfer completion after disabling the controller. Fixes: fd316941c (spi/pl022: disable port when unused) Signed-off-by: Alexander Sverdlin Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- drivers/spi/spi-pl022.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c index 89ca162801da..ee513a85296b 100644 --- a/drivers/spi/spi-pl022.c +++ b/drivers/spi/spi-pl022.c @@ -534,12 +534,12 @@ static void giveback(struct pl022 *pl022) pl022->cur_msg = NULL; pl022->cur_transfer = NULL; pl022->cur_chip = NULL; - spi_finalize_current_message(pl022->master); /* disable the SPI/SSP operation */ writew((readw(SSP_CR1(pl022->virtbase)) & (~SSP_CR1_MASK_SSE)), SSP_CR1(pl022->virtbase)); + spi_finalize_current_message(pl022->master); } /** -- GitLab From 3d4cf65e2db58f927ca3cd13b0074b8fe5124659 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 25 Feb 2015 16:42:12 +0100 Subject: [PATCH 03054/11651] ASoC: omap: fix up SND_OMAP_SOC_OMAP_ABE_TWL6040 dependency The change to enable OMAP5 support on this platform was a little too eager in adding a 'select' for a particular clock driver that might not be enabled in all configurations, which in turn leads to a build error: warning: (SND_OMAP_SOC_OMAP_ABE_TWL6040) selects COMMON_CLK_PALMAS which has unmet direct dependencies (COMMON_CLK && MFD_PALMAS) drivers/built-in.o: In function `palmas_clks_probe': drivers/clk/clk-palmas.c:228: undefined reference to `palmas_ext_control_req_config' I do not see a strong dependency here, so it's probably better to drop this select and to avoid adding more complexity here. Fixes: 5163c1eede8e9 ("ASoC: omap: Kconfig: Support for omap5-uevm analog audio") Signed-off-by: Arnd Bergmann Acked-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/omap/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig index e7c78b0406b5..6768e4f7d7d0 100644 --- a/sound/soc/omap/Kconfig +++ b/sound/soc/omap/Kconfig @@ -105,7 +105,7 @@ config SND_OMAP_SOC_OMAP_ABE_TWL6040 select SND_OMAP_SOC_MCPDM select SND_SOC_TWL6040 select SND_SOC_DMIC - select COMMON_CLK_PALMAS if SOC_OMAP5 + select COMMON_CLK_PALMAS if MFD_PALMAS help Say Y if you want to add support for SoC audio on OMAP boards using ABE and twl6040 codec. This driver currently supports: -- GitLab From aaa4e70404c7b38a8792dc69af54afd7218b2ec0 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Wed, 4 Mar 2015 10:16:43 -0600 Subject: [PATCH 03055/11651] DECnet: Only use neigh_ops for adding the link layer header Other users users of the neighbour table use neigh->output as the method to decided when and which link-layer header to place on a packet. DECnet has been using neigh->output to decide which DECnet headers to place on a packet depending which neighbour the packet is destined for. The DECnet usage isn't totally wrong but it can run into problems if the neighbour output function is run for a second time as the teql driver and the bridge netfilter code can do. Therefore to avoid pathologic problems later down the line and make the neighbour code easier to understand by refactoring the decnet output code to only use a neighbour method to add a link layer header to a packet. This is done by moving the neigbhour operations lookup from dn_to_neigh_output to dn_neigh_output_packet. Signed-off-by: "Eric W. Biederman" Signed-off-by: David S. Miller --- include/net/dn_neigh.h | 1 + net/decnet/dn_neigh.c | 105 +++++++++++++++++++++-------------------- net/decnet/dn_route.c | 9 ---- 3 files changed, 55 insertions(+), 60 deletions(-) diff --git a/include/net/dn_neigh.h b/include/net/dn_neigh.h index fac4e3f4a6d3..0f26aa707e62 100644 --- a/include/net/dn_neigh.h +++ b/include/net/dn_neigh.h @@ -22,6 +22,7 @@ int dn_neigh_router_hello(struct sk_buff *skb); int dn_neigh_endnode_hello(struct sk_buff *skb); void dn_neigh_pointopoint_hello(struct sk_buff *skb); int dn_neigh_elist(struct net_device *dev, unsigned char *ptr, int n); +int dn_to_neigh_output(struct sk_buff *skb); extern struct neigh_table dn_neigh_table; diff --git a/net/decnet/dn_neigh.c b/net/decnet/dn_neigh.c index ee7d1cef0027..be1f08cdad29 100644 --- a/net/decnet/dn_neigh.c +++ b/net/decnet/dn_neigh.c @@ -49,41 +49,17 @@ #include static int dn_neigh_construct(struct neighbour *); -static void dn_long_error_report(struct neighbour *, struct sk_buff *); -static void dn_short_error_report(struct neighbour *, struct sk_buff *); -static int dn_long_output(struct neighbour *, struct sk_buff *); -static int dn_short_output(struct neighbour *, struct sk_buff *); -static int dn_phase3_output(struct neighbour *, struct sk_buff *); - - -/* - * For talking to broadcast devices: Ethernet & PPP - */ -static const struct neigh_ops dn_long_ops = { - .family = AF_DECnet, - .error_report = dn_long_error_report, - .output = dn_long_output, - .connected_output = dn_long_output, -}; +static void dn_neigh_error_report(struct neighbour *, struct sk_buff *); +static int dn_neigh_output(struct neighbour *neigh, struct sk_buff *skb); /* - * For talking to pointopoint and multidrop devices: DDCMP and X.25 + * Operations for adding the link layer header. */ -static const struct neigh_ops dn_short_ops = { +static const struct neigh_ops dn_neigh_ops = { .family = AF_DECnet, - .error_report = dn_short_error_report, - .output = dn_short_output, - .connected_output = dn_short_output, -}; - -/* - * For talking to DECnet phase III nodes - */ -static const struct neigh_ops dn_phase3_ops = { - .family = AF_DECnet, - .error_report = dn_short_error_report, /* Can use short version here */ - .output = dn_phase3_output, - .connected_output = dn_phase3_output, + .error_report = dn_neigh_error_report, + .output = dn_neigh_output, + .connected_output = dn_neigh_output, }; static u32 dn_neigh_hash(const void *pkey, @@ -153,16 +129,9 @@ static int dn_neigh_construct(struct neighbour *neigh) __neigh_parms_put(neigh->parms); neigh->parms = neigh_parms_clone(parms); - - if (dn_db->use_long) - neigh->ops = &dn_long_ops; - else - neigh->ops = &dn_short_ops; rcu_read_unlock(); - if (dn->flags & DN_NDFLAG_P3) - neigh->ops = &dn_phase3_ops; - + neigh->ops = &dn_neigh_ops; neigh->nud_state = NUD_NOARP; neigh->output = neigh->ops->connected_output; @@ -194,24 +163,16 @@ static int dn_neigh_construct(struct neighbour *neigh) return 0; } -static void dn_long_error_report(struct neighbour *neigh, struct sk_buff *skb) -{ - printk(KERN_DEBUG "dn_long_error_report: called\n"); - kfree_skb(skb); -} - - -static void dn_short_error_report(struct neighbour *neigh, struct sk_buff *skb) +static void dn_neigh_error_report(struct neighbour *neigh, struct sk_buff *skb) { - printk(KERN_DEBUG "dn_short_error_report: called\n"); + printk(KERN_DEBUG "dn_neigh_error_report: called\n"); kfree_skb(skb); } -static int dn_neigh_output_packet(struct sk_buff *skb) +static int dn_neigh_output(struct neighbour *neigh, struct sk_buff *skb) { struct dst_entry *dst = skb_dst(skb); struct dn_route *rt = (struct dn_route *)dst; - struct neighbour *neigh = rt->n; struct net_device *dev = neigh->dev; char mac_addr[ETH_ALEN]; unsigned int seq; @@ -233,6 +194,18 @@ static int dn_neigh_output_packet(struct sk_buff *skb) return err; } +static int dn_neigh_output_packet(struct sk_buff *skb) +{ + struct dst_entry *dst = skb_dst(skb); + struct dn_route *rt = (struct dn_route *)dst; + struct neighbour *neigh = rt->n; + + return neigh->output(neigh, skb); +} + +/* + * For talking to broadcast devices: Ethernet & PPP + */ static int dn_long_output(struct neighbour *neigh, struct sk_buff *skb) { struct net_device *dev = neigh->dev; @@ -276,6 +249,9 @@ static int dn_long_output(struct neighbour *neigh, struct sk_buff *skb) neigh->dev, dn_neigh_output_packet); } +/* + * For talking to pointopoint and multidrop devices: DDCMP and X.25 + */ static int dn_short_output(struct neighbour *neigh, struct sk_buff *skb) { struct net_device *dev = neigh->dev; @@ -313,7 +289,8 @@ static int dn_short_output(struct neighbour *neigh, struct sk_buff *skb) } /* - * Phase 3 output is the same is short output, execpt that + * For talking to DECnet phase III nodes + * Phase 3 output is the same as short output, execpt that * it clears the area bits before transmission. */ static int dn_phase3_output(struct neighbour *neigh, struct sk_buff *skb) @@ -351,6 +328,32 @@ static int dn_phase3_output(struct neighbour *neigh, struct sk_buff *skb) neigh->dev, dn_neigh_output_packet); } +int dn_to_neigh_output(struct sk_buff *skb) +{ + struct dst_entry *dst = skb_dst(skb); + struct dn_route *rt = (struct dn_route *) dst; + struct neighbour *neigh = rt->n; + struct dn_neigh *dn = (struct dn_neigh *)neigh; + struct dn_dev *dn_db; + bool use_long; + + rcu_read_lock(); + dn_db = rcu_dereference(neigh->dev->dn_ptr); + if (dn_db == NULL) { + rcu_read_unlock(); + return -EINVAL; + } + use_long = dn_db->use_long; + rcu_read_unlock(); + + if (dn->flags & DN_NDFLAG_P3) + return dn_phase3_output(neigh, skb); + if (use_long) + return dn_long_output(neigh, skb); + else + return dn_short_output(neigh, skb); +} + /* * Unfortunately, the neighbour code uses the device in its hash * function, so we don't get any advantage from it. This function diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index 3b81092771f8..771815575dbd 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c @@ -743,15 +743,6 @@ out: return NET_RX_DROP; } -static int dn_to_neigh_output(struct sk_buff *skb) -{ - struct dst_entry *dst = skb_dst(skb); - struct dn_route *rt = (struct dn_route *) dst; - struct neighbour *n = rt->n; - - return n->output(n, skb); -} - static int dn_output(struct sock *sk, struct sk_buff *skb) { struct dst_entry *dst = skb_dst(skb); -- GitLab From dcd8fb8533ceb493146ce030d15f7965b82d0c27 Mon Sep 17 00:00:00 2001 From: Fan Du Date: Fri, 6 Mar 2015 11:18:22 +0800 Subject: [PATCH 03056/11651] ipv4: Raise tcp PMTU probe mss base size Quotes from RFC4821 7.2. Selecting Initial Values It is RECOMMENDED that search_low be initially set to an MTU size that is likely to work over a very wide range of environments. Given today's technologies, a value of 1024 bytes is probably safe enough. The initial value for search_low SHOULD be configurable. Moreover, set a small value will introduce extra time for the search to converge. So set the initial probe base mss size to 1024 Bytes. Signed-off-by: Fan Du Acked-by: John Heffner Signed-off-by: David S. Miller --- include/net/tcp.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/net/tcp.h b/include/net/tcp.h index f87599d5af82..834089b0cffc 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -65,7 +65,7 @@ void tcp_time_wait(struct sock *sk, int state, int timeo); #define TCP_MIN_MSS 88U /* The least MTU to use for probing */ -#define TCP_BASE_MSS 512 +#define TCP_BASE_MSS 1024 /* After receiving this amount of duplicate ACKs fast retransmit starts. */ #define TCP_FASTRETRANS_THRESH 3 -- GitLab From 6b58e0a5f32dedb609438bb9c9c82aa6e23381f2 Mon Sep 17 00:00:00 2001 From: Fan Du Date: Fri, 6 Mar 2015 11:18:23 +0800 Subject: [PATCH 03057/11651] ipv4: Use binary search to choose tcp PMTU probe_size Current probe_size is chosen by doubling mss_cache, the probing process will end shortly with a sub-optimal mss size, and the link mtu will not be taken full advantage of, in return, this will make user to tweak tcp_base_mss with care. Use binary search to choose probe_size in a fine granularity manner, an optimal mss will be found to boost performance as its maxmium. In addition, introduce a sysctl_tcp_probe_threshold to control when probing will stop in respect to the width of search range. Test env: Docker instance with vxlan encapuslation(82599EB) iperf -c 10.0.0.24 -t 60 before this patch: 1.26 Gbits/sec After this patch: increase 26% 1.59 Gbits/sec Signed-off-by: Fan Du Acked-by: John Heffner Signed-off-by: David S. Miller --- include/net/netns/ipv4.h | 1 + include/net/tcp.h | 3 +++ net/ipv4/sysctl_net_ipv4.c | 7 +++++++ net/ipv4/tcp_ipv4.c | 1 + net/ipv4/tcp_output.c | 14 +++++++++++--- 5 files changed, 23 insertions(+), 3 deletions(-) diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h index 1085e12f940f..e051d399fa17 100644 --- a/include/net/netns/ipv4.h +++ b/include/net/netns/ipv4.h @@ -87,6 +87,7 @@ struct netns_ipv4 { int sysctl_tcp_fwmark_accept; int sysctl_tcp_mtu_probing; int sysctl_tcp_base_mss; + int sysctl_tcp_probe_threshold; struct ping_group_range ping_group_range; diff --git a/include/net/tcp.h b/include/net/tcp.h index 834089b0cffc..1ad82e334e27 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -67,6 +67,9 @@ void tcp_time_wait(struct sock *sk, int state, int timeo); /* The least MTU to use for probing */ #define TCP_BASE_MSS 1024 +/* Specify interval when tcp mtu probing will stop */ +#define TCP_PROBE_THRESHOLD 8 + /* After receiving this amount of duplicate ACKs fast retransmit starts. */ #define TCP_FASTRETRANS_THRESH 3 diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index d151539da8e6..d3c09c12ee81 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c @@ -883,6 +883,13 @@ static struct ctl_table ipv4_net_table[] = { .mode = 0644, .proc_handler = proc_dointvec, }, + { + .procname = "tcp_probe_threshold", + .data = &init_net.ipv4.sysctl_tcp_probe_threshold, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec, + }, { } }; diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 5a2dfed4783b..35790d977a2b 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -2460,6 +2460,7 @@ static int __net_init tcp_sk_init(struct net *net) } net->ipv4.sysctl_tcp_ecn = 2; net->ipv4.sysctl_tcp_base_mss = TCP_BASE_MSS; + net->ipv4.sysctl_tcp_probe_threshold = TCP_PROBE_THRESHOLD; return 0; fail: diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 8bbd86cd81c8..ed024cbb097f 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -1842,11 +1842,13 @@ static int tcp_mtu_probe(struct sock *sk) struct tcp_sock *tp = tcp_sk(sk); struct inet_connection_sock *icsk = inet_csk(sk); struct sk_buff *skb, *nskb, *next; + struct net *net = sock_net(sk); int len; int probe_size; int size_needed; int copy; int mss_now; + int interval; /* Not currently probing/verifying, * not in recovery, @@ -1859,11 +1861,17 @@ static int tcp_mtu_probe(struct sock *sk) tp->rx_opt.num_sacks || tp->rx_opt.dsack) return -1; - /* Very simple search strategy: just double the MSS. */ + /* Use binary search for probe_size between tcp_mss_base, + * and current mss_clamp. if (search_high - search_low) + * smaller than a threshold, backoff from probing. + */ mss_now = tcp_current_mss(sk); - probe_size = 2 * tp->mss_cache; + probe_size = tcp_mtu_to_mss(sk, (icsk->icsk_mtup.search_high + + icsk->icsk_mtup.search_low) >> 1); size_needed = probe_size + (tp->reordering + 1) * tp->mss_cache; - if (probe_size > tcp_mtu_to_mss(sk, icsk->icsk_mtup.search_high)) { + interval = icsk->icsk_mtup.search_high - icsk->icsk_mtup.search_low; + if (probe_size > tcp_mtu_to_mss(sk, icsk->icsk_mtup.search_high) || + interval < max(1, net->ipv4.sysctl_tcp_probe_threshold)) { /* TODO: set timer for probe_converge_event */ return -1; } -- GitLab From 05cbc0db03e82128f2e7e353d4194dd24a1627fe Mon Sep 17 00:00:00 2001 From: Fan Du Date: Fri, 6 Mar 2015 11:18:24 +0800 Subject: [PATCH 03058/11651] ipv4: Create probe timer for tcp PMTU as per RFC4821 As per RFC4821 7.3. Selecting Probe Size, a probe timer should be armed once probing has converged. Once this timer expired, probing again to take advantage of any path PMTU change. The recommended probing interval is 10 minutes per RFC1981. Probing interval could be sysctled by sysctl_tcp_probe_interval. Eric Dumazet suggested to implement pseudo timer based on 32bits jiffies tcp_time_stamp instead of using classic timer for such rare event. Signed-off-by: Fan Du Signed-off-by: David S. Miller --- include/net/inet_connection_sock.h | 2 ++ include/net/netns/ipv4.h | 1 + include/net/tcp.h | 3 +++ net/ipv4/sysctl_net_ipv4.c | 7 ++++++ net/ipv4/tcp_ipv4.c | 1 + net/ipv4/tcp_output.c | 38 ++++++++++++++++++++++++++++-- net/ipv4/tcp_timer.c | 1 + 7 files changed, 51 insertions(+), 2 deletions(-) diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h index 5976bdecf58b..b9a6b0a94cc6 100644 --- a/include/net/inet_connection_sock.h +++ b/include/net/inet_connection_sock.h @@ -126,6 +126,8 @@ struct inet_connection_sock { /* Information on the current probe. */ int probe_size; + + u32 probe_timestamp; } icsk_mtup; u32 icsk_ca_priv[16]; u32 icsk_user_timeout; diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h index e051d399fa17..8f3a1a1a5a94 100644 --- a/include/net/netns/ipv4.h +++ b/include/net/netns/ipv4.h @@ -88,6 +88,7 @@ struct netns_ipv4 { int sysctl_tcp_mtu_probing; int sysctl_tcp_base_mss; int sysctl_tcp_probe_threshold; + u32 sysctl_tcp_probe_interval; struct ping_group_range ping_group_range; diff --git a/include/net/tcp.h b/include/net/tcp.h index 1ad82e334e27..2e11e38205c2 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -67,6 +67,9 @@ void tcp_time_wait(struct sock *sk, int state, int timeo); /* The least MTU to use for probing */ #define TCP_BASE_MSS 1024 +/* probing interval, default to 10 minutes as per RFC4821 */ +#define TCP_PROBE_INTERVAL 600 + /* Specify interval when tcp mtu probing will stop */ #define TCP_PROBE_THRESHOLD 8 diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index d3c09c12ee81..fdf899163d44 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c @@ -890,6 +890,13 @@ static struct ctl_table ipv4_net_table[] = { .mode = 0644, .proc_handler = proc_dointvec, }, + { + .procname = "tcp_probe_interval", + .data = &init_net.ipv4.sysctl_tcp_probe_interval, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec, + }, { } }; diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 35790d977a2b..f0c6fc32bfa8 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -2461,6 +2461,7 @@ static int __net_init tcp_sk_init(struct net *net) net->ipv4.sysctl_tcp_ecn = 2; net->ipv4.sysctl_tcp_base_mss = TCP_BASE_MSS; net->ipv4.sysctl_tcp_probe_threshold = TCP_PROBE_THRESHOLD; + net->ipv4.sysctl_tcp_probe_interval = TCP_PROBE_INTERVAL; return 0; fail: diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index ed024cbb097f..5a73ad5afaf7 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -1354,6 +1354,8 @@ void tcp_mtup_init(struct sock *sk) icsk->icsk_af_ops->net_header_len; icsk->icsk_mtup.search_low = tcp_mss_to_mtu(sk, net->ipv4.sysctl_tcp_base_mss); icsk->icsk_mtup.probe_size = 0; + if (icsk->icsk_mtup.enabled) + icsk->icsk_mtup.probe_timestamp = tcp_time_stamp; } EXPORT_SYMBOL(tcp_mtup_init); @@ -1828,6 +1830,31 @@ send_now: return false; } +static inline void tcp_mtu_check_reprobe(struct sock *sk) +{ + struct inet_connection_sock *icsk = inet_csk(sk); + struct tcp_sock *tp = tcp_sk(sk); + struct net *net = sock_net(sk); + u32 interval; + s32 delta; + + interval = net->ipv4.sysctl_tcp_probe_interval; + delta = tcp_time_stamp - icsk->icsk_mtup.probe_timestamp; + if (unlikely(delta >= interval * HZ)) { + int mss = tcp_current_mss(sk); + + /* Update current search range */ + icsk->icsk_mtup.probe_size = 0; + icsk->icsk_mtup.search_high = tp->rx_opt.mss_clamp + + sizeof(struct tcphdr) + + icsk->icsk_af_ops->net_header_len; + icsk->icsk_mtup.search_low = tcp_mss_to_mtu(sk, mss); + + /* Update probe time stamp */ + icsk->icsk_mtup.probe_timestamp = tcp_time_stamp; + } +} + /* Create a new MTU probe if we are ready. * MTU probe is regularly attempting to increase the path MTU by * deliberately sending larger packets. This discovers routing @@ -1870,9 +1897,16 @@ static int tcp_mtu_probe(struct sock *sk) icsk->icsk_mtup.search_low) >> 1); size_needed = probe_size + (tp->reordering + 1) * tp->mss_cache; interval = icsk->icsk_mtup.search_high - icsk->icsk_mtup.search_low; + /* When misfortune happens, we are reprobing actively, + * and then reprobe timer has expired. We stick with current + * probing process by not resetting search range to its orignal. + */ if (probe_size > tcp_mtu_to_mss(sk, icsk->icsk_mtup.search_high) || - interval < max(1, net->ipv4.sysctl_tcp_probe_threshold)) { - /* TODO: set timer for probe_converge_event */ + interval < net->ipv4.sysctl_tcp_probe_threshold) { + /* Check whether enough time has elaplased for + * another round of probing. + */ + tcp_mtu_check_reprobe(sk); return -1; } diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index 0732b787904e..15505936511d 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c @@ -107,6 +107,7 @@ static void tcp_mtu_probing(struct inet_connection_sock *icsk, struct sock *sk) if (net->ipv4.sysctl_tcp_mtu_probing) { if (!icsk->icsk_mtup.enabled) { icsk->icsk_mtup.enabled = 1; + icsk->icsk_mtup.probe_timestamp = tcp_time_stamp; tcp_sync_mss(sk, icsk->icsk_pmtu_cookie); } else { struct net *net = sock_net(sk); -- GitLab From fab42760843734a82b6b2d1241ca44f375a686eb Mon Sep 17 00:00:00 2001 From: Fan Du Date: Fri, 6 Mar 2015 11:18:25 +0800 Subject: [PATCH 03059/11651] ipv4: Documenting two sysctls for tcp PMTU probe Namely tcp_probe_interval to control how often to restart a probe. And tcp_probe_threshold to control when stop the probing in respect to the width of search range in bytes Signed-off-by: Fan Du Signed-off-by: David S. Miller --- Documentation/networking/ip-sysctl.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index 1b8c964b0d17..4412f695a62f 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt @@ -388,6 +388,16 @@ tcp_mtu_probing - INTEGER 1 - Disabled by default, enabled when an ICMP black hole detected 2 - Always enabled, use initial MSS of tcp_base_mss. +tcp_probe_interval - INTEGER + Controls how often to start TCP Packetization-Layer Path MTU + Discovery reprobe. The default is reprobing every 10 minutes as + per RFC4821. + +tcp_probe_threshold - INTEGER + Controls when TCP Packetization-Layer Path MTU Discovery probing + will stop in respect to the width of search range in bytes. Default + is 8 bytes. + tcp_no_metrics_save - BOOLEAN By default, TCP saves various connection metrics in the route cache when the connection closes, so that connections established in the -- GitLab From 7e906e025d2ccf94f23b0cf8967a52134d6be6d1 Mon Sep 17 00:00:00 2001 From: Petri Gynther Date: Thu, 5 Mar 2015 17:40:10 -0800 Subject: [PATCH 03060/11651] net: bcmgenet: set hw_params->rx_queues = 0 bcmgenet driver doesn't yet support multiple Rx queues. Set hw_params->rx_queues = 0 accordingly. The default Rx queue (Q16) is still created and operational. Signed-off-by: Petri Gynther Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index 9137187063f7..f56553b9f915 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -2500,7 +2500,7 @@ static struct bcmgenet_hw_params bcmgenet_hw_params[] = { [GENET_V2] = { .tx_queues = 4, .tx_bds_per_q = 32, - .rx_queues = 4, + .rx_queues = 0, .bp_in_en_shift = 16, .bp_in_mask = 0xffff, .hfb_filter_cnt = 16, @@ -2516,7 +2516,7 @@ static struct bcmgenet_hw_params bcmgenet_hw_params[] = { [GENET_V3] = { .tx_queues = 4, .tx_bds_per_q = 32, - .rx_queues = 4, + .rx_queues = 0, .bp_in_en_shift = 17, .bp_in_mask = 0x1ffff, .hfb_filter_cnt = 48, @@ -2532,7 +2532,7 @@ static struct bcmgenet_hw_params bcmgenet_hw_params[] = { [GENET_V4] = { .tx_queues = 4, .tx_bds_per_q = 32, - .rx_queues = 4, + .rx_queues = 0, .bp_in_en_shift = 17, .bp_in_mask = 0x1ffff, .hfb_filter_cnt = 48, -- GitLab From 3feafeed16f92b96b7b67a3e30882c62c859f4bb Mon Sep 17 00:00:00 2001 From: Petri Gynther Date: Thu, 5 Mar 2015 17:40:12 -0800 Subject: [PATCH 03061/11651] net: bcmgenet: adjust the call to alloc_etherdev_mqs() In preparation for supporting multiple Rx queues, adjust the call to alloc_etherdev_mqs() to allow max GENET_MAX_MQ_CNT + 1 Rx queues. The actual number of Rx queues in use is correctly adjusted with: netif_set_real_num_rx_queues(priv->dev, priv->hw_params->rx_queues + 1); Signed-off-by: Petri Gynther Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index f56553b9f915..57271f7b2456 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -2668,8 +2668,9 @@ static int bcmgenet_probe(struct platform_device *pdev) struct resource *r; int err = -EIO; - /* Up to GENET_MAX_MQ_CNT + 1 TX queues and a single RX queue */ - dev = alloc_etherdev_mqs(sizeof(*priv), GENET_MAX_MQ_CNT + 1, 1); + /* Up to GENET_MAX_MQ_CNT + 1 TX queues and RX queues */ + dev = alloc_etherdev_mqs(sizeof(*priv), GENET_MAX_MQ_CNT + 1, + GENET_MAX_MQ_CNT + 1); if (!dev) { dev_err(&pdev->dev, "can't allocate net device\n"); return -ENOMEM; -- GitLab From 3feafa02156681a5a2a843680c7daeb93d22e280 Mon Sep 17 00:00:00 2001 From: Petri Gynther Date: Thu, 5 Mar 2015 17:40:14 -0800 Subject: [PATCH 03062/11651] net: bcmgenet: add GENET_Q16_RX_BD_CNT and hw_params->rx_bds_per_q In preparation for supporting multiple Rx queues, add GENET_Q16_RX_BD_CNT and hw_params->rx_bds_per_q. Signed-off-by: Petri Gynther Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 10 ++++++++-- drivers/net/ethernet/broadcom/genet/bcmgenet.h | 1 + 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index 57271f7b2456..d90785caab59 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -54,6 +54,8 @@ /* Default highest priority queue for multi queue support */ #define GENET_Q0_PRIORITY 0 +#define GENET_Q16_RX_BD_CNT \ + (TOTAL_DESC - priv->hw_params->rx_queues * priv->hw_params->rx_bds_per_q) #define GENET_Q16_TX_BD_CNT \ (TOTAL_DESC - priv->hw_params->tx_queues * priv->hw_params->tx_bds_per_q) @@ -2488,6 +2490,7 @@ static struct bcmgenet_hw_params bcmgenet_hw_params[] = { .tx_queues = 0, .tx_bds_per_q = 0, .rx_queues = 0, + .rx_bds_per_q = 0, .bp_in_en_shift = 16, .bp_in_mask = 0xffff, .hfb_filter_cnt = 16, @@ -2501,6 +2504,7 @@ static struct bcmgenet_hw_params bcmgenet_hw_params[] = { .tx_queues = 4, .tx_bds_per_q = 32, .rx_queues = 0, + .rx_bds_per_q = 0, .bp_in_en_shift = 16, .bp_in_mask = 0xffff, .hfb_filter_cnt = 16, @@ -2517,6 +2521,7 @@ static struct bcmgenet_hw_params bcmgenet_hw_params[] = { .tx_queues = 4, .tx_bds_per_q = 32, .rx_queues = 0, + .rx_bds_per_q = 0, .bp_in_en_shift = 17, .bp_in_mask = 0x1ffff, .hfb_filter_cnt = 48, @@ -2533,6 +2538,7 @@ static struct bcmgenet_hw_params bcmgenet_hw_params[] = { .tx_queues = 4, .tx_bds_per_q = 32, .rx_queues = 0, + .rx_bds_per_q = 0, .bp_in_en_shift = 17, .bp_in_mask = 0x1ffff, .hfb_filter_cnt = 48, @@ -2632,7 +2638,7 @@ static void bcmgenet_set_hw_params(struct bcmgenet_priv *priv) #endif pr_debug("Configuration for version: %d\n" - "TXq: %1d, TXqBDs: %1d, RXq: %1d\n" + "TXq: %1d, TXqBDs: %1d, RXq: %1d, RXqBDs: %1d\n" "BP << en: %2d, BP msk: 0x%05x\n" "HFB count: %2d, QTAQ msk: 0x%05x\n" "TBUF: 0x%04x, HFB: 0x%04x, HFBreg: 0x%04x\n" @@ -2640,7 +2646,7 @@ static void bcmgenet_set_hw_params(struct bcmgenet_priv *priv) "Words/BD: %d\n", priv->version, params->tx_queues, params->tx_bds_per_q, - params->rx_queues, + params->rx_queues, params->rx_bds_per_q, params->bp_in_en_shift, params->bp_in_mask, params->hfb_filter_cnt, params->qtag_mask, params->tbuf_offset, params->hfb_offset, diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.h b/drivers/net/ethernet/broadcom/genet/bcmgenet.h index 548b7e934727..5684e8529ecc 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h @@ -505,6 +505,7 @@ struct bcmgenet_hw_params { u8 tx_queues; u8 tx_bds_per_q; u8 rx_queues; + u8 rx_bds_per_q; u8 bp_in_en_shift; u32 bp_in_mask; u8 hfb_filter_cnt; -- GitLab From 5af76d5c0882435241841186b054262407e9eabb Mon Sep 17 00:00:00 2001 From: Jie Yang Date: Fri, 27 Feb 2015 12:52:26 +0800 Subject: [PATCH 03063/11651] ASoC: rt286: correct the OR to AND Here it should be AND(&) to check the status. Signed-off-by: Jie Yang Signed-off-by: Mark Brown --- sound/soc/codecs/rt286.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c index 16723b167fbf..49c44a77b518 100644 --- a/sound/soc/codecs/rt286.c +++ b/sound/soc/codecs/rt286.c @@ -397,7 +397,7 @@ int rt286_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack) if (jack) { /* enable IRQ */ - if (rt286->jack->status | SND_JACK_HEADPHONE) + if (rt286->jack->status & SND_JACK_HEADPHONE) snd_soc_dapm_force_enable_pin(&codec->dapm, "LDO1"); regmap_update_bits(rt286->regmap, RT286_IRQ_CTRL, 0x2, 0x2); /* Send an initial empty report */ -- GitLab From 1a5ab21c2e0f3d6b25ee9f7ca3429fac57027f76 Mon Sep 17 00:00:00 2001 From: Jie Yang Date: Fri, 27 Feb 2015 12:54:29 +0800 Subject: [PATCH 03064/11651] ASoC: Intel: Add suspend_pre and resume_post for Broadwell snd_soc_card For broadwell machine, we need do some machine related setting before suspend and after resume, e.g. disable/enable jack detection, here adding snd_soc_card suspend_pre and resume_post for this task. Signed-off-by: Jie Yang Signed-off-by: Mark Brown --- sound/soc/intel/broadwell.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/sound/soc/intel/broadwell.c b/sound/soc/intel/broadwell.c index fba2ef5dac42..af5d73070f60 100644 --- a/sound/soc/intel/broadwell.c +++ b/sound/soc/intel/broadwell.c @@ -225,6 +225,32 @@ static struct snd_soc_dai_link broadwell_rt286_dais[] = { }, }; +static int broadwell_suspend(struct snd_soc_card *card){ + struct snd_soc_codec *codec; + + list_for_each_entry(codec, &card->codec_dev_list, card_list) { + if (!strcmp(codec->component.name, "i2c-INT343A:00")) { + dev_dbg(codec->dev, "disabling jack detect before going to suspend.\n"); + rt286_mic_detect(codec, NULL); + break; + } + } + return 0; +} + +static int broadwell_resume(struct snd_soc_card *card){ + struct snd_soc_codec *codec; + + list_for_each_entry(codec, &card->codec_dev_list, card_list) { + if (!strcmp(codec->component.name, "i2c-INT343A:00")) { + dev_dbg(codec->dev, "enabling jack detect for resume.\n"); + rt286_mic_detect(codec, &broadwell_headset); + break; + } + } + return 0; +} + /* broadwell audio machine driver for WPT + RT286S */ static struct snd_soc_card broadwell_rt286 = { .name = "broadwell-rt286", @@ -238,6 +264,8 @@ static struct snd_soc_card broadwell_rt286 = { .dapm_routes = broadwell_rt286_map, .num_dapm_routes = ARRAY_SIZE(broadwell_rt286_map), .fully_routed = true, + .suspend_pre = broadwell_suspend, + .resume_post = broadwell_resume, }; static int broadwell_audio_probe(struct platform_device *pdev) -- GitLab From f8d54afc4c7a4c41deaa43fbcfffc2976094d342 Mon Sep 17 00:00:00 2001 From: Robert Shearman Date: Fri, 6 Mar 2015 10:47:00 +0000 Subject: [PATCH 03065/11651] mpls: Properly validate RTA_VIA payload length If the nla length is less than 2 then the nla data could be accessed beyond the accessible bounds. So ensure that the nla is big enough to at least read the via_family before doing so. Replace magic value of 2. Fixes: 03c0566542f4 ("mpls: Basic support for adding and removing routes") Cc: Eric W. Biederman Signed-off-by: Robert Shearman Acked-by: "Eric W. Biederman" Signed-off-by: David S. Miller --- net/mpls/af_mpls.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c index 20cf48a8593d..4f265c677eca 100644 --- a/net/mpls/af_mpls.c +++ b/net/mpls/af_mpls.c @@ -586,8 +586,11 @@ static int rtm_to_route_config(struct sk_buff *skb, struct nlmsghdr *nlh, case RTA_VIA: { struct rtvia *via = nla_data(nla); + if (nla_len(nla) < offsetof(struct rtvia, rtvia_addr)) + goto errout; cfg->rc_via_family = via->rtvia_family; - cfg->rc_via_alen = nla_len(nla) - 2; + cfg->rc_via_alen = nla_len(nla) - + offsetof(struct rtvia, rtvia_addr); if (cfg->rc_via_alen > MAX_VIA_ALEN) goto errout; -- GitLab From c7d910b87d3c8e9fcf4077089ca4327c12eee099 Mon Sep 17 00:00:00 2001 From: Eric Nelson Date: Fri, 27 Feb 2015 08:06:45 -0700 Subject: [PATCH 03066/11651] ASoC: sgtl5000: remove useless register write clearing CHRGPUMP_POWERUP The SGTL5000_CHIP_ANA_POWER register is cached. Update the cached value instead of writing it directly. Patch inspired by Russell King's more colorful remarks in this patch: https://github.com/SolidRun/linux-imx6-3.14/commit/dd4bf6a Signed-off-by: Eric Nelson Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- sound/soc/codecs/sgtl5000.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c index e182e6569bbd..3593a1496056 100644 --- a/sound/soc/codecs/sgtl5000.c +++ b/sound/soc/codecs/sgtl5000.c @@ -1151,13 +1151,7 @@ static int sgtl5000_set_power_regs(struct snd_soc_codec *codec) /* Enable VDDC charge pump */ ana_pwr |= SGTL5000_VDDC_CHRGPMP_POWERUP; } else if (vddio >= 3100 && vdda >= 3100) { - /* - * if vddio and vddd > 3.1v, - * charge pump should be clean before set ana_pwr - */ - snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER, - SGTL5000_VDDC_CHRGPMP_POWERUP, 0); - + ana_pwr &= ~SGTL5000_VDDC_CHRGPMP_POWERUP; /* VDDC use VDDIO rail */ lreg_ctrl |= SGTL5000_VDDC_ASSN_OVRD; lreg_ctrl |= SGTL5000_VDDC_MAN_ASSN_VDDIO << -- GitLab From 45746e82cf89f432f9c986a52137d8a64b78aba9 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 2 Mar 2015 14:58:55 +0200 Subject: [PATCH 03067/11651] spi: dw: make sure SPI controller is enabled The error handling is partially broken since the controller is disabled on error and is not re-enabled until condition occurs, i.e. mode (poll, PIO/DMA), chip (cs_change), or speed (clk_div) is changed. In the result of these changes we will have a predictable state of the SPi controller independently on how successfull was a previous transfer. The patch disables interrupts and re-enables the SPI controller wherever it needs to be done. Thus most of the time the SPI controller is kept enabled. The runtime PM, when it will be implemented, must take care of the controller disabling and re-enabling. Signed-off-by: Andy Shevchenko Signed-off-by: Mark Brown --- drivers/spi/spi-dw.c | 7 ++----- drivers/spi/spi-dw.h | 12 ++++++++++++ 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c index 281121f00138..321965607fc0 100644 --- a/drivers/spi/spi-dw.c +++ b/drivers/spi/spi-dw.c @@ -272,8 +272,7 @@ static void giveback(struct dw_spi *dws) static void int_error_stop(struct dw_spi *dws, const char *msg) { - /* Stop the hw */ - spi_enable_chip(dws, 0); + spi_reset_chip(dws); dev_err(&dws->master->dev, "%s\n", msg); dws->cur_msg->state = ERROR_STATE; @@ -606,9 +605,7 @@ static void dw_spi_cleanup(struct spi_device *spi) /* Restart the controller, disable all interrupts, clean rx fifo */ static void spi_hw_init(struct device *dev, struct dw_spi *dws) { - spi_enable_chip(dws, 0); - spi_mask_intr(dws, 0xff); - spi_enable_chip(dws, 1); + spi_reset_chip(dws); /* * Try to detect the FIFO depth if not set by interface driver, diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h index 3d32be68c142..1a7f083c2217 100644 --- a/drivers/spi/spi-dw.h +++ b/drivers/spi/spi-dw.h @@ -216,6 +216,18 @@ static inline void spi_umask_intr(struct dw_spi *dws, u32 mask) dw_writel(dws, DW_SPI_IMR, new_mask); } +/* + * This does disable the SPI controller, interrupts, and re-enable the + * controller back. Transmit and receive FIFO buffers are cleared when the + * device is disabled. + */ +static inline void spi_reset_chip(struct dw_spi *dws) +{ + spi_enable_chip(dws, 0); + spi_mask_intr(dws, 0xff); + spi_enable_chip(dws, 1); +} + /* * Each SPI slave device to work with dw_api controller should * has such a structure claiming its working mode (PIO/DMA etc), -- GitLab From 0b2e8915ead06b21d8f2360bfc28e747c4c0df8c Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 2 Mar 2015 14:58:56 +0200 Subject: [PATCH 03068/11651] spi: dw: program registers as soon as possible This patch refactors the code in pump_transfers() to reprogram the registers immediately when we have a new configuration data. The behaviour is slightly modified: - chip is always disabled and reenabled - CTRL0 is always reprogrammed This change allows to do a further refactoring and simplier conversion to use SPI core DMA routines in the future. Signed-off-by: Andy Shevchenko Signed-off-by: Mark Brown --- drivers/spi/spi-dw.c | 38 +++++++++++++++----------------------- 1 file changed, 15 insertions(+), 23 deletions(-) diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c index 321965607fc0..9a855bb00694 100644 --- a/drivers/spi/spi-dw.c +++ b/drivers/spi/spi-dw.c @@ -409,6 +409,8 @@ static void pump_transfers(unsigned long data) if (chip != dws->prev_chip) cs_change = 1; + spi_enable_chip(dws, 0); + cr0 = chip->cr0; /* Handle per transfer options for bpw and speed */ @@ -423,6 +425,8 @@ static void pump_transfers(unsigned long data) chip->speed_hz = speed; chip->clk_div = clk_div; + + spi_set_clk(dws, chip->clk_div); } } if (transfer->bits_per_word) { @@ -451,44 +455,32 @@ static void pump_transfers(unsigned long data) cr0 |= (chip->tmode << SPI_TMOD_OFFSET); } + dw_writew(dws, DW_SPI_CTRL0, cr0); + spi_chip_sel(dws, spi, 1); + /* Check if current transfer is a DMA transaction */ dws->dma_mapped = map_dma_buffers(dws); + /* For poll mode just disable all interrupts */ + spi_mask_intr(dws, 0xff); + /* * Interrupt mode * we only need set the TXEI IRQ, as TX/RX always happen syncronizely */ if (!dws->dma_mapped && !chip->poll_mode) { txlevel = min_t(u16, dws->fifo_len / 2, dws->len / dws->n_bytes); + dw_writew(dws, DW_SPI_TXFLTR, txlevel); + /* Set the interrupt mask */ imask |= SPI_INT_TXEI | SPI_INT_TXOI | SPI_INT_RXUI | SPI_INT_RXOI; + spi_umask_intr(dws, imask); + dws->transfer_handler = interrupt_transfer; } - /* - * Reprogram registers only if - * 1. chip select changes - * 2. clk_div is changed - * 3. control value changes - */ - if (dw_readw(dws, DW_SPI_CTRL0) != cr0 || cs_change || clk_div || imask) { - spi_enable_chip(dws, 0); - - dw_writew(dws, DW_SPI_CTRL0, cr0); - - spi_set_clk(dws, chip->clk_div); - spi_chip_sel(dws, spi, 1); - - /* Set the interrupt mask, for poll mode just disable all int */ - spi_mask_intr(dws, 0xff); - if (imask) - spi_umask_intr(dws, imask); - if (txlevel) - dw_writew(dws, DW_SPI_TXFLTR, txlevel); - - spi_enable_chip(dws, 1); - } + spi_enable_chip(dws, 1); if (cs_change) dws->prev_chip = chip; -- GitLab From c22c62db3f7388422257918c9d2582ef20d2e12d Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 2 Mar 2015 14:58:57 +0200 Subject: [PATCH 03069/11651] spi: dw: move to SPI core message handling This patch removes a lot of duplicate code since SPI core provides a nice message handling. Signed-off-by: Andy Shevchenko Signed-off-by: Mark Brown --- drivers/spi/spi-dw-mid.c | 4 +- drivers/spi/spi-dw.c | 183 ++++++++++----------------------------- drivers/spi/spi-dw.h | 26 ------ 3 files changed, 49 insertions(+), 164 deletions(-) diff --git a/drivers/spi/spi-dw-mid.c b/drivers/spi/spi-dw-mid.c index a0197fd4e95c..8f68e8277a3b 100644 --- a/drivers/spi/spi-dw-mid.c +++ b/drivers/spi/spi-dw-mid.c @@ -110,7 +110,7 @@ static void dw_spi_dma_tx_done(void *arg) if (test_and_clear_bit(TX_BUSY, &dws->dma_chan_busy) & BIT(RX_BUSY)) return; - dw_spi_xfer_done(dws); + spi_finalize_current_transfer(dws->master); } static struct dma_async_tx_descriptor *dw_spi_dma_prepare_tx(struct dw_spi *dws) @@ -155,7 +155,7 @@ static void dw_spi_dma_rx_done(void *arg) if (test_and_clear_bit(RX_BUSY, &dws->dma_chan_busy) & BIT(TX_BUSY)) return; - dw_spi_xfer_done(dws); + spi_finalize_current_transfer(dws->master); } static struct dma_async_tx_descriptor *dw_spi_dma_prepare_rx(struct dw_spi *dws) diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c index 9a855bb00694..7d3ee82e10be 100644 --- a/drivers/spi/spi-dw.c +++ b/drivers/spi/spi-dw.c @@ -28,11 +28,6 @@ #include #endif -#define START_STATE ((void *)0) -#define RUNNING_STATE ((void *)1) -#define DONE_STATE ((void *)2) -#define ERROR_STATE ((void *)-1) - /* Slave spi_dev related */ struct chip_data { u16 cr0; @@ -143,6 +138,19 @@ static inline void dw_spi_debugfs_remove(struct dw_spi *dws) } #endif /* CONFIG_DEBUG_FS */ +static void dw_spi_set_cs(struct spi_device *spi, bool enable) +{ + struct dw_spi *dws = spi_master_get_devdata(spi->master); + struct chip_data *chip = spi_get_ctldata(spi); + + /* Chip select logic is inverted from spi_set_cs() */ + if (chip->cs_control) + chip->cs_control(!enable); + + if (!enable) + dw_writel(dws, DW_SPI_SER, BIT(spi->chip_select)); +} + /* Return the max entries we can fill into tx fifo */ static inline u32 tx_max(struct dw_spi *dws) { @@ -209,93 +217,41 @@ static void dw_reader(struct dw_spi *dws) } } -static void *next_transfer(struct dw_spi *dws) -{ - struct spi_message *msg = dws->cur_msg; - struct spi_transfer *trans = dws->cur_transfer; - - /* Move to next transfer */ - if (trans->transfer_list.next != &msg->transfers) { - dws->cur_transfer = - list_entry(trans->transfer_list.next, - struct spi_transfer, - transfer_list); - return RUNNING_STATE; - } - - return DONE_STATE; -} - /* * Note: first step is the protocol driver prepares * a dma-capable memory, and this func just need translate * the virt addr to physical */ -static int map_dma_buffers(struct dw_spi *dws) +static int map_dma_buffers(struct spi_master *master, + struct spi_device *spi, struct spi_transfer *transfer) { - if (!dws->cur_msg->is_dma_mapped + struct dw_spi *dws = spi_master_get_devdata(master); + struct chip_data *chip = spi_get_ctldata(spi); + + if (!master->cur_msg->is_dma_mapped || !dws->dma_inited - || !dws->cur_chip->enable_dma + || !chip->enable_dma || !dws->dma_ops) return 0; - if (dws->cur_transfer->tx_dma) - dws->tx_dma = dws->cur_transfer->tx_dma; + if (transfer->tx_dma) + dws->tx_dma = transfer->tx_dma; - if (dws->cur_transfer->rx_dma) - dws->rx_dma = dws->cur_transfer->rx_dma; + if (transfer->rx_dma) + dws->rx_dma = transfer->rx_dma; return 1; } -/* Caller already set message->status; dma and pio irqs are blocked */ -static void giveback(struct dw_spi *dws) -{ - struct spi_transfer *last_transfer; - struct spi_message *msg; - - msg = dws->cur_msg; - dws->cur_msg = NULL; - dws->cur_transfer = NULL; - dws->prev_chip = dws->cur_chip; - dws->cur_chip = NULL; - dws->dma_mapped = 0; - - last_transfer = list_last_entry(&msg->transfers, struct spi_transfer, - transfer_list); - - if (!last_transfer->cs_change) - spi_chip_sel(dws, msg->spi, 0); - - spi_finalize_current_message(dws->master); -} - static void int_error_stop(struct dw_spi *dws, const char *msg) { spi_reset_chip(dws); dev_err(&dws->master->dev, "%s\n", msg); - dws->cur_msg->state = ERROR_STATE; - tasklet_schedule(&dws->pump_transfers); + dws->master->cur_msg->status = -EIO; + spi_finalize_current_transfer(dws->master); } -void dw_spi_xfer_done(struct dw_spi *dws) -{ - /* Update total byte transferred return count actual bytes read */ - dws->cur_msg->actual_length += dws->len; - - /* Move to next transfer */ - dws->cur_msg->state = next_transfer(dws); - - /* Handle end of message */ - if (dws->cur_msg->state == DONE_STATE) { - dws->cur_msg->status = 0; - giveback(dws); - } else - tasklet_schedule(&dws->pump_transfers); -} -EXPORT_SYMBOL_GPL(dw_spi_xfer_done); - static irqreturn_t interrupt_transfer(struct dw_spi *dws) { u16 irq_status = dw_readw(dws, DW_SPI_ISR); @@ -312,7 +268,7 @@ static irqreturn_t interrupt_transfer(struct dw_spi *dws) dw_reader(dws); if (dws->rx_end == dws->rx) { spi_mask_intr(dws, SPI_INT_TXEI); - dw_spi_xfer_done(dws); + spi_finalize_current_transfer(dws->master); return IRQ_HANDLED; } if (irq_status & SPI_INT_TXEI) { @@ -327,13 +283,14 @@ static irqreturn_t interrupt_transfer(struct dw_spi *dws) static irqreturn_t dw_spi_irq(int irq, void *dev_id) { - struct dw_spi *dws = dev_id; + struct spi_master *master = dev_id; + struct dw_spi *dws = spi_master_get_devdata(master); u16 irq_status = dw_readw(dws, DW_SPI_ISR) & 0x3f; if (!irq_status) return IRQ_NONE; - if (!dws->cur_msg) { + if (!master->cur_msg) { spi_mask_intr(dws, SPI_INT_TXEI); return IRQ_HANDLED; } @@ -342,7 +299,7 @@ static irqreturn_t dw_spi_irq(int irq, void *dev_id) } /* Must be called inside pump_transfers() */ -static void poll_transfer(struct dw_spi *dws) +static int poll_transfer(struct dw_spi *dws) { do { dw_writer(dws); @@ -350,17 +307,14 @@ static void poll_transfer(struct dw_spi *dws) cpu_relax(); } while (dws->rx_end > dws->rx); - dw_spi_xfer_done(dws); + return 0; } -static void pump_transfers(unsigned long data) +static int dw_spi_transfer_one(struct spi_master *master, + struct spi_device *spi, struct spi_transfer *transfer) { - struct dw_spi *dws = (struct dw_spi *)data; - struct spi_message *message = NULL; - struct spi_transfer *transfer = NULL; - struct spi_transfer *previous = NULL; - struct spi_device *spi = NULL; - struct chip_data *chip = NULL; + struct dw_spi *dws = spi_master_get_devdata(master); + struct chip_data *chip = spi_get_ctldata(spi); u8 bits = 0; u8 imask = 0; u8 cs_change = 0; @@ -369,35 +323,8 @@ static void pump_transfers(unsigned long data) u32 speed = 0; u32 cr0 = 0; - /* Get current state information */ - message = dws->cur_msg; - transfer = dws->cur_transfer; - chip = dws->cur_chip; - spi = message->spi; - - if (message->state == ERROR_STATE) { - message->status = -EIO; - goto early_exit; - } - - /* Handle end of message */ - if (message->state == DONE_STATE) { - message->status = 0; - goto early_exit; - } - - /* Delay if requested at end of transfer */ - if (message->state == RUNNING_STATE) { - previous = list_entry(transfer->transfer_list.prev, - struct spi_transfer, - transfer_list); - if (previous->delay_usecs) - udelay(previous->delay_usecs); - } - dws->n_bytes = chip->n_bytes; dws->dma_width = chip->dma_width; - dws->cs_control = chip->cs_control; dws->rx_dma = transfer->rx_dma; dws->tx_dma = transfer->tx_dma; @@ -405,7 +332,7 @@ static void pump_transfers(unsigned long data) dws->tx_end = dws->tx + transfer->len; dws->rx = transfer->rx_buf; dws->rx_end = dws->rx + transfer->len; - dws->len = dws->cur_transfer->len; + dws->len = transfer->len; if (chip != dws->prev_chip) cs_change = 1; @@ -437,13 +364,12 @@ static void pump_transfers(unsigned long data) | (spi->mode << SPI_MODE_OFFSET) | (chip->tmode << SPI_TMOD_OFFSET); } - message->state = RUNNING_STATE; /* * Adjust transfer mode if necessary. Requires platform dependent * chipselect mechanism. */ - if (dws->cs_control) { + if (chip->cs_control) { if (dws->rx && dws->tx) chip->tmode = SPI_TMOD_TR; else if (dws->rx) @@ -456,10 +382,9 @@ static void pump_transfers(unsigned long data) } dw_writew(dws, DW_SPI_CTRL0, cr0); - spi_chip_sel(dws, spi, 1); /* Check if current transfer is a DMA transaction */ - dws->dma_mapped = map_dma_buffers(dws); + dws->dma_mapped = map_dma_buffers(master, spi, transfer); /* For poll mode just disable all interrupts */ spi_mask_intr(dws, 0xff); @@ -489,31 +414,17 @@ static void pump_transfers(unsigned long data) dws->dma_ops->dma_transfer(dws, cs_change); if (chip->poll_mode) - poll_transfer(dws); + return poll_transfer(dws); - return; - -early_exit: - giveback(dws); + return 1; } -static int dw_spi_transfer_one_message(struct spi_master *master, +static void dw_spi_handle_err(struct spi_master *master, struct spi_message *msg) { struct dw_spi *dws = spi_master_get_devdata(master); - dws->cur_msg = msg; - /* Initial message state */ - dws->cur_msg->state = START_STATE; - dws->cur_transfer = list_entry(dws->cur_msg->transfers.next, - struct spi_transfer, - transfer_list); - dws->cur_chip = spi_get_ctldata(dws->cur_msg->spi); - - /* Launch transfers */ - tasklet_schedule(&dws->pump_transfers); - - return 0; + spi_reset_chip(dws); } /* This may be called twice for each spi dev */ @@ -637,7 +548,7 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws) snprintf(dws->name, sizeof(dws->name), "dw_spi%d", dws->bus_num); ret = devm_request_irq(dev, dws->irq, dw_spi_irq, IRQF_SHARED, - dws->name, dws); + dws->name, master); if (ret < 0) { dev_err(&master->dev, "can not get IRQ\n"); goto err_free_master; @@ -649,7 +560,9 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws) master->num_chipselect = dws->num_cs; master->setup = dw_spi_setup; master->cleanup = dw_spi_cleanup; - master->transfer_one_message = dw_spi_transfer_one_message; + master->set_cs = dw_spi_set_cs; + master->transfer_one = dw_spi_transfer_one; + master->handle_err = dw_spi_handle_err; master->max_speed_hz = dws->max_freq; master->dev.of_node = dev->of_node; @@ -664,8 +577,6 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws) } } - tasklet_init(&dws->pump_transfers, pump_transfers, (unsigned long)dws); - spi_master_set_devdata(master, dws); ret = devm_spi_register_master(dev, master); if (ret) { diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h index 1a7f083c2217..855bfdd7b433 100644 --- a/drivers/spi/spi-dw.h +++ b/drivers/spi/spi-dw.h @@ -96,7 +96,6 @@ struct dw_spi_dma_ops { struct dw_spi { struct spi_master *master; - struct spi_device *cur_dev; enum dw_ssi_type type; char name[16]; @@ -109,13 +108,7 @@ struct dw_spi { u16 bus_num; u16 num_cs; /* supported slave numbers */ - /* Message Transfer pump */ - struct tasklet_struct pump_transfers; - /* Current message transfer state info */ - struct spi_message *cur_msg; - struct spi_transfer *cur_transfer; - struct chip_data *cur_chip; struct chip_data *prev_chip; size_t len; void *tx; @@ -128,10 +121,8 @@ struct dw_spi { size_t rx_map_len; size_t tx_map_len; u8 n_bytes; /* current is a 1/2 bytes op */ - u8 max_bits_per_word; /* maxim is 16b */ u32 dma_width; irqreturn_t (*transfer_handler)(struct dw_spi *dws); - void (*cs_control)(u32 command); /* Dma info */ int dma_inited; @@ -182,22 +173,6 @@ static inline void spi_set_clk(struct dw_spi *dws, u16 div) dw_writel(dws, DW_SPI_BAUDR, div); } -static inline void spi_chip_sel(struct dw_spi *dws, struct spi_device *spi, - int active) -{ - u16 cs = spi->chip_select; - int gpio_val = active ? (spi->mode & SPI_CS_HIGH) : - !(spi->mode & SPI_CS_HIGH); - - if (dws->cs_control) - dws->cs_control(active); - if (gpio_is_valid(spi->cs_gpio)) - gpio_set_value(spi->cs_gpio, gpio_val); - - if (active) - dw_writel(dws, DW_SPI_SER, 1 << cs); -} - /* Disable IRQ bits */ static inline void spi_mask_intr(struct dw_spi *dws, u32 mask) { @@ -245,7 +220,6 @@ extern int dw_spi_add_host(struct device *dev, struct dw_spi *dws); extern void dw_spi_remove_host(struct dw_spi *dws); extern int dw_spi_suspend_host(struct dw_spi *dws); extern int dw_spi_resume_host(struct dw_spi *dws); -extern void dw_spi_xfer_done(struct dw_spi *dws); /* platform related setup */ extern int dw_spi_mid_init(struct dw_spi *dws); /* Intel MID platforms */ -- GitLab From a4ee556137a5bb4b542c5023e6fead4b7cf33495 Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Fri, 6 Mar 2015 10:12:58 +0800 Subject: [PATCH 03070/11651] ASoC: rt286: Change the DMI mapping for Dino The board ID will be changed between revisions. So, it is better to map it by project name. Signed-off-by: Bard Liao Signed-off-by: Mark Brown --- sound/soc/codecs/rt286.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c index f374840a5a7c..9b541e52da8c 100644 --- a/sound/soc/codecs/rt286.c +++ b/sound/soc/codecs/rt286.c @@ -1198,7 +1198,7 @@ static struct dmi_system_id dmi_dell_dino[] = { .ident = "Dell Dino", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_BOARD_NAME, "0144P8") + DMI_MATCH(DMI_PRODUCT_NAME, "XPS 13 9343") } }, { } -- GitLab From 89650ad0047f039b3c3bc0f6a5823bb9c9738152 Mon Sep 17 00:00:00 2001 From: Willem de Bruijn Date: Fri, 6 Mar 2015 11:44:28 -0500 Subject: [PATCH 03071/11651] fib: make netdev_switch_fib_ipv4_abort in header file static inline When building without CONFIG_NET_SWITCHDEV, netdev_switch_fib_ipv4_abort is defined in the header file. It must be static inline to avoid build failure at link time. Fixes: 8e05fd7166c6 ("fib: hook IPv4 fib for hardware offload") Signed-off-by: Willem de Bruijn Acked-by: Scott Feldman Signed-off-by: David S. Miller --- include/net/switchdev.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/net/switchdev.h b/include/net/switchdev.h index dc0a5cc7c2c5..933fac410a7a 100644 --- a/include/net/switchdev.h +++ b/include/net/switchdev.h @@ -129,7 +129,7 @@ static inline int netdev_switch_fib_ipv4_del(u32 dst, int dst_len, return 0; } -void netdev_switch_fib_ipv4_abort(struct fib_info *fi) +static inline void netdev_switch_fib_ipv4_abort(struct fib_info *fi) { } -- GitLab From 8a013a9c71b21a9860f44dec7600c8fe77995a77 Mon Sep 17 00:00:00 2001 From: Punnaiah Choudary Kalluri Date: Fri, 6 Mar 2015 18:29:11 +0100 Subject: [PATCH 03072/11651] net: macb: Include multi queue support for xilinx ZynqMP ethernet version Include multi queue support for the ethernet IP version in xilinx ZynqMP SoC. Signed-off-by: Punnaiah Choudary Kalluri Signed-off-by: Michal Simek Acked-by: Nicolas Ferre Signed-off-by: David S. Miller --- drivers/net/ethernet/cadence/macb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c index 1fe8b946243a..0436aefa49e4 100644 --- a/drivers/net/ethernet/cadence/macb.c +++ b/drivers/net/ethernet/cadence/macb.c @@ -2211,7 +2211,7 @@ static void macb_probe_queues(void __iomem *mem, /* is it macb or gem ? */ mid = readl_relaxed(mem + MACB_MID); - if (MACB_BFEXT(IDNUM, mid) != 0x2) + if (MACB_BFEXT(IDNUM, mid) < 0x2) return; /* bit 0 is never set but queue 0 always exists */ -- GitLab From 20488239d236f1615e2be8b0f6dbd30e4310940a Mon Sep 17 00:00:00 2001 From: Punnaiah Choudary Kalluri Date: Fri, 6 Mar 2015 18:29:12 +0100 Subject: [PATCH 03073/11651] net: macb: Fix multi queue support for xilinx ZynqMP ZynqMP soc has single interrupt for all the queue events. So, passing the IRQF_SHARED flag for interrupt registration call. Signed-off-by: Punnaiah Choudary Kalluri Signed-off-by: Michal Simek Acked-by: Nicolas Ferre Signed-off-by: David S. Miller --- drivers/net/ethernet/cadence/macb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c index 0436aefa49e4..f6c8935a4f0b 100644 --- a/drivers/net/ethernet/cadence/macb.c +++ b/drivers/net/ethernet/cadence/macb.c @@ -2339,7 +2339,7 @@ static int macb_probe(struct platform_device *pdev) */ queue->irq = platform_get_irq(pdev, q); err = devm_request_irq(&pdev->dev, queue->irq, macb_interrupt, - 0, dev->name, queue); + IRQF_SHARED, dev->name, queue); if (err) { dev_err(&pdev->dev, "Unable to request IRQ %d (error %d)\n", -- GitLab From 72be72607a560dfa7a4715cb372f9e1e40ed65a5 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Fri, 6 Mar 2015 09:53:56 -0800 Subject: [PATCH 03074/11651] fib_trie: Minor cleanups to fib_table_flush_external This change just does a couple of minor cleanups on fib_table_flush_external. Specifically it addresses the fact that resize was being called even though nothing was being removed from the table, and it drops an unecessary indent since we could just call continue on the inverse of the fi && flag check. Signed-off-by: Alexander Duyck Signed-off-by: David S. Miller --- net/ipv4/fib_trie.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 0131f369f5c9..488cebc86631 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -1586,13 +1586,8 @@ backtrace: while (!(cindex--)) { t_key pkey = pn->key; - n = pn; - pn = node_parent(n); - - /* resize completed node */ - resize(t, n); - /* if we got the root we are done */ + pn = node_parent(pn); if (!pn) return; @@ -1607,12 +1602,13 @@ backtrace: hlist_for_each_entry(fa, &n->leaf, fa_list) { struct fib_info *fi = fa->fa_info; - if (fi && (fi->fib_flags & RTNH_F_EXTERNAL)) { - netdev_switch_fib_ipv4_del(n->key, - KEYLENGTH - fa->fa_slen, - fi, fa->fa_tos, - fa->fa_type, tb->tb_id); - } + if (!fi || !(fi->fib_flags & RTNH_F_EXTERNAL)) + continue; + + netdev_switch_fib_ipv4_del(n->key, + KEYLENGTH - fa->fa_slen, + fi, fa->fa_tos, + fa->fa_type, tb->tb_id); } /* if trie is leaf only loop is completed */ -- GitLab From 8d8e810ca8ec2541f30af916f0de1b41ac86ec4a Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Fri, 6 Mar 2015 09:54:02 -0800 Subject: [PATCH 03075/11651] fib_trie: Return pointer to tnode pointer in resize/inflate/halve Resize related functions now all return a pointer to the pointer that references the object that was resized. Signed-off-by: Alexander Duyck Signed-off-by: David S. Miller --- net/ipv4/fib_trie.c | 106 +++++++++++++++++++++++++++----------------- 1 file changed, 65 insertions(+), 41 deletions(-) diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 488cebc86631..752520747056 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -144,7 +144,7 @@ struct trie { #endif }; -static void resize(struct trie *t, struct tnode *tn); +static struct tnode **resize(struct trie *t, struct tnode *tn); static size_t tnode_free_size; /* @@ -468,9 +468,11 @@ static void tnode_free(struct tnode *tn) } } -static void replace(struct trie *t, struct tnode *oldtnode, struct tnode *tn) +static struct tnode __rcu **replace(struct trie *t, struct tnode *oldtnode, + struct tnode *tn) { struct tnode *tp = node_parent(oldtnode); + struct tnode **cptr; unsigned long i; /* setup the parent pointer out of and back into this node */ @@ -483,6 +485,9 @@ static void replace(struct trie *t, struct tnode *oldtnode, struct tnode *tn) /* all pointers should be clean so we are done */ tnode_free(oldtnode); + /* record the pointer that is pointing to this node */ + cptr = tp ? tp->tnode : &t->trie; + /* resize children now that oldtnode is freed */ for (i = tnode_child_length(tn); i;) { struct tnode *inode = tnode_get_child(tn, --i); @@ -491,9 +496,11 @@ static void replace(struct trie *t, struct tnode *oldtnode, struct tnode *tn) if (tnode_full(tn, inode)) resize(t, inode); } + + return cptr; } -static int inflate(struct trie *t, struct tnode *oldtnode) +static struct tnode __rcu **inflate(struct trie *t, struct tnode *oldtnode) { struct tnode *tn; unsigned long i; @@ -503,7 +510,7 @@ static int inflate(struct trie *t, struct tnode *oldtnode) tn = tnode_new(oldtnode->key, oldtnode->pos - 1, oldtnode->bits + 1); if (!tn) - return -ENOMEM; + goto notnode; /* prepare oldtnode to be freed */ tnode_free_init(oldtnode); @@ -580,16 +587,15 @@ static int inflate(struct trie *t, struct tnode *oldtnode) } /* setup the parent pointers into and out of this node */ - replace(t, oldtnode, tn); - - return 0; + return replace(t, oldtnode, tn); nomem: /* all pointers should be clean so we are done */ tnode_free(tn); - return -ENOMEM; +notnode: + return NULL; } -static int halve(struct trie *t, struct tnode *oldtnode) +static struct tnode __rcu **halve(struct trie *t, struct tnode *oldtnode) { struct tnode *tn; unsigned long i; @@ -598,7 +604,7 @@ static int halve(struct trie *t, struct tnode *oldtnode) tn = tnode_new(oldtnode->key, oldtnode->pos + 1, oldtnode->bits - 1); if (!tn) - return -ENOMEM; + goto notnode; /* prepare oldtnode to be freed */ tnode_free_init(oldtnode); @@ -621,10 +627,8 @@ static int halve(struct trie *t, struct tnode *oldtnode) /* Two nonempty children */ inode = tnode_new(node0->key, oldtnode->pos, 1); - if (!inode) { - tnode_free(tn); - return -ENOMEM; - } + if (!inode) + goto nomem; tnode_free_append(tn, inode); /* initialize pointers out of node */ @@ -637,9 +641,12 @@ static int halve(struct trie *t, struct tnode *oldtnode) } /* setup the parent pointers into and out of this node */ - replace(t, oldtnode, tn); - - return 0; + return replace(t, oldtnode, tn); +nomem: + /* all pointers should be clean so we are done */ + tnode_free(tn); +notnode: + return NULL; } static void collapse(struct trie *t, struct tnode *oldtnode) @@ -796,10 +803,14 @@ static bool should_collapse(const struct tnode *tn) } #define MAX_WORK 10 -static void resize(struct trie *t, struct tnode *tn) +static struct tnode __rcu **resize(struct trie *t, struct tnode *tn) { +#ifdef CONFIG_IP_FIB_TRIE_STATS + struct trie_use_stats __percpu *stats = t->stats; +#endif struct tnode *tp = node_parent(tn); - struct tnode __rcu **cptr; + unsigned long cindex = tp ? get_index(tn->key, tp) : 0; + struct tnode __rcu **cptr = tp ? tp->tnode : &t->trie; int max_work = MAX_WORK; pr_debug("In tnode_resize %p inflate_threshold=%d threshold=%d\n", @@ -809,52 +820,57 @@ static void resize(struct trie *t, struct tnode *tn) * doing it ourselves. This way we can let RCU fully do its * thing without us interfering */ - cptr = tp ? &tp->tnode[get_index(tn->key, tp)] : &t->trie; - BUG_ON(tn != rtnl_dereference(*cptr)); + BUG_ON(tn != rtnl_dereference(cptr[cindex])); /* Double as long as the resulting node has a number of * nonempty nodes that are above the threshold. */ while (should_inflate(tp, tn) && max_work) { - if (inflate(t, tn)) { + struct tnode __rcu **tcptr = inflate(t, tn); + + if (!tcptr) { #ifdef CONFIG_IP_FIB_TRIE_STATS - this_cpu_inc(t->stats->resize_node_skipped); + this_cpu_inc(stats->resize_node_skipped); #endif break; } max_work--; - tn = rtnl_dereference(*cptr); + cptr = tcptr; + tn = rtnl_dereference(cptr[cindex]); } /* Return if at least one inflate is run */ if (max_work != MAX_WORK) - return; + return cptr; /* Halve as long as the number of empty children in this * node is above threshold. */ while (should_halve(tp, tn) && max_work) { - if (halve(t, tn)) { + struct tnode __rcu **tcptr = halve(t, tn); + + if (!tcptr) { #ifdef CONFIG_IP_FIB_TRIE_STATS - this_cpu_inc(t->stats->resize_node_skipped); + this_cpu_inc(stats->resize_node_skipped); #endif break; } max_work--; - tn = rtnl_dereference(*cptr); + cptr = tcptr; + tn = rtnl_dereference(cptr[cindex]); } /* Only one child remains */ if (should_collapse(tn)) { collapse(t, tn); - return; + return cptr; } /* Return if at least one deflate was run */ if (max_work != MAX_WORK) - return; + return cptr; /* push the suffix length to the parent node */ if (tn->slen > tn->pos) { @@ -863,6 +879,8 @@ static void resize(struct trie *t, struct tnode *tn) if (tp && (slen > tp->slen)) tp->slen = slen; } + + return cptr; } static void leaf_pull_suffix(struct tnode *tp, struct tnode *l) @@ -952,16 +970,18 @@ static struct fib_alias *fib_find_alias(struct hlist_head *fah, u8 slen, static void trie_rebalance(struct trie *t, struct tnode *tn) { - struct tnode *tp; + struct tnode __rcu **cptr = &t->trie; while (tn) { - tp = node_parent(tn); - resize(t, tn); - tn = tp; + struct tnode *tp = node_parent(tn); + + cptr = resize(t, tn); + if (!tp) + break; + tn = container_of(cptr, struct tnode, tnode[0]); } } -/* only used from updater-side */ static int fib_insert_node(struct trie *t, struct tnode *tp, struct fib_alias *new, t_key key) { @@ -969,7 +989,7 @@ static int fib_insert_node(struct trie *t, struct tnode *tp, l = leaf_new(key, new); if (!l) - return -ENOMEM; + goto noleaf; /* retrieve child from parent node */ if (tp) @@ -987,10 +1007,8 @@ static int fib_insert_node(struct trie *t, struct tnode *tp, struct tnode *tn; tn = tnode_new(key, __fls(key ^ n->key), 1); - if (!tn) { - node_free(l); - return -ENOMEM; - } + if (!tn) + goto notnode; /* initialize routes out of node */ NODE_INIT_PARENT(tn, tp); @@ -1010,6 +1028,10 @@ static int fib_insert_node(struct trie *t, struct tnode *tp, trie_rebalance(t, tp); return 0; +notnode: + node_free(l); +noleaf: + return -ENOMEM; } static int fib_insert_alias(struct trie *t, struct tnode *tp, @@ -1642,18 +1664,20 @@ backtrace: /* walk trie in reverse order */ do { while (!(cindex--)) { + struct tnode __rcu **cptr; t_key pkey = pn->key; n = pn; pn = node_parent(n); /* resize completed node */ - resize(t, n); + cptr = resize(t, n); /* if we got the root we are done */ if (!pn) goto flush_complete; + pn = container_of(cptr, struct tnode, tnode[0]); cindex = get_index(pkey, pn); } -- GitLab From 35c6edac197fcfb53cea9993d9b64386b15abf48 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Fri, 6 Mar 2015 09:54:08 -0800 Subject: [PATCH 03076/11651] fib_trie: Rename tnode to key_vector Rename the tnode to key_vector. The key_vector will be the eventual container for all of the information needed by either a leaf or a tnode. The final result should be much smaller than the 40 bytes currently needed for either one. This also updates the trie struct so that it contains an array of size 1 of tnode pointers. This is to bring the structure more inline with how an actual tnode itself is configured. Signed-off-by: Alexander Duyck Signed-off-by: David S. Miller --- net/ipv4/fib_trie.c | 247 +++++++++++++++++++++++--------------------- 1 file changed, 128 insertions(+), 119 deletions(-) diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 752520747056..8b21fc3da43e 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -94,12 +94,12 @@ typedef unsigned int t_key; #define get_index(_key, _kv) (((_key) ^ (_kv)->key) >> (_kv)->pos) -struct tnode { +struct key_vector { struct rcu_head rcu; t_key empty_children; /* KEYLENGTH bits needed */ t_key full_children; /* KEYLENGTH bits needed */ - struct tnode __rcu *parent; + struct key_vector __rcu *parent; t_key key; unsigned char pos; /* 2log(KEYLENGTH) bits needed */ @@ -109,11 +109,11 @@ struct tnode { /* This list pointer if valid if (pos | bits) == 0 (LEAF) */ struct hlist_head leaf; /* This array is valid if (pos | bits) > 0 (TNODE) */ - struct tnode __rcu *tnode[0]; + struct key_vector __rcu *tnode[0]; }; }; -#define TNODE_SIZE(n) offsetof(struct tnode, tnode[n]) +#define TNODE_SIZE(n) offsetof(struct key_vector, tnode[n]) #define LEAF_SIZE TNODE_SIZE(1) #ifdef CONFIG_IP_FIB_TRIE_STATS @@ -138,13 +138,13 @@ struct trie_stat { }; struct trie { - struct tnode __rcu *trie; + struct key_vector __rcu *tnode[1]; #ifdef CONFIG_IP_FIB_TRIE_STATS struct trie_use_stats __percpu *stats; #endif }; -static struct tnode **resize(struct trie *t, struct tnode *tn); +static struct key_vector **resize(struct trie *t, struct key_vector *tn); static size_t tnode_free_size; /* @@ -164,7 +164,7 @@ static struct kmem_cache *trie_leaf_kmem __read_mostly; #define node_parent_rcu(n) rcu_dereference_rtnl((n)->parent) /* wrapper for rcu_assign_pointer */ -static inline void node_set_parent(struct tnode *n, struct tnode *tp) +static inline void node_set_parent(struct key_vector *n, struct key_vector *tp) { if (n) rcu_assign_pointer(n->parent, tp); @@ -175,21 +175,21 @@ static inline void node_set_parent(struct tnode *n, struct tnode *tp) /* This provides us with the number of children in this node, in the case of a * leaf this will return 0 meaning none of the children are accessible. */ -static inline unsigned long tnode_child_length(const struct tnode *tn) +static inline unsigned long tnode_child_length(const struct key_vector *tn) { return (1ul << tn->bits) & ~(1ul); } /* caller must hold RTNL */ -static inline struct tnode *tnode_get_child(const struct tnode *tn, - unsigned long i) +static inline struct key_vector *tnode_get_child(struct key_vector *tn, + unsigned long i) { return rtnl_dereference(tn->tnode[i]); } /* caller must hold RCU read lock or RTNL */ -static inline struct tnode *tnode_get_child_rcu(const struct tnode *tn, - unsigned long i) +static inline struct key_vector *tnode_get_child_rcu(struct key_vector *tn, + unsigned long i) { return rcu_dereference_rtnl(tn->tnode[i]); } @@ -277,13 +277,13 @@ static inline void alias_free_mem_rcu(struct fib_alias *fa) } #define TNODE_KMALLOC_MAX \ - ilog2((PAGE_SIZE - TNODE_SIZE(0)) / sizeof(struct tnode *)) + ilog2((PAGE_SIZE - TNODE_SIZE(0)) / sizeof(struct key_vector *)) #define TNODE_VMALLOC_MAX \ - ilog2((SIZE_MAX - TNODE_SIZE(0)) / sizeof(struct tnode *)) + ilog2((SIZE_MAX - TNODE_SIZE(0)) / sizeof(struct key_vector *)) static void __node_free_rcu(struct rcu_head *head) { - struct tnode *n = container_of(head, struct tnode, rcu); + struct key_vector *n = container_of(head, struct key_vector, rcu); if (IS_LEAF(n)) kmem_cache_free(trie_leaf_kmem, n); @@ -295,7 +295,7 @@ static void __node_free_rcu(struct rcu_head *head) #define node_free(n) call_rcu(&n->rcu, __node_free_rcu) -static struct tnode *tnode_alloc(int bits) +static struct key_vector *tnode_alloc(int bits) { size_t size; @@ -312,19 +312,19 @@ static struct tnode *tnode_alloc(int bits) return vzalloc(size); } -static inline void empty_child_inc(struct tnode *n) +static inline void empty_child_inc(struct key_vector *n) { ++n->empty_children ? : ++n->full_children; } -static inline void empty_child_dec(struct tnode *n) +static inline void empty_child_dec(struct key_vector *n) { n->empty_children-- ? : n->full_children--; } -static struct tnode *leaf_new(t_key key, struct fib_alias *fa) +static struct key_vector *leaf_new(t_key key, struct fib_alias *fa) { - struct tnode *l = kmem_cache_alloc(trie_leaf_kmem, GFP_KERNEL); + struct key_vector *l = kmem_cache_alloc(trie_leaf_kmem, GFP_KERNEL); if (l) { l->parent = NULL; /* set key and pos to reflect full key value @@ -344,9 +344,9 @@ static struct tnode *leaf_new(t_key key, struct fib_alias *fa) return l; } -static struct tnode *tnode_new(t_key key, int pos, int bits) +static struct key_vector *tnode_new(t_key key, int pos, int bits) { - struct tnode *tn = tnode_alloc(bits); + struct key_vector *tn = tnode_alloc(bits); unsigned int shift = pos + bits; /* verify bits and pos their msb bits clear and values are valid */ @@ -365,14 +365,14 @@ static struct tnode *tnode_new(t_key key, int pos, int bits) } pr_debug("AT %p s=%zu %zu\n", tn, TNODE_SIZE(0), - sizeof(struct tnode *) << bits); + sizeof(struct key_vector *) << bits); return tn; } /* Check whether a tnode 'n' is "full", i.e. it is an internal node * and no bits are skipped. See discussion in dyntree paper p. 6 */ -static inline int tnode_full(const struct tnode *tn, const struct tnode *n) +static inline int tnode_full(struct key_vector *tn, struct key_vector *n) { return n && ((n->pos + n->bits) == tn->pos) && IS_TNODE(n); } @@ -380,9 +380,10 @@ static inline int tnode_full(const struct tnode *tn, const struct tnode *n) /* Add a child at position i overwriting the old value. * Update the value of full_children and empty_children. */ -static void put_child(struct tnode *tn, unsigned long i, struct tnode *n) +static void put_child(struct key_vector *tn, unsigned long i, + struct key_vector *n) { - struct tnode *chi = tnode_get_child(tn, i); + struct key_vector *chi = tnode_get_child(tn, i); int isfull, wasfull; BUG_ON(i >= tnode_child_length(tn)); @@ -408,13 +409,13 @@ static void put_child(struct tnode *tn, unsigned long i, struct tnode *n) rcu_assign_pointer(tn->tnode[i], n); } -static void update_children(struct tnode *tn) +static void update_children(struct key_vector *tn) { unsigned long i; /* update all of the child parent pointers */ for (i = tnode_child_length(tn); i;) { - struct tnode *inode = tnode_get_child(tn, --i); + struct key_vector *inode = tnode_get_child(tn, --i); if (!inode) continue; @@ -430,27 +431,28 @@ static void update_children(struct tnode *tn) } } -static inline void put_child_root(struct tnode *tp, struct trie *t, - t_key key, struct tnode *n) +static inline void put_child_root(struct key_vector *tp, struct trie *t, + t_key key, struct key_vector *n) { if (tp) put_child(tp, get_index(key, tp), n); else - rcu_assign_pointer(t->trie, n); + rcu_assign_pointer(t->tnode[0], n); } -static inline void tnode_free_init(struct tnode *tn) +static inline void tnode_free_init(struct key_vector *tn) { tn->rcu.next = NULL; } -static inline void tnode_free_append(struct tnode *tn, struct tnode *n) +static inline void tnode_free_append(struct key_vector *tn, + struct key_vector *n) { n->rcu.next = tn->rcu.next; tn->rcu.next = &n->rcu; } -static void tnode_free(struct tnode *tn) +static void tnode_free(struct key_vector *tn) { struct callback_head *head = &tn->rcu; @@ -459,7 +461,7 @@ static void tnode_free(struct tnode *tn) tnode_free_size += TNODE_SIZE(1ul << tn->bits); node_free(tn); - tn = container_of(head, struct tnode, rcu); + tn = container_of(head, struct key_vector, rcu); } if (tnode_free_size >= PAGE_SIZE * sync_pages) { @@ -468,11 +470,12 @@ static void tnode_free(struct tnode *tn) } } -static struct tnode __rcu **replace(struct trie *t, struct tnode *oldtnode, - struct tnode *tn) +static struct key_vector __rcu **replace(struct trie *t, + struct key_vector *oldtnode, + struct key_vector *tn) { - struct tnode *tp = node_parent(oldtnode); - struct tnode **cptr; + struct key_vector *tp = node_parent(oldtnode); + struct key_vector **cptr; unsigned long i; /* setup the parent pointer out of and back into this node */ @@ -486,11 +489,11 @@ static struct tnode __rcu **replace(struct trie *t, struct tnode *oldtnode, tnode_free(oldtnode); /* record the pointer that is pointing to this node */ - cptr = tp ? tp->tnode : &t->trie; + cptr = tp ? tp->tnode : t->tnode; /* resize children now that oldtnode is freed */ for (i = tnode_child_length(tn); i;) { - struct tnode *inode = tnode_get_child(tn, --i); + struct key_vector *inode = tnode_get_child(tn, --i); /* resize child node */ if (tnode_full(tn, inode)) @@ -500,9 +503,10 @@ static struct tnode __rcu **replace(struct trie *t, struct tnode *oldtnode, return cptr; } -static struct tnode __rcu **inflate(struct trie *t, struct tnode *oldtnode) +static struct key_vector __rcu **inflate(struct trie *t, + struct key_vector *oldtnode) { - struct tnode *tn; + struct key_vector *tn; unsigned long i; t_key m; @@ -521,8 +525,8 @@ static struct tnode __rcu **inflate(struct trie *t, struct tnode *oldtnode) * nodes. */ for (i = tnode_child_length(oldtnode), m = 1u << tn->pos; i;) { - struct tnode *inode = tnode_get_child(oldtnode, --i); - struct tnode *node0, *node1; + struct key_vector *inode = tnode_get_child(oldtnode, --i); + struct key_vector *node0, *node1; unsigned long j, k; /* An empty child */ @@ -595,9 +599,10 @@ notnode: return NULL; } -static struct tnode __rcu **halve(struct trie *t, struct tnode *oldtnode) +static struct key_vector __rcu **halve(struct trie *t, + struct key_vector *oldtnode) { - struct tnode *tn; + struct key_vector *tn; unsigned long i; pr_debug("In halve\n"); @@ -615,9 +620,9 @@ static struct tnode __rcu **halve(struct trie *t, struct tnode *oldtnode) * nodes. */ for (i = tnode_child_length(oldtnode); i;) { - struct tnode *node1 = tnode_get_child(oldtnode, --i); - struct tnode *node0 = tnode_get_child(oldtnode, --i); - struct tnode *inode; + struct key_vector *node1 = tnode_get_child(oldtnode, --i); + struct key_vector *node0 = tnode_get_child(oldtnode, --i); + struct key_vector *inode; /* At least one of the children is empty */ if (!node1 || !node0) { @@ -649,9 +654,9 @@ notnode: return NULL; } -static void collapse(struct trie *t, struct tnode *oldtnode) +static void collapse(struct trie *t, struct key_vector *oldtnode) { - struct tnode *n, *tp; + struct key_vector *n, *tp; unsigned long i; /* scan the tnode looking for that one child that might still exist */ @@ -667,7 +672,7 @@ static void collapse(struct trie *t, struct tnode *oldtnode) node_free(oldtnode); } -static unsigned char update_suffix(struct tnode *tn) +static unsigned char update_suffix(struct key_vector *tn) { unsigned char slen = tn->pos; unsigned long stride, i; @@ -678,7 +683,7 @@ static unsigned char update_suffix(struct tnode *tn) * represent the nodes with suffix length equal to tn->pos */ for (i = 0, stride = 0x2ul ; i < tnode_child_length(tn); i += stride) { - struct tnode *n = tnode_get_child(tn, i); + struct key_vector *n = tnode_get_child(tn, i); if (!n || (n->slen <= slen)) continue; @@ -759,7 +764,7 @@ static unsigned char update_suffix(struct tnode *tn) * tnode_child_length(tn) * */ -static bool should_inflate(const struct tnode *tp, const struct tnode *tn) +static inline bool should_inflate(struct key_vector *tp, struct key_vector *tn) { unsigned long used = tnode_child_length(tn); unsigned long threshold = used; @@ -774,7 +779,7 @@ static bool should_inflate(const struct tnode *tp, const struct tnode *tn) return (used > 1) && tn->pos && ((50 * used) >= threshold); } -static bool should_halve(const struct tnode *tp, const struct tnode *tn) +static inline bool should_halve(struct key_vector *tp, struct key_vector *tn) { unsigned long used = tnode_child_length(tn); unsigned long threshold = used; @@ -788,7 +793,7 @@ static bool should_halve(const struct tnode *tp, const struct tnode *tn) return (used > 1) && (tn->bits > 1) && ((100 * used) < threshold); } -static bool should_collapse(const struct tnode *tn) +static inline bool should_collapse(struct key_vector *tn) { unsigned long used = tnode_child_length(tn); @@ -803,14 +808,15 @@ static bool should_collapse(const struct tnode *tn) } #define MAX_WORK 10 -static struct tnode __rcu **resize(struct trie *t, struct tnode *tn) +static struct key_vector __rcu **resize(struct trie *t, + struct key_vector *tn) { #ifdef CONFIG_IP_FIB_TRIE_STATS struct trie_use_stats __percpu *stats = t->stats; #endif - struct tnode *tp = node_parent(tn); + struct key_vector *tp = node_parent(tn); unsigned long cindex = tp ? get_index(tn->key, tp) : 0; - struct tnode __rcu **cptr = tp ? tp->tnode : &t->trie; + struct key_vector __rcu **cptr = tp ? tp->tnode : t->tnode; int max_work = MAX_WORK; pr_debug("In tnode_resize %p inflate_threshold=%d threshold=%d\n", @@ -826,7 +832,7 @@ static struct tnode __rcu **resize(struct trie *t, struct tnode *tn) * nonempty nodes that are above the threshold. */ while (should_inflate(tp, tn) && max_work) { - struct tnode __rcu **tcptr = inflate(t, tn); + struct key_vector __rcu **tcptr = inflate(t, tn); if (!tcptr) { #ifdef CONFIG_IP_FIB_TRIE_STATS @@ -848,7 +854,7 @@ static struct tnode __rcu **resize(struct trie *t, struct tnode *tn) * node is above threshold. */ while (should_halve(tp, tn) && max_work) { - struct tnode __rcu **tcptr = halve(t, tn); + struct key_vector __rcu **tcptr = halve(t, tn); if (!tcptr) { #ifdef CONFIG_IP_FIB_TRIE_STATS @@ -883,7 +889,7 @@ static struct tnode __rcu **resize(struct trie *t, struct tnode *tn) return cptr; } -static void leaf_pull_suffix(struct tnode *tp, struct tnode *l) +static void leaf_pull_suffix(struct key_vector *tp, struct key_vector *l) { while (tp && (tp->slen > tp->pos) && (tp->slen > l->slen)) { if (update_suffix(tp) > l->slen) @@ -892,7 +898,7 @@ static void leaf_pull_suffix(struct tnode *tp, struct tnode *l) } } -static void leaf_push_suffix(struct tnode *tn, struct tnode *l) +static void leaf_push_suffix(struct key_vector *tn, struct key_vector *l) { /* if this is a new leaf then tn will be NULL and we can sort * out parent suffix lengths as a part of trie_rebalance @@ -904,9 +910,10 @@ static void leaf_push_suffix(struct tnode *tn, struct tnode *l) } /* rcu_read_lock needs to be hold by caller from readside */ -static struct tnode *fib_find_node(struct trie *t, struct tnode **tn, u32 key) +static struct key_vector *fib_find_node(struct trie *t, + struct key_vector **tp, u32 key) { - struct tnode *pn = NULL, *n = rcu_dereference_rtnl(t->trie); + struct key_vector *pn = NULL, *n = rcu_dereference_rtnl(t->tnode[0]); while (n) { unsigned long index = get_index(key, n); @@ -938,7 +945,7 @@ static struct tnode *fib_find_node(struct trie *t, struct tnode **tn, u32 key) n = tnode_get_child_rcu(n, index); } - *tn = pn; + *tp = pn; return n; } @@ -968,24 +975,24 @@ static struct fib_alias *fib_find_alias(struct hlist_head *fah, u8 slen, return NULL; } -static void trie_rebalance(struct trie *t, struct tnode *tn) +static void trie_rebalance(struct trie *t, struct key_vector *tn) { - struct tnode __rcu **cptr = &t->trie; + struct key_vector __rcu **cptr = t->tnode; while (tn) { - struct tnode *tp = node_parent(tn); + struct key_vector *tp = node_parent(tn); cptr = resize(t, tn); if (!tp) break; - tn = container_of(cptr, struct tnode, tnode[0]); + tn = container_of(cptr, struct key_vector, tnode[0]); } } -static int fib_insert_node(struct trie *t, struct tnode *tp, +static int fib_insert_node(struct trie *t, struct key_vector *tp, struct fib_alias *new, t_key key) { - struct tnode *n, *l; + struct key_vector *n, *l; l = leaf_new(key, new); if (!l) @@ -995,7 +1002,7 @@ static int fib_insert_node(struct trie *t, struct tnode *tp, if (tp) n = tnode_get_child(tp, get_index(key, tp)); else - n = rcu_dereference_rtnl(t->trie); + n = rcu_dereference_rtnl(t->tnode[0]); /* Case 2: n is a LEAF or a TNODE and the key doesn't match. * @@ -1004,7 +1011,7 @@ static int fib_insert_node(struct trie *t, struct tnode *tp, * leaves us in position for handling as case 3 */ if (n) { - struct tnode *tn; + struct key_vector *tn; tn = tnode_new(key, __fls(key ^ n->key), 1); if (!tn) @@ -1034,8 +1041,8 @@ noleaf: return -ENOMEM; } -static int fib_insert_alias(struct trie *t, struct tnode *tp, - struct tnode *l, struct fib_alias *new, +static int fib_insert_alias(struct trie *t, struct key_vector *tp, + struct key_vector *l, struct fib_alias *new, struct fib_alias *fa, t_key key) { if (!l) @@ -1072,7 +1079,7 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg) { struct trie *t = (struct trie *)tb->tb_data; struct fib_alias *fa, *new_fa; - struct tnode *l, *tp; + struct key_vector *l, *tp; struct fib_info *fi; u8 plen = cfg->fc_dst_len; u8 slen = KEYLENGTH - plen; @@ -1237,7 +1244,7 @@ err: return err; } -static inline t_key prefix_mismatch(t_key key, struct tnode *n) +static inline t_key prefix_mismatch(t_key key, struct key_vector *n) { t_key prefix = n->key; @@ -1253,12 +1260,12 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi4 *flp, struct trie_use_stats __percpu *stats = t->stats; #endif const t_key key = ntohl(flp->daddr); - struct tnode *n, *pn; + struct key_vector *n, *pn; struct fib_alias *fa; unsigned long index; t_key cindex; - n = rcu_dereference(t->trie); + n = rcu_dereference(t->tnode[0]); if (!n) return -EAGAIN; @@ -1310,7 +1317,7 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi4 *flp, /* Step 2: Sort out leaves and begin backtracing for longest prefix */ for (;;) { /* record the pointer where our next node pointer is stored */ - struct tnode __rcu **cptr = n->tnode; + struct key_vector __rcu **cptr = n->tnode; /* This test verifies that none of the bits that differ * between the key and the prefix exist in the region of @@ -1419,8 +1426,8 @@ found: } EXPORT_SYMBOL_GPL(fib_table_lookup); -static void fib_remove_alias(struct trie *t, struct tnode *tp, - struct tnode *l, struct fib_alias *old) +static void fib_remove_alias(struct trie *t, struct key_vector *tp, + struct key_vector *l, struct fib_alias *old) { /* record the location of the previous list_info entry */ struct hlist_node **pprev = old->fa_list.pprev; @@ -1453,7 +1460,7 @@ int fib_table_delete(struct fib_table *tb, struct fib_config *cfg) { struct trie *t = (struct trie *) tb->tb_data; struct fib_alias *fa, *fa_to_delete; - struct tnode *l, *tp; + struct key_vector *l, *tp; u8 plen = cfg->fc_dst_len; u8 slen = KEYLENGTH - plen; u8 tos = cfg->fc_tos; @@ -1520,9 +1527,9 @@ int fib_table_delete(struct fib_table *tb, struct fib_config *cfg) } /* Scan for the next leaf starting at the provided key value */ -static struct tnode *leaf_walk_rcu(struct tnode **tn, t_key key) +static struct key_vector *leaf_walk_rcu(struct key_vector **tn, t_key key) { - struct tnode *pn, *n = *tn; + struct key_vector *pn, *n = *tn; unsigned long cindex; /* record parent node for backtracing */ @@ -1588,10 +1595,10 @@ void fib_table_flush_external(struct fib_table *tb) { struct trie *t = (struct trie *)tb->tb_data; struct fib_alias *fa; - struct tnode *n, *pn; + struct key_vector *n, *pn; unsigned long cindex; - n = rcu_dereference(t->trie); + n = rcu_dereference(t->tnode[0]); if (!n) return; @@ -1642,14 +1649,14 @@ backtrace: int fib_table_flush(struct fib_table *tb) { struct trie *t = (struct trie *)tb->tb_data; + struct key_vector *n, *pn; struct hlist_node *tmp; struct fib_alias *fa; - struct tnode *n, *pn; unsigned long cindex; unsigned char slen; int found = 0; - n = rcu_dereference(t->trie); + n = rcu_dereference(t->tnode[0]); if (!n) goto flush_complete; @@ -1664,7 +1671,7 @@ backtrace: /* walk trie in reverse order */ do { while (!(cindex--)) { - struct tnode __rcu **cptr; + struct key_vector __rcu **cptr; t_key pkey = pn->key; n = pn; @@ -1677,7 +1684,8 @@ backtrace: if (!pn) goto flush_complete; - pn = container_of(cptr, struct tnode, tnode[0]); + pn = container_of(cptr, struct key_vector, + tnode[0]); cindex = get_index(pkey, pn); } @@ -1742,7 +1750,7 @@ void fib_free_table(struct fib_table *tb) call_rcu(&tb->rcu, __trie_free_rcu); } -static int fn_trie_dump_leaf(struct tnode *l, struct fib_table *tb, +static int fn_trie_dump_leaf(struct key_vector *l, struct fib_table *tb, struct sk_buff *skb, struct netlink_callback *cb) { __be32 xkey = htonl(l->key); @@ -1783,14 +1791,14 @@ int fib_table_dump(struct fib_table *tb, struct sk_buff *skb, struct netlink_callback *cb) { struct trie *t = (struct trie *)tb->tb_data; - struct tnode *l, *tp; + struct key_vector *l, *tp; /* Dump starting at last key. * Note: 0.0.0.0/0 (ie default) is first key. */ int count = cb->args[2]; t_key key = cb->args[3]; - tp = rcu_dereference_rtnl(t->trie); + tp = rcu_dereference_rtnl(t->tnode[0]); while ((l = leaf_walk_rcu(&tp, key)) != NULL) { if (fn_trie_dump_leaf(l, tb, skb, cb) < 0) { @@ -1843,7 +1851,7 @@ struct fib_table *fib_trie_table(u32 id) tb->tb_num_default = 0; t = (struct trie *) tb->tb_data; - RCU_INIT_POINTER(t->trie, NULL); + RCU_INIT_POINTER(t->tnode[0], NULL); #ifdef CONFIG_IP_FIB_TRIE_STATS t->stats = alloc_percpu(struct trie_use_stats); if (!t->stats) { @@ -1860,16 +1868,16 @@ struct fib_table *fib_trie_table(u32 id) struct fib_trie_iter { struct seq_net_private p; struct fib_table *tb; - struct tnode *tnode; + struct key_vector *tnode; unsigned int index; unsigned int depth; }; -static struct tnode *fib_trie_get_next(struct fib_trie_iter *iter) +static struct key_vector *fib_trie_get_next(struct fib_trie_iter *iter) { unsigned long cindex = iter->index; - struct tnode *tn = iter->tnode; - struct tnode *p; + struct key_vector *tn = iter->tnode; + struct key_vector *p; /* A single entry routing table */ if (!tn) @@ -1879,7 +1887,7 @@ static struct tnode *fib_trie_get_next(struct fib_trie_iter *iter) iter->tnode, iter->index, iter->depth); rescan: while (cindex < tnode_child_length(tn)) { - struct tnode *n = tnode_get_child_rcu(tn, cindex); + struct key_vector *n = tnode_get_child_rcu(tn, cindex); if (n) { if (IS_LEAF(n)) { @@ -1910,15 +1918,15 @@ rescan: return NULL; } -static struct tnode *fib_trie_get_first(struct fib_trie_iter *iter, - struct trie *t) +static struct key_vector *fib_trie_get_first(struct fib_trie_iter *iter, + struct trie *t) { - struct tnode *n; + struct key_vector *n; if (!t) return NULL; - n = rcu_dereference(t->trie); + n = rcu_dereference(t->tnode[0]); if (!n) return NULL; @@ -1937,7 +1945,7 @@ static struct tnode *fib_trie_get_first(struct fib_trie_iter *iter, static void trie_collect_stats(struct trie *t, struct trie_stat *s) { - struct tnode *n; + struct key_vector *n; struct fib_trie_iter iter; memset(s, 0, sizeof(*s)); @@ -2002,7 +2010,7 @@ static void trie_show_stats(struct seq_file *seq, struct trie_stat *stat) seq_putc(seq, '\n'); seq_printf(seq, "\tPointers: %u\n", pointers); - bytes += sizeof(struct tnode *) * pointers; + bytes += sizeof(struct key_vector *) * pointers; seq_printf(seq, "Null ptrs: %u\n", stat->nullpointers); seq_printf(seq, "Total size: %u kB\n", (bytes + 1023) / 1024); } @@ -2095,7 +2103,7 @@ static const struct file_operations fib_triestat_fops = { .release = single_release_net, }; -static struct tnode *fib_trie_get_idx(struct seq_file *seq, loff_t pos) +static struct key_vector *fib_trie_get_idx(struct seq_file *seq, loff_t pos) { struct fib_trie_iter *iter = seq->private; struct net *net = seq_file_net(seq); @@ -2107,7 +2115,7 @@ static struct tnode *fib_trie_get_idx(struct seq_file *seq, loff_t pos) struct fib_table *tb; hlist_for_each_entry_rcu(tb, head, tb_hlist) { - struct tnode *n; + struct key_vector *n; for (n = fib_trie_get_first(iter, (struct trie *) tb->tb_data); @@ -2136,7 +2144,7 @@ static void *fib_trie_seq_next(struct seq_file *seq, void *v, loff_t *pos) struct fib_table *tb = iter->tb; struct hlist_node *tb_node; unsigned int h; - struct tnode *n; + struct key_vector *n; ++*pos; /* next node in same table */ @@ -2222,7 +2230,7 @@ static inline const char *rtn_type(char *buf, size_t len, unsigned int t) static int fib_trie_seq_show(struct seq_file *seq, void *v) { const struct fib_trie_iter *iter = seq->private; - struct tnode *n = v; + struct key_vector *n = v; if (!node_parent_rcu(n)) fib_table_print(seq, iter->tb); @@ -2284,15 +2292,16 @@ static const struct file_operations fib_trie_fops = { struct fib_route_iter { struct seq_net_private p; struct fib_table *main_tb; - struct tnode *tnode; + struct key_vector *tnode; loff_t pos; t_key key; }; -static struct tnode *fib_route_get_idx(struct fib_route_iter *iter, loff_t pos) +static struct key_vector *fib_route_get_idx(struct fib_route_iter *iter, + loff_t pos) { struct fib_table *tb = iter->main_tb; - struct tnode *l, **tp = &iter->tnode; + struct key_vector *l, **tp = &iter->tnode; struct trie *t; t_key key; @@ -2302,7 +2311,7 @@ static struct tnode *fib_route_get_idx(struct fib_route_iter *iter, loff_t pos) key = iter->key; } else { t = (struct trie *)tb->tb_data; - iter->tnode = rcu_dereference_rtnl(t->trie); + iter->tnode = rcu_dereference_rtnl(t->tnode[0]); iter->pos = 0; key = 0; } @@ -2348,7 +2357,7 @@ static void *fib_route_seq_start(struct seq_file *seq, loff_t *pos) return fib_route_get_idx(iter, *pos); t = (struct trie *)tb->tb_data; - iter->tnode = rcu_dereference_rtnl(t->trie); + iter->tnode = rcu_dereference_rtnl(t->tnode[0]); iter->pos = 0; iter->key = 0; @@ -2358,7 +2367,7 @@ static void *fib_route_seq_start(struct seq_file *seq, loff_t *pos) static void *fib_route_seq_next(struct seq_file *seq, void *v, loff_t *pos) { struct fib_route_iter *iter = seq->private; - struct tnode *l = NULL; + struct key_vector *l = NULL; t_key key = iter->key; ++*pos; @@ -2406,7 +2415,7 @@ static unsigned int fib_flag_trans(int type, __be32 mask, const struct fib_info static int fib_route_seq_show(struct seq_file *seq, void *v) { struct fib_alias *fa; - struct tnode *l = v; + struct key_vector *l = v; __be32 prefix; if (v == SEQ_START_TOKEN) { -- GitLab From 754baf8decce722db6d02bb0db745402f8cbc16f Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Fri, 6 Mar 2015 09:54:14 -0800 Subject: [PATCH 03077/11651] fib_trie: replace tnode_get_child functions with get_child macros I am replacing the tnode_get_child call with get_child since we are techically pulling the child out of a key_vector now and not a tnode. Signed-off-by: Alexander Duyck Signed-off-by: David S. Miller --- net/ipv4/fib_trie.c | 60 ++++++++++++++++++--------------------------- 1 file changed, 24 insertions(+), 36 deletions(-) diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 8b21fc3da43e..b9e2a6195572 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -159,9 +159,11 @@ static struct kmem_cache *trie_leaf_kmem __read_mostly; /* caller must hold RTNL */ #define node_parent(n) rtnl_dereference((n)->parent) +#define get_child(tn, i) rtnl_dereference((tn)->tnode[i]) /* caller must hold RCU read lock or RTNL */ #define node_parent_rcu(n) rcu_dereference_rtnl((n)->parent) +#define get_child_rcu(tn, i) rcu_dereference_rtnl((tn)->tnode[i]) /* wrapper for rcu_assign_pointer */ static inline void node_set_parent(struct key_vector *n, struct key_vector *tp) @@ -180,20 +182,6 @@ static inline unsigned long tnode_child_length(const struct key_vector *tn) return (1ul << tn->bits) & ~(1ul); } -/* caller must hold RTNL */ -static inline struct key_vector *tnode_get_child(struct key_vector *tn, - unsigned long i) -{ - return rtnl_dereference(tn->tnode[i]); -} - -/* caller must hold RCU read lock or RTNL */ -static inline struct key_vector *tnode_get_child_rcu(struct key_vector *tn, - unsigned long i) -{ - return rcu_dereference_rtnl(tn->tnode[i]); -} - static inline struct fib_table *trie_get_table(struct trie *t) { unsigned long *tb_data = (unsigned long *)t; @@ -383,7 +371,7 @@ static inline int tnode_full(struct key_vector *tn, struct key_vector *n) static void put_child(struct key_vector *tn, unsigned long i, struct key_vector *n) { - struct key_vector *chi = tnode_get_child(tn, i); + struct key_vector *chi = get_child(tn, i); int isfull, wasfull; BUG_ON(i >= tnode_child_length(tn)); @@ -415,7 +403,7 @@ static void update_children(struct key_vector *tn) /* update all of the child parent pointers */ for (i = tnode_child_length(tn); i;) { - struct key_vector *inode = tnode_get_child(tn, --i); + struct key_vector *inode = get_child(tn, --i); if (!inode) continue; @@ -493,7 +481,7 @@ static struct key_vector __rcu **replace(struct trie *t, /* resize children now that oldtnode is freed */ for (i = tnode_child_length(tn); i;) { - struct key_vector *inode = tnode_get_child(tn, --i); + struct key_vector *inode = get_child(tn, --i); /* resize child node */ if (tnode_full(tn, inode)) @@ -525,7 +513,7 @@ static struct key_vector __rcu **inflate(struct trie *t, * nodes. */ for (i = tnode_child_length(oldtnode), m = 1u << tn->pos; i;) { - struct key_vector *inode = tnode_get_child(oldtnode, --i); + struct key_vector *inode = get_child(oldtnode, --i); struct key_vector *node0, *node1; unsigned long j, k; @@ -544,8 +532,8 @@ static struct key_vector __rcu **inflate(struct trie *t, /* An internal node with two children */ if (inode->bits == 1) { - put_child(tn, 2 * i + 1, tnode_get_child(inode, 1)); - put_child(tn, 2 * i, tnode_get_child(inode, 0)); + put_child(tn, 2 * i + 1, get_child(inode, 1)); + put_child(tn, 2 * i, get_child(inode, 0)); continue; } @@ -575,10 +563,10 @@ static struct key_vector __rcu **inflate(struct trie *t, /* populate child pointers in new nodes */ for (k = tnode_child_length(inode), j = k / 2; j;) { - put_child(node1, --j, tnode_get_child(inode, --k)); - put_child(node0, j, tnode_get_child(inode, j)); - put_child(node1, --j, tnode_get_child(inode, --k)); - put_child(node0, j, tnode_get_child(inode, j)); + put_child(node1, --j, get_child(inode, --k)); + put_child(node0, j, get_child(inode, j)); + put_child(node1, --j, get_child(inode, --k)); + put_child(node0, j, get_child(inode, j)); } /* link new nodes to parent */ @@ -620,8 +608,8 @@ static struct key_vector __rcu **halve(struct trie *t, * nodes. */ for (i = tnode_child_length(oldtnode); i;) { - struct key_vector *node1 = tnode_get_child(oldtnode, --i); - struct key_vector *node0 = tnode_get_child(oldtnode, --i); + struct key_vector *node1 = get_child(oldtnode, --i); + struct key_vector *node0 = get_child(oldtnode, --i); struct key_vector *inode; /* At least one of the children is empty */ @@ -661,7 +649,7 @@ static void collapse(struct trie *t, struct key_vector *oldtnode) /* scan the tnode looking for that one child that might still exist */ for (n = NULL, i = tnode_child_length(oldtnode); !n && i;) - n = tnode_get_child(oldtnode, --i); + n = get_child(oldtnode, --i); /* compress one level */ tp = node_parent(oldtnode); @@ -683,7 +671,7 @@ static unsigned char update_suffix(struct key_vector *tn) * represent the nodes with suffix length equal to tn->pos */ for (i = 0, stride = 0x2ul ; i < tnode_child_length(tn); i += stride) { - struct key_vector *n = tnode_get_child(tn, i); + struct key_vector *n = get_child(tn, i); if (!n || (n->slen <= slen)) continue; @@ -942,7 +930,7 @@ static struct key_vector *fib_find_node(struct trie *t, break; pn = n; - n = tnode_get_child_rcu(n, index); + n = get_child_rcu(n, index); } *tp = pn; @@ -1000,7 +988,7 @@ static int fib_insert_node(struct trie *t, struct key_vector *tp, /* retrieve child from parent node */ if (tp) - n = tnode_get_child(tp, get_index(key, tp)); + n = get_child(tp, get_index(key, tp)); else n = rcu_dereference_rtnl(t->tnode[0]); @@ -1309,7 +1297,7 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi4 *flp, cindex = index; } - n = tnode_get_child_rcu(n, index); + n = get_child_rcu(n, index); if (unlikely(!n)) goto backtrace; } @@ -1551,7 +1539,7 @@ static struct key_vector *leaf_walk_rcu(struct key_vector **tn, t_key key) cindex = idx; /* descend into the next child */ - n = tnode_get_child_rcu(pn, cindex++); + n = get_child_rcu(pn, cindex++); } /* this loop will search for the next leaf with a greater key */ @@ -1569,7 +1557,7 @@ static struct key_vector *leaf_walk_rcu(struct key_vector **tn, t_key key) } /* grab the next available node */ - n = tnode_get_child_rcu(pn, cindex++); + n = get_child_rcu(pn, cindex++); if (!n) continue; @@ -1624,7 +1612,7 @@ backtrace: } /* grab the next available node */ - n = tnode_get_child(pn, cindex); + n = get_child(pn, cindex); } while (!n); } @@ -1690,7 +1678,7 @@ backtrace: } /* grab the next available node */ - n = tnode_get_child(pn, cindex); + n = get_child(pn, cindex); } while (!n); } @@ -1887,7 +1875,7 @@ static struct key_vector *fib_trie_get_next(struct fib_trie_iter *iter) iter->tnode, iter->index, iter->depth); rescan: while (cindex < tnode_child_length(tn)) { - struct key_vector *n = tnode_get_child_rcu(tn, cindex); + struct key_vector *n = get_child_rcu(tn, cindex); if (n) { if (IS_LEAF(n)) { -- GitLab From 2e1ac88a48370620429cd9e54c41365531962809 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Fri, 6 Mar 2015 09:54:21 -0800 Subject: [PATCH 03078/11651] fib_trie: Rename tnode_child_length to child_length We are now checking the length of a key_vector instead of a tnode so it makes sense to probably just rename this to child_length since it would probably even be applicable to a leaf. Signed-off-by: Alexander Duyck Signed-off-by: David S. Miller --- net/ipv4/fib_trie.c | 53 +++++++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 24 deletions(-) diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index b9e2a6195572..b88c0d0f48ed 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -92,8 +92,6 @@ typedef unsigned int t_key; #define IS_TNODE(n) ((n)->bits) #define IS_LEAF(n) (!(n)->bits) -#define get_index(_key, _kv) (((_key) ^ (_kv)->key) >> (_kv)->pos) - struct key_vector { struct rcu_head rcu; @@ -177,11 +175,18 @@ static inline void node_set_parent(struct key_vector *n, struct key_vector *tp) /* This provides us with the number of children in this node, in the case of a * leaf this will return 0 meaning none of the children are accessible. */ -static inline unsigned long tnode_child_length(const struct key_vector *tn) +static inline unsigned long child_length(const struct key_vector *tn) { return (1ul << tn->bits) & ~(1ul); } +static inline unsigned long get_index(t_key key, struct key_vector *kv) +{ + unsigned long index = key ^ kv->key; + + return index >> kv->pos; +} + static inline struct fib_table *trie_get_table(struct trie *t) { unsigned long *tb_data = (unsigned long *)t; @@ -374,7 +379,7 @@ static void put_child(struct key_vector *tn, unsigned long i, struct key_vector *chi = get_child(tn, i); int isfull, wasfull; - BUG_ON(i >= tnode_child_length(tn)); + BUG_ON(i >= child_length(tn)); /* update emptyChildren, overflow into fullChildren */ if (n == NULL && chi != NULL) @@ -402,7 +407,7 @@ static void update_children(struct key_vector *tn) unsigned long i; /* update all of the child parent pointers */ - for (i = tnode_child_length(tn); i;) { + for (i = child_length(tn); i;) { struct key_vector *inode = get_child(tn, --i); if (!inode) @@ -480,7 +485,7 @@ static struct key_vector __rcu **replace(struct trie *t, cptr = tp ? tp->tnode : t->tnode; /* resize children now that oldtnode is freed */ - for (i = tnode_child_length(tn); i;) { + for (i = child_length(tn); i;) { struct key_vector *inode = get_child(tn, --i); /* resize child node */ @@ -512,7 +517,7 @@ static struct key_vector __rcu **inflate(struct trie *t, * point to existing tnodes and the links between our allocated * nodes. */ - for (i = tnode_child_length(oldtnode), m = 1u << tn->pos; i;) { + for (i = child_length(oldtnode), m = 1u << tn->pos; i;) { struct key_vector *inode = get_child(oldtnode, --i); struct key_vector *node0, *node1; unsigned long j, k; @@ -562,7 +567,7 @@ static struct key_vector __rcu **inflate(struct trie *t, tnode_free_append(tn, node0); /* populate child pointers in new nodes */ - for (k = tnode_child_length(inode), j = k / 2; j;) { + for (k = child_length(inode), j = k / 2; j;) { put_child(node1, --j, get_child(inode, --k)); put_child(node0, j, get_child(inode, j)); put_child(node1, --j, get_child(inode, --k)); @@ -607,7 +612,7 @@ static struct key_vector __rcu **halve(struct trie *t, * point to existing tnodes and the links between our allocated * nodes. */ - for (i = tnode_child_length(oldtnode); i;) { + for (i = child_length(oldtnode); i;) { struct key_vector *node1 = get_child(oldtnode, --i); struct key_vector *node0 = get_child(oldtnode, --i); struct key_vector *inode; @@ -648,7 +653,7 @@ static void collapse(struct trie *t, struct key_vector *oldtnode) unsigned long i; /* scan the tnode looking for that one child that might still exist */ - for (n = NULL, i = tnode_child_length(oldtnode); !n && i;) + for (n = NULL, i = child_length(oldtnode); !n && i;) n = get_child(oldtnode, --i); /* compress one level */ @@ -670,7 +675,7 @@ static unsigned char update_suffix(struct key_vector *tn) * why we start with a stride of 2 since a stride of 1 would * represent the nodes with suffix length equal to tn->pos */ - for (i = 0, stride = 0x2ul ; i < tnode_child_length(tn); i += stride) { + for (i = 0, stride = 0x2ul ; i < child_length(tn); i += stride) { struct key_vector *n = get_child(tn, i); if (!n || (n->slen <= slen)) @@ -703,12 +708,12 @@ static unsigned char update_suffix(struct key_vector *tn) * * 'high' in this instance is the variable 'inflate_threshold'. It * is expressed as a percentage, so we multiply it with - * tnode_child_length() and instead of multiplying by 2 (since the + * child_length() and instead of multiplying by 2 (since the * child array will be doubled by inflate()) and multiplying * the left-hand side by 100 (to handle the percentage thing) we * multiply the left-hand side by 50. * - * The left-hand side may look a bit weird: tnode_child_length(tn) + * The left-hand side may look a bit weird: child_length(tn) * - tn->empty_children is of course the number of non-null children * in the current node. tn->full_children is the number of "full" * children, that is non-null tnodes with a skip value of 0. @@ -718,10 +723,10 @@ static unsigned char update_suffix(struct key_vector *tn) * A clearer way to write this would be: * * to_be_doubled = tn->full_children; - * not_to_be_doubled = tnode_child_length(tn) - tn->empty_children - + * not_to_be_doubled = child_length(tn) - tn->empty_children - * tn->full_children; * - * new_child_length = tnode_child_length(tn) * 2; + * new_child_length = child_length(tn) * 2; * * new_fill_factor = 100 * (not_to_be_doubled + 2*to_be_doubled) / * new_child_length; @@ -738,23 +743,23 @@ static unsigned char update_suffix(struct key_vector *tn) * inflate_threshold * new_child_length * * expand not_to_be_doubled and to_be_doubled, and shorten: - * 100 * (tnode_child_length(tn) - tn->empty_children + + * 100 * (child_length(tn) - tn->empty_children + * tn->full_children) >= inflate_threshold * new_child_length * * expand new_child_length: - * 100 * (tnode_child_length(tn) - tn->empty_children + + * 100 * (child_length(tn) - tn->empty_children + * tn->full_children) >= - * inflate_threshold * tnode_child_length(tn) * 2 + * inflate_threshold * child_length(tn) * 2 * * shorten again: - * 50 * (tn->full_children + tnode_child_length(tn) - + * 50 * (tn->full_children + child_length(tn) - * tn->empty_children) >= inflate_threshold * - * tnode_child_length(tn) + * child_length(tn) * */ static inline bool should_inflate(struct key_vector *tp, struct key_vector *tn) { - unsigned long used = tnode_child_length(tn); + unsigned long used = child_length(tn); unsigned long threshold = used; /* Keep root node larger */ @@ -769,7 +774,7 @@ static inline bool should_inflate(struct key_vector *tp, struct key_vector *tn) static inline bool should_halve(struct key_vector *tp, struct key_vector *tn) { - unsigned long used = tnode_child_length(tn); + unsigned long used = child_length(tn); unsigned long threshold = used; /* Keep root node larger */ @@ -783,7 +788,7 @@ static inline bool should_halve(struct key_vector *tp, struct key_vector *tn) static inline bool should_collapse(struct key_vector *tn) { - unsigned long used = tnode_child_length(tn); + unsigned long used = child_length(tn); used -= tn->empty_children; @@ -1874,7 +1879,7 @@ static struct key_vector *fib_trie_get_next(struct fib_trie_iter *iter) pr_debug("get_next iter={node=%p index=%d depth=%d}\n", iter->tnode, iter->index, iter->depth); rescan: - while (cindex < tnode_child_length(tn)) { + while (cindex < child_length(tn)) { struct key_vector *n = get_child_rcu(tn, cindex); if (n) { -- GitLab From dc35dbeda3e00a05723784078a233c2531d34810 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Fri, 6 Mar 2015 09:54:27 -0800 Subject: [PATCH 03079/11651] fib_trie: Add tnode struct as a container for fields not needed in key_vector This change pulls the fields not explicitly needed in the key_vector and placed them in the new tnode structure. By doing this we will eventually be able to reduce the key_vector down to 16 bytes on 64 bit systems, and 12 bytes on 32 bit systems. Signed-off-by: Alexander Duyck Signed-off-by: David S. Miller --- net/ipv4/fib_trie.c | 72 ++++++++++++++++++++++++--------------------- 1 file changed, 39 insertions(+), 33 deletions(-) diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index b88c0d0f48ed..3a062370fc32 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -111,7 +111,11 @@ struct key_vector { }; }; -#define TNODE_SIZE(n) offsetof(struct key_vector, tnode[n]) +struct tnode { + struct key_vector kv[1]; +}; + +#define TNODE_SIZE(n) offsetof(struct tnode, kv[0].tnode[n]) #define LEAF_SIZE TNODE_SIZE(1) #ifdef CONFIG_IP_FIB_TRIE_STATS @@ -288,7 +292,7 @@ static void __node_free_rcu(struct rcu_head *head) #define node_free(n) call_rcu(&n->rcu, __node_free_rcu) -static struct key_vector *tnode_alloc(int bits) +static struct tnode *tnode_alloc(int bits) { size_t size; @@ -317,48 +321,50 @@ static inline void empty_child_dec(struct key_vector *n) static struct key_vector *leaf_new(t_key key, struct fib_alias *fa) { - struct key_vector *l = kmem_cache_alloc(trie_leaf_kmem, GFP_KERNEL); - if (l) { - l->parent = NULL; - /* set key and pos to reflect full key value - * any trailing zeros in the key should be ignored - * as the nodes are searched - */ - l->key = key; - l->slen = fa->fa_slen; - l->pos = 0; - /* set bits to 0 indicating we are not a tnode */ - l->bits = 0; - - /* link leaf to fib alias */ - INIT_HLIST_HEAD(&l->leaf); - hlist_add_head(&fa->fa_list, &l->leaf); - } + struct tnode *kv = kmem_cache_alloc(trie_leaf_kmem, GFP_KERNEL); + struct key_vector *l = kv->kv; + + if (!kv) + return NULL; + + /* initialize key vector */ + l->key = key; + l->pos = 0; + l->bits = 0; + l->slen = fa->fa_slen; + + /* link leaf to fib alias */ + INIT_HLIST_HEAD(&l->leaf); + hlist_add_head(&fa->fa_list, &l->leaf); + return l; } static struct key_vector *tnode_new(t_key key, int pos, int bits) { - struct key_vector *tn = tnode_alloc(bits); + struct tnode *tnode = tnode_alloc(bits); unsigned int shift = pos + bits; + struct key_vector *tn = tnode->kv; /* verify bits and pos their msb bits clear and values are valid */ BUG_ON(!bits || (shift > KEYLENGTH)); - if (tn) { - tn->parent = NULL; - tn->slen = pos; - tn->pos = pos; - tn->bits = bits; - tn->key = (shift < KEYLENGTH) ? (key >> shift) << shift : 0; - if (bits == KEYLENGTH) - tn->full_children = 1; - else - tn->empty_children = 1ul << bits; - } - - pr_debug("AT %p s=%zu %zu\n", tn, TNODE_SIZE(0), + pr_debug("AT %p s=%zu %zu\n", tnode, TNODE_SIZE(0), sizeof(struct key_vector *) << bits); + + if (!tnode) + return NULL; + + if (bits == KEYLENGTH) + tn->full_children = 1; + else + tn->empty_children = 1ul << bits; + + tn->key = (shift < KEYLENGTH) ? (key >> shift) << shift : 0; + tn->pos = pos; + tn->bits = bits; + tn->slen = pos; + return tn; } -- GitLab From 56ca2adf6ac1fca57f504ac1d76f7dff1dc08d3a Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Fri, 6 Mar 2015 09:54:33 -0800 Subject: [PATCH 03080/11651] fib_trie: Move rcu from key_vector to tnode, add accessors. RCU is only needed once for the entire node, not once per key_vector so we can pull that out and move it to the tnode structure. In addition add accessors to be used inside the RCU functions so that we can more easily get from the key vector to either the tnode or the trie pointers. Signed-off-by: Alexander Duyck Signed-off-by: David S. Miller --- net/ipv4/fib_trie.c | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 3a062370fc32..b9b5bbacace6 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -93,8 +93,6 @@ typedef unsigned int t_key; #define IS_LEAF(n) (!(n)->bits) struct key_vector { - struct rcu_head rcu; - t_key empty_children; /* KEYLENGTH bits needed */ t_key full_children; /* KEYLENGTH bits needed */ struct key_vector __rcu *parent; @@ -112,7 +110,9 @@ struct key_vector { }; struct tnode { + struct rcu_head rcu; struct key_vector kv[1]; +#define tn_bits kv[0].bits }; #define TNODE_SIZE(n) offsetof(struct tnode, kv[0].tnode[n]) @@ -159,6 +159,11 @@ static const int sync_pages = 128; static struct kmem_cache *fn_alias_kmem __read_mostly; static struct kmem_cache *trie_leaf_kmem __read_mostly; +static inline struct tnode *tn_info(struct key_vector *kv) +{ + return container_of(kv, struct tnode, kv[0]); +} + /* caller must hold RTNL */ #define node_parent(n) rtnl_dereference((n)->parent) #define get_child(tn, i) rtnl_dereference((tn)->tnode[i]) @@ -191,13 +196,6 @@ static inline unsigned long get_index(t_key key, struct key_vector *kv) return index >> kv->pos; } -static inline struct fib_table *trie_get_table(struct trie *t) -{ - unsigned long *tb_data = (unsigned long *)t; - - return container_of(tb_data, struct fib_table, tb_data[0]); -} - /* To understand this stuff, an understanding of keys and all their bits is * necessary. Every node in the trie has a key associated with it, but not * all of the bits in that key are significant. @@ -280,17 +278,17 @@ static inline void alias_free_mem_rcu(struct fib_alias *fa) static void __node_free_rcu(struct rcu_head *head) { - struct key_vector *n = container_of(head, struct key_vector, rcu); + struct tnode *n = container_of(head, struct tnode, rcu); - if (IS_LEAF(n)) + if (!n->tn_bits) kmem_cache_free(trie_leaf_kmem, n); - else if (n->bits <= TNODE_KMALLOC_MAX) + else if (n->tn_bits <= TNODE_KMALLOC_MAX) kfree(n); else vfree(n); } -#define node_free(n) call_rcu(&n->rcu, __node_free_rcu) +#define node_free(n) call_rcu(&tn_info(n)->rcu, __node_free_rcu) static struct tnode *tnode_alloc(int bits) { @@ -441,26 +439,26 @@ static inline void put_child_root(struct key_vector *tp, struct trie *t, static inline void tnode_free_init(struct key_vector *tn) { - tn->rcu.next = NULL; + tn_info(tn)->rcu.next = NULL; } static inline void tnode_free_append(struct key_vector *tn, struct key_vector *n) { - n->rcu.next = tn->rcu.next; - tn->rcu.next = &n->rcu; + tn_info(n)->rcu.next = tn_info(tn)->rcu.next; + tn_info(tn)->rcu.next = &tn_info(n)->rcu; } static void tnode_free(struct key_vector *tn) { - struct callback_head *head = &tn->rcu; + struct callback_head *head = &tn_info(tn)->rcu; while (head) { head = head->next; tnode_free_size += TNODE_SIZE(1ul << tn->bits); node_free(tn); - tn = container_of(head, struct key_vector, rcu); + tn = container_of(head, struct tnode, rcu)->kv; } if (tnode_free_size >= PAGE_SIZE * sync_pages) { -- GitLab From 6e22d174ba29a04dfd66e9be3fa9b5fad1278001 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Fri, 6 Mar 2015 09:54:39 -0800 Subject: [PATCH 03081/11651] fib_trie: Pull empty_children and full_children into tnode This pulls the information about the child array out of the key_vector and places it in the tnode since that is where it is needed. Signed-off-by: Alexander Duyck Signed-off-by: David S. Miller --- net/ipv4/fib_trie.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index b9b5bbacace6..acbed2d5347d 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -93,8 +93,6 @@ typedef unsigned int t_key; #define IS_LEAF(n) (!(n)->bits) struct key_vector { - t_key empty_children; /* KEYLENGTH bits needed */ - t_key full_children; /* KEYLENGTH bits needed */ struct key_vector __rcu *parent; t_key key; @@ -111,6 +109,8 @@ struct key_vector { struct tnode { struct rcu_head rcu; + t_key empty_children; /* KEYLENGTH bits needed */ + t_key full_children; /* KEYLENGTH bits needed */ struct key_vector kv[1]; #define tn_bits kv[0].bits }; @@ -309,12 +309,12 @@ static struct tnode *tnode_alloc(int bits) static inline void empty_child_inc(struct key_vector *n) { - ++n->empty_children ? : ++n->full_children; + ++tn_info(n)->empty_children ? : ++tn_info(n)->full_children; } static inline void empty_child_dec(struct key_vector *n) { - n->empty_children-- ? : n->full_children--; + tn_info(n)->empty_children-- ? : tn_info(n)->full_children--; } static struct key_vector *leaf_new(t_key key, struct fib_alias *fa) @@ -354,9 +354,9 @@ static struct key_vector *tnode_new(t_key key, int pos, int bits) return NULL; if (bits == KEYLENGTH) - tn->full_children = 1; + tnode->full_children = 1; else - tn->empty_children = 1ul << bits; + tnode->empty_children = 1ul << bits; tn->key = (shift < KEYLENGTH) ? (key >> shift) << shift : 0; tn->pos = pos; @@ -396,9 +396,9 @@ static void put_child(struct key_vector *tn, unsigned long i, isfull = tnode_full(tn, n); if (wasfull && !isfull) - tn->full_children--; + tn_info(tn)->full_children--; else if (!wasfull && isfull) - tn->full_children++; + tn_info(tn)->full_children++; if (n && (tn->slen < n->slen)) tn->slen = n->slen; @@ -768,8 +768,8 @@ static inline bool should_inflate(struct key_vector *tp, struct key_vector *tn) /* Keep root node larger */ threshold *= tp ? inflate_threshold : inflate_threshold_root; - used -= tn->empty_children; - used += tn->full_children; + used -= tn_info(tn)->empty_children; + used += tn_info(tn)->full_children; /* if bits == KEYLENGTH then pos = 0, and will fail below */ @@ -783,7 +783,7 @@ static inline bool should_halve(struct key_vector *tp, struct key_vector *tn) /* Keep root node larger */ threshold *= tp ? halve_threshold : halve_threshold_root; - used -= tn->empty_children; + used -= tn_info(tn)->empty_children; /* if bits == KEYLENGTH then used = 100% on wrap, and will fail below */ @@ -794,10 +794,10 @@ static inline bool should_collapse(struct key_vector *tn) { unsigned long used = child_length(tn); - used -= tn->empty_children; + used -= tn_info(tn)->empty_children; /* account for bits == KEYLENGTH case */ - if ((tn->bits == KEYLENGTH) && tn->full_children) + if ((tn->bits == KEYLENGTH) && tn_info(tn)->full_children) used -= KEY_MAX; /* One child or none, time to drop us from the trie */ @@ -1963,7 +1963,7 @@ static void trie_collect_stats(struct trie *t, struct trie_stat *s) s->tnodes++; if (n->bits < MAX_STAT_DEPTH) s->nodesizes[n->bits]++; - s->nullpointers += n->empty_children; + s->nullpointers += tn_info(n)->empty_children; } } rcu_read_unlock(); @@ -2238,7 +2238,8 @@ static int fib_trie_seq_show(struct seq_file *seq, void *v) seq_indent(seq, iter->depth-1); seq_printf(seq, " +-- %pI4/%zu %u %u %u\n", &prf, KEYLENGTH - n->pos - n->bits, n->bits, - n->full_children, n->empty_children); + tn_info(n)->full_children, + tn_info(n)->empty_children); } else { __be32 val = htonl(n->key); struct fib_alias *fa; -- GitLab From f23e59fbd77054d9e555ef398bb918320f9319e2 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Fri, 6 Mar 2015 09:54:46 -0800 Subject: [PATCH 03082/11651] fib_trie: Move parent from key_vector to tnode This change pulls the parent pointer from the key_vector and places it in the tnode structure. Signed-off-by: Alexander Duyck Signed-off-by: David S. Miller --- net/ipv4/fib_trie.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index acbed2d5347d..b5fed2f5ef9e 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -93,8 +93,6 @@ typedef unsigned int t_key; #define IS_LEAF(n) (!(n)->bits) struct key_vector { - struct key_vector __rcu *parent; - t_key key; unsigned char pos; /* 2log(KEYLENGTH) bits needed */ unsigned char bits; /* 2log(KEYLENGTH) bits needed */ @@ -111,6 +109,7 @@ struct tnode { struct rcu_head rcu; t_key empty_children; /* KEYLENGTH bits needed */ t_key full_children; /* KEYLENGTH bits needed */ + struct key_vector __rcu *parent; struct key_vector kv[1]; #define tn_bits kv[0].bits }; @@ -165,21 +164,21 @@ static inline struct tnode *tn_info(struct key_vector *kv) } /* caller must hold RTNL */ -#define node_parent(n) rtnl_dereference((n)->parent) +#define node_parent(tn) rtnl_dereference(tn_info(tn)->parent) #define get_child(tn, i) rtnl_dereference((tn)->tnode[i]) /* caller must hold RCU read lock or RTNL */ -#define node_parent_rcu(n) rcu_dereference_rtnl((n)->parent) +#define node_parent_rcu(tn) rcu_dereference_rtnl(tn_info(tn)->parent) #define get_child_rcu(tn, i) rcu_dereference_rtnl((tn)->tnode[i]) /* wrapper for rcu_assign_pointer */ static inline void node_set_parent(struct key_vector *n, struct key_vector *tp) { if (n) - rcu_assign_pointer(n->parent, tp); + rcu_assign_pointer(tn_info(n)->parent, tp); } -#define NODE_INIT_PARENT(n, p) RCU_INIT_POINTER((n)->parent, p) +#define NODE_INIT_PARENT(n, p) RCU_INIT_POINTER(tn_info(n)->parent, p) /* This provides us with the number of children in this node, in the case of a * leaf this will return 0 meaning none of the children are accessible. -- GitLab From 88bae7149a5e980dc5a7488fba2fcb41286fd82e Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Fri, 6 Mar 2015 09:54:52 -0800 Subject: [PATCH 03083/11651] fib_trie: Add key vector to root, return parent key_vector in resize This change makes it so that the root of the trie contains a key_vector, by doing this we make room to essentially collapse the entire trie by at least one cache line as we can store the information about the tnode or leaf that is pointed to in the root. Signed-off-by: Alexander Duyck Signed-off-by: David S. Miller --- net/ipv4/fib_trie.c | 433 ++++++++++++++++++++------------------------ 1 file changed, 201 insertions(+), 232 deletions(-) diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index b5fed2f5ef9e..90955455884e 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -89,8 +89,9 @@ typedef unsigned int t_key; -#define IS_TNODE(n) ((n)->bits) -#define IS_LEAF(n) (!(n)->bits) +#define IS_TRIE(n) ((n)->pos >= KEYLENGTH) +#define IS_TNODE(n) ((n)->bits) +#define IS_LEAF(n) (!(n)->bits) struct key_vector { t_key key; @@ -139,13 +140,13 @@ struct trie_stat { }; struct trie { - struct key_vector __rcu *tnode[1]; + struct key_vector kv[1]; #ifdef CONFIG_IP_FIB_TRIE_STATS struct trie_use_stats __percpu *stats; #endif }; -static struct key_vector **resize(struct trie *t, struct key_vector *tn); +static struct key_vector *resize(struct trie *t, struct key_vector *tn); static size_t tnode_free_size; /* @@ -188,10 +189,15 @@ static inline unsigned long child_length(const struct key_vector *tn) return (1ul << tn->bits) & ~(1ul); } +#define get_cindex(key, kv) (((key) ^ (kv)->key) >> (kv)->pos) + static inline unsigned long get_index(t_key key, struct key_vector *kv) { unsigned long index = key ^ kv->key; + if ((BITS_PER_LONG <= KEYLENGTH) && (KEYLENGTH == kv->pos)) + return 0; + return index >> kv->pos; } @@ -427,13 +433,13 @@ static void update_children(struct key_vector *tn) } } -static inline void put_child_root(struct key_vector *tp, struct trie *t, - t_key key, struct key_vector *n) +static inline void put_child_root(struct key_vector *tp, t_key key, + struct key_vector *n) { - if (tp) - put_child(tp, get_index(key, tp), n); + if (IS_TRIE(tp)) + rcu_assign_pointer(tp->tnode[0], n); else - rcu_assign_pointer(t->tnode[0], n); + put_child(tp, get_index(key, tp), n); } static inline void tnode_free_init(struct key_vector *tn) @@ -466,17 +472,16 @@ static void tnode_free(struct key_vector *tn) } } -static struct key_vector __rcu **replace(struct trie *t, - struct key_vector *oldtnode, - struct key_vector *tn) +static struct key_vector *replace(struct trie *t, + struct key_vector *oldtnode, + struct key_vector *tn) { struct key_vector *tp = node_parent(oldtnode); - struct key_vector **cptr; unsigned long i; /* setup the parent pointer out of and back into this node */ NODE_INIT_PARENT(tn, tp); - put_child_root(tp, t, tn->key, tn); + put_child_root(tp, tn->key, tn); /* update all of the child parent pointers */ update_children(tn); @@ -484,23 +489,20 @@ static struct key_vector __rcu **replace(struct trie *t, /* all pointers should be clean so we are done */ tnode_free(oldtnode); - /* record the pointer that is pointing to this node */ - cptr = tp ? tp->tnode : t->tnode; - /* resize children now that oldtnode is freed */ for (i = child_length(tn); i;) { struct key_vector *inode = get_child(tn, --i); /* resize child node */ if (tnode_full(tn, inode)) - resize(t, inode); + tn = resize(t, inode); } - return cptr; + return tp; } -static struct key_vector __rcu **inflate(struct trie *t, - struct key_vector *oldtnode) +static struct key_vector *inflate(struct trie *t, + struct key_vector *oldtnode) { struct key_vector *tn; unsigned long i; @@ -595,8 +597,8 @@ notnode: return NULL; } -static struct key_vector __rcu **halve(struct trie *t, - struct key_vector *oldtnode) +static struct key_vector *halve(struct trie *t, + struct key_vector *oldtnode) { struct key_vector *tn; unsigned long i; @@ -650,7 +652,8 @@ notnode: return NULL; } -static void collapse(struct trie *t, struct key_vector *oldtnode) +static struct key_vector *collapse(struct trie *t, + struct key_vector *oldtnode) { struct key_vector *n, *tp; unsigned long i; @@ -661,11 +664,13 @@ static void collapse(struct trie *t, struct key_vector *oldtnode) /* compress one level */ tp = node_parent(oldtnode); - put_child_root(tp, t, oldtnode->key, n); + put_child_root(tp, oldtnode->key, n); node_set_parent(n, tp); /* drop dead node */ node_free(oldtnode); + + return tp; } static unsigned char update_suffix(struct key_vector *tn) @@ -766,7 +771,7 @@ static inline bool should_inflate(struct key_vector *tp, struct key_vector *tn) unsigned long threshold = used; /* Keep root node larger */ - threshold *= tp ? inflate_threshold : inflate_threshold_root; + threshold *= IS_TRIE(tp) ? inflate_threshold_root : inflate_threshold; used -= tn_info(tn)->empty_children; used += tn_info(tn)->full_children; @@ -781,7 +786,7 @@ static inline bool should_halve(struct key_vector *tp, struct key_vector *tn) unsigned long threshold = used; /* Keep root node larger */ - threshold *= tp ? halve_threshold : halve_threshold_root; + threshold *= IS_TRIE(tp) ? halve_threshold_root : halve_threshold; used -= tn_info(tn)->empty_children; /* if bits == KEYLENGTH then used = 100% on wrap, and will fail below */ @@ -804,15 +809,13 @@ static inline bool should_collapse(struct key_vector *tn) } #define MAX_WORK 10 -static struct key_vector __rcu **resize(struct trie *t, - struct key_vector *tn) +static struct key_vector *resize(struct trie *t, struct key_vector *tn) { #ifdef CONFIG_IP_FIB_TRIE_STATS struct trie_use_stats __percpu *stats = t->stats; #endif struct key_vector *tp = node_parent(tn); - unsigned long cindex = tp ? get_index(tn->key, tp) : 0; - struct key_vector __rcu **cptr = tp ? tp->tnode : t->tnode; + unsigned long cindex = get_index(tn->key, tp); int max_work = MAX_WORK; pr_debug("In tnode_resize %p inflate_threshold=%d threshold=%d\n", @@ -822,15 +825,14 @@ static struct key_vector __rcu **resize(struct trie *t, * doing it ourselves. This way we can let RCU fully do its * thing without us interfering */ - BUG_ON(tn != rtnl_dereference(cptr[cindex])); + BUG_ON(tn != get_child(tp, cindex)); /* Double as long as the resulting node has a number of * nonempty nodes that are above the threshold. */ while (should_inflate(tp, tn) && max_work) { - struct key_vector __rcu **tcptr = inflate(t, tn); - - if (!tcptr) { + tp = inflate(t, tn); + if (!tp) { #ifdef CONFIG_IP_FIB_TRIE_STATS this_cpu_inc(stats->resize_node_skipped); #endif @@ -838,21 +840,19 @@ static struct key_vector __rcu **resize(struct trie *t, } max_work--; - cptr = tcptr; - tn = rtnl_dereference(cptr[cindex]); + tn = get_child(tp, cindex); } /* Return if at least one inflate is run */ if (max_work != MAX_WORK) - return cptr; + return node_parent(tn); /* Halve as long as the number of empty children in this * node is above threshold. */ while (should_halve(tp, tn) && max_work) { - struct key_vector __rcu **tcptr = halve(t, tn); - - if (!tcptr) { + tp = halve(t, tn); + if (!tp) { #ifdef CONFIG_IP_FIB_TRIE_STATS this_cpu_inc(stats->resize_node_skipped); #endif @@ -860,34 +860,34 @@ static struct key_vector __rcu **resize(struct trie *t, } max_work--; - cptr = tcptr; - tn = rtnl_dereference(cptr[cindex]); + tn = get_child(tp, cindex); } /* Only one child remains */ - if (should_collapse(tn)) { - collapse(t, tn); - return cptr; - } + if (should_collapse(tn)) + return collapse(t, tn); + + /* update parent in case inflate or halve failed */ + tp = node_parent(tn); /* Return if at least one deflate was run */ if (max_work != MAX_WORK) - return cptr; + return tp; /* push the suffix length to the parent node */ if (tn->slen > tn->pos) { unsigned char slen = update_suffix(tn); - if (tp && (slen > tp->slen)) + if (slen > tp->slen) tp->slen = slen; } - return cptr; + return tp; } static void leaf_pull_suffix(struct key_vector *tp, struct key_vector *l) { - while (tp && (tp->slen > tp->pos) && (tp->slen > l->slen)) { + while ((tp->slen > tp->pos) && (tp->slen > l->slen)) { if (update_suffix(tp) > l->slen) break; tp = node_parent(tp); @@ -899,7 +899,7 @@ static void leaf_push_suffix(struct key_vector *tn, struct key_vector *l) /* if this is a new leaf then tn will be NULL and we can sort * out parent suffix lengths as a part of trie_rebalance */ - while (tn && (tn->slen < l->slen)) { + while (tn->slen < l->slen) { tn->slen = l->slen; tn = node_parent(tn); } @@ -909,10 +909,17 @@ static void leaf_push_suffix(struct key_vector *tn, struct key_vector *l) static struct key_vector *fib_find_node(struct trie *t, struct key_vector **tp, u32 key) { - struct key_vector *pn = NULL, *n = rcu_dereference_rtnl(t->tnode[0]); + struct key_vector *pn, *n = t->kv; + unsigned long index = 0; + + do { + pn = n; + n = get_child_rcu(n, index); + + if (!n) + break; - while (n) { - unsigned long index = get_index(key, n); + index = get_cindex(key, n); /* This bit of code is a bit tricky but it combines multiple * checks into a single check. The prefix consists of the @@ -933,13 +940,8 @@ static struct key_vector *fib_find_node(struct trie *t, break; } - /* we have found a leaf. Prefixes have already been compared */ - if (IS_LEAF(n)) - break; - - pn = n; - n = get_child_rcu(n, index); - } + /* keep searching until we find a perfect match leaf or NULL */ + } while (IS_TNODE(n)); *tp = pn; @@ -973,16 +975,8 @@ static struct fib_alias *fib_find_alias(struct hlist_head *fah, u8 slen, static void trie_rebalance(struct trie *t, struct key_vector *tn) { - struct key_vector __rcu **cptr = t->tnode; - - while (tn) { - struct key_vector *tp = node_parent(tn); - - cptr = resize(t, tn); - if (!tp) - break; - tn = container_of(cptr, struct key_vector, tnode[0]); - } + while (!IS_TRIE(tn)) + tn = resize(t, tn); } static int fib_insert_node(struct trie *t, struct key_vector *tp, @@ -995,10 +989,7 @@ static int fib_insert_node(struct trie *t, struct key_vector *tp, goto noleaf; /* retrieve child from parent node */ - if (tp) - n = get_child(tp, get_index(key, tp)); - else - n = rcu_dereference_rtnl(t->tnode[0]); + n = get_child(tp, get_index(key, tp)); /* Case 2: n is a LEAF or a TNODE and the key doesn't match. * @@ -1018,7 +1009,7 @@ static int fib_insert_node(struct trie *t, struct key_vector *tp, put_child(tn, get_index(key, tn) ^ 1, n); /* start adding routes into the node */ - put_child_root(tp, t, key, tn); + put_child_root(tp, key, tn); node_set_parent(n, tn); /* parent now has a NULL spot where the leaf can go */ @@ -1027,7 +1018,7 @@ static int fib_insert_node(struct trie *t, struct key_vector *tp, /* Case 3: n is NULL, and will just insert a new leaf */ NODE_INIT_PARENT(l, tp); - put_child_root(tp, t, key, l); + put_child_root(tp, key, l); trie_rebalance(t, tp); return 0; @@ -1261,7 +1252,10 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi4 *flp, unsigned long index; t_key cindex; - n = rcu_dereference(t->tnode[0]); + pn = t->kv; + cindex = 0; + + n = get_child_rcu(pn, cindex); if (!n) return -EAGAIN; @@ -1269,12 +1263,9 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi4 *flp, this_cpu_inc(stats->gets); #endif - pn = n; - cindex = 0; - /* Step 1: Travel to the longest prefix match in the trie */ for (;;) { - index = get_index(key, n); + index = get_cindex(key, n); /* This bit of code is a bit tricky but it combines multiple * checks into a single check. The prefix consists of the @@ -1345,13 +1336,17 @@ backtrace: while (!cindex) { t_key pkey = pn->key; - pn = node_parent_rcu(pn); - if (unlikely(!pn)) + /* If we don't have a parent then there is + * nothing for us to do as we do not have any + * further nodes to parse. + */ + if (IS_TRIE(pn)) return -EAGAIN; #ifdef CONFIG_IP_FIB_TRIE_STATS this_cpu_inc(stats->backtrack); #endif /* Get Child's index */ + pn = node_parent_rcu(pn); cindex = get_index(pkey, pn); } @@ -1436,7 +1431,7 @@ static void fib_remove_alias(struct trie *t, struct key_vector *tp, * out parent suffix lengths as a part of trie_rebalance */ if (hlist_empty(&l->leaf)) { - put_child_root(tp, t, l->key, NULL); + put_child_root(tp, l->key, NULL); node_free(l); trie_rebalance(t, tp); return; @@ -1528,38 +1523,32 @@ static struct key_vector *leaf_walk_rcu(struct key_vector **tn, t_key key) struct key_vector *pn, *n = *tn; unsigned long cindex; - /* record parent node for backtracing */ - pn = n; - cindex = n ? get_index(key, n) : 0; - /* this loop is meant to try and find the key in the trie */ - while (n) { - unsigned long idx = get_index(key, n); - - /* guarantee forward progress on the keys */ - if (IS_LEAF(n) && (n->key >= key)) - goto found; - if (idx >= (1ul << n->bits)) - break; - + do { /* record parent and next child index */ pn = n; - cindex = idx; + cindex = get_index(key, pn); + + if (cindex >> pn->bits) + break; /* descend into the next child */ n = get_child_rcu(pn, cindex++); - } + if (!n) + break; + + /* guarantee forward progress on the keys */ + if (IS_LEAF(n) && (n->key >= key)) + goto found; + } while (IS_TNODE(n)); /* this loop will search for the next leaf with a greater key */ - while (pn) { + while (!IS_TRIE(pn)) { /* if we exhausted the parent node we will need to climb */ if (cindex >= (1ul << pn->bits)) { t_key pkey = pn->key; pn = node_parent_rcu(pn); - if (!pn) - break; - cindex = get_index(pkey, pn) + 1; continue; } @@ -1582,7 +1571,7 @@ static struct key_vector *leaf_walk_rcu(struct key_vector **tn, t_key key) return NULL; /* Root of trie */ found: /* if we are at the limit for keys just return NULL for the tnode */ - *tn = (n->key == KEY_MAX) ? NULL : pn; + *tn = pn; return n; } @@ -1590,113 +1579,106 @@ found: void fib_table_flush_external(struct fib_table *tb) { struct trie *t = (struct trie *)tb->tb_data; + struct key_vector *pn = t->kv; + unsigned long cindex = 1; + struct hlist_node *tmp; struct fib_alias *fa; - struct key_vector *n, *pn; - unsigned long cindex; - n = rcu_dereference(t->tnode[0]); - if (!n) - return; + /* walk trie in reverse order */ + for (;;) { + struct key_vector *n; - pn = NULL; - cindex = 0; + if (!(cindex--)) { + t_key pkey = pn->key; - while (IS_TNODE(n)) { - /* record pn and cindex for leaf walking */ - pn = n; - cindex = 1ul << n->bits; -backtrace: - /* walk trie in reverse order */ - do { - while (!(cindex--)) { - t_key pkey = pn->key; + /* cannot resize the trie vector */ + if (IS_TRIE(pn)) + break; - /* if we got the root we are done */ - pn = node_parent(pn); - if (!pn) - return; + /* no need to resize like in flush below */ + pn = node_parent(pn); + cindex = get_index(pkey, pn); - cindex = get_index(pkey, pn); - } + continue; + } - /* grab the next available node */ - n = get_child(pn, cindex); - } while (!n); - } + /* grab the next available node */ + n = get_child(pn, cindex); + if (!n) + continue; - hlist_for_each_entry(fa, &n->leaf, fa_list) { - struct fib_info *fi = fa->fa_info; + if (IS_TNODE(n)) { + /* record pn and cindex for leaf walking */ + pn = n; + cindex = 1ul << n->bits; - if (!fi || !(fi->fib_flags & RTNH_F_EXTERNAL)) continue; + } - netdev_switch_fib_ipv4_del(n->key, - KEYLENGTH - fa->fa_slen, - fi, fa->fa_tos, - fa->fa_type, tb->tb_id); - } + hlist_for_each_entry_safe(fa, tmp, &n->leaf, fa_list) { + struct fib_info *fi = fa->fa_info; + + if (!fi || !(fi->fib_flags & RTNH_F_EXTERNAL)) + continue; - /* if trie is leaf only loop is completed */ - if (pn) - goto backtrace; + netdev_switch_fib_ipv4_del(n->key, + KEYLENGTH - fa->fa_slen, + fi, fa->fa_tos, + fa->fa_type, tb->tb_id); + } + } } /* Caller must hold RTNL. */ int fib_table_flush(struct fib_table *tb) { struct trie *t = (struct trie *)tb->tb_data; - struct key_vector *n, *pn; + struct key_vector *pn = t->kv; + unsigned long cindex = 1; struct hlist_node *tmp; struct fib_alias *fa; - unsigned long cindex; - unsigned char slen; int found = 0; - n = rcu_dereference(t->tnode[0]); - if (!n) - goto flush_complete; + /* walk trie in reverse order */ + for (;;) { + unsigned char slen = 0; + struct key_vector *n; - pn = NULL; - cindex = 0; + if (!(cindex--)) { + t_key pkey = pn->key; - while (IS_TNODE(n)) { - /* record pn and cindex for leaf walking */ - pn = n; - cindex = 1ul << n->bits; -backtrace: - /* walk trie in reverse order */ - do { - while (!(cindex--)) { - struct key_vector __rcu **cptr; - t_key pkey = pn->key; + /* cannot resize the trie vector */ + if (IS_TRIE(pn)) + break; - n = pn; - pn = node_parent(n); + /* resize completed node */ + pn = resize(t, pn); + cindex = get_index(pkey, pn); - /* resize completed node */ - cptr = resize(t, n); + continue; + } - /* if we got the root we are done */ - if (!pn) - goto flush_complete; + /* grab the next available node */ + n = get_child(pn, cindex); + if (!n) + continue; - pn = container_of(cptr, struct key_vector, - tnode[0]); - cindex = get_index(pkey, pn); - } + if (IS_TNODE(n)) { + /* record pn and cindex for leaf walking */ + pn = n; + cindex = 1ul << n->bits; - /* grab the next available node */ - n = get_child(pn, cindex); - } while (!n); - } + continue; + } - /* track slen in case any prefixes survive */ - slen = 0; + hlist_for_each_entry_safe(fa, tmp, &n->leaf, fa_list) { + struct fib_info *fi = fa->fa_info; - hlist_for_each_entry_safe(fa, tmp, &n->leaf, fa_list) { - struct fib_info *fi = fa->fa_info; + if (!fi || !(fi->fib_flags & RTNH_F_DEAD)) { + slen = fa->fa_slen; + continue; + } - if (fi && (fi->fib_flags & RTNH_F_DEAD)) { netdev_switch_fib_ipv4_del(n->key, KEYLENGTH - fa->fa_slen, fi, fa->fa_tos, @@ -1705,27 +1687,19 @@ backtrace: fib_release_info(fa->fa_info); alias_free_mem_rcu(fa); found++; - - continue; } - slen = fa->fa_slen; - } - - /* update leaf slen */ - n->slen = slen; + /* update leaf slen */ + n->slen = slen; - if (hlist_empty(&n->leaf)) { - put_child_root(pn, t, n->key, NULL); - node_free(n); - } else { - leaf_pull_suffix(pn, n); + if (hlist_empty(&n->leaf)) { + put_child_root(pn, n->key, NULL); + node_free(n); + } else { + leaf_pull_suffix(pn, n); + } } - /* if trie is leaf only loop is completed */ - if (pn) - goto backtrace; -flush_complete: pr_debug("trie_flush found=%d\n", found); return found; } @@ -1787,15 +1761,13 @@ int fib_table_dump(struct fib_table *tb, struct sk_buff *skb, struct netlink_callback *cb) { struct trie *t = (struct trie *)tb->tb_data; - struct key_vector *l, *tp; + struct key_vector *l, *tp = t->kv; /* Dump starting at last key. * Note: 0.0.0.0/0 (ie default) is first key. */ int count = cb->args[2]; t_key key = cb->args[3]; - tp = rcu_dereference_rtnl(t->tnode[0]); - while ((l = leaf_walk_rcu(&tp, key)) != NULL) { if (fn_trie_dump_leaf(l, tb, skb, cb) < 0) { cb->args[3] = key; @@ -1831,14 +1803,12 @@ void __init fib_trie_init(void) 0, SLAB_PANIC, NULL); } - struct fib_table *fib_trie_table(u32 id) { struct fib_table *tb; struct trie *t; - tb = kmalloc(sizeof(struct fib_table) + sizeof(struct trie), - GFP_KERNEL); + tb = kzalloc(sizeof(*tb) + sizeof(struct trie), GFP_KERNEL); if (tb == NULL) return NULL; @@ -1847,7 +1817,8 @@ struct fib_table *fib_trie_table(u32 id) tb->tb_num_default = 0; t = (struct trie *) tb->tb_data; - RCU_INIT_POINTER(t->tnode[0], NULL); + t->kv[0].pos = KEYLENGTH; + t->kv[0].slen = KEYLENGTH; #ifdef CONFIG_IP_FIB_TRIE_STATS t->stats = alloc_percpu(struct trie_use_stats); if (!t->stats) { @@ -1872,57 +1843,55 @@ struct fib_trie_iter { static struct key_vector *fib_trie_get_next(struct fib_trie_iter *iter) { unsigned long cindex = iter->index; - struct key_vector *tn = iter->tnode; - struct key_vector *p; - - /* A single entry routing table */ - if (!tn) - return NULL; + struct key_vector *pn = iter->tnode; + t_key pkey; pr_debug("get_next iter={node=%p index=%d depth=%d}\n", iter->tnode, iter->index, iter->depth); -rescan: - while (cindex < child_length(tn)) { - struct key_vector *n = get_child_rcu(tn, cindex); - if (n) { + while (!IS_TRIE(pn)) { + while (cindex < child_length(pn)) { + struct key_vector *n = get_child_rcu(pn, cindex++); + + if (!n) + continue; + if (IS_LEAF(n)) { - iter->tnode = tn; - iter->index = cindex + 1; + iter->tnode = pn; + iter->index = cindex; } else { /* push down one level */ iter->tnode = n; iter->index = 0; ++iter->depth; } + return n; } - ++cindex; - } - - /* Current node exhausted, pop back up */ - p = node_parent_rcu(tn); - if (p) { - cindex = get_index(tn->key, p) + 1; - tn = p; + /* Current node exhausted, pop back up */ + pkey = pn->key; + pn = node_parent_rcu(pn); + cindex = get_index(pkey, pn) + 1; --iter->depth; - goto rescan; } - /* got root? */ + /* record root node so further searches know we are done */ + iter->tnode = pn; + iter->index = 0; + return NULL; } static struct key_vector *fib_trie_get_first(struct fib_trie_iter *iter, struct trie *t) { - struct key_vector *n; + struct key_vector *n, *pn = t->kv; if (!t) return NULL; - n = rcu_dereference(t->tnode[0]); + n = rcu_dereference(pn->tnode[0]); if (!n) return NULL; @@ -1931,7 +1900,7 @@ static struct key_vector *fib_trie_get_first(struct fib_trie_iter *iter, iter->index = 0; iter->depth = 1; } else { - iter->tnode = NULL; + iter->tnode = pn; iter->index = 0; iter->depth = 0; } @@ -2228,7 +2197,7 @@ static int fib_trie_seq_show(struct seq_file *seq, void *v) const struct fib_trie_iter *iter = seq->private; struct key_vector *n = v; - if (!node_parent_rcu(n)) + if (IS_TRIE(node_parent_rcu(n))) fib_table_print(seq, iter->tb); if (IS_TNODE(n)) { @@ -2308,7 +2277,7 @@ static struct key_vector *fib_route_get_idx(struct fib_route_iter *iter, key = iter->key; } else { t = (struct trie *)tb->tb_data; - iter->tnode = rcu_dereference_rtnl(t->tnode[0]); + iter->tnode = t->kv; iter->pos = 0; key = 0; } @@ -2354,7 +2323,7 @@ static void *fib_route_seq_start(struct seq_file *seq, loff_t *pos) return fib_route_get_idx(iter, *pos); t = (struct trie *)tb->tb_data; - iter->tnode = rcu_dereference_rtnl(t->tnode[0]); + iter->tnode = t->kv; iter->pos = 0; iter->key = 0; -- GitLab From 3fe0607a04ed7deea7c048052fd63b8670e7a176 Mon Sep 17 00:00:00 2001 From: "Lu, Han" Date: Wed, 25 Feb 2015 08:26:21 +0800 Subject: [PATCH 03084/11651] ASoC: Intel: remove conflicts when load/unload multiple firmware images Details: 1. Unload all modules on fw_list of dsp when suspend, and reload all modules on fw_list when resume. 2. A DSP expects only one scratch, but hsw_parse_fw_image() allocates scratch blocks for each firmware image it parses. Move the allocate function sst_block_alloc_scratch() out of hsw_parse_fw_image() to make sure a scratch be allocated only after all firmware images be parsed. Signed-off-by: Lu, Han Signed-off-by: Mark Brown --- sound/soc/intel/sst-haswell-dsp.c | 3 --- sound/soc/intel/sst-haswell-ipc.c | 32 +++++++++++++++++++++++-------- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/sound/soc/intel/sst-haswell-dsp.c b/sound/soc/intel/sst-haswell-dsp.c index 57039b00efc2..f6e1e6b2b18e 100644 --- a/sound/soc/intel/sst-haswell-dsp.c +++ b/sound/soc/intel/sst-haswell-dsp.c @@ -207,9 +207,6 @@ static int hsw_parse_fw_image(struct sst_fw *sst_fw) module = (void *)module + sizeof(*module) + module->mod_size; } - /* allocate scratch mem regions */ - sst_block_alloc_scratch(dsp); - return 0; } diff --git a/sound/soc/intel/sst-haswell-ipc.c b/sound/soc/intel/sst-haswell-ipc.c index 8156cc1accb7..6c7052a40e36 100644 --- a/sound/soc/intel/sst-haswell-ipc.c +++ b/sound/soc/intel/sst-haswell-ipc.c @@ -1870,6 +1870,7 @@ static void sst_hsw_drop_all(struct sst_hsw *hsw) int sst_hsw_dsp_load(struct sst_hsw *hsw) { struct sst_dsp *dsp = hsw->dsp; + struct sst_fw *sst_fw, *t; int ret; dev_dbg(hsw->dev, "loading audio DSP...."); @@ -1886,12 +1887,17 @@ int sst_hsw_dsp_load(struct sst_hsw *hsw) return ret; } - ret = sst_fw_reload(hsw->sst_fw); - if (ret < 0) { - dev_err(hsw->dev, "error: SST FW reload failed\n"); - sst_dsp_dma_put_channel(dsp); - return -ENOMEM; + list_for_each_entry_safe_reverse(sst_fw, t, &dsp->fw_list, list) { + ret = sst_fw_reload(sst_fw); + if (ret < 0) { + dev_err(hsw->dev, "error: SST FW reload failed\n"); + sst_dsp_dma_put_channel(dsp); + return -ENOMEM; + } } + ret = sst_block_alloc_scratch(hsw->dsp); + if (ret < 0) + return -EINVAL; sst_dsp_dma_put_channel(dsp); return 0; @@ -1947,12 +1953,17 @@ int sst_hsw_dsp_runtime_suspend(struct sst_hsw *hsw) int sst_hsw_dsp_runtime_sleep(struct sst_hsw *hsw) { - sst_fw_unload(hsw->sst_fw); - sst_block_free_scratch(hsw->dsp); + struct sst_fw *sst_fw, *t; + struct sst_dsp *dsp = hsw->dsp; + + list_for_each_entry_safe(sst_fw, t, &dsp->fw_list, list) { + sst_fw_unload(sst_fw); + } + sst_block_free_scratch(dsp); hsw->boot_complete = false; - sst_dsp_sleep(hsw->dsp); + sst_dsp_sleep(dsp); return 0; } @@ -2081,6 +2092,11 @@ int sst_hsw_dsp_init(struct device *dev, struct sst_pdata *pdata) goto fw_err; } + /* allocate scratch mem regions */ + ret = sst_block_alloc_scratch(hsw->dsp); + if (ret < 0) + goto boot_err; + /* wait for DSP boot completion */ sst_dsp_boot(hsw->dsp); ret = wait_event_timeout(hsw->boot_wait, hsw->boot_complete, -- GitLab From 62dfd912ab3b5405b6fe72d0135c37e9648071f1 Mon Sep 17 00:00:00 2001 From: "jmlatten@linux.vnet.ibm.com" Date: Fri, 20 Feb 2015 18:11:24 -0600 Subject: [PATCH 03085/11651] tpm/ibmvtpm: Additional LE support for tpm_ibmvtpm_send Problem: When IMA and VTPM are both enabled in kernel config, kernel hangs during bootup on LE OS. Why?: IMA calls tpm_pcr_read() which results in tpm_ibmvtpm_send and tpm_ibmtpm_recv getting called. A trace showed that tpm_ibmtpm_recv was hanging. Resolution: tpm_ibmtpm_recv was hanging because tpm_ibmvtpm_send was sending CRQ message that probably did not make much sense to phype because of Endianness. The fix below sends correctly converted CRQ for LE. This was not caught before because it seems IMA is not enabled by default in kernel config and IMA exercises this particular code path in vtpm. Tested with IMA and VTPM enabled in kernel config and VTPM enabled on both a BE OS and a LE OS ppc64 lpar. This exercised CRQ and TPM command code paths in vtpm. Patch is against Peter's tpmdd tree on github which included Vicky's previous vtpm le patches. Signed-off-by: Joy Latten Cc: # eb71f8a5e33f: "Added Little Endian support to vtpm module" Cc: Reviewed-by: Ashley Lai Signed-off-by: Peter Huewe --- drivers/char/tpm/tpm_ibmvtpm.c | 10 +++++----- drivers/char/tpm/tpm_ibmvtpm.h | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/char/tpm/tpm_ibmvtpm.c b/drivers/char/tpm/tpm_ibmvtpm.c index b1e53e3aece5..42ffa5e7a1e0 100644 --- a/drivers/char/tpm/tpm_ibmvtpm.c +++ b/drivers/char/tpm/tpm_ibmvtpm.c @@ -124,7 +124,7 @@ static int tpm_ibmvtpm_send(struct tpm_chip *chip, u8 *buf, size_t count) { struct ibmvtpm_dev *ibmvtpm; struct ibmvtpm_crq crq; - u64 *word = (u64 *) &crq; + __be64 *word = (__be64 *)&crq; int rc; ibmvtpm = (struct ibmvtpm_dev *)TPM_VPRIV(chip); @@ -145,11 +145,11 @@ static int tpm_ibmvtpm_send(struct tpm_chip *chip, u8 *buf, size_t count) memcpy((void *)ibmvtpm->rtce_buf, (void *)buf, count); crq.valid = (u8)IBMVTPM_VALID_CMD; crq.msg = (u8)VTPM_TPM_COMMAND; - crq.len = (u16)count; - crq.data = ibmvtpm->rtce_dma_handle; + crq.len = cpu_to_be16(count); + crq.data = cpu_to_be32(ibmvtpm->rtce_dma_handle); - rc = ibmvtpm_send_crq(ibmvtpm->vdev, cpu_to_be64(word[0]), - cpu_to_be64(word[1])); + rc = ibmvtpm_send_crq(ibmvtpm->vdev, be64_to_cpu(word[0]), + be64_to_cpu(word[1])); if (rc != H_SUCCESS) { dev_err(ibmvtpm->dev, "tpm_ibmvtpm_send failed rc=%d\n", rc); rc = 0; diff --git a/drivers/char/tpm/tpm_ibmvtpm.h b/drivers/char/tpm/tpm_ibmvtpm.h index f595f14426bf..6af92890518f 100644 --- a/drivers/char/tpm/tpm_ibmvtpm.h +++ b/drivers/char/tpm/tpm_ibmvtpm.h @@ -22,9 +22,9 @@ struct ibmvtpm_crq { u8 valid; u8 msg; - u16 len; - u32 data; - u64 reserved; + __be16 len; + __be32 data; + __be64 reserved; } __attribute__((packed, aligned(8))); struct ibmvtpm_crq_queue { -- GitLab From 19913b6db3aa417d855318c9cf5b40fbc1f28e52 Mon Sep 17 00:00:00 2001 From: Jarkko Sakkinen Date: Sun, 1 Mar 2015 23:55:47 +0200 Subject: [PATCH 03086/11651] tpm: fix call order in tpm-chip.c - tpm_dev_add_device(): cdev_add() must be done before uevent is propagated in order to avoid races. - tpm_chip_register(): tpm_dev_add_device() must be done as the last step before exposing device to the user space in order to avoid races. In addition clarified description in tpm_chip_register(). Fixes: 313d21eeab92 ("tpm: device class for tpm") Fixes: afb5abc262e9 ("tpm: two-phase chip management functions") Signed-off-by: Jarkko Sakkinen Reviewed-by: Peter Huewe Signed-off-by: Peter Huewe --- drivers/char/tpm/tpm-chip.c | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c index 1d278ccd751f..e096e9cddb40 100644 --- a/drivers/char/tpm/tpm-chip.c +++ b/drivers/char/tpm/tpm-chip.c @@ -140,24 +140,24 @@ static int tpm_dev_add_device(struct tpm_chip *chip) { int rc; - rc = device_add(&chip->dev); + rc = cdev_add(&chip->cdev, chip->dev.devt, 1); if (rc) { dev_err(&chip->dev, - "unable to device_register() %s, major %d, minor %d, err=%d\n", + "unable to cdev_add() %s, major %d, minor %d, err=%d\n", chip->devname, MAJOR(chip->dev.devt), MINOR(chip->dev.devt), rc); + device_unregister(&chip->dev); return rc; } - rc = cdev_add(&chip->cdev, chip->dev.devt, 1); + rc = device_add(&chip->dev); if (rc) { dev_err(&chip->dev, - "unable to cdev_add() %s, major %d, minor %d, err=%d\n", + "unable to device_register() %s, major %d, minor %d, err=%d\n", chip->devname, MAJOR(chip->dev.devt), MINOR(chip->dev.devt), rc); - device_unregister(&chip->dev); return rc; } @@ -174,27 +174,17 @@ static void tpm_dev_del_device(struct tpm_chip *chip) * tpm_chip_register() - create a character device for the TPM chip * @chip: TPM chip to use. * - * Creates a character device for the TPM chip and adds sysfs interfaces for - * the device, PPI and TCPA. As the last step this function adds the - * chip to the list of TPM chips available for use. + * Creates a character device for the TPM chip and adds sysfs attributes for + * the device. As the last step this function adds the chip to the list of TPM + * chips available for in-kernel use. * - * NOTE: This function should be only called after the chip initialization - * is complete. - * - * Called from tpm_.c probe function only for devices - * the driver has determined it should claim. Prior to calling - * this function the specific probe function has called pci_enable_device - * upon errant exit from this function specific probe function should call - * pci_disable_device + * This function should be only called after the chip initialization is + * complete. */ int tpm_chip_register(struct tpm_chip *chip) { int rc; - rc = tpm_dev_add_device(chip); - if (rc) - return rc; - /* Populate sysfs for TPM1 devices. */ if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) { rc = tpm_sysfs_add_device(chip); @@ -208,6 +198,10 @@ int tpm_chip_register(struct tpm_chip *chip) chip->bios_dir = tpm_bios_log_setup(chip->devname); } + rc = tpm_dev_add_device(chip); + if (rc) + return rc; + /* Make the chip available. */ spin_lock(&driver_lock); list_add_rcu(&chip->list, &tpm_chip_list); -- GitLab From 015fdaa9f8edd89a456b3331088e1b77ebdad9d0 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Fri, 6 Mar 2015 11:14:42 -0500 Subject: [PATCH 03087/11651] HID: multitouch: add support of clickpads Touchpads that have only one button are called clickpads and should be advertised as such by the kernel. Signed-off-by: Benjamin Tissoires Tested-by: Jason Ekstrand Signed-off-by: Jiri Kosina --- drivers/hid/hid-multitouch.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index f65e78b46999..ef06dc30b9b1 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -116,6 +116,7 @@ struct mt_device { __u8 touches_by_report; /* how many touches are present in one report: * 1 means we should use a serial protocol * > 1 means hybrid (multitouch) protocol */ + __u8 buttons_count; /* number of physical buttons per touchpad */ bool serial_maybe; /* need to check for serial protocol */ bool curvalid; /* is the current contact valid? */ unsigned mt_flags; /* flags to pass to input-mt */ @@ -379,6 +380,10 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi, td->inputmode_value = MT_INPUTMODE_TOUCHPAD; } + /* count the buttons on touchpads */ + if ((usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON) + td->buttons_count++; + if (usage->usage_index) prev_usage = &field->usage[usage->usage_index - 1]; @@ -728,6 +733,10 @@ static void mt_touch_input_configured(struct hid_device *hdev, if (cls->quirks & MT_QUIRK_NOT_SEEN_MEANS_UP) td->mt_flags |= INPUT_MT_DROP_UNUSED; + /* check for clickpads */ + if ((td->mt_flags & INPUT_MT_POINTER) && (td->buttons_count == 1)) + __set_bit(INPUT_PROP_BUTTONPAD, input->propbit); + input_mt_init_slots(input, td->maxcontacts, td->mt_flags); td->mt_flags = 0; -- GitLab From 637473cf006fe4cd85aed0fb69b6c917d868ada2 Mon Sep 17 00:00:00 2001 From: Sharon Dvir Date: Thu, 22 Jan 2015 12:15:25 +0200 Subject: [PATCH 03088/11651] mod_devicetable: fix comment for match_flags Signed-off-by: Sharon Dvir Signed-off-by: Jiri Kosina --- include/linux/mod_devicetable.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index 745def862580..470a240f66a1 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -53,9 +53,9 @@ struct ieee1394_device_id { /** * struct usb_device_id - identifies USB devices for probing and hotplugging - * @match_flags: Bit mask controlling of the other fields are used to match - * against new devices. Any field except for driver_info may be used, - * although some only make sense in conjunction with other fields. + * @match_flags: Bit mask controlling which of the other fields are used to + * match against new devices. Any field except for driver_info may be + * used, although some only make sense in conjunction with other fields. * This is usually set by a USB_DEVICE_*() macro, which sets all * other fields in this structure except for driver_info. * @idVendor: USB vendor ID for a device; numbers are assigned -- GitLab From f42cf8d6a3ec934551ac0f20f4654dccb11fa30d Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Tue, 24 Feb 2015 23:11:26 +0900 Subject: [PATCH 03089/11651] treewide: Fix typo in printk messages This patch fix spelling typo in printk messages. Signed-off-by: Masanari Iida Acked-by: Randy Dunlap Signed-off-by: Jiri Kosina --- arch/powerpc/perf/hv-24x7.c | 2 +- drivers/mfd/si476x-i2c.c | 2 +- drivers/mmc/core/mmc.c | 4 ++-- drivers/mmc/core/sd.c | 4 ++-- drivers/mtd/nand/gpmi-nand/gpmi-lib.c | 2 +- drivers/net/phy/dp83640.c | 2 +- drivers/net/wireless/airo.c | 4 ++-- drivers/net/wireless/ath/wcn36xx/smd.c | 2 +- drivers/pinctrl/nomadik/pinctrl-abx500.c | 2 +- drivers/scsi/ch.c | 2 +- fs/jffs2/xattr.c | 2 +- net/atm/mpoa_proc.c | 2 +- sound/soc/soc-core.c | 4 ++-- 13 files changed, 17 insertions(+), 17 deletions(-) diff --git a/arch/powerpc/perf/hv-24x7.c b/arch/powerpc/perf/hv-24x7.c index dba34088da28..23cb66ced793 100644 --- a/arch/powerpc/perf/hv-24x7.c +++ b/arch/powerpc/perf/hv-24x7.c @@ -362,7 +362,7 @@ static int h_24x7_event_init(struct perf_event *event) /* PHYSICAL domains & other lpars require extra capabilities */ if (!caps.collect_privileged && (is_physical_domain(domain) || (event_get_lpar(event) != event_get_lpar_max()))) { - pr_devel("hv permisions disallow: is_physical_domain:%d, lpar=0x%llx\n", + pr_devel("hv permissions disallow: is_physical_domain:%d, lpar=0x%llx\n", is_physical_domain(domain), event_get_lpar(event)); return -EACCES; diff --git a/drivers/mfd/si476x-i2c.c b/drivers/mfd/si476x-i2c.c index 0e4a76daf187..7f87c62d91b3 100644 --- a/drivers/mfd/si476x-i2c.c +++ b/drivers/mfd/si476x-i2c.c @@ -766,7 +766,7 @@ static int si476x_core_probe(struct i2c_client *client, sizeof(struct v4l2_rds_data), GFP_KERNEL); if (rval) { - dev_err(&client->dev, "Could not alloate the FIFO\n"); + dev_err(&client->dev, "Could not allocate the FIFO\n"); goto free_gpio; } mutex_init(&core->rds_drainer_status_lock); diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index a301a78a2bd1..b212239750af 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -1816,7 +1816,7 @@ static int mmc_runtime_suspend(struct mmc_host *host) err = _mmc_suspend(host, true); if (err) - pr_err("%s: error %d doing aggessive suspend\n", + pr_err("%s: error %d doing aggressive suspend\n", mmc_hostname(host), err); return err; @@ -1834,7 +1834,7 @@ static int mmc_runtime_resume(struct mmc_host *host) err = _mmc_resume(host); if (err) - pr_err("%s: error %d doing aggessive resume\n", + pr_err("%s: error %d doing aggressive resume\n", mmc_hostname(host), err); return 0; diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index d90a6de7901d..c2cddfd99c7c 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -1156,7 +1156,7 @@ static int mmc_sd_runtime_suspend(struct mmc_host *host) err = _mmc_sd_suspend(host); if (err) - pr_err("%s: error %d doing aggessive suspend\n", + pr_err("%s: error %d doing aggressive suspend\n", mmc_hostname(host), err); return err; @@ -1174,7 +1174,7 @@ static int mmc_sd_runtime_resume(struct mmc_host *host) err = _mmc_sd_resume(host); if (err) - pr_err("%s: error %d doing aggessive resume\n", + pr_err("%s: error %d doing aggressive resume\n", mmc_hostname(host), err); return 0; diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c index 87e658ce23ef..2788af980086 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c +++ b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c @@ -1105,7 +1105,7 @@ int gpmi_is_ready(struct gpmi_nand_data *this, unsigned chip) mask = MX28_BF_GPMI_STAT_READY_BUSY(1 << chip); reg = readl(r->gpmi_regs + HW_GPMI_STAT); } else - dev_err(this->dev, "unknow arch.\n"); + dev_err(this->dev, "unknown arch.\n"); return reg & mask; } diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c index e22e602beef3..4c2b5a80f17c 100644 --- a/drivers/net/phy/dp83640.c +++ b/drivers/net/phy/dp83640.c @@ -614,7 +614,7 @@ static void recalibrate(struct dp83640_clock *clock) trigger = CAL_TRIGGER; cal_gpio = 1 + ptp_find_pin(clock->ptp_clock, PTP_PF_PHYSYNC, 0); if (cal_gpio < 1) { - pr_err("PHY calibration pin not avaible - PHY is not calibrated."); + pr_err("PHY calibration pin not available - PHY is not calibrated."); return; } diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index e71a2ce7a448..b97367d50717 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c @@ -3211,7 +3211,7 @@ static void airo_print_status(const char *devname, u16 status) airo_print_dbg(devname, "link lost (TSF sync lost)"); break; default: - airo_print_dbg(devname, "unknow status %x\n", status); + airo_print_dbg(devname, "unknown status %x\n", status); break; } break; @@ -3233,7 +3233,7 @@ static void airo_print_status(const char *devname, u16 status) case STAT_REASSOC: break; default: - airo_print_dbg(devname, "unknow status %x\n", status); + airo_print_dbg(devname, "unknown status %x\n", status); break; } } diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c b/drivers/net/wireless/ath/wcn36xx/smd.c index 63986931829e..3866b285b3ff 100644 --- a/drivers/net/wireless/ath/wcn36xx/smd.c +++ b/drivers/net/wireless/ath/wcn36xx/smd.c @@ -1632,7 +1632,7 @@ int wcn36xx_smd_keep_alive_req(struct wcn36xx *wcn, } else if (packet_type == WCN36XX_HAL_KEEP_ALIVE_UNSOLICIT_ARP_RSP) { /* TODO: it also support ARP response type */ } else { - wcn36xx_warn("unknow keep alive packet type %d\n", packet_type); + wcn36xx_warn("unknown keep alive packet type %d\n", packet_type); ret = -EINVAL; goto out; } diff --git a/drivers/pinctrl/nomadik/pinctrl-abx500.c b/drivers/pinctrl/nomadik/pinctrl-abx500.c index 228972827132..90a2c194027c 100644 --- a/drivers/pinctrl/nomadik/pinctrl-abx500.c +++ b/drivers/pinctrl/nomadik/pinctrl-abx500.c @@ -466,7 +466,7 @@ static int abx500_set_mode(struct pinctrl_dev *pctldev, struct gpio_chip *chip, break; default: - dev_dbg(pct->dev, "unknow alt_setting %d\n", alt_setting); + dev_dbg(pct->dev, "unknown alt_setting %d\n", alt_setting); return -EINVAL; } diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c index ef5ae0d03616..9449f4aab78f 100644 --- a/drivers/scsi/ch.c +++ b/drivers/scsi/ch.c @@ -345,7 +345,7 @@ ch_readconfig(scsi_changer *ch) ch->firsts[CHET_DT], ch->counts[CHET_DT]); } else { - VPRINTK(KERN_INFO, "reading element address assigment page failed!\n"); + VPRINTK(KERN_INFO, "reading element address assignment page failed!\n"); } /* vendor specific element types */ diff --git a/fs/jffs2/xattr.c b/fs/jffs2/xattr.c index d72817ac51f6..762c7a3cf43d 100644 --- a/fs/jffs2/xattr.c +++ b/fs/jffs2/xattr.c @@ -195,7 +195,7 @@ static int do_verify_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_dat /* unchecked xdatum is chained with c->xattr_unchecked */ list_del_init(&xd->xindex); - dbg_xattr("success on verfying xdatum (xid=%u, version=%u)\n", + dbg_xattr("success on verifying xdatum (xid=%u, version=%u)\n", xd->xid, xd->version); return 0; diff --git a/net/atm/mpoa_proc.c b/net/atm/mpoa_proc.c index 5bdd300db0f7..2df34eb5d65f 100644 --- a/net/atm/mpoa_proc.c +++ b/net/atm/mpoa_proc.c @@ -272,7 +272,7 @@ static int parse_qos(const char *buff) qos.rxtp.max_pcr = rx_pcr; qos.rxtp.max_sdu = rx_sdu; qos.aal = ATM_AAL5; - dprintk("parse_qos(): setting qos paramameters to tx=%d,%d rx=%d,%d\n", + dprintk("parse_qos(): setting qos parameters to tx=%d,%d rx=%d,%d\n", qos.txtp.max_pcr, qos.txtp.max_sdu, qos.rxtp.max_pcr, qos.rxtp.max_sdu); diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 4c8f8a23a0e9..69e655e1ce11 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -4064,7 +4064,7 @@ int snd_soc_register_component(struct device *dev, ret = snd_soc_register_dais(cmpnt, dai_drv, num_dai, true); if (ret < 0) { - dev_err(dev, "ASoC: Failed to regster DAIs: %d\n", ret); + dev_err(dev, "ASoC: Failed to register DAIs: %d\n", ret); goto err_cleanup; } @@ -4379,7 +4379,7 @@ int snd_soc_register_codec(struct device *dev, ret = snd_soc_register_dais(&codec->component, dai_drv, num_dai, false); if (ret < 0) { - dev_err(dev, "ASoC: Failed to regster DAIs: %d\n", ret); + dev_err(dev, "ASoC: Failed to register DAIs: %d\n", ret); goto err_cleanup; } -- GitLab From d939be3add4f1410079dad2755d4936cdb70903b Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Fri, 27 Feb 2015 23:52:31 +0900 Subject: [PATCH 03090/11651] treewide: Fix typo in printk messages This patch fix spelling typo in printk messages. Signed-off-by: Masanari Iida Acked-by: Randy Dunlap Signed-off-by: Jiri Kosina --- arch/arc/kernel/unwind.c | 2 +- arch/powerpc/kernel/prom.c | 2 +- arch/powerpc/platforms/85xx/p1022_rdk.c | 4 ++-- arch/x86/kernel/test_rodata.c | 2 +- drivers/iio/adc/max1027.c | 2 +- drivers/isdn/hardware/mISDN/mISDNinfineon.c | 2 +- drivers/isdn/mISDN/dsp_cmx.c | 2 +- drivers/isdn/mISDN/dsp_core.c | 4 ++-- drivers/media/tuners/msi001.c | 2 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c | 2 +- drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c | 2 +- drivers/net/wireless/ath/ath10k/mac.c | 2 +- drivers/net/wireless/rtlwifi/rtl8723be/dm.c | 2 +- drivers/net/wireless/rtlwifi/rtl8821ae/dm.c | 2 +- drivers/parisc/eisa_enumerator.c | 2 +- drivers/scsi/be2iscsi/be_cmds.c | 2 +- drivers/scsi/osd/osd_initiator.c | 2 +- drivers/scsi/qla2xxx/qla_nx.c | 2 +- drivers/scsi/qla2xxx/qla_os.c | 4 ++-- net/sunrpc/xprtrdma/verbs.c | 4 ++-- tools/perf/util/probe-finder.c | 2 +- 21 files changed, 25 insertions(+), 25 deletions(-) diff --git a/arch/arc/kernel/unwind.c b/arch/arc/kernel/unwind.c index e550b117ec4f..93c6ea52b671 100644 --- a/arch/arc/kernel/unwind.c +++ b/arch/arc/kernel/unwind.c @@ -841,7 +841,7 @@ static int processCFI(const u8 *start, const u8 *end, unsigned long targetLoc, break; case DW_CFA_GNU_window_save: default: - unw_debug("UNKNOW OPCODE 0x%x\n", opcode); + unw_debug("UNKNOWN OPCODE 0x%x\n", opcode); result = 0; break; } diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 099f27e6d1b0..20ce051312fc 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -721,7 +721,7 @@ void __init early_init_devtree(void *params) */ of_scan_flat_dt(early_init_dt_scan_cpus, NULL); if (boot_cpuid < 0) { - printk("Failed to indentify boot CPU !\n"); + printk("Failed to identify boot CPU !\n"); BUG(); } diff --git a/arch/powerpc/platforms/85xx/p1022_rdk.c b/arch/powerpc/platforms/85xx/p1022_rdk.c index 7a180f0308d5..680232d6ba48 100644 --- a/arch/powerpc/platforms/85xx/p1022_rdk.c +++ b/arch/powerpc/platforms/85xx/p1022_rdk.c @@ -50,14 +50,14 @@ void p1022rdk_set_pixel_clock(unsigned int pixclock) /* Map the global utilities registers. */ guts_np = of_find_compatible_node(NULL, NULL, "fsl,p1022-guts"); if (!guts_np) { - pr_err("p1022rdk: missing global utilties device node\n"); + pr_err("p1022rdk: missing global utilities device node\n"); return; } guts = of_iomap(guts_np, 0); of_node_put(guts_np); if (!guts) { - pr_err("p1022rdk: could not map global utilties device\n"); + pr_err("p1022rdk: could not map global utilities device\n"); return; } diff --git a/arch/x86/kernel/test_rodata.c b/arch/x86/kernel/test_rodata.c index b79133abda48..5ecbfe5099da 100644 --- a/arch/x86/kernel/test_rodata.c +++ b/arch/x86/kernel/test_rodata.c @@ -57,7 +57,7 @@ int rodata_test(void) /* test 3: check the value hasn't changed */ /* If this test fails, we managed to overwrite the data */ if (!rodata_test_data) { - printk(KERN_ERR "rodata_test: Test 3 failes (end data)\n"); + printk(KERN_ERR "rodata_test: Test 3 fails (end data)\n"); return -ENODEV; } /* test 4: check if the rodata section is 4Kb aligned */ diff --git a/drivers/iio/adc/max1027.c b/drivers/iio/adc/max1027.c index 87ee1c7d0b54..44bf815adb6c 100644 --- a/drivers/iio/adc/max1027.c +++ b/drivers/iio/adc/max1027.c @@ -436,7 +436,7 @@ static int max1027_probe(struct spi_device *spi) indio_dev->num_channels * 2, GFP_KERNEL); if (st->buffer == NULL) { - dev_err(&indio_dev->dev, "Can't allocate bufffer\n"); + dev_err(&indio_dev->dev, "Can't allocate buffer\n"); return -ENOMEM; } diff --git a/drivers/isdn/hardware/mISDN/mISDNinfineon.c b/drivers/isdn/hardware/mISDN/mISDNinfineon.c index c1493f4162fb..d5bdbaf93a1a 100644 --- a/drivers/isdn/hardware/mISDN/mISDNinfineon.c +++ b/drivers/isdn/hardware/mISDN/mISDNinfineon.c @@ -1092,7 +1092,7 @@ inf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } card->ci = get_card_info(ent->driver_data); if (!card->ci) { - pr_info("mISDN: do not have informations about adapter at %s\n", + pr_info("mISDN: do not have information about adapter at %s\n", pci_name(pdev)); kfree(card); pci_disable_device(pdev); diff --git a/drivers/isdn/mISDN/dsp_cmx.c b/drivers/isdn/mISDN/dsp_cmx.c index 87f7dff20ff6..52c43821f746 100644 --- a/drivers/isdn/mISDN/dsp_cmx.c +++ b/drivers/isdn/mISDN/dsp_cmx.c @@ -295,7 +295,7 @@ dsp_cmx_del_conf_member(struct dsp *dsp) } } printk(KERN_WARNING - "%s: dsp is not present in its own conf_meber list.\n", + "%s: dsp is not present in its own conf_member list.\n", __func__); return -EINVAL; diff --git a/drivers/isdn/mISDN/dsp_core.c b/drivers/isdn/mISDN/dsp_core.c index 77025f5cb57d..0222b1a35a2d 100644 --- a/drivers/isdn/mISDN/dsp_core.c +++ b/drivers/isdn/mISDN/dsp_core.c @@ -460,7 +460,7 @@ dsp_control_req(struct dsp *dsp, struct mISDNhead *hh, struct sk_buff *skb) } if (dsp_debug & DEBUG_DSP_CORE) printk(KERN_DEBUG "%s: enable mixing of " - "tx-data with conf mebers\n", __func__); + "tx-data with conf members\n", __func__); dsp->tx_mix = 1; dsp_cmx_hardware(dsp->conf, dsp); dsp_rx_off(dsp); @@ -474,7 +474,7 @@ dsp_control_req(struct dsp *dsp, struct mISDNhead *hh, struct sk_buff *skb) } if (dsp_debug & DEBUG_DSP_CORE) printk(KERN_DEBUG "%s: disable mixing of " - "tx-data with conf mebers\n", __func__); + "tx-data with conf members\n", __func__); dsp->tx_mix = 0; dsp_cmx_hardware(dsp->conf, dsp); dsp_rx_off(dsp); diff --git a/drivers/media/tuners/msi001.c b/drivers/media/tuners/msi001.c index 26019e731993..74cfc3c98edb 100644 --- a/drivers/media/tuners/msi001.c +++ b/drivers/media/tuners/msi001.c @@ -408,7 +408,7 @@ static int msi001_s_ctrl(struct v4l2_ctrl *ctrl) s->mixer_gain->cur.val, s->if_gain->val); break; default: - dev_dbg(&s->spi->dev, "unkown control %d\n", ctrl->id); + dev_dbg(&s->spi->dev, "unknown control %d\n", ctrl->id); ret = -EINVAL; } diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c index c88b20af87df..bb2af7207826 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c @@ -591,7 +591,7 @@ int bnx2x_vf_mcast(struct bnx2x *bp, struct bnx2x_virtf *vf, mc = kzalloc(mc_num * sizeof(struct bnx2x_mcast_list_elem), GFP_KERNEL); if (!mc) { - BNX2X_ERR("Cannot Configure mulicasts due to lack of memory\n"); + BNX2X_ERR("Cannot Configure multicasts due to lack of memory\n"); return -ENOMEM; } } diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c index 69b46c051cc0..a5a482946679 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c @@ -794,7 +794,7 @@ int qlcnic_82xx_config_intr_coalesce(struct qlcnic_adapter *adapter, if (rv) netdev_err(adapter->netdev, - "Failed to set Rx coalescing parametrs\n"); + "Failed to set Rx coalescing parameters\n"); return rv; } diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 46709301a51e..8698af91eaca 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -4342,7 +4342,7 @@ static void ath10k_sta_rc_update(struct ieee80211_hw *hw, bw = WMI_PEER_CHWIDTH_80MHZ; break; case IEEE80211_STA_RX_BW_160: - ath10k_warn(ar, "Invalid bandwith %d in rc update for %pM\n", + ath10k_warn(ar, "Invalid bandwidth %d in rc update for %pM\n", sta->bandwidth, sta->addr); bw = WMI_PEER_CHWIDTH_20MHZ; break; diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/dm.c b/drivers/net/wireless/rtlwifi/rtl8723be/dm.c index dd7eb4371f49..13430b53f7ca 100644 --- a/drivers/net/wireless/rtlwifi/rtl8723be/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8723be/dm.c @@ -336,7 +336,7 @@ static void rtl8723be_dm_find_minimum_rssi(struct ieee80211_hw *hw) rtl_dm_dig->min_undec_pwdb_for_dm = rtlpriv->dm.entry_min_undec_sm_pwdb; RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, - "AP Ext Port or disconnet PWDB = 0x%x\n", + "AP Ext Port or disconnect PWDB = 0x%x\n", rtl_dm_dig->min_undec_pwdb_for_dm); } RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "MinUndecoratedPWDBForDM =%d\n", diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/dm.c b/drivers/net/wireless/rtlwifi/rtl8821ae/dm.c index 9be106109921..cb20e23744e3 100644 --- a/drivers/net/wireless/rtlwifi/rtl8821ae/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8821ae/dm.c @@ -899,7 +899,7 @@ static void rtl8821ae_dm_dig(struct ieee80211_hw *hw) if (rtlpriv->falsealm_cnt.cnt_all > 10000) { RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, - "Abnornally false alarm case.\n"); + "Abnormally false alarm case.\n"); if (dm_digtable->large_fa_hit != 3) dm_digtable->large_fa_hit++; diff --git a/drivers/parisc/eisa_enumerator.c b/drivers/parisc/eisa_enumerator.c index caa153133754..a656d9e83343 100644 --- a/drivers/parisc/eisa_enumerator.c +++ b/drivers/parisc/eisa_enumerator.c @@ -357,7 +357,7 @@ static int parse_slot_config(int slot, } if (flags & HPEE_FUNCTION_INFO_CFG_FREE_FORM) { /* I have no idea how to handle this */ - printk("function %d have free-form confgiuration, skipping ", + printk("function %d have free-form configuration, skipping ", num_func); pos = p0 + function_len; continue; diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c index 80d97f3d2ed9..1028760b8a22 100644 --- a/drivers/scsi/be2iscsi/be_cmds.c +++ b/drivers/scsi/be2iscsi/be_cmds.c @@ -237,7 +237,7 @@ int beiscsi_mccq_compl(struct beiscsi_hba *phba, beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_INIT | BEISCSI_LOG_EH | BEISCSI_LOG_CONFIG, - "BC_%d : Insufficent Buffer Error " + "BC_%d : Insufficient Buffer Error " "Resp_Len : %d Actual_Resp_Len : %d\n", mbx_resp_hdr->response_length, mbx_resp_hdr->actual_resp_len); diff --git a/drivers/scsi/osd/osd_initiator.c b/drivers/scsi/osd/osd_initiator.c index 488c3929f19a..0cccd6033feb 100644 --- a/drivers/scsi/osd/osd_initiator.c +++ b/drivers/scsi/osd/osd_initiator.c @@ -186,7 +186,7 @@ static int _osd_get_print_system_info(struct osd_dev *od, if (unlikely(len > sizeof(odi->systemid))) { OSD_ERR("OSD Target error: OSD_SYSTEM_ID too long(%d). " - "device idetification might not work\n", len); + "device identification might not work\n", len); len = sizeof(odi->systemid); } odi->systemid_len = len; diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c index 54cb2ac9339b..7d2b18f2675c 100644 --- a/drivers/scsi/qla2xxx/qla_nx.c +++ b/drivers/scsi/qla2xxx/qla_nx.c @@ -1274,7 +1274,7 @@ qla82xx_pinit_from_rom(scsi_qla_host_t *vha) if (off == ADDR_ERROR) { ql_log(ql_log_fatal, vha, 0x0116, - "Unknow addr: 0x%08lx.\n", buf[i].addr); + "Unknown addr: 0x%08lx.\n", buf[i].addr); continue; } diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index db3dbd999cb6..45bdc4d558c0 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -4174,7 +4174,7 @@ qla83xx_schedule_work(scsi_qla_host_t *base_vha, int work_code) break; default: ql_log(ql_log_warn, base_vha, 0xb05f, - "Unknow work-code=0x%x.\n", work_code); + "Unknown work-code=0x%x.\n", work_code); } return; @@ -4774,7 +4774,7 @@ qla83xx_idc_state_handler(scsi_qla_host_t *base_vha) break; default: ql_log(ql_log_warn, base_vha, 0xb071, - "Unknow Device State: %x.\n", dev_state); + "Unknown Device State: %x.\n", dev_state); qla83xx_idc_unlock(base_vha, 0); qla8xxx_dev_failed_handler(base_vha); rval = QLA_FUNCTION_FAILED; diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c index 61c41298b4ea..3b91aedf439e 100644 --- a/net/sunrpc/xprtrdma/verbs.c +++ b/net/sunrpc/xprtrdma/verbs.c @@ -1005,7 +1005,7 @@ rpcrdma_init_fmrs(struct rpcrdma_ia *ia, struct rpcrdma_buffer *buf) int i, rc; i = (buf->rb_max_requests + 1) * RPCRDMA_MAX_SEGS; - dprintk("RPC: %s: initalizing %d FMRs\n", __func__, i); + dprintk("RPC: %s: initializing %d FMRs\n", __func__, i); while (i--) { r = kzalloc(sizeof(*r), GFP_KERNEL); @@ -1038,7 +1038,7 @@ rpcrdma_init_frmrs(struct rpcrdma_ia *ia, struct rpcrdma_buffer *buf) int i, rc; i = (buf->rb_max_requests + 1) * RPCRDMA_MAX_SEGS; - dprintk("RPC: %s: initalizing %d FRMRs\n", __func__, i); + dprintk("RPC: %s: initializing %d FRMRs\n", __func__, i); while (i--) { r = kzalloc(sizeof(*r), GFP_KERNEL); diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index c7918f83b300..1cb1ef765ca0 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c @@ -456,7 +456,7 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname, return -EINVAL; } if (field->name[0] == '[') { - pr_err("Semantic error: %s is not a pointor" + pr_err("Semantic error: %s is not a pointer" " nor array.\n", varname); return -EINVAL; } -- GitLab From c5b66e47251d797e38f3ee8ec8d613780506c245 Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Fri, 23 Jan 2015 13:36:55 +0800 Subject: [PATCH 03091/11651] smpboot.h: Remove unused function prototype Function smpboot_thread_schedule() is neither used nor defined, so kill it. Signed-off-by: Jiang Liu Signed-off-by: Jiri Kosina --- include/linux/smpboot.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/linux/smpboot.h b/include/linux/smpboot.h index 13e929679550..d600afb21926 100644 --- a/include/linux/smpboot.h +++ b/include/linux/smpboot.h @@ -47,6 +47,5 @@ struct smp_hotplug_thread { int smpboot_register_percpu_thread(struct smp_hotplug_thread *plug_thread); void smpboot_unregister_percpu_thread(struct smp_hotplug_thread *plug_thread); -int smpboot_thread_schedule(void); #endif -- GitLab From f38bacb3ebdd30ae4695735a82497659ba05d9fa Mon Sep 17 00:00:00 2001 From: Himanshu Maithani Date: Fri, 30 Jan 2015 01:31:14 +0530 Subject: [PATCH 03092/11651] stacktrace.h: remove duplicate declaration task_struct There is duplicate declaration for struct task_struct. One can be removed safely. Signed-off-by: Himanshu Maithani Signed-off-by: Jiri Kosina --- include/linux/stacktrace.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/linux/stacktrace.h b/include/linux/stacktrace.h index 115b570e3bff..1fea0380e97f 100644 --- a/include/linux/stacktrace.h +++ b/include/linux/stacktrace.h @@ -5,8 +5,6 @@ struct task_struct; struct pt_regs; #ifdef CONFIG_STACKTRACE -struct task_struct; - struct stack_trace { unsigned int nr_entries, max_entries; unsigned long *entries; -- GitLab From d38712a7e2773ed4bc4f694cfa7bcbee4f804675 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Thu, 5 Feb 2015 14:35:05 +0100 Subject: [PATCH 03093/11651] coredump: Fix do_coredump() comment Signed-off-by: Bastien Nocera Signed-off-by: Jiri Kosina --- fs/coredump.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/coredump.c b/fs/coredump.c index b5c86ffd5033..f319926ddf8c 100644 --- a/fs/coredump.c +++ b/fs/coredump.c @@ -572,7 +572,7 @@ void do_coredump(const siginfo_t *siginfo) * * Normally core limits are irrelevant to pipes, since * we're not writing to the file system, but we use - * cprm.limit of 1 here as a speacial value, this is a + * cprm.limit of 1 here as a special value, this is a * consistent way to catch recursive crashes. * We can still crash if the core_pattern binary sets * RLIM_CORE = !1, but it runs as root, and can do -- GitLab From 2a2483685a9decd0af60f1dc9e49f46f9e65891b Mon Sep 17 00:00:00 2001 From: Alan Date: Thu, 19 Feb 2015 21:11:13 +0000 Subject: [PATCH 03094/11651] goldfish: remove unreachable line of code Signed-off-by: Alan Cox Signed-off-by: Jiri Kosina --- drivers/tty/goldfish.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/tty/goldfish.c b/drivers/tty/goldfish.c index 09495f515fa9..e423550c3516 100644 --- a/drivers/tty/goldfish.c +++ b/drivers/tty/goldfish.c @@ -293,7 +293,6 @@ static int goldfish_tty_probe(struct platform_device *pdev) mutex_unlock(&goldfish_tty_lock); return 0; - tty_unregister_device(goldfish_tty_driver, i); err_tty_register_device_failed: free_irq(irq, pdev); err_request_irq_failed: -- GitLab From 52df3d5b6a49dc3d867abb5414315490dd0098ef Mon Sep 17 00:00:00 2001 From: Alan Date: Thu, 19 Feb 2015 21:43:35 +0000 Subject: [PATCH 03095/11651] ipwireless: missing assignment We never report the error because we don't assign it to ret. Signed-off-by: Alan Cox Signed-off-by: Jiri Kosina --- drivers/tty/ipwireless/hardware.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/ipwireless/hardware.c b/drivers/tty/ipwireless/hardware.c index 2c14842541dd..017bfb624e8e 100644 --- a/drivers/tty/ipwireless/hardware.c +++ b/drivers/tty/ipwireless/hardware.c @@ -1455,7 +1455,7 @@ static void __handle_setup_get_version_rsp(struct ipw_hardware *hw) return; } - set_RTS(hw, PRIO_SETUP, channel_idx, + ret = set_RTS(hw, PRIO_SETUP, channel_idx, (hw->control_lines [channel_idx] & IPW_CONTROL_LINE_RTS) != 0); if (ret) { -- GitLab From fc454fdc108e44bf7e7ebd39f8209a2d021dd8ca Mon Sep 17 00:00:00 2001 From: Frans Klaver Date: Mon, 23 Feb 2015 22:05:56 +0100 Subject: [PATCH 03096/11651] init/main: fix reset_device comment Fix incorrect spelling of situation. Signed-off-by: Frans Klaver Signed-off-by: Jiri Kosina --- init/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/init/main.c b/init/main.c index 321d0ceb26d3..b0c705515089 100644 --- a/init/main.c +++ b/init/main.c @@ -145,7 +145,7 @@ EXPORT_SYMBOL_GPL(static_key_initialized); * rely on the BIOS and skip the reset operation. * * This is useful if kernel is booting in an unreliable environment. - * For ex. kdump situaiton where previous kernel has crashed, BIOS has been + * For ex. kdump situation where previous kernel has crashed, BIOS has been * skipped and devices will be in unknown state. */ unsigned int reset_devices; -- GitLab From 6ef68da70f5242f71a2bc76fc8d78b473d6b5c05 Mon Sep 17 00:00:00 2001 From: Yannick Guerrini Date: Mon, 23 Feb 2015 23:26:50 +0100 Subject: [PATCH 03097/11651] qla2xxx: Fix printk in qla25xx_setup_mode Change 'enalbed' to 'enabled' Signed-off-by: Yannick Guerrini Acked-by: Saurav Kashyap Signed-off-by: Jiri Kosina --- drivers/scsi/qla2xxx/qla_os.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 45bdc4d558c0..92fd85c8b09f 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -447,11 +447,11 @@ static int qla25xx_setup_mode(struct scsi_qla_host *vha) } ha->flags.cpu_affinity_enabled = 1; ql_dbg(ql_dbg_multiq, vha, 0xc007, - "CPU affinity mode enalbed, " + "CPU affinity mode enabled, " "no. of response queues:%d no. of request queues:%d.\n", ha->max_rsp_queues, ha->max_req_queues); ql_dbg(ql_dbg_init, vha, 0x00e9, - "CPU affinity mode enalbed, " + "CPU affinity mode enabled, " "no. of response queues:%d no. of request queues:%d.\n", ha->max_rsp_queues, ha->max_req_queues); } -- GitLab From 7a35a865049f60f0891797f46150d3b611a64d0b Mon Sep 17 00:00:00 2001 From: Yannick Guerrini Date: Tue, 24 Feb 2015 16:42:45 +0100 Subject: [PATCH 03098/11651] usb: storage: Fix printk in isd200_log_config() Change 'Supsend' to 'Suspend' Signed-off-by: Yannick Guerrini Signed-off-by: Jiri Kosina --- drivers/usb/storage/isd200.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c index 599d8bff26c3..076178645ba4 100644 --- a/drivers/usb/storage/isd200.c +++ b/drivers/usb/storage/isd200.c @@ -737,7 +737,7 @@ static void isd200_log_config(struct us_data *us, struct isd200_info *info) info->ConfigData.ATAExtraConfig & ATACFGE_CONF_DESC2); usb_stor_dbg(us, " Skip Device Boot: 0x%x\n", info->ConfigData.ATAExtraConfig & ATACFGE_SKIP_BOOT); - usb_stor_dbg(us, " ATA 3 State Supsend: 0x%x\n", + usb_stor_dbg(us, " ATA 3 State Suspend: 0x%x\n", info->ConfigData.ATAExtraConfig & ATACFGE_STATE_SUSPEND); usb_stor_dbg(us, " Descriptor Override: 0x%x\n", info->ConfigData.ATAExtraConfig & ATACFGE_DESC_OVERRIDE); -- GitLab From 2701e84f8beaa878af13187d4cd7c040a8953b32 Mon Sep 17 00:00:00 2001 From: Yannick Guerrini Date: Thu, 26 Feb 2015 11:13:06 +0100 Subject: [PATCH 03099/11651] si2168, tda10071, m88ds3103: Fix firmware wording Change 'firmare' to 'firmware' Signed-off-by: Yannick Guerrini Acked-by: Antti Palosaari Signed-off-by: Jiri Kosina --- drivers/media/dvb-frontends/m88ds3103.c | 2 +- drivers/media/dvb-frontends/si2168_priv.h | 2 +- drivers/media/dvb-frontends/tda10071_priv.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c index 81657e94c5a4..fdafbeb6ed8c 100644 --- a/drivers/media/dvb-frontends/m88ds3103.c +++ b/drivers/media/dvb-frontends/m88ds3103.c @@ -567,7 +567,7 @@ static int m88ds3103_init(struct dvb_frontend *fe) /* request the firmware, this will block and timeout */ ret = request_firmware(&fw, fw_file, priv->i2c->dev.parent); if (ret) { - dev_err(&priv->i2c->dev, "%s: firmare file '%s' not found\n", + dev_err(&priv->i2c->dev, "%s: firmware file '%s' not found\n", KBUILD_MODNAME, fw_file); goto err; } diff --git a/drivers/media/dvb-frontends/si2168_priv.h b/drivers/media/dvb-frontends/si2168_priv.h index e13983ed4be1..451d85456639 100644 --- a/drivers/media/dvb-frontends/si2168_priv.h +++ b/drivers/media/dvb-frontends/si2168_priv.h @@ -40,7 +40,7 @@ struct si2168 { u8 ts_mode; }; -/* firmare command struct */ +/* firmware command struct */ #define SI2168_ARGLEN 30 struct si2168_cmd { u8 args[SI2168_ARGLEN]; diff --git a/drivers/media/dvb-frontends/tda10071_priv.h b/drivers/media/dvb-frontends/tda10071_priv.h index 420486192736..03f839c431e9 100644 --- a/drivers/media/dvb-frontends/tda10071_priv.h +++ b/drivers/media/dvb-frontends/tda10071_priv.h @@ -99,7 +99,7 @@ struct tda10071_reg_val_mask { #define CMD_BER_CONTROL 0x3e #define CMD_BER_UPDATE_COUNTERS 0x3f -/* firmare command struct */ +/* firmware command struct */ #define TDA10071_ARGLEN 30 struct tda10071_cmd { u8 args[TDA10071_ARGLEN]; -- GitLab From 28ca84e04803786d63277c8bb23c60c7f57f1cdc Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Thu, 26 Feb 2015 20:19:03 +0100 Subject: [PATCH 03100/11651] lib: correct link to the original source for div64_u64 The code refers to an invalid url http://www.hackersdelight.org/HDcode/newCode/divDouble.c.txt The correct url is http://www.hackersdelight.org/hdcodetxt/divDouble.c.txt Signed-off-by: Heinrich Schuchardt Signed-off-by: Jiri Kosina --- lib/div64.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/div64.c b/lib/div64.c index 4382ad77777e..19ea7ed4b948 100644 --- a/lib/div64.c +++ b/lib/div64.c @@ -127,7 +127,7 @@ EXPORT_SYMBOL(div64_u64_rem); * by the book 'Hacker's Delight'. The original source and full proof * can be found here and is available for use without restriction. * - * 'http://www.hackersdelight.org/HDcode/newCode/divDouble.c.txt' + * 'http://www.hackersdelight.org/hdcodetxt/divDouble.c.txt' */ #ifndef div64_u64 u64 div64_u64(u64 dividend, u64 divisor) -- GitLab From 94bcf830114a7a062d46344088cee33ac4b65df7 Mon Sep 17 00:00:00 2001 From: Yannick Guerrini Date: Thu, 26 Feb 2015 22:49:34 +0100 Subject: [PATCH 03101/11651] qla2xxx: Fix printks in ql_log message Change 'Fimware' to 'Firmware' Change 'enalbled' to 'enabled' Signed-off-by: Yannick Guerrini Acked-by: Saurav Kashyap Signed-off-by: Jiri Kosina --- drivers/scsi/qla2xxx/qla_init.c | 4 ++-- drivers/scsi/qla2xxx/qla_mid.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index a4dde7e80dbd..17d30adb07d1 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -5366,7 +5366,7 @@ qla2x00_load_risc(scsi_qla_host_t *vha, uint32_t *srisc_addr) blob = qla2x00_request_firmware(vha); if (!blob) { ql_log(ql_log_info, vha, 0x0083, - "Fimware image unavailable.\n"); + "Firmware image unavailable.\n"); ql_log(ql_log_info, vha, 0x0084, "Firmware images can be retrieved from: "QLA_FW_URL ".\n"); return QLA_FUNCTION_FAILED; @@ -5469,7 +5469,7 @@ qla24xx_load_risc_blob(scsi_qla_host_t *vha, uint32_t *srisc_addr) blob = qla2x00_request_firmware(vha); if (!blob) { ql_log(ql_log_warn, vha, 0x0090, - "Fimware image unavailable.\n"); + "Firmware image unavailable.\n"); ql_log(ql_log_warn, vha, 0x0091, "Firmware images can be retrieved from: " QLA_FW_URL ".\n"); diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index 5c2e0317f1c0..ca3804e34833 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c @@ -788,7 +788,7 @@ qla25xx_create_rsp_que(struct qla_hw_data *ha, uint16_t options, rsp->msix = &ha->msix_entries[que_id + 1]; else ql_log(ql_log_warn, base_vha, 0x00e3, - "MSIX not enalbled.\n"); + "MSIX not enabled.\n"); ha->rsp_q_map[que_id] = rsp; rsp->rid = rid; -- GitLab From c1f4775ab57605a5e2003cd96034145d791abf62 Mon Sep 17 00:00:00 2001 From: Yannick Guerrini Date: Fri, 27 Feb 2015 23:22:54 +0100 Subject: [PATCH 03102/11651] powerpc: Fix comment in smu.h Change 'Kenrel' to 'Kernel' Signed-off-by: Yannick Guerrini Signed-off-by: Jiri Kosina --- arch/powerpc/include/asm/smu.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/include/asm/smu.h b/arch/powerpc/include/asm/smu.h index 6e909f3e6a46..37d2da6feabf 100644 --- a/arch/powerpc/include/asm/smu.h +++ b/arch/powerpc/include/asm/smu.h @@ -478,7 +478,7 @@ extern unsigned long smu_cmdbuf_abs; /* - * Kenrel asynchronous i2c interface + * Kernel asynchronous i2c interface */ #define SMU_I2C_READ_MAX 0x1d -- GitLab From 25ff6f8da004f49c2cab55a51cf8c250d21e9738 Mon Sep 17 00:00:00 2001 From: Aya Mahfouz Date: Wed, 4 Mar 2015 07:28:48 +0200 Subject: [PATCH 03103/11651] staging: comedi: drivers: remove extra parentheses around right bit shift operation Removes extra parentheses around bitwise right shift operation. The issue was detected and resolved using the following coccinelle script: @@ expression e, e1; constant c; @@ e = -(e1 +e1 >> -c); +c; @@ identifier i; constant c; type t; expression e; @@ t i = -(e +e >> -c); +c; @@ expression e, e1; identifier f; constant c; @@ e1 = f(..., -(e +e >> -c) +c ,...); Signed-off-by: Aya Mahfouz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/dt2801.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/dt2801.c b/drivers/staging/comedi/drivers/dt2801.c index b96e60ffad73..7e565fc944c4 100644 --- a/drivers/staging/comedi/drivers/dt2801.c +++ b/drivers/staging/comedi/drivers/dt2801.c @@ -280,7 +280,7 @@ static int dt2801_writedata2(struct comedi_device *dev, unsigned int data) ret = dt2801_writedata(dev, data & 0xff); if (ret < 0) return ret; - ret = dt2801_writedata(dev, (data >> 8)); + ret = dt2801_writedata(dev, data >> 8); if (ret < 0) return ret; -- GitLab From 159dc4bff27a300d2c70108bf49ae01f6d1b34f2 Mon Sep 17 00:00:00 2001 From: Aya Mahfouz Date: Wed, 4 Mar 2015 07:29:28 +0200 Subject: [PATCH 03104/11651] staging: lustre: lclient: remove extra parentheses around right bit shift operation Removes extra parentheses around bitwise right shift operations. The cases handled here are when the resultant value is assigned to a variable. The issue was detected and resolved using the following coccinelle script: @@ expression e, e1; constant c; @@ e = -(e1 +e1 >> -c); +c; @@ identifier i; constant c; type t; expression e; @@ t i = -(e +e >> -c); +c; @@ expression e, e1; identifier f; constant c; @@ e1 = f(..., -(e +e >> -c) +c ,...); Signed-off-by: Aya Mahfouz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/lclient/lcommon_cl.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/staging/lustre/lustre/lclient/lcommon_cl.c b/drivers/staging/lustre/lustre/lclient/lcommon_cl.c index 23095bb75226..ab6cb419302f 100644 --- a/drivers/staging/lustre/lustre/lclient/lcommon_cl.c +++ b/drivers/staging/lustre/lustre/lclient/lcommon_cl.c @@ -828,7 +828,8 @@ int ccc_prep_size(const struct lu_env *env, struct cl_object *obj, * --bug 17336 */ loff_t size = cl_isize_read(inode); loff_t cur_index = start >> PAGE_CACHE_SHIFT; - loff_t size_index = ((size - 1) >> PAGE_CACHE_SHIFT); + loff_t size_index = (size - 1) >> + PAGE_CACHE_SHIFT; if ((size == 0 && cur_index != 0) || size_index < cur_index) @@ -1263,7 +1264,7 @@ __u32 cl_fid_build_gen(const struct lu_fid *fid) return gen; } - gen = (fid_flatten(fid) >> 32); + gen = fid_flatten(fid) >> 32; return gen; } -- GitLab From a354e0d8d2ce4beb61097eeac6069b41c0797ed3 Mon Sep 17 00:00:00 2001 From: Aya Mahfouz Date: Wed, 4 Mar 2015 07:30:18 +0200 Subject: [PATCH 03105/11651] staging: lustre: llite: remove extra parentheses around right bit shift operation Removes extra parentheses around bitwise right shift operation. The case handled here is when the resultant value is assigned to a variable. The issue was detected and resolved using the following coccinelle script: @@ expression e, e1; constant c; @@ e = -(e1 +e1 >> -c); +c; @@ identifier i; constant c; type t; expression e; @@ t i = -(e +e >> -c); +c; @@ expression e, e1; identifier f; constant c; @@ e1 = f(..., -(e +e >> -c) +c ,...); Signed-off-by: Aya Mahfouz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/llite/vvp_dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/lustre/lustre/llite/vvp_dev.c b/drivers/staging/lustre/lustre/llite/vvp_dev.c index 5a1078a4198d..97d94fc738f2 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_dev.c +++ b/drivers/staging/lustre/lustre/llite/vvp_dev.c @@ -286,7 +286,7 @@ static void vvp_pgcache_id_unpack(loff_t pos, struct vvp_pgcache_id *id) id->vpi_index = pos & 0xffffffff; id->vpi_depth = (pos >> PGC_DEPTH_SHIFT) & 0xf; - id->vpi_bucket = ((unsigned long long)pos >> PGC_OBJ_SHIFT); + id->vpi_bucket = (unsigned long long)pos >> PGC_OBJ_SHIFT; } static loff_t vvp_pgcache_id_pack(struct vvp_pgcache_id *id) -- GitLab From 11d6e5c5623a1cdbee1560f4957c070b0ea76b22 Mon Sep 17 00:00:00 2001 From: Aya Mahfouz Date: Wed, 4 Mar 2015 07:30:49 +0200 Subject: [PATCH 03106/11651] staging: media: bcm2048: remove extra parentheses around right bit shift operation Removes extra parentheses around bitwise right shift operation. The case handled here is when the resultant value is assigned to a variable. The issue was detected and resolved using the following coccinelle script: @@ expression e, e1; constant c; @@ e = -(e1 +e1 >> -c); +c; @@ identifier i; constant c; type t; expression e; @@ t i = -(e +e >> -c); +c; @@ expression e, e1; identifier f; constant c; @@ e1 = f(..., -(e +e >> -c) +c ,...); Signed-off-by: Aya Mahfouz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/media/bcm2048/radio-bcm2048.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/media/bcm2048/radio-bcm2048.c b/drivers/staging/media/bcm2048/radio-bcm2048.c index 538250667918..116251b4e317 100644 --- a/drivers/staging/media/bcm2048/radio-bcm2048.c +++ b/drivers/staging/media/bcm2048/radio-bcm2048.c @@ -2245,8 +2245,7 @@ static ssize_t bcm2048_fops_read(struct file *file, char __user *buf, tmpbuf[i] = bdev->rds_info.radio_text[bdev->rd_index+i+2]; tmpbuf[i+1] = bdev->rds_info.radio_text[bdev->rd_index+i+1]; - tmpbuf[i+2] = ((bdev->rds_info.radio_text[bdev->rd_index+i] - & 0xf0) >> 4); + tmpbuf[i+2] = (bdev->rds_info.radio_text[bdev->rd_index + i] & 0xf0) >> 4; if ((bdev->rds_info.radio_text[bdev->rd_index+i] & BCM2048_RDS_CRC_MASK) == BCM2048_RDS_CRC_UNRECOVARABLE) tmpbuf[i+2] |= 0x80; -- GitLab From 6182930bdb207789c3c92051c2c4a03f5da8f6ee Mon Sep 17 00:00:00 2001 From: Aya Mahfouz Date: Wed, 4 Mar 2015 07:31:19 +0200 Subject: [PATCH 03107/11651] staging: media: lirc: remove extra parentheses around right bit shift operation Removes extra parentheses around bitwise right shift operation. The case handled here is when the resultant value is assigned to a variable. The issue was detected and resolved using the following coccinelle script: @@ expression e, e1; constant c; @@ e = -(e1 +e1 >> -c); +c; @@ identifier i; constant c; type t; expression e; @@ t i = -(e +e >> -c); +c; @@ expression e, e1; identifier f; constant c; @@ e1 = f(..., -(e +e >> -c) +c ,...); Signed-off-by: Aya Mahfouz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/media/lirc/lirc_serial.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/media/lirc/lirc_serial.c b/drivers/staging/media/lirc/lirc_serial.c index 19628d0104ab..9f55a83d5ab2 100644 --- a/drivers/staging/media/lirc/lirc_serial.c +++ b/drivers/staging/media/lirc/lirc_serial.c @@ -344,7 +344,7 @@ static int init_timing_params(unsigned int new_duty_cycle, /* How many clocks in a microsecond?, avoiding long long divide */ work = loops_per_sec; work *= 4295; /* 4295 = 2^32 / 1e6 */ - conv_us_to_clocks = (work >> 32); + conv_us_to_clocks = work >> 32; /* * Carrier period in clocks, approach good up to 32GHz clock, -- GitLab From 07add2d38d48ca168b266c0f4f6af923bb9886e3 Mon Sep 17 00:00:00 2001 From: Aya Mahfouz Date: Wed, 4 Mar 2015 07:31:56 +0200 Subject: [PATCH 03108/11651] staging: rtl8188eu: remove extra parentheses around right bit shift operations Removes extra parentheses around bitwise right shift operations. The cases handled here are when resultant values are assigned to variables. The issue was detected and resolved using the following coccinelle script: @@ expression e, e1; constant c; @@ e = -(e1 +e1 >> -c); +c; @@ identifier i; constant c; type t; expression e; @@ t i = -(e +e >> -c); +c; @@ expression e, e1; identifier f; constant c; @@ e1 = f(..., -(e +e >> -c) +c ,...); Signed-off-by: Aya Mahfouz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/core/rtw_efuse.c | 2 +- drivers/staging/rtl8188eu/hal/odm.c | 8 ++++---- drivers/staging/rtl8188eu/hal/odm_HWConfig.c | 2 +- drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c | 3 ++- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_efuse.c b/drivers/staging/rtl8188eu/core/rtw_efuse.c index 8816d116a8b8..defec6b7883d 100644 --- a/drivers/staging/rtl8188eu/core/rtw_efuse.c +++ b/drivers/staging/rtl8188eu/core/rtw_efuse.c @@ -139,7 +139,7 @@ efuse_phymap_to_logical(u8 *phymap, u16 _offset, u16 _size_byte, u8 *pbuf) while ((rtemp8 != 0xFF) && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) { /* Check PG header for section num. */ if ((rtemp8 & 0x1F) == 0x0F) { /* extended header */ - u1temp = ((rtemp8 & 0xE0) >> 5); + u1temp = (rtemp8 & 0xE0) >> 5; rtemp8 = *(phymap+eFuse_Addr); if ((rtemp8 & 0x0F) == 0x0F) { eFuse_Addr++; diff --git a/drivers/staging/rtl8188eu/hal/odm.c b/drivers/staging/rtl8188eu/hal/odm.c index 06477e834653..28b5e7bd4fc0 100644 --- a/drivers/staging/rtl8188eu/hal/odm.c +++ b/drivers/staging/rtl8188eu/hal/odm.c @@ -741,13 +741,13 @@ void odm_FalseAlarmCounterStatistics(struct odm_dm_struct *pDM_Odm) ret_value = phy_query_bb_reg(adapter, ODM_REG_OFDM_FA_TYPE1_11N, bMaskDWord); FalseAlmCnt->Cnt_Fast_Fsync = (ret_value&0xffff); - FalseAlmCnt->Cnt_SB_Search_fail = ((ret_value&0xffff0000)>>16); + FalseAlmCnt->Cnt_SB_Search_fail = (ret_value & 0xffff0000)>>16; ret_value = phy_query_bb_reg(adapter, ODM_REG_OFDM_FA_TYPE2_11N, bMaskDWord); FalseAlmCnt->Cnt_OFDM_CCA = (ret_value&0xffff); - FalseAlmCnt->Cnt_Parity_Fail = ((ret_value&0xffff0000)>>16); + FalseAlmCnt->Cnt_Parity_Fail = (ret_value & 0xffff0000)>>16; ret_value = phy_query_bb_reg(adapter, ODM_REG_OFDM_FA_TYPE3_11N, bMaskDWord); FalseAlmCnt->Cnt_Rate_Illegal = (ret_value&0xffff); - FalseAlmCnt->Cnt_Crc8_fail = ((ret_value&0xffff0000)>>16); + FalseAlmCnt->Cnt_Crc8_fail = (ret_value & 0xffff0000)>>16; ret_value = phy_query_bb_reg(adapter, ODM_REG_OFDM_FA_TYPE4_11N, bMaskDWord); FalseAlmCnt->Cnt_Mcs_fail = (ret_value&0xffff); @@ -757,7 +757,7 @@ void odm_FalseAlarmCounterStatistics(struct odm_dm_struct *pDM_Odm) ret_value = phy_query_bb_reg(adapter, ODM_REG_SC_CNT_11N, bMaskDWord); FalseAlmCnt->Cnt_BW_LSC = (ret_value&0xffff); - FalseAlmCnt->Cnt_BW_USC = ((ret_value&0xffff0000)>>16); + FalseAlmCnt->Cnt_BW_USC = (ret_value & 0xffff0000)>>16; /* hold cck counter */ phy_set_bb_reg(adapter, ODM_REG_CCK_FA_RST_11N, BIT12, 1); diff --git a/drivers/staging/rtl8188eu/hal/odm_HWConfig.c b/drivers/staging/rtl8188eu/hal/odm_HWConfig.c index 29f87dffbad3..f8fae18341fa 100644 --- a/drivers/staging/rtl8188eu/hal/odm_HWConfig.c +++ b/drivers/staging/rtl8188eu/hal/odm_HWConfig.c @@ -123,7 +123,7 @@ static void odm_RxPhyStatus92CSeries_Parsing(struct odm_dm_struct *dm_odm, /* 2011.11.28 LukeLee: 88E use different LNA & VGA gain table */ /* The RSSI formula should be modified according to the gain table */ /* In 88E, cck_highpwr is always set to 1 */ - LNA_idx = ((cck_agc_rpt & 0xE0) >> 5); + LNA_idx = (cck_agc_rpt & 0xE0) >> 5; VGA_idx = (cck_agc_rpt & 0x1F); switch (LNA_idx) { case 7: diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c b/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c index 3222d8d08b5b..7904d2260f2c 100644 --- a/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c +++ b/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c @@ -596,7 +596,8 @@ void Hal_EfuseParseBoardType88E(struct adapter *pAdapter, u8 *hwinfo, bool AutoL struct hal_data_8188e *pHalData = GET_HAL_DATA(pAdapter); if (!AutoLoadFail) - pHalData->BoardType = ((hwinfo[EEPROM_RF_BOARD_OPTION_88E]&0xE0)>>5); + pHalData->BoardType = (hwinfo[EEPROM_RF_BOARD_OPTION_88E] + & 0xE0) >> 5; else pHalData->BoardType = 0; DBG_88E("Board Type: 0x%2x\n", pHalData->BoardType); -- GitLab From 0c401c1dc9739580d758dfa88ec568897c2e2dfd Mon Sep 17 00:00:00 2001 From: Aya Mahfouz Date: Wed, 4 Mar 2015 07:32:30 +0200 Subject: [PATCH 03109/11651] staging: rtl8192e: remove extra parentheses around right bit shift operation Removes extra parentheses around bitwise right shift operation. The cases handled are when the resultant value is assigned to a variable or when a shift operation is carried out for a function argument. The issues were detected and resolved using the following coccinelle script: @@ expression e, e1; constant c; @@ e = -(e1 +e1 >> -c); +c; @@ identifier i; constant c; type t; expression e; @@ t i = -(e +e >> -c); +c; @@ expression e, e1; identifier f; constant c; @@ e1 = f(..., -(e +e >> -c) +c ,...); Some coding style issues were handled manually to avoid checkpatch warnings and errors. Signed-off-by: Aya Mahfouz Signed-off-by: Greg Kroah-Hartman --- .../staging/rtl8192e/rtl8192e/r8192E_dev.c | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c index a85fb7118b7b..08735cb116c0 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c +++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c @@ -334,17 +334,17 @@ static void rtl8192_read_eeprom_info(struct net_device *dev) } if (!priv->AutoloadFailFlag) { - priv->eeprom_vid = eprom_read(dev, (EEPROM_VID >> 1)); - priv->eeprom_did = eprom_read(dev, (EEPROM_DID >> 1)); + priv->eeprom_vid = eprom_read(dev, EEPROM_VID >> 1); + priv->eeprom_did = eprom_read(dev, EEPROM_DID >> 1); usValue = eprom_read(dev, (u16)(EEPROM_Customer_ID>>1)) >> 8; priv->eeprom_CustomerID = (u8)(usValue & 0xff); - usValue = eprom_read(dev, (EEPROM_ICVersion_ChannelPlan>>1)); + usValue = eprom_read(dev, EEPROM_ICVersion_ChannelPlan>>1); priv->eeprom_ChannelPlan = usValue&0xff; - IC_Version = ((usValue&0xff00)>>8); + IC_Version = (usValue & 0xff00)>>8; ICVer8192 = (IC_Version&0xf); - ICVer8256 = ((IC_Version&0xf0)>>4); + ICVer8256 = (IC_Version & 0xf0)>>4; RT_TRACE(COMP_INIT, "\nICVer8192 = 0x%x\n", ICVer8192); RT_TRACE(COMP_INIT, "\nICVer8256 = 0x%x\n", ICVer8256); if (ICVer8192 == 0x2) { @@ -424,7 +424,7 @@ static void rtl8192_read_eeprom_info(struct net_device *dev) if (priv->epromtype == EEPROM_93C46) { if (!priv->AutoloadFailFlag) { usValue = eprom_read(dev, - (EEPROM_TxPwDiff_CrystalCap >> 1)); + EEPROM_TxPwDiff_CrystalCap >> 1); priv->EEPROMAntPwDiff = (usValue&0x0fff); priv->EEPROMCrystalCap = (u8)((usValue & 0xf000) >> 12); @@ -483,15 +483,15 @@ static void rtl8192_read_eeprom_info(struct net_device *dev) priv->EEPROMLegacyHTTxPowerDiff; priv->AntennaTxPwDiff[0] = (priv->EEPROMAntPwDiff & 0xf); - priv->AntennaTxPwDiff[1] = ((priv->EEPROMAntPwDiff & - 0xf0)>>4); - priv->AntennaTxPwDiff[2] = ((priv->EEPROMAntPwDiff & - 0xf00)>>8); + priv->AntennaTxPwDiff[1] = (priv->EEPROMAntPwDiff & + 0xf0) >> 4; + priv->AntennaTxPwDiff[2] = (priv->EEPROMAntPwDiff & + 0xf00) >> 8; priv->CrystalCap = priv->EEPROMCrystalCap; priv->ThermalMeter[0] = (priv->EEPROMThermalMeter & 0xf); - priv->ThermalMeter[1] = ((priv->EEPROMThermalMeter & - 0xf0)>>4); + priv->ThermalMeter[1] = (priv->EEPROMThermalMeter & + 0xf0) >> 4; } else if (priv->epromtype == EEPROM_93C56) { for (i = 0; i < 3; i++) { @@ -548,8 +548,8 @@ static void rtl8192_read_eeprom_info(struct net_device *dev) priv->CrystalCap = priv->EEPROMCrystalCap; priv->ThermalMeter[0] = (priv->EEPROMThermalMeter & 0xf); - priv->ThermalMeter[1] = ((priv->EEPROMThermalMeter & - 0xf0)>>4); + priv->ThermalMeter[1] = (priv->EEPROMThermalMeter & + 0xf0) >> 4; } } -- GitLab From 9eb9e69536ba00d2dbe4f481b20ced67053a6c08 Mon Sep 17 00:00:00 2001 From: Aya Mahfouz Date: Wed, 4 Mar 2015 07:33:06 +0200 Subject: [PATCH 03110/11651] staging: rtl8192u: remove extra parentheses around right bit shift operation Removes extra parentheses around bitwise right shift operation. The cases handled are when the resultant value is assigned to a variable or when a shift operation is carried out for a function argument. The issues were detected and resolved using the following coccinelle script: @@ expression e, e1; constant c; @@ e = -(e1 +e1 >> -c); +c; @@ identifier i; constant c; type t; expression e; @@ t i = -(e +e >> -c); +c; @@ expression e, e1; identifier f; constant c; @@ e1 = f(..., -(e +e >> -c) +c ,...); Some coding style issues were handled manually to avoid checkpatch warnings and errors. Signed-off-by: Aya Mahfouz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/r8192U_core.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c index 9de4412da3b3..bab7751a7636 100644 --- a/drivers/staging/rtl8192u/r8192U_core.c +++ b/drivers/staging/rtl8192u/r8192U_core.c @@ -2310,11 +2310,11 @@ static void rtl8192_read_eeprom_info(struct net_device *dev) } if (bLoad_From_EEPOM) { - tmpValue = eprom_read(dev, (EEPROM_VID>>1)); + tmpValue = eprom_read(dev, EEPROM_VID>>1); priv->eeprom_vid = endian_swap(&tmpValue); - priv->eeprom_pid = eprom_read(dev, (EEPROM_PID>>1)); - tmpValue = eprom_read(dev, (EEPROM_ChannelPlan>>1)); - priv->eeprom_ChannelPlan = ((tmpValue&0xff00)>>8); + priv->eeprom_pid = eprom_read(dev, EEPROM_PID>>1); + tmpValue = eprom_read(dev, EEPROM_ChannelPlan>>1); + priv->eeprom_ChannelPlan = (tmpValue & 0xff00)>>8; priv->btxpowerdata_readfromEEPORM = true; priv->eeprom_CustomerID = eprom_read(dev, (EEPROM_Customer_ID>>1)) >>8; } else { @@ -2397,7 +2397,8 @@ static void rtl8192_read_eeprom_info(struct net_device *dev) } } else if (priv->EEPROM_Def_Ver == 1) { if (bLoad_From_EEPOM) { - tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_CCK_V1>>1)); + tmpValue = eprom_read(dev, + EEPROM_TxPwIndex_CCK_V1 >> 1); tmpValue = (tmpValue & 0xff00) >> 8; } else { tmpValue = 0x10; @@ -2410,7 +2411,8 @@ static void rtl8192_read_eeprom_info(struct net_device *dev) tmpValue = 0x1010; *((u16 *)(&priv->EEPROMTxPowerLevelCCK_V1[1])) = tmpValue; if (bLoad_From_EEPOM) - tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G_V1>>1)); + tmpValue = eprom_read(dev, + EEPROM_TxPwIndex_OFDM_24G_V1 >> 1); else tmpValue = 0x1010; *((u16 *)(&priv->EEPROMTxPowerLevelOFDM24G[0])) = tmpValue; @@ -2453,7 +2455,7 @@ static void rtl8192_read_eeprom_info(struct net_device *dev) // Antenna B gain offset to antenna A, bit0~3 priv->AntennaTxPwDiff[0] = (priv->EEPROMTxPowerDiff & 0xf); // Antenna C gain offset to antenna A, bit4~7 - priv->AntennaTxPwDiff[1] = ((priv->EEPROMTxPowerDiff & 0xf0)>>4); + priv->AntennaTxPwDiff[1] = (priv->EEPROMTxPowerDiff & 0xf0)>>4; // CrystalCap, bit12~15 priv->CrystalCap = priv->EEPROMCrystalCap; // ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2 -- GitLab From 25978642332b10efcaf67b1a26dbfa04949c2e7b Mon Sep 17 00:00:00 2001 From: Aya Mahfouz Date: Wed, 4 Mar 2015 07:33:39 +0200 Subject: [PATCH 03111/11651] staging: rtl8712: remove extra parentheses around right bit shift operation Removes extra parentheses around bitwise right shift operation. The cases handled are when the resultant value is assigned to a variable or when a shift operation is carried out for a function argument. The issues were detected and resolved using the following coccinelle script: @@ expression e, e1; constant c; @@ e = -(e1 +e1 >> -c); +c; @@ identifier i; constant c; type t; expression e; @@ t i = -(e +e >> -c); +c; @@ expression e, e1; identifier f; constant c; @@ e1 = f(..., -(e +e >> -c) +c ,...); Signed-off-by: Aya Mahfouz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/rtl8712_recv.c | 4 ++-- drivers/staging/rtl8712/rtl871x_mp.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/rtl8712/rtl8712_recv.c b/drivers/staging/rtl8712/rtl8712_recv.c index 0ec0bda45d50..50227b598e0c 100644 --- a/drivers/staging/rtl8712/rtl8712_recv.c +++ b/drivers/staging/rtl8712/rtl8712_recv.c @@ -166,7 +166,7 @@ static void update_recvframe_attrib_from_recvstat(struct rx_pkt_attrib *pattrib, * Offset 0 */ pattrib->bdecrypted = ((le32_to_cpu(prxstat->rxdw0) & BIT(27)) >> 27) ? 0 : 1; - pattrib->crc_err = ((le32_to_cpu(prxstat->rxdw0) & BIT(14)) >> 14); + pattrib->crc_err = (le32_to_cpu(prxstat->rxdw0) & BIT(14)) >> 14; /*Offset 4*/ /*Offset 8*/ /*Offset 12*/ @@ -435,7 +435,7 @@ void r8712_rxcmd_event_hdl(struct _adapter *padapter, void *prxcmdbuf) poffset = (u8 *)prxcmdbuf; voffset = *(uint *)poffset; prxstat = (struct recv_stat *)prxcmdbuf; - drvinfo_sz = ((le32_to_cpu(prxstat->rxdw0) & 0x000f0000) >> 16); + drvinfo_sz = (le32_to_cpu(prxstat->rxdw0) & 0x000f0000) >> 16; drvinfo_sz <<= 3; poffset += RXDESC_SIZE + drvinfo_sz; do { diff --git a/drivers/staging/rtl8712/rtl871x_mp.c b/drivers/staging/rtl8712/rtl871x_mp.c index 3d913b9701bb..26201ea3cca6 100644 --- a/drivers/staging/rtl8712/rtl871x_mp.c +++ b/drivers/staging/rtl8712/rtl871x_mp.c @@ -327,8 +327,8 @@ void r8712_SetTxAGCOffset(struct _adapter *pAdapter, u32 ulTxAGCOffset) u32 TxAGCOffset_B, TxAGCOffset_C, TxAGCOffset_D, tmpAGC; TxAGCOffset_B = (ulTxAGCOffset&0x000000ff); - TxAGCOffset_C = ((ulTxAGCOffset&0x0000ff00)>>8); - TxAGCOffset_D = ((ulTxAGCOffset&0x00ff0000)>>16); + TxAGCOffset_C = (ulTxAGCOffset & 0x0000ff00)>>8; + TxAGCOffset_D = (ulTxAGCOffset & 0x00ff0000)>>16; tmpAGC = (TxAGCOffset_D<<8 | TxAGCOffset_C<<4 | TxAGCOffset_B); set_bb_reg(pAdapter, rFPGA0_TxGainStage, (bXBTxAGC|bXCTxAGC|bXDTxAGC), tmpAGC); -- GitLab From e1bc88f1d94f1b34ef0ae27d3c6801a6fdac1f60 Mon Sep 17 00:00:00 2001 From: Aya Mahfouz Date: Wed, 4 Mar 2015 07:34:07 +0200 Subject: [PATCH 03112/11651] staging: rtl8723au: remove extra parentheses around right bit shift operations Removes extra parentheses around bitwise right shift operations. The cases handled here are when resultant values are assigned to variables. The issue was detected and resolved using the following coccinelle script: @@ expression e, e1; constant c; @@ e = -(e1 +e1 >> -c); +c; @@ identifier i; constant c; type t; expression e; @@ t i = -(e +e >> -c); +c; @@ expression e, e1; identifier f; constant c; @@ e1 = f(..., -(e +e >> -c) +c ,...); Signed-off-by: Aya Mahfouz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/hal/odm.c | 6 +++--- drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/odm.c b/drivers/staging/rtl8723au/hal/odm.c index 8d4266100ff0..2d3653e784d2 100644 --- a/drivers/staging/rtl8723au/hal/odm.c +++ b/drivers/staging/rtl8723au/hal/odm.c @@ -736,15 +736,15 @@ void odm_FalseAlarmCounterStatistics23a(struct dm_odm_t *pDM_Odm) ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_OFDM_FA_TYPE1_11N, bMaskDWord); FalseAlmCnt->Cnt_Fast_Fsync = (ret_value&0xffff); - FalseAlmCnt->Cnt_SB_Search_fail = ((ret_value&0xffff0000)>>16); + FalseAlmCnt->Cnt_SB_Search_fail = (ret_value & 0xffff0000)>>16; ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_OFDM_FA_TYPE2_11N, bMaskDWord); FalseAlmCnt->Cnt_OFDM_CCA = (ret_value&0xffff); - FalseAlmCnt->Cnt_Parity_Fail = ((ret_value&0xffff0000)>>16); + FalseAlmCnt->Cnt_Parity_Fail = (ret_value & 0xffff0000)>>16; ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_OFDM_FA_TYPE3_11N, bMaskDWord); FalseAlmCnt->Cnt_Rate_Illegal = (ret_value&0xffff); - FalseAlmCnt->Cnt_Crc8_fail = ((ret_value&0xffff0000)>>16); + FalseAlmCnt->Cnt_Crc8_fail = (ret_value & 0xffff0000)>>16; ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_OFDM_FA_TYPE4_11N, bMaskDWord); FalseAlmCnt->Cnt_Mcs_fail = (ret_value&0xffff); diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c b/drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c index 7b3fdc841aac..ebe33392c8d9 100644 --- a/drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c +++ b/drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c @@ -751,7 +751,7 @@ void rtl8723a_read_chip_version(struct rtw_adapter *padapter) value32 = rtl8723au_read32(padapter, REG_GPIO_OUTSTS); /* ROM code version. */ - ChipVersion.ROMVer = ((value32 & RF_RL_ID) >> 20); + ChipVersion.ROMVer = (value32 & RF_RL_ID) >> 20; /* For multi-function consideration. Added by Roger, 2010.10.06. */ pHalData->MultiFunc = RT_MULTI_FUNC_NONE; @@ -1728,8 +1728,8 @@ Hal_EfuseParseBTCoexistInfo_8723A(struct rtw_adapter *padapter, /* eeprom spec */ tempval = hwinfo[RF_OPTION4_8723A]; pHalData->EEPROMBluetoothAntNum = (tempval & 0x1); - pHalData->EEPROMBluetoothAntIsolation = ((tempval & 0x10) >> 4); - pHalData->EEPROMBluetoothRadioShared = ((tempval & 0x20) >> 5); + pHalData->EEPROMBluetoothAntIsolation = (tempval & 0x10) >> 4; + pHalData->EEPROMBluetoothRadioShared = (tempval & 0x20) >> 5; } else { pHalData->EEPROMBluetoothCoexist = 0; pHalData->EEPROMBluetoothType = BT_RTL8723A; -- GitLab From a659b3e807a9e0a3f4b48ffbd491dbcab8e7d1d6 Mon Sep 17 00:00:00 2001 From: Aya Mahfouz Date: Wed, 4 Mar 2015 07:34:52 +0200 Subject: [PATCH 03113/11651] staging: slicoss: remove extra parentheses around right bit shift operations Removes extra parentheses around bitwise right shift operations. The cases handled here are when resultant values are assigned to variables. The issue was detected and resolved using the following coccinelle script: @@ expression e, e1; constant c; @@ e = -(e1 +e1 >> -c); +c; @@ identifier i; constant c; type t; expression e; @@ t i = -(e +e >> -c); +c; @@ expression e, e1; identifier f; constant c; @@ e1 = f(..., -(e +e >> -c) +c ,...); Some coding style issues were handled manually to avoid checkpatch warnings and errors. Signed-off-by: Aya Mahfouz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/slicoss/slicoss.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/slicoss/slicoss.c b/drivers/staging/slicoss/slicoss.c index 45f6a5fce963..c84dd6062a03 100644 --- a/drivers/staging/slicoss/slicoss.c +++ b/drivers/staging/slicoss/slicoss.c @@ -164,7 +164,7 @@ static void slic_mcast_set_bit(struct adapter *adapter, char *address) /* Get the CRC polynomial for the mac address */ /* we use bits 1-8 (lsb), bitwise reversed, * msb (= lsb bit 0 before bitrev) is automatically discarded */ - crcpoly = (ether_crc(ETH_ALEN, address)>>23); + crcpoly = ether_crc(ETH_ALEN, address)>>23; /* We only have space on the SLIC for 64 entries. Lop * off the top two bits. (2^6 = 64) @@ -1862,8 +1862,8 @@ static void slic_xmit_build_request(struct adapter *adapter, hcmd->cmdsize = (u32) ((((u64)&ihcmd->u.slic_buffers.bufs[1] - (u64) hcmd) + 31) >> 5); #else - hcmd->cmdsize = ((((u32) &ihcmd->u.slic_buffers.bufs[1] - - (u32) hcmd) + 31) >> 5); + hcmd->cmdsize = (((u32)&ihcmd->u.slic_buffers.bufs[1] - + (u32)hcmd) + 31) >> 5; #endif } -- GitLab From 6de3f58bc32cc10516b286b26476d5aa65c6d1e5 Mon Sep 17 00:00:00 2001 From: Aya Mahfouz Date: Wed, 4 Mar 2015 07:35:28 +0200 Subject: [PATCH 03114/11651] staging: speakup: remove extra parentheses around right bit shift operation Removes extra parentheses around bitwise right shift operation. The case handled is when the resultant value is assigned to a variable. The issue was detected and resolved using the following coccinelle script: @@ expression e, e1; constant c; @@ e = -(e1 +e1 >> -c); +c; @@ identifier i; constant c; type t; expression e; @@ t i = -(e +e >> -c); +c; @@ expression e, e1; identifier f; constant c; @@ e1 = f(..., -(e +e >> -c) +c ,...); Signed-off-by: Aya Mahfouz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/speakup/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/speakup/main.c b/drivers/staging/speakup/main.c index e9f0c150d246..1249f910aed1 100644 --- a/drivers/staging/speakup/main.c +++ b/drivers/staging/speakup/main.c @@ -1527,7 +1527,7 @@ static void update_color_buffer(struct vc_data *vc, const char *ic, int len) int i, bi, hi; int vc_num = vc->vc_num; - bi = ((vc->vc_attr & 0x70) >> 4); + bi = (vc->vc_attr & 0x70) >> 4; hi = speakup_console[vc_num]->ht.highsize[bi]; i = 0; -- GitLab From 9ea755f3e8b05445ee6029c6b497a30f1e6a7bf6 Mon Sep 17 00:00:00 2001 From: Aya Mahfouz Date: Wed, 4 Mar 2015 07:35:48 +0200 Subject: [PATCH 03115/11651] staging: xgifb: remove extra parentheses around right bit shift operations Removes extra parentheses around bitwise right shift operations. The cases handled here are when resultant values are assigned to variables. The issue was detected and resolved using the following coccinelle script: @@ expression e, e1; constant c; @@ e = -(e1 +e1 >> -c); +c; @@ identifier i; constant c; type t; expression e; @@ t i = -(e +e >> -c); +c; @@ expression e, e1; identifier f; constant c; @@ e1 = f(..., -(e +e >> -c) +c ,...); Signed-off-by: Aya Mahfouz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main_26.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index 935c714f592a..74e88200726c 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -106,7 +106,7 @@ static int XGIfb_mode_rate_to_ddata(struct vb_device_info *XGI_Pr, sr_data = XGI_CRT1Table[index].CR[5]; - HDE = (XGI330_RefIndex[RefreshRateTableIndex].XRes >> 3); + HDE = XGI330_RefIndex[RefreshRateTableIndex].XRes >> 3; cr_data = XGI_CRT1Table[index].CR[3]; @@ -1011,8 +1011,8 @@ static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive, XGIbios_mode[xgifb_info->mode_idx].mode_no); return -EINVAL; } - info->fix.line_length = ((info->var.xres_virtual - * info->var.bits_per_pixel) >> 6); + info->fix.line_length = (info->var.xres_virtual + * info->var.bits_per_pixel) >> 6; xgifb_reg_set(XGISR, IND_SIS_PASSWORD, SIS_PASSWORD); -- GitLab From e21bf3388b960bce8dd2d7bc17331f3b8020fd9f Mon Sep 17 00:00:00 2001 From: Aya Mahfouz Date: Wed, 4 Mar 2015 08:18:19 +0200 Subject: [PATCH 03116/11651] staging: lustre: remove extra parentheses around left bit shift operations Removes extra parentheses around bitwise left shift operations. The cases handled here are when resultant values are assigned to variables. The issue was detected and resolved using the following coccinelle script: @@ expression e, e1; constant c; @@ e = -(e1 +e1 << -c); +c; @@ identifier i; constant c; type t; expression e; @@ t i = -(e +e << -c); +c; @@ expression e, e1; identifier f; constant c; @@ e1 = f(..., -(e +e << -c) +c ,...); Signed-off-by: Aya Mahfouz Signed-off-by: Greg Kroah-Hartman --- .../staging/lustre/lnet/klnds/socklnd/socklnd_modparams.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_modparams.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_modparams.c index 66d78c9be650..86b88db1cf20 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_modparams.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_modparams.c @@ -72,7 +72,7 @@ static int typed_conns = 1; module_param(typed_conns, int, 0444); MODULE_PARM_DESC(typed_conns, "use different sockets for bulk"); -static int min_bulk = (1<<10); +static int min_bulk = 1<<10; module_param(min_bulk, int, 0644); MODULE_PARM_DESC(min_bulk, "smallest 'large' message"); @@ -122,7 +122,7 @@ static int nonblk_zcack = 1; module_param(nonblk_zcack, int, 0644); MODULE_PARM_DESC(nonblk_zcack, "always send ZC-ACK on non-blocking connection"); -static unsigned int zc_min_payload = (16 << 10); +static unsigned int zc_min_payload = 16 << 10; module_param(zc_min_payload, int, 0644); MODULE_PARM_DESC(zc_min_payload, "minimum payload size to zero copy"); @@ -182,7 +182,7 @@ int ksocknal_tunables_init(void) #endif if (*ksocknal_tunables.ksnd_zc_min_payload < (2 << 10)) - *ksocknal_tunables.ksnd_zc_min_payload = (2 << 10); + *ksocknal_tunables.ksnd_zc_min_payload = 2 << 10; return 0; }; -- GitLab From dbc9eb5af20578a931efb6fac721e9a977c5171b Mon Sep 17 00:00:00 2001 From: Aya Mahfouz Date: Wed, 4 Mar 2015 08:18:47 +0200 Subject: [PATCH 03117/11651] staging: ozwpan: remove extra parentheses around left bit shift operations Removes extra parentheses around bitwise left shift operations. The case handled is when resultant value is assigned to a variable. The issue was detected and resolved using the following coccinelle script: @@ expression e, e1; constant c; @@ e = -(e1 +e1 << -c); +c; @@ identifier i; constant c; type t; expression e; @@ t i = -(e +e << -c); +c; Signed-off-by: Aya Mahfouz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ozwpan/ozproto.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/ozwpan/ozproto.c b/drivers/staging/ozwpan/ozproto.c index 3d3a3a890f73..1ba24a2aef83 100644 --- a/drivers/staging/ozwpan/ozproto.c +++ b/drivers/staging/ozwpan/ozproto.c @@ -98,7 +98,7 @@ static void oz_send_conn_rsp(struct oz_pd *pd, u8 status) kfree_skb(skb); return; } - oz_hdr->control = (OZ_PROTOCOL_VERSION<control = OZ_PROTOCOL_VERSION<last_pkt_num = 0; put_unaligned(0, &oz_hdr->pkt_num); elt->type = OZ_ELT_CONNECT_RSP; -- GitLab From 5a80ee6f8871a81afb4fd919133ae5be3b656d44 Mon Sep 17 00:00:00 2001 From: Aya Mahfouz Date: Wed, 4 Mar 2015 08:19:24 +0200 Subject: [PATCH 03118/11651] staging: rts5208: remove extra parentheses around left bit shift operation Removes extra parentheses around bitwise left shift operations. The case handled is when resultant value is assigned to a variable. The issue was detected and resolved using the following coccinelle script: @@ expression e, e1; constant c; @@ e = -(e1 +e1 << -c); +c; @@ identifier i; constant c; type t; expression e; @@ t i = -(e +e << -c); +c; @@ expression e, e1; identifier f; constant c; @@ e1 = f(..., -(e +e << -c) +c ,...); Signed-off-by: Aya Mahfouz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rts5208/rtsx_transport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rts5208/rtsx_transport.c b/drivers/staging/rts5208/rtsx_transport.c index dab1995d1a6a..03caa9b3771f 100644 --- a/drivers/staging/rts5208/rtsx_transport.c +++ b/drivers/staging/rts5208/rtsx_transport.c @@ -642,7 +642,7 @@ static int rtsx_transfer_buf(struct rtsx_chip *chip, u8 card, void *buf, dma_addr_t addr; u8 dir; int err = 0; - u32 val = (1 << 31); + u32 val = 1 << 31; long timeleft; if ((buf == NULL) || (len <= 0)) -- GitLab From 6e28c2a24aedbd64bf9cc1391ca203e9aa95d757 Mon Sep 17 00:00:00 2001 From: Aya Mahfouz Date: Wed, 4 Mar 2015 08:19:50 +0200 Subject: [PATCH 03119/11651] staging: slicoss: remove extra parentheses around left bit shift operations Removes extra parentheses around bitwise left shift operations. The case handled is when resultant value is assigned to a variable. The issue was detected and resolved using the following coccinelle script: @@ expression e, e1; constant c; @@ e = -(e1 +e1 << -c); +c; @@ identifier i; constant c; type t; expression e; @@ t i = -(e +e << -c); +c; @@ expression e, e1; identifier f; constant c; @@ e1 = f(..., -(e +e << -c) +c ,...); Signed-off-by: Aya Mahfouz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/slicoss/slicoss.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/slicoss/slicoss.c b/drivers/staging/slicoss/slicoss.c index c84dd6062a03..a3afb3e4d157 100644 --- a/drivers/staging/slicoss/slicoss.c +++ b/drivers/staging/slicoss/slicoss.c @@ -1850,7 +1850,7 @@ static void slic_xmit_build_request(struct adapter *adapter, ihcmd = &hcmd->cmd64; - ihcmd->flags = (adapter->port << IHFLG_IFSHFT); + ihcmd->flags = adapter->port << IHFLG_IFSHFT; ihcmd->command = IHCMD_XMT_REQ; ihcmd->u.slic_buffers.totlen = skb->len; phys_addr = pci_map_single(adapter->pcidev, skb->data, skb->len, -- GitLab From a06487242467aa9511470f1f92184ae1a9149d37 Mon Sep 17 00:00:00 2001 From: Aya Mahfouz Date: Wed, 4 Mar 2015 08:20:14 +0200 Subject: [PATCH 03120/11651] staging: unisys: virthba: remove extra parentheses around left bit shift operations Removes extra parentheses around bitwise left shift operations. The case handled is when resultant value is assigned to a variable. The issue was detected and resolved using the following coccinelle script: @@ expression e, e1; constant c; @@ e = -(e1 +e1 << -c); +c; @@ identifier i; constant c; type t; expression e; @@ t i = -(e +e << -c); +c; @@ expression e, e1; identifier f; constant c; @@ e1 = f(..., -(e +e << -c) +c ,...); Signed-off-by: Aya Mahfouz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/virthba/virthba.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/unisys/virthba/virthba.c b/drivers/staging/unisys/virthba/virthba.c index ca89e76fbf7e..2ad0c1939623 100644 --- a/drivers/staging/unisys/virthba/virthba.c +++ b/drivers/staging/unisys/virthba/virthba.c @@ -1534,7 +1534,7 @@ virthba_serverdown_complete(struct work_struct *work) switch (pendingdel->cmdtype) { case CMD_SCSI_TYPE: scsicmd = (struct scsi_cmnd *)pendingdel->sent; - scsicmd->result = (DID_RESET << 16); + scsicmd->result = DID_RESET << 16; if (scsicmd->scsi_done) scsicmd->scsi_done(scsicmd); break; -- GitLab From 8e5d9433412d34f02a83edd265605bfe6c347a0a Mon Sep 17 00:00:00 2001 From: Aya Mahfouz Date: Wed, 4 Mar 2015 08:56:45 +0200 Subject: [PATCH 03121/11651] staging: rtl8188eu: replace memset(x,0,ETH_ALEN) eth_zero_addr() is a wrapper function for memset if 0 is going to be assigned to a mac address. The aforementioned function replaces memset. In addition, linux/etherdevice.h was included as a header since it is the file that define the inline function eth_zero_addr(). The changes were carried out using the following coccinelle script: @header@ @@ #include @eth_zero_addr@ expression e; @@ -memset(e,0,ETH_ALEN); +eth_zero_addr(e); @eth_broadcast_addr@ identifier e; @@ -memset(e,\(0xff\|0xFF\|255\),ETH_ALEN); +eth_broadcast_addr(e); @linux_header depends on !header && (eth_zero_addr || eth_broadcast_addr) @ @@ + #include + @special_header depends on !header && !linux_header && (eth_zero_addr || eth_broadcast_addr) @ @@ + + #include + @custom_header depends on !header && !linux_header && !special_header && (eth_zero_addr || eth_broadcast_addr) @ @@ + + #include Signed-off-by: Aya Mahfouz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/os_dep/ioctl_linux.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c index 58998f2f2b09..96c1c2d4a112 100644 --- a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c +++ b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c @@ -32,6 +32,8 @@ #include #include +#include + #include "osdep_intf.h" #define RTL_IOCTL_WPA_SUPPLICANT (SIOCIWFIRSTPRIV + 30) @@ -92,7 +94,7 @@ void rtw_indicate_wx_disassoc_event(struct adapter *padapter) memset(&wrqu, 0, sizeof(union iwreq_data)); wrqu.ap_addr.sa_family = ARPHRD_ETHER; - memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN); + eth_zero_addr(wrqu.ap_addr.sa_data); DBG_88E_LEVEL(_drv_always_, "indicate disassoc\n"); wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL); @@ -827,7 +829,7 @@ static int rtw_wx_set_pmkid(struct net_device *dev, for (j = 0; j < NUM_PMKID_CACHE; j++) { if (!memcmp(psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN)) { /* BSSID is matched, the same AP => Remove this PMKID information and reset it. */ - memset(psecuritypriv->PMKIDList[j].Bssid, 0x00, ETH_ALEN); + eth_zero_addr(psecuritypriv->PMKIDList[j].Bssid); psecuritypriv->PMKIDList[j].bUsed = false; break; } @@ -1028,7 +1030,7 @@ static int rtw_wx_get_wap(struct net_device *dev, wrqu->ap_addr.sa_family = ARPHRD_ETHER; - memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN); + eth_zero_addr(wrqu->ap_addr.sa_data); RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_wap\n")); @@ -1037,7 +1039,7 @@ static int rtw_wx_get_wap(struct net_device *dev, ((check_fwstate(pmlmepriv, WIFI_AP_STATE)) == true)) memcpy(wrqu->ap_addr.sa_data, pcur_bss->MacAddress, ETH_ALEN); else - memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN); + eth_zero_addr(wrqu->ap_addr.sa_data); return 0; } -- GitLab From 22905b8594d58a6fceeb4510a57e34571a075b45 Mon Sep 17 00:00:00 2001 From: Aya Mahfouz Date: Wed, 4 Mar 2015 09:00:02 +0200 Subject: [PATCH 03122/11651] staging: rtl8712: replace memset(x,0,ETH_ALEN) eth_zero_addr() is a wrapper function for memset if 0 is going to be assigned to a mac address. The aforementioned function replaces memset. In addition, linux/etherdevice.h was included as a header since it is the file that defines the inline function eth_zero_addr(). The changes were carried out using the following coccinelle script: @header@ @@ #include @eth_zero_addr@ expression e; @@ -memset(e,0,ETH_ALEN); +eth_zero_addr(e); @eth_broadcast_addr@ identifier e; @@ -memset(e,\(0xff\|0xFF\|255\),ETH_ALEN); +eth_broadcast_addr(e); @linux_header depends on !header && (eth_zero_addr || eth_broadcast_addr) @ @@ + #include + @special_header depends on !header && !linux_header && (eth_zero_addr || eth_broadcast_addr) @ @@ + + #include + @custom_header depends on !header && !linux_header && !special_header && (eth_zero_addr || eth_broadcast_addr) @ @@ + + #include Signed-off-by: Aya Mahfouz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/rtl871x_ioctl_linux.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c index 5d4470a9aeb5..eacba8c37cc1 100644 --- a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c +++ b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c @@ -46,6 +46,8 @@ #include #include #include +#include + #define RTL_IOCTL_WPA_SUPPLICANT (SIOCIWFIRSTPRIV + 0x1E) @@ -112,7 +114,7 @@ void r8712_indicate_wx_disassoc_event(struct _adapter *padapter) union iwreq_data wrqu; wrqu.ap_addr.sa_family = ARPHRD_ETHER; - memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN); + eth_zero_addr(wrqu.ap_addr.sa_data); wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL); } @@ -852,8 +854,7 @@ static int r871x_wx_set_pmkid(struct net_device *dev, strIssueBssid, ETH_ALEN)) { /* BSSID is matched, the same AP => Remove * this PMKID information and reset it. */ - memset(psecuritypriv->PMKIDList[j].Bssid, - 0x00, ETH_ALEN); + eth_zero_addr(psecuritypriv->PMKIDList[j].Bssid); psecuritypriv->PMKIDList[j].bUsed = false; break; } @@ -1118,7 +1119,7 @@ static int r8711_wx_get_wap(struct net_device *dev, WIFI_AP_STATE)) memcpy(wrqu->ap_addr.sa_data, pcur_bss->MacAddress, ETH_ALEN); else - memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN); + eth_zero_addr(wrqu->ap_addr.sa_data); return 0; } -- GitLab From aea42ee42196ee164b46eda047953c0974536d5b Mon Sep 17 00:00:00 2001 From: Somya Anand Date: Wed, 4 Mar 2015 14:10:44 +0530 Subject: [PATCH 03123/11651] Staging: rtl8188eu: Remove redundant local variable This patch removes a redundant variable "raid" and adds inline return statements. This issue is identified by the following coccinelle script: @@ expression ret; identifier f; @@ -ret = +return f(...); -return ret; Signed-off-by: Somya Anand Signed-off-by: Greg Kroah-Hartman --- .../staging/rtl8188eu/core/rtw_wlan_util.c | 24 ++++++------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_wlan_util.c b/drivers/staging/rtl8188eu/core/rtw_wlan_util.c index a3ffc691be9a..6917abf21ec0 100644 --- a/drivers/staging/rtl8188eu/core/rtw_wlan_util.c +++ b/drivers/staging/rtl8188eu/core/rtw_wlan_util.c @@ -88,35 +88,25 @@ int cckratesonly_included(unsigned char *rate, int ratelen) unsigned char networktype_to_raid(unsigned char network_type) { - unsigned char raid; - switch (network_type) { case WIRELESS_11B: - raid = RATR_INX_WIRELESS_B; - break; + return RATR_INX_WIRELESS_B; case WIRELESS_11A: case WIRELESS_11G: - raid = RATR_INX_WIRELESS_G; - break; + return RATR_INX_WIRELESS_G; case WIRELESS_11BG: - raid = RATR_INX_WIRELESS_GB; - break; + return RATR_INX_WIRELESS_GB; case WIRELESS_11_24N: case WIRELESS_11_5N: - raid = RATR_INX_WIRELESS_N; - break; + return RATR_INX_WIRELESS_N; case WIRELESS_11A_5N: case WIRELESS_11G_24N: - raid = RATR_INX_WIRELESS_NG; - break; + return RATR_INX_WIRELESS_NG; case WIRELESS_11BG_24N: - raid = RATR_INX_WIRELESS_NGB; - break; + return RATR_INX_WIRELESS_NGB; default: - raid = RATR_INX_WIRELESS_GB; - break; + return RATR_INX_WIRELESS_GB; } - return raid; } u8 judge_network_type(struct adapter *padapter, unsigned char *rate, int ratelen) -- GitLab From 3bd52fb13a56a9dbe7780480d0c66a5b8e450743 Mon Sep 17 00:00:00 2001 From: Somya Anand Date: Wed, 4 Mar 2015 14:10:46 +0530 Subject: [PATCH 03124/11651] Staging: rtl8188eu: Remove unnecessary return statements This patch removes unnecessary return statement from a void function. This issue is identified by checkpatch.pl Signed-off-by: Somya Anand Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/core/rtw_wlan_util.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_wlan_util.c b/drivers/staging/rtl8188eu/core/rtw_wlan_util.c index 6917abf21ec0..4f2f736598f2 100644 --- a/drivers/staging/rtl8188eu/core/rtw_wlan_util.c +++ b/drivers/staging/rtl8188eu/core/rtw_wlan_util.c @@ -649,8 +649,6 @@ void WMMOnAssocRsp(struct adapter *padapter) pxmitpriv->wmm_para_seq[i] = inx[i]; DBG_88E("wmm_para_seq(%d): %d\n", i, pxmitpriv->wmm_para_seq[i]); } - - return; } static void bwmode_update_check(struct adapter *padapter, struct ndis_802_11_var_ie *pIE) -- GitLab From a568dc1f3779c9fde5a58bf793574ecd7024090a Mon Sep 17 00:00:00 2001 From: Navya Sri Nizamkari Date: Wed, 4 Mar 2015 14:15:05 +0530 Subject: [PATCH 03125/11651] staging: rtl8192e: Remove if conditions. This patch removes if conditions with no exececutable statements in the bodies of those ifs and also no variable assignments in the if conditional checks. The call to rtllib_act_scanning in the condition doesn't have any side effects as it too performs conditional checks without changing any values. Hence, it's safe to remove the if condition. Signed-off-by: Navya Sri Nizamkari Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtl8192e/rtl_wx.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c b/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c index df0323f00f69..c233a1c1bb31 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c @@ -572,10 +572,6 @@ static int r8192_wx_set_essid(struct net_device *dev, struct r8192_priv *priv = rtllib_priv(dev); int ret; - if ((rtllib_act_scanning(priv->rtllib, false)) && - !(priv->rtllib->softmac_features & IEEE_SOFTMAC_SCAN)) { - ; /* TODO - get rid of if */ - } if (priv->bHwRadioOff == true) { printk(KERN_INFO "=========>%s():hw radio off,or Rf state is " "eRfOff, return\n", __func__); @@ -708,11 +704,6 @@ static int r8192_wx_set_wap(struct net_device *dev, int ret; struct r8192_priv *priv = rtllib_priv(dev); - if ((rtllib_act_scanning(priv->rtllib, false)) && - !(priv->rtllib->softmac_features & IEEE_SOFTMAC_SCAN)) { - ; /* TODO - get rid of if */ - } - if (priv->bHwRadioOff == true) return 0; @@ -763,9 +754,6 @@ static int r8192_wx_set_enc(struct net_device *dev, {0x00, 0x00, 0x00, 0x00, 0x00, 0x03} }; int i; - if ((rtllib_act_scanning(priv->rtllib, false)) && - !(priv->rtllib->softmac_features & IEEE_SOFTMAC_SCAN)) - ; /* TODO - get rid of if */ if (priv->bHwRadioOff == true) return 0; -- GitLab From 19cd22972fbe419235b380a94f31c826809cafec Mon Sep 17 00:00:00 2001 From: Cristina Opriceana Date: Wed, 4 Mar 2015 12:37:28 +0200 Subject: [PATCH 03126/11651] Staging: drivers: Bool initializations should use true/false This patch replaces bool initializations of 1/0 with true/false in order to increase readability and respect the standards. Warning found by coccinelle. Signed-off-by: Cristina Opriceana Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_debug.c | 4 ++-- drivers/staging/lustre/lustre/llite/llite_mmap.c | 2 +- drivers/staging/rtl8192u/ieee80211/dot11d.c | 2 +- drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c | 2 +- drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c | 4 ++-- drivers/staging/rtl8192u/r8192U_core.c | 2 +- drivers/staging/rtl8192u/r8192U_dm.c | 4 ++-- drivers/staging/vt6655/rxtx.c | 4 ++-- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c b/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c index da34257f0e2b..0f776d0bf0e4 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c @@ -544,7 +544,7 @@ static long ft1000_ioctl(struct file *file, unsigned int command, if (ft1000dev->fProvComplete == 0) return -EACCES; - ft1000dev->fAppMsgPend = 1; + ft1000dev->fAppMsgPend = true; if (info->CardReady) { @@ -719,7 +719,7 @@ static long ft1000_ioctl(struct file *file, unsigned int command, result = -ENOTTY; break; } - ft1000dev->fAppMsgPend = 0; + ft1000dev->fAppMsgPend = false; return result; } diff --git a/drivers/staging/lustre/lustre/llite/llite_mmap.c b/drivers/staging/lustre/lustre/llite/llite_mmap.c index ab07959d3912..a90214bb84dd 100644 --- a/drivers/staging/lustre/lustre/llite/llite_mmap.c +++ b/drivers/staging/lustre/lustre/llite/llite_mmap.c @@ -312,7 +312,7 @@ static int ll_fault0(struct vm_area_struct *vma, struct vm_fault *vmf) vio->u.fault.ft_vmpage = NULL; vio->u.fault.fault.ft_vmf = vmf; vio->u.fault.fault.ft_flags = 0; - vio->u.fault.fault.ft_flags_valid = 0; + vio->u.fault.fault.ft_flags_valid = false; result = cl_io_loop(env, io); diff --git a/drivers/staging/rtl8192u/ieee80211/dot11d.c b/drivers/staging/rtl8192u/ieee80211/dot11d.c index 90ace791f2d7..82d60380bb40 100644 --- a/drivers/staging/rtl8192u/ieee80211/dot11d.c +++ b/drivers/staging/rtl8192u/ieee80211/dot11d.c @@ -6,7 +6,7 @@ void Dot11d_Init(struct ieee80211_device *ieee) { PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee); - pDot11dInfo->bEnabled = 0; + pDot11dInfo->bEnabled = false; pDot11dInfo->State = DOT11D_STATE_NONE; pDot11dInfo->CountryIeLen = 0; diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c index 286b71d35212..d2c2fb82f2fc 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c @@ -943,7 +943,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, if(net_ratelimit()) printk("find HTCControl\n"); hdrlen += 4; - rx_stats->bContainHTC = 1; + rx_stats->bContainHTC = true; } //IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len); diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c index 3527edc39064..878086af9445 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c @@ -1371,7 +1371,7 @@ static void ieee80211_associate_complete_wq(struct work_struct *work) else if(ieee->is_silent_reset == 1) { printk("==================>silent reset associate\n"); - ieee->is_silent_reset = 0; + ieee->is_silent_reset = false; } if (ieee->data_hard_resume) @@ -2719,7 +2719,7 @@ void ieee80211_softmac_init(struct ieee80211_device *ieee) ieee->sta_edca_param[2] = 0x005E4342; ieee->sta_edca_param[3] = 0x002F3262; ieee->aggregation = true; - ieee->enable_rx_imm_BA = 1; + ieee->enable_rx_imm_BA = true; ieee->tx_pending.txb = NULL; setup_timer(&ieee->associate_timer, ieee80211_associate_abort_cb, diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c index bab7751a7636..0d64d2dfd38c 100644 --- a/drivers/staging/rtl8192u/r8192U_core.c +++ b/drivers/staging/rtl8192u/r8192U_core.c @@ -2143,7 +2143,7 @@ static void rtl8192_init_priv_variable(struct net_device *dev) //for silent reset priv->IrpPendingCount = 1; priv->ResetProgress = RESET_TYPE_NORESET; - priv->bForcedSilentReset = 0; + priv->bForcedSilentReset = false; priv->bDisableNormalResetCheck = false; priv->force_reset = false; diff --git a/drivers/staging/rtl8192u/r8192U_dm.c b/drivers/staging/rtl8192u/r8192U_dm.c index 5a01b7d405b1..16cafcdb26c6 100644 --- a/drivers/staging/rtl8192u/r8192U_dm.c +++ b/drivers/staging/rtl8192u/r8192U_dm.c @@ -2419,9 +2419,9 @@ void dm_rf_pathcheck_workitemcallback(struct work_struct *work) /* Check Bit 0-3, it means if RF A-D is enabled. */ for (i = 0; i < RF90_PATH_MAX; i++) { if (rfpath & (0x01<brfpath_rxenable[i] = 1; + priv->brfpath_rxenable[i] = true; else - priv->brfpath_rxenable[i] = 0; + priv->brfpath_rxenable[i] = false; } if (!DM_RxPathSelTable.Enable) return; diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c index ac8c8b5a1450..2b4f005dc7fa 100644 --- a/drivers/staging/vt6655/rxtx.c +++ b/drivers/staging/vt6655/rxtx.c @@ -248,11 +248,11 @@ s_uGetDataDuration( unsigned char byFBOption ) { - bool bLastFrag = 0; + bool bLastFrag = false; unsigned int uAckTime = 0, uNextPktTime = 0; if (uFragIdx == (uMACfragNum-1)) - bLastFrag = 1; + bLastFrag = true; switch (byDurType) { case DATADUR_B: //DATADUR_B -- GitLab From 708bca5dc480412fc61030806eb0520d4c8590d7 Mon Sep 17 00:00:00 2001 From: Yeliz Taneroglu Date: Wed, 4 Mar 2015 21:32:49 +0200 Subject: [PATCH 03127/11651] Staging: unisys: Remove unnecessary semicolon This fixes the checkpatch.pl warning: WARNING: macros should not use a trailing semicolon. Signed-off-by: Yeliz Taneroglu Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/common-spar/include/channels/iochannel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/iochannel.h b/drivers/staging/unisys/common-spar/include/channels/iochannel.h index eb7efe484f6f..3bd7579e1daf 100644 --- a/drivers/staging/unisys/common-spar/include/channels/iochannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/iochannel.h @@ -337,7 +337,7 @@ struct uiscmdrsp_scsi { /* peripheral type of 3 - processor */ /* specifies device capable, but not present */ -#define DEV_HISUPPORT 0x10; /* HiSup = 1; shows support for report luns */ +#define DEV_HISUPPORT 0x10 /* HiSup = 1; shows support for report luns */ /* must be returned for lun 0. */ /* NOTE: Linux code assumes inquiry contains 36 bytes. Without checking length -- GitLab From 67d095a0405adefd019f0abaa291fe9664257f6b Mon Sep 17 00:00:00 2001 From: Yeliz Taneroglu Date: Wed, 4 Mar 2015 23:15:16 +0200 Subject: [PATCH 03128/11651] Staging: rtl8723au: Fixed error 'else should follow close brace '}". This patch fixes error 'else should follow close brace '}" found by checkpatch in driver rtl8723au. Signed-off-by: Yeliz Taneroglu Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/core/rtw_efuse.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/rtl8723au/core/rtw_efuse.c b/drivers/staging/rtl8723au/core/rtw_efuse.c index a6deddc02291..29fc25b367e5 100644 --- a/drivers/staging/rtl8723au/core/rtw_efuse.c +++ b/drivers/staging/rtl8723au/core/rtw_efuse.c @@ -304,8 +304,7 @@ EFUSE_Read1Byte23a(struct rtw_adapter *Adapter, u16 Address) } data = rtl8723au_read8(Adapter, EFUSE_CTRL); return data; - } - else + } else return 0xFF; }/* EFUSE_Read1Byte23a */ -- GitLab From 6d67b3a2f3bd82bfa75f34d9e816788d133d63b5 Mon Sep 17 00:00:00 2001 From: Ksenija Stanojevic Date: Thu, 5 Mar 2015 00:51:46 +0100 Subject: [PATCH 03129/11651] Staging: rtl8192u: Replace TRUE with true This patch replaces TRUE by true, since Linux kernel has already a boolean type, bool, defined in linux/stddef.h Signed-off-by: Ksenija Stanojevic Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c index 96ab304d327c..9f68c652fb2b 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c @@ -553,16 +553,16 @@ static void ieee80211_txrate_selectmode(struct ieee80211_device *ieee, #ifdef TO_DO_LIST if(!IsDataFrame(pFrame)) { - pTcb->bTxDisableRateFallBack = TRUE; - pTcb->bTxUseDriverAssingedRate = TRUE; + pTcb->bTxDisableRateFallBack = true; + pTcb->bTxUseDriverAssingedRate = true; pTcb->RATRIndex = 7; return; } if(pMgntInfo->ForcedDataRate!= 0) { - pTcb->bTxDisableRateFallBack = TRUE; - pTcb->bTxUseDriverAssingedRate = TRUE; + pTcb->bTxDisableRateFallBack = true; + pTcb->bTxUseDriverAssingedRate = true; return; } #endif -- GitLab From cd25503f5a6f0b0d6d66185461a358e8218db745 Mon Sep 17 00:00:00 2001 From: Haneen Mohammed Date: Thu, 5 Mar 2015 13:01:49 +0300 Subject: [PATCH 03130/11651] Staging: comedi: Clean dev_err() logging This patch removes __func__ from dev_err. dev_err includes information about: (devcice, driver, specific instance of device, etc) in the log printout, so there is no need for __func__. This was done using Coccinelle, with the following semantic patch: @a@ expression E; expression msg; @@ dev_err(E, msg, __func__); @script:python b@ e << a.msg; y; @@ if(e.find("%s: ") == True): m = e.replace("%s: ", ""); coccinelle.y = m; elif(e.find("%s ") == True): m = e.replace("%s ", ""); coccinelle.y = m; else: m = e.replace("%s", ""); @c@ expression a.E, a.msg; identifier b.y; @@ - dev_err(E, msg, __func__); + dev_err(E, y); Signed-off-by: Haneen Mohammed Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidas64.c | 6 ++-- .../staging/comedi/drivers/ni_mio_common.c | 36 +++++++------------ 2 files changed, 15 insertions(+), 27 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index 551e9d92e918..bd2405999906 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -1703,8 +1703,7 @@ static void i2c_write(struct comedi_device *dev, unsigned int address, /* get acknowledge */ if (i2c_read_ack(dev) != 0) { - dev_err(dev->class_dev, "%s failed: no acknowledge\n", - __func__); + dev_err(dev->class_dev, "failed: no acknowledge\n"); i2c_stop(dev); return; } @@ -1712,8 +1711,7 @@ static void i2c_write(struct comedi_device *dev, unsigned int address, for (i = 0; i < length; i++) { i2c_write_byte(dev, data[i]); if (i2c_read_ack(dev) != 0) { - dev_err(dev->class_dev, "%s failed: no acknowledge\n", - __func__); + dev_err(dev->class_dev, "failed: no acknowledge\n"); i2c_stop(dev); return; } diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c index b6ddc015dedf..176b64a6b567 100644 --- a/drivers/staging/comedi/drivers/ni_mio_common.c +++ b/drivers/staging/comedi/drivers/ni_mio_common.c @@ -1068,7 +1068,7 @@ static int ni_ai_drain_dma(struct comedi_device *dev) udelay(5); } if (i == timeout) { - dev_err(dev->class_dev, "%s timed out\n", __func__); + dev_err(dev->class_dev, "timed out\n"); dev_err(dev->class_dev, "mite_bytes_in_transit=%i, AI_Status1_Register=0x%x\n", mite_bytes_in_transit(devpriv->ai_mite_chan), @@ -2116,8 +2116,7 @@ static int ni_ai_insn_read(struct comedi_device *dev, } } if (i == NI_TIMEOUT) { - dev_err(dev->class_dev, "%s timeout\n", - __func__); + dev_err(dev->class_dev, "timeout\n"); return -ETIME; } d += signbits; @@ -2140,8 +2139,7 @@ static int ni_ai_insn_read(struct comedi_device *dev, } } if (i == NI_TIMEOUT) { - dev_err(dev->class_dev, "%s timeout\n", - __func__); + dev_err(dev->class_dev, "timeout\n"); return -ETIME; } data[n] = (((dl >> 16) & 0xFFFF) + signbits) & 0xFFFF; @@ -2156,8 +2154,7 @@ static int ni_ai_insn_read(struct comedi_device *dev, break; } if (i == NI_TIMEOUT) { - dev_err(dev->class_dev, "%s timeout\n", - __func__); + dev_err(dev->class_dev, "timeout\n"); return -ETIME; } if (devpriv->is_m_series) { @@ -2808,8 +2805,7 @@ static int ni_m_series_ao_config_chanlist(struct comedi_device *dev, break; default: dev_err(dev->class_dev, - "%s: bug! unhandled ao reference voltage\n", - __func__); + "bug! unhandled ao reference voltage\n"); break; } switch (krange->max + krange->min) { @@ -2821,8 +2817,7 @@ static int ni_m_series_ao_config_chanlist(struct comedi_device *dev, break; default: dev_err(dev->class_dev, - "%s: bug! unhandled ao offset voltage\n", - __func__); + "bug! unhandled ao offset voltage\n"); break; } if (timed) @@ -3694,8 +3689,7 @@ static int ni_serial_hw_readwrite8(struct comedi_device *dev, udelay((devpriv->serial_interval_ns + 999) / 1000); if (--count < 0) { dev_err(dev->class_dev, - "%s: SPI serial I/O didn't finish in time!\n", - __func__); + "SPI serial I/O didn't finish in time!\n"); err = -ETIME; goto Error; } @@ -3833,8 +3827,7 @@ static int ni_serial_insn_config(struct comedi_device *dev, err = ni_serial_sw_readwrite8(dev, s, byte_out, &byte_in); } else { - dev_err(dev->class_dev, "%s: serial disabled!\n", - __func__); + dev_err(dev->class_dev, "serial disabled!\n"); return -EINVAL; } if (err < 0) @@ -4520,8 +4513,7 @@ static unsigned ni_old_get_pfi_routing(struct comedi_device *dev, case 9: return NI_PFI_OUTPUT_G_GATE0; default: - dev_err(dev->class_dev, - "%s: bug, unhandled case in switch.\n", __func__); + dev_err(dev->class_dev, "bug, unhandled case in switch.\n"); break; } return 0; @@ -4673,7 +4665,7 @@ static int cs5529_wait_for_idle(struct comedi_device *dev) return -EIO; } if (i == timeout) { - dev_err(dev->class_dev, "%s timeout\n", __func__); + dev_err(dev->class_dev, "timeout\n"); return -ETIME; } return 0; @@ -4908,7 +4900,7 @@ static int ni_mseries_set_pll_master_clock(struct comedi_device *dev, &devpriv->clock_ns); if (retval < 0) { dev_err(dev->class_dev, - "%s: bug, failed to find pll parameters\n", __func__); + "bug, failed to find pll parameters\n"); return retval; } @@ -4966,8 +4958,7 @@ static int ni_set_master_clock(struct comedi_device *dev, RTSI_Trig_Direction_Register); if (period_ns == 0) { dev_err(dev->class_dev, - "%s: we don't handle an unspecified clock period correctly yet, returning error\n", - __func__); + "we don't handle an unspecified clock period correctly yet, returning error\n"); return -EINVAL; } devpriv->clock_ns = period_ns; @@ -5057,8 +5048,7 @@ static unsigned ni_get_rtsi_routing(struct comedi_device *dev, unsigned chan) } else { if (chan == old_RTSI_clock_channel) return NI_RTSI_OUTPUT_RTSI_OSC; - dev_err(dev->class_dev, "%s: bug! should never get here?\n", - __func__); + dev_err(dev->class_dev, "bug! should never get here?\n"); return 0; } } -- GitLab From 14f63eeecfa3ca092f1c83755303161e53a9c641 Mon Sep 17 00:00:00 2001 From: Haneen Mohammed Date: Fri, 6 Mar 2015 20:01:07 +0300 Subject: [PATCH 03131/11651] Staging: media: Replace dev_err with pr_err to avoid null pointer derefrence This patch replace dev_err with pr_err, for pointer is derefrenced after comparing it to NULL. This was found using the following coccinelle script: @disable is_null@ identifier f; expression E; identifier fld; statement S; @@ + if(E == NULL) S f(...,E->fld,...); -if(E == NULL) S; @@ identifier f; expression E; identifier fld; statement S; @@ + if(!E) S f(...,E->fld,...); -if(!E) S; Signed-off-by: Haneen Mohammed Signed-off-by: Greg Kroah-Hartman --- drivers/staging/media/lirc/lirc_zilog.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/media/lirc/lirc_zilog.c b/drivers/staging/media/lirc/lirc_zilog.c index e16627ca488e..261e27d6b054 100644 --- a/drivers/staging/media/lirc/lirc_zilog.c +++ b/drivers/staging/media/lirc/lirc_zilog.c @@ -1341,8 +1341,7 @@ static int close(struct inode *node, struct file *filep) struct IR *ir = filep->private_data; if (ir == NULL) { - dev_err(ir->l.dev, - "close: no private_data attached to the file!\n"); + pr_err("ir: close: no private_data attached to the file!\n"); return -ENODEV; } -- GitLab From aed1c72e447f0ac0985eecbe1c2403eb7176d606 Mon Sep 17 00:00:00 2001 From: Haneen Mohammed Date: Fri, 6 Mar 2015 21:59:04 +0300 Subject: [PATCH 03132/11651] Staging: fbtft: clean dev_err() logging This patch removes __func__ from dev_err. dev_err includes information about: (devcice, driver, specific instance of device, etc) in the log printout. This was done using Coccinelle, with the following semantic patch: @a@ expression E, R; expression msg; @@ dev_err(E, msg, __func__, R); @script:python b@ e << a.msg; y; @@ if(e.find("%s: ") == True): m = e.replace("%s: ", "", 1); coccinelle.y = m; elif(e.find("%s ") == True): m = e.replace("%s ", "", 1); coccinelle.y = m; elif(e.find("%s:") == True): m = e.replace("%s:", "", 1); coccinelle.y = m; else: m = e.replace("%s", "",1); coccinelle.y = m; @c@ expression a.E, a.msg, a.R; identifier b.y; @@ - dev_err(E, msg, __func__, R); + dev_err(E, y, R); Signed-off-by: Haneen Mohammed Signed-off-by: Greg Kroah-Hartman --- drivers/staging/fbtft/fb_agm1264k-fl.c | 16 ++++++++-------- drivers/staging/fbtft/fb_pcd8544.c | 3 ++- drivers/staging/fbtft/fb_ra8875.c | 8 ++++---- drivers/staging/fbtft/fb_ssd1306.c | 4 ++-- drivers/staging/fbtft/fb_ssd1331.c | 6 ++++-- drivers/staging/fbtft/fb_tls8204.c | 2 +- drivers/staging/fbtft/fb_uc1701.c | 3 ++- drivers/staging/fbtft/fb_watterott.c | 2 +- drivers/staging/fbtft/fbtft-bus.c | 2 +- drivers/staging/fbtft/fbtft-core.c | 5 ++--- drivers/staging/fbtft/fbtft-io.c | 7 +++---- 11 files changed, 30 insertions(+), 28 deletions(-) diff --git a/drivers/staging/fbtft/fb_agm1264k-fl.c b/drivers/staging/fbtft/fb_agm1264k-fl.c index 9cc7d25cf0e5..7aa9e8c0763d 100644 --- a/drivers/staging/fbtft/fb_agm1264k-fl.c +++ b/drivers/staging/fbtft/fb_agm1264k-fl.c @@ -198,8 +198,8 @@ static void write_reg8_bus8(struct fbtft_par *par, int len, ...) if (*buf > 1) { va_end(args); - dev_err(par->info->device, "%s: Incorrect chip sellect request (%d)\n", - __func__, *buf); + dev_err(par->info->device, + "Incorrect chip sellect request (%d)\n", *buf); return; } @@ -224,8 +224,8 @@ static void write_reg8_bus8(struct fbtft_par *par, int len, ...) ret = par->fbtftops.write(par, par->buf, len * (sizeof(u8))); if (ret < 0) { va_end(args); - dev_err(par->info->device, "%s: write() failed and returned %d\n", - __func__, ret); + dev_err(par->info->device, + "write() failed and returned %d\n", ret); return; } } @@ -376,8 +376,8 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len) ret = par->fbtftops.write(par, buf, len); if (ret < 0) dev_err(par->info->device, - "%s: write failed and returned: %d\n", - __func__, ret); + "write failed and returned: %d\n", + ret); } /* right half of display */ if (addr_win.xe >= par->info->var.xres / 2) { @@ -398,8 +398,8 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len) par->fbtftops.write(par, buf, len); if (ret < 0) dev_err(par->info->device, - "%s: write failed and returned: %d\n", - __func__, ret); + "write failed and returned: %d\n", + ret); } } kfree(convert_buf); diff --git a/drivers/staging/fbtft/fb_pcd8544.c b/drivers/staging/fbtft/fb_pcd8544.c index 5e08a70c25b4..b13162c35508 100644 --- a/drivers/staging/fbtft/fb_pcd8544.c +++ b/drivers/staging/fbtft/fb_pcd8544.c @@ -130,7 +130,8 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len) gpio_set_value(par->gpio.dc, 1); ret = par->fbtftops.write(par, par->txbuf.buf, 6*84); if (ret < 0) - dev_err(par->info->device, "%s: write failed and returned: %d\n", __func__, ret); + dev_err(par->info->device, "write failed and returned: %d\n", + ret); return ret; } diff --git a/drivers/staging/fbtft/fb_ra8875.c b/drivers/staging/fbtft/fb_ra8875.c index 8df97373e183..e21af6c5a95f 100644 --- a/drivers/staging/fbtft/fb_ra8875.c +++ b/drivers/staging/fbtft/fb_ra8875.c @@ -238,8 +238,8 @@ static void write_reg8_bus8(struct fbtft_par *par, int len, ...) ret = par->fbtftops.write(par, par->buf, 2); if (ret < 0) { va_end(args); - dev_err(par->info->device, "%s: write() failed and returned %dn", - __func__, ret); + dev_err(par->info->device, "write() failed and returned %dn", + ret); return; } len--; @@ -256,8 +256,8 @@ static void write_reg8_bus8(struct fbtft_par *par, int len, ...) ret = par->fbtftops.write(par, par->buf, len + 1); if (ret < 0) { va_end(args); - dev_err(par->info->device, "%s: write() failed and returned %dn", - __func__, ret); + dev_err(par->info->device, + "write() failed and returned %dn", ret); return; } } diff --git a/drivers/staging/fbtft/fb_ssd1306.c b/drivers/staging/fbtft/fb_ssd1306.c index 5ea195b0de1b..15ee44dd130b 100644 --- a/drivers/staging/fbtft/fb_ssd1306.c +++ b/drivers/staging/fbtft/fb_ssd1306.c @@ -193,8 +193,8 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len) ret = par->fbtftops.write(par, par->txbuf.buf, par->info->var.xres*par->info->var.yres/8); if (ret < 0) - dev_err(par->info->device, - "%s: write failed and returned: %d\n", __func__, ret); + dev_err(par->info->device, "write failed and returned: %d\n", + ret); return ret; } diff --git a/drivers/staging/fbtft/fb_ssd1331.c b/drivers/staging/fbtft/fb_ssd1331.c index ba17f0c83ec5..5bb741046c85 100644 --- a/drivers/staging/fbtft/fb_ssd1331.c +++ b/drivers/staging/fbtft/fb_ssd1331.c @@ -83,7 +83,8 @@ static void write_reg8_bus8(struct fbtft_par *par, int len, ...) ret = par->fbtftops.write(par, par->buf, sizeof(u8)); if (ret < 0) { va_end(args); - dev_err(par->info->device, "%s: write() failed and returned %d\n", __func__, ret); + dev_err(par->info->device, + "write() failed and returned %d\n", ret); return; } len--; @@ -95,7 +96,8 @@ static void write_reg8_bus8(struct fbtft_par *par, int len, ...) ret = par->fbtftops.write(par, par->buf, len * (sizeof(u8))); if (ret < 0) { va_end(args); - dev_err(par->info->device, "%s: write() failed and returned %d\n", __func__, ret); + dev_err(par->info->device, + "write() failed and returned %d\n", ret); return; } } diff --git a/drivers/staging/fbtft/fb_tls8204.c b/drivers/staging/fbtft/fb_tls8204.c index 8738c7a7bfda..fcd38bf2ed79 100644 --- a/drivers/staging/fbtft/fb_tls8204.c +++ b/drivers/staging/fbtft/fb_tls8204.c @@ -127,7 +127,7 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len) ret = par->fbtftops.write(par, par->txbuf.buf, WIDTH); if (ret < 0) { dev_err(par->info->device, - "%s: write failed and returned: %d\n", __func__, ret); + "write failed and returned: %d\n", ret); break; } } diff --git a/drivers/staging/fbtft/fb_uc1701.c b/drivers/staging/fbtft/fb_uc1701.c index d70ac524278c..26d669b57916 100644 --- a/drivers/staging/fbtft/fb_uc1701.c +++ b/drivers/staging/fbtft/fb_uc1701.c @@ -183,7 +183,8 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len) } if (ret < 0) - dev_err(par->info->device, "%s: write failed and returned: %d\n", __func__, ret); + dev_err(par->info->device, "write failed and returned: %d\n", + ret); return ret; } diff --git a/drivers/staging/fbtft/fb_watterott.c b/drivers/staging/fbtft/fb_watterott.c index 975b579359f3..88fb2c0132d5 100644 --- a/drivers/staging/fbtft/fb_watterott.c +++ b/drivers/staging/fbtft/fb_watterott.c @@ -65,7 +65,7 @@ static void write_reg8_bus8(struct fbtft_par *par, int len, ...) ret = par->fbtftops.write(par, par->buf, len); if (ret < 0) { dev_err(par->info->device, - "%s: write() failed and returned %d\n", __func__, ret); + "write() failed and returned %d\n", ret); return; } } diff --git a/drivers/staging/fbtft/fbtft-bus.c b/drivers/staging/fbtft/fbtft-bus.c index b3cddb0b3d69..52af9cbbc2a6 100644 --- a/drivers/staging/fbtft/fbtft-bus.c +++ b/drivers/staging/fbtft/fbtft-bus.c @@ -111,7 +111,7 @@ void fbtft_write_reg8_bus9(struct fbtft_par *par, int len, ...) ret = par->fbtftops.write(par, par->buf, (len + pad) * sizeof(u16)); if (ret < 0) { dev_err(par->info->device, - "%s: write() failed and returned %d\n", __func__, ret); + "write() failed and returned %d\n", ret); return; } } diff --git a/drivers/staging/fbtft/fbtft-core.c b/drivers/staging/fbtft/fbtft-core.c index 3c4769aab678..fd9f92e2dba6 100644 --- a/drivers/staging/fbtft/fbtft-core.c +++ b/drivers/staging/fbtft/fbtft-core.c @@ -703,9 +703,8 @@ struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display, /* sanity check */ if (display->gamma_num * display->gamma_len > FBTFT_GAMMA_MAX_VALUES_TOTAL) { - dev_err(dev, - "%s: FBTFT_GAMMA_MAX_VALUES_TOTAL=%d is exceeded\n", - __func__, FBTFT_GAMMA_MAX_VALUES_TOTAL); + dev_err(dev, "FBTFT_GAMMA_MAX_VALUES_TOTAL=%d is exceeded\n", + FBTFT_GAMMA_MAX_VALUES_TOTAL); return NULL; } diff --git a/drivers/staging/fbtft/fbtft-io.c b/drivers/staging/fbtft/fbtft-io.c index 9b2f8cfbb386..e19b814c3327 100644 --- a/drivers/staging/fbtft/fbtft-io.c +++ b/drivers/staging/fbtft/fbtft-io.c @@ -59,8 +59,7 @@ int fbtft_write_spi_emulate_9(struct fbtft_par *par, void *buf, size_t len) } if ((len % 8) != 0) { dev_err(par->info->device, - "%s: error: len=%zu must be divisible by 8\n", - __func__, len); + "error: len=%zu must be divisible by 8\n", len); return -EINVAL; } @@ -106,8 +105,8 @@ int fbtft_read_spi(struct fbtft_par *par, void *buf, size_t len) if (par->startbyte) { if (len > 32) { dev_err(par->info->device, - "%s: len=%zu can't be larger than 32 when using 'startbyte'\n", - __func__, len); + "len=%zu can't be larger than 32 when using 'startbyte'\n", + len); return -EINVAL; } txbuf[0] = par->startbyte | 0x3; -- GitLab From 8c6ccbeb510fe48ed8808067cd7cbf92f7e8ebac Mon Sep 17 00:00:00 2001 From: Haneen Mohammed Date: Fri, 6 Mar 2015 22:00:10 +0300 Subject: [PATCH 03133/11651] Staging: media: clean dev_err logging This patch removes __func__ from dev_err. dev_err includes information about: (devcice, driver, specific instance of device, etc) in the log printout. This was done using Coccinelle, with the following semantic patch: @a@ expression E, R; expression msg; @@ dev_err(E, msg, __func__, R); @script:python b@ e << a.msg; y; @@ if(e.find("%s: ") == True): m = e.replace("%s: ", "", 1); coccinelle.y = m; elif(e.find("%s ") == True): m = e.replace("%s ", "", 1); coccinelle.y = m; elif(e.find("%s:") == True): m = e.replace("%s:", "", 1); coccinelle.y = m; else: m = e.replace("%s", "",1); coccinelle.y = m; @c@ expression a.E, a.msg, a.R; identifier b.y; @@ - dev_err(E, msg, __func__, R); + dev_err(E, y, R); Signed-off-by: Haneen Mohammed Signed-off-by: Greg Kroah-Hartman --- drivers/staging/media/lirc/lirc_imon.c | 26 +++++++++------------- drivers/staging/media/lirc/lirc_sasem.c | 18 ++++++--------- drivers/staging/media/omap4iss/iss.c | 16 ++++++------- drivers/staging/media/omap4iss/iss_video.c | 3 +-- 4 files changed, 27 insertions(+), 36 deletions(-) diff --git a/drivers/staging/media/lirc/lirc_imon.c b/drivers/staging/media/lirc/lirc_imon.c index 9ce7d9990e3e..2e883e9457db 100644 --- a/drivers/staging/media/lirc/lirc_imon.c +++ b/drivers/staging/media/lirc/lirc_imon.c @@ -208,8 +208,7 @@ static void deregister_from_lirc(struct imon_context *context) retval = lirc_unregister_driver(minor); if (retval) dev_err(&context->usbdev->dev, - ": %s: unable to deregister from lirc(%d)", - __func__, retval); + "unable to deregister from lirc(%d)", retval); else dev_info(&context->usbdev->dev, "Deregistered iMON driver (minor:%d)\n", minor); @@ -241,9 +240,8 @@ static int display_open(struct inode *inode, struct file *file) context = usb_get_intfdata(interface); if (!context) { - dev_err(&interface->dev, - "%s: no context found for minor %d\n", - __func__, subminor); + dev_err(&interface->dev, "no context found for minor %d\n", + subminor); retval = -ENODEV; goto exit; } @@ -344,8 +342,8 @@ static int send_packet(struct imon_context *context) retval = usb_submit_urb(context->tx_urb, GFP_KERNEL); if (retval) { atomic_set(&(context->tx.busy), 0); - dev_err(&context->usbdev->dev, - "%s: error submitting urb(%d)\n", __func__, retval); + dev_err(&context->usbdev->dev, "error submitting urb(%d)\n", + retval); } else { /* Wait for transmission to complete (or abort) */ mutex_unlock(&context->ctx_lock); @@ -359,8 +357,7 @@ static int send_packet(struct imon_context *context) retval = context->tx.status; if (retval) dev_err(&context->usbdev->dev, - "%s: packet tx failed (%d)\n", - __func__, retval); + "packet tx failed (%d)\n", retval); } return retval; @@ -437,8 +434,8 @@ static ssize_t vfd_write(struct file *file, const char __user *buf, retval = send_packet(context); if (retval) { dev_err(&context->usbdev->dev, - "%s: send packet failed for packet #%d\n", - __func__, seq/2); + "send packet failed for packet #%d\n", + seq / 2); goto exit; } else { seq += 2; @@ -454,8 +451,8 @@ static ssize_t vfd_write(struct file *file, const char __user *buf, retval = send_packet(context); if (retval) dev_err(&context->usbdev->dev, - "%s: send packet failed for packet #%d\n", - __func__, seq/2); + "send packet failed for packet #%d\n", + seq / 2); } exit: @@ -877,8 +874,7 @@ static int imon_probe(struct usb_interface *interface, retval = usb_submit_urb(context->rx_urb, GFP_KERNEL); if (retval) { - dev_err(dev, "%s: usb_submit_urb failed for intf0 (%d)\n", - __func__, retval); + dev_err(dev, "usb_submit_urb failed for intf0 (%d)\n", retval); alloc_status = 8; goto unlock; } diff --git a/drivers/staging/media/lirc/lirc_sasem.c b/drivers/staging/media/lirc/lirc_sasem.c index 4a268200cbf5..9944af1ba4d3 100644 --- a/drivers/staging/media/lirc/lirc_sasem.c +++ b/drivers/staging/media/lirc/lirc_sasem.c @@ -214,9 +214,8 @@ static int vfd_open(struct inode *inode, struct file *file) context = usb_get_intfdata(interface); if (!context) { - dev_err(&interface->dev, - "%s: no context found for minor %d\n", - __func__, subminor); + dev_err(&interface->dev, "no context found for minor %d\n", + subminor); retval = -ENODEV; goto exit; } @@ -337,8 +336,8 @@ static int send_packet(struct sasem_context *context) retval = usb_submit_urb(context->tx_urb, GFP_KERNEL); if (retval) { atomic_set(&(context->tx.busy), 0); - dev_err(&context->dev->dev, "%s: error submitting urb (%d)\n", - __func__, retval); + dev_err(&context->dev->dev, "error submitting urb (%d)\n", + retval); } else { /* Wait for transmission to complete (or abort) */ mutex_unlock(&context->ctx_lock); @@ -348,8 +347,7 @@ static int send_packet(struct sasem_context *context) retval = context->tx.status; if (retval) dev_err(&context->dev->dev, - "%s: packet tx failed (%d)\n", - __func__, retval); + "packet tx failed (%d)\n", retval); } return retval; @@ -444,8 +442,7 @@ static ssize_t vfd_write(struct file *file, const char __user *buf, retval = send_packet(context); if (retval) { dev_err(&context->dev->dev, - "%s: send packet failed for packet #%d\n", - __func__, i); + "send packet failed for packet #%d\n", i); goto exit; } } @@ -509,8 +506,7 @@ static int ir_open(void *data) if (retval) dev_err(&context->dev->dev, - "%s: usb_submit_urb failed for ir_open (%d)\n", - __func__, retval); + "usb_submit_urb failed for ir_open (%d)\n", retval); else { context->ir_isopen = 1; dev_info(&context->dev->dev, "IR port opened\n"); diff --git a/drivers/staging/media/omap4iss/iss.c b/drivers/staging/media/omap4iss/iss.c index 44b81a2c8b6f..e0ad5e520e2d 100644 --- a/drivers/staging/media/omap4iss/iss.c +++ b/drivers/staging/media/omap4iss/iss.c @@ -1160,8 +1160,8 @@ iss_register_subdev_group(struct iss_device *iss, subdev = v4l2_i2c_new_subdev_board(&iss->v4l2_dev, adapter, board_info->board_info, NULL); if (subdev == NULL) { - dev_err(iss->dev, "%s: Unable to register subdev %s\n", - __func__, board_info->board_info->type); + dev_err(iss->dev, "Unable to register subdev %s\n", + board_info->board_info->type); continue; } @@ -1185,16 +1185,16 @@ static int iss_register_entities(struct iss_device *iss) iss->media_dev.link_notify = iss_pipeline_link_notify; ret = media_device_register(&iss->media_dev); if (ret < 0) { - dev_err(iss->dev, "%s: Media device registration failed (%d)\n", - __func__, ret); + dev_err(iss->dev, "Media device registration failed (%d)\n", + ret); return ret; } iss->v4l2_dev.mdev = &iss->media_dev; ret = v4l2_device_register(iss->dev, &iss->v4l2_dev); if (ret < 0) { - dev_err(iss->dev, "%s: V4L2 device registration failed (%d)\n", - __func__, ret); + dev_err(iss->dev, "V4L2 device registration failed (%d)\n", + ret); goto done; } @@ -1252,8 +1252,8 @@ static int iss_register_entities(struct iss_device *iss) break; default: - dev_err(iss->dev, "%s: invalid interface type %u\n", - __func__, subdevs->interface); + dev_err(iss->dev, "invalid interface type %u\n", + subdevs->interface); ret = -EINVAL; goto done; } diff --git a/drivers/staging/media/omap4iss/iss_video.c b/drivers/staging/media/omap4iss/iss_video.c index 69550445a341..55938cccde7f 100644 --- a/drivers/staging/media/omap4iss/iss_video.c +++ b/drivers/staging/media/omap4iss/iss_video.c @@ -1221,8 +1221,7 @@ int omap4iss_video_register(struct iss_video *video, struct v4l2_device *vdev) ret = video_register_device(&video->video, VFL_TYPE_GRABBER, -1); if (ret < 0) dev_err(video->iss->dev, - "%s: could not register video device (%d)\n", - __func__, ret); + "could not register video device (%d)\n", ret); return ret; } -- GitLab From 99beca13675c842b83d83e5d5b24d3a80dde1f58 Mon Sep 17 00:00:00 2001 From: Haneen Mohammed Date: Fri, 6 Mar 2015 22:00:42 +0300 Subject: [PATCH 03134/11651] Staging: gdm72xx: clean dev_err logging This patch removes __func__ from dev_err. dev_err includes information about: (devcice, driver, specific instance of device, etc) in the log printout. This was done using Coccinelle, with the following semantic patch: @a@ expression E, R; expression msg; @@ dev_err(E, msg, __func__, R); @script:python b@ e << a.msg; y; @@ if(e.find("%s: ") == True): m = e.replace("%s: ", "", 1); coccinelle.y = m; elif(e.find("%s ") == True): m = e.replace("%s ", "", 1); coccinelle.y = m; elif(e.find("%s:") == True): m = e.replace("%s:", "", 1); coccinelle.y = m; else: m = e.replace("%s", "",1); coccinelle.y = m; @c@ expression a.E, a.msg, a.R; identifier b.y; @@ - dev_err(E, msg, __func__, R); + dev_err(E, y, R); Signed-off-by: Haneen Mohammed Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gdm72xx/gdm_sdio.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/staging/gdm72xx/gdm_sdio.c b/drivers/staging/gdm72xx/gdm_sdio.c index 7a0a0f221418..a5fd0794842e 100644 --- a/drivers/staging/gdm72xx/gdm_sdio.c +++ b/drivers/staging/gdm72xx/gdm_sdio.c @@ -223,8 +223,7 @@ static void send_sdio_pkt(struct sdio_func *func, u8 *data, int len) if (ret < 0) { if (ret != -ENOMEDIUM) dev_err(&func->dev, - "gdmwms: %s error: ret = %d\n", - __func__, ret); + "gdmwms: error: ret = %d\n", ret); goto end_io; } } @@ -237,8 +236,7 @@ static void send_sdio_pkt(struct sdio_func *func, u8 *data, int len) if (ret < 0) { if (ret != -ENOMEDIUM) dev_err(&func->dev, - "gdmwms: %s error: ret = %d\n", - __func__, ret); + "gdmwms: error: ret = %d\n", ret); goto end_io; } } -- GitLab From ce82410c76374be44a4dbd60b906e896a5e20687 Mon Sep 17 00:00:00 2001 From: Haneen Mohammed Date: Fri, 6 Mar 2015 22:01:38 +0300 Subject: [PATCH 03135/11651] Staging: comedi: clean dev_err logging This patch removes __func__ from dev_err. dev_err includes information about: (devcice, driver, specific instance of device, etc) in the log printout. This was done using Coccinelle, with the following semantic patch: @a@ expression E, R; expression msg; @@ dev_err(E, msg, __func__, R); @script:python b@ e << a.msg; y; @@ if(e.find("%s: ") == True): m = e.replace("%s: ", "", 1); coccinelle.y = m; elif(e.find("%s ") == True): m = e.replace("%s ", "", 1); coccinelle.y = m; elif(e.find("%s:") == True): m = e.replace("%s:", "", 1); coccinelle.y = m; else: m = e.replace("%s", "",1); coccinelle.y = m; @c@ expression a.E, a.msg, a.R; identifier b.y; @@ - dev_err(E, msg, __func__, R); + dev_err(E, y, R); Signed-off-by: Haneen Mohammed Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/ni_mio_common.c | 4 +-- drivers/staging/comedi/drivers/usbduxsigma.c | 26 ++++++++----------- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c index 176b64a6b567..97728d25da53 100644 --- a/drivers/staging/comedi/drivers/ni_mio_common.c +++ b/drivers/staging/comedi/drivers/ni_mio_common.c @@ -670,8 +670,8 @@ static inline void ni_set_bitfield(struct comedi_device *dev, int reg, ni_writeb(dev, devpriv->g0_g1_select_reg, G0_G1_Select); break; default: - dev_err(dev->class_dev, - "%s called with invalid register %d\n", __func__, reg); + dev_err(dev->class_dev, "called with invalid register %d\n", + reg); break; } mmiowb(); diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c index 394969b7458c..f50cf8a8dada 100644 --- a/drivers/staging/comedi/drivers/usbduxsigma.c +++ b/drivers/staging/comedi/drivers/usbduxsigma.c @@ -243,9 +243,8 @@ static void usbduxsigma_ai_handle_urb(struct comedi_device *dev, urb->dev = comedi_to_usb_dev(dev); ret = usb_submit_urb(urb, GFP_ATOMIC); if (ret < 0) { - dev_err(dev->class_dev, - "%s: urb resubmit failed (%d)\n", - __func__, ret); + dev_err(dev->class_dev, "urb resubmit failed (%d)\n", + ret); if (ret == -EL2NSYNC) dev_err(dev->class_dev, "buggy USB host controller or bug in IRQ handler\n"); @@ -292,8 +291,8 @@ static void usbduxsigma_ai_urb_complete(struct urb *urb) default: /* a real error */ - dev_err(dev->class_dev, "%s: non-zero urb status (%d)\n", - __func__, urb->status); + dev_err(dev->class_dev, "non-zero urb status (%d)\n", + urb->status); async->events |= COMEDI_CB_ERROR; break; } @@ -386,9 +385,8 @@ static void usbduxsigma_ao_handle_urb(struct comedi_device *dev, urb->iso_frame_desc[0].status = 0; ret = usb_submit_urb(urb, GFP_ATOMIC); if (ret < 0) { - dev_err(dev->class_dev, - "%s: urb resubmit failed (%d)\n", - __func__, ret); + dev_err(dev->class_dev, "urb resubmit failed (%d)\n", + ret); if (ret == -EL2NSYNC) dev_err(dev->class_dev, "buggy USB host controller or bug in IRQ handler\n"); @@ -423,8 +421,8 @@ static void usbduxsigma_ao_urb_complete(struct urb *urb) default: /* a real error */ - dev_err(dev->class_dev, "%s: non-zero urb status (%d)\n", - __func__, urb->status); + dev_err(dev->class_dev, "non-zero urb status (%d)\n", + urb->status); async->events |= COMEDI_CB_ERROR; break; } @@ -1071,9 +1069,8 @@ static void usbduxsigma_pwm_urb_complete(struct urb *urb) default: /* a real error */ if (devpriv->pwm_cmd_running) { - dev_err(dev->class_dev, - "%s: non-zero urb status (%d)\n", - __func__, urb->status); + dev_err(dev->class_dev, "non-zero urb status (%d)\n", + urb->status); usbduxsigma_pwm_stop(dev, 0); /* w/o unlink */ } return; @@ -1087,8 +1084,7 @@ static void usbduxsigma_pwm_urb_complete(struct urb *urb) urb->status = 0; ret = usb_submit_urb(urb, GFP_ATOMIC); if (ret < 0) { - dev_err(dev->class_dev, "%s: urb resubmit failed (%d)\n", - __func__, ret); + dev_err(dev->class_dev, "urb resubmit failed (%d)\n", ret); if (ret == -EL2NSYNC) dev_err(dev->class_dev, "buggy USB host controller or bug in IRQ handler\n"); -- GitLab From 651cd163ba038079fd4796f046ba77c216e22a2c Mon Sep 17 00:00:00 2001 From: Haneen Mohammed Date: Fri, 6 Mar 2015 22:03:05 +0300 Subject: [PATCH 03136/11651] Staging: rts5208: clean dev_err logging This patch removes __func__ from dev_err. dev_err includes information about: (devcice, driver, specific instance of device, etc) in the log printout. This was done using Coccinelle, with the following semantic patch: @a@ expression E, R; expression msg; @@ dev_err(E, msg, __func__, R); @script:python b@ e << a.msg; y; @@ if(e.find("%s: ") == True): m = e.replace("%s: ", "", 1); coccinelle.y = m; elif(e.find("%s ") == True): m = e.replace("%s ", "", 1); coccinelle.y = m; elif(e.find("%s:") == True): m = e.replace("%s:", "", 1); coccinelle.y = m; else: m = e.replace("%s", "",1); coccinelle.y = m; @c@ expression a.E, a.msg, a.R; identifier b.y; @@ - dev_err(E, msg, __func__, R); + dev_err(E, y, R); Signed-off-by: Haneen Mohammed Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rts5208/rtsx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rts5208/rtsx.c b/drivers/staging/rts5208/rtsx.c index c74f1b8108f6..7f2c0c38e840 100644 --- a/drivers/staging/rts5208/rtsx.c +++ b/drivers/staging/rts5208/rtsx.c @@ -137,8 +137,8 @@ static int queuecommand_lck(struct scsi_cmnd *srb, /* check for state-transition errors */ if (chip->srb != NULL) { - dev_err(&dev->pci->dev, "Error in %s: chip->srb = %p\n", - __func__, chip->srb); + dev_err(&dev->pci->dev, "Error: chip->srb = %p\n", + chip->srb); return SCSI_MLQUEUE_HOST_BUSY; } -- GitLab From 3daf9df3bab88a14135b5b83713c64d5a58af60d Mon Sep 17 00:00:00 2001 From: Haneen Mohammed Date: Fri, 6 Mar 2015 22:03:53 +0300 Subject: [PATCH 03137/11651] Staging: iio: clean dev_err logging This patch removes __func__ from dev_err. dev_err includes information about: (devcice, driver, specific instance of device, etc) in the log printout. This was done using Coccinelle, with the following semantic patch: @a@ expression E, R; expression msg; @@ dev_err(E, msg, __func__, R); @script:python b@ e << a.msg; y; @@ if(e.find("%s: ") == True): m = e.replace("%s: ", "", 1); coccinelle.y = m; elif(e.find("%s ") == True): m = e.replace("%s ", "", 1); coccinelle.y = m; elif(e.find("%s:") == True): m = e.replace("%s:", "", 1); coccinelle.y = m; else: m = e.replace("%s", "",1); coccinelle.y = m; @c@ expression a.E, a.msg, a.R; identifier b.y; @@ - dev_err(E, msg, __func__, R); + dev_err(E, y, R); Signed-off-by: Haneen Mohammed Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/light/isl29028.c | 8 +++--- drivers/staging/iio/light/tsl2x7x_core.c | 34 ++++++++++-------------- 2 files changed, 18 insertions(+), 24 deletions(-) diff --git a/drivers/staging/iio/light/isl29028.c b/drivers/staging/iio/light/isl29028.c index 6440e3b293ca..e5b2fdc2334b 100644 --- a/drivers/staging/iio/light/isl29028.c +++ b/drivers/staging/iio/light/isl29028.c @@ -441,15 +441,15 @@ static int isl29028_chip_init(struct isl29028_chip *chip) ret = isl29028_set_proxim_sampling(chip, chip->prox_sampling); if (ret < 0) { - dev_err(chip->dev, "%s(): setting the proximity, err = %d\n", - __func__, ret); + dev_err(chip->dev, "setting the proximity, err = %d\n", + ret); return ret; } ret = isl29028_set_als_scale(chip, chip->lux_scale); if (ret < 0) - dev_err(chip->dev, "%s(): setting als scale failed, err = %d\n", - __func__, ret); + dev_err(chip->dev, + "setting als scale failed, err = %d\n", ret); return ret; } diff --git a/drivers/staging/iio/light/tsl2x7x_core.c b/drivers/staging/iio/light/tsl2x7x_core.c index 4a5dc26fed4c..52f4e65fcdf1 100644 --- a/drivers/staging/iio/light/tsl2x7x_core.c +++ b/drivers/staging/iio/light/tsl2x7x_core.c @@ -301,8 +301,7 @@ tsl2x7x_i2c_read(struct i2c_client *client, u8 reg, u8 *val) /* select register to write */ ret = i2c_smbus_write_byte(client, (TSL2X7X_CMD_REG | reg)); if (ret < 0) { - dev_err(&client->dev, "%s: failed to write register %x\n" - , __func__, reg); + dev_err(&client->dev, "failed to write register %x\n", reg); return ret; } @@ -311,8 +310,7 @@ tsl2x7x_i2c_read(struct i2c_client *client, u8 reg, u8 *val) if (ret >= 0) *val = (u8)ret; else - dev_err(&client->dev, "%s: failed to read register %x\n" - , __func__, reg); + dev_err(&client->dev, "failed to read register %x\n", reg); return ret; } @@ -377,7 +375,7 @@ static int tsl2x7x_get_lux(struct iio_dev *indio_dev) &buf[i]); if (ret < 0) { dev_err(&chip->client->dev, - "%s: failed to read. err=%x\n", __func__, ret); + "failed to read. err=%x\n", ret); goto out_unlock; } } @@ -389,8 +387,7 @@ static int tsl2x7x_get_lux(struct iio_dev *indio_dev) TSL2X7X_CMD_ALS_INT_CLR)); if (ret < 0) { dev_err(&chip->client->dev, - "%s: i2c_write_command failed - err = %d\n", - __func__, ret); + "i2c_write_command failed - err = %d\n", ret); goto out_unlock; /* have no data, so return failure */ } @@ -493,8 +490,7 @@ static int tsl2x7x_get_prox(struct iio_dev *indio_dev) ret = tsl2x7x_i2c_read(chip->client, (TSL2X7X_CMD_REG | TSL2X7X_STATUS), &status); if (ret < 0) { - dev_err(&chip->client->dev, - "%s: i2c err=%d\n", __func__, ret); + dev_err(&chip->client->dev, "i2c err=%d\n", ret); goto prox_poll_err; } @@ -583,8 +579,7 @@ static int tsl2x7x_als_calibrate(struct iio_dev *indio_dev) (TSL2X7X_CMD_REG | TSL2X7X_CNTRL)); if (ret < 0) { dev_err(&chip->client->dev, - "%s: failed to write CNTRL register, ret=%d\n", - __func__, ret); + "failed to write CNTRL register, ret=%d\n", ret); return ret; } @@ -600,8 +595,7 @@ static int tsl2x7x_als_calibrate(struct iio_dev *indio_dev) (TSL2X7X_CMD_REG | TSL2X7X_CNTRL)); if (ret < 0) { dev_err(&chip->client->dev, - "%s: failed to write ctrl reg: ret=%d\n", - __func__, ret); + "failed to write ctrl reg: ret=%d\n", ret); return ret; } @@ -720,7 +714,7 @@ static int tsl2x7x_chip_on(struct iio_dev *indio_dev) TSL2X7X_CMD_REG + i, *dev_reg++); if (ret < 0) { dev_err(&chip->client->dev, - "%s: failed on write to reg %d.\n", __func__, i); + "failed on write to reg %d.\n", i); return ret; } } @@ -871,8 +865,8 @@ static void tsl2x7x_prox_cal(struct iio_dev *indio_dev) if (chip->tsl2x7x_settings.prox_max_samples_cal > MAX_SAMPLES_CAL) { dev_err(&chip->client->dev, - "%s: max prox samples cal is too big: %d\n", - __func__, chip->tsl2x7x_settings.prox_max_samples_cal); + "max prox samples cal is too big: %d\n", + chip->tsl2x7x_settings.prox_max_samples_cal); chip->tsl2x7x_settings.prox_max_samples_cal = MAX_SAMPLES_CAL; } @@ -1563,8 +1557,8 @@ static irqreturn_t tsl2x7x_event_handler(int irq, void *private) TSL2X7X_CMD_PROXALS_INT_CLR); if (ret < 0) dev_err(&chip->client->dev, - "%s: Failed to clear irq from event handler. err = %d\n", - __func__, ret); + "Failed to clear irq from event handler. err = %d\n", + ret); return IRQ_HANDLED; } @@ -1893,8 +1887,8 @@ static int tsl2x7x_probe(struct i2c_client *clientp, ret = i2c_smbus_write_byte(clientp, (TSL2X7X_CMD_REG | TSL2X7X_CNTRL)); if (ret < 0) { - dev_err(&clientp->dev, "%s: write to cmd reg failed. err = %d\n", - __func__, ret); + dev_err(&clientp->dev, "write to cmd reg failed. err = %d\n", + ret); return ret; } -- GitLab From eb856202b9f11735237db61c2d4d647825c123e1 Mon Sep 17 00:00:00 2001 From: Haneen Mohammed Date: Fri, 6 Mar 2015 22:05:05 +0300 Subject: [PATCH 03138/11651] Staging: slicoss: clean dev_err logging This patch removes __func__ from dev_err. dev_err includes information about: (devcice, driver, specific instance of device, etc) in the log printout. This was done using Coccinelle, with the following semantic patch: @a@ expression E, R; expression msg; @@ dev_err(E, msg, __func__, R); @script:python b@ e << a.msg; y; @@ if(e.find("%s: ") == True): m = e.replace("%s: ", "", 1); coccinelle.y = m; elif(e.find("%s ") == True): m = e.replace("%s ", "", 1); coccinelle.y = m; elif(e.find("%s:") == True): m = e.replace("%s:", "", 1); coccinelle.y = m; else: m = e.replace("%s", "",1); coccinelle.y = m; @c@ expression a.E, a.msg, a.R; identifier b.y; @@ - dev_err(E, msg, __func__, R); + dev_err(E, y, R); Signed-off-by: Haneen Mohammed Signed-off-by: Greg Kroah-Hartman --- drivers/staging/slicoss/slicoss.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/staging/slicoss/slicoss.c b/drivers/staging/slicoss/slicoss.c index a3afb3e4d157..3104cb0d0589 100644 --- a/drivers/staging/slicoss/slicoss.c +++ b/drivers/staging/slicoss/slicoss.c @@ -2313,9 +2313,8 @@ static int slic_if_init(struct adapter *adapter) } rc = slic_adapter_allocresources(adapter); if (rc) { - dev_err(&dev->dev, - "%s: slic_adapter_allocresources FAILED %x\n", - __func__, rc); + dev_err(&dev->dev, "slic_adapter_allocresources FAILED %x\n", + rc); slic_adapter_freeresources(adapter); goto err; } @@ -2549,8 +2548,8 @@ static int slic_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) if (copy_from_user(data, rq->ifr_data, 28)) return -EFAULT; intagg = data[0]; - dev_err(&dev->dev, "%s: set interrupt aggregation to %d\n", - __func__, intagg); + dev_err(&dev->dev, "set interrupt aggregation to %d\n", + intagg); slic_intagg_set(adapter, intagg); return 0; -- GitLab From 62af7214d8c3c9c81788e988cf99bfb02da77d0b Mon Sep 17 00:00:00 2001 From: Haneen Mohammed Date: Fri, 6 Mar 2015 22:07:13 +0300 Subject: [PATCH 03139/11651] Staging: ste_rmi4: clean dev_err logging This patch removes __func__ from dev_err. dev_err includes information about: (devcice, driver, specific instance of device, etc) in the log printout. This was done using Coccinelle, with the following semantic patch: @a@ expression E, R; expression msg; @@ dev_err(E, msg, __func__, R); @script:python b@ e << a.msg; y; @@ if(e.find("%s: ") == True): m = e.replace("%s: ", "", 1); coccinelle.y = m; elif(e.find("%s ") == True): m = e.replace("%s ", "", 1); coccinelle.y = m; elif(e.find("%s:") == True): m = e.replace("%s:", "", 1); coccinelle.y = m; else: m = e.replace("%s", "",1); coccinelle.y = m; @c@ expression a.E, a.msg, a.R; identifier b.y; @@ - dev_err(E, msg, __func__, R); + dev_err(E, y, R); Signed-off-by: Haneen Mohammed Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c b/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c index f92ae1d24f9f..6385b336bd0d 100644 --- a/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c +++ b/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c @@ -209,7 +209,7 @@ static int synaptics_rmi4_set_page(struct synaptics_rmi4_data *pdata, txbuf[1] = page; retval = i2c_master_send(i2c, txbuf, PAGE_LEN); if (retval != PAGE_LEN) - dev_err(&i2c->dev, "%s:failed:%d\n", __func__, retval); + dev_err(&i2c->dev, "failed:%d\n", retval); else pdata->current_page = page; } else @@ -283,7 +283,7 @@ static int synaptics_rmi4_i2c_byte_write(struct synaptics_rmi4_data *pdata, retval = i2c_master_send(pdata->i2c_client, txbuf, 2); /* Add in retry on writes only in certain error return values */ if (retval != 2) { - dev_err(&i2c->dev, "%s:failed:%d\n", __func__, retval); + dev_err(&i2c->dev, "failed:%d\n", retval); retval = -EIO; } else retval = 1; @@ -830,8 +830,8 @@ static int synaptics_rmi4_i2c_query_device(struct synaptics_rmi4_data *pdata) /* Check if this is a Synaptics device - report if not. */ if (pdata->rmi4_mod_info.manufacturer_id != 1) - dev_err(&client->dev, "%s: non-Synaptics mfg id:%d\n", - __func__, pdata->rmi4_mod_info.manufacturer_id); + dev_err(&client->dev, "non-Synaptics mfg id:%d\n", + pdata->rmi4_mod_info.manufacturer_id); list_for_each_entry(rfi, &pdata->rmi4_mod_info.support_fn_list, link) data_sources += rfi->num_of_data_sources; @@ -990,8 +990,8 @@ static int synaptics_rmi4_probe platformdata->irq_type, DRIVER_NAME, rmi4_data); if (retval) { - dev_err(&client->dev, "%s:Unable to get attn irq %d\n", - __func__, client->irq); + dev_err(&client->dev, "Unable to get attn irq %d\n", + client->irq); goto err_query_dev; } -- GitLab From 88cc30cfcfd38d81da3f8b4d9cedb16556c5fdfc Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 4 Mar 2015 12:15:28 -0700 Subject: [PATCH 03140/11651] staging: comedi: comedi_fops: (!foo) preferred over (foo == NULL) Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_fops.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 727640e89c73..2f8257cd9824 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -144,7 +144,7 @@ static void comedi_device_cleanup(struct comedi_device *dev) { struct module *driver_module = NULL; - if (dev == NULL) + if (!dev) return; mutex_lock(&dev->mutex); if (dev->attached) @@ -260,7 +260,7 @@ comedi_read_subdevice(const struct comedi_device *dev, unsigned int minor) if (minor >= COMEDI_NUM_BOARD_MINORS) { s = comedi_subdevice_from_minor(dev, minor); - if (s == NULL || (s->subdev_flags & SDF_CMD_READ)) + if (!s || (s->subdev_flags & SDF_CMD_READ)) return s; } return dev->read_subdev; @@ -273,7 +273,7 @@ comedi_write_subdevice(const struct comedi_device *dev, unsigned int minor) if (minor >= COMEDI_NUM_BOARD_MINORS) { s = comedi_subdevice_from_minor(dev, minor); - if (s == NULL || (s->subdev_flags & SDF_CMD_WRITE)) + if (!s || (s->subdev_flags & SDF_CMD_WRITE)) return s; } return dev->write_subdev; @@ -290,9 +290,9 @@ static void comedi_file_reset(struct file *file) write_s = dev->write_subdev; if (minor >= COMEDI_NUM_BOARD_MINORS) { s = comedi_subdevice_from_minor(dev, minor); - if (s == NULL || s->subdev_flags & SDF_CMD_READ) + if (!s || s->subdev_flags & SDF_CMD_READ) read_s = s; - if (s == NULL || s->subdev_flags & SDF_CMD_WRITE) + if (!s || s->subdev_flags & SDF_CMD_WRITE) write_s = s; } cfp->last_attached = dev->attached; @@ -759,7 +759,7 @@ static int do_devconfig_ioctl(struct comedi_device *dev, if (!capable(CAP_SYS_ADMIN)) return -EPERM; - if (arg == NULL) { + if (!arg) { if (is_device_busy(dev)) return -EBUSY; if (dev->attached) { @@ -1840,7 +1840,7 @@ static int do_cancel_ioctl(struct comedi_device *dev, unsigned long arg, if (arg >= dev->n_subdevices) return -EINVAL; s = &dev->subdevices[arg]; - if (s->async == NULL) + if (!s->async) return -EINVAL; if (!s->busy) @@ -2682,7 +2682,7 @@ struct comedi_device *comedi_alloc_board_minor(struct device *hardware_device) unsigned i; dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (dev == NULL) + if (!dev) return ERR_PTR(-ENOMEM); comedi_device_init(dev); comedi_set_hw_dev(dev, hardware_device); @@ -2690,7 +2690,7 @@ struct comedi_device *comedi_alloc_board_minor(struct device *hardware_device) mutex_lock(&comedi_board_minor_table_lock); for (i = hardware_device ? comedi_num_legacy_minors : 0; i < COMEDI_NUM_BOARD_MINORS; ++i) { - if (comedi_board_minor_table[i] == NULL) { + if (!comedi_board_minor_table[i]) { comedi_board_minor_table[i] = dev; break; } @@ -2746,7 +2746,7 @@ int comedi_alloc_subdevice_minor(struct comedi_subdevice *s) mutex_lock(&comedi_subdevice_minor_table_lock); for (i = 0; i < COMEDI_NUM_SUBDEVICE_MINORS; ++i) { - if (comedi_subdevice_minor_table[i] == NULL) { + if (!comedi_subdevice_minor_table[i]) { comedi_subdevice_minor_table[i] = s; break; } @@ -2771,7 +2771,7 @@ void comedi_free_subdevice_minor(struct comedi_subdevice *s) { unsigned int i; - if (s == NULL) + if (!s) return; if (s->minor < 0) return; -- GitLab From e2850160763e716e55fa6328bfab335cac90fc80 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 4 Mar 2015 12:15:29 -0700 Subject: [PATCH 03141/11651] staging: comedi: drivers: (!foo) preferred over (foo == NULL) Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index e87c68cf11d4..57dcffe00204 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -46,7 +46,7 @@ int comedi_set_hw_dev(struct comedi_device *dev, struct device *hw_dev) { if (hw_dev == dev->hw_dev) return 0; - if (dev->hw_dev != NULL) + if (dev->hw_dev) return -EEXIST; dev->hw_dev = get_device(hw_dev); return 0; @@ -802,7 +802,7 @@ int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it) } module_put(driv->module); } - if (driv == NULL) { + if (!driv) { /* recognize has failed if we get here */ /* report valid board names before returning error */ for (driv = comedi_drivers; driv; driv = driv->next) { @@ -814,7 +814,7 @@ int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it) ret = -EIO; goto out; } - if (driv->attach == NULL) { + if (!driv->attach) { /* driver does not support manual configuration */ dev_warn(dev->class_dev, "driver '%s' does not support attach using comedi_config\n", @@ -898,7 +898,7 @@ EXPORT_SYMBOL_GPL(comedi_auto_config); void comedi_auto_unconfig(struct device *hardware_device) { - if (hardware_device == NULL) + if (!hardware_device) return; comedi_release_hardware_device(hardware_device); } -- GitLab From 0048b9923daced04ffcb3b9974019b488ce19e8f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 4 Mar 2015 12:15:30 -0700 Subject: [PATCH 03142/11651] staging: comedi: amplc_pci224: (!foo) preferred over (foo == NULL) Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci224.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index 88b8c0101c25..8ac35f9fc69f 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -838,7 +838,7 @@ static int pci224_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) unsigned long flags; /* Cannot handle null/empty chanlist. */ - if (cmd->chanlist == NULL || cmd->chanlist_len == 0) + if (!cmd->chanlist || cmd->chanlist_len == 0) return -EINVAL; /* Determine which channels are enabled and their load order. */ -- GitLab From 4d719cecc08ecc58040ffd751423810b4c19d772 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 4 Mar 2015 12:15:31 -0700 Subject: [PATCH 03143/11651] staging: comedi: amplc_pci230: (!foo) preferred over (foo == NULL) Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci230.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index a977156ca468..2dd794d01354 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -2381,7 +2381,7 @@ static int pci230_auto_attach(struct comedi_device *dev, spin_lock_init(&devpriv->ao_stop_spinlock); dev->board_ptr = pci230_find_pci_board(pci_dev); - if (dev->board_ptr == NULL) { + if (!dev->board_ptr) { dev_err(dev->class_dev, "amplc_pci230: BUG! cannot determine board type!\n"); return -EINVAL; -- GitLab From 854472c27046646f3f258970a9fee9ab1e5d7593 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 4 Mar 2015 12:15:32 -0700 Subject: [PATCH 03144/11651] staging: comedi: cb_pcidas64: (!foo) preferred over (foo == NULL) Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidas64.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index bd2405999906..c8f4a227cc59 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -1473,7 +1473,7 @@ static int alloc_and_init_dma_members(struct comedi_device *dev) devpriv->ai_buffer[i] = pci_alloc_consistent(pcidev, DMA_BUFFER_SIZE, &devpriv->ai_buffer_bus_addr[i]); - if (devpriv->ai_buffer[i] == NULL) + if (!devpriv->ai_buffer[i]) return -ENOMEM; } @@ -1483,7 +1483,7 @@ static int alloc_and_init_dma_members(struct comedi_device *dev) pci_alloc_consistent(pcidev, DMA_BUFFER_SIZE, &devpriv-> ao_buffer_bus_addr[i]); - if (devpriv->ao_buffer[i] == NULL) + if (!devpriv->ao_buffer[i]) return -ENOMEM; } @@ -1493,7 +1493,7 @@ static int alloc_and_init_dma_members(struct comedi_device *dev) pci_alloc_consistent(pcidev, sizeof(struct plx_dma_desc) * ai_dma_ring_count(thisboard), &devpriv->ai_dma_desc_bus_addr); - if (devpriv->ai_dma_desc == NULL) + if (!devpriv->ai_dma_desc) return -ENOMEM; if (ao_cmd_is_supported(thisboard)) { @@ -1502,7 +1502,7 @@ static int alloc_and_init_dma_members(struct comedi_device *dev) sizeof(struct plx_dma_desc) * AO_DMA_RING_COUNT, &devpriv->ao_dma_desc_bus_addr); - if (devpriv->ao_dma_desc == NULL) + if (!devpriv->ao_dma_desc) return -ENOMEM; } /* initialize dma descriptors */ @@ -2975,7 +2975,7 @@ static void handle_ao_interrupt(struct comedi_device *dev, unsigned long flags; /* board might not support ao, in which case write_subdev is NULL */ - if (s == NULL) + if (!s) return; async = s->async; cmd = &async->cmd; -- GitLab From 5effdf708100fd5eeeaa8c7bbbed3b90cbb70cf5 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 4 Mar 2015 12:15:33 -0700 Subject: [PATCH 03145/11651] staging: comedi: mite: (!foo) preferred over (foo == NULL) Also, clarify the 'ring' allocation failure by returning NULL instead of 'ring' (which would be NULL). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/mite.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/mite.c b/drivers/staging/comedi/drivers/mite.c index 1e537a5cf862..79b5597db1a1 100644 --- a/drivers/staging/comedi/drivers/mite.c +++ b/drivers/staging/comedi/drivers/mite.c @@ -186,10 +186,10 @@ struct mite_dma_descriptor_ring *mite_alloc_ring(struct mite_struct *mite) struct mite_dma_descriptor_ring *ring = kmalloc(sizeof(struct mite_dma_descriptor_ring), GFP_KERNEL); - if (ring == NULL) - return ring; + if (!ring) + return NULL; ring->hw_dev = get_device(&mite->pcidev->dev); - if (ring->hw_dev == NULL) { + if (!ring->hw_dev) { kfree(ring); return NULL; } -- GitLab From 307da4b2e89c388d2e44efdd6899d4d1d8429806 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 4 Mar 2015 12:15:34 -0700 Subject: [PATCH 03146/11651] staging: comedi: ni_660x: (!foo) preferred over (foo == NULL) Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_660x.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 1e4dd82b12ea..9d7567bf1ce3 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -702,7 +702,7 @@ static int ni_660x_request_mite_channel(struct comedi_device *dev, BUG_ON(counter->mite_chan); mite_chan = mite_request_channel(devpriv->mite, mite_ring(devpriv, counter)); - if (mite_chan == NULL) { + if (!mite_chan) { spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags); dev_err(dev->class_dev, "failed to reserve mite dma channel for counter\n"); @@ -861,7 +861,7 @@ static int ni_660x_alloc_mite_rings(struct comedi_device *dev) for (j = 0; j < counters_per_chip; ++j) { devpriv->mite_rings[i][j] = mite_alloc_ring(devpriv->mite); - if (devpriv->mite_rings[i][j] == NULL) + if (!devpriv->mite_rings[i][j]) return -ENOMEM; } } @@ -1107,7 +1107,7 @@ static int ni_660x_auto_attach(struct comedi_device *dev, ni_gpct_variant_660x, ni_660x_num_counters (dev)); - if (devpriv->counter_dev == NULL) + if (!devpriv->counter_dev) return -ENOMEM; for (i = 0; i < NI_660X_MAX_NUM_COUNTERS; ++i) { s = &dev->subdevices[NI_660X_GPCT_SUBDEV(i)]; -- GitLab From 77ba71f6485d2b7f923987b173d590b3003bc2a6 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 4 Mar 2015 12:15:35 -0700 Subject: [PATCH 03147/11651] staging: comedi: ni_atmio: (!foo) preferred over (foo == NULL) Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_atmio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/ni_atmio.c b/drivers/staging/comedi/drivers/ni_atmio.c index 301f154be813..9cb9beb53e16 100644 --- a/drivers/staging/comedi/drivers/ni_atmio.c +++ b/drivers/staging/comedi/drivers/ni_atmio.c @@ -250,7 +250,7 @@ static int ni_isapnp_find_board(struct pnp_dev **dev) ISAPNP_FUNCTION(ni_boards[i]. isapnp_id), NULL); - if (isapnp_dev == NULL || isapnp_dev->card == NULL) + if (!isapnp_dev || !isapnp_dev->card) continue; if (pnp_device_attach(isapnp_dev) < 0) -- GitLab From c1bce7fd0d930a60af858039239d824973d147ab Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 4 Mar 2015 12:15:36 -0700 Subject: [PATCH 03148/11651] staging: comedi: ni_labpc_common: (!foo) preferred over (foo == NULL) Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_labpc_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/ni_labpc_common.c b/drivers/staging/comedi/drivers/ni_labpc_common.c index 74518c5645af..0dac8cf312b2 100644 --- a/drivers/staging/comedi/drivers/ni_labpc_common.c +++ b/drivers/staging/comedi/drivers/ni_labpc_common.c @@ -428,7 +428,7 @@ static enum scan_mode labpc_ai_scan_mode(const struct comedi_cmd *cmd) return MODE_SINGLE_CHAN; /* chanlist may be NULL during cmdtest */ - if (cmd->chanlist == NULL) + if (!cmd->chanlist) return MODE_MULT_CHAN_UP; chan0 = CR_CHAN(cmd->chanlist[0]); -- GitLab From 4ce82def8da5787d8661fa5f7d5f7c899b5a20d9 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 4 Mar 2015 12:15:37 -0700 Subject: [PATCH 03149/11651] staging: comedi: ni_pcidio: (!foo) preferred over (foo == NULL) Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_pcidio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c index db399fe8c301..8d91029c7d30 100644 --- a/drivers/staging/comedi/drivers/ni_pcidio.c +++ b/drivers/staging/comedi/drivers/ni_pcidio.c @@ -304,7 +304,7 @@ static int ni_pcidio_request_di_mite_channel(struct comedi_device *dev) devpriv->di_mite_chan = mite_request_channel_in_range(devpriv->mite, devpriv->di_mite_ring, 1, 2); - if (devpriv->di_mite_chan == NULL) { + if (!devpriv->di_mite_chan) { spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags); dev_err(dev->class_dev, "failed to reserve mite dma channel\n"); return -EBUSY; @@ -924,7 +924,7 @@ static int nidio_auto_attach(struct comedi_device *dev, return ret; devpriv->di_mite_ring = mite_alloc_ring(devpriv->mite); - if (devpriv->di_mite_ring == NULL) + if (!devpriv->di_mite_ring) return -ENOMEM; if (board->uses_firmware) { -- GitLab From 9bacea57f445a2bc199401d1149d6f323c531028 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 4 Mar 2015 12:15:38 -0700 Subject: [PATCH 03150/11651] staging: comedi: ni_pcimio: (!foo) preferred over (foo == NULL) Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_pcimio.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_pcimio.c b/drivers/staging/comedi/drivers/ni_pcimio.c index 3b2bdebbca59..e78739cce175 100644 --- a/drivers/staging/comedi/drivers/ni_pcimio.c +++ b/drivers/staging/comedi/drivers/ni_pcimio.c @@ -1183,19 +1183,19 @@ static int pcimio_auto_attach(struct comedi_device *dev, return ret; devpriv->ai_mite_ring = mite_alloc_ring(devpriv->mite); - if (devpriv->ai_mite_ring == NULL) + if (!devpriv->ai_mite_ring) return -ENOMEM; devpriv->ao_mite_ring = mite_alloc_ring(devpriv->mite); - if (devpriv->ao_mite_ring == NULL) + if (!devpriv->ao_mite_ring) return -ENOMEM; devpriv->cdo_mite_ring = mite_alloc_ring(devpriv->mite); - if (devpriv->cdo_mite_ring == NULL) + if (!devpriv->cdo_mite_ring) return -ENOMEM; devpriv->gpct_mite_ring[0] = mite_alloc_ring(devpriv->mite); - if (devpriv->gpct_mite_ring[0] == NULL) + if (!devpriv->gpct_mite_ring[0]) return -ENOMEM; devpriv->gpct_mite_ring[1] = mite_alloc_ring(devpriv->mite); - if (devpriv->gpct_mite_ring[1] == NULL) + if (!devpriv->gpct_mite_ring[1]) return -ENOMEM; if (devpriv->is_m_series) -- GitLab From 56e97078602996123d849b7621442a934aa19b77 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 4 Mar 2015 12:15:39 -0700 Subject: [PATCH 03151/11651] staging: comedi: ni_tiocmd: (!foo) preferred over (foo == NULL) Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_tiocmd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_tiocmd.c b/drivers/staging/comedi/drivers/ni_tiocmd.c index d36c3abd3120..41735700e5f9 100644 --- a/drivers/staging/comedi/drivers/ni_tiocmd.c +++ b/drivers/staging/comedi/drivers/ni_tiocmd.c @@ -201,7 +201,7 @@ int ni_tio_cmd(struct comedi_device *dev, struct comedi_subdevice *s) unsigned long flags; spin_lock_irqsave(&counter->lock, flags); - if (counter->mite_chan == NULL) { + if (!counter->mite_chan) { dev_err(counter->counter_dev->dev->class_dev, "commands only supported with DMA. "); dev_err(counter->counter_dev->dev->class_dev, @@ -329,7 +329,7 @@ static int should_ack_gate(struct ni_gpct *counter) case ni_gpct_variant_e_series: spin_lock_irqsave(&counter->lock, flags); { - if (counter->mite_chan == NULL || + if (!counter->mite_chan || counter->mite_chan->dir != COMEDI_INPUT || (mite_done(counter->mite_chan))) { retval = 1; @@ -443,7 +443,7 @@ void ni_tio_handle_interrupt(struct ni_gpct *counter, break; } spin_lock_irqsave(&counter->lock, flags); - if (counter->mite_chan == NULL) { + if (!counter->mite_chan) { spin_unlock_irqrestore(&counter->lock, flags); return; } -- GitLab From c6be154812114819873e8254c8d89679a11ac21c Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 4 Mar 2015 12:15:40 -0700 Subject: [PATCH 03152/11651] staging: comedi: ni_mio_common: (!foo) preferred over (foo == NULL) Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_mio_common.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c index 97728d25da53..5bb2b5e936bc 100644 --- a/drivers/staging/comedi/drivers/ni_mio_common.c +++ b/drivers/staging/comedi/drivers/ni_mio_common.c @@ -755,7 +755,7 @@ static int ni_request_ai_mite_channel(struct comedi_device *dev) BUG_ON(devpriv->ai_mite_chan); devpriv->ai_mite_chan = mite_request_channel(devpriv->mite, devpriv->ai_mite_ring); - if (devpriv->ai_mite_chan == NULL) { + if (!devpriv->ai_mite_chan) { spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags); dev_err(dev->class_dev, "failed to reserve mite dma channel for analog input\n"); @@ -776,7 +776,7 @@ static int ni_request_ao_mite_channel(struct comedi_device *dev) BUG_ON(devpriv->ao_mite_chan); devpriv->ao_mite_chan = mite_request_channel(devpriv->mite, devpriv->ao_mite_ring); - if (devpriv->ao_mite_chan == NULL) { + if (!devpriv->ao_mite_chan) { spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags); dev_err(dev->class_dev, "failed to reserve mite dma channel for analog outut\n"); @@ -802,7 +802,7 @@ static int ni_request_gpct_mite_channel(struct comedi_device *dev, mite_chan = mite_request_channel(devpriv->mite, devpriv->gpct_mite_ring[gpct_index]); - if (mite_chan == NULL) { + if (!mite_chan) { spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags); dev_err(dev->class_dev, "failed to reserve mite dma channel for counter\n"); @@ -828,7 +828,7 @@ static int ni_request_cdo_mite_channel(struct comedi_device *dev) BUG_ON(devpriv->cdo_mite_chan); devpriv->cdo_mite_chan = mite_request_channel(devpriv->mite, devpriv->cdo_mite_ring); - if (devpriv->cdo_mite_chan == NULL) { + if (!devpriv->cdo_mite_chan) { spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags); dev_err(dev->class_dev, "failed to reserve mite dma channel for correlated digital output\n"); @@ -1657,7 +1657,7 @@ static int ni_ai_setup_MITE_dma(struct comedi_device *dev) comedi_buf_write_alloc(s, s->async->prealloc_bufsz); spin_lock_irqsave(&devpriv->mite_channel_lock, flags); - if (devpriv->ai_mite_chan == NULL) { + if (!devpriv->ai_mite_chan) { spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags); return -EIO; } @@ -3699,7 +3699,7 @@ static int ni_serial_hw_readwrite8(struct comedi_device *dev, DIO_Serial_IO_In_Progress_St goes high one bit too early. */ udelay((devpriv->serial_interval_ns + 999) / 1000); - if (data_in != NULL) + if (data_in) *data_in = ni_stc_readw(dev, DIO_Serial_Input_Register); Error: -- GitLab From 4c36fdde64f858ce167ad69859c89b1a8c9b6fb0 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 4 Mar 2015 12:15:41 -0700 Subject: [PATCH 03153/11651] staging: comedi: kcomedilib_main: (!foo) preferred over (foo == NULL) Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/kcomedilib/kcomedilib_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c index 973f544e85e1..76bf5619fdd5 100644 --- a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c +++ b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c @@ -58,7 +58,7 @@ struct comedi_device *comedi_open(const char *filename) retval = NULL; up_read(&dev->attach_lock); - if (retval == NULL) + if (!retval) comedi_dev_put(dev); return retval; -- GitLab From 857ced45a548c3f8196d6e45079678ab3c9f3581 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 4 Mar 2015 12:15:42 -0700 Subject: [PATCH 03154/11651] staging: comedi: s626: remove unnecessary 'cmd' pointer checks The local variable 'cmd' is a pointer to the address of a member variable of a struct. It will always be valid. Remove the unnecessary checks. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/s626.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index fc497dd92021..422ea9c73706 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -1576,7 +1576,7 @@ static void s626_reset_adc(struct comedi_device *dev, uint8_t *ppl) dev->mmio + S626_P_RPSADDR1); /* Construct RPS program in rps_buf DMA buffer */ - if (cmd != NULL && cmd->scan_begin_src != TRIG_FOLLOW) { + if (cmd->scan_begin_src != TRIG_FOLLOW) { /* Wait for Start trigger. */ *rps++ = S626_RPS_PAUSE | S626_RPS_SIGADC; *rps++ = S626_RPS_CLRSIGNAL | S626_RPS_SIGADC; @@ -1665,7 +1665,7 @@ static void s626_reset_adc(struct comedi_device *dev, uint8_t *ppl) *rps++ = jmp_adrs; } - if (cmd != NULL && cmd->convert_src != TRIG_NOW) { + if (cmd->convert_src != TRIG_NOW) { /* Wait for Start trigger. */ *rps++ = S626_RPS_PAUSE | S626_RPS_SIGADC; *rps++ = S626_RPS_CLRSIGNAL | S626_RPS_SIGADC; @@ -2034,10 +2034,6 @@ static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) /* reset ai_cmd_running flag */ devpriv->ai_cmd_running = 0; - /* test if cmd is valid */ - if (cmd == NULL) - return -EINVAL; - s626_ai_load_polllist(ppl, cmd); devpriv->ai_cmd_running = 1; devpriv->ai_convert_count = 0; -- GitLab From 9949595c0da61ff2aecc90c3a8e924848e6ac03b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 5 Mar 2015 13:21:15 -0700 Subject: [PATCH 03155/11651] staging: comedi: drivers/*.c: fix common misspellings Fix these common misspellings: s/dependancy/dependency s/occured/occurred s/informations/information s/intialize/initialize s/serveral/several s/interrups/interrupts s/acknowledgement/acknowledgment s/suppport/support s/writting/writing Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/8255_pci.c | 2 +- drivers/staging/comedi/drivers/addi_apci_1500.c | 4 ++-- drivers/staging/comedi/drivers/adv_pci1710.c | 2 +- drivers/staging/comedi/drivers/das08.c | 2 +- drivers/staging/comedi/drivers/dmm32at.c | 4 ++-- drivers/staging/comedi/drivers/ni_65xx.c | 2 +- drivers/staging/comedi/drivers/ni_670x.c | 2 +- drivers/staging/comedi/drivers/ni_labpc_pci.c | 2 +- drivers/staging/comedi/drivers/ni_tiocmd.c | 2 +- drivers/staging/comedi/drivers/pcmuio.c | 2 +- drivers/staging/comedi/drivers/unioxx5.c | 4 ++-- 11 files changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/staging/comedi/drivers/8255_pci.c b/drivers/staging/comedi/drivers/8255_pci.c index 984764211a2d..291aed14f7e3 100644 --- a/drivers/staging/comedi/drivers/8255_pci.c +++ b/drivers/staging/comedi/drivers/8255_pci.c @@ -178,7 +178,7 @@ static const struct pci_8255_boardinfo pci_8255_boards[] = { }, }; -/* ripped from mite.h and mite_setup2() to avoid mite dependancy */ +/* ripped from mite.h and mite_setup2() to avoid mite dependency */ #define MITE_IODWBSR 0xc0 /* IO Device Window Base Size Register */ #define WENAB (1 << 7) /* window enable */ diff --git a/drivers/staging/comedi/drivers/addi_apci_1500.c b/drivers/staging/comedi/drivers/addi_apci_1500.c index f15aa1f6b476..3dd017940aaf 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1500.c +++ b/drivers/staging/comedi/drivers/addi_apci_1500.c @@ -249,8 +249,8 @@ static irqreturn_t apci1500_interrupt(int irq, void *d) * * Mask Meaning * ---------- ------------------------------------------ - * 0x00000001 Event 1 has occured - * 0x00000010 Event 2 has occured + * 0x00000001 Event 1 has occurred + * 0x00000010 Event 2 has occurred * 0x00000100 Counter/timer 1 has run down (not implemented) * 0x00001000 Counter/timer 2 has run down (not implemented) * 0x00010000 Counter 3 has run down (not implemented) diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 9c881ff01297..812f4dde63a4 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -4,7 +4,7 @@ * Author: Michal Dobes * * Thanks to ZhenGang Shang - * for testing and informations. + * for testing and information. * * hardware driver for Advantech cards: * card: PCI-1710, PCI-1710HG, PCI-1711, PCI-1713, PCI-1720, PCI-1731 diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index ecd363901922..73f4c8dbbde3 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -408,7 +408,7 @@ int das08_common_attach(struct comedi_device *dev, unsigned long iobase) if (ret) return ret; - /* intialize all channels to 0V */ + /* initialize all channels to 0V */ for (i = 0; i < s->n_chan; i++) { s->readback[i] = s->maxdata / 2; das08_ao_set_data(dev, i, s->readback[i]); diff --git a/drivers/staging/comedi/drivers/dmm32at.c b/drivers/staging/comedi/drivers/dmm32at.c index 1af006609fc1..74830f4b95f5 100644 --- a/drivers/staging/comedi/drivers/dmm32at.c +++ b/drivers/staging/comedi/drivers/dmm32at.c @@ -30,7 +30,7 @@ * This driver is for the Diamond Systems MM-32-AT board * http://www.diamondsystems.com/products/diamondmm32at * - * It is being used on serveral projects inside NASA, without + * It is being used on several projects inside NASA, without * problems so far. For analog input commands, TRIG_EXT is not * yet supported. */ @@ -391,7 +391,7 @@ static int dmm32at_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) /* start the clock and enable the interrupts */ dmm32at_setaitimer(dev, cmd->scan_begin_arg); } else { - /* start the interrups and initiate a single scan */ + /* start the interrupts and initiate a single scan */ outb(DMM32AT_INTCLK_ADINT, dev->iobase + DMM32AT_INTCLK_REG); outb(0xff, dev->iobase + DMM32AT_AI_START_CONV_REG); } diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c index 67cb758eb0cd..9d0714b802b1 100644 --- a/drivers/staging/comedi/drivers/ni_65xx.c +++ b/drivers/staging/comedi/drivers/ni_65xx.c @@ -613,7 +613,7 @@ static int ni_65xx_intr_insn_config(struct comedi_device *dev, return insn->n; } -/* ripped from mite.h and mite_setup2() to avoid mite dependancy */ +/* ripped from mite.h and mite_setup2() to avoid mite dependency */ #define MITE_IODWBSR 0xc0 /* IO Device Window Base Size Register */ #define WENAB (1 << 7) /* window enable */ diff --git a/drivers/staging/comedi/drivers/ni_670x.c b/drivers/staging/comedi/drivers/ni_670x.c index c42a81c0bfa1..90b4dfa6261b 100644 --- a/drivers/staging/comedi/drivers/ni_670x.c +++ b/drivers/staging/comedi/drivers/ni_670x.c @@ -146,7 +146,7 @@ static int ni_670x_dio_insn_config(struct comedi_device *dev, return insn->n; } -/* ripped from mite.h and mite_setup2() to avoid mite dependancy */ +/* ripped from mite.h and mite_setup2() to avoid mite dependency */ #define MITE_IODWBSR 0xc0 /* IO Device Window Base Size Register */ #define WENAB (1 << 7) /* window enable */ diff --git a/drivers/staging/comedi/drivers/ni_labpc_pci.c b/drivers/staging/comedi/drivers/ni_labpc_pci.c index 245c59bbaef8..f50a5a2ee079 100644 --- a/drivers/staging/comedi/drivers/ni_labpc_pci.c +++ b/drivers/staging/comedi/drivers/ni_labpc_pci.c @@ -51,7 +51,7 @@ static const struct labpc_boardinfo labpc_pci_boards[] = { }, }; -/* ripped from mite.h and mite_setup2() to avoid mite dependancy */ +/* ripped from mite.h and mite_setup2() to avoid mite dependency */ #define MITE_IODWBSR 0xc0 /* IO Device Window Base Size Register */ #define WENAB (1 << 7) /* window enable */ diff --git a/drivers/staging/comedi/drivers/ni_tiocmd.c b/drivers/staging/comedi/drivers/ni_tiocmd.c index 41735700e5f9..2a1f8b26c407 100644 --- a/drivers/staging/comedi/drivers/ni_tiocmd.c +++ b/drivers/staging/comedi/drivers/ni_tiocmd.c @@ -366,7 +366,7 @@ static void ni_tio_acknowledge_and_confirm(struct ni_gpct *counter, if (gxx_status & GI_GATE_ERROR(cidx)) { ack |= GI_GATE_ERROR_CONFIRM(cidx); if (gate_error) { - /*660x don't support automatic acknowledgement + /*660x don't support automatic acknowledgment of gate interrupt via dma read/write and report bogus gate errors */ if (counter->counter_dev->variant != diff --git a/drivers/staging/comedi/drivers/pcmuio.c b/drivers/staging/comedi/drivers/pcmuio.c index a1641d981812..1a4a1f589a56 100644 --- a/drivers/staging/comedi/drivers/pcmuio.c +++ b/drivers/staging/comedi/drivers/pcmuio.c @@ -588,7 +588,7 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->insn_bits = pcmuio_dio_insn_bits; s->insn_config = pcmuio_dio_insn_config; - /* subdevices 0 and 2 can suppport interrupts */ + /* subdevices 0 and 2 can support interrupts */ if ((i == 0 && dev->irq) || (i == 2 && devpriv->irq2)) { /* setup the interrupt subdevice */ dev->read_subdev = s; diff --git a/drivers/staging/comedi/drivers/unioxx5.c b/drivers/staging/comedi/drivers/unioxx5.c index 7c2276a086ac..12d828063c06 100644 --- a/drivers/staging/comedi/drivers/unioxx5.c +++ b/drivers/staging/comedi/drivers/unioxx5.c @@ -266,7 +266,7 @@ static int __unioxx5_analog_write(struct comedi_subdevice *s, /* sending for bytes to module(one byte per cycle iteration) */ for (i = 0; i < 4; i++) { while (!((inb(usp->usp_iobase + 0)) & TxBE)) - ; /* waits while writting will be allowed */ + ; /* waits while writing will be allowed */ outb(usp->usp_extra_data[module][i], usp->usp_iobase + 6); } @@ -399,7 +399,7 @@ static int __unioxx5_subdev_init(struct comedi_device *dev, outb(i + 1, iobase + 5); outb('H', iobase + 6); /* requests EEPROM world */ while (!(inb(iobase + 0) & TxBE)) - ; /* waits while writting will be allowed */ + ; /* waits while writing will be allowed */ outb(0, iobase + 6); /* waits while reading of two bytes will be allowed */ -- GitLab From 6c7d2c8b5230272b394d51462c8cae46df09f126 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 5 Mar 2015 13:21:16 -0700 Subject: [PATCH 03156/11651] staging: comedi: drivers/*.c: alignment should match open parenthesis Fix the alignment issues in all the comedi drivers. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi_apci_1032.c | 4 ++-- .../staging/comedi/drivers/addi_apci_1564.c | 4 ++-- .../staging/comedi/drivers/addi_apci_3501.c | 2 +- .../staging/comedi/drivers/addi_watchdog.c | 2 +- drivers/staging/comedi/drivers/adl_pci8164.c | 2 +- drivers/staging/comedi/drivers/adl_pci9111.c | 6 ++--- drivers/staging/comedi/drivers/adl_pci9118.c | 2 +- drivers/staging/comedi/drivers/cb_pcidas.c | 2 +- drivers/staging/comedi/drivers/cb_pcimdda.c | 2 +- drivers/staging/comedi/drivers/comedi_bond.c | 6 ++--- .../staging/comedi/drivers/comedi_isadma.c | 3 ++- .../staging/comedi/drivers/contec_pci_dio.c | 2 +- drivers/staging/comedi/drivers/daqboard2000.c | 2 +- drivers/staging/comedi/drivers/das16.c | 2 +- drivers/staging/comedi/drivers/das16m1.c | 2 +- drivers/staging/comedi/drivers/dt282x.c | 2 +- drivers/staging/comedi/drivers/dyna_pci10xx.c | 17 ++++++++------ drivers/staging/comedi/drivers/icp_multi.c | 2 +- drivers/staging/comedi/drivers/me4000.c | 22 +++++++++---------- drivers/staging/comedi/drivers/ni_65xx.c | 2 +- .../staging/comedi/drivers/ni_mio_common.c | 2 +- drivers/staging/comedi/drivers/pcmuio.c | 2 +- drivers/staging/comedi/drivers/rtd520.c | 4 ++-- drivers/staging/comedi/drivers/s626.c | 20 ++++++++--------- drivers/staging/comedi/drivers/usbdux.c | 4 ++-- 25 files changed, 62 insertions(+), 58 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index 4911b627203b..993ecc639430 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -238,7 +238,7 @@ static int apci1032_cos_cmd(struct comedi_device *dev, if (!devpriv->ctrl) { dev_warn(dev->class_dev, - "Interrupts disabled due to mode configuration!\n"); + "Interrupts disabled due to mode configuration!\n"); return -EINVAL; } @@ -296,7 +296,7 @@ static int apci1032_di_insn_bits(struct comedi_device *dev, } static int apci1032_auto_attach(struct comedi_device *dev, - unsigned long context_unused) + unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct apci1032_private *devpriv; diff --git a/drivers/staging/comedi/drivers/addi_apci_1564.c b/drivers/staging/comedi/drivers/addi_apci_1564.c index 6872b69da5db..2de5e8320957 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1564.c +++ b/drivers/staging/comedi/drivers/addi_apci_1564.c @@ -407,7 +407,7 @@ static int apci1564_cos_cmd(struct comedi_device *dev, if (!devpriv->ctrl) { dev_warn(dev->class_dev, - "Interrupts disabled due to mode configuration!\n"); + "Interrupts disabled due to mode configuration!\n"); return -EINVAL; } @@ -430,7 +430,7 @@ static int apci1564_cos_cancel(struct comedi_device *dev, } static int apci1564_auto_attach(struct comedi_device *dev, - unsigned long context_unused) + unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct apci1564_private *devpriv; diff --git a/drivers/staging/comedi/drivers/addi_apci_3501.c b/drivers/staging/comedi/drivers/addi_apci_3501.c index 5961f195ba0b..b8f336681788 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3501.c +++ b/drivers/staging/comedi/drivers/addi_apci_3501.c @@ -203,7 +203,7 @@ static unsigned short apci3501_eeprom_readw(unsigned long iobase, outb(NVCMD_LOAD_HIGH, iobase + AMCC_OP_REG_MCSR_NVCMD); apci3501_eeprom_wait(iobase); outb(((addr + i) >> 8) & 0xff, - iobase + AMCC_OP_REG_MCSR_NVDATA); + iobase + AMCC_OP_REG_MCSR_NVDATA); apci3501_eeprom_wait(iobase); /* Read the eeprom data byte */ diff --git a/drivers/staging/comedi/drivers/addi_watchdog.c b/drivers/staging/comedi/drivers/addi_watchdog.c index c5b082d4e51e..9d9853fe54a0 100644 --- a/drivers/staging/comedi/drivers/addi_watchdog.c +++ b/drivers/staging/comedi/drivers/addi_watchdog.c @@ -54,7 +54,7 @@ static int addi_watchdog_insn_config(struct comedi_device *dev, /* Time base is 20ms, let the user know the timeout */ dev_info(dev->class_dev, "watchdog enabled, timeout:%dms\n", - 20 * reload + 20); + 20 * reload + 20); break; case INSN_CONFIG_DISARM: spriv->wdog_ctrl = 0; diff --git a/drivers/staging/comedi/drivers/adl_pci8164.c b/drivers/staging/comedi/drivers/adl_pci8164.c index cc6c53b800a7..4a9d63ab10bc 100644 --- a/drivers/staging/comedi/drivers/adl_pci8164.c +++ b/drivers/staging/comedi/drivers/adl_pci8164.c @@ -69,7 +69,7 @@ static int adl_pci8164_insn_write(struct comedi_device *dev, } static int adl_pci8164_auto_attach(struct comedi_device *dev, - unsigned long context_unused) + unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct comedi_subdevice *s; diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index 3f82fa002e0d..144e9c2dbaf9 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -378,7 +378,7 @@ static int pci9111_ai_do_cmd(struct comedi_device *dev, /* This is the same gain on every channel */ outb(CR_RANGE(cmd->chanlist[0]) & PCI9111_AI_RANGE_MASK, - dev->iobase + PCI9111_AI_RANGE_STAT_REG); + dev->iobase + PCI9111_AI_RANGE_STAT_REG); /* Set timer pacer */ dev_private->scan_delay = 0; @@ -572,7 +572,7 @@ static int pci9111_ai_insn_read(struct comedi_device *dev, status = inb(dev->iobase + PCI9111_AI_RANGE_STAT_REG); if ((status & PCI9111_AI_RANGE_MASK) != range) { outb(range & PCI9111_AI_RANGE_MASK, - dev->iobase + PCI9111_AI_RANGE_STAT_REG); + dev->iobase + PCI9111_AI_RANGE_STAT_REG); } pci9111_fifo_reset(dev); @@ -650,7 +650,7 @@ static int pci9111_reset(struct comedi_device *dev) } static int pci9111_auto_attach(struct comedi_device *dev, - unsigned long context_unused) + unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct pci9111_private_data *dev_private; diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index 4b604423635f..1cd54556a2dd 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -936,7 +936,7 @@ static int Compute_and_setup_dma(struct comedi_device *dev, /* outl(0x02000000|AINT_WRITE_COMPL, devpriv->iobase_a+AMCC_OP_REG_INTCSR); */ pci9118_amcc_dma_ena(dev, true); outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | EN_A2P_TRANSFERS, - devpriv->iobase_a + AMCC_OP_REG_INTCSR); + devpriv->iobase_a + AMCC_OP_REG_INTCSR); /* allow bus mastering */ return 0; diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c index b6ef4b47c673..112627d24d41 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas.c +++ b/drivers/staging/comedi/drivers/cb_pcidas.c @@ -525,7 +525,7 @@ static int wait_for_nvram_ready(unsigned long s5933_base_addr) } static int nvram_read(struct comedi_device *dev, unsigned int address, - uint8_t *data) + uint8_t *data) { struct cb_pcidas_private *devpriv = dev->private; unsigned long iobase = devpriv->s5933_config; diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c index 03043e7b9b58..e834be9b0567 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdda.c +++ b/drivers/staging/comedi/drivers/cb_pcimdda.c @@ -134,7 +134,7 @@ static int cb_pcimdda_ao_insn_read(struct comedi_device *dev, } static int cb_pcimdda_auto_attach(struct comedi_device *dev, - unsigned long context_unused) + unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct comedi_subdevice *s; diff --git a/drivers/staging/comedi/drivers/comedi_bond.c b/drivers/staging/comedi/drivers/comedi_bond.c index 221d3819c967..7a68727cc880 100644 --- a/drivers/staging/comedi/drivers/comedi_bond.c +++ b/drivers/staging/comedi/drivers/comedi_bond.c @@ -313,9 +313,9 @@ static int bonding_attach(struct comedi_device *dev, s->insn_config = bonding_dio_insn_config; dev_info(dev->class_dev, - "%s: %s attached, %u channels from %u devices\n", - dev->driver->driver_name, dev->board_name, - devpriv->nchans, devpriv->ndevs); + "%s: %s attached, %u channels from %u devices\n", + dev->driver->driver_name, dev->board_name, + devpriv->nchans, devpriv->ndevs); return 0; } diff --git a/drivers/staging/comedi/drivers/comedi_isadma.c b/drivers/staging/comedi/drivers/comedi_isadma.c index dbdea71d6b95..9b2a2997134f 100644 --- a/drivers/staging/comedi/drivers/comedi_isadma.c +++ b/drivers/staging/comedi/drivers/comedi_isadma.c @@ -234,7 +234,8 @@ void comedi_isadma_free(struct comedi_isadma *dma) desc = &dma->desc[i]; if (desc->virt_addr) dma_free_coherent(NULL, desc->maxsize, - desc->virt_addr, desc->hw_addr); + desc->virt_addr, + desc->hw_addr); } kfree(dma->desc); } diff --git a/drivers/staging/comedi/drivers/contec_pci_dio.c b/drivers/staging/comedi/drivers/contec_pci_dio.c index 205f9df345a2..ba26c134a46d 100644 --- a/drivers/staging/comedi/drivers/contec_pci_dio.c +++ b/drivers/staging/comedi/drivers/contec_pci_dio.c @@ -59,7 +59,7 @@ static int contec_di_insn_bits(struct comedi_device *dev, } static int contec_auto_attach(struct comedi_device *dev, - unsigned long context_unused) + unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct comedi_subdevice *s; diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c index 96697fbb5239..d625afd633d3 100644 --- a/drivers/staging/comedi/drivers/daqboard2000.c +++ b/drivers/staging/comedi/drivers/daqboard2000.c @@ -649,7 +649,7 @@ static const void *daqboard2000_find_boardinfo(struct comedi_device *dev, } static int daqboard2000_auto_attach(struct comedi_device *dev, - unsigned long context_unused) + unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); const struct daq200_boardtype *board; diff --git a/drivers/staging/comedi/drivers/das16.c b/drivers/staging/comedi/drivers/das16.c index 4b3bdade6596..be6277ae4abc 100644 --- a/drivers/staging/comedi/drivers/das16.c +++ b/drivers/staging/comedi/drivers/das16.c @@ -708,7 +708,7 @@ static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s) if (cmd->flags & CMDF_PRIORITY) { dev_err(dev->class_dev, - "isa dma transfers cannot be performed with CMDF_PRIORITY, aborting\n"); + "isa dma transfers cannot be performed with CMDF_PRIORITY, aborting\n"); return -1; } diff --git a/drivers/staging/comedi/drivers/das16m1.c b/drivers/staging/comedi/drivers/das16m1.c index 219746bc7641..cdef03d09738 100644 --- a/drivers/staging/comedi/drivers/das16m1.c +++ b/drivers/staging/comedi/drivers/das16m1.c @@ -167,7 +167,7 @@ static int das16m1_ai_check_chanlist(struct comedi_device *dev, if ((i % 2) != (chan % 2)) { dev_dbg(dev->class_dev, - "even/odd channels must go have even/odd chanlist indices\n"); + "even/odd channels must go have even/odd chanlist indices\n"); return -EINVAL; } } diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c index db21d2135856..2cdd8bf44b4d 100644 --- a/drivers/staging/comedi/drivers/dt282x.c +++ b/drivers/staging/comedi/drivers/dt282x.c @@ -764,7 +764,7 @@ static int dt282x_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) if (cmd->scan_begin_src == TRIG_FOLLOW) { outw(devpriv->supcsr | DT2821_SUPCSR_STRIG, - dev->iobase + DT2821_SUPCSR_REG); + dev->iobase + DT2821_SUPCSR_REG); } else { devpriv->supcsr |= DT2821_SUPCSR_XTRIG; outw(devpriv->supcsr, dev->iobase + DT2821_SUPCSR_REG); diff --git a/drivers/staging/comedi/drivers/dyna_pci10xx.c b/drivers/staging/comedi/drivers/dyna_pci10xx.c index 6c1e442f6c81..c241d92e7cc2 100644 --- a/drivers/staging/comedi/drivers/dyna_pci10xx.c +++ b/drivers/staging/comedi/drivers/dyna_pci10xx.c @@ -70,8 +70,9 @@ static int dyna_pci10xx_ai_eoc(struct comedi_device *dev, } static int dyna_pci10xx_insn_read_ai(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct dyna_pci10xx_private *devpriv = dev->private; int n; @@ -109,8 +110,9 @@ static int dyna_pci10xx_insn_read_ai(struct comedi_device *dev, /* analog output callback */ static int dyna_pci10xx_insn_write_ao(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct dyna_pci10xx_private *devpriv = dev->private; int n; @@ -132,8 +134,9 @@ static int dyna_pci10xx_insn_write_ao(struct comedi_device *dev, /* digital input bit interface */ static int dyna_pci10xx_di_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct dyna_pci10xx_private *devpriv = dev->private; u16 d = 0; @@ -171,7 +174,7 @@ static int dyna_pci10xx_do_insn_bits(struct comedi_device *dev, } static int dyna_pci10xx_auto_attach(struct comedi_device *dev, - unsigned long context_unused) + unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct dyna_pci10xx_private *devpriv; diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index 1ea168620103..ba5b7a538492 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c @@ -445,7 +445,7 @@ static int icp_multi_reset(struct comedi_device *dev) } static int icp_multi_auto_attach(struct comedi_device *dev, - unsigned long context_unused) + unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct icp_multi_private *devpriv; diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 2d0e60d84a32..d473e03e34f7 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -423,7 +423,7 @@ static void me4000_reset(struct comedi_device *dev) /* Set both stop bits in the analog input control register */ outl(ME4000_AI_CTRL_BIT_IMMEDIATE_STOP | ME4000_AI_CTRL_BIT_STOP, - dev->iobase + ME4000_AI_CTRL_REG); + dev->iobase + ME4000_AI_CTRL_REG); /* Set both stop bits in the analog output control register */ val = ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP; @@ -437,7 +437,7 @@ static void me4000_reset(struct comedi_device *dev) /* Set the adustment register for AO demux */ outl(ME4000_AO_DEMUX_ADJUST_VALUE, - dev->iobase + ME4000_AO_DEMUX_ADJUST_REG); + dev->iobase + ME4000_AO_DEMUX_ADJUST_REG); /* * Set digital I/O direction for port 0 @@ -608,7 +608,7 @@ static int me4000_ai_check_chanlist(struct comedi_device *dev, if (!comedi_range_is_bipolar(s, range)) { dev_dbg(dev->class_dev, - "Bipolar is not selected in differential mode\n"); + "Bipolar is not selected in differential mode\n"); return -EINVAL; } } @@ -771,12 +771,12 @@ static int ai_prepare(struct comedi_device *dev, /* Stop triggers */ if (cmd->stop_src == TRIG_COUNT) { outl(cmd->chanlist_len * cmd->stop_arg, - dev->iobase + ME4000_AI_SAMPLE_COUNTER_REG); + dev->iobase + ME4000_AI_SAMPLE_COUNTER_REG); tmp |= ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ; } else if (cmd->stop_src == TRIG_NONE && cmd->scan_end_src == TRIG_COUNT) { outl(cmd->scan_end_arg, - dev->iobase + ME4000_AI_SAMPLE_COUNTER_REG); + dev->iobase + ME4000_AI_SAMPLE_COUNTER_REG); tmp |= ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ; } else { tmp |= ME4000_AI_CTRL_BIT_HF_IRQ; @@ -1186,13 +1186,13 @@ static int me4000_dio_insn_bits(struct comedi_device *dev, { if (comedi_dio_update_state(s, data)) { outl((s->state >> 0) & 0xFF, - dev->iobase + ME4000_DIO_PORT_0_REG); + dev->iobase + ME4000_DIO_PORT_0_REG); outl((s->state >> 8) & 0xFF, - dev->iobase + ME4000_DIO_PORT_1_REG); + dev->iobase + ME4000_DIO_PORT_1_REG); outl((s->state >> 16) & 0xFF, - dev->iobase + ME4000_DIO_PORT_2_REG); + dev->iobase + ME4000_DIO_PORT_2_REG); outl((s->state >> 24) & 0xFF, - dev->iobase + ME4000_DIO_PORT_3_REG); + dev->iobase + ME4000_DIO_PORT_3_REG); } data[1] = ((inl(dev->iobase + ME4000_DIO_PORT_0_REG) & 0xFF) << 0) | @@ -1296,7 +1296,7 @@ static int me4000_auto_attach(struct comedi_device *dev, if (pcidev->irq > 0) { result = request_irq(pcidev->irq, me4000_ai_isr, IRQF_SHARED, - dev->board_name, dev); + dev->board_name, dev); if (result == 0) dev->irq = pcidev->irq; } @@ -1378,7 +1378,7 @@ static int me4000_auto_attach(struct comedi_device *dev, if (!inl(dev->iobase + ME4000_DIO_DIR_REG)) { s->io_bits |= 0xFF; outl(ME4000_DIO_CTRL_BIT_MODE_0, - dev->iobase + ME4000_DIO_DIR_REG); + dev->iobase + ME4000_DIO_DIR_REG); } /* Counter subdevice (8254) */ diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c index 9d0714b802b1..1ff231f91f3b 100644 --- a/drivers/staging/comedi/drivers/ni_65xx.c +++ b/drivers/staging/comedi/drivers/ni_65xx.c @@ -676,7 +676,7 @@ static int ni_65xx_auto_attach(struct comedi_device *dev, } dev_info(dev->class_dev, "board: %s, ID=0x%02x", dev->board_name, - readb(dev->mmio + NI_65XX_ID_REG)); + readb(dev->mmio + NI_65XX_ID_REG)); ret = comedi_alloc_subdevices(dev, 4); if (ret) diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c index 5bb2b5e936bc..b6f8cd85c3aa 100644 --- a/drivers/staging/comedi/drivers/ni_mio_common.c +++ b/drivers/staging/comedi/drivers/ni_mio_common.c @@ -2526,7 +2526,7 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) start_stop_select |= AI_START_Select(1 + CR_CHAN(cmd->scan_begin_arg)); ni_stc_writew(dev, start_stop_select, - AI_START_STOP_Select_Register); + AI_START_STOP_Select_Register); break; } diff --git a/drivers/staging/comedi/drivers/pcmuio.c b/drivers/staging/comedi/drivers/pcmuio.c index 1a4a1f589a56..213457286031 100644 --- a/drivers/staging/comedi/drivers/pcmuio.c +++ b/drivers/staging/comedi/drivers/pcmuio.c @@ -568,7 +568,7 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it) } else if (it->options[2]) { /* request the irq for the 2nd asic */ ret = request_irq(it->options[2], pcmuio_interrupt, 0, - dev->board_name, dev); + dev->board_name, dev); if (ret == 0) devpriv->irq2 = it->options[2]; } diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index 2688af7f3405..20cce96d3d88 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -1181,8 +1181,8 @@ static void rtd_pci_latency_quirk(struct comedi_device *dev, pci_read_config_byte(pcidev, PCI_LATENCY_TIMER, &pci_latency); if (pci_latency < 32) { dev_info(dev->class_dev, - "PCI latency changed from %d to %d\n", - pci_latency, 32); + "PCI latency changed from %d to %d\n", + pci_latency, 32); pci_write_config_byte(pcidev, PCI_LATENCY_TIMER, 32); } } diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index 422ea9c73706..3b9ef9a6918b 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -231,9 +231,9 @@ static void s626_debi_replace(struct comedi_device *dev, unsigned int addr, /* ************** EEPROM ACCESS FUNCTIONS ************** */ static int s626_i2c_handshake_eoc(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned long context) + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned long context) { bool status; @@ -294,7 +294,7 @@ static uint8_t s626_i2c_read(struct comedi_device *dev, uint8_t addr) * Byte0 = Not sent. */ if (s626_i2c_handshake(dev, S626_I2C_B2(S626_I2C_ATTRSTART, - (devpriv->i2c_adrs | 1)) | + (devpriv->i2c_adrs | 1)) | S626_I2C_B1(S626_I2C_ATTRSTOP, 0) | S626_I2C_B0(S626_I2C_ATTRNOP, 0))) /* Abort function and declare error if handshake failed. */ @@ -517,8 +517,8 @@ static int s626_send_dac(struct comedi_device *dev, uint32_t val) /* * Private helper function: Write setpoint to an application DAC channel. */ -static int s626_set_dac(struct comedi_device *dev, uint16_t chan, - int16_t dacdata) +static int s626_set_dac(struct comedi_device *dev, + uint16_t chan, int16_t dacdata) { struct s626_private *devpriv = dev->private; uint16_t signmask; @@ -583,8 +583,8 @@ static int s626_set_dac(struct comedi_device *dev, uint16_t chan, return s626_send_dac(dev, val); } -static int s626_write_trim_dac(struct comedi_device *dev, uint8_t logical_chan, - uint8_t dac_data) +static int s626_write_trim_dac(struct comedi_device *dev, + uint8_t logical_chan, uint8_t dac_data) { struct s626_private *devpriv = dev->private; uint32_t chan; @@ -641,7 +641,7 @@ static int s626_load_trim_dacs(struct comedi_device *dev) /* Copy TrimDac setpoint values from EEPROM to TrimDacs. */ for (i = 0; i < ARRAY_SIZE(s626_trimchan); i++) { ret = s626_write_trim_dac(dev, i, - s626_i2c_read(dev, s626_trimadrs[i])); + s626_i2c_read(dev, s626_trimadrs[i])); if (ret) return ret; } @@ -2729,7 +2729,7 @@ static int s626_initialize(struct comedi_device *dev) } static int s626_auto_attach(struct comedi_device *dev, - unsigned long context_unused) + unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct s626_private *devpriv; diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index 1cd7403a4e9c..feaa5ae53fcb 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c @@ -633,8 +633,8 @@ static int receive_dux_commands(struct comedi_device *dev, unsigned int command) for (i = 0; i < RETRIES; i++) { ret = usb_bulk_msg(usb, usb_rcvbulkpipe(usb, 8), - devpriv->insn_buf, SIZEINSNBUF, - &nrec, BULK_TIMEOUT); + devpriv->insn_buf, SIZEINSNBUF, + &nrec, BULK_TIMEOUT); if (ret < 0) return ret; if (le16_to_cpu(devpriv->insn_buf[0]) == command) -- GitLab From c8f4b98f47e498a823d1b82b8f3848d81183ea22 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 5 Mar 2015 13:21:17 -0700 Subject: [PATCH 03157/11651] staging: comedi: drivers/*.c: remove unnecessary blank lines Blank lines are not needed before a close brace '}' or after an open brace '{'. Also remove any multiple blank lines. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adl_pci9111.c | 1 - drivers/staging/comedi/drivers/adl_pci9118.c | 1 - drivers/staging/comedi/drivers/adq12b.c | 3 --- drivers/staging/comedi/drivers/adv_pci_dio.c | 1 - drivers/staging/comedi/drivers/amplc_pc236_common.c | 1 - drivers/staging/comedi/drivers/amplc_pci224.c | 3 --- drivers/staging/comedi/drivers/cb_das16_cs.c | 2 -- drivers/staging/comedi/drivers/cb_pcidas64.c | 4 ---- drivers/staging/comedi/drivers/comedi_bond.c | 1 - drivers/staging/comedi/drivers/das1800.c | 1 - drivers/staging/comedi/drivers/das800.c | 4 ---- drivers/staging/comedi/drivers/dmm32at.c | 1 - drivers/staging/comedi/drivers/dt2801.c | 1 - drivers/staging/comedi/drivers/dt2811.c | 1 - drivers/staging/comedi/drivers/dt2814.c | 2 -- drivers/staging/comedi/drivers/dt2815.c | 1 - drivers/staging/comedi/drivers/dt282x.c | 1 - drivers/staging/comedi/drivers/gsc_hpdi.c | 1 - drivers/staging/comedi/drivers/icp_multi.c | 1 - drivers/staging/comedi/drivers/me4000.c | 9 --------- drivers/staging/comedi/drivers/mf6x4.c | 1 - drivers/staging/comedi/drivers/mpc624.c | 1 - drivers/staging/comedi/drivers/ni_660x.c | 1 - drivers/staging/comedi/drivers/ni_atmio.c | 2 -- drivers/staging/comedi/drivers/ni_atmio16d.c | 1 - drivers/staging/comedi/drivers/ni_mio_common.c | 2 -- drivers/staging/comedi/drivers/ni_pcimio.c | 1 - drivers/staging/comedi/drivers/pcl816.c | 3 --- drivers/staging/comedi/drivers/quatech_daqp_cs.c | 1 - drivers/staging/comedi/drivers/rtd520.c | 1 - drivers/staging/comedi/drivers/serial2002.c | 3 --- drivers/staging/comedi/drivers/ssv_dnp.c | 1 - drivers/staging/comedi/drivers/unioxx5.c | 2 -- drivers/staging/comedi/drivers/usbdux.c | 1 - drivers/staging/comedi/drivers/usbduxfast.c | 1 - 35 files changed, 62 deletions(-) diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index 144e9c2dbaf9..bf563ed08bc2 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -354,7 +354,6 @@ static int pci9111_ai_do_cmd_test(struct comedi_device *dev, return 5; return 0; - } static int pci9111_ai_do_cmd(struct comedi_device *dev, diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index 1cd54556a2dd..65b702cc04c1 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -633,7 +633,6 @@ static void pci9118_ai_munge(struct comedi_device *dev, array[i] ^= 0x8000; else array[i] = (array[i] >> 4) & 0x0fff; - } } diff --git a/drivers/staging/comedi/drivers/adq12b.c b/drivers/staging/comedi/drivers/adq12b.c index 8b15cbec9891..bc5f97f50f9a 100644 --- a/drivers/staging/comedi/drivers/adq12b.c +++ b/drivers/staging/comedi/drivers/adq12b.c @@ -69,8 +69,6 @@ If you do not specify any options, they will default to 13-oct-2007 + first try - - */ #include @@ -170,7 +168,6 @@ static int adq12b_di_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - /* only bits 0-4 have information about digital inputs */ data[1] = (inb(dev->iobase + ADQ12B_STINR) & ADQ12B_STINR_IN_MASK); diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index a46cffe5f9b8..11168f9e135b 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -419,7 +419,6 @@ static int pci_dio_insn_bits_di_b(struct comedi_device *dev, for (i = 0; i < d->regs; i++) data[1] |= inb(dev->iobase + d->addr + i) << (8 * i); - return insn->n; } diff --git a/drivers/staging/comedi/drivers/amplc_pc236_common.c b/drivers/staging/comedi/drivers/amplc_pc236_common.c index be87172d1f3f..cc26b9d04d66 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236_common.c +++ b/drivers/staging/comedi/drivers/amplc_pc236_common.c @@ -195,7 +195,6 @@ static void __exit amplc_pc236_common_exit(void) } module_exit(amplc_pc236_common_exit); - MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi helper for amplc_pc236 and amplc_pci236"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index 8ac35f9fc69f..cf5f646e514e 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -446,7 +446,6 @@ static void pci224_ao_stop(struct comedi_device *dev, if (!test_and_clear_bit(AO_CMD_STARTED, &devpriv->state)) return; - spin_lock_irqsave(&devpriv->ao_spinlock, flags); /* Kill the interrupts. */ devpriv->intsce = 0; @@ -1029,14 +1028,12 @@ pci224_auto_attach(struct comedi_device *dev, unsigned long context_model) if (!devpriv->ao_scan_vals) return -ENOMEM; - /* Allocate buffer to hold AO channel scan order. */ devpriv->ao_scan_order = kmalloc(sizeof(devpriv->ao_scan_order[0]) * thisboard->ao_chans, GFP_KERNEL); if (!devpriv->ao_scan_order) return -ENOMEM; - /* Disable interrupt sources. */ devpriv->intsce = 0; outb(0, devpriv->iobase1 + PCI224_INT_SCE); diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index 9c7242d81963..9abc2c795479 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -30,8 +30,6 @@ Devices: [ComputerBoards] PC-CARD DAS16/16 (cb_das16_cs), PC-CARD DAS16/16-AO Author: ds Updated: Mon, 04 Nov 2002 20:04:21 -0800 Status: experimental - - */ #include diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index c8f4a227cc59..5033c7cddda2 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -1475,7 +1475,6 @@ static int alloc_and_init_dma_members(struct comedi_device *dev) &devpriv->ai_buffer_bus_addr[i]); if (!devpriv->ai_buffer[i]) return -ENOMEM; - } for (i = 0; i < AO_DMA_RING_COUNT; i++) { if (ao_cmd_is_supported(thisboard)) { @@ -1485,7 +1484,6 @@ static int alloc_and_init_dma_members(struct comedi_device *dev) ao_buffer_bus_addr[i]); if (!devpriv->ao_buffer[i]) return -ENOMEM; - } } /* allocate dma descriptors */ @@ -1838,7 +1836,6 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, } for (n = 0; n < insn->n; n++) { - /* clear adc buffer (inside loop for 4020 sake) */ writew(0, devpriv->main_iobase + ADC_BUFFER_CLEAR_REG); @@ -1900,7 +1897,6 @@ static int ai_config_block_size(struct comedi_device *dev, unsigned int *data) retval = set_ai_fifo_size(dev, fifo_size); if (retval < 0) return retval; - } block_size = ai_fifo_size(dev) / fifo->num_segments * bytes_in_sample; diff --git a/drivers/staging/comedi/drivers/comedi_bond.c b/drivers/staging/comedi/drivers/comedi_bond.c index 7a68727cc880..96db0c2686a1 100644 --- a/drivers/staging/comedi/drivers/comedi_bond.c +++ b/drivers/staging/comedi/drivers/comedi_bond.c @@ -267,7 +267,6 @@ static int do_dev_config(struct comedi_device *dev, struct comedi_devconfig *it) strlcat(devpriv->name, buf, sizeof(devpriv->name)); } - } } diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c index ca4f322c0d2f..0a93ae93da93 100644 --- a/drivers/staging/comedi/drivers/das1800.c +++ b/drivers/staging/comedi/drivers/das1800.c @@ -1141,7 +1141,6 @@ static int das1800_di_rbits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - data[1] = inb(dev->iobase + DAS1800_DIGITAL) & 0xf; data[0] = 0; diff --git a/drivers/staging/comedi/drivers/das800.c b/drivers/staging/comedi/drivers/das800.c index 50ca03bd6459..ece3e56a72bb 100644 --- a/drivers/staging/comedi/drivers/das800.c +++ b/drivers/staging/comedi/drivers/das800.c @@ -43,8 +43,6 @@ Notes: The cio-das802/16 does not have a fifo-empty status bit! Therefore only fifo-half-full transfers are possible with this card. -*/ -/* cmd triggers supported: start_src: TRIG_NOW | TRIG_EXT @@ -52,8 +50,6 @@ cmd triggers supported: scan_end_src: TRIG_COUNT convert_src: TRIG_TIMER | TRIG_EXT stop_src: TRIG_NONE | TRIG_COUNT - - */ #include diff --git a/drivers/staging/comedi/drivers/dmm32at.c b/drivers/staging/comedi/drivers/dmm32at.c index 74830f4b95f5..094422f81d4c 100644 --- a/drivers/staging/comedi/drivers/dmm32at.c +++ b/drivers/staging/comedi/drivers/dmm32at.c @@ -397,7 +397,6 @@ static int dmm32at_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) } return 0; - } static int dmm32at_ai_cancel(struct comedi_device *dev, diff --git a/drivers/staging/comedi/drivers/dt2801.c b/drivers/staging/comedi/drivers/dt2801.c index 7e565fc944c4..80e38dedd359 100644 --- a/drivers/staging/comedi/drivers/dt2801.c +++ b/drivers/staging/comedi/drivers/dt2801.c @@ -126,7 +126,6 @@ static const struct comedi_lrange range_dt2801_ai_pgl_unipolar = { }; struct dt2801_board { - const char *name; int boardcode; int ad_diff; diff --git a/drivers/staging/comedi/drivers/dt2811.c b/drivers/staging/comedi/drivers/dt2811.c index d660f277487e..a80773291fdc 100644 --- a/drivers/staging/comedi/drivers/dt2811.c +++ b/drivers/staging/comedi/drivers/dt2811.c @@ -194,7 +194,6 @@ static const struct comedi_lrange range_dt2811_pgl_ai_5_bipolar = { #define DT2811_ADMODE 0x03 struct dt2811_board { - const char *name; const struct comedi_lrange *bip_5; const struct comedi_lrange *bip_2_5; diff --git a/drivers/staging/comedi/drivers/dt2814.c b/drivers/staging/comedi/drivers/dt2814.c index 9805be13005a..5a20be569011 100644 --- a/drivers/staging/comedi/drivers/dt2814.c +++ b/drivers/staging/comedi/drivers/dt2814.c @@ -56,7 +56,6 @@ addition, the clock does not seem to be very accurate. #define DT2814_CHANMASK 0x0f struct dt2814_private { - int ntrig; int curadchan; }; @@ -193,7 +192,6 @@ static int dt2814_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) outb(chan | DT2814_ENB | (trigvar << 5), dev->iobase + DT2814_CSR); return 0; - } static irqreturn_t dt2814_interrupt(int irq, void *d) diff --git a/drivers/staging/comedi/drivers/dt2815.c b/drivers/staging/comedi/drivers/dt2815.c index a98fb66fdd53..fb08569c1ac1 100644 --- a/drivers/staging/comedi/drivers/dt2815.c +++ b/drivers/staging/comedi/drivers/dt2815.c @@ -60,7 +60,6 @@ Configuration options: #define DT2815_STATUS 1 struct dt2815_private { - const struct comedi_lrange *range_type_list[8]; unsigned int ao_readback[8]; }; diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c index 2cdd8bf44b4d..52a50bc3343a 100644 --- a/drivers/staging/comedi/drivers/dt282x.c +++ b/drivers/staging/comedi/drivers/dt282x.c @@ -874,7 +874,6 @@ static int dt282x_ao_cmdtest(struct comedi_device *dev, return 4; return 0; - } static int dt282x_ao_inttrig(struct comedi_device *dev, diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c index deada9784b69..be9988d37338 100644 --- a/drivers/staging/comedi/drivers/gsc_hpdi.c +++ b/drivers/staging/comedi/drivers/gsc_hpdi.c @@ -433,7 +433,6 @@ static int gsc_hpdi_cmd_test(struct comedi_device *dev, return 5; return 0; - } /* setup dma descriptors so a link completes every 'len' bytes */ diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index ba5b7a538492..ddcb25df9c51 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c @@ -370,7 +370,6 @@ static irqreturn_t interrupt_service_icp_multi(int irq, void *d) break; default: break; - } return IRQ_HANDLED; diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index d473e03e34f7..ec99254b3a64 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -623,7 +623,6 @@ static int ai_round_cmd_args(struct comedi_device *dev, unsigned int *init_ticks, unsigned int *scan_ticks, unsigned int *chan_ticks) { - int rest; *init_ticks = 0; @@ -730,7 +729,6 @@ static int ai_prepare(struct comedi_device *dev, unsigned int init_ticks, unsigned int scan_ticks, unsigned int chan_ticks) { - unsigned int tmp = 0; /* Write timer arguments */ @@ -826,7 +824,6 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { - unsigned int init_ticks; unsigned int chan_ticks; unsigned int scan_ticks; @@ -918,7 +915,6 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev, if (cmd->start_src == TRIG_NOW && cmd->scan_begin_src == TRIG_TIMER && cmd->convert_src == TRIG_TIMER) { - /* Check timer arguments */ if (init_ticks < ME4000_AI_MIN_TICKS) { dev_err(dev->class_dev, "Invalid start arg\n"); @@ -940,7 +936,6 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev, } else if (cmd->start_src == TRIG_NOW && cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_TIMER) { - /* Check timer arguments */ if (init_ticks < ME4000_AI_MIN_TICKS) { dev_err(dev->class_dev, "Invalid start arg\n"); @@ -955,7 +950,6 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev, } else if (cmd->start_src == TRIG_EXT && cmd->scan_begin_src == TRIG_TIMER && cmd->convert_src == TRIG_TIMER) { - /* Check timer arguments */ if (init_ticks < ME4000_AI_MIN_TICKS) { dev_err(dev->class_dev, "Invalid start arg\n"); @@ -977,7 +971,6 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev, } else if (cmd->start_src == TRIG_EXT && cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_TIMER) { - /* Check timer arguments */ if (init_ticks < ME4000_AI_MIN_TICKS) { dev_err(dev->class_dev, "Invalid start arg\n"); @@ -992,7 +985,6 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev, } else if (cmd->start_src == TRIG_EXT && cmd->scan_begin_src == TRIG_EXT && cmd->convert_src == TRIG_TIMER) { - /* Check timer arguments */ if (init_ticks < ME4000_AI_MIN_TICKS) { dev_err(dev->class_dev, "Invalid start arg\n"); @@ -1007,7 +999,6 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev, } else if (cmd->start_src == TRIG_EXT && cmd->scan_begin_src == TRIG_EXT && cmd->convert_src == TRIG_EXT) { - /* Check timer arguments */ if (init_ticks < ME4000_AI_MIN_TICKS) { dev_err(dev->class_dev, "Invalid start arg\n"); diff --git a/drivers/staging/comedi/drivers/mf6x4.c b/drivers/staging/comedi/drivers/mf6x4.c index db972bce2b5b..e9a74ca8f7e9 100644 --- a/drivers/staging/comedi/drivers/mf6x4.c +++ b/drivers/staging/comedi/drivers/mf6x4.c @@ -237,7 +237,6 @@ static int mf6x4_auto_attach(struct comedi_device *dev, unsigned long context) else devpriv->gpioc_R = devpriv->bar0_mem + MF624_GPIOC_R; - ret = comedi_alloc_subdevices(dev, 4); if (ret) return ret; diff --git a/drivers/staging/comedi/drivers/mpc624.c b/drivers/staging/comedi/drivers/mpc624.c index 1241f9987cab..0207b8edfcb4 100644 --- a/drivers/staging/comedi/drivers/mpc624.c +++ b/drivers/staging/comedi/drivers/mpc624.c @@ -115,7 +115,6 @@ Configuration Options: (MPC624_OSR4 | MPC624_OSR3 | MPC624_OSR2 | MPC624_OSR1 | MPC624_OSR0) /* -------------------------------------------------------------------------- */ struct mpc624_private { - /* set by mpc624_attach() from driver's parameters */ unsigned long int ulConvertionRate; }; diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 9d7567bf1ce3..660dc6fc777e 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -195,7 +195,6 @@ static inline unsigned NI_660X_GPCT_SUBDEV(unsigned index) } struct NI_660xRegisterData { - const char *name; /* Register Name */ int offset; /* Offset from base address from GPCT chip */ enum ni_660x_register_direction direction; diff --git a/drivers/staging/comedi/drivers/ni_atmio.c b/drivers/staging/comedi/drivers/ni_atmio.c index 9cb9beb53e16..1304b06980a6 100644 --- a/drivers/staging/comedi/drivers/ni_atmio.c +++ b/drivers/staging/comedi/drivers/ni_atmio.c @@ -282,7 +282,6 @@ static int ni_getboardtype(struct comedi_device *dev) for (i = 0; i < ARRAY_SIZE(ni_boards); i++) { if (ni_boards[i].device_id == device_id) return i; - } if (device_id == 255) dev_err(dev->class_dev, "can't find board\n"); @@ -355,7 +354,6 @@ static int ni_atmio_attach(struct comedi_device *dev, if (ret < 0) return ret; - return 0; } diff --git a/drivers/staging/comedi/drivers/ni_atmio16d.c b/drivers/staging/comedi/drivers/ni_atmio16d.c index c484c89c94b5..73e580243795 100644 --- a/drivers/staging/comedi/drivers/ni_atmio16d.c +++ b/drivers/staging/comedi/drivers/ni_atmio16d.c @@ -96,7 +96,6 @@ Devices: [National Instruments] AT-MIO-16 (atmio16), AT-MIO-16D (atmio16d) #define CLOCK_100_HZ 0x8F25 struct atmio16_board_t { - const char *name; int has_8255; }; diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c index b6f8cd85c3aa..4aa8a2cef4d1 100644 --- a/drivers/staging/comedi/drivers/ni_mio_common.c +++ b/drivers/staging/comedi/drivers/ni_mio_common.c @@ -2569,7 +2569,6 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) } if (dev->irq) { - /* interrupt on FIFO, errors, SC_TC */ interrupt_a_enable |= AI_Error_Interrupt_Enable | AI_SC_TC_Interrupt_Enable; @@ -3839,7 +3838,6 @@ static int ni_serial_insn_config(struct comedi_device *dev, default: return -EINVAL; } - } static void init_ao_67xx(struct comedi_device *dev, struct comedi_subdevice *s) diff --git a/drivers/staging/comedi/drivers/ni_pcimio.c b/drivers/staging/comedi/drivers/ni_pcimio.c index e78739cce175..409090d78cc4 100644 --- a/drivers/staging/comedi/drivers/ni_pcimio.c +++ b/drivers/staging/comedi/drivers/ni_pcimio.c @@ -1041,7 +1041,6 @@ static int pcimio_dio_change(struct comedi_device *dev, return 0; } - static void m_series_init_eeprom_buffer(struct comedi_device *dev) { struct ni_private *devpriv = dev->private; diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c index 9cc6933d47da..992a38c81d0f 100644 --- a/drivers/staging/comedi/drivers/pcl816.c +++ b/drivers/staging/comedi/drivers/pcl816.c @@ -369,7 +369,6 @@ static int pcl816_ai_cmdtest(struct comedi_device *dev, if (err) return 2; - /* Step 3: check if arguments are trivially valid */ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); @@ -390,7 +389,6 @@ static int pcl816_ai_cmdtest(struct comedi_device *dev, if (err) return 3; - /* step 4: fix up any arguments */ if (cmd->convert_src == TRIG_TIMER) { unsigned int arg = cmd->convert_arg; @@ -402,7 +400,6 @@ static int pcl816_ai_cmdtest(struct comedi_device *dev, if (err) return 4; - /* step 5: complain about special chanlist considerations */ if (cmd->chanlist) { diff --git a/drivers/staging/comedi/drivers/quatech_daqp_cs.c b/drivers/staging/comedi/drivers/quatech_daqp_cs.c index 8387fd0e4b7e..aa8653465771 100644 --- a/drivers/staging/comedi/drivers/quatech_daqp_cs.c +++ b/drivers/staging/comedi/drivers/quatech_daqp_cs.c @@ -315,7 +315,6 @@ static int daqp_ai_insn_read(struct comedi_device *dev, devpriv->interrupt_mode = semaphore; for (i = 0; i < insn->n; i++) { - /* Start conversion */ outb(DAQP_COMMAND_ARM | DAQP_COMMAND_FIFO_DATA, dev->iobase + DAQP_COMMAND); diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index 20cce96d3d88..f05b187c33aa 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -839,7 +839,6 @@ static int rtd_ai_cmdtest(struct comedi_device *dev, if (err) return 3; - /* step 4: fix up any arguments */ if (cmd->scan_begin_src == TRIG_TIMER) { diff --git a/drivers/staging/comedi/drivers/serial2002.c b/drivers/staging/comedi/drivers/serial2002.c index 71226ee9064e..482a2a8a4a57 100644 --- a/drivers/staging/comedi/drivers/serial2002.c +++ b/drivers/staging/comedi/drivers/serial2002.c @@ -39,14 +39,12 @@ Status: in development #include struct serial2002_range_table_t { - /* HACK... */ int length; struct comedi_krange range; }; struct serial2002_private { - int port; /* /dev/ttyS */ int speed; /* baudrate */ struct file *tty; @@ -300,7 +298,6 @@ static struct serial_data serial2002_read(struct file *f, int timeout) } } return result; - } static void serial2002_write(struct file *f, struct serial_data data) diff --git a/drivers/staging/comedi/drivers/ssv_dnp.c b/drivers/staging/comedi/drivers/ssv_dnp.c index 848c30801580..acc7f3445c58 100644 --- a/drivers/staging/comedi/drivers/ssv_dnp.c +++ b/drivers/staging/comedi/drivers/ssv_dnp.c @@ -127,7 +127,6 @@ static int dnp_dio_insn_config(struct comedi_device *dev, outb(val, CSCDR); return insn->n; - } static int dnp_attach(struct comedi_device *dev, struct comedi_devconfig *it) diff --git a/drivers/staging/comedi/drivers/unioxx5.c b/drivers/staging/comedi/drivers/unioxx5.c index 12d828063c06..f5606b26a501 100644 --- a/drivers/staging/comedi/drivers/unioxx5.c +++ b/drivers/staging/comedi/drivers/unioxx5.c @@ -38,7 +38,6 @@ Devices: [Fastwel] UNIOxx-5 (unioxx5), */ - #include #include #include "../comedidev.h" @@ -81,7 +80,6 @@ struct unioxx5_subd_priv { static int __unioxx5_define_chan_offset(int chan_num) { - if (chan_num < 0 || chan_num > 23) return -1; diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index feaa5ae53fcb..a6403d2d2c08 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c @@ -1041,7 +1041,6 @@ static int usbdux_dio_insn_bits(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - struct usbdux_private *devpriv = dev->private; int ret; diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c index 7ce27c16c2f9..50c47af5f0ac 100644 --- a/drivers/staging/comedi/drivers/usbduxfast.c +++ b/drivers/staging/comedi/drivers/usbduxfast.c @@ -419,7 +419,6 @@ static int usbduxfast_ai_cmdtest(struct comedi_device *dev, /* step 4: fix up any arguments */ return 0; - } static int usbduxfast_ai_inttrig(struct comedi_device *dev, -- GitLab From 6ac986d098ee81b75973a0c2f46a9a4edef2a8c6 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 5 Mar 2015 13:21:18 -0700 Subject: [PATCH 03158/11651] staging: comedi: drivers/*.c: add missing braces {} to if/else branches According to the CodingStyle, braces should be used on all branches if thet are used on any branch, Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidas.c | 3 ++- drivers/staging/comedi/drivers/cb_pcidas64.c | 21 ++++++++++++------- .../staging/comedi/drivers/ni_mio_common.c | 6 ++++-- drivers/staging/comedi/drivers/ni_pcidio.c | 3 ++- drivers/staging/comedi/drivers/unioxx5.c | 3 ++- 5 files changed, 24 insertions(+), 12 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c index 112627d24d41..6fdf975daa19 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas.c +++ b/drivers/staging/comedi/drivers/cb_pcidas.c @@ -1508,8 +1508,9 @@ static int cb_pcidas_auto_attach(struct comedi_device *dev, dac08_write(dev, s->maxdata / 2); s->readback[i] = s->maxdata / 2; } - } else + } else { s->type = COMEDI_SUBD_UNUSED; + } /* make sure mailbox 4 is empty */ inl(devpriv->s5933_config + AMCC_OP_REG_IMB4); diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index 5033c7cddda2..2b7c50aa1e39 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -2630,8 +2630,9 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) bits |= ADC_START_TRIG_EXT_BITS; if (cmd->start_arg & CR_INVERT) bits |= ADC_START_TRIG_FALLING_BIT; - } else if (cmd->start_src == TRIG_NOW) + } else if (cmd->start_src == TRIG_NOW) { bits |= ADC_START_TRIG_SOFT_BITS; + } if (use_hw_sample_counter(cmd)) bits |= ADC_SAMPLE_COUNTER_EN_BIT; writew(bits, devpriv->main_iobase + ADC_CONTROL0_REG); @@ -2820,8 +2821,9 @@ static void handle_ai_interrupt(struct comedi_device *dev, if (devpriv->ai_cmd_running) { spin_unlock_irqrestore(&dev->spinlock, flags); pio_drain_ai_fifo(dev); - } else + } else { spin_unlock_irqrestore(&dev->spinlock, flags); + } } /* if we are have all the data, then quit */ if ((cmd->stop_src == TRIG_COUNT && @@ -3810,8 +3812,9 @@ static int setup_subdevices(struct comedi_device *dev) s->maxdata = 1; s->range_table = &range_digital; s->insn_bits = di_rbits; - } else + } else { s->type = COMEDI_SUBD_UNUSED; + } /* digital output */ if (thisboard->layout == LAYOUT_64XX) { @@ -3822,8 +3825,9 @@ static int setup_subdevices(struct comedi_device *dev) s->maxdata = 1; s->range_table = &range_digital; s->insn_bits = do_wbits; - } else + } else { s->type = COMEDI_SUBD_UNUSED; + } /* 8255 */ s = &dev->subdevices[4]; @@ -3851,8 +3855,9 @@ static int setup_subdevices(struct comedi_device *dev) s->range_table = &range_digital; s->insn_config = dio_60xx_config_insn; s->insn_bits = dio_60xx_wbits; - } else + } else { s->type = COMEDI_SUBD_UNUSED; + } /* caldac */ s = &dev->subdevices[6]; @@ -3891,8 +3896,9 @@ static int setup_subdevices(struct comedi_device *dev) ad8402_write(dev, i, s->maxdata / 2); s->readback[i] = s->maxdata / 2; } - } else + } else { s->type = COMEDI_SUBD_UNUSED; + } /* serial EEPROM, if present */ s = &dev->subdevices[8]; @@ -3902,8 +3908,9 @@ static int setup_subdevices(struct comedi_device *dev) s->n_chan = 128; s->maxdata = 0xffff; s->insn_read = eeprom_read_insn; - } else + } else { s->type = COMEDI_SUBD_UNUSED; + } /* user counter subd XXX */ s = &dev->subdevices[9]; diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c index 4aa8a2cef4d1..42fdedd6943c 100644 --- a/drivers/staging/comedi/drivers/ni_mio_common.c +++ b/drivers/staging/comedi/drivers/ni_mio_common.c @@ -1700,8 +1700,9 @@ static int ni_ao_setup_MITE_dma(struct comedi_device *dev) mite_prep_dma(devpriv->ao_mite_chan, 16, 32); } mite_dma_arm(devpriv->ao_mite_chan); - } else + } else { retval = -EIO; + } spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags); return retval; @@ -4961,8 +4962,9 @@ static int ni_set_master_clock(struct comedi_device *dev, } devpriv->clock_ns = period_ns; devpriv->clock_source = source; - } else + } else { return -EINVAL; + } } } return 3; diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c index 8d91029c7d30..28523199f7de 100644 --- a/drivers/staging/comedi/drivers/ni_pcidio.c +++ b/drivers/staging/comedi/drivers/ni_pcidio.c @@ -354,8 +354,9 @@ static int setup_mite_dma(struct comedi_device *dev, struct comedi_subdevice *s) if (devpriv->di_mite_chan) { mite_prep_dma(devpriv->di_mite_chan, 32, 32); mite_dma_arm(devpriv->di_mite_chan); - } else + } else { retval = -EIO; + } spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags); return retval; diff --git a/drivers/staging/comedi/drivers/unioxx5.c b/drivers/staging/comedi/drivers/unioxx5.c index f5606b26a501..51498b889c6c 100644 --- a/drivers/staging/comedi/drivers/unioxx5.c +++ b/drivers/staging/comedi/drivers/unioxx5.c @@ -411,8 +411,9 @@ static int __unioxx5_subdev_init(struct comedi_device *dev, if (ndef_flag) { usp->usp_module_type[i] = 0; ndef_flag = 0; - } else + } else { usp->usp_module_type[i] = inb(iobase + 6); + } udelay(1); } -- GitLab From 6301647b1873250cb8aac18e02a4ea062e72278e Mon Sep 17 00:00:00 2001 From: Oleg Drokin Date: Mon, 2 Mar 2015 01:01:46 -0500 Subject: [PATCH 03159/11651] staging/lustre/ptlrpc: Do not use deprecated cpus_* functions As per Rusty Russel, cpus_* functions are deprecated. When mixing cpumask_copy with cpus_weight, they operate on different sized masks if CPUMASK_OFFSTACK is enabled, causing an immediate assertion failure. Copying of cpumasks by assignment is also not allowed now. Additionally, in ptlrpc/service.c avoid the cpumask copies, since we only use it to check how many siblings are there for core #0 and nothing else. Reported-by: Tyson Whitehead Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c | 8 ++++---- drivers/staging/lustre/lustre/ptlrpc/service.c | 9 +++------ 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c index 8f7be84aa187..0c178ec0e487 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c +++ b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c @@ -511,10 +511,10 @@ static int ptlrpcd_bind(int index, int max) #if defined(CONFIG_NUMA) { int i; - mask = *cpumask_of_node(cpu_to_node(index)); + cpumask_copy(&mask, cpumask_of_node(cpu_to_node(index))); for (i = max; i < num_online_cpus(); i++) - cpu_clear(i, mask); - pc->pc_npartners = cpus_weight(mask) - 1; + cpumask_clear_cpu(i, &mask); + pc->pc_npartners = cpumask_weight(&mask) - 1; set_bit(LIOD_BIND, &pc->pc_flags); } #else @@ -554,7 +554,7 @@ static int ptlrpcd_bind(int index, int max) * that are already initialized */ for (pidx = 0, i = 0; i < index; i++) { - if (cpu_isset(i, mask)) { + if (cpumask_test_cpu(i, &mask)) { ppc = &ptlrpcds->pd_threads[i]; pc->pc_partners[pidx++] = ppc; ppc->pc_partners[ppc-> diff --git a/drivers/staging/lustre/lustre/ptlrpc/service.c b/drivers/staging/lustre/lustre/ptlrpc/service.c index 635b12b22cef..8e61421515cb 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/service.c +++ b/drivers/staging/lustre/lustre/ptlrpc/service.c @@ -543,7 +543,6 @@ ptlrpc_server_nthreads_check(struct ptlrpc_service *svc, if (tc->tc_thr_factor != 0) { int factor = tc->tc_thr_factor; const int fade = 4; - cpumask_t mask; /* * User wants to increase number of threads with for @@ -557,8 +556,8 @@ ptlrpc_server_nthreads_check(struct ptlrpc_service *svc, * have too many threads no matter how many cores/HTs * there are. */ - cpumask_copy(&mask, topology_thread_cpumask(0)); - if (cpus_weight(mask) > 1) { /* weight is # of HTs */ + /* weight is # of HTs */ + if (cpumask_weight(topology_thread_cpumask(0)) > 1) { /* depress thread factor for hyper-thread */ factor = factor - (factor >> 1) + (factor >> 3); } @@ -2752,7 +2751,6 @@ int ptlrpc_start_thread(struct ptlrpc_service_part *svcpt, int wait) int ptlrpc_hr_init(void) { - cpumask_t mask; struct ptlrpc_hr_partition *hrp; struct ptlrpc_hr_thread *hrt; int rc; @@ -2770,8 +2768,7 @@ int ptlrpc_hr_init(void) init_waitqueue_head(&ptlrpc_hr.hr_waitq); - cpumask_copy(&mask, topology_thread_cpumask(0)); - weight = cpus_weight(mask); + weight = cpumask_weight(topology_thread_cpumask(0)); cfs_percpt_for_each(hrp, i, ptlrpc_hr.hr_partitions) { hrp->hrp_cpt = i; -- GitLab From c96d236f8f4d479d25cb493c8ec240f7129709ca Mon Sep 17 00:00:00 2001 From: Oleg Drokin Date: Mon, 2 Mar 2015 01:01:47 -0500 Subject: [PATCH 03160/11651] staging/lustre/libcfs: replace deprecated cpus_ calls with cpumask_ Rusty Russel advises that cpus_* functions are deprecated to work on cpumasks and cpumask_* functions should be called instead, otherwise problems with CPUMASK_OFFSTACK arise. Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- .../lustre/lustre/libcfs/linux/linux-cpu.c | 78 +++++++++---------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/drivers/staging/lustre/lustre/libcfs/linux/linux-cpu.c b/drivers/staging/lustre/lustre/libcfs/linux/linux-cpu.c index 05f7595f18aa..1eeacefef52c 100644 --- a/drivers/staging/lustre/lustre/libcfs/linux/linux-cpu.c +++ b/drivers/staging/lustre/lustre/libcfs/linux/linux-cpu.c @@ -240,8 +240,8 @@ cfs_cpt_weight(struct cfs_cpt_table *cptab, int cpt) LASSERT(cpt == CFS_CPT_ANY || (cpt >= 0 && cpt < cptab->ctb_nparts)); return cpt == CFS_CPT_ANY ? - cpus_weight(*cptab->ctb_cpumask) : - cpus_weight(*cptab->ctb_parts[cpt].cpt_cpumask); + cpumask_weight(cptab->ctb_cpumask) : + cpumask_weight(cptab->ctb_parts[cpt].cpt_cpumask); } EXPORT_SYMBOL(cfs_cpt_weight); @@ -251,8 +251,8 @@ cfs_cpt_online(struct cfs_cpt_table *cptab, int cpt) LASSERT(cpt == CFS_CPT_ANY || (cpt >= 0 && cpt < cptab->ctb_nparts)); return cpt == CFS_CPT_ANY ? - any_online_cpu(*cptab->ctb_cpumask) != NR_CPUS : - any_online_cpu(*cptab->ctb_parts[cpt].cpt_cpumask) != NR_CPUS; + any_online_cpu(*cptab->ctb_cpumask) < nr_cpu_ids : + any_online_cpu(*cptab->ctb_parts[cpt].cpt_cpumask) < nr_cpu_ids; } EXPORT_SYMBOL(cfs_cpt_online); @@ -283,7 +283,7 @@ cfs_cpt_set_cpu(struct cfs_cpt_table *cptab, int cpt, int cpu) LASSERT(cpt >= 0 && cpt < cptab->ctb_nparts); - if (cpu < 0 || cpu >= NR_CPUS || !cpu_online(cpu)) { + if (cpu < 0 || cpu >= nr_cpu_ids || !cpu_online(cpu)) { CDEBUG(D_INFO, "CPU %d is invalid or it's offline\n", cpu); return 0; } @@ -296,11 +296,11 @@ cfs_cpt_set_cpu(struct cfs_cpt_table *cptab, int cpt, int cpu) cptab->ctb_cpu2cpt[cpu] = cpt; - LASSERT(!cpu_isset(cpu, *cptab->ctb_cpumask)); - LASSERT(!cpu_isset(cpu, *cptab->ctb_parts[cpt].cpt_cpumask)); + LASSERT(!cpumask_test_cpu(cpu, cptab->ctb_cpumask)); + LASSERT(!cpumask_test_cpu(cpu, cptab->ctb_parts[cpt].cpt_cpumask)); - cpu_set(cpu, *cptab->ctb_cpumask); - cpu_set(cpu, *cptab->ctb_parts[cpt].cpt_cpumask); + cpumask_set_cpu(cpu, cptab->ctb_cpumask); + cpumask_set_cpu(cpu, cptab->ctb_parts[cpt].cpt_cpumask); node = cpu_to_node(cpu); @@ -324,7 +324,7 @@ cfs_cpt_unset_cpu(struct cfs_cpt_table *cptab, int cpt, int cpu) LASSERT(cpt == CFS_CPT_ANY || (cpt >= 0 && cpt < cptab->ctb_nparts)); - if (cpu < 0 || cpu >= NR_CPUS) { + if (cpu < 0 || cpu >= nr_cpu_ids) { CDEBUG(D_INFO, "Invalid CPU id %d\n", cpu); return; } @@ -344,11 +344,11 @@ cfs_cpt_unset_cpu(struct cfs_cpt_table *cptab, int cpt, int cpu) return; } - LASSERT(cpu_isset(cpu, *cptab->ctb_parts[cpt].cpt_cpumask)); - LASSERT(cpu_isset(cpu, *cptab->ctb_cpumask)); + LASSERT(cpumask_test_cpu(cpu, cptab->ctb_parts[cpt].cpt_cpumask)); + LASSERT(cpumask_test_cpu(cpu, cptab->ctb_cpumask)); - cpu_clear(cpu, *cptab->ctb_parts[cpt].cpt_cpumask); - cpu_clear(cpu, *cptab->ctb_cpumask); + cpumask_clear_cpu(cpu, cptab->ctb_parts[cpt].cpt_cpumask); + cpumask_clear_cpu(cpu, cptab->ctb_cpumask); cptab->ctb_cpu2cpt[cpu] = -1; node = cpu_to_node(cpu); @@ -383,7 +383,7 @@ cfs_cpt_set_cpumask(struct cfs_cpt_table *cptab, int cpt, cpumask_t *mask) { int i; - if (cpus_weight(*mask) == 0 || any_online_cpu(*mask) == NR_CPUS) { + if (cpumask_weight(mask) == 0 || any_online_cpu(*mask) >= nr_cpu_ids) { CDEBUG(D_INFO, "No online CPU is found in the CPU mask for CPU partition %d\n", cpt); return 0; @@ -554,7 +554,7 @@ EXPORT_SYMBOL(cfs_cpt_current); int cfs_cpt_of_cpu(struct cfs_cpt_table *cptab, int cpu) { - LASSERT(cpu >= 0 && cpu < NR_CPUS); + LASSERT(cpu >= 0 && cpu < nr_cpu_ids); return cptab->ctb_cpu2cpt[cpu]; } @@ -578,14 +578,14 @@ cfs_cpt_bind(struct cfs_cpt_table *cptab, int cpt) nodemask = cptab->ctb_parts[cpt].cpt_nodemask; } - if (any_online_cpu(*cpumask) == NR_CPUS) { + if (any_online_cpu(*cpumask) >= nr_cpu_ids) { CERROR("No online CPU found in CPU partition %d, did someone do CPU hotplug on system? You might need to reload Lustre modules to keep system working well.\n", cpt); return -EINVAL; } for_each_online_cpu(i) { - if (cpu_isset(i, *cpumask)) + if (cpumask_test_cpu(i, cpumask)) continue; rc = set_cpus_allowed_ptr(current, cpumask); @@ -616,14 +616,14 @@ cfs_cpt_choose_ncpus(struct cfs_cpt_table *cptab, int cpt, LASSERT(number > 0); - if (number >= cpus_weight(*node)) { - while (!cpus_empty(*node)) { - cpu = first_cpu(*node); + if (number >= cpumask_weight(node)) { + while (!cpumask_empty(node)) { + cpu = cpumask_first(node); rc = cfs_cpt_set_cpu(cptab, cpt, cpu); if (!rc) return -EINVAL; - cpu_clear(cpu, *node); + cpumask_clear_cpu(cpu, node); } return 0; } @@ -636,27 +636,27 @@ cfs_cpt_choose_ncpus(struct cfs_cpt_table *cptab, int cpt, goto out; } - while (!cpus_empty(*node)) { - cpu = first_cpu(*node); + while (!cpumask_empty(node)) { + cpu = cpumask_first(node); /* get cpumask for cores in the same socket */ cfs_cpu_core_siblings(cpu, socket); - cpus_and(*socket, *socket, *node); + cpumask_and(socket, socket, node); - LASSERT(!cpus_empty(*socket)); + LASSERT(!cpumask_empty(socket)); - while (!cpus_empty(*socket)) { + while (!cpumask_empty(socket)) { int i; /* get cpumask for hts in the same core */ cfs_cpu_ht_siblings(cpu, core); - cpus_and(*core, *core, *node); + cpumask_and(core, core, node); - LASSERT(!cpus_empty(*core)); + LASSERT(!cpumask_empty(core)); for_each_cpu_mask(i, *core) { - cpu_clear(i, *socket); - cpu_clear(i, *node); + cpumask_clear_cpu(i, socket); + cpumask_clear_cpu(i, node); rc = cfs_cpt_set_cpu(cptab, cpt, i); if (!rc) { @@ -667,7 +667,7 @@ cfs_cpt_choose_ncpus(struct cfs_cpt_table *cptab, int cpt, if (--number == 0) goto out; } - cpu = first_cpu(*socket); + cpu = cpumask_first(socket); } } @@ -767,7 +767,7 @@ cfs_cpt_table_create(int ncpt) for_each_online_node(i) { cfs_node_to_cpumask(i, mask); - while (!cpus_empty(*mask)) { + while (!cpumask_empty(mask)) { struct cfs_cpu_partition *part; int n; @@ -776,24 +776,24 @@ cfs_cpt_table_create(int ncpt) part = &cptab->ctb_parts[cpt]; - n = num - cpus_weight(*part->cpt_cpumask); + n = num - cpumask_weight(part->cpt_cpumask); LASSERT(n > 0); rc = cfs_cpt_choose_ncpus(cptab, cpt, mask, n); if (rc < 0) goto failed; - LASSERT(num >= cpus_weight(*part->cpt_cpumask)); - if (num == cpus_weight(*part->cpt_cpumask)) + LASSERT(num >= cpumask_weight(part->cpt_cpumask)); + if (num == cpumask_weight(part->cpt_cpumask)) cpt++; } } if (cpt != ncpt || - num != cpus_weight(*cptab->ctb_parts[ncpt - 1].cpt_cpumask)) { + num != cpumask_weight(cptab->ctb_parts[ncpt - 1].cpt_cpumask)) { CERROR("Expect %d(%d) CPU partitions but got %d(%d), CPU hotplug/unplug while setting?\n", cptab->ctb_nparts, num, cpt, - cpus_weight(*cptab->ctb_parts[ncpt - 1].cpt_cpumask)); + cpumask_weight(cptab->ctb_parts[ncpt - 1].cpt_cpumask)); goto failed; } @@ -845,7 +845,7 @@ cfs_cpt_table_create_pattern(char *pattern) return NULL; } - high = node ? MAX_NUMNODES - 1 : NR_CPUS - 1; + high = node ? MAX_NUMNODES - 1 : nr_cpu_ids - 1; cptab = cfs_cpt_table_alloc(ncpt); if (cptab == NULL) { -- GitLab From 804db5d06d549119b885443d9b2dc2da7d80f149 Mon Sep 17 00:00:00 2001 From: Alberto Pires de Oliveira Neto Date: Mon, 2 Mar 2015 21:09:48 -0300 Subject: [PATCH 03161/11651] staging: lustre: space prohibited between function name and open parenthesis '(' This patch fixes checkpatch.pl warning. WARNING: space prohibited between function name and open parenthesis '(' Signed-off-by: Alberto Pires de Oliveira Neto Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/fld/fld_request.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/lustre/lustre/fld/fld_request.c b/drivers/staging/lustre/lustre/fld/fld_request.c index f3e9154afdc2..22e0d94bb0f8 100644 --- a/drivers/staging/lustre/lustre/fld/fld_request.c +++ b/drivers/staging/lustre/lustre/fld/fld_request.c @@ -279,7 +279,7 @@ EXPORT_SYMBOL(fld_client_del_target); static struct proc_dir_entry *fld_type_proc_dir; -#if defined (CONFIG_PROC_FS) +#if defined(CONFIG_PROC_FS) static int fld_client_proc_init(struct lu_client_fld *fld) { int rc; -- GitLab From 87643abf92484074937594897145bb53efc0e77e Mon Sep 17 00:00:00 2001 From: Matthew Tyler Date: Fri, 6 Mar 2015 18:09:27 +0800 Subject: [PATCH 03162/11651] staging:lustre:libcfs: Merge linux-proc.c into module.c module.c was previously the sole exporter of symbols from linux-proc.c This patch removes the global symbols by merging the two files Signed-off-by: Matthew Tyler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/libcfs/Makefile | 2 +- .../lustre/lustre/libcfs/linux/linux-proc.c | 577 ------------------ drivers/staging/lustre/lustre/libcfs/module.c | 561 ++++++++++++++++- 3 files changed, 548 insertions(+), 592 deletions(-) delete mode 100644 drivers/staging/lustre/lustre/libcfs/linux/linux-proc.c diff --git a/drivers/staging/lustre/lustre/libcfs/Makefile b/drivers/staging/lustre/lustre/libcfs/Makefile index fcecbd2271af..2996a48a31fb 100644 --- a/drivers/staging/lustre/lustre/libcfs/Makefile +++ b/drivers/staging/lustre/lustre/libcfs/Makefile @@ -3,7 +3,7 @@ obj-$(CONFIG_LUSTRE_FS) += libcfs.o libcfs-linux-objs := linux-tracefile.o linux-debug.o libcfs-linux-objs += linux-prim.o linux-cpu.o libcfs-linux-objs += linux-tcpip.o -libcfs-linux-objs += linux-proc.o linux-curproc.o +libcfs-linux-objs += linux-curproc.o libcfs-linux-objs += linux-module.o libcfs-linux-objs += linux-crypto.o libcfs-linux-objs += linux-crypto-adler.o diff --git a/drivers/staging/lustre/lustre/libcfs/linux/linux-proc.c b/drivers/staging/lustre/lustre/libcfs/linux/linux-proc.c deleted file mode 100644 index 3100cb138548..000000000000 --- a/drivers/staging/lustre/lustre/libcfs/linux/linux-proc.c +++ /dev/null @@ -1,577 +0,0 @@ -/* - * GPL HEADER START - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 only, - * 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 version 2 for more details (a copy is included - * in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; If not, see - * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - * GPL HEADER END - */ -/* - * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. - * Use is subject to license terms. - * - * Copyright (c) 2011, 2012, Intel Corporation. - */ -/* - * This file is part of Lustre, http://www.lustre.org/ - * Lustre is a trademark of Sun Microsystems, Inc. - * - * libcfs/libcfs/linux/linux-proc.c - * - * Author: Zach Brown - * Author: Peter J. Braam - * Author: Phil Schwan - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include -#include - -# define DEBUG_SUBSYSTEM S_LNET - -#include "../../../include/linux/libcfs/libcfs.h" -#include -#include "../tracefile.h" - -static struct ctl_table_header *lnet_table_header = NULL; -extern char lnet_upcall[1024]; -/** - * The path of debug log dump upcall script. - */ -extern char lnet_debug_log_upcall[1024]; - -#define CTL_LNET (0x100) -enum { - PSDEV_DEBUG = 1, /* control debugging */ - PSDEV_SUBSYSTEM_DEBUG, /* control debugging */ - PSDEV_PRINTK, /* force all messages to console */ - PSDEV_CONSOLE_RATELIMIT, /* ratelimit console messages */ - PSDEV_CONSOLE_MAX_DELAY_CS, /* maximum delay over which we skip messages */ - PSDEV_CONSOLE_MIN_DELAY_CS, /* initial delay over which we skip messages */ - PSDEV_CONSOLE_BACKOFF, /* delay increase factor */ - PSDEV_DEBUG_PATH, /* crashdump log location */ - PSDEV_DEBUG_DUMP_PATH, /* crashdump tracelog location */ - PSDEV_CPT_TABLE, /* information about cpu partitions */ - PSDEV_LNET_UPCALL, /* User mode upcall script */ - PSDEV_LNET_MEMUSED, /* bytes currently PORTAL_ALLOCated */ - PSDEV_LNET_CATASTROPHE, /* if we have LBUGged or panic'd */ - PSDEV_LNET_PANIC_ON_LBUG, /* flag to panic on LBUG */ - PSDEV_LNET_DUMP_KERNEL, /* snapshot kernel debug buffer to file */ - PSDEV_LNET_DAEMON_FILE, /* spool kernel debug buffer to file */ - PSDEV_LNET_DEBUG_MB, /* size of debug buffer */ - PSDEV_LNET_DEBUG_LOG_UPCALL, /* debug log upcall script */ - PSDEV_LNET_WATCHDOG_RATELIMIT, /* ratelimit watchdog messages */ - PSDEV_LNET_FORCE_LBUG, /* hook to force an LBUG */ - PSDEV_LNET_FAIL_LOC, /* control test failures instrumentation */ - PSDEV_LNET_FAIL_VAL, /* userdata for fail loc */ -}; - -static int proc_call_handler(void *data, int write, loff_t *ppos, - void __user *buffer, size_t *lenp, - int (*handler)(void *data, int write, - loff_t pos, void __user *buffer, int len)) -{ - int rc = handler(data, write, *ppos, buffer, *lenp); - - if (rc < 0) - return rc; - - if (write) { - *ppos += *lenp; - } else { - *lenp = rc; - *ppos += rc; - } - return 0; -} - -static int __proc_dobitmasks(void *data, int write, - loff_t pos, void __user *buffer, int nob) -{ - const int tmpstrlen = 512; - char *tmpstr; - int rc; - unsigned int *mask = data; - int is_subsys = (mask == &libcfs_subsystem_debug) ? 1 : 0; - int is_printk = (mask == &libcfs_printk) ? 1 : 0; - - rc = cfs_trace_allocate_string_buffer(&tmpstr, tmpstrlen); - if (rc < 0) - return rc; - - if (!write) { - libcfs_debug_mask2str(tmpstr, tmpstrlen, *mask, is_subsys); - rc = strlen(tmpstr); - - if (pos >= rc) { - rc = 0; - } else { - rc = cfs_trace_copyout_string(buffer, nob, - tmpstr + pos, "\n"); - } - } else { - rc = cfs_trace_copyin_string(tmpstr, tmpstrlen, buffer, nob); - if (rc < 0) { - cfs_trace_free_string_buffer(tmpstr, tmpstrlen); - return rc; - } - - rc = libcfs_debug_str2mask(mask, tmpstr, is_subsys); - /* Always print LBUG/LASSERT to console, so keep this mask */ - if (is_printk) - *mask |= D_EMERG; - } - - cfs_trace_free_string_buffer(tmpstr, tmpstrlen); - return rc; -} - -static int proc_dobitmasks(struct ctl_table *table, int write, - void __user *buffer, size_t *lenp, loff_t *ppos) -{ - return proc_call_handler(table->data, write, ppos, buffer, lenp, - __proc_dobitmasks); -} - -static int min_watchdog_ratelimit; /* disable ratelimiting */ -static int max_watchdog_ratelimit = (24*60*60); /* limit to once per day */ - -static int __proc_dump_kernel(void *data, int write, - loff_t pos, void __user *buffer, int nob) -{ - if (!write) - return 0; - - return cfs_trace_dump_debug_buffer_usrstr(buffer, nob); -} - -static int proc_dump_kernel(struct ctl_table *table, int write, - void __user *buffer, size_t *lenp, loff_t *ppos) -{ - return proc_call_handler(table->data, write, ppos, buffer, lenp, - __proc_dump_kernel); -} - -static int __proc_daemon_file(void *data, int write, - loff_t pos, void __user *buffer, int nob) -{ - if (!write) { - int len = strlen(cfs_tracefile); - - if (pos >= len) - return 0; - - return cfs_trace_copyout_string(buffer, nob, - cfs_tracefile + pos, "\n"); - } - - return cfs_trace_daemon_command_usrstr(buffer, nob); -} - -static int proc_daemon_file(struct ctl_table *table, int write, - void __user *buffer, size_t *lenp, loff_t *ppos) -{ - return proc_call_handler(table->data, write, ppos, buffer, lenp, - __proc_daemon_file); -} - -static int __proc_debug_mb(void *data, int write, - loff_t pos, void __user *buffer, int nob) -{ - if (!write) { - char tmpstr[32]; - int len = snprintf(tmpstr, sizeof(tmpstr), "%d", - cfs_trace_get_debug_mb()); - - if (pos >= len) - return 0; - - return cfs_trace_copyout_string(buffer, nob, tmpstr + pos, - "\n"); - } - - return cfs_trace_set_debug_mb_usrstr(buffer, nob); -} - -static int proc_debug_mb(struct ctl_table *table, int write, - void __user *buffer, size_t *lenp, loff_t *ppos) -{ - return proc_call_handler(table->data, write, ppos, buffer, lenp, - __proc_debug_mb); -} - -static int proc_console_max_delay_cs(struct ctl_table *table, int write, - void __user *buffer, size_t *lenp, - loff_t *ppos) -{ - int rc, max_delay_cs; - struct ctl_table dummy = *table; - long d; - - dummy.data = &max_delay_cs; - dummy.proc_handler = &proc_dointvec; - - if (!write) { /* read */ - max_delay_cs = cfs_duration_sec(libcfs_console_max_delay * 100); - rc = proc_dointvec(&dummy, write, buffer, lenp, ppos); - return rc; - } - - /* write */ - max_delay_cs = 0; - rc = proc_dointvec(&dummy, write, buffer, lenp, ppos); - if (rc < 0) - return rc; - if (max_delay_cs <= 0) - return -EINVAL; - - d = cfs_time_seconds(max_delay_cs) / 100; - if (d == 0 || d < libcfs_console_min_delay) - return -EINVAL; - libcfs_console_max_delay = d; - - return rc; -} - -static int proc_console_min_delay_cs(struct ctl_table *table, int write, - void __user *buffer, size_t *lenp, - loff_t *ppos) -{ - int rc, min_delay_cs; - struct ctl_table dummy = *table; - long d; - - dummy.data = &min_delay_cs; - dummy.proc_handler = &proc_dointvec; - - if (!write) { /* read */ - min_delay_cs = cfs_duration_sec(libcfs_console_min_delay * 100); - rc = proc_dointvec(&dummy, write, buffer, lenp, ppos); - return rc; - } - - /* write */ - min_delay_cs = 0; - rc = proc_dointvec(&dummy, write, buffer, lenp, ppos); - if (rc < 0) - return rc; - if (min_delay_cs <= 0) - return -EINVAL; - - d = cfs_time_seconds(min_delay_cs) / 100; - if (d == 0 || d > libcfs_console_max_delay) - return -EINVAL; - libcfs_console_min_delay = d; - - return rc; -} - -static int proc_console_backoff(struct ctl_table *table, int write, - void __user *buffer, size_t *lenp, loff_t *ppos) -{ - int rc, backoff; - struct ctl_table dummy = *table; - - dummy.data = &backoff; - dummy.proc_handler = &proc_dointvec; - - if (!write) { /* read */ - backoff= libcfs_console_backoff; - rc = proc_dointvec(&dummy, write, buffer, lenp, ppos); - return rc; - } - - /* write */ - backoff = 0; - rc = proc_dointvec(&dummy, write, buffer, lenp, ppos); - if (rc < 0) - return rc; - if (backoff <= 0) - return -EINVAL; - - libcfs_console_backoff = backoff; - - return rc; -} - -static int libcfs_force_lbug(struct ctl_table *table, int write, - void __user *buffer, - size_t *lenp, loff_t *ppos) -{ - if (write) - LBUG(); - return 0; -} - -static int proc_fail_loc(struct ctl_table *table, int write, - void __user *buffer, - size_t *lenp, loff_t *ppos) -{ - int rc; - long old_fail_loc = cfs_fail_loc; - - rc = proc_doulongvec_minmax(table, write, buffer, lenp, ppos); - if (old_fail_loc != cfs_fail_loc) - wake_up(&cfs_race_waitq); - return rc; -} - -static int __proc_cpt_table(void *data, int write, - loff_t pos, void __user *buffer, int nob) -{ - char *buf = NULL; - int len = 4096; - int rc = 0; - - if (write) - return -EPERM; - - LASSERT(cfs_cpt_table != NULL); - - while (1) { - LIBCFS_ALLOC(buf, len); - if (buf == NULL) - return -ENOMEM; - - rc = cfs_cpt_table_print(cfs_cpt_table, buf, len); - if (rc >= 0) - break; - - if (rc == -EFBIG) { - LIBCFS_FREE(buf, len); - len <<= 1; - continue; - } - goto out; - } - - if (pos >= rc) { - rc = 0; - goto out; - } - - rc = cfs_trace_copyout_string(buffer, nob, buf + pos, NULL); - out: - if (buf != NULL) - LIBCFS_FREE(buf, len); - return rc; -} - -static int proc_cpt_table(struct ctl_table *table, int write, - void __user *buffer, size_t *lenp, loff_t *ppos) -{ - return proc_call_handler(table->data, write, ppos, buffer, lenp, - __proc_cpt_table); -} - -static struct ctl_table lnet_table[] = { - /* - * NB No .strategy entries have been provided since sysctl(8) prefers - * to go via /proc for portability. - */ - { - .procname = "debug", - .data = &libcfs_debug, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dobitmasks, - }, - { - .procname = "subsystem_debug", - .data = &libcfs_subsystem_debug, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dobitmasks, - }, - { - .procname = "printk", - .data = &libcfs_printk, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dobitmasks, - }, - { - .procname = "console_ratelimit", - .data = &libcfs_console_ratelimit, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec - }, - { - .procname = "console_max_delay_centisecs", - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_console_max_delay_cs - }, - { - .procname = "console_min_delay_centisecs", - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_console_min_delay_cs - }, - { - .procname = "console_backoff", - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_console_backoff - }, - - { - .procname = "debug_path", - .data = libcfs_debug_file_path_arr, - .maxlen = sizeof(libcfs_debug_file_path_arr), - .mode = 0644, - .proc_handler = &proc_dostring, - }, - - { - .procname = "cpu_partition_table", - .maxlen = 128, - .mode = 0444, - .proc_handler = &proc_cpt_table, - }, - - { - .procname = "upcall", - .data = lnet_upcall, - .maxlen = sizeof(lnet_upcall), - .mode = 0644, - .proc_handler = &proc_dostring, - }, - { - .procname = "debug_log_upcall", - .data = lnet_debug_log_upcall, - .maxlen = sizeof(lnet_debug_log_upcall), - .mode = 0644, - .proc_handler = &proc_dostring, - }, - { - .procname = "lnet_memused", - .data = (int *)&libcfs_kmemory.counter, - .maxlen = sizeof(int), - .mode = 0444, - .proc_handler = &proc_dointvec, - }, - { - .procname = "catastrophe", - .data = &libcfs_catastrophe, - .maxlen = sizeof(int), - .mode = 0444, - .proc_handler = &proc_dointvec, - }, - { - .procname = "panic_on_lbug", - .data = &libcfs_panic_on_lbug, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec, - }, - { - .procname = "dump_kernel", - .maxlen = 256, - .mode = 0200, - .proc_handler = &proc_dump_kernel, - }, - { - .procname = "daemon_file", - .mode = 0644, - .maxlen = 256, - .proc_handler = &proc_daemon_file, - }, - { - .procname = "debug_mb", - .mode = 0644, - .proc_handler = &proc_debug_mb, - }, - { - .procname = "watchdog_ratelimit", - .data = &libcfs_watchdog_ratelimit, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec_minmax, - .extra1 = &min_watchdog_ratelimit, - .extra2 = &max_watchdog_ratelimit, - }, - { - .procname = "force_lbug", - .data = NULL, - .maxlen = 0, - .mode = 0200, - .proc_handler = &libcfs_force_lbug - }, - { - .procname = "fail_loc", - .data = &cfs_fail_loc, - .maxlen = sizeof(cfs_fail_loc), - .mode = 0644, - .proc_handler = &proc_fail_loc - }, - { - .procname = "fail_val", - .data = &cfs_fail_val, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec - }, - { - } -}; - -static struct ctl_table top_table[] = { - { - .procname = "lnet", - .mode = 0555, - .data = NULL, - .maxlen = 0, - .child = lnet_table, - }, - { - } -}; - -int insert_proc(void) -{ - if (lnet_table_header == NULL) - lnet_table_header = register_sysctl_table(top_table); - return 0; -} - -void remove_proc(void) -{ - if (lnet_table_header != NULL) - unregister_sysctl_table(lnet_table_header); - - lnet_table_header = NULL; -} diff --git a/drivers/staging/lustre/lustre/libcfs/module.c b/drivers/staging/lustre/lustre/libcfs/module.c index e35f5981cb43..f0ee76abfd5a 100644 --- a/drivers/staging/lustre/lustre/libcfs/module.c +++ b/drivers/staging/lustre/lustre/libcfs/module.c @@ -33,15 +33,82 @@ * This file is part of Lustre, http://www.lustre.org/ * Lustre is a trademark of Sun Microsystems, Inc. */ +#include +#include +#include +#include +#include +#include +#include +#include +#include -#define DEBUG_SUBSYSTEM S_LNET +#include + +#include +#include +#include + +#include +#include + +# define DEBUG_SUBSYSTEM S_LNET #include "../../include/linux/libcfs/libcfs.h" +#include + #include "../../include/linux/libcfs/libcfs_crypto.h" #include "../../include/linux/lnet/lib-lnet.h" #include "../../include/linux/lnet/lnet.h" #include "tracefile.h" +MODULE_AUTHOR("Peter J. Braam "); +MODULE_DESCRIPTION("Portals v3.1"); +MODULE_LICENSE("GPL"); + +extern struct miscdevice libcfs_dev; +extern struct rw_semaphore cfs_tracefile_sem; +extern struct mutex cfs_trace_thread_mutex; +extern struct cfs_wi_sched *cfs_sched_rehash; +extern void libcfs_init_nidstrings(void); + +static int insert_proc(void); +static void remove_proc(void); + +static struct ctl_table_header *lnet_table_header; +extern char lnet_upcall[1024]; +/** + * The path of debug log dump upcall script. + */ +extern char lnet_debug_log_upcall[1024]; + +#define CTL_LNET (0x100) + +enum { + PSDEV_DEBUG = 1, /* control debugging */ + PSDEV_SUBSYSTEM_DEBUG, /* control debugging */ + PSDEV_PRINTK, /* force all messages to console */ + PSDEV_CONSOLE_RATELIMIT, /* ratelimit console messages */ + PSDEV_CONSOLE_MAX_DELAY_CS, /* maximum delay over which we skip messages */ + PSDEV_CONSOLE_MIN_DELAY_CS, /* initial delay over which we skip messages */ + PSDEV_CONSOLE_BACKOFF, /* delay increase factor */ + PSDEV_DEBUG_PATH, /* crashdump log location */ + PSDEV_DEBUG_DUMP_PATH, /* crashdump tracelog location */ + PSDEV_CPT_TABLE, /* information about cpu partitions */ + PSDEV_LNET_UPCALL, /* User mode upcall script */ + PSDEV_LNET_MEMUSED, /* bytes currently PORTAL_ALLOCated */ + PSDEV_LNET_CATASTROPHE, /* if we have LBUGged or panic'd */ + PSDEV_LNET_PANIC_ON_LBUG, /* flag to panic on LBUG */ + PSDEV_LNET_DUMP_KERNEL, /* snapshot kernel debug buffer to file */ + PSDEV_LNET_DAEMON_FILE, /* spool kernel debug buffer to file */ + PSDEV_LNET_DEBUG_MB, /* size of debug buffer */ + PSDEV_LNET_DEBUG_LOG_UPCALL, /* debug log upcall script */ + PSDEV_LNET_WATCHDOG_RATELIMIT, /* ratelimit watchdog messages */ + PSDEV_LNET_FORCE_LBUG, /* hook to force an LBUG */ + PSDEV_LNET_FAIL_LOC, /* control test failures instrumentation */ + PSDEV_LNET_FAIL_VAL, /* userdata for fail loc */ +}; + static void kportal_memhog_free (struct libcfs_device_userstate *ldu) { struct page **level0p = &ldu->ldu_memhog_root_page; @@ -320,19 +387,6 @@ struct cfs_psdev_ops libcfs_psdev_ops = { libcfs_ioctl }; -extern int insert_proc(void); -extern void remove_proc(void); -MODULE_AUTHOR("Peter J. Braam "); -MODULE_DESCRIPTION("Portals v3.1"); -MODULE_LICENSE("GPL"); - -extern struct miscdevice libcfs_dev; -extern struct rw_semaphore cfs_tracefile_sem; -extern struct mutex cfs_trace_thread_mutex; -extern struct cfs_wi_sched *cfs_sched_rehash; - -extern void libcfs_init_nidstrings(void); - static int init_libcfs_module(void) { int rc; @@ -438,6 +492,485 @@ static void exit_libcfs_module(void) libcfs_arch_cleanup(); } +static int proc_call_handler(void *data, int write, loff_t *ppos, + void __user *buffer, size_t *lenp, + int (*handler)(void *data, int write, + loff_t pos, void __user *buffer, int len)) +{ + int rc = handler(data, write, *ppos, buffer, *lenp); + + if (rc < 0) + return rc; + + if (write) { + *ppos += *lenp; + } else { + *lenp = rc; + *ppos += rc; + } + return 0; +} + +static int __proc_dobitmasks(void *data, int write, + loff_t pos, void __user *buffer, int nob) +{ + const int tmpstrlen = 512; + char *tmpstr; + int rc; + unsigned int *mask = data; + int is_subsys = (mask == &libcfs_subsystem_debug) ? 1 : 0; + int is_printk = (mask == &libcfs_printk) ? 1 : 0; + + rc = cfs_trace_allocate_string_buffer(&tmpstr, tmpstrlen); + if (rc < 0) + return rc; + + if (!write) { + libcfs_debug_mask2str(tmpstr, tmpstrlen, *mask, is_subsys); + rc = strlen(tmpstr); + + if (pos >= rc) { + rc = 0; + } else { + rc = cfs_trace_copyout_string(buffer, nob, + tmpstr + pos, "\n"); + } + } else { + rc = cfs_trace_copyin_string(tmpstr, tmpstrlen, buffer, nob); + if (rc < 0) { + cfs_trace_free_string_buffer(tmpstr, tmpstrlen); + return rc; + } + + rc = libcfs_debug_str2mask(mask, tmpstr, is_subsys); + /* Always print LBUG/LASSERT to console, so keep this mask */ + if (is_printk) + *mask |= D_EMERG; + } + + cfs_trace_free_string_buffer(tmpstr, tmpstrlen); + return rc; +} + +static int proc_dobitmasks(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) +{ + return proc_call_handler(table->data, write, ppos, buffer, lenp, + __proc_dobitmasks); +} + +static int min_watchdog_ratelimit; /* disable ratelimiting */ +static int max_watchdog_ratelimit = (24*60*60); /* limit to once per day */ + +static int __proc_dump_kernel(void *data, int write, + loff_t pos, void __user *buffer, int nob) +{ + if (!write) + return 0; + + return cfs_trace_dump_debug_buffer_usrstr(buffer, nob); +} + +static int proc_dump_kernel(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) +{ + return proc_call_handler(table->data, write, ppos, buffer, lenp, + __proc_dump_kernel); +} + +static int __proc_daemon_file(void *data, int write, + loff_t pos, void __user *buffer, int nob) +{ + if (!write) { + int len = strlen(cfs_tracefile); + + if (pos >= len) + return 0; + + return cfs_trace_copyout_string(buffer, nob, + cfs_tracefile + pos, "\n"); + } + + return cfs_trace_daemon_command_usrstr(buffer, nob); +} + +static int proc_daemon_file(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) +{ + return proc_call_handler(table->data, write, ppos, buffer, lenp, + __proc_daemon_file); +} + +static int __proc_debug_mb(void *data, int write, + loff_t pos, void __user *buffer, int nob) +{ + if (!write) { + char tmpstr[32]; + int len = snprintf(tmpstr, sizeof(tmpstr), "%d", + cfs_trace_get_debug_mb()); + + if (pos >= len) + return 0; + + return cfs_trace_copyout_string(buffer, nob, tmpstr + pos, + "\n"); + } + + return cfs_trace_set_debug_mb_usrstr(buffer, nob); +} + +static int proc_debug_mb(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) +{ + return proc_call_handler(table->data, write, ppos, buffer, lenp, + __proc_debug_mb); +} + +static int proc_console_max_delay_cs(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, + loff_t *ppos) +{ + int rc, max_delay_cs; + struct ctl_table dummy = *table; + long d; + + dummy.data = &max_delay_cs; + dummy.proc_handler = &proc_dointvec; + + if (!write) { /* read */ + max_delay_cs = cfs_duration_sec(libcfs_console_max_delay * 100); + rc = proc_dointvec(&dummy, write, buffer, lenp, ppos); + return rc; + } + + /* write */ + max_delay_cs = 0; + rc = proc_dointvec(&dummy, write, buffer, lenp, ppos); + if (rc < 0) + return rc; + if (max_delay_cs <= 0) + return -EINVAL; + + d = cfs_time_seconds(max_delay_cs) / 100; + if (d == 0 || d < libcfs_console_min_delay) + return -EINVAL; + libcfs_console_max_delay = d; + + return rc; +} + +static int proc_console_min_delay_cs(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, + loff_t *ppos) +{ + int rc, min_delay_cs; + struct ctl_table dummy = *table; + long d; + + dummy.data = &min_delay_cs; + dummy.proc_handler = &proc_dointvec; + + if (!write) { /* read */ + min_delay_cs = cfs_duration_sec(libcfs_console_min_delay * 100); + rc = proc_dointvec(&dummy, write, buffer, lenp, ppos); + return rc; + } + + /* write */ + min_delay_cs = 0; + rc = proc_dointvec(&dummy, write, buffer, lenp, ppos); + if (rc < 0) + return rc; + if (min_delay_cs <= 0) + return -EINVAL; + + d = cfs_time_seconds(min_delay_cs) / 100; + if (d == 0 || d > libcfs_console_max_delay) + return -EINVAL; + libcfs_console_min_delay = d; + + return rc; +} + +static int proc_console_backoff(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) +{ + int rc, backoff; + struct ctl_table dummy = *table; + + dummy.data = &backoff; + dummy.proc_handler = &proc_dointvec; + + if (!write) { /* read */ + backoff = libcfs_console_backoff; + rc = proc_dointvec(&dummy, write, buffer, lenp, ppos); + return rc; + } + + /* write */ + backoff = 0; + rc = proc_dointvec(&dummy, write, buffer, lenp, ppos); + if (rc < 0) + return rc; + if (backoff <= 0) + return -EINVAL; + + libcfs_console_backoff = backoff; + + return rc; +} + +static int libcfs_force_lbug(struct ctl_table *table, int write, + void __user *buffer, + size_t *lenp, loff_t *ppos) +{ + if (write) + LBUG(); + return 0; +} + +static int proc_fail_loc(struct ctl_table *table, int write, + void __user *buffer, + size_t *lenp, loff_t *ppos) +{ + int rc; + long old_fail_loc = cfs_fail_loc; + + rc = proc_doulongvec_minmax(table, write, buffer, lenp, ppos); + if (old_fail_loc != cfs_fail_loc) + wake_up(&cfs_race_waitq); + return rc; +} + +static int __proc_cpt_table(void *data, int write, + loff_t pos, void __user *buffer, int nob) +{ + char *buf = NULL; + int len = 4096; + int rc = 0; + + if (write) + return -EPERM; + + LASSERT(cfs_cpt_table != NULL); + + while (1) { + LIBCFS_ALLOC(buf, len); + if (buf == NULL) + return -ENOMEM; + + rc = cfs_cpt_table_print(cfs_cpt_table, buf, len); + if (rc >= 0) + break; + + if (rc == -EFBIG) { + LIBCFS_FREE(buf, len); + len <<= 1; + continue; + } + goto out; + } + + if (pos >= rc) { + rc = 0; + goto out; + } + + rc = cfs_trace_copyout_string(buffer, nob, buf + pos, NULL); + out: + if (buf != NULL) + LIBCFS_FREE(buf, len); + return rc; +} + +static int proc_cpt_table(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) +{ + return proc_call_handler(table->data, write, ppos, buffer, lenp, + __proc_cpt_table); +} + +static struct ctl_table lnet_table[] = { + /* + * NB No .strategy entries have been provided since sysctl(8) prefers + * to go via /proc for portability. + */ + { + .procname = "debug", + .data = &libcfs_debug, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dobitmasks, + }, + { + .procname = "subsystem_debug", + .data = &libcfs_subsystem_debug, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dobitmasks, + }, + { + .procname = "printk", + .data = &libcfs_printk, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dobitmasks, + }, + { + .procname = "console_ratelimit", + .data = &libcfs_console_ratelimit, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + .procname = "console_max_delay_centisecs", + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_console_max_delay_cs + }, + { + .procname = "console_min_delay_centisecs", + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_console_min_delay_cs + }, + { + .procname = "console_backoff", + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_console_backoff + }, + + { + .procname = "debug_path", + .data = libcfs_debug_file_path_arr, + .maxlen = sizeof(libcfs_debug_file_path_arr), + .mode = 0644, + .proc_handler = &proc_dostring, + }, + + { + .procname = "cpu_partition_table", + .maxlen = 128, + .mode = 0444, + .proc_handler = &proc_cpt_table, + }, + + { + .procname = "upcall", + .data = lnet_upcall, + .maxlen = sizeof(lnet_upcall), + .mode = 0644, + .proc_handler = &proc_dostring, + }, + { + .procname = "debug_log_upcall", + .data = lnet_debug_log_upcall, + .maxlen = sizeof(lnet_debug_log_upcall), + .mode = 0644, + .proc_handler = &proc_dostring, + }, + { + .procname = "lnet_memused", + .data = (int *)&libcfs_kmemory.counter, + .maxlen = sizeof(int), + .mode = 0444, + .proc_handler = &proc_dointvec, + }, + { + .procname = "catastrophe", + .data = &libcfs_catastrophe, + .maxlen = sizeof(int), + .mode = 0444, + .proc_handler = &proc_dointvec, + }, + { + .procname = "panic_on_lbug", + .data = &libcfs_panic_on_lbug, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, + { + .procname = "dump_kernel", + .maxlen = 256, + .mode = 0200, + .proc_handler = &proc_dump_kernel, + }, + { + .procname = "daemon_file", + .mode = 0644, + .maxlen = 256, + .proc_handler = &proc_daemon_file, + }, + { + .procname = "debug_mb", + .mode = 0644, + .proc_handler = &proc_debug_mb, + }, + { + .procname = "watchdog_ratelimit", + .data = &libcfs_watchdog_ratelimit, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_minmax, + .extra1 = &min_watchdog_ratelimit, + .extra2 = &max_watchdog_ratelimit, + }, + { + .procname = "force_lbug", + .data = NULL, + .maxlen = 0, + .mode = 0200, + .proc_handler = &libcfs_force_lbug + }, + { + .procname = "fail_loc", + .data = &cfs_fail_loc, + .maxlen = sizeof(cfs_fail_loc), + .mode = 0644, + .proc_handler = &proc_fail_loc + }, + { + .procname = "fail_val", + .data = &cfs_fail_val, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { + } +}; + +static struct ctl_table top_table[] = { + { + .procname = "lnet", + .mode = 0555, + .data = NULL, + .maxlen = 0, + .child = lnet_table, + }, + { + } +}; + +static int insert_proc(void) +{ + if (lnet_table_header == NULL) + lnet_table_header = register_sysctl_table(top_table); + return 0; +} + +static void remove_proc(void) +{ + if (lnet_table_header != NULL) + unregister_sysctl_table(lnet_table_header); + + lnet_table_header = NULL; +} + MODULE_VERSION("1.0.0"); + module_init(init_libcfs_module); module_exit(exit_libcfs_module); -- GitLab From 9b5c9f043e7a70665b2eb092f316d5d5cd238d49 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 10 Feb 2015 19:06:06 +0200 Subject: [PATCH 03163/11651] i2c: designware-baytrail: describe magic numbers The patch converts hardcoded numerical constants to a named ones. While here, align the variable name in get_sem() and reset_semaphore(). Signed-off-by: Andy Shevchenko Acked-by: David E. Box Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-designware-baytrail.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/i2c/busses/i2c-designware-baytrail.c b/drivers/i2c/busses/i2c-designware-baytrail.c index 5f1ff4cc5c34..e9cb3555dc79 100644 --- a/drivers/i2c/busses/i2c-designware-baytrail.c +++ b/drivers/i2c/busses/i2c-designware-baytrail.c @@ -22,22 +22,24 @@ #define SEMAPHORE_TIMEOUT 100 #define PUNIT_SEMAPHORE 0x7 +#define PUNIT_SEMAPHORE_BIT BIT(0) +#define PUNIT_SEMAPHORE_ACQUIRE BIT(1) static unsigned long acquired; static int get_sem(struct device *dev, u32 *sem) { - u32 reg_val; + u32 data; int ret; ret = iosf_mbi_read(BT_MBI_UNIT_PMC, BT_MBI_BUNIT_READ, PUNIT_SEMAPHORE, - ®_val); + &data); if (ret) { dev_err(dev, "iosf failed to read punit semaphore\n"); return ret; } - *sem = reg_val & 0x1; + *sem = data & PUNIT_SEMAPHORE_BIT; return 0; } @@ -52,9 +54,9 @@ static void reset_semaphore(struct device *dev) return; } - data = data & 0xfffffffe; + data &= ~PUNIT_SEMAPHORE_BIT; if (iosf_mbi_write(BT_MBI_UNIT_PMC, BT_MBI_BUNIT_WRITE, - PUNIT_SEMAPHORE, data)) + PUNIT_SEMAPHORE, data)) dev_err(dev, "iosf failed to reset punit semaphore during write\n"); } @@ -70,9 +72,9 @@ int baytrail_i2c_acquire(struct dw_i2c_dev *dev) if (!dev->acquire_lock) return 0; - /* host driver writes 0x2 to side band semaphore register */ + /* host driver writes to side band semaphore register */ ret = iosf_mbi_write(BT_MBI_UNIT_PMC, BT_MBI_BUNIT_WRITE, - PUNIT_SEMAPHORE, 0x2); + PUNIT_SEMAPHORE, PUNIT_SEMAPHORE_ACQUIRE); if (ret) { dev_err(dev->dev, "iosf punit semaphore request failed\n"); return ret; -- GitLab From 259aada436e13ec75a8b0f252a78e6577879008e Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 10 Feb 2015 19:06:07 +0200 Subject: [PATCH 03164/11651] i2c: designware-baytrail: fix typo in error path It seems we have same message for different return values in get_sem() and baytrail_i2c_acquire(). I suspect this is just a typo, so this patch fixes it. Signed-off-by: Andy Shevchenko Acked-by: David E. Box Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-designware-baytrail.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/busses/i2c-designware-baytrail.c b/drivers/i2c/busses/i2c-designware-baytrail.c index e9cb3555dc79..9b6765554c70 100644 --- a/drivers/i2c/busses/i2c-designware-baytrail.c +++ b/drivers/i2c/busses/i2c-designware-baytrail.c @@ -99,8 +99,8 @@ int baytrail_i2c_acquire(struct dw_i2c_dev *dev) reset_semaphore(dev->dev); ret = iosf_mbi_read(BT_MBI_UNIT_PMC, BT_MBI_BUNIT_READ, - PUNIT_SEMAPHORE, &sem); - if (!ret) + PUNIT_SEMAPHORE, &sem); + if (ret) dev_err(dev->dev, "iosf failed to read punit semaphore\n"); else dev_err(dev->dev, "PUNIT SEM: %d\n", sem); -- GitLab From c8e043e6f717b0256b1cfc55d03c232e8a5c8cbd Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 10 Feb 2015 19:06:08 +0200 Subject: [PATCH 03165/11651] i2c: designware-baytrail: fix sparse warnings There is no need to export functions that are used as the callbacks in the struct dw_i2c_dev. Otherwise we get the following warnings: drivers/i2c/busses/i2c-designware-baytrail.c:63:5: warning: symbol 'baytrail_i2c_acquire' was not declared. Should it be static? drivers/i2c/busses/i2c-designware-baytrail.c:114:6: warning: symbol 'baytrail_i2c_release' was not declared. Should it be static? While here, do few indentation fixes, remove i2c_dw_eval_lock_support() from functions exported to the modules and redundant assignment of local sem variable. Signed-off-by: Andy Shevchenko Acked-by: David E. Box Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-designware-baytrail.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/i2c/busses/i2c-designware-baytrail.c b/drivers/i2c/busses/i2c-designware-baytrail.c index 9b6765554c70..d33474422003 100644 --- a/drivers/i2c/busses/i2c-designware-baytrail.c +++ b/drivers/i2c/busses/i2c-designware-baytrail.c @@ -17,7 +17,9 @@ #include #include #include + #include + #include "i2c-designware-core.h" #define SEMAPHORE_TIMEOUT 100 @@ -60,9 +62,9 @@ static void reset_semaphore(struct device *dev) dev_err(dev, "iosf failed to reset punit semaphore during write\n"); } -int baytrail_i2c_acquire(struct dw_i2c_dev *dev) +static int baytrail_i2c_acquire(struct dw_i2c_dev *dev) { - u32 sem = 0; + u32 sem; int ret; unsigned long start, end; @@ -109,9 +111,8 @@ int baytrail_i2c_acquire(struct dw_i2c_dev *dev) return -ETIMEDOUT; } -EXPORT_SYMBOL(baytrail_i2c_acquire); -void baytrail_i2c_release(struct dw_i2c_dev *dev) +static void baytrail_i2c_release(struct dw_i2c_dev *dev) { if (!dev || !dev->dev) return; @@ -123,7 +124,6 @@ void baytrail_i2c_release(struct dw_i2c_dev *dev) dev_dbg(dev->dev, "punit semaphore held for %ums\n", jiffies_to_msecs(jiffies - acquired)); } -EXPORT_SYMBOL(baytrail_i2c_release); int i2c_dw_eval_lock_support(struct dw_i2c_dev *dev) { @@ -139,7 +139,6 @@ int i2c_dw_eval_lock_support(struct dw_i2c_dev *dev) return 0; status = acpi_evaluate_integer(handle, "_SEM", NULL, &shared_host); - if (ACPI_FAILURE(status)) return 0; @@ -155,7 +154,6 @@ int i2c_dw_eval_lock_support(struct dw_i2c_dev *dev) return 0; } -EXPORT_SYMBOL(i2c_dw_eval_lock_support); MODULE_AUTHOR("David E. Box "); MODULE_DESCRIPTION("Baytrail I2C Semaphore driver"); -- GitLab From 30be774b38d845791b1acbd750f19e56c57f0185 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 10 Feb 2015 19:06:09 +0200 Subject: [PATCH 03166/11651] i2c: designware-baytrail: cross-check lock functions It seems the idea behind the cross-check is to prevent acquire semaphore when there is no release callback and vice versa. Thus, patch fixes a typo. Signed-off-by: Andy Shevchenko Acked-by: David E. Box Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-designware-baytrail.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-designware-baytrail.c b/drivers/i2c/busses/i2c-designware-baytrail.c index d33474422003..036d9bdc0aaa 100644 --- a/drivers/i2c/busses/i2c-designware-baytrail.c +++ b/drivers/i2c/busses/i2c-designware-baytrail.c @@ -71,7 +71,7 @@ static int baytrail_i2c_acquire(struct dw_i2c_dev *dev) if (!dev || !dev->dev) return -ENODEV; - if (!dev->acquire_lock) + if (!dev->release_lock) return 0; /* host driver writes to side band semaphore register */ -- GitLab From ebf2ef8f613433aaffac53aef2f6703445821fc6 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 10 Feb 2015 19:06:10 +0200 Subject: [PATCH 03167/11651] i2c: designware-baytrail: baytrail_i2c_acquire() might sleep This patch marks baytrail_i2c_acquire() that it might sleep. Also it chages while-loop to do-while and, though it is matter of taste, gives a chance to check one more time before report a timeout. Signed-off-by: Andy Shevchenko Acked-by: David E. Box Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-designware-baytrail.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/busses/i2c-designware-baytrail.c b/drivers/i2c/busses/i2c-designware-baytrail.c index 036d9bdc0aaa..7d7ae97476e2 100644 --- a/drivers/i2c/busses/i2c-designware-baytrail.c +++ b/drivers/i2c/busses/i2c-designware-baytrail.c @@ -68,6 +68,8 @@ static int baytrail_i2c_acquire(struct dw_i2c_dev *dev) int ret; unsigned long start, end; + might_sleep(); + if (!dev || !dev->dev) return -ENODEV; @@ -85,7 +87,7 @@ static int baytrail_i2c_acquire(struct dw_i2c_dev *dev) /* host driver waits for bit 0 to be set in semaphore register */ start = jiffies; end = start + msecs_to_jiffies(SEMAPHORE_TIMEOUT); - while (!time_after(jiffies, end)) { + do { ret = get_sem(dev->dev, &sem); if (!ret && sem) { acquired = jiffies; @@ -95,7 +97,7 @@ static int baytrail_i2c_acquire(struct dw_i2c_dev *dev) } usleep_range(1000, 2000); - } + } while (time_before(jiffies, end)); dev_err(dev->dev, "punit semaphore timed out, resetting\n"); reset_semaphore(dev->dev); -- GitLab From 834d86735d2b12c74d252addf20fc448bae8f813 Mon Sep 17 00:00:00 2001 From: Salah Triki Date: Sun, 1 Mar 2015 23:18:50 +0100 Subject: [PATCH 03168/11651] staging: dgnc: fix braces {} are not necessary for single statement blocks This patch fixes the following checkpatch.pl warning: braces {} are not necessary for single statement blocks Signed-off-by: Salah Triki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgnc/dgnc_tty.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/staging/dgnc/dgnc_tty.c b/drivers/staging/dgnc/dgnc_tty.c index f81a375f8bc1..817934269520 100644 --- a/drivers/staging/dgnc/dgnc_tty.c +++ b/drivers/staging/dgnc/dgnc_tty.c @@ -886,10 +886,6 @@ void dgnc_check_queue_flow_control(struct channel_t *ch) ch->ch_stops_sent++; } } - /* No FLOW */ - else { - /* Empty... Can't do anything about the impending overflow... */ - } } /* -- GitLab From 5f9dca1e7d5a5463f9e9cc4e1f5c8e9bc9d118a9 Mon Sep 17 00:00:00 2001 From: Salah Triki Date: Thu, 5 Mar 2015 03:50:24 +0100 Subject: [PATCH 03169/11651] Staging: dgnc: Fix checking return value of register_chrdev The failure code is negative. So check <0 instead of <=0. Return the failure code instead of -ENXIO. Signed-off-by: Salah Triki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgnc/dgnc_driver.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/dgnc/dgnc_driver.c b/drivers/staging/dgnc/dgnc_driver.c index c1d1a97e0c94..fa1ee79ef88e 100644 --- a/drivers/staging/dgnc/dgnc_driver.c +++ b/drivers/staging/dgnc/dgnc_driver.c @@ -251,9 +251,9 @@ static int dgnc_start(void) * Register management/dpa devices */ rc = register_chrdev(0, "dgnc", &dgnc_BoardFops); - if (rc <= 0) { + if (rc < 0) { pr_err(DRVSTR ": Can't register dgnc driver device (%d)\n", rc); - return -ENXIO; + return rc; } dgnc_Major = rc; -- GitLab From 5d232112f94b0f3920dc4fec09688ef6cb5c09df Mon Sep 17 00:00:00 2001 From: Matt Porter Date: Tue, 3 Mar 2015 11:57:08 -0500 Subject: [PATCH 03170/11651] i2c: imx: add required clocks property to binding A clock specifier is required for i.MX I2C and is provided in all DTS implementations. Add this to the list of required properties in the binding. Signed-off-by: Matt Porter Signed-off-by: Wolfram Sang --- Documentation/devicetree/bindings/i2c/i2c-imx.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/i2c/i2c-imx.txt b/Documentation/devicetree/bindings/i2c/i2c-imx.txt index 52d37fd8d3e5..ce4311d726ae 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-imx.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-imx.txt @@ -7,6 +7,7 @@ Required properties: - "fsl,vf610-i2c" for I2C compatible with the one integrated on Vybrid vf610 SoC - reg : Should contain I2C/HS-I2C registers location and length - interrupts : Should contain I2C/HS-I2C interrupt +- clocks : Should contain the I2C/HS-I2C clock specifier Optional properties: - clock-frequency : Constains desired I2C/HS-I2C bus clock frequency in Hz. -- GitLab From e03b7297f8e8968e98ff9eab57e0f92e106248ad Mon Sep 17 00:00:00 2001 From: Quentin Lambert Date: Tue, 10 Feb 2015 10:24:12 +0100 Subject: [PATCH 03171/11651] staging: ozwpan: Remove allocation from delaration line This patch removes allocation from declaration line because people are known to gloss over declarations. Signed-off-by: Quentin Lambert Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ozwpan/ozhcd.c | 5 +++-- drivers/staging/ozwpan/ozpd.c | 8 +++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/staging/ozwpan/ozhcd.c b/drivers/staging/ozwpan/ozhcd.c index 8543bb29a138..96e95bf8fd32 100644 --- a/drivers/staging/ozwpan/ozhcd.c +++ b/drivers/staging/ozwpan/ozhcd.c @@ -280,8 +280,9 @@ static void oz_free_urb_link(struct oz_urb_link *urbl) */ static struct oz_endpoint *oz_ep_alloc(int buffer_size, gfp_t mem_flags) { - struct oz_endpoint *ep = - kzalloc(sizeof(struct oz_endpoint)+buffer_size, mem_flags); + struct oz_endpoint *ep; + + ep = kzalloc(sizeof(struct oz_endpoint)+buffer_size, mem_flags); if (ep) { INIT_LIST_HEAD(&ep->urb_list); INIT_LIST_HEAD(&ep->link); diff --git a/drivers/staging/ozwpan/ozpd.c b/drivers/staging/ozwpan/ozpd.c index 852c288aaf13..1c95d5799217 100644 --- a/drivers/staging/ozwpan/ozpd.c +++ b/drivers/staging/ozwpan/ozpd.c @@ -102,8 +102,9 @@ void oz_pd_put(struct oz_pd *pd) */ struct oz_pd *oz_pd_alloc(const u8 *mac_addr) { - struct oz_pd *pd = kzalloc(sizeof(struct oz_pd), GFP_ATOMIC); + struct oz_pd *pd; + pd = kzalloc(sizeof(struct oz_pd), GFP_ATOMIC); if (pd) { int i; @@ -652,8 +653,9 @@ static struct oz_isoc_stream *pd_stream_find(struct oz_pd *pd, u8 ep_num) */ int oz_isoc_stream_create(struct oz_pd *pd, u8 ep_num) { - struct oz_isoc_stream *st = - kzalloc(sizeof(struct oz_isoc_stream), GFP_ATOMIC); + struct oz_isoc_stream *st; + + st = kzalloc(sizeof(struct oz_isoc_stream), GFP_ATOMIC); if (!st) return -ENOMEM; st->ep_num = ep_num; -- GitLab From 6498613d2cf23269a6a483a751f61655115de251 Mon Sep 17 00:00:00 2001 From: Quentin Lambert Date: Tue, 10 Feb 2015 11:42:08 +0100 Subject: [PATCH 03172/11651] staging: ozwpan: Move code from success handling to error handling The original version was success handling rather than error handling, therefore this patch reduces nesting. Signed-off-by: Quentin Lambert Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ozwpan/ozhcd.c | 18 +++++++----- drivers/staging/ozwpan/ozpd.c | 53 +++++++++++++++++----------------- 2 files changed, 37 insertions(+), 34 deletions(-) diff --git a/drivers/staging/ozwpan/ozhcd.c b/drivers/staging/ozwpan/ozhcd.c index 96e95bf8fd32..5ff4716b72c3 100644 --- a/drivers/staging/ozwpan/ozhcd.c +++ b/drivers/staging/ozwpan/ozhcd.c @@ -283,15 +283,17 @@ static struct oz_endpoint *oz_ep_alloc(int buffer_size, gfp_t mem_flags) struct oz_endpoint *ep; ep = kzalloc(sizeof(struct oz_endpoint)+buffer_size, mem_flags); - if (ep) { - INIT_LIST_HEAD(&ep->urb_list); - INIT_LIST_HEAD(&ep->link); - ep->credit = -1; - if (buffer_size) { - ep->buffer_size = buffer_size; - ep->buffer = (u8 *)(ep+1); - } + if (!ep) + return NULL; + + INIT_LIST_HEAD(&ep->urb_list); + INIT_LIST_HEAD(&ep->link); + ep->credit = -1; + if (buffer_size) { + ep->buffer_size = buffer_size; + ep->buffer = (u8 *)(ep+1); } + return ep; } diff --git a/drivers/staging/ozwpan/ozpd.c b/drivers/staging/ozwpan/ozpd.c index 1c95d5799217..021d74a132dd 100644 --- a/drivers/staging/ozwpan/ozpd.c +++ b/drivers/staging/ozwpan/ozpd.c @@ -103,34 +103,35 @@ void oz_pd_put(struct oz_pd *pd) struct oz_pd *oz_pd_alloc(const u8 *mac_addr) { struct oz_pd *pd; + int i; pd = kzalloc(sizeof(struct oz_pd), GFP_ATOMIC); - if (pd) { - int i; - - atomic_set(&pd->ref_count, 2); - for (i = 0; i < OZ_NB_APPS; i++) - spin_lock_init(&pd->app_lock[i]); - pd->last_rx_pkt_num = 0xffffffff; - oz_pd_set_state(pd, OZ_PD_S_IDLE); - pd->max_tx_size = OZ_MAX_TX_SIZE; - ether_addr_copy(pd->mac_addr, mac_addr); - oz_elt_buf_init(&pd->elt_buff); - spin_lock_init(&pd->tx_frame_lock); - INIT_LIST_HEAD(&pd->tx_queue); - INIT_LIST_HEAD(&pd->farewell_list); - pd->last_sent_frame = &pd->tx_queue; - spin_lock_init(&pd->stream_lock); - INIT_LIST_HEAD(&pd->stream_list); - tasklet_init(&pd->heartbeat_tasklet, oz_pd_heartbeat_handler, - (unsigned long)pd); - tasklet_init(&pd->timeout_tasklet, oz_pd_timeout_handler, - (unsigned long)pd); - hrtimer_init(&pd->heartbeat, CLOCK_MONOTONIC, HRTIMER_MODE_REL); - hrtimer_init(&pd->timeout, CLOCK_MONOTONIC, HRTIMER_MODE_REL); - pd->heartbeat.function = oz_pd_heartbeat_event; - pd->timeout.function = oz_pd_timeout_event; - } + if (!pd) + return NULL; + + atomic_set(&pd->ref_count, 2); + for (i = 0; i < OZ_NB_APPS; i++) + spin_lock_init(&pd->app_lock[i]); + pd->last_rx_pkt_num = 0xffffffff; + oz_pd_set_state(pd, OZ_PD_S_IDLE); + pd->max_tx_size = OZ_MAX_TX_SIZE; + ether_addr_copy(pd->mac_addr, mac_addr); + oz_elt_buf_init(&pd->elt_buff); + spin_lock_init(&pd->tx_frame_lock); + INIT_LIST_HEAD(&pd->tx_queue); + INIT_LIST_HEAD(&pd->farewell_list); + pd->last_sent_frame = &pd->tx_queue; + spin_lock_init(&pd->stream_lock); + INIT_LIST_HEAD(&pd->stream_list); + tasklet_init(&pd->heartbeat_tasklet, oz_pd_heartbeat_handler, + (unsigned long)pd); + tasklet_init(&pd->timeout_tasklet, oz_pd_timeout_handler, + (unsigned long)pd); + hrtimer_init(&pd->heartbeat, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + hrtimer_init(&pd->timeout, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + pd->heartbeat.function = oz_pd_heartbeat_event; + pd->timeout.function = oz_pd_timeout_event; + return pd; } -- GitLab From d34add05946ffda90ad5c4f0f71af2819748c660 Mon Sep 17 00:00:00 2001 From: Christian Engelmayer Date: Wed, 11 Feb 2015 20:33:15 +0100 Subject: [PATCH 03173/11651] staging: vt6656: Fix possible leak in vnt_download_firmware() When failing to allocate buffer memory, function vnt_download_firmware() goes through the wrong exit path and fails to release the already requested firmware. Thus use the correct cleanup. Detected by Coverity CID 1269128. Signed-off-by: Christian Engelmayer Reviewed-by: Martin Kepplinger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/firmware.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/vt6656/firmware.c b/drivers/staging/vt6656/firmware.c index a177645af83e..d440f284bf18 100644 --- a/drivers/staging/vt6656/firmware.c +++ b/drivers/staging/vt6656/firmware.c @@ -61,7 +61,7 @@ int vnt_download_firmware(struct vnt_private *priv) buffer = kmalloc(FIRMWARE_CHUNK_SIZE, GFP_KERNEL); if (!buffer) - goto out; + goto free_fw; for (ii = 0; ii < fw->size; ii += FIRMWARE_CHUNK_SIZE) { length = min_t(int, fw->size - ii, FIRMWARE_CHUNK_SIZE); -- GitLab From 636cd168064937408114cb6cd9d2fa5095ac827c Mon Sep 17 00:00:00 2001 From: Ivan Stankovic Date: Thu, 12 Feb 2015 22:08:26 +0100 Subject: [PATCH 03174/11651] staging: vt6655: fix coding style issues in channel.c Observe the line length limit to make checkpatch.pl happy. Signed-off-by: Ivan Stankovic Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/channel.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/staging/vt6655/channel.c b/drivers/staging/vt6655/channel.c index 3c17725d5910..7a717828fa09 100644 --- a/drivers/staging/vt6655/channel.c +++ b/drivers/staging/vt6655/channel.c @@ -193,7 +193,8 @@ bool set_channel(void *pDeviceHandler, struct ieee80211_channel *ch) /* clear NAV */ MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MACCR, MACCR_CLRNAV); - /* TX_PE will reserve 3 us for MAX2829 A mode only, it is for better TX throughput */ + /* TX_PE will reserve 3 us for MAX2829 A mode only, + it is for better TX throughput */ if (pDevice->byRFType == RF_AIROHA7230) RFbAL7230SelectChannelPostProcess(pDevice, pDevice->byCurrentCh, @@ -217,9 +218,11 @@ bool set_channel(void *pDeviceHandler, struct ieee80211_channel *ch) /* set HW default power register */ MACvSelectPage1(pDevice->PortOffset); RFbSetPower(pDevice, RATE_1M, pDevice->byCurrentCh); - VNSvOutPortB(pDevice->PortOffset + MAC_REG_PWRCCK, pDevice->byCurPwr); + VNSvOutPortB(pDevice->PortOffset + MAC_REG_PWRCCK, + pDevice->byCurPwr); RFbSetPower(pDevice, RATE_6M, pDevice->byCurrentCh); - VNSvOutPortB(pDevice->PortOffset + MAC_REG_PWROFDM, pDevice->byCurPwr); + VNSvOutPortB(pDevice->PortOffset + MAC_REG_PWROFDM, + pDevice->byCurPwr); MACvSelectPage0(pDevice->PortOffset); spin_unlock_irqrestore(&pDevice->lock, flags); -- GitLab From 7e59b047ccb64c57e5a372ca1877b5ad979fdfdb Mon Sep 17 00:00:00 2001 From: Matt Date: Sat, 21 Feb 2015 10:40:02 +0100 Subject: [PATCH 03175/11651] Staging: vt6655 fix C99 style comments Signed-off-by: Matteo Semenzato Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/tmacro.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/vt6655/tmacro.h b/drivers/staging/vt6655/tmacro.h index 607b78f7a6a0..597efefc017f 100644 --- a/drivers/staging/vt6655/tmacro.h +++ b/drivers/staging/vt6655/tmacro.h @@ -55,4 +55,4 @@ #define MAKEDWORD(lw, hw) ((unsigned long)(((unsigned short)(lw)) | (((unsigned long)((unsigned short)(hw))) << 16))) #endif -#endif // __TMACRO_H__ +#endif /* __TMACRO_H__ */ -- GitLab From bb72dd53d7e5b8a13f5a2bbc1a3f0111fdc6450d Mon Sep 17 00:00:00 2001 From: Alex W Slater Date: Thu, 26 Feb 2015 20:09:26 +0000 Subject: [PATCH 03176/11651] staging: vt6655: Cleanup C99 comments Fix checkpatch.pl errors: "ERROR: do not use C99 // comments" Signed-off-by: Alex W Slater Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device_main.c | 36 +++++++++++++++------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 4324282afe49..0204ea520385 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -64,9 +64,9 @@ #include /*--------------------- Static Definitions -------------------------*/ -// -// Define module options -// +/* + * Define module options + */ MODULE_AUTHOR("VIA Networking Technologies, Inc., "); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("VIA Networking Solomon-A/B/G Wireless LAN Adapter Driver"); @@ -126,9 +126,9 @@ DEVICE_PARAM(LongRetryLimit, "long frame retry limits"); DEVICE_PARAM(BasebandType, "baseband type"); -// -// Static vars definitions -// +/* + * Static vars definitions + */ static CHIP_INFO chip_info_table[] = { { VT3253, "VIA Networking Solomon-A/B/G Wireless LAN Adapter ", 256, 1, DEVICE_FLAGS_IP_ALIGN|DEVICE_FLAGS_TX_ALIGN }, @@ -231,9 +231,9 @@ device_set_options(struct vnt_private *pDevice) pr_debug(" byBBType= %d\n", (int)pDevice->byBBType); } -// -// Initialisation of MAC & BBP registers -// +/* + * Initialisation of MAC & BBP registers + */ static void device_init_registers(struct vnt_private *pDevice) { @@ -584,7 +584,7 @@ static bool device_init_rings(struct vnt_private *pDevice) pDevice->td1_pool_dma = pDevice->td0_pool_dma + pDevice->sOpts.nTxDescs[0] * sizeof(STxDesc); - // vir_pool: pvoid type + /* vir_pool: pvoid type */ pDevice->apTD0Rings = vir_pool + pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc) + pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc); @@ -943,7 +943,7 @@ static int device_tx_srv(struct vnt_private *pDevice, unsigned int uIdx) byTsr0 = pTD->m_td0TD0.byTSR0; byTsr1 = pTD->m_td0TD0.byTSR1; - //Only the status of first TD in the chain is correct + /* Only the status of first TD in the chain is correct */ if (pTD->m_td1TD1.byTCR & TCR_STP) { if ((pTD->pTDInfo->byFlags & TD_FLAGS_NETIF_SKB) != 0) { @@ -992,7 +992,7 @@ static void device_free_tx_buf(struct vnt_private *pDevice, PSTxDesc pDesc) PDEVICE_TD_INFO pTDInfo = pDesc->pTDInfo; struct sk_buff *skb = pTDInfo->skb; - // pre-allocated buf_dma can't be unmapped. + /* pre-allocated buf_dma can't be unmapped. */ if (pTDInfo->skb_dma && (pTDInfo->skb_dma != pTDInfo->buf_dma)) { pci_unmap_single(pDevice->pcid, pTDInfo->skb_dma, skb->len, PCI_DMA_TODEVICE); @@ -1084,7 +1084,7 @@ static irqreturn_t device_intr(int irq, void *dev_instance) spin_lock_irqsave(&pDevice->lock, flags); - //Make sure current page is 0 + /* Make sure current page is 0 */ VNSvInPortB(pDevice->PortOffset + MAC_REG_PAGE1SEL, &byOrgPageSel); if (byOrgPageSel == 1) MACvSelectPage0(pDevice->PortOffset); @@ -1092,10 +1092,12 @@ static irqreturn_t device_intr(int irq, void *dev_instance) byOrgPageSel = 0; MACvReadMIBCounter(pDevice->PortOffset, &dwMIBCounter); - // TBD.... - // Must do this after doing rx/tx, cause ISR bit is slow - // than RD/TD write back - // update ISR counter + /* + * TBD.... + * Must do this after doing rx/tx, cause ISR bit is slow + * than RD/TD write back + * update ISR counter + */ STAvUpdate802_11Counter(&pDevice->s802_11Counter, &pDevice->scStatistic, dwMIBCounter); while (pDevice->dwIsr != 0) { STAvUpdateIsrStatCounter(&pDevice->scStatistic, pDevice->dwIsr); -- GitLab From 9ab81fb7a968c81d16fa00584487d7f1e7211887 Mon Sep 17 00:00:00 2001 From: Matteo Semenzato Date: Sat, 28 Feb 2015 15:28:15 +0100 Subject: [PATCH 03177/11651] Staging: vt6655: fix C99 comments This patch fixes the following warning: do not use C99 // comments Signed-off-by: Matteo Semenzato Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/mac.c | 82 ++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/drivers/staging/vt6655/mac.c b/drivers/staging/vt6655/mac.c index 3653a2bd1e36..8048b3263360 100644 --- a/drivers/staging/vt6655/mac.c +++ b/drivers/staging/vt6655/mac.c @@ -141,7 +141,7 @@ bool MACbIsIntDisable(void __iomem *dwIoBase) */ void MACvSetShortRetryLimit(void __iomem *dwIoBase, unsigned char byRetryLimit) { - // set SRT + /* set SRT */ VNSvOutPortB(dwIoBase + MAC_REG_SRT, byRetryLimit); } @@ -162,7 +162,7 @@ void MACvSetShortRetryLimit(void __iomem *dwIoBase, unsigned char byRetryLimit) */ void MACvSetLongRetryLimit(void __iomem *dwIoBase, unsigned char byRetryLimit) { - // set LRT + /* set LRT */ VNSvOutPortB(dwIoBase + MAC_REG_LRT, byRetryLimit); } @@ -186,7 +186,7 @@ void MACvSetLoopbackMode(void __iomem *dwIoBase, unsigned char byLoopbackMode) ASSERT(byLoopbackMode < 3); byLoopbackMode <<= 6; - // set TCR + /* set TCR */ VNSvInPortB(dwIoBase + MAC_REG_TEST, &byOrgValue); byOrgValue = byOrgValue & 0x3F; byOrgValue = byOrgValue | byLoopbackMode; @@ -210,13 +210,13 @@ void MACvSaveContext(void __iomem *dwIoBase, unsigned char *pbyCxtBuf) { int ii; - // read page0 register + /* read page0 register */ for (ii = 0; ii < MAC_MAX_CONTEXT_SIZE_PAGE0; ii++) VNSvInPortB((dwIoBase + ii), (pbyCxtBuf + ii)); MACvSelectPage1(dwIoBase); - // read page1 register + /* read page1 register */ for (ii = 0; ii < MAC_MAX_CONTEXT_SIZE_PAGE1; ii++) VNSvInPortB((dwIoBase + ii), (pbyCxtBuf + MAC_MAX_CONTEXT_SIZE_PAGE0 + ii)); @@ -242,27 +242,27 @@ void MACvRestoreContext(void __iomem *dwIoBase, unsigned char *pbyCxtBuf) int ii; MACvSelectPage1(dwIoBase); - // restore page1 + /* restore page1 */ for (ii = 0; ii < MAC_MAX_CONTEXT_SIZE_PAGE1; ii++) VNSvOutPortB((dwIoBase + ii), *(pbyCxtBuf + MAC_MAX_CONTEXT_SIZE_PAGE0 + ii)); MACvSelectPage0(dwIoBase); - // restore RCR,TCR,IMR... + /* restore RCR,TCR,IMR... */ for (ii = MAC_REG_RCR; ii < MAC_REG_ISR; ii++) VNSvOutPortB(dwIoBase + ii, *(pbyCxtBuf + ii)); - // restore MAC Config. + /* restore MAC Config. */ for (ii = MAC_REG_LRT; ii < MAC_REG_PAGE1SEL; ii++) VNSvOutPortB(dwIoBase + ii, *(pbyCxtBuf + ii)); VNSvOutPortB(dwIoBase + MAC_REG_CFG, *(pbyCxtBuf + MAC_REG_CFG)); - // restore PS Config. + /* restore PS Config. */ for (ii = MAC_REG_PSCFG; ii < MAC_REG_BBREGCTL; ii++) VNSvOutPortB(dwIoBase + ii, *(pbyCxtBuf + ii)); - // restore CURR_RX_DESC_ADDR, CURR_TX_DESC_ADDR + /* restore CURR_RX_DESC_ADDR, CURR_TX_DESC_ADDR */ VNSvOutPortD(dwIoBase + MAC_REG_TXDMAPTR0, *(unsigned long *)(pbyCxtBuf + MAC_REG_TXDMAPTR0)); VNSvOutPortD(dwIoBase + MAC_REG_AC0DMAPTR, *(unsigned long *)(pbyCxtBuf + MAC_REG_AC0DMAPTR)); VNSvOutPortD(dwIoBase + MAC_REG_BCNDMAPTR, *(unsigned long *)(pbyCxtBuf + MAC_REG_BCNDMAPTR)); @@ -290,7 +290,7 @@ bool MACbSoftwareReset(void __iomem *dwIoBase) unsigned char byData; unsigned short ww; - // turn on HOSTCR_SOFTRST, just write 0x01 to reset + /* turn on HOSTCR_SOFTRST, just write 0x01 to reset */ VNSvOutPortB(dwIoBase + MAC_REG_HOSTCR, 0x01); for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { @@ -321,15 +321,15 @@ bool MACbSafeSoftwareReset(void __iomem *dwIoBase) unsigned char abyTmpRegData[MAC_MAX_CONTEXT_SIZE_PAGE0+MAC_MAX_CONTEXT_SIZE_PAGE1]; bool bRetVal; - // PATCH.... - // save some important register's value, then do - // reset, then restore register's value - - // save MAC context + /* PATCH.... + * save some important register's value, then do + * reset, then restore register's value + */ + /* save MAC context */ MACvSaveContext(dwIoBase, abyTmpRegData); - // do reset + /* do reset */ bRetVal = MACbSoftwareReset(dwIoBase); - // restore MAC context, except CR0 + /* restore MAC context, except CR0 */ MACvRestoreContext(dwIoBase, abyTmpRegData); return bRetVal; @@ -354,9 +354,9 @@ bool MACbSafeRxOff(void __iomem *dwIoBase) unsigned long dwData; unsigned char byData; - // turn off wow temp for turn off Rx safely + /* turn off wow temp for turn off Rx safely */ - // Clear RX DMA0,1 + /* Clear RX DMA0,1 */ VNSvOutPortD(dwIoBase + MAC_REG_RXDMACTL0, DMACTL_CLRRUN); VNSvOutPortD(dwIoBase + MAC_REG_RXDMACTL1, DMACTL_CLRRUN); for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { @@ -380,9 +380,9 @@ bool MACbSafeRxOff(void __iomem *dwIoBase) return false; } - // try to safe shutdown RX + /* try to safe shutdown RX */ MACvRegBitsOff(dwIoBase, MAC_REG_HOSTCR, HOSTCR_RXON); - // W_MAX_TIMEOUT is the timeout period + /* W_MAX_TIMEOUT is the timeout period */ for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { VNSvInPortB(dwIoBase + MAC_REG_HOSTCR, &byData); if (!(byData & HOSTCR_RXONST)) @@ -415,10 +415,10 @@ bool MACbSafeTxOff(void __iomem *dwIoBase) unsigned long dwData; unsigned char byData; - // Clear TX DMA - //Tx0 + /* Clear TX DMA */ + /* Tx0 */ VNSvOutPortD(dwIoBase + MAC_REG_TXDMACTL0, DMACTL_CLRRUN); - //AC0 + /* AC0 */ VNSvOutPortD(dwIoBase + MAC_REG_AC0DMACTL, DMACTL_CLRRUN); for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { @@ -442,10 +442,10 @@ bool MACbSafeTxOff(void __iomem *dwIoBase) return false; } - // try to safe shutdown TX + /* try to safe shutdown TX */ MACvRegBitsOff(dwIoBase, MAC_REG_HOSTCR, HOSTCR_TXON); - // W_MAX_TIMEOUT is the timeout period + /* W_MAX_TIMEOUT is the timeout period */ for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { VNSvInPortB(dwIoBase + MAC_REG_HOSTCR, &byData); if (!(byData & HOSTCR_TXONST)) @@ -509,10 +509,10 @@ bool MACbSafeStop(void __iomem *dwIoBase) */ bool MACbShutdown(void __iomem *dwIoBase) { - // disable MAC IMR + /* disable MAC IMR */ MACvIntDisable(dwIoBase); MACvSetLoopbackMode(dwIoBase, MAC_LB_INTERNAL); - // stop the adapter + /* stop the adapter */ if (!MACbSafeStop(dwIoBase)) { MACvSetLoopbackMode(dwIoBase, MAC_LB_NONE); return false; @@ -536,18 +536,18 @@ bool MACbShutdown(void __iomem *dwIoBase) */ void MACvInitialize(void __iomem *dwIoBase) { - // clear sticky bits + /* clear sticky bits */ MACvClearStckDS(dwIoBase); - // disable force PME-enable + /* disable force PME-enable */ VNSvOutPortB(dwIoBase + MAC_REG_PMC1, PME_OVR); - // only 3253 A + /* only 3253 A */ - // do reset + /* do reset */ MACbSoftwareReset(dwIoBase); - // reset TSF counter + /* reset TSF counter */ VNSvOutPortB(dwIoBase + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST); - // enable TSF counter + /* enable TSF counter */ VNSvOutPortB(dwIoBase + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN); } @@ -678,7 +678,7 @@ void MACvSetCurrTx0DescAddrEx(void __iomem *dwIoBase, unsigned long dwCurrDescAd * Return Value: none * */ -//TxDMA1 = AC0DMA +/* TxDMA1 = AC0DMA */ void MACvSetCurrAC0DescAddrEx(void __iomem *dwIoBase, unsigned long dwCurrDescAddr) { unsigned short ww; @@ -733,7 +733,7 @@ void MACvTimer0MicroSDelay(void __iomem *dwIoBase, unsigned int uDelay) VNSvOutPortB(dwIoBase + MAC_REG_TMCTL0, 0); VNSvOutPortD(dwIoBase + MAC_REG_TMDATA0, uDelay); VNSvOutPortB(dwIoBase + MAC_REG_TMCTL0, (TMCTL_TMD | TMCTL_TE)); - for (ii = 0; ii < 66; ii++) { // assume max PCI clock is 66Mhz + for (ii = 0; ii < 66; ii++) { /* assume max PCI clock is 66Mhz */ for (uu = 0; uu < uDelay; uu++) { VNSvInPortB(dwIoBase + MAC_REG_TMCTL0, &byValue); if ((byValue == 0) || @@ -780,14 +780,14 @@ bool MACbPSWakeup(void __iomem *dwIoBase) { unsigned char byOrgValue; unsigned int ww; - // Read PSCTL + /* Read PSCTL */ if (MACbIsRegBitsOff(dwIoBase, MAC_REG_PSCTL, PSCTL_PS)) return true; - // Disable PS + /* Disable PS */ MACvRegBitsOff(dwIoBase, MAC_REG_PSCTL, PSCTL_PSEN); - // Check if SyncFlushOK + /* Check if SyncFlushOK */ for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { VNSvInPortB(dwIoBase + MAC_REG_PSCTL, &byOrgValue); if (byOrgValue & PSCTL_WAKEDONE) @@ -859,7 +859,7 @@ void MACvSetKeyEntry(void __iomem *dwIoBase, unsigned short wKeyCtl, unsigned in wOffset += (uKeyIdx * 4); for (ii = 0; ii < 4; ii++) { - // always push 128 bits + /* always push 128 bits */ pr_debug("3.(%d) wOffset: %d, Data: %X\n", ii, wOffset+ii, *pdwKey); VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset+ii); -- GitLab From f43de77c9dddba86284f7cb58c5e257ebed843a3 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Tue, 10 Feb 2015 17:26:02 +0530 Subject: [PATCH 03178/11651] staging: panel: register driver after checking device register the driver only if lcd or keypad has been enabled and if both are disabled then just exit. Signed-off-by: Sudip Mukherjee Acked-by: Willy Tarreau Signed-off-by: Greg Kroah-Hartman --- drivers/staging/panel/panel.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/drivers/staging/panel/panel.c b/drivers/staging/panel/panel.c index 4da854ca3115..322b73d265d6 100644 --- a/drivers/staging/panel/panel.c +++ b/drivers/staging/panel/panel.c @@ -2377,23 +2377,17 @@ static int __init panel_init_module(void) /* tells various subsystems about the fact that we are initializing */ init_in_progress = 1; - if (parport_register_driver(&panel_driver)) { - pr_err("could not register with parport. Aborting.\n"); - return -EIO; - } - if (!lcd.enabled && !keypad.enabled) { - /* no device enabled, let's release the parport */ - if (pprt) { - parport_release(pprt); - parport_unregister_device(pprt); - pprt = NULL; - } - parport_unregister_driver(&panel_driver); + /* no device enabled, let's exit */ pr_err("driver version " PANEL_VERSION " disabled.\n"); return -ENODEV; } + if (parport_register_driver(&panel_driver)) { + pr_err("could not register with parport. Aborting.\n"); + return -EIO; + } + register_reboot_notifier(&panel_notifier); if (pprt) -- GitLab From 733345ec4ee3756822d455fc809f40713975bf76 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Wed, 11 Feb 2015 16:57:08 +0530 Subject: [PATCH 03179/11651] staging: panel: initialize lcd if lcd enabled initialiaze lcd parameters only if lcd is enabled. Signed-off-by: Sudip Mukherjee Acked-by: Willy Tarreau Signed-off-by: Greg Kroah-Hartman --- drivers/staging/panel/panel.c | 41 +++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/drivers/staging/panel/panel.c b/drivers/staging/panel/panel.c index 322b73d265d6..3339633e88d3 100644 --- a/drivers/staging/panel/panel.c +++ b/drivers/staging/panel/panel.c @@ -2321,25 +2321,6 @@ static int __init panel_init_module(void) break; } - /* - * Init lcd struct with load-time values to preserve exact current - * functionality (at least for now). - */ - lcd.height = lcd_height; - lcd.width = lcd_width; - lcd.bwidth = lcd_bwidth; - lcd.hwidth = lcd_hwidth; - lcd.charset = lcd_charset; - lcd.proto = lcd_proto; - lcd.pins.e = lcd_e_pin; - lcd.pins.rs = lcd_rs_pin; - lcd.pins.rw = lcd_rw_pin; - lcd.pins.cl = lcd_cl_pin; - lcd.pins.da = lcd_da_pin; - lcd.pins.bl = lcd_bl_pin; - - /* Leave it for now, just in case */ - lcd.esc_seq.len = -1; /* * Overwrite selection with module param values (both keypad and lcd), @@ -2359,6 +2340,28 @@ static int __init panel_init_module(void) lcd.enabled = (selected_lcd_type > 0); + if (lcd.enabled) { + /* + * Init lcd struct with load-time values to preserve exact + * current functionality (at least for now). + */ + lcd.height = lcd_height; + lcd.width = lcd_width; + lcd.bwidth = lcd_bwidth; + lcd.hwidth = lcd_hwidth; + lcd.charset = lcd_charset; + lcd.proto = lcd_proto; + lcd.pins.e = lcd_e_pin; + lcd.pins.rs = lcd_rs_pin; + lcd.pins.rw = lcd_rw_pin; + lcd.pins.cl = lcd_cl_pin; + lcd.pins.da = lcd_da_pin; + lcd.pins.bl = lcd_bl_pin; + + /* Leave it for now, just in case */ + lcd.esc_seq.len = -1; + } + switch (selected_keypad_type) { case KEYPAD_TYPE_OLD: keypad_profile = old_keypad_profile; -- GitLab From 8895f04b7a0c203af80a40f6bd0c85ac1fb3f7d7 Mon Sep 17 00:00:00 2001 From: Yannick Guerrini Date: Thu, 26 Feb 2015 17:36:33 +0100 Subject: [PATCH 03180/11651] staging: rtl8188eu: Fix trivial typos in comments Change 'disabed' and 'disabel' to 'disabled' Change 'inviation' to 'invitation' Change 'negoitation' to 'negotiation' Signed-off-by: Yannick Guerrini Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/include/wifi.h | 24 ++++++++++----------- drivers/staging/rtl8188eu/os_dep/usb_intf.c | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/staging/rtl8188eu/include/wifi.h b/drivers/staging/rtl8188eu/include/wifi.h index a68b52208192..a89275e0e0e0 100644 --- a/drivers/staging/rtl8188eu/include/wifi.h +++ b/drivers/staging/rtl8188eu/include/wifi.h @@ -888,7 +888,7 @@ enum ht_cap_ampdu_factor { #define P2P_STATUS_FAIL_INCOMPATIBLE_PROVSION 0x0A #define P2P_STATUS_FAIL_USER_REJECT 0x0B -/* Value of Inviation Flags Attribute */ +/* Value of Invitation Flags Attribute */ #define P2P_INVITATION_FLAGS_PERSISTENT BIT(0) #define DMP_P2P_DEVCAP_SUPPORT (P2P_DEVCAP_SERVICE_DISCOVERY | \ @@ -942,7 +942,7 @@ enum ht_cap_ampdu_factor { #define P2P_WILDCARD_SSID_LEN 7 -/* default value, used when: (1)p2p disabed or (2)p2p enabled +/* default value, used when: (1)p2p disabled or (2)p2p enabled * but only do 1 scan phase */ #define P2P_FINDPHASE_EX_NONE 0 /* used when p2p enabled and want to do 1 scan phase and @@ -1007,13 +1007,13 @@ enum P2P_STATE { P2P_STATE_TX_PROVISION_DIS_REQ = 6, P2P_STATE_RX_PROVISION_DIS_RSP = 7, P2P_STATE_RX_PROVISION_DIS_REQ = 8, - /* Doing the group owner negoitation handshake */ + /* Doing the group owner negotiation handshake */ P2P_STATE_GONEGO_ING = 9, - /* finish the group negoitation handshake with success */ + /* finish the group negotiation handshake with success */ P2P_STATE_GONEGO_OK = 10, - /* finish the group negoitation handshake with failure */ + /* finish the group negotiation handshake with failure */ P2P_STATE_GONEGO_FAIL = 11, - /* receiving the P2P Inviation request and match with the profile. */ + /* receiving the P2P Invitation request and match with the profile. */ P2P_STATE_RECV_INVITE_REQ_MATCH = 12, /* Doing the P2P WPS */ P2P_STATE_PROVISIONING_ING = 13, @@ -1023,17 +1023,17 @@ enum P2P_STATE { P2P_STATE_TX_INVITE_REQ = 15, /* Receiving the P2P Invitation response */ P2P_STATE_RX_INVITE_RESP_OK = 16, - /* receiving the P2P Inviation request and dismatch with the profile. */ + /* receiving the P2P Invitation request and dismatch with the profile. */ P2P_STATE_RECV_INVITE_REQ_DISMATCH = 17, - /* receiving the P2P Inviation request and this wifi is GO. */ + /* receiving the P2P Invitation request and this wifi is GO. */ P2P_STATE_RECV_INVITE_REQ_GO = 18, - /* receiving the P2P Inviation request to join an existing P2P Group. */ + /* receiving the P2P Invitation request to join an existing P2P Group. */ P2P_STATE_RECV_INVITE_REQ_JOIN = 19, - /* recveing the P2P Inviation response with failure */ + /* receiving the P2P Invitation response with failure */ P2P_STATE_RX_INVITE_RESP_FAIL = 20, - /* receiving p2p negoitation response with information is not available */ + /* receiving p2p negotiation response with information is not available */ P2P_STATE_RX_INFOR_NOREADY = 21, - /* sending p2p negoitation response with information is not available */ + /* sending p2p negotiation response with information is not available */ P2P_STATE_TX_INFOR_NOREADY = 22, }; diff --git a/drivers/staging/rtl8188eu/os_dep/usb_intf.c b/drivers/staging/rtl8188eu/os_dep/usb_intf.c index bee39c2278f1..ef3c73e38172 100644 --- a/drivers/staging/rtl8188eu/os_dep/usb_intf.c +++ b/drivers/staging/rtl8188eu/os_dep/usb_intf.c @@ -179,7 +179,7 @@ static void usb_intf_stop(struct adapter *padapter) { RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+usb_intf_stop\n")); - /* disabel_hw_interrupt */ + /* disable_hw_interrupt */ if (!padapter->bSurpriseRemoved) { /* device still exists, so driver can do i/o operation */ /* TODO: */ -- GitLab From 6a3386b15f40e3750b52b9be7a84100edc9ae0f6 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sat, 21 Feb 2015 18:53:44 -0800 Subject: [PATCH 03181/11651] staging: i2o: Remove use of seq_printf return value The seq_printf return value, because it's frequently misused, will eventually be converted to void. See: commit 1f33c41c03da ("seq_file: Rename seq_overflow() to seq_has_overflowed() and make public") Signed-off-by: Joe Perches Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/staging/i2o/i2o_proc.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/staging/i2o/i2o_proc.c b/drivers/staging/i2o/i2o_proc.c index 27d6b824aff8..780fee3224ea 100644 --- a/drivers/staging/i2o/i2o_proc.c +++ b/drivers/staging/i2o/i2o_proc.c @@ -264,16 +264,22 @@ static int i2o_report_query_status(struct seq_file *seq, int block_status, { switch (block_status) { case -ETIMEDOUT: - return seq_printf(seq, "Timeout reading group %s.\n", group); + seq_printf(seq, "Timeout reading group %s.\n", group); + break; case -ENOMEM: - return seq_printf(seq, "No free memory to read the table.\n"); + seq_puts(seq, "No free memory to read the table.\n"); + break; case -I2O_PARAMS_STATUS_INVALID_GROUP_ID: - return seq_printf(seq, "Group %s not supported.\n", group); + seq_printf(seq, "Group %s not supported.\n", group); + break; default: - return seq_printf(seq, - "Error reading group %s. BlockStatus 0x%02X\n", - group, -block_status); + seq_printf(seq, + "Error reading group %s. BlockStatus 0x%02X\n", + group, -block_status); + break; } + + return 0; } static char *bus_strings[] = { -- GitLab From c3d6047d95fad6d70894d7ff79d49e47deae41e5 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Tue, 10 Feb 2015 17:38:40 +0530 Subject: [PATCH 03182/11651] staging: sm7xxfb: make vgamode static the variable vgamode is used only in this file and hence can be safely made as static. Signed-off-by: Sudip Mukherjee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sm7xxfb/sm7xx.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/sm7xxfb/sm7xx.h b/drivers/staging/sm7xxfb/sm7xx.h index 7cc1896938b6..c5d62534e4a4 100644 --- a/drivers/staging/sm7xxfb/sm7xx.h +++ b/drivers/staging/sm7xxfb/sm7xx.h @@ -119,7 +119,7 @@ struct ModeInit { /********************************************************************** SM712 Mode table. **********************************************************************/ -struct ModeInit vgamode[] = { +static struct ModeInit vgamode[] = { { /* mode#0: 640 x 480 16Bpp 60Hz */ 640, 480, 16, 60, -- GitLab From 81dee67e215b23f0c98182eece122b906d35765a Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Tue, 3 Mar 2015 16:21:06 +0530 Subject: [PATCH 03183/11651] staging: sm750fb: add sm750 to staging sm750 of Silicon Motion is pci-e display controller device and has features like dual display and 2D acceleration. This patch adds the driver to staging. Signed-off-by: Sudip Mukherjee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 + drivers/staging/Makefile | 1 + drivers/staging/sm750fb/Kconfig | 10 + drivers/staging/sm750fb/Makefile | 4 + drivers/staging/sm750fb/TODO | 15 + drivers/staging/sm750fb/ddk750.h | 24 + drivers/staging/sm750fb/ddk750_chip.c | 639 ++++++ drivers/staging/sm750fb/ddk750_chip.h | 83 + drivers/staging/sm750fb/ddk750_display.c | 318 +++ drivers/staging/sm750fb/ddk750_display.h | 160 ++ drivers/staging/sm750fb/ddk750_dvi.c | 99 + drivers/staging/sm750fb/ddk750_dvi.h | 67 + drivers/staging/sm750fb/ddk750_help.c | 19 + drivers/staging/sm750fb/ddk750_help.h | 29 + drivers/staging/sm750fb/ddk750_hwi2c.c | 271 +++ drivers/staging/sm750fb/ddk750_hwi2c.h | 10 + drivers/staging/sm750fb/ddk750_mode.c | 205 ++ drivers/staging/sm750fb/ddk750_mode.h | 43 + drivers/staging/sm750fb/ddk750_power.c | 239 ++ drivers/staging/sm750fb/ddk750_power.h | 71 + drivers/staging/sm750fb/ddk750_reg.h | 2616 ++++++++++++++++++++++ drivers/staging/sm750fb/ddk750_sii164.c | 425 ++++ drivers/staging/sm750fb/ddk750_sii164.h | 172 ++ drivers/staging/sm750fb/ddk750_swi2c.c | 535 +++++ drivers/staging/sm750fb/ddk750_swi2c.h | 92 + drivers/staging/sm750fb/modedb.h | 221 ++ drivers/staging/sm750fb/readme | 38 + drivers/staging/sm750fb/sm750.c | 1451 ++++++++++++ drivers/staging/sm750fb/sm750.h | 185 ++ drivers/staging/sm750fb/sm750_accel.c | 516 +++++ drivers/staging/sm750fb/sm750_accel.h | 276 +++ drivers/staging/sm750fb/sm750_cursor.c | 254 +++ drivers/staging/sm750fb/sm750_cursor.h | 17 + drivers/staging/sm750fb/sm750_help.h | 111 + drivers/staging/sm750fb/sm750_hw.c | 640 ++++++ drivers/staging/sm750fb/sm750_hw.h | 104 + 36 files changed, 9962 insertions(+) create mode 100644 drivers/staging/sm750fb/Kconfig create mode 100644 drivers/staging/sm750fb/Makefile create mode 100644 drivers/staging/sm750fb/TODO create mode 100644 drivers/staging/sm750fb/ddk750.h create mode 100644 drivers/staging/sm750fb/ddk750_chip.c create mode 100644 drivers/staging/sm750fb/ddk750_chip.h create mode 100644 drivers/staging/sm750fb/ddk750_display.c create mode 100644 drivers/staging/sm750fb/ddk750_display.h create mode 100644 drivers/staging/sm750fb/ddk750_dvi.c create mode 100644 drivers/staging/sm750fb/ddk750_dvi.h create mode 100644 drivers/staging/sm750fb/ddk750_help.c create mode 100644 drivers/staging/sm750fb/ddk750_help.h create mode 100644 drivers/staging/sm750fb/ddk750_hwi2c.c create mode 100644 drivers/staging/sm750fb/ddk750_hwi2c.h create mode 100644 drivers/staging/sm750fb/ddk750_mode.c create mode 100644 drivers/staging/sm750fb/ddk750_mode.h create mode 100644 drivers/staging/sm750fb/ddk750_power.c create mode 100644 drivers/staging/sm750fb/ddk750_power.h create mode 100644 drivers/staging/sm750fb/ddk750_reg.h create mode 100644 drivers/staging/sm750fb/ddk750_sii164.c create mode 100644 drivers/staging/sm750fb/ddk750_sii164.h create mode 100644 drivers/staging/sm750fb/ddk750_swi2c.c create mode 100644 drivers/staging/sm750fb/ddk750_swi2c.h create mode 100644 drivers/staging/sm750fb/modedb.h create mode 100644 drivers/staging/sm750fb/readme create mode 100644 drivers/staging/sm750fb/sm750.c create mode 100644 drivers/staging/sm750fb/sm750.h create mode 100644 drivers/staging/sm750fb/sm750_accel.c create mode 100644 drivers/staging/sm750fb/sm750_accel.h create mode 100644 drivers/staging/sm750fb/sm750_cursor.c create mode 100644 drivers/staging/sm750fb/sm750_cursor.h create mode 100644 drivers/staging/sm750fb/sm750_help.h create mode 100644 drivers/staging/sm750fb/sm750_hw.c create mode 100644 drivers/staging/sm750fb/sm750_hw.h diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 45baa83be7ce..5da70fddd036 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -58,6 +58,8 @@ source "drivers/staging/iio/Kconfig" source "drivers/staging/sm7xxfb/Kconfig" +source "drivers/staging/sm750fb/Kconfig" + source "drivers/staging/xgifb/Kconfig" source "drivers/staging/emxx_udc/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 29160790841f..0b922ae30356 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -23,6 +23,7 @@ obj-$(CONFIG_VT6656) += vt6656/ obj-$(CONFIG_VME_BUS) += vme/ obj-$(CONFIG_IIO) += iio/ obj-$(CONFIG_FB_SM7XX) += sm7xxfb/ +obj-$(CONFIG_FB_SM7XX) += sm750fb/ obj-$(CONFIG_FB_XGI) += xgifb/ obj-$(CONFIG_USB_EMXX) += emxx_udc/ obj-$(CONFIG_FT1000) += ft1000/ diff --git a/drivers/staging/sm750fb/Kconfig b/drivers/staging/sm750fb/Kconfig new file mode 100644 index 000000000000..c40d088a4d3b --- /dev/null +++ b/drivers/staging/sm750fb/Kconfig @@ -0,0 +1,10 @@ +config FB_SM750 + tristate "Silicon Motion SM750 framebuffer support" + depends on FB && PCI + help + Frame buffer driver for the Silicon Motion SM750 chip + with 2D accelearion and dual head support. + + This driver is also available as a module. The module will be + called sm750fb. If you want to compile it as a module, say M + here and read . diff --git a/drivers/staging/sm750fb/Makefile b/drivers/staging/sm750fb/Makefile new file mode 100644 index 000000000000..dcce3f487ed5 --- /dev/null +++ b/drivers/staging/sm750fb/Makefile @@ -0,0 +1,4 @@ +obj-$(CONFIG_FB_SM750) += sm750fb.o + +sm750fb-objs := sm750.o sm750_hw.o sm750_accel.o sm750_cursor.o ddk750_chip.o ddk750_power.o ddk750_mode.o +sm750fb-objs += ddk750_display.o ddk750_help.o ddk750_swi2c.o ddk750_sii164.o ddk750_dvi.o ddk750_hwi2c.o diff --git a/drivers/staging/sm750fb/TODO b/drivers/staging/sm750fb/TODO new file mode 100644 index 000000000000..bc1617249395 --- /dev/null +++ b/drivers/staging/sm750fb/TODO @@ -0,0 +1,15 @@ +TODO: +- lots of clechpatch cleanup +- use kernel coding style +- refine the code and remove unused code +- check on hardware effects of removal of USE_HW_I2C and USE_DVICHIP (these two + are supposed to be sample code which is given here if someone wants to + use those functionalities) +- move it to drivers/video/fbdev +- modify the code for drm framework + +Please send any patches to + Greg Kroah-Hartman + Sudip Mukherjee + Teddy Wang + Sudip Mukherjee diff --git a/drivers/staging/sm750fb/ddk750.h b/drivers/staging/sm750fb/ddk750.h new file mode 100644 index 000000000000..2c10a08ed964 --- /dev/null +++ b/drivers/staging/sm750fb/ddk750.h @@ -0,0 +1,24 @@ +#ifndef DDK750_H__ +#define DDK750_H__ +/******************************************************************* +* +* Copyright (c) 2007 by Silicon Motion, Inc. (SMI) +* +* All rights are reserved. Reproduction or in part is prohibited +* without the written consent of the copyright owner. +* +* RegSC.h --- SM718 SDK +* This file contains the definitions for the System Configuration registers. +* +*******************************************************************/ +#include "ddk750_reg.h" +#include "ddk750_mode.h" +#include "ddk750_chip.h" +#include "ddk750_display.h" +#include "ddk750_power.h" +#include "ddk750_help.h" +#ifdef USE_HW_I2C +#include "ddk750_hwi2c.h" +#endif +#include "ddk750_swi2c.h" +#endif diff --git a/drivers/staging/sm750fb/ddk750_chip.c b/drivers/staging/sm750fb/ddk750_chip.c new file mode 100644 index 000000000000..b71169ed063c --- /dev/null +++ b/drivers/staging/sm750fb/ddk750_chip.c @@ -0,0 +1,639 @@ +#include "ddk750_help.h" +#include "ddk750_reg.h" +#include "ddk750_chip.h" +#include "ddk750_power.h" +typedef struct _pllcalparam{ + unsigned char power;/* d : 0~ 6*/ + unsigned char pod; + unsigned char od; + unsigned char value;/* value of 2 power d (2^d) */ +} +pllcalparam; + + +logical_chip_type_t getChipType() +{ + unsigned short physicalID; + char physicalRev; + logical_chip_type_t chip; + + physicalID = devId750;//either 0x718 or 0x750 + physicalRev = revId750; + + if (physicalID == 0x718) + { + chip = SM718; + } + else if (physicalID == 0x750) + { + chip = SM750; + /* SM750 and SM750LE are different in their revision ID only. */ + if (physicalRev == SM750LE_REVISION_ID){ + chip = SM750LE; + } + } + else + { + chip = SM_UNKNOWN; + } + + return chip; +} + + +inline unsigned int twoToPowerOfx(unsigned long x) +{ + unsigned long i; + unsigned long result = 1; + + for (i=1; i<=x; i++) + result *= 2; + return result; +} + +inline unsigned int calcPLL(pll_value_t *pPLL) +{ + return (pPLL->inputFreq * pPLL->M / pPLL->N / twoToPowerOfx(pPLL->OD) / twoToPowerOfx(pPLL->POD)); +} + +unsigned int getPllValue(clock_type_t clockType, pll_value_t *pPLL) +{ + unsigned int ulPllReg = 0; + + pPLL->inputFreq = DEFAULT_INPUT_CLOCK; + pPLL->clockType = clockType; + + switch (clockType) + { + case MXCLK_PLL: + ulPllReg = PEEK32(MXCLK_PLL_CTRL); + break; + case PRIMARY_PLL: + ulPllReg = PEEK32(PANEL_PLL_CTRL); + break; + case SECONDARY_PLL: + ulPllReg = PEEK32(CRT_PLL_CTRL); + break; + case VGA0_PLL: + ulPllReg = PEEK32(VGA_PLL0_CTRL); + break; + case VGA1_PLL: + ulPllReg = PEEK32(VGA_PLL1_CTRL); + break; + } + + pPLL->M = FIELD_GET(ulPllReg, PANEL_PLL_CTRL, M); + pPLL->N = FIELD_GET(ulPllReg, PANEL_PLL_CTRL, N); + pPLL->OD = FIELD_GET(ulPllReg, PANEL_PLL_CTRL, OD); + pPLL->POD = FIELD_GET(ulPllReg, PANEL_PLL_CTRL, POD); + + return calcPLL(pPLL); +} + + +unsigned int getChipClock() +{ + pll_value_t pll; +#if 1 + if(getChipType() == SM750LE) + return MHz(130); +#endif + + return getPllValue(MXCLK_PLL, &pll); +} + + +/* + * This function set up the main chip clock. + * + * Input: Frequency to be set. + */ +void setChipClock(unsigned int frequency) +{ + pll_value_t pll; + unsigned int ulActualMxClk; +#if 1 + /* Cheok_0509: For SM750LE, the chip clock is fixed. Nothing to set. */ + if (getChipType() == SM750LE) + return; +#endif + + if (frequency != 0) + { + /* + * Set up PLL, a structure to hold the value to be set in clocks. + */ + pll.inputFreq = DEFAULT_INPUT_CLOCK; /* Defined in CLOCK.H */ + pll.clockType = MXCLK_PLL; + + /* + * Call calcPllValue() to fill up the other fields for PLL structure. + * Sometime, the chip cannot set up the exact clock required by User. + * Return value from calcPllValue() gives the actual possible clock. + */ + ulActualMxClk = calcPllValue(frequency, &pll); + + /* Master Clock Control: MXCLK_PLL */ + POKE32(MXCLK_PLL_CTRL, formatPllReg(&pll)); + } +} + + + +void setMemoryClock(unsigned int frequency) +{ + unsigned int ulReg, divisor; + #if 1 + /* Cheok_0509: For SM750LE, the memory clock is fixed. Nothing to set. */ + if (getChipType() == SM750LE) + return; +#endif + if (frequency != 0) + { + /* Set the frequency to the maximum frequency that the DDR Memory can take + which is 336MHz. */ + if (frequency > MHz(336)) + frequency = MHz(336); + + /* Calculate the divisor */ + divisor = (unsigned int) roundedDiv(getChipClock(), frequency); + + /* Set the corresponding divisor in the register. */ + ulReg = PEEK32(CURRENT_GATE); + switch(divisor) + { + default: + case 1: + ulReg = FIELD_SET(ulReg, CURRENT_GATE, M2XCLK, DIV_1); + break; + case 2: + ulReg = FIELD_SET(ulReg, CURRENT_GATE, M2XCLK, DIV_2); + break; + case 3: + ulReg = FIELD_SET(ulReg, CURRENT_GATE, M2XCLK, DIV_3); + break; + case 4: + ulReg = FIELD_SET(ulReg, CURRENT_GATE, M2XCLK, DIV_4); + break; + } + + setCurrentGate(ulReg); + } +} + + +/* + * This function set up the master clock (MCLK). + * + * Input: Frequency to be set. + * + * NOTE: + * The maximum frequency the engine can run is 168MHz. + */ +void setMasterClock(unsigned int frequency) +{ + unsigned int ulReg, divisor; + #if 1 + /* Cheok_0509: For SM750LE, the memory clock is fixed. Nothing to set. */ + if (getChipType() == SM750LE) + return; +#endif + if (frequency != 0) + { + /* Set the frequency to the maximum frequency that the SM750 engine can + run, which is about 190 MHz. */ + if (frequency > MHz(190)) + frequency = MHz(190); + + /* Calculate the divisor */ + divisor = (unsigned int) roundedDiv(getChipClock(), frequency); + + /* Set the corresponding divisor in the register. */ + ulReg = PEEK32(CURRENT_GATE); + switch(divisor) + { + default: + case 3: + ulReg = FIELD_SET(ulReg, CURRENT_GATE, MCLK, DIV_3); + break; + case 4: + ulReg = FIELD_SET(ulReg, CURRENT_GATE, MCLK, DIV_4); + break; + case 6: + ulReg = FIELD_SET(ulReg, CURRENT_GATE, MCLK, DIV_6); + break; + case 8: + ulReg = FIELD_SET(ulReg, CURRENT_GATE, MCLK, DIV_8); + break; + } + + setCurrentGate(ulReg); + } +} + + +unsigned int ddk750_getVMSize() +{ + unsigned int reg; + unsigned int data; + + /* sm750le only use 64 mb memory*/ + if(getChipType() == SM750LE) + return MB(64); + + /* for 750,always use power mode0*/ + reg = PEEK32(MODE0_GATE); + reg = FIELD_SET(reg,MODE0_GATE,GPIO,ON); + POKE32(MODE0_GATE,reg); + + /* get frame buffer size from GPIO */ + reg = FIELD_GET(PEEK32(MISC_CTRL),MISC_CTRL,LOCALMEM_SIZE); + switch(reg){ + case MISC_CTRL_LOCALMEM_SIZE_8M: data = MB(8); break; /* 8 Mega byte */ + case MISC_CTRL_LOCALMEM_SIZE_16M: data = MB(16); break; /* 16 Mega byte */ + case MISC_CTRL_LOCALMEM_SIZE_32M: data = MB(32); break; /* 32 Mega byte */ + case MISC_CTRL_LOCALMEM_SIZE_64M: data = MB(64); break; /* 64 Mega byte */ + default: data = 0;break; + } + return data; + +} + +int ddk750_initHw(initchip_param_t * pInitParam) +{ + + unsigned int ulReg; +#if 0 + //move the code to map regiter function. + if(getChipType() == SM718){ + /* turn on big endian bit*/ + ulReg = PEEK32(0x74); + /* now consider register definition in a big endian pattern*/ + POKE32(0x74,ulReg|0x80000000); + } + +#endif + + + if (pInitParam->powerMode != 0 ) + pInitParam->powerMode = 0; + setPowerMode(pInitParam->powerMode); + + /* Enable display power gate & LOCALMEM power gate*/ + ulReg = PEEK32(CURRENT_GATE); + ulReg = FIELD_SET(ulReg, CURRENT_GATE, DISPLAY, ON); + ulReg = FIELD_SET(ulReg,CURRENT_GATE,LOCALMEM,ON); + setCurrentGate(ulReg); + + if(getChipType() != SM750LE){ + /* set panel pll and graphic mode via mmio_88 */ + ulReg = PEEK32(VGA_CONFIGURATION); + ulReg = FIELD_SET(ulReg,VGA_CONFIGURATION,PLL,PANEL); + ulReg = FIELD_SET(ulReg,VGA_CONFIGURATION,MODE,GRAPHIC); + POKE32(VGA_CONFIGURATION,ulReg); + }else{ +#if defined(__i386__) || defined( __x86_64__) + /* set graphic mode via IO method */ + outb_p(0x88,0x3d4); + outb_p(0x06,0x3d5); +#endif + } + + /* Set the Main Chip Clock */ + setChipClock(MHz((unsigned int)pInitParam->chipClock)); + + /* Set up memory clock. */ + setMemoryClock(MHz(pInitParam->memClock)); + + /* Set up master clock */ + setMasterClock(MHz(pInitParam->masterClock)); + + + /* Reset the memory controller. If the memory controller is not reset in SM750, + the system might hang when sw accesses the memory. + The memory should be resetted after changing the MXCLK. + */ + if (pInitParam->resetMemory == 1) + { + ulReg = PEEK32(MISC_CTRL); + ulReg = FIELD_SET(ulReg, MISC_CTRL, LOCALMEM_RESET, RESET); + POKE32(MISC_CTRL, ulReg); + + ulReg = FIELD_SET(ulReg, MISC_CTRL, LOCALMEM_RESET, NORMAL); + POKE32(MISC_CTRL, ulReg); + } + + if (pInitParam->setAllEngOff == 1) + { + enable2DEngine(0); + + /* Disable Overlay, if a former application left it on */ + ulReg = PEEK32(VIDEO_DISPLAY_CTRL); + ulReg = FIELD_SET(ulReg, VIDEO_DISPLAY_CTRL, PLANE, DISABLE); + POKE32(VIDEO_DISPLAY_CTRL, ulReg); + + /* Disable video alpha, if a former application left it on */ + ulReg = PEEK32(VIDEO_ALPHA_DISPLAY_CTRL); + ulReg = FIELD_SET(ulReg, VIDEO_ALPHA_DISPLAY_CTRL, PLANE, DISABLE); + POKE32(VIDEO_ALPHA_DISPLAY_CTRL, ulReg); + + /* Disable alpha plane, if a former application left it on */ + ulReg = PEEK32(ALPHA_DISPLAY_CTRL); + ulReg = FIELD_SET(ulReg, ALPHA_DISPLAY_CTRL, PLANE, DISABLE); + POKE32(ALPHA_DISPLAY_CTRL, ulReg); + +#if 0 + /* Disable LCD hardware cursor, if a former application left it on */ + ulReg = PEEK32(PANEL_HWC_ADDRESS); + ulReg = FIELD_SET(ulReg, PANEL_HWC_ADDRESS, ENABLE, DISABLE); + POKE32(PANEL_HWC_ADDRESS, ulReg); + + /* Disable CRT hardware cursor, if a former application left it on */ + ulReg = PEEK32(CRT_HWC_ADDRESS); + ulReg = FIELD_SET(ulReg, CRT_HWC_ADDRESS, ENABLE, DISABLE); + POKE32(CRT_HWC_ADDRESS, ulReg); + + /* Disable ZV Port 0, if a former application left it on */ + ulReg = PEEK32(ZV0_CAPTURE_CTRL); + ulReg = FIELD_SET(ulReg, ZV0_CAPTURE_CTRL, CAP, DISABLE); + POKE32(ZV0_CAPTURE_CTRL, ulReg); + + /* Disable ZV Port 1, if a former application left it on */ + ulReg = PEEK32(ZV1_CAPTURE_CTRL); + ulReg = FIELD_SET(ulReg, ZV1_CAPTURE_CTRL, CAP, DISABLE); + POKE32(ZV1_CAPTURE_CTRL, ulReg); + + /* Disable ZV Port Power, if a former application left it on */ + enableZVPort(0); + /* Disable DMA Channel, if a former application left it on */ + ulReg = PEEK32(DMA_ABORT_INTERRUPT); + ulReg = FIELD_SET(ulReg, DMA_ABORT_INTERRUPT, ABORT_1, ABORT); + POKE32(DMA_ABORT_INTERRUPT, ulReg); + + /* Disable i2c */ + enableI2C(0); +#endif + /* Disable DMA Channel, if a former application left it on */ + ulReg = PEEK32(DMA_ABORT_INTERRUPT); + ulReg = FIELD_SET(ulReg, DMA_ABORT_INTERRUPT, ABORT_1, ABORT); + POKE32(DMA_ABORT_INTERRUPT, ulReg); + + /* Disable DMA Power, if a former application left it on */ + enableDMA(0); + } + + /* We can add more initialization as needed. */ + + return 0; +} + +#if 0 + +unsigned int absDiff(unsigned int a, unsigned int b) +{ + if ( a > b ) + return(a - b); + else + return(b - a); +} + +#endif +/* + monk liu @ 4/6/2011: + re-write the calculatePLL function of ddk750. + the original version function does not use some mathematics tricks and shortcut + when it doing the calculation of the best N,M,D combination + I think this version gives a little upgrade in speed + + 750 pll clock formular: + Request Clock = (Input Clock * M )/(N * X) + + Input Clock = 14318181 hz + X = 2 power D + D ={0,1,2,3,4,5,6} + M = {1,...,255} + N = {2,...,15} +*/ +unsigned int calcPllValue(unsigned int request_orig,pll_value_t *pll) +{ + /* used for primary and secondary channel pixel clock pll */ + static pllcalparam xparm_PIXEL[] = { + /* 2^0 = 1*/ {0,0,0,1}, + /* 2^ 1 =2*/ {1,0,1,2}, + /* 2^ 2 = 4*/ {2,0,2,4}, + {3,0,3,8}, + {4,1,3,16}, + {5,2,3,32}, + /* 2^6 = 64 */ {6,3,3,64}, + }; + + /* used for MXCLK (chip clock) */ + static pllcalparam xparm_MXCLK[] = { + /* 2^0 = 1*/ {0,0,0,1}, + /* 2^ 1 =2*/ {1,0,1,2}, + /* 2^ 2 = 4*/ {2,0,2,4}, + {3,0,3,8}, + }; + + /* as sm750 register definition, N located in 2,15 and M located in 1,255 */ + int N,M,X,d; + int xcnt; + int miniDiff; + unsigned int RN,quo,rem,fl_quo; + unsigned int input,request; + unsigned int tmpClock,ret; + pllcalparam * xparm; + +#if 1 + if (getChipType() == SM750LE) + { + /* SM750LE don't have prgrammable PLL and M/N values to work on. + Just return the requested clock. */ + return request_orig; + } +#endif + + ret = 0; + miniDiff = ~0; + request = request_orig / 1000; + input = pll->inputFreq / 1000; + + /* for MXCLK register , no POD provided, so need be treated differently */ + + if(pll->clockType != MXCLK_PLL){ + xparm = &xparm_PIXEL[0]; + xcnt = sizeof(xparm_PIXEL)/sizeof(xparm_PIXEL[0]); + }else{ + xparm = &xparm_MXCLK[0]; + xcnt = sizeof(xparm_MXCLK)/sizeof(xparm_MXCLK[0]); + } + + + for(N = 15;N>1;N--) + { + /* RN will not exceed maximum long if @request <= 285 MHZ (for 32bit cpu) */ + RN = N * request; + quo = RN / input; + rem = RN % input;/* rem always small than 14318181 */ + fl_quo = (rem * 10000 /input); + + for(d = xcnt - 1;d >= 0;d--){ + X = xparm[d].value; + M = quo*X; + M += fl_quo * X / 10000; + /* round step */ + M += (fl_quo*X % 10000)>5000?1:0; + if(M < 256 && M > 0) + { + unsigned int diff; + tmpClock = pll->inputFreq *M / N / X; + diff = absDiff(tmpClock,request_orig); + if(diff < miniDiff) + { + pll->M = M; + pll->N = N; + pll->OD = xparm[d].od; + pll->POD = xparm[d].pod; + miniDiff = diff; + ret = tmpClock; + } + } + } + } + + //printk("Finally: pll->n[%lu],m[%lu],od[%lu],pod[%lu]\n",pll->N,pll->M,pll->OD,pll->POD); + return ret; +} + +unsigned int calcPllValue2( +unsigned int ulRequestClk, /* Required pixel clock in Hz unit */ +pll_value_t *pPLL /* Structure to hold the value to be set in PLL */ +) +{ + unsigned int M, N, OD, POD = 0, diff, pllClk, odPower, podPower; + unsigned int bestDiff = 0xffffffff; /* biggest 32 bit unsigned number */ + unsigned int ret; + /* Init PLL structure to know states */ + pPLL->M = 0; + pPLL->N = 0; + pPLL->OD = 0; + pPLL->POD = 0; + + /* Sanity check: None at the moment */ + + /* Convert everything in Khz range in order to avoid calculation overflow */ + pPLL->inputFreq /= 1000; + ulRequestClk /= 1000; + +#ifndef VALIDATION_CHIP + /* The maximum of post divider is 8. */ + for (POD=0; POD<=3; POD++) +#endif + { + +#ifndef VALIDATION_CHIP + /* MXCLK_PLL does not have post divider. */ + if ((POD > 0) && (pPLL->clockType == MXCLK_PLL)) + break; +#endif + + /* Work out 2 to the power of POD */ + podPower = twoToPowerOfx(POD); + + /* OD has only 2 bits [15:14] and its value must between 0 to 3 */ + for (OD=0; OD<=3; OD++) + { + /* Work out 2 to the power of OD */ + odPower = twoToPowerOfx(OD); + +#ifdef VALIDATION_CHIP + if (odPower > 4) + podPower = 4; + else + podPower = odPower; +#endif + + /* N has 4 bits [11:8] and its value must between 2 and 15. + The N == 1 will behave differently --> Result is not correct. */ + for (N=2; N<=15; N++) + { + /* The formula for PLL is ulRequestClk = inputFreq * M / N / (2^OD) + In the following steps, we try to work out a best M value given the others are known. + To avoid decimal calculation, we use 1000 as multiplier for up to 3 decimal places of accuracy. + */ + M = ulRequestClk * N * odPower * 1000 / pPLL->inputFreq; + M = roundedDiv(M, 1000); + + /* M field has only 8 bits, reject value bigger than 8 bits */ + if (M < 256) + { + /* Calculate the actual clock for a given M & N */ + pllClk = pPLL->inputFreq * M / N / odPower / podPower; + + /* How much are we different from the requirement */ + diff = absDiff(pllClk, ulRequestClk); + + if (diff < bestDiff) + { + bestDiff = diff; + + /* Store M and N values */ + pPLL->M = M; + pPLL->N = N; + pPLL->OD = OD; + +#ifdef VALIDATION_CHIP + if (OD > 2) + POD = 2; + else + POD = OD; +#endif + + pPLL->POD = POD; + } + } + } + } + } + + /* Restore input frequency from Khz to hz unit */ +// pPLL->inputFreq *= 1000; + ulRequestClk *= 1000; + pPLL->inputFreq = DEFAULT_INPUT_CLOCK; /* Default reference clock */ + + /* Output debug information */ + //DDKDEBUGPRINT((DISPLAY_LEVEL, "calcPllValue: Requested Frequency = %d\n", ulRequestClk)); + //DDKDEBUGPRINT((DISPLAY_LEVEL, "calcPllValue: Input CLK = %dHz, M=%d, N=%d, OD=%d, POD=%d\n", pPLL->inputFreq, pPLL->M, pPLL->N, pPLL->OD, pPLL->POD)); + + /* Return actual frequency that the PLL can set */ + ret = calcPLL(pPLL); + return ret; +} + + + + + +unsigned int formatPllReg(pll_value_t *pPLL) +{ + unsigned int ulPllReg = 0; + + /* Note that all PLL's have the same format. Here, we just use Panel PLL parameter + to work out the bit fields in the register. + On returning a 32 bit number, the value can be applied to any PLL in the calling function. + */ + ulPllReg = + FIELD_SET( 0, PANEL_PLL_CTRL, BYPASS, OFF) + | FIELD_SET( 0, PANEL_PLL_CTRL, POWER, ON) + | FIELD_SET( 0, PANEL_PLL_CTRL, INPUT, OSC) +#ifndef VALIDATION_CHIP + | FIELD_VALUE(0, PANEL_PLL_CTRL, POD, pPLL->POD) +#endif + | FIELD_VALUE(0, PANEL_PLL_CTRL, OD, pPLL->OD) + | FIELD_VALUE(0, PANEL_PLL_CTRL, N, pPLL->N) + | FIELD_VALUE(0, PANEL_PLL_CTRL, M, pPLL->M); + + return(ulPllReg); +} + + diff --git a/drivers/staging/sm750fb/ddk750_chip.h b/drivers/staging/sm750fb/ddk750_chip.h new file mode 100644 index 000000000000..1c7887512b69 --- /dev/null +++ b/drivers/staging/sm750fb/ddk750_chip.h @@ -0,0 +1,83 @@ +#ifndef DDK750_CHIP_H__ +#define DDK750_CHIP_H__ +#define DEFAULT_INPUT_CLOCK 14318181 /* Default reference clock */ +#define SM750LE_REVISION_ID (char)0xfe + +/* This is all the chips recognized by this library */ +typedef enum _logical_chip_type_t +{ + SM_UNKNOWN, + SM718, + SM750, + SM750LE, +} +logical_chip_type_t; + + +typedef enum _clock_type_t +{ + MXCLK_PLL, + PRIMARY_PLL, + SECONDARY_PLL, + VGA0_PLL, + VGA1_PLL, +} +clock_type_t; + +typedef struct _pll_value_t +{ + clock_type_t clockType; + unsigned long inputFreq; /* Input clock frequency to the PLL */ + + /* Use this when clockType = PANEL_PLL */ + unsigned long M; + unsigned long N; + unsigned long OD; + unsigned long POD; +} +pll_value_t; + +/* input struct to initChipParam() function */ +typedef struct _initchip_param_t +{ + unsigned short powerMode; /* Use power mode 0 or 1 */ + unsigned short chipClock; /* Speed of main chip clock in MHz unit + 0 = keep the current clock setting + Others = the new main chip clock + */ + unsigned short memClock; /* Speed of memory clock in MHz unit + 0 = keep the current clock setting + Others = the new memory clock + */ + unsigned short masterClock; /* Speed of master clock in MHz unit + 0 = keep the current clock setting + Others = the new master clock + */ + unsigned short setAllEngOff; /* 0 = leave all engine state untouched. + 1 = make sure they are off: 2D, Overlay, + video alpha, alpha, hardware cursors + */ + unsigned char resetMemory; /* 0 = Do not reset the memory controller + 1 = Reset the memory controller + */ + + /* More initialization parameter can be added if needed */ +} +initchip_param_t; + + +logical_chip_type_t getChipType(void); +unsigned int calcPllValue(unsigned int request,pll_value_t *pll); +unsigned int calcPllValue2(unsigned int,pll_value_t *); +unsigned int formatPllReg(pll_value_t *pPLL); +void ddk750_set_mmio(volatile unsigned char *,unsigned short,char); +unsigned int ddk750_getVMSize(void); +int ddk750_initHw(initchip_param_t *); +unsigned int getPllValue(clock_type_t clockType, pll_value_t *pPLL); +unsigned int getChipClock(void); +void setChipClock(unsigned int); +void setMemoryClock(unsigned int frequency); +void setMasterClock(unsigned int frequency); + + +#endif diff --git a/drivers/staging/sm750fb/ddk750_display.c b/drivers/staging/sm750fb/ddk750_display.c new file mode 100644 index 000000000000..57192e5b4730 --- /dev/null +++ b/drivers/staging/sm750fb/ddk750_display.c @@ -0,0 +1,318 @@ +#include "ddk750_reg.h" +#include "ddk750_help.h" +#include "ddk750_display.h" +#include "ddk750_power.h" +#include "ddk750_dvi.h" + +#define primaryWaitVerticalSync(delay) waitNextVerticalSync(0,delay) + +static void setDisplayControl(int ctrl,int dispState) +{ + /* state != 0 means turn on both timing & plane en_bit */ + unsigned long ulDisplayCtrlReg, ulReservedBits; + int cnt; + + cnt = 0; + + /* Set the primary display control */ + if (!ctrl) + { + ulDisplayCtrlReg = PEEK32(PANEL_DISPLAY_CTRL); + /* Turn on/off the Panel display control */ + if (dispState) + { + /* Timing should be enabled first before enabling the plane + * because changing at the same time does not guarantee that + * the plane will also enabled or disabled. + */ + ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg, + PANEL_DISPLAY_CTRL, TIMING, ENABLE); + POKE32(PANEL_DISPLAY_CTRL, ulDisplayCtrlReg); + + ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg, + PANEL_DISPLAY_CTRL, PLANE, ENABLE); + + /* Added some masks to mask out the reserved bits. + * Sometimes, the reserved bits are set/reset randomly when + * writing to the PRIMARY_DISPLAY_CTRL, therefore, the register + * reserved bits are needed to be masked out. + */ + ulReservedBits = FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_1_MASK, ENABLE) | + FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_2_MASK, ENABLE) | + FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_3_MASK, ENABLE); + + /* Somehow the register value on the plane is not set + * until a few delay. Need to write + * and read it a couple times + */ + do + { + cnt++; + POKE32(PANEL_DISPLAY_CTRL, ulDisplayCtrlReg); + } while((PEEK32(PANEL_DISPLAY_CTRL) & ~ulReservedBits) != + (ulDisplayCtrlReg & ~ulReservedBits)); + printk("Set Panel Plane enbit:after tried %d times\n",cnt); + } + else + { + /* When turning off, there is no rule on the programming + * sequence since whenever the clock is off, then it does not + * matter whether the plane is enabled or disabled. + * Note: Modifying the plane bit will take effect on the + * next vertical sync. Need to find out if it is necessary to + * wait for 1 vsync before modifying the timing enable bit. + * */ + ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg, + PANEL_DISPLAY_CTRL, PLANE, DISABLE); + POKE32(PANEL_DISPLAY_CTRL, ulDisplayCtrlReg); + + ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg, + PANEL_DISPLAY_CTRL, TIMING, DISABLE); + POKE32(PANEL_DISPLAY_CTRL, ulDisplayCtrlReg); + } + + } + /* Set the secondary display control */ + else + { + ulDisplayCtrlReg = PEEK32(CRT_DISPLAY_CTRL); + + if (dispState) + { + /* Timing should be enabled first before enabling the plane because changing at the + same time does not guarantee that the plane will also enabled or disabled. + */ + ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg, + CRT_DISPLAY_CTRL, TIMING, ENABLE); + POKE32(CRT_DISPLAY_CTRL, ulDisplayCtrlReg); + + ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg, + CRT_DISPLAY_CTRL, PLANE, ENABLE); + + /* Added some masks to mask out the reserved bits. + * Sometimes, the reserved bits are set/reset randomly when + * writing to the PRIMARY_DISPLAY_CTRL, therefore, the register + * reserved bits are needed to be masked out. + */ + + ulReservedBits = FIELD_SET(0, CRT_DISPLAY_CTRL, RESERVED_1_MASK, ENABLE) | + FIELD_SET(0, CRT_DISPLAY_CTRL, RESERVED_2_MASK, ENABLE) | + FIELD_SET(0, CRT_DISPLAY_CTRL, RESERVED_3_MASK, ENABLE) | + FIELD_SET(0, CRT_DISPLAY_CTRL, RESERVED_4_MASK, ENABLE); + + do + { + cnt++; + POKE32(CRT_DISPLAY_CTRL, ulDisplayCtrlReg); + } while((PEEK32(CRT_DISPLAY_CTRL) & ~ulReservedBits) != + (ulDisplayCtrlReg & ~ulReservedBits)); + printk("Set Crt Plane enbit:after tried %d times\n",cnt); + } + else + { + /* When turning off, there is no rule on the programming + * sequence since whenever the clock is off, then it does not + * matter whether the plane is enabled or disabled. + * Note: Modifying the plane bit will take effect on the next + * vertical sync. Need to find out if it is necessary to + * wait for 1 vsync before modifying the timing enable bit. + */ + ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg, + CRT_DISPLAY_CTRL, PLANE, DISABLE); + POKE32(CRT_DISPLAY_CTRL, ulDisplayCtrlReg); + + ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg, + CRT_DISPLAY_CTRL, TIMING, DISABLE); + POKE32(CRT_DISPLAY_CTRL, ulDisplayCtrlReg); + } + } +} + + +static void waitNextVerticalSync(int ctrl,int delay) +{ + unsigned int status; + if(!ctrl){ + /* primary controller */ + + /* Do not wait when the Primary PLL is off or display control is already off. + This will prevent the software to wait forever. */ + if ((FIELD_GET(PEEK32(PANEL_PLL_CTRL), PANEL_PLL_CTRL, POWER) == + PANEL_PLL_CTRL_POWER_OFF) || + (FIELD_GET(PEEK32(PANEL_DISPLAY_CTRL), PANEL_DISPLAY_CTRL, TIMING) == + PANEL_DISPLAY_CTRL_TIMING_DISABLE)) + { + return; + } + + while (delay-- > 0) + { + /* Wait for end of vsync. */ + do + { + status = FIELD_GET(PEEK32(SYSTEM_CTRL), + SYSTEM_CTRL, + PANEL_VSYNC); + } + while (status == SYSTEM_CTRL_PANEL_VSYNC_ACTIVE); + + /* Wait for start of vsync. */ + do + { + status = FIELD_GET(PEEK32(SYSTEM_CTRL), + SYSTEM_CTRL, + PANEL_VSYNC); + } + while (status == SYSTEM_CTRL_PANEL_VSYNC_INACTIVE); + } + + }else{ + + /* Do not wait when the Primary PLL is off or display control is already off. + This will prevent the software to wait forever. */ + if ((FIELD_GET(PEEK32(CRT_PLL_CTRL), CRT_PLL_CTRL, POWER) == + CRT_PLL_CTRL_POWER_OFF) || + (FIELD_GET(PEEK32(CRT_DISPLAY_CTRL), CRT_DISPLAY_CTRL, TIMING) == + CRT_DISPLAY_CTRL_TIMING_DISABLE)) + { + return; + } + + while (delay-- > 0) + { + /* Wait for end of vsync. */ + do + { + status = FIELD_GET(PEEK32(SYSTEM_CTRL), + SYSTEM_CTRL, + CRT_VSYNC); + } + while (status == SYSTEM_CTRL_CRT_VSYNC_ACTIVE); + + /* Wait for start of vsync. */ + do + { + status = FIELD_GET(PEEK32(SYSTEM_CTRL), + SYSTEM_CTRL, + CRT_VSYNC); + } + while (status == SYSTEM_CTRL_CRT_VSYNC_INACTIVE); + } + } +} + +static void swPanelPowerSequence_sm750le(int disp,int delay) +{ + unsigned int reg; + reg = PEEK32(DISPLAY_CONTROL_750LE); + if(disp) + reg |= 0xf; + else + reg &= ~0xf; + POKE32(DISPLAY_CONTROL_750LE,reg); +} + +static void swPanelPowerSequence(int disp,int delay) +{ + unsigned int reg; + + /* disp should be 1 to open sequence */ + reg = PEEK32(PANEL_DISPLAY_CTRL); + reg = FIELD_VALUE(reg,PANEL_DISPLAY_CTRL,FPEN,disp); + POKE32(PANEL_DISPLAY_CTRL,reg); + primaryWaitVerticalSync(delay); + + + reg = PEEK32(PANEL_DISPLAY_CTRL); + reg = FIELD_VALUE(reg,PANEL_DISPLAY_CTRL,DATA,disp); + POKE32(PANEL_DISPLAY_CTRL,reg); + primaryWaitVerticalSync(delay); + + reg = PEEK32(PANEL_DISPLAY_CTRL); + reg = FIELD_VALUE(reg,PANEL_DISPLAY_CTRL,VBIASEN,disp); + POKE32(PANEL_DISPLAY_CTRL,reg); + primaryWaitVerticalSync(delay); + + + reg = PEEK32(PANEL_DISPLAY_CTRL); + reg = FIELD_VALUE(reg,PANEL_DISPLAY_CTRL,FPEN,disp); + POKE32(PANEL_DISPLAY_CTRL,reg); + primaryWaitVerticalSync(delay); + +} + +void ddk750_setLogicalDispOut(disp_output_t output) +{ + unsigned int reg; + if(output & PNL_2_USAGE){ + /* set panel path controller select */ + reg = PEEK32(PANEL_DISPLAY_CTRL); + reg = FIELD_VALUE(reg,PANEL_DISPLAY_CTRL,SELECT,(output & PNL_2_MASK)>>PNL_2_OFFSET); + POKE32(PANEL_DISPLAY_CTRL,reg); + } + + if(output & CRT_2_USAGE){ + /* set crt path controller select */ + reg = PEEK32(CRT_DISPLAY_CTRL); + reg = FIELD_VALUE(reg,CRT_DISPLAY_CTRL,SELECT,(output & CRT_2_MASK)>>CRT_2_OFFSET); + /*se blank off */ + reg = FIELD_SET(reg,CRT_DISPLAY_CTRL,BLANK,OFF); + POKE32(CRT_DISPLAY_CTRL,reg); + + } + + if(output & PRI_TP_USAGE){ + /* set primary timing and plane en_bit */ + setDisplayControl(0,(output&PRI_TP_MASK)>>PRI_TP_OFFSET); + } + + if(output & SEC_TP_USAGE){ + /* set secondary timing and plane en_bit*/ + setDisplayControl(1,(output&SEC_TP_MASK)>>SEC_TP_OFFSET); + } + + if(output & PNL_SEQ_USAGE){ + /* set panel sequence */ + swPanelPowerSequence((output&PNL_SEQ_MASK)>>PNL_SEQ_OFFSET,4); + } + + if(output & DAC_USAGE) + setDAC((output & DAC_MASK)>>DAC_OFFSET); + + if(output & DPMS_USAGE) + ddk750_setDPMS((output & DPMS_MASK) >> DPMS_OFFSET); +} + + +int ddk750_initDVIDisp() +{ + /* Initialize DVI. If the dviInit fail and the VendorID or the DeviceID are + not zeroed, then set the failure flag. If it is zeroe, it might mean + that the system is in Dual CRT Monitor configuration. */ + + /* De-skew enabled with default 111b value. + This will fix some artifacts problem in some mode on board 2.2. + Somehow this fix does not affect board 2.1. + */ + if ((dviInit(1, /* Select Rising Edge */ + 1, /* Select 24-bit bus */ + 0, /* Select Single Edge clock */ + 1, /* Enable HSync as is */ + 1, /* Enable VSync as is */ + 1, /* Enable De-skew */ + 7, /* Set the de-skew setting to maximum setup */ + 1, /* Enable continuous Sync */ + 1, /* Enable PLL Filter */ + 4 /* Use the recommended value for PLL Filter value */ + ) != 0) && (dviGetVendorID() != 0x0000) && (dviGetDeviceID() != 0x0000)) + { + return (-1); + } + + /* TODO: Initialize other display component */ + + /* Success */ + return 0; + +} + diff --git a/drivers/staging/sm750fb/ddk750_display.h b/drivers/staging/sm750fb/ddk750_display.h new file mode 100644 index 000000000000..ae0f84c68de5 --- /dev/null +++ b/drivers/staging/sm750fb/ddk750_display.h @@ -0,0 +1,160 @@ +#ifndef DDK750_DISPLAY_H__ +#define DDK750_DISPLAY_H__ + +/* panel path select + 80000[29:28] +*/ + +#define PNL_2_OFFSET 0 +#define PNL_2_MASK (3 << PNL_2_OFFSET) +#define PNL_2_USAGE (PNL_2_MASK << 16) +#define PNL_2_PRI ((0 << PNL_2_OFFSET)|PNL_2_USAGE) +#define PNL_2_SEC ((2 << PNL_2_OFFSET)|PNL_2_USAGE) + + +/* primary timing & plane enable bit + 1: 80000[8] & 80000[2] on + 0: both off +*/ +#define PRI_TP_OFFSET 4 +#define PRI_TP_MASK (1 << PRI_TP_OFFSET) +#define PRI_TP_USAGE (PRI_TP_MASK << 16) +#define PRI_TP_ON ((0x1 << PRI_TP_OFFSET)|PRI_TP_USAGE) +#define PRI_TP_OFF ((0x0 << PRI_TP_OFFSET)|PRI_TP_USAGE) + + +/* panel sequency status + 80000[27:24] +*/ +#define PNL_SEQ_OFFSET 6 +#define PNL_SEQ_MASK (1 << PNL_SEQ_OFFSET) +#define PNL_SEQ_USAGE (PNL_SEQ_MASK << 16) +#define PNL_SEQ_ON ((1 << PNL_SEQ_OFFSET)|PNL_SEQ_USAGE) +#define PNL_SEQ_OFF ((0 << PNL_SEQ_OFFSET)|PNL_SEQ_USAGE) + +/* dual digital output + 80000[19] +*/ +#define DUAL_TFT_OFFSET 8 +#define DUAL_TFT_MASK (1 << DUAL_TFT_OFFSET) +#define DUAL_TFT_USAGE (DUAL_TFT_MASK << 16) +#define DUAL_TFT_ON ((1 << DUAL_TFT_OFFSET)|DUAL_TFT_USAGE) +#define DUAL_TFT_OFF ((0 << DUAL_TFT_OFFSET)|DUAL_TFT_USAGE) + +/* secondary timing & plane enable bit + 1:80200[8] & 80200[2] on + 0: both off +*/ +#define SEC_TP_OFFSET 5 +#define SEC_TP_MASK (1<< SEC_TP_OFFSET) +#define SEC_TP_USAGE (SEC_TP_MASK << 16) +#define SEC_TP_ON ((0x1 << SEC_TP_OFFSET)|SEC_TP_USAGE) +#define SEC_TP_OFF ((0x0 << SEC_TP_OFFSET)|SEC_TP_USAGE) + +/* crt path select + 80200[19:18] +*/ +#define CRT_2_OFFSET 2 +#define CRT_2_MASK (3 << CRT_2_OFFSET) +#define CRT_2_USAGE (CRT_2_MASK << 16) +#define CRT_2_PRI ((0x0 << CRT_2_OFFSET)|CRT_2_USAGE) +#define CRT_2_SEC ((0x2 << CRT_2_OFFSET)|CRT_2_USAGE) + + +/* DAC affect both DVI and DSUB + 4[20] +*/ +#define DAC_OFFSET 7 +#define DAC_MASK (1 << DAC_OFFSET) +#define DAC_USAGE (DAC_MASK << 16) +#define DAC_ON ((0x0<< DAC_OFFSET)|DAC_USAGE) +#define DAC_OFF ((0x1 << DAC_OFFSET)|DAC_USAGE) + +/* DPMS only affect D-SUB head + 0[31:30] +*/ +#define DPMS_OFFSET 9 +#define DPMS_MASK (3 << DPMS_OFFSET) +#define DPMS_USAGE (DPMS_MASK << 16) +#define DPMS_OFF ((3 << DPMS_OFFSET)|DPMS_USAGE) +#define DPMS_ON ((0 << DPMS_OFFSET)|DPMS_USAGE) + + + +/* + LCD1 means panel path TFT1 & panel path DVI (so enable DAC) + CRT means crt path DSUB +*/ +#if 0 +typedef enum _disp_output_t +{ + NO_DISPLAY = DPMS_OFF, + + LCD1_PRI = PNL_2_PRI|PRI_TP_ON|PNL_SEQ_ON|DPMS_OFF|DAC_ON, + LCD1_SEC = PNL_2_SEC|SEC_TP_ON|PNL_SEQ_ON|DPMS_OFF|DAC_ON, + + LCD2_PRI = CRT_2_PRI|PRI_TP_ON|DUAL_TFT_ON|DPMS_OFF, + LCD2_SEC = CRT_2_SEC|SEC_TP_ON|DUAL_TFT_ON|DPMS_OFF, + + DSUB_PRI = CRT_2_PRI|PRI_TP_ON|DAC_ON, + DSUB_SEC = CRT_2_SEC|SEC_TP_ON|DAC_ON, + + LCD1_DSUB_PRI = PNL_2_PRI|PRI_TP_ON|PNL_SEQ_ON| + CRT_2_PRI|SEC_TP_OFF|DAC_ON, + + LCD1_DSUB_SEC = PNL_2_SEC|SEC_TP_ON|PNL_SEQ_ON| + CRT_2_SEC|PRI_TP_OFF|DAC_ON, + + /* LCD1 show primary and DSUB show secondary */ + LCD1_DSUB_DUAL = PNL_2_PRI|PRI_TP_ON|PNL_SEQ_ON| + CRT_2_SEC|SEC_TP_ON|DAC_ON, + + /* LCD1 show secondary and DSUB show primary */ + LCD1_DSUB_DUAL_SWAP = PNL_2_SEC|SEC_TP_ON|PNL_SEQ_ON| + CRT_2_PRI|PRI_TP_ON|DAC_ON, + + LCD1_LCD2_PRI = PNL_2_PRI|PRI_TP_ON|PNL_SEQ_ON| + CRT_2_PRI|SEC_TP_OFF|DPMS_OFF|DUAL_TFT_ON, + + LCD1_LCD2_SEC = PNL_2_SEC|SEC_TP_ON|PNL_SEQ_ON| + CRT_2_SEC|PRI_TP_OFF|DPMS_OFF|DUAL_TFT_ON, + + LCD1_LCD2_DSUB_PRI = PNL_2_PRI|PRI_TP_ON|PNL_SEQ_ON|DAC_ON| + CRT_2_PRI|SEC_TP_OFF|DPMS_ON|DUAL_TFT_ON, + + LCD1_LCD2_DSUB_SEC = PNL_2_SEC|SEC_TP_ON|PNL_SEQ_ON|DAC_ON| + CRT_2_SEC|PRI_TP_OFF|DPMS_ON|DUAL_TFT_ON, + + +} +disp_output_t; +#else +typedef enum _disp_output_t{ + do_LCD1_PRI = PNL_2_PRI|PRI_TP_ON|PNL_SEQ_ON|DAC_ON, + do_LCD1_SEC = PNL_2_SEC|SEC_TP_ON|PNL_SEQ_ON|DAC_ON, +#if 0 + do_LCD2_PRI = CRT_2_PRI|PRI_TP_ON, + do_LCD2_SEC = CRT_2_SEC|SEC_TP_ON, +#else + do_LCD2_PRI = CRT_2_PRI|PRI_TP_ON|DUAL_TFT_ON, + do_LCD2_SEC = CRT_2_SEC|SEC_TP_ON|DUAL_TFT_ON, +#endif + /* + do_DSUB_PRI = CRT_2_PRI|PRI_TP_ON|DPMS_ON|DAC_ON, + do_DSUB_SEC = CRT_2_SEC|SEC_TP_ON|DPMS_ON|DAC_ON, + */ +#if 0 + do_CRT_PRI = CRT_2_PRI|PRI_TP_ON, + do_CRT_SEC = CRT_2_SEC|SEC_TP_ON, +#else + do_CRT_PRI = CRT_2_PRI|PRI_TP_ON|DPMS_ON|DAC_ON, + do_CRT_SEC = CRT_2_SEC|SEC_TP_ON|DPMS_ON|DAC_ON, +#endif +} +disp_output_t; +#endif + +void ddk750_setLogicalDispOut(disp_output_t); +int ddk750_initDVIDisp(void); + +#endif diff --git a/drivers/staging/sm750fb/ddk750_dvi.c b/drivers/staging/sm750fb/ddk750_dvi.c new file mode 100644 index 000000000000..1c083e7dc710 --- /dev/null +++ b/drivers/staging/sm750fb/ddk750_dvi.c @@ -0,0 +1,99 @@ +#define USE_DVICHIP +#ifdef USE_DVICHIP +#include "ddk750_help.h" +#include "ddk750_reg.h" +#include "ddk750_dvi.h" +#include "ddk750_sii164.h" + + +/* This global variable contains all the supported driver and its corresponding + function API. Please set the function pointer to NULL whenever the function + is not supported. */ +static dvi_ctrl_device_t g_dcftSupportedDviController[] = +{ +#ifdef DVI_CTRL_SII164 + { + .pfnInit = sii164InitChip, + .pfnGetVendorId = sii164GetVendorID, + .pfnGetDeviceId = sii164GetDeviceID, +#ifdef SII164_FULL_FUNCTIONS + .pfnResetChip = sii164ResetChip, + .pfnGetChipString = sii164GetChipString, + .pfnSetPower = sii164SetPower, + .pfnEnableHotPlugDetection = sii164EnableHotPlugDetection, + .pfnIsConnected = sii164IsConnected, + .pfnCheckInterrupt = sii164CheckInterrupt, + .pfnClearInterrupt = sii164ClearInterrupt, +#endif + }, +#endif +}; + + +int dviInit( + unsigned char edgeSelect, + unsigned char busSelect, + unsigned char dualEdgeClkSelect, + unsigned char hsyncEnable, + unsigned char vsyncEnable, + unsigned char deskewEnable, + unsigned char deskewSetting, + unsigned char continuousSyncEnable, + unsigned char pllFilterEnable, + unsigned char pllFilterValue + ) +{ + dvi_ctrl_device_t *pCurrentDviCtrl; + pCurrentDviCtrl = g_dcftSupportedDviController; + if(pCurrentDviCtrl->pfnInit != NULL) + { + return pCurrentDviCtrl->pfnInit(edgeSelect, busSelect, dualEdgeClkSelect, hsyncEnable, + vsyncEnable, deskewEnable, deskewSetting, continuousSyncEnable, + pllFilterEnable, pllFilterValue); + } + return -1;//error +} + + +/* + * dviGetVendorID + * This function gets the vendor ID of the DVI controller chip. + * + * Output: + * Vendor ID + */ +unsigned short dviGetVendorID() +{ + dvi_ctrl_device_t *pCurrentDviCtrl; + + //pCurrentDviCtrl = getDviCtrl(); + pCurrentDviCtrl = g_dcftSupportedDviController; + if (pCurrentDviCtrl != (dvi_ctrl_device_t *)0) + return pCurrentDviCtrl->pfnGetVendorId(); + + return 0x0000; +} + + +/* + * dviGetDeviceID + * This function gets the device ID of the DVI controller chip. + * + * Output: + * Device ID + */ +unsigned short dviGetDeviceID() +{ + dvi_ctrl_device_t *pCurrentDviCtrl; + +// pCurrentDviCtrl = getDviCtrl(); + pCurrentDviCtrl = g_dcftSupportedDviController; + if (pCurrentDviCtrl != (dvi_ctrl_device_t *)0) + return pCurrentDviCtrl->pfnGetDeviceId(); + + return 0x0000; +} + +#endif + + diff --git a/drivers/staging/sm750fb/ddk750_dvi.h b/drivers/staging/sm750fb/ddk750_dvi.h new file mode 100644 index 000000000000..50bcec29b2c0 --- /dev/null +++ b/drivers/staging/sm750fb/ddk750_dvi.h @@ -0,0 +1,67 @@ +#ifndef DDK750_DVI_H__ +#define DDK750_DVI_H__ + +/* dvi chip stuffs structros */ + +typedef long (*PFN_DVICTRL_INIT)( + unsigned char edgeSelect, + unsigned char busSelect, + unsigned char dualEdgeClkSelect, + unsigned char hsyncEnable, + unsigned char vsyncEnable, + unsigned char deskewEnable, + unsigned char deskewSetting, + unsigned char continuousSyncEnable, + unsigned char pllFilterEnable, + unsigned char pllFilterValue); +typedef void (*PFN_DVICTRL_RESETCHIP)(void); +typedef char* (*PFN_DVICTRL_GETCHIPSTRING)(void); +typedef unsigned short (*PFN_DVICTRL_GETVENDORID)(void); +typedef unsigned short (*PFN_DVICTRL_GETDEVICEID)(void); +typedef void (*PFN_DVICTRL_SETPOWER)(unsigned char powerUp); +typedef void (*PFN_DVICTRL_HOTPLUGDETECTION)(unsigned char enableHotPlug); +typedef unsigned char (*PFN_DVICTRL_ISCONNECTED)(void); +typedef unsigned char (*PFN_DVICTRL_CHECKINTERRUPT)(void); +typedef void (*PFN_DVICTRL_CLEARINTERRUPT)(void); + + + +/* Structure to hold all the function pointer to the DVI Controller. */ +typedef struct _dvi_ctrl_device_t +{ + PFN_DVICTRL_INIT pfnInit; + PFN_DVICTRL_RESETCHIP pfnResetChip; + PFN_DVICTRL_GETCHIPSTRING pfnGetChipString; + PFN_DVICTRL_GETVENDORID pfnGetVendorId; + PFN_DVICTRL_GETDEVICEID pfnGetDeviceId; + PFN_DVICTRL_SETPOWER pfnSetPower; + PFN_DVICTRL_HOTPLUGDETECTION pfnEnableHotPlugDetection; + PFN_DVICTRL_ISCONNECTED pfnIsConnected; + PFN_DVICTRL_CHECKINTERRUPT pfnCheckInterrupt; + PFN_DVICTRL_CLEARINTERRUPT pfnClearInterrupt; +} dvi_ctrl_device_t; +#define DVI_CTRL_SII164 + + + +/* dvi functions prototype */ +int dviInit( + unsigned char edgeSelect, + unsigned char busSelect, + unsigned char dualEdgeClkSelect, + unsigned char hsyncEnable, + unsigned char vsyncEnable, + unsigned char deskewEnable, + unsigned char deskewSetting, + unsigned char continuousSyncEnable, + unsigned char pllFilterEnable, + unsigned char pllFilterValue +); + +unsigned short dviGetVendorID(void); +unsigned short dviGetDeviceID(void); + + + +#endif + diff --git a/drivers/staging/sm750fb/ddk750_help.c b/drivers/staging/sm750fb/ddk750_help.c new file mode 100644 index 000000000000..cc00d2b32436 --- /dev/null +++ b/drivers/staging/sm750fb/ddk750_help.c @@ -0,0 +1,19 @@ +//#include "ddk750_reg.h" +//#include "ddk750_chip.h" +#include "ddk750_help.h" + +volatile unsigned char __iomem * mmio750 = NULL; +char revId750 = 0; +unsigned short devId750 = 0; + +/* after driver mapped io registers, use this function first */ +void ddk750_set_mmio(volatile unsigned char * addr,unsigned short devId,char revId) +{ + mmio750 = addr; + devId750 = devId; + revId750 = revId; + if(revId == 0xfe) + printk("found sm750le\n"); +} + + diff --git a/drivers/staging/sm750fb/ddk750_help.h b/drivers/staging/sm750fb/ddk750_help.h new file mode 100644 index 000000000000..4fc93b5d41c7 --- /dev/null +++ b/drivers/staging/sm750fb/ddk750_help.h @@ -0,0 +1,29 @@ +#ifndef DDK750_HELP_H__ +#define DDK750_HELP_H__ +#include "ddk750_chip.h" +#ifndef USE_INTERNAL_REGISTER_ACCESS + +#include +#include +#include +#include "sm750_help.h" + + +#if 0 +/* if 718 big endian turned on,be aware that don't use this driver for general use,only for ppc big-endian */ +#warning "big endian on target cpu and enable nature big endian support of 718 capability !" +#define PEEK32(addr) __raw_readl((void __iomem *)(mmio750)+(addr)) +#define POKE32(addr,data) __raw_writel((data),(void __iomem*)(mmio750)+(addr)) +#else /* software control endianess */ +#define PEEK32(addr) readl((addr)+mmio750) +#define POKE32(addr,data) writel((data),(addr)+mmio750) +#endif + +extern volatile unsigned char __iomem * mmio750; +extern char revId750; +extern unsigned short devId750; +#else +/* implement if you want use it*/ +#endif + +#endif diff --git a/drivers/staging/sm750fb/ddk750_hwi2c.c b/drivers/staging/sm750fb/ddk750_hwi2c.c new file mode 100644 index 000000000000..84dfb6f41142 --- /dev/null +++ b/drivers/staging/sm750fb/ddk750_hwi2c.c @@ -0,0 +1,271 @@ +#define USE_HW_I2C +#ifdef USE_HW_I2C +#include "ddk750_help.h" +#include "ddk750_reg.h" +#include "ddk750_hwi2c.h" +#include "ddk750_power.h" + +#define MAX_HWI2C_FIFO 16 +#define HWI2C_WAIT_TIMEOUT 0xF0000 + + +int hwI2CInit( + unsigned char busSpeedMode +) +{ + unsigned int value; + + /* Enable GPIO 30 & 31 as IIC clock & data */ + value = PEEK32(GPIO_MUX); + + value = FIELD_SET(value, GPIO_MUX, 30, I2C) | + FIELD_SET(0, GPIO_MUX, 31, I2C); + POKE32(GPIO_MUX, value); + + /* Enable Hardware I2C power. + TODO: Check if we need to enable GPIO power? + */ + enableI2C(1); + + /* Enable the I2C Controller and set the bus speed mode */ + value = PEEK32(I2C_CTRL); + if (busSpeedMode == 0) + value = FIELD_SET(value, I2C_CTRL, MODE, STANDARD); + else + value = FIELD_SET(value, I2C_CTRL, MODE, FAST); + value = FIELD_SET(value, I2C_CTRL, EN, ENABLE); + POKE32(I2C_CTRL, value); + + return 0; +} + + +void hwI2CClose(void) +{ + unsigned int value; + + /* Disable I2C controller */ + value = PEEK32(I2C_CTRL); + value = FIELD_SET(value, I2C_CTRL, EN, DISABLE); + POKE32(I2C_CTRL, value); + + /* Disable I2C Power */ + enableI2C(0); + + /* Set GPIO 30 & 31 back as GPIO pins */ + value = PEEK32(GPIO_MUX); + value = FIELD_SET(value, GPIO_MUX, 30, GPIO); + value = FIELD_SET(value, GPIO_MUX, 31, GPIO); + POKE32(GPIO_MUX, value); +} + + +long hwI2CWaitTXDone(void) +{ + unsigned int timeout; + + /* Wait until the transfer is completed. */ + timeout = HWI2C_WAIT_TIMEOUT; + while ((FIELD_GET(PEEK32(I2C_STATUS), I2C_STATUS, TX) != I2C_STATUS_TX_COMPLETED) && + (timeout != 0)) + timeout--; + + if (timeout == 0) + return (-1); + + return 0; +} + + + +/* + * This function writes data to the i2c slave device registers. + * + * Parameters: + * deviceAddress - i2c Slave device address + * length - Total number of bytes to be written to the device + * pBuffer - The buffer that contains the data to be written to the + * i2c device. + * + * Return Value: + * Total number of bytes those are actually written. + */ +unsigned int hwI2CWriteData( + unsigned char deviceAddress, + unsigned int length, + unsigned char *pBuffer +) +{ + unsigned char count, i; + unsigned int totalBytes = 0; + + /* Set the Device Address */ + POKE32(I2C_SLAVE_ADDRESS, deviceAddress & ~0x01); + + /* Write data. + * Note: + * Only 16 byte can be accessed per i2c start instruction. + */ + do + { + /* Reset I2C by writing 0 to I2C_RESET register to clear the previous status. */ + POKE32(I2C_RESET, 0); + + /* Set the number of bytes to be written */ + if (length < MAX_HWI2C_FIFO) + count = length - 1; + else + count = MAX_HWI2C_FIFO - 1; + POKE32(I2C_BYTE_COUNT, count); + + /* Move the data to the I2C data register */ + for (i = 0; i <= count; i++) + POKE32(I2C_DATA0 + i, *pBuffer++); + + /* Start the I2C */ + POKE32(I2C_CTRL, FIELD_SET(PEEK32(I2C_CTRL), I2C_CTRL, CTRL, START)); + + /* Wait until the transfer is completed. */ + if (hwI2CWaitTXDone() != 0) + break; + + /* Substract length */ + length -= (count + 1); + + /* Total byte written */ + totalBytes += (count + 1); + + } while (length > 0); + + return totalBytes; +} + + + + +/* + * This function reads data from the slave device and stores them + * in the given buffer + * + * Parameters: + * deviceAddress - i2c Slave device address + * length - Total number of bytes to be read + * pBuffer - Pointer to a buffer to be filled with the data read + * from the slave device. It has to be the same size as the + * length to make sure that it can keep all the data read. + * + * Return Value: + * Total number of actual bytes read from the slave device + */ +unsigned int hwI2CReadData( + unsigned char deviceAddress, + unsigned int length, + unsigned char *pBuffer +) +{ + unsigned char count, i; + unsigned int totalBytes = 0; + + /* Set the Device Address */ + POKE32(I2C_SLAVE_ADDRESS, deviceAddress | 0x01); + + /* Read data and save them to the buffer. + * Note: + * Only 16 byte can be accessed per i2c start instruction. + */ + do + { + /* Reset I2C by writing 0 to I2C_RESET register to clear all the status. */ + POKE32(I2C_RESET, 0); + + /* Set the number of bytes to be read */ + if (length <= MAX_HWI2C_FIFO) + count = length - 1; + else + count = MAX_HWI2C_FIFO - 1; + POKE32(I2C_BYTE_COUNT, count); + + /* Start the I2C */ + POKE32(I2C_CTRL, FIELD_SET(PEEK32(I2C_CTRL), I2C_CTRL, CTRL, START)); + + /* Wait until transaction done. */ + if (hwI2CWaitTXDone() != 0) + break; + + /* Save the data to the given buffer */ + for (i = 0; i <= count; i++) + *pBuffer++ = PEEK32(I2C_DATA0 + i); + + /* Substract length by 16 */ + length -= (count + 1); + + /* Number of bytes read. */ + totalBytes += (count + 1); + + } while (length > 0); + + return totalBytes; +} + + + + +/* + * This function reads the slave device's register + * + * Parameters: + * deviceAddress - i2c Slave device address which register + * to be read from + * registerIndex - Slave device's register to be read + * + * Return Value: + * Register value + */ +unsigned char hwI2CReadReg( + unsigned char deviceAddress, + unsigned char registerIndex +) +{ + unsigned char value = (0xFF); + + if (hwI2CWriteData(deviceAddress, 1, ®isterIndex) == 1) + hwI2CReadData(deviceAddress, 1, &value); + + return value; +} + + + + + +/* + * This function writes a value to the slave device's register + * + * Parameters: + * deviceAddress - i2c Slave device address which register + * to be written + * registerIndex - Slave device's register to be written + * data - Data to be written to the register + * + * Result: + * 0 - Success + * -1 - Fail + */ +int hwI2CWriteReg( + unsigned char deviceAddress, + unsigned char registerIndex, + unsigned char data +) +{ + unsigned char value[2]; + + value[0] = registerIndex; + value[1] = data; + if (hwI2CWriteData(deviceAddress, 2, value) == 2) + return 0; + + return (-1); +} + + +#endif diff --git a/drivers/staging/sm750fb/ddk750_hwi2c.h b/drivers/staging/sm750fb/ddk750_hwi2c.h new file mode 100644 index 000000000000..ad311493c9fc --- /dev/null +++ b/drivers/staging/sm750fb/ddk750_hwi2c.h @@ -0,0 +1,10 @@ +#ifndef DDK750_HWI2C_H__ +#define DDK750_HWI2C_H__ + +/* hwi2c functions */ +int hwI2CInit(unsigned char busSpeedMode); +void hwI2CClose(void); + +unsigned char hwI2CReadReg(unsigned char deviceAddress,unsigned char registerIndex); +int hwI2CWriteReg(unsigned char deviceAddress,unsigned char registerIndex,unsigned char data); +#endif diff --git a/drivers/staging/sm750fb/ddk750_mode.c b/drivers/staging/sm750fb/ddk750_mode.c new file mode 100644 index 000000000000..2e418fb6ffde --- /dev/null +++ b/drivers/staging/sm750fb/ddk750_mode.c @@ -0,0 +1,205 @@ + +#include "ddk750_help.h" +#include "ddk750_reg.h" +#include "ddk750_mode.h" +#include "ddk750_chip.h" + +/* + SM750LE only: + This function takes care extra registers and bit fields required to set + up a mode in SM750LE + + Explanation about Display Control register: + HW only supports 7 predefined pixel clocks, and clock select is + in bit 29:27 of Display Control register. +*/ +static unsigned long displayControlAdjust_SM750LE(mode_parameter_t *pModeParam, unsigned long dispControl) +{ + unsigned long x, y; + + x = pModeParam->horizontal_display_end; + y = pModeParam->vertical_display_end; + + /* SM750LE has to set up the top-left and bottom-right + registers as well. + Note that normal SM750/SM718 only use those two register for + auto-centering mode. + */ + POKE32(CRT_AUTO_CENTERING_TL, + FIELD_VALUE(0, CRT_AUTO_CENTERING_TL, TOP, 0) + | FIELD_VALUE(0, CRT_AUTO_CENTERING_TL, LEFT, 0)); + + POKE32(CRT_AUTO_CENTERING_BR, + FIELD_VALUE(0, CRT_AUTO_CENTERING_BR, BOTTOM, y-1) + | FIELD_VALUE(0, CRT_AUTO_CENTERING_BR, RIGHT, x-1)); + + /* Assume common fields in dispControl have been properly set before + calling this function. + This function only sets the extra fields in dispControl. + */ + + /* Clear bit 29:27 of display control register */ + dispControl &= FIELD_CLEAR(CRT_DISPLAY_CTRL, CLK); + + /* Set bit 29:27 of display control register for the right clock */ + /* Note that SM750LE only need to supported 7 resoluitons. */ + if ( x == 800 && y == 600 ) + dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL41); + else if (x == 1024 && y == 768) + dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL65); + else if (x == 1152 && y == 864) + dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL80); + else if (x == 1280 && y == 768) + dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL80); + else if (x == 1280 && y == 720) + dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL74); + else if (x == 1280 && y == 960) + dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL108); + else if (x == 1280 && y == 1024) + dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL108); + else /* default to VGA clock */ + dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL25); + + /* Set bit 25:24 of display controller */ + dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CRTSELECT, CRT); + dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, RGBBIT, 24BIT); + + /* Set bit 14 of display controller */ + dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLOCK_PHASE, ACTIVE_LOW); + + POKE32(CRT_DISPLAY_CTRL, dispControl); + + return dispControl; +} + + + +/* only timing related registers will be programed */ +static int programModeRegisters(mode_parameter_t * pModeParam,pll_value_t * pll) +{ + int ret = 0; + int cnt = 0; + unsigned int ulTmpValue,ulReg; + if(pll->clockType == SECONDARY_PLL) + { + /* programe secondary pixel clock */ + POKE32(CRT_PLL_CTRL,formatPllReg(pll)); + POKE32(CRT_HORIZONTAL_TOTAL, + FIELD_VALUE(0, CRT_HORIZONTAL_TOTAL, TOTAL, pModeParam->horizontal_total - 1) + | FIELD_VALUE(0, CRT_HORIZONTAL_TOTAL, DISPLAY_END, pModeParam->horizontal_display_end - 1)); + + POKE32(CRT_HORIZONTAL_SYNC, + FIELD_VALUE(0, CRT_HORIZONTAL_SYNC, WIDTH, pModeParam->horizontal_sync_width) + | FIELD_VALUE(0, CRT_HORIZONTAL_SYNC, START, pModeParam->horizontal_sync_start - 1)); + + POKE32(CRT_VERTICAL_TOTAL, + FIELD_VALUE(0, CRT_VERTICAL_TOTAL, TOTAL, pModeParam->vertical_total - 1) + | FIELD_VALUE(0, CRT_VERTICAL_TOTAL, DISPLAY_END, pModeParam->vertical_display_end - 1)); + + POKE32(CRT_VERTICAL_SYNC, + FIELD_VALUE(0, CRT_VERTICAL_SYNC, HEIGHT, pModeParam->vertical_sync_height) + | FIELD_VALUE(0, CRT_VERTICAL_SYNC, START, pModeParam->vertical_sync_start - 1)); + + + ulTmpValue = FIELD_VALUE(0,CRT_DISPLAY_CTRL,VSYNC_PHASE,pModeParam->vertical_sync_polarity)| + FIELD_VALUE(0,CRT_DISPLAY_CTRL,HSYNC_PHASE,pModeParam->horizontal_sync_polarity)| + FIELD_SET(0,CRT_DISPLAY_CTRL,TIMING,ENABLE)| + FIELD_SET(0,CRT_DISPLAY_CTRL,PLANE,ENABLE); + + + if(getChipType() == SM750LE){ + displayControlAdjust_SM750LE(pModeParam,ulTmpValue); + }else{ + ulReg = PEEK32(CRT_DISPLAY_CTRL) + & FIELD_CLEAR(CRT_DISPLAY_CTRL,VSYNC_PHASE) + & FIELD_CLEAR(CRT_DISPLAY_CTRL,HSYNC_PHASE) + & FIELD_CLEAR(CRT_DISPLAY_CTRL,TIMING) + & FIELD_CLEAR(CRT_DISPLAY_CTRL,PLANE); + + POKE32(CRT_DISPLAY_CTRL,ulTmpValue|ulReg); + } + + } + else if(pll->clockType == PRIMARY_PLL) + { + unsigned int ulReservedBits; + POKE32(PANEL_PLL_CTRL,formatPllReg(pll)); + + POKE32(PANEL_HORIZONTAL_TOTAL, + FIELD_VALUE(0, PANEL_HORIZONTAL_TOTAL, TOTAL, pModeParam->horizontal_total - 1) + | FIELD_VALUE(0, PANEL_HORIZONTAL_TOTAL, DISPLAY_END, pModeParam->horizontal_display_end - 1)); + + POKE32(PANEL_HORIZONTAL_SYNC, + FIELD_VALUE(0, PANEL_HORIZONTAL_SYNC, WIDTH, pModeParam->horizontal_sync_width) + | FIELD_VALUE(0, PANEL_HORIZONTAL_SYNC, START, pModeParam->horizontal_sync_start - 1)); + + POKE32(PANEL_VERTICAL_TOTAL, + FIELD_VALUE(0, PANEL_VERTICAL_TOTAL, TOTAL, pModeParam->vertical_total - 1) + | FIELD_VALUE(0, PANEL_VERTICAL_TOTAL, DISPLAY_END, pModeParam->vertical_display_end - 1)); + + POKE32(PANEL_VERTICAL_SYNC, + FIELD_VALUE(0, PANEL_VERTICAL_SYNC, HEIGHT, pModeParam->vertical_sync_height) + | FIELD_VALUE(0, PANEL_VERTICAL_SYNC, START, pModeParam->vertical_sync_start - 1)); + + ulTmpValue = FIELD_VALUE(0,PANEL_DISPLAY_CTRL,VSYNC_PHASE,pModeParam->vertical_sync_polarity)| + FIELD_VALUE(0,PANEL_DISPLAY_CTRL,HSYNC_PHASE,pModeParam->horizontal_sync_polarity)| + FIELD_VALUE(0,PANEL_DISPLAY_CTRL,CLOCK_PHASE,pModeParam->clock_phase_polarity)| + FIELD_SET(0,PANEL_DISPLAY_CTRL,TIMING,ENABLE)| + FIELD_SET(0,PANEL_DISPLAY_CTRL,PLANE,ENABLE); + + ulReservedBits = FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_1_MASK, ENABLE) | + FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_2_MASK, ENABLE) | + FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_3_MASK, ENABLE)| + FIELD_SET(0,PANEL_DISPLAY_CTRL,VSYNC,ACTIVE_LOW); + + ulReg = (PEEK32(PANEL_DISPLAY_CTRL) & ~ulReservedBits) + & FIELD_CLEAR(PANEL_DISPLAY_CTRL, CLOCK_PHASE) + & FIELD_CLEAR(PANEL_DISPLAY_CTRL, VSYNC_PHASE) + & FIELD_CLEAR(PANEL_DISPLAY_CTRL, HSYNC_PHASE) + & FIELD_CLEAR(PANEL_DISPLAY_CTRL, TIMING) + & FIELD_CLEAR(PANEL_DISPLAY_CTRL, PLANE); + + + /* May a hardware bug or just my test chip (not confirmed). + * PANEL_DISPLAY_CTRL register seems requiring few writes + * before a value can be succesfully written in. + * Added some masks to mask out the reserved bits. + * Note: This problem happens by design. The hardware will wait for the + * next vertical sync to turn on/off the plane. + */ + + POKE32(PANEL_DISPLAY_CTRL,ulTmpValue|ulReg); +#if 1 + while((PEEK32(PANEL_DISPLAY_CTRL) & ~ulReservedBits) != (ulTmpValue|ulReg)) + { + cnt++; + if(cnt > 1000) + break; + POKE32(PANEL_DISPLAY_CTRL,ulTmpValue|ulReg); + } +#endif + } + else{ + ret = -1; + } + return ret; +} + +int ddk750_setModeTiming(mode_parameter_t * parm,clock_type_t clock) +{ + pll_value_t pll; + unsigned int uiActualPixelClk; + pll.inputFreq = DEFAULT_INPUT_CLOCK; + pll.clockType = clock; + + uiActualPixelClk = calcPllValue(parm->pixel_clock,&pll); + if(getChipType() == SM750LE){ + /* set graphic mode via IO method */ + outb_p(0x88,0x3d4); + outb_p(0x06,0x3d5); + } + programModeRegisters(parm,&pll); + return 0; +} + + diff --git a/drivers/staging/sm750fb/ddk750_mode.h b/drivers/staging/sm750fb/ddk750_mode.h new file mode 100644 index 000000000000..6f8df96a8b02 --- /dev/null +++ b/drivers/staging/sm750fb/ddk750_mode.h @@ -0,0 +1,43 @@ +#ifndef DDK750_MODE_H__ +#define DDK750_MODE_H__ + +#include "ddk750_chip.h" + +typedef enum _spolarity_t +{ + POS = 0, /* positive */ + NEG, /* negative */ +} +spolarity_t; + + +typedef struct _mode_parameter_t +{ + /* Horizontal timing. */ + unsigned long horizontal_total; + unsigned long horizontal_display_end; + unsigned long horizontal_sync_start; + unsigned long horizontal_sync_width; + spolarity_t horizontal_sync_polarity; + + /* Vertical timing. */ + unsigned long vertical_total; + unsigned long vertical_display_end; + unsigned long vertical_sync_start; + unsigned long vertical_sync_height; + spolarity_t vertical_sync_polarity; + + /* Refresh timing. */ + unsigned long pixel_clock; + unsigned long horizontal_frequency; + unsigned long vertical_frequency; + + /* Clock Phase. This clock phase only applies to Panel. */ + spolarity_t clock_phase_polarity; +} +mode_parameter_t; + +int ddk750_setModeTiming(mode_parameter_t *,clock_type_t); + + +#endif diff --git a/drivers/staging/sm750fb/ddk750_power.c b/drivers/staging/sm750fb/ddk750_power.c new file mode 100644 index 000000000000..98dfcbde1eb6 --- /dev/null +++ b/drivers/staging/sm750fb/ddk750_power.c @@ -0,0 +1,239 @@ +#include "ddk750_help.h" +#include "ddk750_reg.h" +#include "ddk750_power.h" + +void ddk750_setDPMS(DPMS_t state) +{ + unsigned int value; + if(getChipType() == SM750LE){ + value = PEEK32(CRT_DISPLAY_CTRL); + POKE32(CRT_DISPLAY_CTRL,FIELD_VALUE(value,CRT_DISPLAY_CTRL,DPMS,state)); + }else{ + value = PEEK32(SYSTEM_CTRL); + value= FIELD_VALUE(value,SYSTEM_CTRL,DPMS,state); + POKE32(SYSTEM_CTRL, value); + } +} + +unsigned int getPowerMode() +{ + if(getChipType() == SM750LE) + return 0; + return (FIELD_GET(PEEK32(POWER_MODE_CTRL), POWER_MODE_CTRL, MODE)); +} + + +/* + * SM50x can operate in one of three modes: 0, 1 or Sleep. + * On hardware reset, power mode 0 is default. + */ +void setPowerMode(unsigned int powerMode) +{ + unsigned int control_value = 0; + + control_value = PEEK32(POWER_MODE_CTRL); + + if(getChipType() == SM750LE) + return; + + switch (powerMode) + { + case POWER_MODE_CTRL_MODE_MODE0: + control_value = FIELD_SET(control_value, POWER_MODE_CTRL, MODE, MODE0); + break; + + case POWER_MODE_CTRL_MODE_MODE1: + control_value = FIELD_SET(control_value, POWER_MODE_CTRL, MODE, MODE1); + break; + + case POWER_MODE_CTRL_MODE_SLEEP: + control_value = FIELD_SET(control_value, POWER_MODE_CTRL, MODE, SLEEP); + break; + + default: + break; + } + + /* Set up other fields in Power Control Register */ + if (powerMode == POWER_MODE_CTRL_MODE_SLEEP) + { + control_value = +#ifdef VALIDATION_CHIP + FIELD_SET( control_value, POWER_MODE_CTRL, 336CLK, OFF) | +#endif + FIELD_SET( control_value, POWER_MODE_CTRL, OSC_INPUT, OFF); + } + else + { + control_value = +#ifdef VALIDATION_CHIP + FIELD_SET( control_value, POWER_MODE_CTRL, 336CLK, ON) | +#endif + FIELD_SET( control_value, POWER_MODE_CTRL, OSC_INPUT, ON); + } + + /* Program new power mode. */ + POKE32(POWER_MODE_CTRL, control_value); +} + +void setCurrentGate(unsigned int gate) +{ + unsigned int gate_reg; + unsigned int mode; + + /* Get current power mode. */ + mode = getPowerMode(); + + switch (mode) + { + case POWER_MODE_CTRL_MODE_MODE0: + gate_reg = MODE0_GATE; + break; + + case POWER_MODE_CTRL_MODE_MODE1: + gate_reg = MODE1_GATE; + break; + + default: + gate_reg = MODE0_GATE; + break; + } + POKE32(gate_reg, gate); +} + + + +/* + * This function enable/disable the 2D engine. + */ +void enable2DEngine(unsigned int enable) +{ + uint32_t gate; + + gate = PEEK32(CURRENT_GATE); + if (enable) + { + gate = FIELD_SET(gate, CURRENT_GATE, DE, ON); + gate = FIELD_SET(gate, CURRENT_GATE, CSC, ON); + } + else + { + gate = FIELD_SET(gate, CURRENT_GATE, DE, OFF); + gate = FIELD_SET(gate, CURRENT_GATE, CSC, OFF); + } + + setCurrentGate(gate); +} + + +/* + * This function enable/disable the ZV Port. + */ +void enableZVPort(unsigned int enable) +{ + uint32_t gate; + + /* Enable ZV Port Gate */ + gate = PEEK32(CURRENT_GATE); + if (enable) + { + gate = FIELD_SET(gate, CURRENT_GATE, ZVPORT, ON); +#if 1 + /* Using Software I2C */ + gate = FIELD_SET(gate, CURRENT_GATE, GPIO, ON); +#else + /* Using Hardware I2C */ + gate = FIELD_SET(gate, CURRENT_GATE, I2C, ON); +#endif + } + else + { + /* Disable ZV Port Gate. There is no way to know whether the GPIO pins are being used + or not. Therefore, do not disable the GPIO gate. */ + gate = FIELD_SET(gate, CURRENT_GATE, ZVPORT, OFF); + } + + setCurrentGate(gate); +} + + +void enableSSP(unsigned int enable) +{ + uint32_t gate; + + /* Enable SSP Gate */ + gate = PEEK32(CURRENT_GATE); + if (enable) + gate = FIELD_SET(gate, CURRENT_GATE, SSP, ON); + else + gate = FIELD_SET(gate, CURRENT_GATE, SSP, OFF); + + setCurrentGate(gate); +} + +void enableDMA(unsigned int enable) +{ + uint32_t gate; + + /* Enable DMA Gate */ + gate = PEEK32(CURRENT_GATE); + if (enable) + gate = FIELD_SET(gate, CURRENT_GATE, DMA, ON); + else + gate = FIELD_SET(gate, CURRENT_GATE, DMA, OFF); + + setCurrentGate(gate); +} + +/* + * This function enable/disable the GPIO Engine + */ +void enableGPIO(unsigned int enable) +{ + uint32_t gate; + + /* Enable GPIO Gate */ + gate = PEEK32(CURRENT_GATE); + if (enable) + gate = FIELD_SET(gate, CURRENT_GATE, GPIO, ON); + else + gate = FIELD_SET(gate, CURRENT_GATE, GPIO, OFF); + + setCurrentGate(gate); +} + +/* + * This function enable/disable the PWM Engine + */ +void enablePWM(unsigned int enable) +{ + uint32_t gate; + + /* Enable PWM Gate */ + gate = PEEK32(CURRENT_GATE); + if (enable) + gate = FIELD_SET(gate, CURRENT_GATE, PWM, ON); + else + gate = FIELD_SET(gate, CURRENT_GATE, PWM, OFF); + + setCurrentGate(gate); +} + +/* + * This function enable/disable the I2C Engine + */ +void enableI2C(unsigned int enable) +{ + uint32_t gate; + + /* Enable I2C Gate */ + gate = PEEK32(CURRENT_GATE); + if (enable) + gate = FIELD_SET(gate, CURRENT_GATE, I2C, ON); + else + gate = FIELD_SET(gate, CURRENT_GATE, I2C, OFF); + + setCurrentGate(gate); +} + + diff --git a/drivers/staging/sm750fb/ddk750_power.h b/drivers/staging/sm750fb/ddk750_power.h new file mode 100644 index 000000000000..71dc7f980069 --- /dev/null +++ b/drivers/staging/sm750fb/ddk750_power.h @@ -0,0 +1,71 @@ +#ifndef DDK750_POWER_H__ +#define DDK750_POWER_H__ + +typedef enum _DPMS_t +{ + crtDPMS_ON = 0x0, + crtDPMS_STANDBY = 0x1, + crtDPMS_SUSPEND = 0x2, + crtDPMS_OFF = 0x3, +} +DPMS_t; + +#define setDAC(off) \ + { \ + POKE32(MISC_CTRL,FIELD_VALUE(PEEK32(MISC_CTRL), \ + MISC_CTRL, \ + DAC_POWER, \ + off)); \ + } + +void ddk750_setDPMS(DPMS_t); + +unsigned int getPowerMode(void); + +/* + * This function sets the current power mode + */ +void setPowerMode(unsigned int powerMode); + +/* + * This function sets current gate + */ +void setCurrentGate(unsigned int gate); + +/* + * This function enable/disable the 2D engine. + */ +void enable2DEngine(unsigned int enable); + +/* + * This function enable/disable the ZV Port + */ +void enableZVPort(unsigned int enable); + +/* + * This function enable/disable the DMA Engine + */ +void enableDMA(unsigned int enable); + +/* + * This function enable/disable the GPIO Engine + */ +void enableGPIO(unsigned int enable); + +/* + * This function enable/disable the PWM Engine + */ +void enablePWM(unsigned int enable); + +/* + * This function enable/disable the I2C Engine + */ +void enableI2C(unsigned int enable); + +/* + * This function enable/disable the SSP. + */ +void enableSSP(unsigned int enable); + + +#endif diff --git a/drivers/staging/sm750fb/ddk750_reg.h b/drivers/staging/sm750fb/ddk750_reg.h new file mode 100644 index 000000000000..2016f97d2a3d --- /dev/null +++ b/drivers/staging/sm750fb/ddk750_reg.h @@ -0,0 +1,2616 @@ +#ifndef DDK750_REG_H__ +#define DDK750_REG_H__ + +/* New register for SM750LE */ +#define DE_STATE1 0x100054 +#define DE_STATE1_DE_ABORT 0:0 +#define DE_STATE1_DE_ABORT_OFF 0 +#define DE_STATE1_DE_ABORT_ON 1 + +#define DE_STATE2 0x100058 +#define DE_STATE2_DE_FIFO 3:3 +#define DE_STATE2_DE_FIFO_NOTEMPTY 0 +#define DE_STATE2_DE_FIFO_EMPTY 1 +#define DE_STATE2_DE_STATUS 2:2 +#define DE_STATE2_DE_STATUS_IDLE 0 +#define DE_STATE2_DE_STATUS_BUSY 1 +#define DE_STATE2_DE_MEM_FIFO 1:1 +#define DE_STATE2_DE_MEM_FIFO_NOTEMPTY 0 +#define DE_STATE2_DE_MEM_FIFO_EMPTY 1 +#define DE_STATE2_DE_RESERVED 0:0 + + + +#define SYSTEM_CTRL 0x000000 +#define SYSTEM_CTRL_DPMS 31:30 +#define SYSTEM_CTRL_DPMS_VPHP 0 +#define SYSTEM_CTRL_DPMS_VPHN 1 +#define SYSTEM_CTRL_DPMS_VNHP 2 +#define SYSTEM_CTRL_DPMS_VNHN 3 +#define SYSTEM_CTRL_PCI_BURST 29:29 +#define SYSTEM_CTRL_PCI_BURST_OFF 0 +#define SYSTEM_CTRL_PCI_BURST_ON 1 +#define SYSTEM_CTRL_PCI_MASTER 25:25 +#define SYSTEM_CTRL_PCI_MASTER_OFF 0 +#define SYSTEM_CTRL_PCI_MASTER_ON 1 +#define SYSTEM_CTRL_LATENCY_TIMER 24:24 +#define SYSTEM_CTRL_LATENCY_TIMER_ON 0 +#define SYSTEM_CTRL_LATENCY_TIMER_OFF 1 +#define SYSTEM_CTRL_DE_FIFO 23:23 +#define SYSTEM_CTRL_DE_FIFO_NOTEMPTY 0 +#define SYSTEM_CTRL_DE_FIFO_EMPTY 1 +#define SYSTEM_CTRL_DE_STATUS 22:22 +#define SYSTEM_CTRL_DE_STATUS_IDLE 0 +#define SYSTEM_CTRL_DE_STATUS_BUSY 1 +#define SYSTEM_CTRL_DE_MEM_FIFO 21:21 +#define SYSTEM_CTRL_DE_MEM_FIFO_NOTEMPTY 0 +#define SYSTEM_CTRL_DE_MEM_FIFO_EMPTY 1 +#define SYSTEM_CTRL_CSC_STATUS 20:20 +#define SYSTEM_CTRL_CSC_STATUS_IDLE 0 +#define SYSTEM_CTRL_CSC_STATUS_BUSY 1 +#define SYSTEM_CTRL_CRT_VSYNC 19:19 +#define SYSTEM_CTRL_CRT_VSYNC_INACTIVE 0 +#define SYSTEM_CTRL_CRT_VSYNC_ACTIVE 1 +#define SYSTEM_CTRL_PANEL_VSYNC 18:18 +#define SYSTEM_CTRL_PANEL_VSYNC_INACTIVE 0 +#define SYSTEM_CTRL_PANEL_VSYNC_ACTIVE 1 +#define SYSTEM_CTRL_CURRENT_BUFFER 17:17 +#define SYSTEM_CTRL_CURRENT_BUFFER_NORMAL 0 +#define SYSTEM_CTRL_CURRENT_BUFFER_FLIP_PENDING 1 +#define SYSTEM_CTRL_DMA_STATUS 16:16 +#define SYSTEM_CTRL_DMA_STATUS_IDLE 0 +#define SYSTEM_CTRL_DMA_STATUS_BUSY 1 +#define SYSTEM_CTRL_PCI_BURST_READ 15:15 +#define SYSTEM_CTRL_PCI_BURST_READ_OFF 0 +#define SYSTEM_CTRL_PCI_BURST_READ_ON 1 +#define SYSTEM_CTRL_DE_ABORT 13:13 +#define SYSTEM_CTRL_DE_ABORT_OFF 0 +#define SYSTEM_CTRL_DE_ABORT_ON 1 +#define SYSTEM_CTRL_PCI_SUBSYS_ID_LOCK 11:11 +#define SYSTEM_CTRL_PCI_SUBSYS_ID_LOCK_OFF 0 +#define SYSTEM_CTRL_PCI_SUBSYS_ID_LOCK_ON 1 +#define SYSTEM_CTRL_PCI_RETRY 7:7 +#define SYSTEM_CTRL_PCI_RETRY_ON 0 +#define SYSTEM_CTRL_PCI_RETRY_OFF 1 +#define SYSTEM_CTRL_PCI_SLAVE_BURST_READ_SIZE 5:4 +#define SYSTEM_CTRL_PCI_SLAVE_BURST_READ_SIZE_1 0 +#define SYSTEM_CTRL_PCI_SLAVE_BURST_READ_SIZE_2 1 +#define SYSTEM_CTRL_PCI_SLAVE_BURST_READ_SIZE_4 2 +#define SYSTEM_CTRL_PCI_SLAVE_BURST_READ_SIZE_8 3 +#define SYSTEM_CTRL_CRT_TRISTATE 3:3 +#define SYSTEM_CTRL_CRT_TRISTATE_OFF 0 +#define SYSTEM_CTRL_CRT_TRISTATE_ON 1 +#define SYSTEM_CTRL_PCIMEM_TRISTATE 2:2 +#define SYSTEM_CTRL_PCIMEM_TRISTATE_OFF 0 +#define SYSTEM_CTRL_PCIMEM_TRISTATE_ON 1 +#define SYSTEM_CTRL_LOCALMEM_TRISTATE 1:1 +#define SYSTEM_CTRL_LOCALMEM_TRISTATE_OFF 0 +#define SYSTEM_CTRL_LOCALMEM_TRISTATE_ON 1 +#define SYSTEM_CTRL_PANEL_TRISTATE 0:0 +#define SYSTEM_CTRL_PANEL_TRISTATE_OFF 0 +#define SYSTEM_CTRL_PANEL_TRISTATE_ON 1 + +#define MISC_CTRL 0x000004 +#define MISC_CTRL_DRAM_RERESH_COUNT 27:27 +#define MISC_CTRL_DRAM_RERESH_COUNT_1ROW 0 +#define MISC_CTRL_DRAM_RERESH_COUNT_3ROW 1 +#define MISC_CTRL_DRAM_REFRESH_TIME 26:25 +#define MISC_CTRL_DRAM_REFRESH_TIME_8 0 +#define MISC_CTRL_DRAM_REFRESH_TIME_16 1 +#define MISC_CTRL_DRAM_REFRESH_TIME_32 2 +#define MISC_CTRL_DRAM_REFRESH_TIME_64 3 +#define MISC_CTRL_INT_OUTPUT 24:24 +#define MISC_CTRL_INT_OUTPUT_NORMAL 0 +#define MISC_CTRL_INT_OUTPUT_INVERT 1 +#define MISC_CTRL_PLL_CLK_COUNT 23:23 +#define MISC_CTRL_PLL_CLK_COUNT_OFF 0 +#define MISC_CTRL_PLL_CLK_COUNT_ON 1 +#define MISC_CTRL_DAC_POWER 20:20 +#define MISC_CTRL_DAC_POWER_ON 0 +#define MISC_CTRL_DAC_POWER_OFF 1 +#define MISC_CTRL_CLK_SELECT 16:16 +#define MISC_CTRL_CLK_SELECT_OSC 0 +#define MISC_CTRL_CLK_SELECT_TESTCLK 1 +#define MISC_CTRL_DRAM_COLUMN_SIZE 15:14 +#define MISC_CTRL_DRAM_COLUMN_SIZE_256 0 +#define MISC_CTRL_DRAM_COLUMN_SIZE_512 1 +#define MISC_CTRL_DRAM_COLUMN_SIZE_1024 2 +#define MISC_CTRL_LOCALMEM_SIZE 13:12 +#define MISC_CTRL_LOCALMEM_SIZE_8M 3 +#define MISC_CTRL_LOCALMEM_SIZE_16M 0 +#define MISC_CTRL_LOCALMEM_SIZE_32M 1 +#define MISC_CTRL_LOCALMEM_SIZE_64M 2 +#define MISC_CTRL_DRAM_TWTR 11:11 +#define MISC_CTRL_DRAM_TWTR_2CLK 0 +#define MISC_CTRL_DRAM_TWTR_1CLK 1 +#define MISC_CTRL_DRAM_TWR 10:10 +#define MISC_CTRL_DRAM_TWR_3CLK 0 +#define MISC_CTRL_DRAM_TWR_2CLK 1 +#define MISC_CTRL_DRAM_TRP 9:9 +#define MISC_CTRL_DRAM_TRP_3CLK 0 +#define MISC_CTRL_DRAM_TRP_4CLK 1 +#define MISC_CTRL_DRAM_TRFC 8:8 +#define MISC_CTRL_DRAM_TRFC_12CLK 0 +#define MISC_CTRL_DRAM_TRFC_14CLK 1 +#define MISC_CTRL_DRAM_TRAS 7:7 +#define MISC_CTRL_DRAM_TRAS_7CLK 0 +#define MISC_CTRL_DRAM_TRAS_8CLK 1 +#define MISC_CTRL_LOCALMEM_RESET 6:6 +#define MISC_CTRL_LOCALMEM_RESET_RESET 0 +#define MISC_CTRL_LOCALMEM_RESET_NORMAL 1 +#define MISC_CTRL_LOCALMEM_STATE 5:5 +#define MISC_CTRL_LOCALMEM_STATE_ACTIVE 0 +#define MISC_CTRL_LOCALMEM_STATE_INACTIVE 1 +#define MISC_CTRL_CPU_CAS_LATENCY 4:4 +#define MISC_CTRL_CPU_CAS_LATENCY_2CLK 0 +#define MISC_CTRL_CPU_CAS_LATENCY_3CLK 1 +#define MISC_CTRL_DLL 3:3 +#define MISC_CTRL_DLL_ON 0 +#define MISC_CTRL_DLL_OFF 1 +#define MISC_CTRL_DRAM_OUTPUT 2:2 +#define MISC_CTRL_DRAM_OUTPUT_LOW 0 +#define MISC_CTRL_DRAM_OUTPUT_HIGH 1 +#define MISC_CTRL_LOCALMEM_BUS_SIZE 1:1 +#define MISC_CTRL_LOCALMEM_BUS_SIZE_32 0 +#define MISC_CTRL_LOCALMEM_BUS_SIZE_64 1 +#define MISC_CTRL_EMBEDDED_LOCALMEM 0:0 +#define MISC_CTRL_EMBEDDED_LOCALMEM_ON 0 +#define MISC_CTRL_EMBEDDED_LOCALMEM_OFF 1 + +#define GPIO_MUX 0x000008 +#define GPIO_MUX_31 31:31 +#define GPIO_MUX_31_GPIO 0 +#define GPIO_MUX_31_I2C 1 +#define GPIO_MUX_30 30:30 +#define GPIO_MUX_30_GPIO 0 +#define GPIO_MUX_30_I2C 1 +#define GPIO_MUX_29 29:29 +#define GPIO_MUX_29_GPIO 0 +#define GPIO_MUX_29_SSP1 1 +#define GPIO_MUX_28 28:28 +#define GPIO_MUX_28_GPIO 0 +#define GPIO_MUX_28_SSP1 1 +#define GPIO_MUX_27 27:27 +#define GPIO_MUX_27_GPIO 0 +#define GPIO_MUX_27_SSP1 1 +#define GPIO_MUX_26 26:26 +#define GPIO_MUX_26_GPIO 0 +#define GPIO_MUX_26_SSP1 1 +#define GPIO_MUX_25 25:25 +#define GPIO_MUX_25_GPIO 0 +#define GPIO_MUX_25_SSP1 1 +#define GPIO_MUX_24 24:24 +#define GPIO_MUX_24_GPIO 0 +#define GPIO_MUX_24_SSP0 1 +#define GPIO_MUX_23 23:23 +#define GPIO_MUX_23_GPIO 0 +#define GPIO_MUX_23_SSP0 1 +#define GPIO_MUX_22 22:22 +#define GPIO_MUX_22_GPIO 0 +#define GPIO_MUX_22_SSP0 1 +#define GPIO_MUX_21 21:21 +#define GPIO_MUX_21_GPIO 0 +#define GPIO_MUX_21_SSP0 1 +#define GPIO_MUX_20 20:20 +#define GPIO_MUX_20_GPIO 0 +#define GPIO_MUX_20_SSP0 1 +#define GPIO_MUX_19 19:19 +#define GPIO_MUX_19_GPIO 0 +#define GPIO_MUX_19_PWM 1 +#define GPIO_MUX_18 18:18 +#define GPIO_MUX_18_GPIO 0 +#define GPIO_MUX_18_PWM 1 +#define GPIO_MUX_17 17:17 +#define GPIO_MUX_17_GPIO 0 +#define GPIO_MUX_17_PWM 1 +#define GPIO_MUX_16 16:16 +#define GPIO_MUX_16_GPIO_ZVPORT 0 +#define GPIO_MUX_16_TEST_DATA 1 +#define GPIO_MUX_15 15:15 +#define GPIO_MUX_15_GPIO_ZVPORT 0 +#define GPIO_MUX_15_TEST_DATA 1 +#define GPIO_MUX_14 14:14 +#define GPIO_MUX_14_GPIO_ZVPORT 0 +#define GPIO_MUX_14_TEST_DATA 1 +#define GPIO_MUX_13 13:13 +#define GPIO_MUX_13_GPIO_ZVPORT 0 +#define GPIO_MUX_13_TEST_DATA 1 +#define GPIO_MUX_12 12:12 +#define GPIO_MUX_12_GPIO_ZVPORT 0 +#define GPIO_MUX_12_TEST_DATA 1 +#define GPIO_MUX_11 11:11 +#define GPIO_MUX_11_GPIO_ZVPORT 0 +#define GPIO_MUX_11_TEST_DATA 1 +#define GPIO_MUX_10 10:10 +#define GPIO_MUX_10_GPIO_ZVPORT 0 +#define GPIO_MUX_10_TEST_DATA 1 +#define GPIO_MUX_9 9:9 +#define GPIO_MUX_9_GPIO_ZVPORT 0 +#define GPIO_MUX_9_TEST_DATA 1 +#define GPIO_MUX_8 8:8 +#define GPIO_MUX_8_GPIO_ZVPORT 0 +#define GPIO_MUX_8_TEST_DATA 1 +#define GPIO_MUX_7 7:7 +#define GPIO_MUX_7_GPIO_ZVPORT 0 +#define GPIO_MUX_7_TEST_DATA 1 +#define GPIO_MUX_6 6:6 +#define GPIO_MUX_6_GPIO_ZVPORT 0 +#define GPIO_MUX_6_TEST_DATA 1 +#define GPIO_MUX_5 5:5 +#define GPIO_MUX_5_GPIO_ZVPORT 0 +#define GPIO_MUX_5_TEST_DATA 1 +#define GPIO_MUX_4 4:4 +#define GPIO_MUX_4_GPIO_ZVPORT 0 +#define GPIO_MUX_4_TEST_DATA 1 +#define GPIO_MUX_3 3:3 +#define GPIO_MUX_3_GPIO_ZVPORT 0 +#define GPIO_MUX_3_TEST_DATA 1 +#define GPIO_MUX_2 2:2 +#define GPIO_MUX_2_GPIO_ZVPORT 0 +#define GPIO_MUX_2_TEST_DATA 1 +#define GPIO_MUX_1 1:1 +#define GPIO_MUX_1_GPIO_ZVPORT 0 +#define GPIO_MUX_1_TEST_DATA 1 +#define GPIO_MUX_0 0:0 +#define GPIO_MUX_0_GPIO_ZVPORT 0 +#define GPIO_MUX_0_TEST_DATA 1 + +#define LOCALMEM_ARBITRATION 0x00000C +#define LOCALMEM_ARBITRATION_ROTATE 28:28 +#define LOCALMEM_ARBITRATION_ROTATE_OFF 0 +#define LOCALMEM_ARBITRATION_ROTATE_ON 1 +#define LOCALMEM_ARBITRATION_VGA 26:24 +#define LOCALMEM_ARBITRATION_VGA_OFF 0 +#define LOCALMEM_ARBITRATION_VGA_PRIORITY_1 1 +#define LOCALMEM_ARBITRATION_VGA_PRIORITY_2 2 +#define LOCALMEM_ARBITRATION_VGA_PRIORITY_3 3 +#define LOCALMEM_ARBITRATION_VGA_PRIORITY_4 4 +#define LOCALMEM_ARBITRATION_VGA_PRIORITY_5 5 +#define LOCALMEM_ARBITRATION_VGA_PRIORITY_6 6 +#define LOCALMEM_ARBITRATION_VGA_PRIORITY_7 7 +#define LOCALMEM_ARBITRATION_DMA 22:20 +#define LOCALMEM_ARBITRATION_DMA_OFF 0 +#define LOCALMEM_ARBITRATION_DMA_PRIORITY_1 1 +#define LOCALMEM_ARBITRATION_DMA_PRIORITY_2 2 +#define LOCALMEM_ARBITRATION_DMA_PRIORITY_3 3 +#define LOCALMEM_ARBITRATION_DMA_PRIORITY_4 4 +#define LOCALMEM_ARBITRATION_DMA_PRIORITY_5 5 +#define LOCALMEM_ARBITRATION_DMA_PRIORITY_6 6 +#define LOCALMEM_ARBITRATION_DMA_PRIORITY_7 7 +#define LOCALMEM_ARBITRATION_ZVPORT1 18:16 +#define LOCALMEM_ARBITRATION_ZVPORT1_OFF 0 +#define LOCALMEM_ARBITRATION_ZVPORT1_PRIORITY_1 1 +#define LOCALMEM_ARBITRATION_ZVPORT1_PRIORITY_2 2 +#define LOCALMEM_ARBITRATION_ZVPORT1_PRIORITY_3 3 +#define LOCALMEM_ARBITRATION_ZVPORT1_PRIORITY_4 4 +#define LOCALMEM_ARBITRATION_ZVPORT1_PRIORITY_5 5 +#define LOCALMEM_ARBITRATION_ZVPORT1_PRIORITY_6 6 +#define LOCALMEM_ARBITRATION_ZVPORT1_PRIORITY_7 7 +#define LOCALMEM_ARBITRATION_ZVPORT0 14:12 +#define LOCALMEM_ARBITRATION_ZVPORT0_OFF 0 +#define LOCALMEM_ARBITRATION_ZVPORT0_PRIORITY_1 1 +#define LOCALMEM_ARBITRATION_ZVPORT0_PRIORITY_2 2 +#define LOCALMEM_ARBITRATION_ZVPORT0_PRIORITY_3 3 +#define LOCALMEM_ARBITRATION_ZVPORT0_PRIORITY_4 4 +#define LOCALMEM_ARBITRATION_ZVPORT0_PRIORITY_5 5 +#define LOCALMEM_ARBITRATION_ZVPORT0_PRIORITY_6 6 +#define LOCALMEM_ARBITRATION_ZVPORT0_PRIORITY_7 7 +#define LOCALMEM_ARBITRATION_VIDEO 10:8 +#define LOCALMEM_ARBITRATION_VIDEO_OFF 0 +#define LOCALMEM_ARBITRATION_VIDEO_PRIORITY_1 1 +#define LOCALMEM_ARBITRATION_VIDEO_PRIORITY_2 2 +#define LOCALMEM_ARBITRATION_VIDEO_PRIORITY_3 3 +#define LOCALMEM_ARBITRATION_VIDEO_PRIORITY_4 4 +#define LOCALMEM_ARBITRATION_VIDEO_PRIORITY_5 5 +#define LOCALMEM_ARBITRATION_VIDEO_PRIORITY_6 6 +#define LOCALMEM_ARBITRATION_VIDEO_PRIORITY_7 7 +#define LOCALMEM_ARBITRATION_PANEL 6:4 +#define LOCALMEM_ARBITRATION_PANEL_OFF 0 +#define LOCALMEM_ARBITRATION_PANEL_PRIORITY_1 1 +#define LOCALMEM_ARBITRATION_PANEL_PRIORITY_2 2 +#define LOCALMEM_ARBITRATION_PANEL_PRIORITY_3 3 +#define LOCALMEM_ARBITRATION_PANEL_PRIORITY_4 4 +#define LOCALMEM_ARBITRATION_PANEL_PRIORITY_5 5 +#define LOCALMEM_ARBITRATION_PANEL_PRIORITY_6 6 +#define LOCALMEM_ARBITRATION_PANEL_PRIORITY_7 7 +#define LOCALMEM_ARBITRATION_CRT 2:0 +#define LOCALMEM_ARBITRATION_CRT_OFF 0 +#define LOCALMEM_ARBITRATION_CRT_PRIORITY_1 1 +#define LOCALMEM_ARBITRATION_CRT_PRIORITY_2 2 +#define LOCALMEM_ARBITRATION_CRT_PRIORITY_3 3 +#define LOCALMEM_ARBITRATION_CRT_PRIORITY_4 4 +#define LOCALMEM_ARBITRATION_CRT_PRIORITY_5 5 +#define LOCALMEM_ARBITRATION_CRT_PRIORITY_6 6 +#define LOCALMEM_ARBITRATION_CRT_PRIORITY_7 7 + +#define PCIMEM_ARBITRATION 0x000010 +#define PCIMEM_ARBITRATION_ROTATE 28:28 +#define PCIMEM_ARBITRATION_ROTATE_OFF 0 +#define PCIMEM_ARBITRATION_ROTATE_ON 1 +#define PCIMEM_ARBITRATION_VGA 26:24 +#define PCIMEM_ARBITRATION_VGA_OFF 0 +#define PCIMEM_ARBITRATION_VGA_PRIORITY_1 1 +#define PCIMEM_ARBITRATION_VGA_PRIORITY_2 2 +#define PCIMEM_ARBITRATION_VGA_PRIORITY_3 3 +#define PCIMEM_ARBITRATION_VGA_PRIORITY_4 4 +#define PCIMEM_ARBITRATION_VGA_PRIORITY_5 5 +#define PCIMEM_ARBITRATION_VGA_PRIORITY_6 6 +#define PCIMEM_ARBITRATION_VGA_PRIORITY_7 7 +#define PCIMEM_ARBITRATION_DMA 22:20 +#define PCIMEM_ARBITRATION_DMA_OFF 0 +#define PCIMEM_ARBITRATION_DMA_PRIORITY_1 1 +#define PCIMEM_ARBITRATION_DMA_PRIORITY_2 2 +#define PCIMEM_ARBITRATION_DMA_PRIORITY_3 3 +#define PCIMEM_ARBITRATION_DMA_PRIORITY_4 4 +#define PCIMEM_ARBITRATION_DMA_PRIORITY_5 5 +#define PCIMEM_ARBITRATION_DMA_PRIORITY_6 6 +#define PCIMEM_ARBITRATION_DMA_PRIORITY_7 7 +#define PCIMEM_ARBITRATION_ZVPORT1 18:16 +#define PCIMEM_ARBITRATION_ZVPORT1_OFF 0 +#define PCIMEM_ARBITRATION_ZVPORT1_PRIORITY_1 1 +#define PCIMEM_ARBITRATION_ZVPORT1_PRIORITY_2 2 +#define PCIMEM_ARBITRATION_ZVPORT1_PRIORITY_3 3 +#define PCIMEM_ARBITRATION_ZVPORT1_PRIORITY_4 4 +#define PCIMEM_ARBITRATION_ZVPORT1_PRIORITY_5 5 +#define PCIMEM_ARBITRATION_ZVPORT1_PRIORITY_6 6 +#define PCIMEM_ARBITRATION_ZVPORT1_PRIORITY_7 7 +#define PCIMEM_ARBITRATION_ZVPORT0 14:12 +#define PCIMEM_ARBITRATION_ZVPORT0_OFF 0 +#define PCIMEM_ARBITRATION_ZVPORT0_PRIORITY_1 1 +#define PCIMEM_ARBITRATION_ZVPORT0_PRIORITY_2 2 +#define PCIMEM_ARBITRATION_ZVPORT0_PRIORITY_3 3 +#define PCIMEM_ARBITRATION_ZVPORT0_PRIORITY_4 4 +#define PCIMEM_ARBITRATION_ZVPORT0_PRIORITY_5 5 +#define PCIMEM_ARBITRATION_ZVPORT0_PRIORITY_6 6 +#define PCIMEM_ARBITRATION_ZVPORT0_PRIORITY_7 7 +#define PCIMEM_ARBITRATION_VIDEO 10:8 +#define PCIMEM_ARBITRATION_VIDEO_OFF 0 +#define PCIMEM_ARBITRATION_VIDEO_PRIORITY_1 1 +#define PCIMEM_ARBITRATION_VIDEO_PRIORITY_2 2 +#define PCIMEM_ARBITRATION_VIDEO_PRIORITY_3 3 +#define PCIMEM_ARBITRATION_VIDEO_PRIORITY_4 4 +#define PCIMEM_ARBITRATION_VIDEO_PRIORITY_5 5 +#define PCIMEM_ARBITRATION_VIDEO_PRIORITY_6 6 +#define PCIMEM_ARBITRATION_VIDEO_PRIORITY_7 7 +#define PCIMEM_ARBITRATION_PANEL 6:4 +#define PCIMEM_ARBITRATION_PANEL_OFF 0 +#define PCIMEM_ARBITRATION_PANEL_PRIORITY_1 1 +#define PCIMEM_ARBITRATION_PANEL_PRIORITY_2 2 +#define PCIMEM_ARBITRATION_PANEL_PRIORITY_3 3 +#define PCIMEM_ARBITRATION_PANEL_PRIORITY_4 4 +#define PCIMEM_ARBITRATION_PANEL_PRIORITY_5 5 +#define PCIMEM_ARBITRATION_PANEL_PRIORITY_6 6 +#define PCIMEM_ARBITRATION_PANEL_PRIORITY_7 7 +#define PCIMEM_ARBITRATION_CRT 2:0 +#define PCIMEM_ARBITRATION_CRT_OFF 0 +#define PCIMEM_ARBITRATION_CRT_PRIORITY_1 1 +#define PCIMEM_ARBITRATION_CRT_PRIORITY_2 2 +#define PCIMEM_ARBITRATION_CRT_PRIORITY_3 3 +#define PCIMEM_ARBITRATION_CRT_PRIORITY_4 4 +#define PCIMEM_ARBITRATION_CRT_PRIORITY_5 5 +#define PCIMEM_ARBITRATION_CRT_PRIORITY_6 6 +#define PCIMEM_ARBITRATION_CRT_PRIORITY_7 7 + +#define RAW_INT 0x000020 +#define RAW_INT_ZVPORT1_VSYNC 4:4 +#define RAW_INT_ZVPORT1_VSYNC_INACTIVE 0 +#define RAW_INT_ZVPORT1_VSYNC_ACTIVE 1 +#define RAW_INT_ZVPORT1_VSYNC_CLEAR 1 +#define RAW_INT_ZVPORT0_VSYNC 3:3 +#define RAW_INT_ZVPORT0_VSYNC_INACTIVE 0 +#define RAW_INT_ZVPORT0_VSYNC_ACTIVE 1 +#define RAW_INT_ZVPORT0_VSYNC_CLEAR 1 +#define RAW_INT_CRT_VSYNC 2:2 +#define RAW_INT_CRT_VSYNC_INACTIVE 0 +#define RAW_INT_CRT_VSYNC_ACTIVE 1 +#define RAW_INT_CRT_VSYNC_CLEAR 1 +#define RAW_INT_PANEL_VSYNC 1:1 +#define RAW_INT_PANEL_VSYNC_INACTIVE 0 +#define RAW_INT_PANEL_VSYNC_ACTIVE 1 +#define RAW_INT_PANEL_VSYNC_CLEAR 1 +#define RAW_INT_VGA_VSYNC 0:0 +#define RAW_INT_VGA_VSYNC_INACTIVE 0 +#define RAW_INT_VGA_VSYNC_ACTIVE 1 +#define RAW_INT_VGA_VSYNC_CLEAR 1 + +#define INT_STATUS 0x000024 +#define INT_STATUS_GPIO31 31:31 +#define INT_STATUS_GPIO31_INACTIVE 0 +#define INT_STATUS_GPIO31_ACTIVE 1 +#define INT_STATUS_GPIO30 30:30 +#define INT_STATUS_GPIO30_INACTIVE 0 +#define INT_STATUS_GPIO30_ACTIVE 1 +#define INT_STATUS_GPIO29 29:29 +#define INT_STATUS_GPIO29_INACTIVE 0 +#define INT_STATUS_GPIO29_ACTIVE 1 +#define INT_STATUS_GPIO28 28:28 +#define INT_STATUS_GPIO28_INACTIVE 0 +#define INT_STATUS_GPIO28_ACTIVE 1 +#define INT_STATUS_GPIO27 27:27 +#define INT_STATUS_GPIO27_INACTIVE 0 +#define INT_STATUS_GPIO27_ACTIVE 1 +#define INT_STATUS_GPIO26 26:26 +#define INT_STATUS_GPIO26_INACTIVE 0 +#define INT_STATUS_GPIO26_ACTIVE 1 +#define INT_STATUS_GPIO25 25:25 +#define INT_STATUS_GPIO25_INACTIVE 0 +#define INT_STATUS_GPIO25_ACTIVE 1 +#define INT_STATUS_I2C 12:12 +#define INT_STATUS_I2C_INACTIVE 0 +#define INT_STATUS_I2C_ACTIVE 1 +#define INT_STATUS_PWM 11:11 +#define INT_STATUS_PWM_INACTIVE 0 +#define INT_STATUS_PWM_ACTIVE 1 +#define INT_STATUS_DMA1 10:10 +#define INT_STATUS_DMA1_INACTIVE 0 +#define INT_STATUS_DMA1_ACTIVE 1 +#define INT_STATUS_DMA0 9:9 +#define INT_STATUS_DMA0_INACTIVE 0 +#define INT_STATUS_DMA0_ACTIVE 1 +#define INT_STATUS_PCI 8:8 +#define INT_STATUS_PCI_INACTIVE 0 +#define INT_STATUS_PCI_ACTIVE 1 +#define INT_STATUS_SSP1 7:7 +#define INT_STATUS_SSP1_INACTIVE 0 +#define INT_STATUS_SSP1_ACTIVE 1 +#define INT_STATUS_SSP0 6:6 +#define INT_STATUS_SSP0_INACTIVE 0 +#define INT_STATUS_SSP0_ACTIVE 1 +#define INT_STATUS_DE 5:5 +#define INT_STATUS_DE_INACTIVE 0 +#define INT_STATUS_DE_ACTIVE 1 +#define INT_STATUS_ZVPORT1_VSYNC 4:4 +#define INT_STATUS_ZVPORT1_VSYNC_INACTIVE 0 +#define INT_STATUS_ZVPORT1_VSYNC_ACTIVE 1 +#define INT_STATUS_ZVPORT0_VSYNC 3:3 +#define INT_STATUS_ZVPORT0_VSYNC_INACTIVE 0 +#define INT_STATUS_ZVPORT0_VSYNC_ACTIVE 1 +#define INT_STATUS_CRT_VSYNC 2:2 +#define INT_STATUS_CRT_VSYNC_INACTIVE 0 +#define INT_STATUS_CRT_VSYNC_ACTIVE 1 +#define INT_STATUS_PANEL_VSYNC 1:1 +#define INT_STATUS_PANEL_VSYNC_INACTIVE 0 +#define INT_STATUS_PANEL_VSYNC_ACTIVE 1 +#define INT_STATUS_VGA_VSYNC 0:0 +#define INT_STATUS_VGA_VSYNC_INACTIVE 0 +#define INT_STATUS_VGA_VSYNC_ACTIVE 1 + +#define INT_MASK 0x000028 +#define INT_MASK_GPIO31 31:31 +#define INT_MASK_GPIO31_DISABLE 0 +#define INT_MASK_GPIO31_ENABLE 1 +#define INT_MASK_GPIO30 30:30 +#define INT_MASK_GPIO30_DISABLE 0 +#define INT_MASK_GPIO30_ENABLE 1 +#define INT_MASK_GPIO29 29:29 +#define INT_MASK_GPIO29_DISABLE 0 +#define INT_MASK_GPIO29_ENABLE 1 +#define INT_MASK_GPIO28 28:28 +#define INT_MASK_GPIO28_DISABLE 0 +#define INT_MASK_GPIO28_ENABLE 1 +#define INT_MASK_GPIO27 27:27 +#define INT_MASK_GPIO27_DISABLE 0 +#define INT_MASK_GPIO27_ENABLE 1 +#define INT_MASK_GPIO26 26:26 +#define INT_MASK_GPIO26_DISABLE 0 +#define INT_MASK_GPIO26_ENABLE 1 +#define INT_MASK_GPIO25 25:25 +#define INT_MASK_GPIO25_DISABLE 0 +#define INT_MASK_GPIO25_ENABLE 1 +#define INT_MASK_I2C 12:12 +#define INT_MASK_I2C_DISABLE 0 +#define INT_MASK_I2C_ENABLE 1 +#define INT_MASK_PWM 11:11 +#define INT_MASK_PWM_DISABLE 0 +#define INT_MASK_PWM_ENABLE 1 +#define INT_MASK_DMA1 10:10 +#define INT_MASK_DMA1_DISABLE 0 +#define INT_MASK_DMA1_ENABLE 1 +#define INT_MASK_DMA 9:9 +#define INT_MASK_DMA_DISABLE 0 +#define INT_MASK_DMA_ENABLE 1 +#define INT_MASK_PCI 8:8 +#define INT_MASK_PCI_DISABLE 0 +#define INT_MASK_PCI_ENABLE 1 +#define INT_MASK_SSP1 7:7 +#define INT_MASK_SSP1_DISABLE 0 +#define INT_MASK_SSP1_ENABLE 1 +#define INT_MASK_SSP0 6:6 +#define INT_MASK_SSP0_DISABLE 0 +#define INT_MASK_SSP0_ENABLE 1 +#define INT_MASK_DE 5:5 +#define INT_MASK_DE_DISABLE 0 +#define INT_MASK_DE_ENABLE 1 +#define INT_MASK_ZVPORT1_VSYNC 4:4 +#define INT_MASK_ZVPORT1_VSYNC_DISABLE 0 +#define INT_MASK_ZVPORT1_VSYNC_ENABLE 1 +#define INT_MASK_ZVPORT0_VSYNC 3:3 +#define INT_MASK_ZVPORT0_VSYNC_DISABLE 0 +#define INT_MASK_ZVPORT0_VSYNC_ENABLE 1 +#define INT_MASK_CRT_VSYNC 2:2 +#define INT_MASK_CRT_VSYNC_DISABLE 0 +#define INT_MASK_CRT_VSYNC_ENABLE 1 +#define INT_MASK_PANEL_VSYNC 1:1 +#define INT_MASK_PANEL_VSYNC_DISABLE 0 +#define INT_MASK_PANEL_VSYNC_ENABLE 1 +#define INT_MASK_VGA_VSYNC 0:0 +#define INT_MASK_VGA_VSYNC_DISABLE 0 +#define INT_MASK_VGA_VSYNC_ENABLE 1 + +#define CURRENT_GATE 0x000040 +#define CURRENT_GATE_MCLK 15:14 +#ifdef VALIDATION_CHIP + #define CURRENT_GATE_MCLK_112MHZ 0 + #define CURRENT_GATE_MCLK_84MHZ 1 + #define CURRENT_GATE_MCLK_56MHZ 2 + #define CURRENT_GATE_MCLK_42MHZ 3 +#else + #define CURRENT_GATE_MCLK_DIV_3 0 + #define CURRENT_GATE_MCLK_DIV_4 1 + #define CURRENT_GATE_MCLK_DIV_6 2 + #define CURRENT_GATE_MCLK_DIV_8 3 +#endif +#define CURRENT_GATE_M2XCLK 13:12 +#ifdef VALIDATION_CHIP + #define CURRENT_GATE_M2XCLK_336MHZ 0 + #define CURRENT_GATE_M2XCLK_168MHZ 1 + #define CURRENT_GATE_M2XCLK_112MHZ 2 + #define CURRENT_GATE_M2XCLK_84MHZ 3 +#else + #define CURRENT_GATE_M2XCLK_DIV_1 0 + #define CURRENT_GATE_M2XCLK_DIV_2 1 + #define CURRENT_GATE_M2XCLK_DIV_3 2 + #define CURRENT_GATE_M2XCLK_DIV_4 3 +#endif +#define CURRENT_GATE_VGA 10:10 +#define CURRENT_GATE_VGA_OFF 0 +#define CURRENT_GATE_VGA_ON 1 +#define CURRENT_GATE_PWM 9:9 +#define CURRENT_GATE_PWM_OFF 0 +#define CURRENT_GATE_PWM_ON 1 +#define CURRENT_GATE_I2C 8:8 +#define CURRENT_GATE_I2C_OFF 0 +#define CURRENT_GATE_I2C_ON 1 +#define CURRENT_GATE_SSP 7:7 +#define CURRENT_GATE_SSP_OFF 0 +#define CURRENT_GATE_SSP_ON 1 +#define CURRENT_GATE_GPIO 6:6 +#define CURRENT_GATE_GPIO_OFF 0 +#define CURRENT_GATE_GPIO_ON 1 +#define CURRENT_GATE_ZVPORT 5:5 +#define CURRENT_GATE_ZVPORT_OFF 0 +#define CURRENT_GATE_ZVPORT_ON 1 +#define CURRENT_GATE_CSC 4:4 +#define CURRENT_GATE_CSC_OFF 0 +#define CURRENT_GATE_CSC_ON 1 +#define CURRENT_GATE_DE 3:3 +#define CURRENT_GATE_DE_OFF 0 +#define CURRENT_GATE_DE_ON 1 +#define CURRENT_GATE_DISPLAY 2:2 +#define CURRENT_GATE_DISPLAY_OFF 0 +#define CURRENT_GATE_DISPLAY_ON 1 +#define CURRENT_GATE_LOCALMEM 1:1 +#define CURRENT_GATE_LOCALMEM_OFF 0 +#define CURRENT_GATE_LOCALMEM_ON 1 +#define CURRENT_GATE_DMA 0:0 +#define CURRENT_GATE_DMA_OFF 0 +#define CURRENT_GATE_DMA_ON 1 + +#define MODE0_GATE 0x000044 +#define MODE0_GATE_MCLK 15:14 +#define MODE0_GATE_MCLK_112MHZ 0 +#define MODE0_GATE_MCLK_84MHZ 1 +#define MODE0_GATE_MCLK_56MHZ 2 +#define MODE0_GATE_MCLK_42MHZ 3 +#define MODE0_GATE_M2XCLK 13:12 +#define MODE0_GATE_M2XCLK_336MHZ 0 +#define MODE0_GATE_M2XCLK_168MHZ 1 +#define MODE0_GATE_M2XCLK_112MHZ 2 +#define MODE0_GATE_M2XCLK_84MHZ 3 +#define MODE0_GATE_VGA 10:10 +#define MODE0_GATE_VGA_OFF 0 +#define MODE0_GATE_VGA_ON 1 +#define MODE0_GATE_PWM 9:9 +#define MODE0_GATE_PWM_OFF 0 +#define MODE0_GATE_PWM_ON 1 +#define MODE0_GATE_I2C 8:8 +#define MODE0_GATE_I2C_OFF 0 +#define MODE0_GATE_I2C_ON 1 +#define MODE0_GATE_SSP 7:7 +#define MODE0_GATE_SSP_OFF 0 +#define MODE0_GATE_SSP_ON 1 +#define MODE0_GATE_GPIO 6:6 +#define MODE0_GATE_GPIO_OFF 0 +#define MODE0_GATE_GPIO_ON 1 +#define MODE0_GATE_ZVPORT 5:5 +#define MODE0_GATE_ZVPORT_OFF 0 +#define MODE0_GATE_ZVPORT_ON 1 +#define MODE0_GATE_CSC 4:4 +#define MODE0_GATE_CSC_OFF 0 +#define MODE0_GATE_CSC_ON 1 +#define MODE0_GATE_DE 3:3 +#define MODE0_GATE_DE_OFF 0 +#define MODE0_GATE_DE_ON 1 +#define MODE0_GATE_DISPLAY 2:2 +#define MODE0_GATE_DISPLAY_OFF 0 +#define MODE0_GATE_DISPLAY_ON 1 +#define MODE0_GATE_LOCALMEM 1:1 +#define MODE0_GATE_LOCALMEM_OFF 0 +#define MODE0_GATE_LOCALMEM_ON 1 +#define MODE0_GATE_DMA 0:0 +#define MODE0_GATE_DMA_OFF 0 +#define MODE0_GATE_DMA_ON 1 + +#define MODE1_GATE 0x000048 +#define MODE1_GATE_MCLK 15:14 +#define MODE1_GATE_MCLK_112MHZ 0 +#define MODE1_GATE_MCLK_84MHZ 1 +#define MODE1_GATE_MCLK_56MHZ 2 +#define MODE1_GATE_MCLK_42MHZ 3 +#define MODE1_GATE_M2XCLK 13:12 +#define MODE1_GATE_M2XCLK_336MHZ 0 +#define MODE1_GATE_M2XCLK_168MHZ 1 +#define MODE1_GATE_M2XCLK_112MHZ 2 +#define MODE1_GATE_M2XCLK_84MHZ 3 +#define MODE1_GATE_VGA 10:10 +#define MODE1_GATE_VGA_OFF 0 +#define MODE1_GATE_VGA_ON 1 +#define MODE1_GATE_PWM 9:9 +#define MODE1_GATE_PWM_OFF 0 +#define MODE1_GATE_PWM_ON 1 +#define MODE1_GATE_I2C 8:8 +#define MODE1_GATE_I2C_OFF 0 +#define MODE1_GATE_I2C_ON 1 +#define MODE1_GATE_SSP 7:7 +#define MODE1_GATE_SSP_OFF 0 +#define MODE1_GATE_SSP_ON 1 +#define MODE1_GATE_GPIO 6:6 +#define MODE1_GATE_GPIO_OFF 0 +#define MODE1_GATE_GPIO_ON 1 +#define MODE1_GATE_ZVPORT 5:5 +#define MODE1_GATE_ZVPORT_OFF 0 +#define MODE1_GATE_ZVPORT_ON 1 +#define MODE1_GATE_CSC 4:4 +#define MODE1_GATE_CSC_OFF 0 +#define MODE1_GATE_CSC_ON 1 +#define MODE1_GATE_DE 3:3 +#define MODE1_GATE_DE_OFF 0 +#define MODE1_GATE_DE_ON 1 +#define MODE1_GATE_DISPLAY 2:2 +#define MODE1_GATE_DISPLAY_OFF 0 +#define MODE1_GATE_DISPLAY_ON 1 +#define MODE1_GATE_LOCALMEM 1:1 +#define MODE1_GATE_LOCALMEM_OFF 0 +#define MODE1_GATE_LOCALMEM_ON 1 +#define MODE1_GATE_DMA 0:0 +#define MODE1_GATE_DMA_OFF 0 +#define MODE1_GATE_DMA_ON 1 + +#define POWER_MODE_CTRL 0x00004C +#ifdef VALIDATION_CHIP + #define POWER_MODE_CTRL_336CLK 4:4 + #define POWER_MODE_CTRL_336CLK_OFF 0 + #define POWER_MODE_CTRL_336CLK_ON 1 +#endif +#define POWER_MODE_CTRL_OSC_INPUT 3:3 +#define POWER_MODE_CTRL_OSC_INPUT_OFF 0 +#define POWER_MODE_CTRL_OSC_INPUT_ON 1 +#define POWER_MODE_CTRL_ACPI 2:2 +#define POWER_MODE_CTRL_ACPI_OFF 0 +#define POWER_MODE_CTRL_ACPI_ON 1 +#define POWER_MODE_CTRL_MODE 1:0 +#define POWER_MODE_CTRL_MODE_MODE0 0 +#define POWER_MODE_CTRL_MODE_MODE1 1 +#define POWER_MODE_CTRL_MODE_SLEEP 2 + +#define PCI_MASTER_BASE 0x000050 +#define PCI_MASTER_BASE_ADDRESS 7:0 + +#define DEVICE_ID 0x000054 +#define DEVICE_ID_DEVICE_ID 31:16 +#define DEVICE_ID_REVISION_ID 7:0 + +#define PLL_CLK_COUNT 0x000058 +#define PLL_CLK_COUNT_COUNTER 15:0 + +#define PANEL_PLL_CTRL 0x00005C +#define PANEL_PLL_CTRL_BYPASS 18:18 +#define PANEL_PLL_CTRL_BYPASS_OFF 0 +#define PANEL_PLL_CTRL_BYPASS_ON 1 +#define PANEL_PLL_CTRL_POWER 17:17 +#define PANEL_PLL_CTRL_POWER_OFF 0 +#define PANEL_PLL_CTRL_POWER_ON 1 +#define PANEL_PLL_CTRL_INPUT 16:16 +#define PANEL_PLL_CTRL_INPUT_OSC 0 +#define PANEL_PLL_CTRL_INPUT_TESTCLK 1 +#ifdef VALIDATION_CHIP + #define PANEL_PLL_CTRL_OD 15:14 +#else + #define PANEL_PLL_CTRL_POD 15:14 + #define PANEL_PLL_CTRL_OD 13:12 +#endif +#define PANEL_PLL_CTRL_N 11:8 +#define PANEL_PLL_CTRL_M 7:0 + +#define CRT_PLL_CTRL 0x000060 +#define CRT_PLL_CTRL_BYPASS 18:18 +#define CRT_PLL_CTRL_BYPASS_OFF 0 +#define CRT_PLL_CTRL_BYPASS_ON 1 +#define CRT_PLL_CTRL_POWER 17:17 +#define CRT_PLL_CTRL_POWER_OFF 0 +#define CRT_PLL_CTRL_POWER_ON 1 +#define CRT_PLL_CTRL_INPUT 16:16 +#define CRT_PLL_CTRL_INPUT_OSC 0 +#define CRT_PLL_CTRL_INPUT_TESTCLK 1 +#ifdef VALIDATION_CHIP + #define CRT_PLL_CTRL_OD 15:14 +#else + #define CRT_PLL_CTRL_POD 15:14 + #define CRT_PLL_CTRL_OD 13:12 +#endif +#define CRT_PLL_CTRL_N 11:8 +#define CRT_PLL_CTRL_M 7:0 + +#define VGA_PLL0_CTRL 0x000064 +#define VGA_PLL0_CTRL_BYPASS 18:18 +#define VGA_PLL0_CTRL_BYPASS_OFF 0 +#define VGA_PLL0_CTRL_BYPASS_ON 1 +#define VGA_PLL0_CTRL_POWER 17:17 +#define VGA_PLL0_CTRL_POWER_OFF 0 +#define VGA_PLL0_CTRL_POWER_ON 1 +#define VGA_PLL0_CTRL_INPUT 16:16 +#define VGA_PLL0_CTRL_INPUT_OSC 0 +#define VGA_PLL0_CTRL_INPUT_TESTCLK 1 +#ifdef VALIDATION_CHIP + #define VGA_PLL0_CTRL_OD 15:14 +#else + #define VGA_PLL0_CTRL_POD 15:14 + #define VGA_PLL0_CTRL_OD 13:12 +#endif +#define VGA_PLL0_CTRL_N 11:8 +#define VGA_PLL0_CTRL_M 7:0 + +#define VGA_PLL1_CTRL 0x000068 +#define VGA_PLL1_CTRL_BYPASS 18:18 +#define VGA_PLL1_CTRL_BYPASS_OFF 0 +#define VGA_PLL1_CTRL_BYPASS_ON 1 +#define VGA_PLL1_CTRL_POWER 17:17 +#define VGA_PLL1_CTRL_POWER_OFF 0 +#define VGA_PLL1_CTRL_POWER_ON 1 +#define VGA_PLL1_CTRL_INPUT 16:16 +#define VGA_PLL1_CTRL_INPUT_OSC 0 +#define VGA_PLL1_CTRL_INPUT_TESTCLK 1 +#ifdef VALIDATION_CHIP + #define VGA_PLL1_CTRL_OD 15:14 +#else + #define VGA_PLL1_CTRL_POD 15:14 + #define VGA_PLL1_CTRL_OD 13:12 +#endif +#define VGA_PLL1_CTRL_N 11:8 +#define VGA_PLL1_CTRL_M 7:0 + +#define SCRATCH_DATA 0x00006c + +#ifndef VALIDATION_CHIP + +#define MXCLK_PLL_CTRL 0x000070 +#define MXCLK_PLL_CTRL_BYPASS 18:18 +#define MXCLK_PLL_CTRL_BYPASS_OFF 0 +#define MXCLK_PLL_CTRL_BYPASS_ON 1 +#define MXCLK_PLL_CTRL_POWER 17:17 +#define MXCLK_PLL_CTRL_POWER_OFF 0 +#define MXCLK_PLL_CTRL_POWER_ON 1 +#define MXCLK_PLL_CTRL_INPUT 16:16 +#define MXCLK_PLL_CTRL_INPUT_OSC 0 +#define MXCLK_PLL_CTRL_INPUT_TESTCLK 1 +#define MXCLK_PLL_CTRL_POD 15:14 +#define MXCLK_PLL_CTRL_OD 13:12 +#define MXCLK_PLL_CTRL_N 11:8 +#define MXCLK_PLL_CTRL_M 7:0 + +#define VGA_CONFIGURATION 0x000088 +#define VGA_CONFIGURATION_USER_DEFINE 5:4 +#define VGA_CONFIGURATION_PLL 2:2 +#define VGA_CONFIGURATION_PLL_VGA 0 +#define VGA_CONFIGURATION_PLL_PANEL 1 +#define VGA_CONFIGURATION_MODE 1:1 +#define VGA_CONFIGURATION_MODE_TEXT 0 +#define VGA_CONFIGURATION_MODE_GRAPHIC 1 + +#endif + +#define GPIO_DATA 0x010000 +#define GPIO_DATA_31 31:31 +#define GPIO_DATA_30 30:30 +#define GPIO_DATA_29 29:29 +#define GPIO_DATA_28 28:28 +#define GPIO_DATA_27 27:27 +#define GPIO_DATA_26 26:26 +#define GPIO_DATA_25 25:25 +#define GPIO_DATA_24 24:24 +#define GPIO_DATA_23 23:23 +#define GPIO_DATA_22 22:22 +#define GPIO_DATA_21 21:21 +#define GPIO_DATA_20 20:20 +#define GPIO_DATA_19 19:19 +#define GPIO_DATA_18 18:18 +#define GPIO_DATA_17 17:17 +#define GPIO_DATA_16 16:16 +#define GPIO_DATA_15 15:15 +#define GPIO_DATA_14 14:14 +#define GPIO_DATA_13 13:13 +#define GPIO_DATA_12 12:12 +#define GPIO_DATA_11 11:11 +#define GPIO_DATA_10 10:10 +#define GPIO_DATA_9 9:9 +#define GPIO_DATA_8 8:8 +#define GPIO_DATA_7 7:7 +#define GPIO_DATA_6 6:6 +#define GPIO_DATA_5 5:5 +#define GPIO_DATA_4 4:4 +#define GPIO_DATA_3 3:3 +#define GPIO_DATA_2 2:2 +#define GPIO_DATA_1 1:1 +#define GPIO_DATA_0 0:0 + +#define GPIO_DATA_DIRECTION 0x010004 +#define GPIO_DATA_DIRECTION_31 31:31 +#define GPIO_DATA_DIRECTION_31_INPUT 0 +#define GPIO_DATA_DIRECTION_31_OUTPUT 1 +#define GPIO_DATA_DIRECTION_30 30:30 +#define GPIO_DATA_DIRECTION_30_INPUT 0 +#define GPIO_DATA_DIRECTION_30_OUTPUT 1 +#define GPIO_DATA_DIRECTION_29 29:29 +#define GPIO_DATA_DIRECTION_29_INPUT 0 +#define GPIO_DATA_DIRECTION_29_OUTPUT 1 +#define GPIO_DATA_DIRECTION_28 28:28 +#define GPIO_DATA_DIRECTION_28_INPUT 0 +#define GPIO_DATA_DIRECTION_28_OUTPUT 1 +#define GPIO_DATA_DIRECTION_27 27:27 +#define GPIO_DATA_DIRECTION_27_INPUT 0 +#define GPIO_DATA_DIRECTION_27_OUTPUT 1 +#define GPIO_DATA_DIRECTION_26 26:26 +#define GPIO_DATA_DIRECTION_26_INPUT 0 +#define GPIO_DATA_DIRECTION_26_OUTPUT 1 +#define GPIO_DATA_DIRECTION_25 25:25 +#define GPIO_DATA_DIRECTION_25_INPUT 0 +#define GPIO_DATA_DIRECTION_25_OUTPUT 1 +#define GPIO_DATA_DIRECTION_24 24:24 +#define GPIO_DATA_DIRECTION_24_INPUT 0 +#define GPIO_DATA_DIRECTION_24_OUTPUT 1 +#define GPIO_DATA_DIRECTION_23 23:23 +#define GPIO_DATA_DIRECTION_23_INPUT 0 +#define GPIO_DATA_DIRECTION_23_OUTPUT 1 +#define GPIO_DATA_DIRECTION_22 22:22 +#define GPIO_DATA_DIRECTION_22_INPUT 0 +#define GPIO_DATA_DIRECTION_22_OUTPUT 1 +#define GPIO_DATA_DIRECTION_21 21:21 +#define GPIO_DATA_DIRECTION_21_INPUT 0 +#define GPIO_DATA_DIRECTION_21_OUTPUT 1 +#define GPIO_DATA_DIRECTION_20 20:20 +#define GPIO_DATA_DIRECTION_20_INPUT 0 +#define GPIO_DATA_DIRECTION_20_OUTPUT 1 +#define GPIO_DATA_DIRECTION_19 19:19 +#define GPIO_DATA_DIRECTION_19_INPUT 0 +#define GPIO_DATA_DIRECTION_19_OUTPUT 1 +#define GPIO_DATA_DIRECTION_18 18:18 +#define GPIO_DATA_DIRECTION_18_INPUT 0 +#define GPIO_DATA_DIRECTION_18_OUTPUT 1 +#define GPIO_DATA_DIRECTION_17 17:17 +#define GPIO_DATA_DIRECTION_17_INPUT 0 +#define GPIO_DATA_DIRECTION_17_OUTPUT 1 +#define GPIO_DATA_DIRECTION_16 16:16 +#define GPIO_DATA_DIRECTION_16_INPUT 0 +#define GPIO_DATA_DIRECTION_16_OUTPUT 1 +#define GPIO_DATA_DIRECTION_15 15:15 +#define GPIO_DATA_DIRECTION_15_INPUT 0 +#define GPIO_DATA_DIRECTION_15_OUTPUT 1 +#define GPIO_DATA_DIRECTION_14 14:14 +#define GPIO_DATA_DIRECTION_14_INPUT 0 +#define GPIO_DATA_DIRECTION_14_OUTPUT 1 +#define GPIO_DATA_DIRECTION_13 13:13 +#define GPIO_DATA_DIRECTION_13_INPUT 0 +#define GPIO_DATA_DIRECTION_13_OUTPUT 1 +#define GPIO_DATA_DIRECTION_12 12:12 +#define GPIO_DATA_DIRECTION_12_INPUT 0 +#define GPIO_DATA_DIRECTION_12_OUTPUT 1 +#define GPIO_DATA_DIRECTION_11 11:11 +#define GPIO_DATA_DIRECTION_11_INPUT 0 +#define GPIO_DATA_DIRECTION_11_OUTPUT 1 +#define GPIO_DATA_DIRECTION_10 10:10 +#define GPIO_DATA_DIRECTION_10_INPUT 0 +#define GPIO_DATA_DIRECTION_10_OUTPUT 1 +#define GPIO_DATA_DIRECTION_9 9:9 +#define GPIO_DATA_DIRECTION_9_INPUT 0 +#define GPIO_DATA_DIRECTION_9_OUTPUT 1 +#define GPIO_DATA_DIRECTION_8 8:8 +#define GPIO_DATA_DIRECTION_8_INPUT 0 +#define GPIO_DATA_DIRECTION_8_OUTPUT 1 +#define GPIO_DATA_DIRECTION_7 7:7 +#define GPIO_DATA_DIRECTION_7_INPUT 0 +#define GPIO_DATA_DIRECTION_7_OUTPUT 1 +#define GPIO_DATA_DIRECTION_6 6:6 +#define GPIO_DATA_DIRECTION_6_INPUT 0 +#define GPIO_DATA_DIRECTION_6_OUTPUT 1 +#define GPIO_DATA_DIRECTION_5 5:5 +#define GPIO_DATA_DIRECTION_5_INPUT 0 +#define GPIO_DATA_DIRECTION_5_OUTPUT 1 +#define GPIO_DATA_DIRECTION_4 4:4 +#define GPIO_DATA_DIRECTION_4_INPUT 0 +#define GPIO_DATA_DIRECTION_4_OUTPUT 1 +#define GPIO_DATA_DIRECTION_3 3:3 +#define GPIO_DATA_DIRECTION_3_INPUT 0 +#define GPIO_DATA_DIRECTION_3_OUTPUT 1 +#define GPIO_DATA_DIRECTION_2 2:2 +#define GPIO_DATA_DIRECTION_2_INPUT 0 +#define GPIO_DATA_DIRECTION_2_OUTPUT 1 +#define GPIO_DATA_DIRECTION_1 131 +#define GPIO_DATA_DIRECTION_1_INPUT 0 +#define GPIO_DATA_DIRECTION_1_OUTPUT 1 +#define GPIO_DATA_DIRECTION_0 0:0 +#define GPIO_DATA_DIRECTION_0_INPUT 0 +#define GPIO_DATA_DIRECTION_0_OUTPUT 1 + +#define GPIO_INTERRUPT_SETUP 0x010008 +#define GPIO_INTERRUPT_SETUP_TRIGGER_31 22:22 +#define GPIO_INTERRUPT_SETUP_TRIGGER_31_EDGE 0 +#define GPIO_INTERRUPT_SETUP_TRIGGER_31_LEVEL 1 +#define GPIO_INTERRUPT_SETUP_TRIGGER_30 21:21 +#define GPIO_INTERRUPT_SETUP_TRIGGER_30_EDGE 0 +#define GPIO_INTERRUPT_SETUP_TRIGGER_30_LEVEL 1 +#define GPIO_INTERRUPT_SETUP_TRIGGER_29 20:20 +#define GPIO_INTERRUPT_SETUP_TRIGGER_29_EDGE 0 +#define GPIO_INTERRUPT_SETUP_TRIGGER_29_LEVEL 1 +#define GPIO_INTERRUPT_SETUP_TRIGGER_28 19:19 +#define GPIO_INTERRUPT_SETUP_TRIGGER_28_EDGE 0 +#define GPIO_INTERRUPT_SETUP_TRIGGER_28_LEVEL 1 +#define GPIO_INTERRUPT_SETUP_TRIGGER_27 18:18 +#define GPIO_INTERRUPT_SETUP_TRIGGER_27_EDGE 0 +#define GPIO_INTERRUPT_SETUP_TRIGGER_27_LEVEL 1 +#define GPIO_INTERRUPT_SETUP_TRIGGER_26 17:17 +#define GPIO_INTERRUPT_SETUP_TRIGGER_26_EDGE 0 +#define GPIO_INTERRUPT_SETUP_TRIGGER_26_LEVEL 1 +#define GPIO_INTERRUPT_SETUP_TRIGGER_25 16:16 +#define GPIO_INTERRUPT_SETUP_TRIGGER_25_EDGE 0 +#define GPIO_INTERRUPT_SETUP_TRIGGER_25_LEVEL 1 +#define GPIO_INTERRUPT_SETUP_ACTIVE_31 14:14 +#define GPIO_INTERRUPT_SETUP_ACTIVE_31_LOW 0 +#define GPIO_INTERRUPT_SETUP_ACTIVE_31_HIGH 1 +#define GPIO_INTERRUPT_SETUP_ACTIVE_30 13:13 +#define GPIO_INTERRUPT_SETUP_ACTIVE_30_LOW 0 +#define GPIO_INTERRUPT_SETUP_ACTIVE_30_HIGH 1 +#define GPIO_INTERRUPT_SETUP_ACTIVE_29 12:12 +#define GPIO_INTERRUPT_SETUP_ACTIVE_29_LOW 0 +#define GPIO_INTERRUPT_SETUP_ACTIVE_29_HIGH 1 +#define GPIO_INTERRUPT_SETUP_ACTIVE_28 11:11 +#define GPIO_INTERRUPT_SETUP_ACTIVE_28_LOW 0 +#define GPIO_INTERRUPT_SETUP_ACTIVE_28_HIGH 1 +#define GPIO_INTERRUPT_SETUP_ACTIVE_27 10:10 +#define GPIO_INTERRUPT_SETUP_ACTIVE_27_LOW 0 +#define GPIO_INTERRUPT_SETUP_ACTIVE_27_HIGH 1 +#define GPIO_INTERRUPT_SETUP_ACTIVE_26 9:9 +#define GPIO_INTERRUPT_SETUP_ACTIVE_26_LOW 0 +#define GPIO_INTERRUPT_SETUP_ACTIVE_26_HIGH 1 +#define GPIO_INTERRUPT_SETUP_ACTIVE_25 8:8 +#define GPIO_INTERRUPT_SETUP_ACTIVE_25_LOW 0 +#define GPIO_INTERRUPT_SETUP_ACTIVE_25_HIGH 1 +#define GPIO_INTERRUPT_SETUP_ENABLE_31 6:6 +#define GPIO_INTERRUPT_SETUP_ENABLE_31_GPIO 0 +#define GPIO_INTERRUPT_SETUP_ENABLE_31_INTERRUPT 1 +#define GPIO_INTERRUPT_SETUP_ENABLE_30 5:5 +#define GPIO_INTERRUPT_SETUP_ENABLE_30_GPIO 0 +#define GPIO_INTERRUPT_SETUP_ENABLE_30_INTERRUPT 1 +#define GPIO_INTERRUPT_SETUP_ENABLE_29 4:4 +#define GPIO_INTERRUPT_SETUP_ENABLE_29_GPIO 0 +#define GPIO_INTERRUPT_SETUP_ENABLE_29_INTERRUPT 1 +#define GPIO_INTERRUPT_SETUP_ENABLE_28 3:3 +#define GPIO_INTERRUPT_SETUP_ENABLE_28_GPIO 0 +#define GPIO_INTERRUPT_SETUP_ENABLE_28_INTERRUPT 1 +#define GPIO_INTERRUPT_SETUP_ENABLE_27 2:2 +#define GPIO_INTERRUPT_SETUP_ENABLE_27_GPIO 0 +#define GPIO_INTERRUPT_SETUP_ENABLE_27_INTERRUPT 1 +#define GPIO_INTERRUPT_SETUP_ENABLE_26 1:1 +#define GPIO_INTERRUPT_SETUP_ENABLE_26_GPIO 0 +#define GPIO_INTERRUPT_SETUP_ENABLE_26_INTERRUPT 1 +#define GPIO_INTERRUPT_SETUP_ENABLE_25 0:0 +#define GPIO_INTERRUPT_SETUP_ENABLE_25_GPIO 0 +#define GPIO_INTERRUPT_SETUP_ENABLE_25_INTERRUPT 1 + +#define GPIO_INTERRUPT_STATUS 0x01000C +#define GPIO_INTERRUPT_STATUS_31 22:22 +#define GPIO_INTERRUPT_STATUS_31_INACTIVE 0 +#define GPIO_INTERRUPT_STATUS_31_ACTIVE 1 +#define GPIO_INTERRUPT_STATUS_31_RESET 1 +#define GPIO_INTERRUPT_STATUS_30 21:21 +#define GPIO_INTERRUPT_STATUS_30_INACTIVE 0 +#define GPIO_INTERRUPT_STATUS_30_ACTIVE 1 +#define GPIO_INTERRUPT_STATUS_30_RESET 1 +#define GPIO_INTERRUPT_STATUS_29 20:20 +#define GPIO_INTERRUPT_STATUS_29_INACTIVE 0 +#define GPIO_INTERRUPT_STATUS_29_ACTIVE 1 +#define GPIO_INTERRUPT_STATUS_29_RESET 1 +#define GPIO_INTERRUPT_STATUS_28 19:19 +#define GPIO_INTERRUPT_STATUS_28_INACTIVE 0 +#define GPIO_INTERRUPT_STATUS_28_ACTIVE 1 +#define GPIO_INTERRUPT_STATUS_28_RESET 1 +#define GPIO_INTERRUPT_STATUS_27 18:18 +#define GPIO_INTERRUPT_STATUS_27_INACTIVE 0 +#define GPIO_INTERRUPT_STATUS_27_ACTIVE 1 +#define GPIO_INTERRUPT_STATUS_27_RESET 1 +#define GPIO_INTERRUPT_STATUS_26 17:17 +#define GPIO_INTERRUPT_STATUS_26_INACTIVE 0 +#define GPIO_INTERRUPT_STATUS_26_ACTIVE 1 +#define GPIO_INTERRUPT_STATUS_26_RESET 1 +#define GPIO_INTERRUPT_STATUS_25 16:16 +#define GPIO_INTERRUPT_STATUS_25_INACTIVE 0 +#define GPIO_INTERRUPT_STATUS_25_ACTIVE 1 +#define GPIO_INTERRUPT_STATUS_25_RESET 1 + + +#define PANEL_DISPLAY_CTRL 0x080000 +#define PANEL_DISPLAY_CTRL_RESERVED_1_MASK 31:30 +#define PANEL_DISPLAY_CTRL_RESERVED_1_MASK_DISABLE 0 +#define PANEL_DISPLAY_CTRL_RESERVED_1_MASK_ENABLE 3 +#define PANEL_DISPLAY_CTRL_SELECT 29:28 +#define PANEL_DISPLAY_CTRL_SELECT_PANEL 0 +#define PANEL_DISPLAY_CTRL_SELECT_VGA 1 +#define PANEL_DISPLAY_CTRL_SELECT_CRT 2 +#define PANEL_DISPLAY_CTRL_FPEN 27:27 +#define PANEL_DISPLAY_CTRL_FPEN_LOW 0 +#define PANEL_DISPLAY_CTRL_FPEN_HIGH 1 +#define PANEL_DISPLAY_CTRL_VBIASEN 26:26 +#define PANEL_DISPLAY_CTRL_VBIASEN_LOW 0 +#define PANEL_DISPLAY_CTRL_VBIASEN_HIGH 1 +#define PANEL_DISPLAY_CTRL_DATA 25:25 +#define PANEL_DISPLAY_CTRL_DATA_DISABLE 0 +#define PANEL_DISPLAY_CTRL_DATA_ENABLE 1 +#define PANEL_DISPLAY_CTRL_FPVDDEN 24:24 +#define PANEL_DISPLAY_CTRL_FPVDDEN_LOW 0 +#define PANEL_DISPLAY_CTRL_FPVDDEN_HIGH 1 +#define PANEL_DISPLAY_CTRL_RESERVED_2_MASK 23:20 +#define PANEL_DISPLAY_CTRL_RESERVED_2_MASK_DISABLE 0 +#define PANEL_DISPLAY_CTRL_RESERVED_2_MASK_ENABLE 15 + +#define PANEL_DISPLAY_CTRL_TFT_DISP 19:18 +#define PANEL_DISPLAY_CTRL_TFT_DISP_24 0 +#define PANEL_DISPLAY_CTRL_TFT_DISP_36 1 +#define PANEL_DISPLAY_CTRL_TFT_DISP_18 2 + + +#define PANEL_DISPLAY_CTRL_DUAL_DISPLAY 19:19 +#define PANEL_DISPLAY_CTRL_DUAL_DISPLAY_DISABLE 0 +#define PANEL_DISPLAY_CTRL_DUAL_DISPLAY_ENABLE 1 +#define PANEL_DISPLAY_CTRL_DOUBLE_PIXEL 18:18 +#define PANEL_DISPLAY_CTRL_DOUBLE_PIXEL_DISABLE 0 +#define PANEL_DISPLAY_CTRL_DOUBLE_PIXEL_ENABLE 1 +#define PANEL_DISPLAY_CTRL_FIFO 17:16 +#define PANEL_DISPLAY_CTRL_FIFO_1 0 +#define PANEL_DISPLAY_CTRL_FIFO_3 1 +#define PANEL_DISPLAY_CTRL_FIFO_7 2 +#define PANEL_DISPLAY_CTRL_FIFO_11 3 +#define PANEL_DISPLAY_CTRL_RESERVED_3_MASK 15:15 +#define PANEL_DISPLAY_CTRL_RESERVED_3_MASK_DISABLE 0 +#define PANEL_DISPLAY_CTRL_RESERVED_3_MASK_ENABLE 1 +#define PANEL_DISPLAY_CTRL_CLOCK_PHASE 14:14 +#define PANEL_DISPLAY_CTRL_CLOCK_PHASE_ACTIVE_HIGH 0 +#define PANEL_DISPLAY_CTRL_CLOCK_PHASE_ACTIVE_LOW 1 +#define PANEL_DISPLAY_CTRL_VSYNC_PHASE 13:13 +#define PANEL_DISPLAY_CTRL_VSYNC_PHASE_ACTIVE_HIGH 0 +#define PANEL_DISPLAY_CTRL_VSYNC_PHASE_ACTIVE_LOW 1 +#define PANEL_DISPLAY_CTRL_HSYNC_PHASE 12:12 +#define PANEL_DISPLAY_CTRL_HSYNC_PHASE_ACTIVE_HIGH 0 +#define PANEL_DISPLAY_CTRL_HSYNC_PHASE_ACTIVE_LOW 1 +#define PANEL_DISPLAY_CTRL_VSYNC 11:11 +#define PANEL_DISPLAY_CTRL_VSYNC_ACTIVE_HIGH 0 +#define PANEL_DISPLAY_CTRL_VSYNC_ACTIVE_LOW 1 +#define PANEL_DISPLAY_CTRL_CAPTURE_TIMING 10:10 +#define PANEL_DISPLAY_CTRL_CAPTURE_TIMING_DISABLE 0 +#define PANEL_DISPLAY_CTRL_CAPTURE_TIMING_ENABLE 1 +#define PANEL_DISPLAY_CTRL_COLOR_KEY 9:9 +#define PANEL_DISPLAY_CTRL_COLOR_KEY_DISABLE 0 +#define PANEL_DISPLAY_CTRL_COLOR_KEY_ENABLE 1 +#define PANEL_DISPLAY_CTRL_TIMING 8:8 +#define PANEL_DISPLAY_CTRL_TIMING_DISABLE 0 +#define PANEL_DISPLAY_CTRL_TIMING_ENABLE 1 +#define PANEL_DISPLAY_CTRL_VERTICAL_PAN_DIR 7:7 +#define PANEL_DISPLAY_CTRL_VERTICAL_PAN_DIR_DOWN 0 +#define PANEL_DISPLAY_CTRL_VERTICAL_PAN_DIR_UP 1 +#define PANEL_DISPLAY_CTRL_VERTICAL_PAN 6:6 +#define PANEL_DISPLAY_CTRL_VERTICAL_PAN_DISABLE 0 +#define PANEL_DISPLAY_CTRL_VERTICAL_PAN_ENABLE 1 +#define PANEL_DISPLAY_CTRL_HORIZONTAL_PAN_DIR 5:5 +#define PANEL_DISPLAY_CTRL_HORIZONTAL_PAN_DIR_RIGHT 0 +#define PANEL_DISPLAY_CTRL_HORIZONTAL_PAN_DIR_LEFT 1 +#define PANEL_DISPLAY_CTRL_HORIZONTAL_PAN 4:4 +#define PANEL_DISPLAY_CTRL_HORIZONTAL_PAN_DISABLE 0 +#define PANEL_DISPLAY_CTRL_HORIZONTAL_PAN_ENABLE 1 +#define PANEL_DISPLAY_CTRL_GAMMA 3:3 +#define PANEL_DISPLAY_CTRL_GAMMA_DISABLE 0 +#define PANEL_DISPLAY_CTRL_GAMMA_ENABLE 1 +#define PANEL_DISPLAY_CTRL_PLANE 2:2 +#define PANEL_DISPLAY_CTRL_PLANE_DISABLE 0 +#define PANEL_DISPLAY_CTRL_PLANE_ENABLE 1 +#define PANEL_DISPLAY_CTRL_FORMAT 1:0 +#define PANEL_DISPLAY_CTRL_FORMAT_8 0 +#define PANEL_DISPLAY_CTRL_FORMAT_16 1 +#define PANEL_DISPLAY_CTRL_FORMAT_32 2 + +#define PANEL_PAN_CTRL 0x080004 +#define PANEL_PAN_CTRL_VERTICAL_PAN 31:24 +#define PANEL_PAN_CTRL_VERTICAL_VSYNC 21:16 +#define PANEL_PAN_CTRL_HORIZONTAL_PAN 15:8 +#define PANEL_PAN_CTRL_HORIZONTAL_VSYNC 5:0 + +#define PANEL_COLOR_KEY 0x080008 +#define PANEL_COLOR_KEY_MASK 31:16 +#define PANEL_COLOR_KEY_VALUE 15:0 + +#define PANEL_FB_ADDRESS 0x08000C +#define PANEL_FB_ADDRESS_STATUS 31:31 +#define PANEL_FB_ADDRESS_STATUS_CURRENT 0 +#define PANEL_FB_ADDRESS_STATUS_PENDING 1 +#define PANEL_FB_ADDRESS_EXT 27:27 +#define PANEL_FB_ADDRESS_EXT_LOCAL 0 +#define PANEL_FB_ADDRESS_EXT_EXTERNAL 1 +#define PANEL_FB_ADDRESS_ADDRESS 25:0 + +#define PANEL_FB_WIDTH 0x080010 +#define PANEL_FB_WIDTH_WIDTH 29:16 +#define PANEL_FB_WIDTH_OFFSET 13:0 + +#define PANEL_WINDOW_WIDTH 0x080014 +#define PANEL_WINDOW_WIDTH_WIDTH 27:16 +#define PANEL_WINDOW_WIDTH_X 11:0 + +#define PANEL_WINDOW_HEIGHT 0x080018 +#define PANEL_WINDOW_HEIGHT_HEIGHT 27:16 +#define PANEL_WINDOW_HEIGHT_Y 11:0 + +#define PANEL_PLANE_TL 0x08001C +#define PANEL_PLANE_TL_TOP 26:16 +#define PANEL_PLANE_TL_LEFT 10:0 + +#define PANEL_PLANE_BR 0x080020 +#define PANEL_PLANE_BR_BOTTOM 26:16 +#define PANEL_PLANE_BR_RIGHT 10:0 + +#define PANEL_HORIZONTAL_TOTAL 0x080024 +#define PANEL_HORIZONTAL_TOTAL_TOTAL 27:16 +#define PANEL_HORIZONTAL_TOTAL_DISPLAY_END 11:0 + +#define PANEL_HORIZONTAL_SYNC 0x080028 +#define PANEL_HORIZONTAL_SYNC_WIDTH 23:16 +#define PANEL_HORIZONTAL_SYNC_START 11:0 + +#define PANEL_VERTICAL_TOTAL 0x08002C +#define PANEL_VERTICAL_TOTAL_TOTAL 26:16 +#define PANEL_VERTICAL_TOTAL_DISPLAY_END 10:0 + +#define PANEL_VERTICAL_SYNC 0x080030 +#define PANEL_VERTICAL_SYNC_HEIGHT 21:16 +#define PANEL_VERTICAL_SYNC_START 10:0 + +#define PANEL_CURRENT_LINE 0x080034 +#define PANEL_CURRENT_LINE_LINE 10:0 + +/* Video Control */ + +#define VIDEO_DISPLAY_CTRL 0x080040 +#define VIDEO_DISPLAY_CTRL_LINE_BUFFER 18:18 +#define VIDEO_DISPLAY_CTRL_LINE_BUFFER_DISABLE 0 +#define VIDEO_DISPLAY_CTRL_LINE_BUFFER_ENABLE 1 +#define VIDEO_DISPLAY_CTRL_FIFO 17:16 +#define VIDEO_DISPLAY_CTRL_FIFO_1 0 +#define VIDEO_DISPLAY_CTRL_FIFO_3 1 +#define VIDEO_DISPLAY_CTRL_FIFO_7 2 +#define VIDEO_DISPLAY_CTRL_FIFO_11 3 +#define VIDEO_DISPLAY_CTRL_BUFFER 15:15 +#define VIDEO_DISPLAY_CTRL_BUFFER_0 0 +#define VIDEO_DISPLAY_CTRL_BUFFER_1 1 +#define VIDEO_DISPLAY_CTRL_CAPTURE 14:14 +#define VIDEO_DISPLAY_CTRL_CAPTURE_DISABLE 0 +#define VIDEO_DISPLAY_CTRL_CAPTURE_ENABLE 1 +#define VIDEO_DISPLAY_CTRL_DOUBLE_BUFFER 13:13 +#define VIDEO_DISPLAY_CTRL_DOUBLE_BUFFER_DISABLE 0 +#define VIDEO_DISPLAY_CTRL_DOUBLE_BUFFER_ENABLE 1 +#define VIDEO_DISPLAY_CTRL_BYTE_SWAP 12:12 +#define VIDEO_DISPLAY_CTRL_BYTE_SWAP_DISABLE 0 +#define VIDEO_DISPLAY_CTRL_BYTE_SWAP_ENABLE 1 +#define VIDEO_DISPLAY_CTRL_VERTICAL_SCALE 11:11 +#define VIDEO_DISPLAY_CTRL_VERTICAL_SCALE_NORMAL 0 +#define VIDEO_DISPLAY_CTRL_VERTICAL_SCALE_HALF 1 +#define VIDEO_DISPLAY_CTRL_HORIZONTAL_SCALE 10:10 +#define VIDEO_DISPLAY_CTRL_HORIZONTAL_SCALE_NORMAL 0 +#define VIDEO_DISPLAY_CTRL_HORIZONTAL_SCALE_HALF 1 +#define VIDEO_DISPLAY_CTRL_VERTICAL_MODE 9:9 +#define VIDEO_DISPLAY_CTRL_VERTICAL_MODE_REPLICATE 0 +#define VIDEO_DISPLAY_CTRL_VERTICAL_MODE_INTERPOLATE 1 +#define VIDEO_DISPLAY_CTRL_HORIZONTAL_MODE 8:8 +#define VIDEO_DISPLAY_CTRL_HORIZONTAL_MODE_REPLICATE 0 +#define VIDEO_DISPLAY_CTRL_HORIZONTAL_MODE_INTERPOLATE 1 +#define VIDEO_DISPLAY_CTRL_PIXEL 7:4 +#define VIDEO_DISPLAY_CTRL_GAMMA 3:3 +#define VIDEO_DISPLAY_CTRL_GAMMA_DISABLE 0 +#define VIDEO_DISPLAY_CTRL_GAMMA_ENABLE 1 +#define VIDEO_DISPLAY_CTRL_PLANE 2:2 +#define VIDEO_DISPLAY_CTRL_PLANE_DISABLE 0 +#define VIDEO_DISPLAY_CTRL_PLANE_ENABLE 1 +#define VIDEO_DISPLAY_CTRL_FORMAT 1:0 +#define VIDEO_DISPLAY_CTRL_FORMAT_8 0 +#define VIDEO_DISPLAY_CTRL_FORMAT_16 1 +#define VIDEO_DISPLAY_CTRL_FORMAT_32 2 +#define VIDEO_DISPLAY_CTRL_FORMAT_YUV 3 + +#define VIDEO_FB_0_ADDRESS 0x080044 +#define VIDEO_FB_0_ADDRESS_STATUS 31:31 +#define VIDEO_FB_0_ADDRESS_STATUS_CURRENT 0 +#define VIDEO_FB_0_ADDRESS_STATUS_PENDING 1 +#define VIDEO_FB_0_ADDRESS_EXT 27:27 +#define VIDEO_FB_0_ADDRESS_EXT_LOCAL 0 +#define VIDEO_FB_0_ADDRESS_EXT_EXTERNAL 1 +#define VIDEO_FB_0_ADDRESS_ADDRESS 25:0 + +#define VIDEO_FB_WIDTH 0x080048 +#define VIDEO_FB_WIDTH_WIDTH 29:16 +#define VIDEO_FB_WIDTH_OFFSET 13:0 + +#define VIDEO_FB_0_LAST_ADDRESS 0x08004C +#define VIDEO_FB_0_LAST_ADDRESS_EXT 27:27 +#define VIDEO_FB_0_LAST_ADDRESS_EXT_LOCAL 0 +#define VIDEO_FB_0_LAST_ADDRESS_EXT_EXTERNAL 1 +#define VIDEO_FB_0_LAST_ADDRESS_ADDRESS 25:0 + +#define VIDEO_PLANE_TL 0x080050 +#define VIDEO_PLANE_TL_TOP 26:16 +#define VIDEO_PLANE_TL_LEFT 10:0 + +#define VIDEO_PLANE_BR 0x080054 +#define VIDEO_PLANE_BR_BOTTOM 26:16 +#define VIDEO_PLANE_BR_RIGHT 10:0 + +#define VIDEO_SCALE 0x080058 +#define VIDEO_SCALE_VERTICAL_MODE 31:31 +#define VIDEO_SCALE_VERTICAL_MODE_EXPAND 0 +#define VIDEO_SCALE_VERTICAL_MODE_SHRINK 1 +#define VIDEO_SCALE_VERTICAL_SCALE 27:16 +#define VIDEO_SCALE_HORIZONTAL_MODE 15:15 +#define VIDEO_SCALE_HORIZONTAL_MODE_EXPAND 0 +#define VIDEO_SCALE_HORIZONTAL_MODE_SHRINK 1 +#define VIDEO_SCALE_HORIZONTAL_SCALE 11:0 + +#define VIDEO_INITIAL_SCALE 0x08005C +#define VIDEO_INITIAL_SCALE_FB_1 27:16 +#define VIDEO_INITIAL_SCALE_FB_0 11:0 + +#define VIDEO_YUV_CONSTANTS 0x080060 +#define VIDEO_YUV_CONSTANTS_Y 31:24 +#define VIDEO_YUV_CONSTANTS_R 23:16 +#define VIDEO_YUV_CONSTANTS_G 15:8 +#define VIDEO_YUV_CONSTANTS_B 7:0 + +#define VIDEO_FB_1_ADDRESS 0x080064 +#define VIDEO_FB_1_ADDRESS_STATUS 31:31 +#define VIDEO_FB_1_ADDRESS_STATUS_CURRENT 0 +#define VIDEO_FB_1_ADDRESS_STATUS_PENDING 1 +#define VIDEO_FB_1_ADDRESS_EXT 27:27 +#define VIDEO_FB_1_ADDRESS_EXT_LOCAL 0 +#define VIDEO_FB_1_ADDRESS_EXT_EXTERNAL 1 +#define VIDEO_FB_1_ADDRESS_ADDRESS 25:0 + +#define VIDEO_FB_1_LAST_ADDRESS 0x080068 +#define VIDEO_FB_1_LAST_ADDRESS_EXT 27:27 +#define VIDEO_FB_1_LAST_ADDRESS_EXT_LOCAL 0 +#define VIDEO_FB_1_LAST_ADDRESS_EXT_EXTERNAL 1 +#define VIDEO_FB_1_LAST_ADDRESS_ADDRESS 25:0 + +/* Video Alpha Control */ + +#define VIDEO_ALPHA_DISPLAY_CTRL 0x080080 +#define VIDEO_ALPHA_DISPLAY_CTRL_SELECT 28:28 +#define VIDEO_ALPHA_DISPLAY_CTRL_SELECT_PER_PIXEL 0 +#define VIDEO_ALPHA_DISPLAY_CTRL_SELECT_ALPHA 1 +#define VIDEO_ALPHA_DISPLAY_CTRL_ALPHA 27:24 +#define VIDEO_ALPHA_DISPLAY_CTRL_FIFO 17:16 +#define VIDEO_ALPHA_DISPLAY_CTRL_FIFO_1 0 +#define VIDEO_ALPHA_DISPLAY_CTRL_FIFO_3 1 +#define VIDEO_ALPHA_DISPLAY_CTRL_FIFO_7 2 +#define VIDEO_ALPHA_DISPLAY_CTRL_FIFO_11 3 +#define VIDEO_ALPHA_DISPLAY_CTRL_VERT_SCALE 11:11 +#define VIDEO_ALPHA_DISPLAY_CTRL_VERT_SCALE_NORMAL 0 +#define VIDEO_ALPHA_DISPLAY_CTRL_VERT_SCALE_HALF 1 +#define VIDEO_ALPHA_DISPLAY_CTRL_HORZ_SCALE 10:10 +#define VIDEO_ALPHA_DISPLAY_CTRL_HORZ_SCALE_NORMAL 0 +#define VIDEO_ALPHA_DISPLAY_CTRL_HORZ_SCALE_HALF 1 +#define VIDEO_ALPHA_DISPLAY_CTRL_VERT_MODE 9:9 +#define VIDEO_ALPHA_DISPLAY_CTRL_VERT_MODE_REPLICATE 0 +#define VIDEO_ALPHA_DISPLAY_CTRL_VERT_MODE_INTERPOLATE 1 +#define VIDEO_ALPHA_DISPLAY_CTRL_HORZ_MODE 8:8 +#define VIDEO_ALPHA_DISPLAY_CTRL_HORZ_MODE_REPLICATE 0 +#define VIDEO_ALPHA_DISPLAY_CTRL_HORZ_MODE_INTERPOLATE 1 +#define VIDEO_ALPHA_DISPLAY_CTRL_PIXEL 7:4 +#define VIDEO_ALPHA_DISPLAY_CTRL_CHROMA_KEY 3:3 +#define VIDEO_ALPHA_DISPLAY_CTRL_CHROMA_KEY_DISABLE 0 +#define VIDEO_ALPHA_DISPLAY_CTRL_CHROMA_KEY_ENABLE 1 +#define VIDEO_ALPHA_DISPLAY_CTRL_PLANE 2:2 +#define VIDEO_ALPHA_DISPLAY_CTRL_PLANE_DISABLE 0 +#define VIDEO_ALPHA_DISPLAY_CTRL_PLANE_ENABLE 1 +#define VIDEO_ALPHA_DISPLAY_CTRL_FORMAT 1:0 +#define VIDEO_ALPHA_DISPLAY_CTRL_FORMAT_8 0 +#define VIDEO_ALPHA_DISPLAY_CTRL_FORMAT_16 1 +#define VIDEO_ALPHA_DISPLAY_CTRL_FORMAT_ALPHA_4_4 2 +#define VIDEO_ALPHA_DISPLAY_CTRL_FORMAT_ALPHA_4_4_4_4 3 + +#define VIDEO_ALPHA_FB_ADDRESS 0x080084 +#define VIDEO_ALPHA_FB_ADDRESS_STATUS 31:31 +#define VIDEO_ALPHA_FB_ADDRESS_STATUS_CURRENT 0 +#define VIDEO_ALPHA_FB_ADDRESS_STATUS_PENDING 1 +#define VIDEO_ALPHA_FB_ADDRESS_EXT 27:27 +#define VIDEO_ALPHA_FB_ADDRESS_EXT_LOCAL 0 +#define VIDEO_ALPHA_FB_ADDRESS_EXT_EXTERNAL 1 +#define VIDEO_ALPHA_FB_ADDRESS_ADDRESS 25:0 + +#define VIDEO_ALPHA_FB_WIDTH 0x080088 +#define VIDEO_ALPHA_FB_WIDTH_WIDTH 29:16 +#define VIDEO_ALPHA_FB_WIDTH_OFFSET 13:0 + +#define VIDEO_ALPHA_FB_LAST_ADDRESS 0x08008C +#define VIDEO_ALPHA_FB_LAST_ADDRESS_EXT 27:27 +#define VIDEO_ALPHA_FB_LAST_ADDRESS_EXT_LOCAL 0 +#define VIDEO_ALPHA_FB_LAST_ADDRESS_EXT_EXTERNAL 1 +#define VIDEO_ALPHA_FB_LAST_ADDRESS_ADDRESS 25:0 + +#define VIDEO_ALPHA_PLANE_TL 0x080090 +#define VIDEO_ALPHA_PLANE_TL_TOP 26:16 +#define VIDEO_ALPHA_PLANE_TL_LEFT 10:0 + +#define VIDEO_ALPHA_PLANE_BR 0x080094 +#define VIDEO_ALPHA_PLANE_BR_BOTTOM 26:16 +#define VIDEO_ALPHA_PLANE_BR_RIGHT 10:0 + +#define VIDEO_ALPHA_SCALE 0x080098 +#define VIDEO_ALPHA_SCALE_VERTICAL_MODE 31:31 +#define VIDEO_ALPHA_SCALE_VERTICAL_MODE_EXPAND 0 +#define VIDEO_ALPHA_SCALE_VERTICAL_MODE_SHRINK 1 +#define VIDEO_ALPHA_SCALE_VERTICAL_SCALE 27:16 +#define VIDEO_ALPHA_SCALE_HORIZONTAL_MODE 15:15 +#define VIDEO_ALPHA_SCALE_HORIZONTAL_MODE_EXPAND 0 +#define VIDEO_ALPHA_SCALE_HORIZONTAL_MODE_SHRINK 1 +#define VIDEO_ALPHA_SCALE_HORIZONTAL_SCALE 11:0 + +#define VIDEO_ALPHA_INITIAL_SCALE 0x08009C +#define VIDEO_ALPHA_INITIAL_SCALE_VERTICAL 27:16 +#define VIDEO_ALPHA_INITIAL_SCALE_HORIZONTAL 11:0 + +#define VIDEO_ALPHA_CHROMA_KEY 0x0800A0 +#define VIDEO_ALPHA_CHROMA_KEY_MASK 31:16 +#define VIDEO_ALPHA_CHROMA_KEY_VALUE 15:0 + +#define VIDEO_ALPHA_COLOR_LOOKUP_01 0x0800A4 +#define VIDEO_ALPHA_COLOR_LOOKUP_01_1 31:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_01_1_RED 31:27 +#define VIDEO_ALPHA_COLOR_LOOKUP_01_1_GREEN 26:21 +#define VIDEO_ALPHA_COLOR_LOOKUP_01_1_BLUE 20:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_01_0 15:0 +#define VIDEO_ALPHA_COLOR_LOOKUP_01_0_RED 15:11 +#define VIDEO_ALPHA_COLOR_LOOKUP_01_0_GREEN 10:5 +#define VIDEO_ALPHA_COLOR_LOOKUP_01_0_BLUE 4:0 + +#define VIDEO_ALPHA_COLOR_LOOKUP_23 0x0800A8 +#define VIDEO_ALPHA_COLOR_LOOKUP_23_3 31:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_23_3_RED 31:27 +#define VIDEO_ALPHA_COLOR_LOOKUP_23_3_GREEN 26:21 +#define VIDEO_ALPHA_COLOR_LOOKUP_23_3_BLUE 20:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_23_2 15:0 +#define VIDEO_ALPHA_COLOR_LOOKUP_23_2_RED 15:11 +#define VIDEO_ALPHA_COLOR_LOOKUP_23_2_GREEN 10:5 +#define VIDEO_ALPHA_COLOR_LOOKUP_23_2_BLUE 4:0 + +#define VIDEO_ALPHA_COLOR_LOOKUP_45 0x0800AC +#define VIDEO_ALPHA_COLOR_LOOKUP_45_5 31:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_45_5_RED 31:27 +#define VIDEO_ALPHA_COLOR_LOOKUP_45_5_GREEN 26:21 +#define VIDEO_ALPHA_COLOR_LOOKUP_45_5_BLUE 20:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_45_4 15:0 +#define VIDEO_ALPHA_COLOR_LOOKUP_45_4_RED 15:11 +#define VIDEO_ALPHA_COLOR_LOOKUP_45_4_GREEN 10:5 +#define VIDEO_ALPHA_COLOR_LOOKUP_45_4_BLUE 4:0 + +#define VIDEO_ALPHA_COLOR_LOOKUP_67 0x0800B0 +#define VIDEO_ALPHA_COLOR_LOOKUP_67_7 31:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_67_7_RED 31:27 +#define VIDEO_ALPHA_COLOR_LOOKUP_67_7_GREEN 26:21 +#define VIDEO_ALPHA_COLOR_LOOKUP_67_7_BLUE 20:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_67_6 15:0 +#define VIDEO_ALPHA_COLOR_LOOKUP_67_6_RED 15:11 +#define VIDEO_ALPHA_COLOR_LOOKUP_67_6_GREEN 10:5 +#define VIDEO_ALPHA_COLOR_LOOKUP_67_6_BLUE 4:0 + +#define VIDEO_ALPHA_COLOR_LOOKUP_89 0x0800B4 +#define VIDEO_ALPHA_COLOR_LOOKUP_89_9 31:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_89_9_RED 31:27 +#define VIDEO_ALPHA_COLOR_LOOKUP_89_9_GREEN 26:21 +#define VIDEO_ALPHA_COLOR_LOOKUP_89_9_BLUE 20:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_89_8 15:0 +#define VIDEO_ALPHA_COLOR_LOOKUP_89_8_RED 15:11 +#define VIDEO_ALPHA_COLOR_LOOKUP_89_8_GREEN 10:5 +#define VIDEO_ALPHA_COLOR_LOOKUP_89_8_BLUE 4:0 + +#define VIDEO_ALPHA_COLOR_LOOKUP_AB 0x0800B8 +#define VIDEO_ALPHA_COLOR_LOOKUP_AB_B 31:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_AB_B_RED 31:27 +#define VIDEO_ALPHA_COLOR_LOOKUP_AB_B_GREEN 26:21 +#define VIDEO_ALPHA_COLOR_LOOKUP_AB_B_BLUE 20:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_AB_A 15:0 +#define VIDEO_ALPHA_COLOR_LOOKUP_AB_A_RED 15:11 +#define VIDEO_ALPHA_COLOR_LOOKUP_AB_A_GREEN 10:5 +#define VIDEO_ALPHA_COLOR_LOOKUP_AB_A_BLUE 4:0 + +#define VIDEO_ALPHA_COLOR_LOOKUP_CD 0x0800BC +#define VIDEO_ALPHA_COLOR_LOOKUP_CD_D 31:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_CD_D_RED 31:27 +#define VIDEO_ALPHA_COLOR_LOOKUP_CD_D_GREEN 26:21 +#define VIDEO_ALPHA_COLOR_LOOKUP_CD_D_BLUE 20:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_CD_C 15:0 +#define VIDEO_ALPHA_COLOR_LOOKUP_CD_C_RED 15:11 +#define VIDEO_ALPHA_COLOR_LOOKUP_CD_C_GREEN 10:5 +#define VIDEO_ALPHA_COLOR_LOOKUP_CD_C_BLUE 4:0 + +#define VIDEO_ALPHA_COLOR_LOOKUP_EF 0x0800C0 +#define VIDEO_ALPHA_COLOR_LOOKUP_EF_F 31:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_EF_F_RED 31:27 +#define VIDEO_ALPHA_COLOR_LOOKUP_EF_F_GREEN 26:21 +#define VIDEO_ALPHA_COLOR_LOOKUP_EF_F_BLUE 20:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_EF_E 15:0 +#define VIDEO_ALPHA_COLOR_LOOKUP_EF_E_RED 15:11 +#define VIDEO_ALPHA_COLOR_LOOKUP_EF_E_GREEN 10:5 +#define VIDEO_ALPHA_COLOR_LOOKUP_EF_E_BLUE 4:0 + +/* Panel Cursor Control */ + +#define PANEL_HWC_ADDRESS 0x0800F0 +#define PANEL_HWC_ADDRESS_ENABLE 31:31 +#define PANEL_HWC_ADDRESS_ENABLE_DISABLE 0 +#define PANEL_HWC_ADDRESS_ENABLE_ENABLE 1 +#define PANEL_HWC_ADDRESS_EXT 27:27 +#define PANEL_HWC_ADDRESS_EXT_LOCAL 0 +#define PANEL_HWC_ADDRESS_EXT_EXTERNAL 1 +#define PANEL_HWC_ADDRESS_ADDRESS 25:0 + +#define PANEL_HWC_LOCATION 0x0800F4 +#define PANEL_HWC_LOCATION_TOP 27:27 +#define PANEL_HWC_LOCATION_TOP_INSIDE 0 +#define PANEL_HWC_LOCATION_TOP_OUTSIDE 1 +#define PANEL_HWC_LOCATION_Y 26:16 +#define PANEL_HWC_LOCATION_LEFT 11:11 +#define PANEL_HWC_LOCATION_LEFT_INSIDE 0 +#define PANEL_HWC_LOCATION_LEFT_OUTSIDE 1 +#define PANEL_HWC_LOCATION_X 10:0 + +#define PANEL_HWC_COLOR_12 0x0800F8 +#define PANEL_HWC_COLOR_12_2_RGB565 31:16 +#define PANEL_HWC_COLOR_12_1_RGB565 15:0 + +#define PANEL_HWC_COLOR_3 0x0800FC +#define PANEL_HWC_COLOR_3_RGB565 15:0 + +/* Old Definitions +++ */ +#define PANEL_HWC_COLOR_01 0x0800F8 +#define PANEL_HWC_COLOR_01_1_RED 31:27 +#define PANEL_HWC_COLOR_01_1_GREEN 26:21 +#define PANEL_HWC_COLOR_01_1_BLUE 20:16 +#define PANEL_HWC_COLOR_01_0_RED 15:11 +#define PANEL_HWC_COLOR_01_0_GREEN 10:5 +#define PANEL_HWC_COLOR_01_0_BLUE 4:0 + +#define PANEL_HWC_COLOR_2 0x0800FC +#define PANEL_HWC_COLOR_2_RED 15:11 +#define PANEL_HWC_COLOR_2_GREEN 10:5 +#define PANEL_HWC_COLOR_2_BLUE 4:0 +/* Old Definitions --- */ + +/* Alpha Control */ + +#define ALPHA_DISPLAY_CTRL 0x080100 +#define ALPHA_DISPLAY_CTRL_SELECT 28:28 +#define ALPHA_DISPLAY_CTRL_SELECT_PER_PIXEL 0 +#define ALPHA_DISPLAY_CTRL_SELECT_ALPHA 1 +#define ALPHA_DISPLAY_CTRL_ALPHA 27:24 +#define ALPHA_DISPLAY_CTRL_FIFO 17:16 +#define ALPHA_DISPLAY_CTRL_FIFO_1 0 +#define ALPHA_DISPLAY_CTRL_FIFO_3 1 +#define ALPHA_DISPLAY_CTRL_FIFO_7 2 +#define ALPHA_DISPLAY_CTRL_FIFO_11 3 +#define ALPHA_DISPLAY_CTRL_PIXEL 7:4 +#define ALPHA_DISPLAY_CTRL_CHROMA_KEY 3:3 +#define ALPHA_DISPLAY_CTRL_CHROMA_KEY_DISABLE 0 +#define ALPHA_DISPLAY_CTRL_CHROMA_KEY_ENABLE 1 +#define ALPHA_DISPLAY_CTRL_PLANE 2:2 +#define ALPHA_DISPLAY_CTRL_PLANE_DISABLE 0 +#define ALPHA_DISPLAY_CTRL_PLANE_ENABLE 1 +#define ALPHA_DISPLAY_CTRL_FORMAT 1:0 +#define ALPHA_DISPLAY_CTRL_FORMAT_16 1 +#define ALPHA_DISPLAY_CTRL_FORMAT_ALPHA_4_4 2 +#define ALPHA_DISPLAY_CTRL_FORMAT_ALPHA_4_4_4_4 3 + +#define ALPHA_FB_ADDRESS 0x080104 +#define ALPHA_FB_ADDRESS_STATUS 31:31 +#define ALPHA_FB_ADDRESS_STATUS_CURRENT 0 +#define ALPHA_FB_ADDRESS_STATUS_PENDING 1 +#define ALPHA_FB_ADDRESS_EXT 27:27 +#define ALPHA_FB_ADDRESS_EXT_LOCAL 0 +#define ALPHA_FB_ADDRESS_EXT_EXTERNAL 1 +#define ALPHA_FB_ADDRESS_ADDRESS 25:0 + +#define ALPHA_FB_WIDTH 0x080108 +#define ALPHA_FB_WIDTH_WIDTH 29:16 +#define ALPHA_FB_WIDTH_OFFSET 13:0 + +#define ALPHA_PLANE_TL 0x08010C +#define ALPHA_PLANE_TL_TOP 26:16 +#define ALPHA_PLANE_TL_LEFT 10:0 + +#define ALPHA_PLANE_BR 0x080110 +#define ALPHA_PLANE_BR_BOTTOM 26:16 +#define ALPHA_PLANE_BR_RIGHT 10:0 + +#define ALPHA_CHROMA_KEY 0x080114 +#define ALPHA_CHROMA_KEY_MASK 31:16 +#define ALPHA_CHROMA_KEY_VALUE 15:0 + +#define ALPHA_COLOR_LOOKUP_01 0x080118 +#define ALPHA_COLOR_LOOKUP_01_1 31:16 +#define ALPHA_COLOR_LOOKUP_01_1_RED 31:27 +#define ALPHA_COLOR_LOOKUP_01_1_GREEN 26:21 +#define ALPHA_COLOR_LOOKUP_01_1_BLUE 20:16 +#define ALPHA_COLOR_LOOKUP_01_0 15:0 +#define ALPHA_COLOR_LOOKUP_01_0_RED 15:11 +#define ALPHA_COLOR_LOOKUP_01_0_GREEN 10:5 +#define ALPHA_COLOR_LOOKUP_01_0_BLUE 4:0 + +#define ALPHA_COLOR_LOOKUP_23 0x08011C +#define ALPHA_COLOR_LOOKUP_23_3 31:16 +#define ALPHA_COLOR_LOOKUP_23_3_RED 31:27 +#define ALPHA_COLOR_LOOKUP_23_3_GREEN 26:21 +#define ALPHA_COLOR_LOOKUP_23_3_BLUE 20:16 +#define ALPHA_COLOR_LOOKUP_23_2 15:0 +#define ALPHA_COLOR_LOOKUP_23_2_RED 15:11 +#define ALPHA_COLOR_LOOKUP_23_2_GREEN 10:5 +#define ALPHA_COLOR_LOOKUP_23_2_BLUE 4:0 + +#define ALPHA_COLOR_LOOKUP_45 0x080120 +#define ALPHA_COLOR_LOOKUP_45_5 31:16 +#define ALPHA_COLOR_LOOKUP_45_5_RED 31:27 +#define ALPHA_COLOR_LOOKUP_45_5_GREEN 26:21 +#define ALPHA_COLOR_LOOKUP_45_5_BLUE 20:16 +#define ALPHA_COLOR_LOOKUP_45_4 15:0 +#define ALPHA_COLOR_LOOKUP_45_4_RED 15:11 +#define ALPHA_COLOR_LOOKUP_45_4_GREEN 10:5 +#define ALPHA_COLOR_LOOKUP_45_4_BLUE 4:0 + +#define ALPHA_COLOR_LOOKUP_67 0x080124 +#define ALPHA_COLOR_LOOKUP_67_7 31:16 +#define ALPHA_COLOR_LOOKUP_67_7_RED 31:27 +#define ALPHA_COLOR_LOOKUP_67_7_GREEN 26:21 +#define ALPHA_COLOR_LOOKUP_67_7_BLUE 20:16 +#define ALPHA_COLOR_LOOKUP_67_6 15:0 +#define ALPHA_COLOR_LOOKUP_67_6_RED 15:11 +#define ALPHA_COLOR_LOOKUP_67_6_GREEN 10:5 +#define ALPHA_COLOR_LOOKUP_67_6_BLUE 4:0 + +#define ALPHA_COLOR_LOOKUP_89 0x080128 +#define ALPHA_COLOR_LOOKUP_89_9 31:16 +#define ALPHA_COLOR_LOOKUP_89_9_RED 31:27 +#define ALPHA_COLOR_LOOKUP_89_9_GREEN 26:21 +#define ALPHA_COLOR_LOOKUP_89_9_BLUE 20:16 +#define ALPHA_COLOR_LOOKUP_89_8 15:0 +#define ALPHA_COLOR_LOOKUP_89_8_RED 15:11 +#define ALPHA_COLOR_LOOKUP_89_8_GREEN 10:5 +#define ALPHA_COLOR_LOOKUP_89_8_BLUE 4:0 + +#define ALPHA_COLOR_LOOKUP_AB 0x08012C +#define ALPHA_COLOR_LOOKUP_AB_B 31:16 +#define ALPHA_COLOR_LOOKUP_AB_B_RED 31:27 +#define ALPHA_COLOR_LOOKUP_AB_B_GREEN 26:21 +#define ALPHA_COLOR_LOOKUP_AB_B_BLUE 20:16 +#define ALPHA_COLOR_LOOKUP_AB_A 15:0 +#define ALPHA_COLOR_LOOKUP_AB_A_RED 15:11 +#define ALPHA_COLOR_LOOKUP_AB_A_GREEN 10:5 +#define ALPHA_COLOR_LOOKUP_AB_A_BLUE 4:0 + +#define ALPHA_COLOR_LOOKUP_CD 0x080130 +#define ALPHA_COLOR_LOOKUP_CD_D 31:16 +#define ALPHA_COLOR_LOOKUP_CD_D_RED 31:27 +#define ALPHA_COLOR_LOOKUP_CD_D_GREEN 26:21 +#define ALPHA_COLOR_LOOKUP_CD_D_BLUE 20:16 +#define ALPHA_COLOR_LOOKUP_CD_C 15:0 +#define ALPHA_COLOR_LOOKUP_CD_C_RED 15:11 +#define ALPHA_COLOR_LOOKUP_CD_C_GREEN 10:5 +#define ALPHA_COLOR_LOOKUP_CD_C_BLUE 4:0 + +#define ALPHA_COLOR_LOOKUP_EF 0x080134 +#define ALPHA_COLOR_LOOKUP_EF_F 31:16 +#define ALPHA_COLOR_LOOKUP_EF_F_RED 31:27 +#define ALPHA_COLOR_LOOKUP_EF_F_GREEN 26:21 +#define ALPHA_COLOR_LOOKUP_EF_F_BLUE 20:16 +#define ALPHA_COLOR_LOOKUP_EF_E 15:0 +#define ALPHA_COLOR_LOOKUP_EF_E_RED 15:11 +#define ALPHA_COLOR_LOOKUP_EF_E_GREEN 10:5 +#define ALPHA_COLOR_LOOKUP_EF_E_BLUE 4:0 + +/* CRT Graphics Control */ + +#define CRT_DISPLAY_CTRL 0x080200 +#define CRT_DISPLAY_CTRL_RESERVED_1_MASK 31:27 +#define CRT_DISPLAY_CTRL_RESERVED_1_MASK_DISABLE 0 +#define CRT_DISPLAY_CTRL_RESERVED_1_MASK_ENABLE 0x1F + +/* SM750LE definition */ +#define CRT_DISPLAY_CTRL_DPMS 31:30 +#define CRT_DISPLAY_CTRL_DPMS_0 0 +#define CRT_DISPLAY_CTRL_DPMS_1 1 +#define CRT_DISPLAY_CTRL_DPMS_2 2 +#define CRT_DISPLAY_CTRL_DPMS_3 3 +#define CRT_DISPLAY_CTRL_CLK 29:27 +#define CRT_DISPLAY_CTRL_CLK_PLL25 0 +#define CRT_DISPLAY_CTRL_CLK_PLL41 1 +#define CRT_DISPLAY_CTRL_CLK_PLL62 2 +#define CRT_DISPLAY_CTRL_CLK_PLL65 3 +#define CRT_DISPLAY_CTRL_CLK_PLL74 4 +#define CRT_DISPLAY_CTRL_CLK_PLL80 5 +#define CRT_DISPLAY_CTRL_CLK_PLL108 6 +#define CRT_DISPLAY_CTRL_CLK_RESERVED 7 +#define CRT_DISPLAY_CTRL_SHIFT_VGA_DAC 26:26 +#define CRT_DISPLAY_CTRL_SHIFT_VGA_DAC_DISABLE 1 +#define CRT_DISPLAY_CTRL_SHIFT_VGA_DAC_ENABLE 0 + + +#define CRT_DISPLAY_CTRL_RESERVED_2_MASK 25:24 +#define CRT_DISPLAY_CTRL_RESERVED_2_MASK_ENABLE 3 +#define CRT_DISPLAY_CTRL_RESERVED_2_MASK_DISABLE 0 + +/* SM750LE definition */ +#define CRT_DISPLAY_CTRL_CRTSELECT 25:25 +#define CRT_DISPLAY_CTRL_CRTSELECT_VGA 0 +#define CRT_DISPLAY_CTRL_CRTSELECT_CRT 1 +#define CRT_DISPLAY_CTRL_RGBBIT 24:24 +#define CRT_DISPLAY_CTRL_RGBBIT_24BIT 0 +#define CRT_DISPLAY_CTRL_RGBBIT_12BIT 1 + + +#define CRT_DISPLAY_CTRL_RESERVED_3_MASK 15:15 +#define CRT_DISPLAY_CTRL_RESERVED_3_MASK_DISABLE 0 +#define CRT_DISPLAY_CTRL_RESERVED_3_MASK_ENABLE 1 + +#define CRT_DISPLAY_CTRL_RESERVED_4_MASK 9:9 +#define CRT_DISPLAY_CTRL_RESERVED_4_MASK_DISABLE 0 +#define CRT_DISPLAY_CTRL_RESERVED_4_MASK_ENABLE 1 + +#ifndef VALIDATION_CHIP + #define CRT_DISPLAY_CTRL_SHIFT_VGA_DAC 26:26 + #define CRT_DISPLAY_CTRL_SHIFT_VGA_DAC_DISABLE 1 + #define CRT_DISPLAY_CTRL_SHIFT_VGA_DAC_ENABLE 0 + #define CRT_DISPLAY_CTRL_CENTERING 24:24 + #define CRT_DISPLAY_CTRL_CENTERING_DISABLE 0 + #define CRT_DISPLAY_CTRL_CENTERING_ENABLE 1 +#endif +#define CRT_DISPLAY_CTRL_LOCK_TIMING 23:23 +#define CRT_DISPLAY_CTRL_LOCK_TIMING_DISABLE 0 +#define CRT_DISPLAY_CTRL_LOCK_TIMING_ENABLE 1 +#define CRT_DISPLAY_CTRL_EXPANSION 22:22 +#define CRT_DISPLAY_CTRL_EXPANSION_DISABLE 0 +#define CRT_DISPLAY_CTRL_EXPANSION_ENABLE 1 +#define CRT_DISPLAY_CTRL_VERTICAL_MODE 21:21 +#define CRT_DISPLAY_CTRL_VERTICAL_MODE_REPLICATE 0 +#define CRT_DISPLAY_CTRL_VERTICAL_MODE_INTERPOLATE 1 +#define CRT_DISPLAY_CTRL_HORIZONTAL_MODE 20:20 +#define CRT_DISPLAY_CTRL_HORIZONTAL_MODE_REPLICATE 0 +#define CRT_DISPLAY_CTRL_HORIZONTAL_MODE_INTERPOLATE 1 +#define CRT_DISPLAY_CTRL_SELECT 19:18 +#define CRT_DISPLAY_CTRL_SELECT_PANEL 0 +#define CRT_DISPLAY_CTRL_SELECT_VGA 1 +#define CRT_DISPLAY_CTRL_SELECT_CRT 2 +#define CRT_DISPLAY_CTRL_FIFO 17:16 +#define CRT_DISPLAY_CTRL_FIFO_1 0 +#define CRT_DISPLAY_CTRL_FIFO_3 1 +#define CRT_DISPLAY_CTRL_FIFO_7 2 +#define CRT_DISPLAY_CTRL_FIFO_11 3 +#define CRT_DISPLAY_CTRL_CLOCK_PHASE 14:14 +#define CRT_DISPLAY_CTRL_CLOCK_PHASE_ACTIVE_HIGH 0 +#define CRT_DISPLAY_CTRL_CLOCK_PHASE_ACTIVE_LOW 1 +#define CRT_DISPLAY_CTRL_VSYNC_PHASE 13:13 +#define CRT_DISPLAY_CTRL_VSYNC_PHASE_ACTIVE_HIGH 0 +#define CRT_DISPLAY_CTRL_VSYNC_PHASE_ACTIVE_LOW 1 +#define CRT_DISPLAY_CTRL_HSYNC_PHASE 12:12 +#define CRT_DISPLAY_CTRL_HSYNC_PHASE_ACTIVE_HIGH 0 +#define CRT_DISPLAY_CTRL_HSYNC_PHASE_ACTIVE_LOW 1 +#define CRT_DISPLAY_CTRL_BLANK 10:10 +#define CRT_DISPLAY_CTRL_BLANK_OFF 0 +#define CRT_DISPLAY_CTRL_BLANK_ON 1 +#define CRT_DISPLAY_CTRL_TIMING 8:8 +#define CRT_DISPLAY_CTRL_TIMING_DISABLE 0 +#define CRT_DISPLAY_CTRL_TIMING_ENABLE 1 +#define CRT_DISPLAY_CTRL_PIXEL 7:4 +#define CRT_DISPLAY_CTRL_GAMMA 3:3 +#define CRT_DISPLAY_CTRL_GAMMA_DISABLE 0 +#define CRT_DISPLAY_CTRL_GAMMA_ENABLE 1 +#define CRT_DISPLAY_CTRL_PLANE 2:2 +#define CRT_DISPLAY_CTRL_PLANE_DISABLE 0 +#define CRT_DISPLAY_CTRL_PLANE_ENABLE 1 +#define CRT_DISPLAY_CTRL_FORMAT 1:0 +#define CRT_DISPLAY_CTRL_FORMAT_8 0 +#define CRT_DISPLAY_CTRL_FORMAT_16 1 +#define CRT_DISPLAY_CTRL_FORMAT_32 2 +#define CRT_DISPLAY_CTRL_RESERVED_BITS_MASK 0xFF000200 + +#define CRT_FB_ADDRESS 0x080204 +#define CRT_FB_ADDRESS_STATUS 31:31 +#define CRT_FB_ADDRESS_STATUS_CURRENT 0 +#define CRT_FB_ADDRESS_STATUS_PENDING 1 +#define CRT_FB_ADDRESS_EXT 27:27 +#define CRT_FB_ADDRESS_EXT_LOCAL 0 +#define CRT_FB_ADDRESS_EXT_EXTERNAL 1 +#define CRT_FB_ADDRESS_ADDRESS 25:0 + +#define CRT_FB_WIDTH 0x080208 +#define CRT_FB_WIDTH_WIDTH 29:16 +#define CRT_FB_WIDTH_OFFSET 13:0 + +#define CRT_HORIZONTAL_TOTAL 0x08020C +#define CRT_HORIZONTAL_TOTAL_TOTAL 27:16 +#define CRT_HORIZONTAL_TOTAL_DISPLAY_END 11:0 + +#define CRT_HORIZONTAL_SYNC 0x080210 +#define CRT_HORIZONTAL_SYNC_WIDTH 23:16 +#define CRT_HORIZONTAL_SYNC_START 11:0 + +#define CRT_VERTICAL_TOTAL 0x080214 +#define CRT_VERTICAL_TOTAL_TOTAL 26:16 +#define CRT_VERTICAL_TOTAL_DISPLAY_END 10:0 + +#define CRT_VERTICAL_SYNC 0x080218 +#define CRT_VERTICAL_SYNC_HEIGHT 21:16 +#define CRT_VERTICAL_SYNC_START 10:0 + +#define CRT_SIGNATURE_ANALYZER 0x08021C +#define CRT_SIGNATURE_ANALYZER_STATUS 31:16 +#define CRT_SIGNATURE_ANALYZER_ENABLE 3:3 +#define CRT_SIGNATURE_ANALYZER_ENABLE_DISABLE 0 +#define CRT_SIGNATURE_ANALYZER_ENABLE_ENABLE 1 +#define CRT_SIGNATURE_ANALYZER_RESET 2:2 +#define CRT_SIGNATURE_ANALYZER_RESET_NORMAL 0 +#define CRT_SIGNATURE_ANALYZER_RESET_RESET 1 +#define CRT_SIGNATURE_ANALYZER_SOURCE 1:0 +#define CRT_SIGNATURE_ANALYZER_SOURCE_RED 0 +#define CRT_SIGNATURE_ANALYZER_SOURCE_GREEN 1 +#define CRT_SIGNATURE_ANALYZER_SOURCE_BLUE 2 + +#define CRT_CURRENT_LINE 0x080220 +#define CRT_CURRENT_LINE_LINE 10:0 + +#define CRT_MONITOR_DETECT 0x080224 +#define CRT_MONITOR_DETECT_VALUE 25:25 +#define CRT_MONITOR_DETECT_VALUE_DISABLE 0 +#define CRT_MONITOR_DETECT_VALUE_ENABLE 1 +#define CRT_MONITOR_DETECT_ENABLE 24:24 +#define CRT_MONITOR_DETECT_ENABLE_DISABLE 0 +#define CRT_MONITOR_DETECT_ENABLE_ENABLE 1 +#define CRT_MONITOR_DETECT_RED 23:16 +#define CRT_MONITOR_DETECT_GREEN 15:8 +#define CRT_MONITOR_DETECT_BLUE 7:0 + +#define CRT_SCALE 0x080228 +#define CRT_SCALE_VERTICAL_MODE 31:31 +#define CRT_SCALE_VERTICAL_MODE_EXPAND 0 +#define CRT_SCALE_VERTICAL_MODE_SHRINK 1 +#define CRT_SCALE_VERTICAL_SCALE 27:16 +#define CRT_SCALE_HORIZONTAL_MODE 15:15 +#define CRT_SCALE_HORIZONTAL_MODE_EXPAND 0 +#define CRT_SCALE_HORIZONTAL_MODE_SHRINK 1 +#define CRT_SCALE_HORIZONTAL_SCALE 11:0 + +/* CRT Cursor Control */ + +#define CRT_HWC_ADDRESS 0x080230 +#define CRT_HWC_ADDRESS_ENABLE 31:31 +#define CRT_HWC_ADDRESS_ENABLE_DISABLE 0 +#define CRT_HWC_ADDRESS_ENABLE_ENABLE 1 +#define CRT_HWC_ADDRESS_EXT 27:27 +#define CRT_HWC_ADDRESS_EXT_LOCAL 0 +#define CRT_HWC_ADDRESS_EXT_EXTERNAL 1 +#define CRT_HWC_ADDRESS_ADDRESS 25:0 + +#define CRT_HWC_LOCATION 0x080234 +#define CRT_HWC_LOCATION_TOP 27:27 +#define CRT_HWC_LOCATION_TOP_INSIDE 0 +#define CRT_HWC_LOCATION_TOP_OUTSIDE 1 +#define CRT_HWC_LOCATION_Y 26:16 +#define CRT_HWC_LOCATION_LEFT 11:11 +#define CRT_HWC_LOCATION_LEFT_INSIDE 0 +#define CRT_HWC_LOCATION_LEFT_OUTSIDE 1 +#define CRT_HWC_LOCATION_X 10:0 + +#define CRT_HWC_COLOR_12 0x080238 +#define CRT_HWC_COLOR_12_2_RGB565 31:16 +#define CRT_HWC_COLOR_12_1_RGB565 15:0 + +#define CRT_HWC_COLOR_3 0x08023C +#define CRT_HWC_COLOR_3_RGB565 15:0 + +/* Old Definitions +++. Need to be removed if no application use it. */ +#if 0 + #define CRT_HWC_COLOR_01 0x080238 + #define CRT_HWC_COLOR_01_1_RED 31:27 + #define CRT_HWC_COLOR_01_1_GREEN 26:21 + #define CRT_HWC_COLOR_01_1_BLUE 20:16 + #define CRT_HWC_COLOR_01_0_RED 15:11 + #define CRT_HWC_COLOR_01_0_GREEN 10:5 + #define CRT_HWC_COLOR_01_0_BLUE 4:0 + + #define CRT_HWC_COLOR_2 0x08023C + #define CRT_HWC_COLOR_2_RED 15:11 + #define CRT_HWC_COLOR_2_GREEN 10:5 + #define CRT_HWC_COLOR_2_BLUE 4:0 +#endif +/* Old Definitions --- */ + +/* This vertical expansion below start at 0x080240 ~ 0x080264 */ +#define CRT_VERTICAL_EXPANSION 0x080240 +#ifndef VALIDATION_CHIP + #define CRT_VERTICAL_CENTERING_VALUE 31:24 +#endif +#define CRT_VERTICAL_EXPANSION_COMPARE_VALUE 23:16 +#define CRT_VERTICAL_EXPANSION_LINE_BUFFER 15:12 +#define CRT_VERTICAL_EXPANSION_SCALE_FACTOR 11:0 + +/* This horizontal expansion below start at 0x080268 ~ 0x08027C */ +#define CRT_HORIZONTAL_EXPANSION 0x080268 +#ifndef VALIDATION_CHIP + #define CRT_HORIZONTAL_CENTERING_VALUE 31:24 +#endif +#define CRT_HORIZONTAL_EXPANSION_COMPARE_VALUE 23:16 +#define CRT_HORIZONTAL_EXPANSION_SCALE_FACTOR 11:0 + +#ifndef VALIDATION_CHIP + /* Auto Centering */ + #define CRT_AUTO_CENTERING_TL 0x080280 + #define CRT_AUTO_CENTERING_TL_TOP 26:16 + #define CRT_AUTO_CENTERING_TL_LEFT 10:0 + + #define CRT_AUTO_CENTERING_BR 0x080284 + #define CRT_AUTO_CENTERING_BR_BOTTOM 26:16 + #define CRT_AUTO_CENTERING_BR_RIGHT 10:0 +#endif + +/* sm750le new register to control panel output */ +#define DISPLAY_CONTROL_750LE 0x80288 +/* Palette RAM */ + +/* Panel Pallete register starts at 0x080400 ~ 0x0807FC */ +#define PANEL_PALETTE_RAM 0x080400 + +/* Panel Pallete register starts at 0x080C00 ~ 0x080FFC */ +#define CRT_PALETTE_RAM 0x080C00 + +/* 2D registers + * move their defination into general lynx_accel.h file + * because all smi graphic chip share the same drawing engine + * register format */ +#if 0 +#define DE_SOURCE 0x100000 +#define DE_SOURCE_WRAP 31:31 +#define DE_SOURCE_WRAP_DISABLE 0 +#define DE_SOURCE_WRAP_ENABLE 1 + +/* + * The following definitions are used in different setting + */ + +/* Use these definitions in XY addressing mode or linear addressing mode. */ +#define DE_SOURCE_X_K1 27:16 +#define DE_SOURCE_Y_K2 11:0 + +/* Use this definition in host write mode for mono. The Y_K2 is not used + in host write mode. */ +#define DE_SOURCE_X_K1_MONO 20:16 + +/* Use these definitions in Bresenham line drawing mode. */ +#define DE_SOURCE_X_K1_LINE 29:16 +#define DE_SOURCE_Y_K2_LINE 13:0 + +#define DE_DESTINATION 0x100004 +#define DE_DESTINATION_WRAP 31:31 +#define DE_DESTINATION_WRAP_DISABLE 0 +#define DE_DESTINATION_WRAP_ENABLE 1 +#if 1 + #define DE_DESTINATION_X 27:16 + #define DE_DESTINATION_Y 11:0 +#else + #define DE_DESTINATION_X 28:16 + #define DE_DESTINATION_Y 15:0 +#endif + +#define DE_DIMENSION 0x100008 +#define DE_DIMENSION_X 28:16 +#define DE_DIMENSION_Y_ET 15:0 + +#define DE_CONTROL 0x10000C +#define DE_CONTROL_STATUS 31:31 +#define DE_CONTROL_STATUS_STOP 0 +#define DE_CONTROL_STATUS_START 1 +#define DE_CONTROL_PATTERN 30:30 +#define DE_CONTROL_PATTERN_MONO 0 +#define DE_CONTROL_PATTERN_COLOR 1 +#define DE_CONTROL_UPDATE_DESTINATION_X 29:29 +#define DE_CONTROL_UPDATE_DESTINATION_X_DISABLE 0 +#define DE_CONTROL_UPDATE_DESTINATION_X_ENABLE 1 +#define DE_CONTROL_QUICK_START 28:28 +#define DE_CONTROL_QUICK_START_DISABLE 0 +#define DE_CONTROL_QUICK_START_ENABLE 1 +#define DE_CONTROL_DIRECTION 27:27 +#define DE_CONTROL_DIRECTION_LEFT_TO_RIGHT 0 +#define DE_CONTROL_DIRECTION_RIGHT_TO_LEFT 1 +#define DE_CONTROL_MAJOR 26:26 +#define DE_CONTROL_MAJOR_X 0 +#define DE_CONTROL_MAJOR_Y 1 +#define DE_CONTROL_STEP_X 25:25 +#define DE_CONTROL_STEP_X_POSITIVE 0 +#define DE_CONTROL_STEP_X_NEGATIVE 1 +#define DE_CONTROL_STEP_Y 24:24 +#define DE_CONTROL_STEP_Y_POSITIVE 0 +#define DE_CONTROL_STEP_Y_NEGATIVE 1 +#define DE_CONTROL_STRETCH 23:23 +#define DE_CONTROL_STRETCH_DISABLE 0 +#define DE_CONTROL_STRETCH_ENABLE 1 +#define DE_CONTROL_HOST 22:22 +#define DE_CONTROL_HOST_COLOR 0 +#define DE_CONTROL_HOST_MONO 1 +#define DE_CONTROL_LAST_PIXEL 21:21 +#define DE_CONTROL_LAST_PIXEL_OFF 0 +#define DE_CONTROL_LAST_PIXEL_ON 1 +#define DE_CONTROL_COMMAND 20:16 +#define DE_CONTROL_COMMAND_BITBLT 0 +#define DE_CONTROL_COMMAND_RECTANGLE_FILL 1 +#define DE_CONTROL_COMMAND_DE_TILE 2 +#define DE_CONTROL_COMMAND_TRAPEZOID_FILL 3 +#define DE_CONTROL_COMMAND_ALPHA_BLEND 4 +#define DE_CONTROL_COMMAND_RLE_STRIP 5 +#define DE_CONTROL_COMMAND_SHORT_STROKE 6 +#define DE_CONTROL_COMMAND_LINE_DRAW 7 +#define DE_CONTROL_COMMAND_HOST_WRITE 8 +#define DE_CONTROL_COMMAND_HOST_READ 9 +#define DE_CONTROL_COMMAND_HOST_WRITE_BOTTOM_UP 10 +#define DE_CONTROL_COMMAND_ROTATE 11 +#define DE_CONTROL_COMMAND_FONT 12 +#define DE_CONTROL_COMMAND_TEXTURE_LOAD 15 +#define DE_CONTROL_ROP_SELECT 15:15 +#define DE_CONTROL_ROP_SELECT_ROP3 0 +#define DE_CONTROL_ROP_SELECT_ROP2 1 +#define DE_CONTROL_ROP2_SOURCE 14:14 +#define DE_CONTROL_ROP2_SOURCE_BITMAP 0 +#define DE_CONTROL_ROP2_SOURCE_PATTERN 1 +#define DE_CONTROL_MONO_DATA 13:12 +#define DE_CONTROL_MONO_DATA_NOT_PACKED 0 +#define DE_CONTROL_MONO_DATA_8_PACKED 1 +#define DE_CONTROL_MONO_DATA_16_PACKED 2 +#define DE_CONTROL_MONO_DATA_32_PACKED 3 +#define DE_CONTROL_REPEAT_ROTATE 11:11 +#define DE_CONTROL_REPEAT_ROTATE_DISABLE 0 +#define DE_CONTROL_REPEAT_ROTATE_ENABLE 1 +#define DE_CONTROL_TRANSPARENCY_MATCH 10:10 +#define DE_CONTROL_TRANSPARENCY_MATCH_OPAQUE 0 +#define DE_CONTROL_TRANSPARENCY_MATCH_TRANSPARENT 1 +#define DE_CONTROL_TRANSPARENCY_SELECT 9:9 +#define DE_CONTROL_TRANSPARENCY_SELECT_SOURCE 0 +#define DE_CONTROL_TRANSPARENCY_SELECT_DESTINATION 1 +#define DE_CONTROL_TRANSPARENCY 8:8 +#define DE_CONTROL_TRANSPARENCY_DISABLE 0 +#define DE_CONTROL_TRANSPARENCY_ENABLE 1 +#define DE_CONTROL_ROP 7:0 + +/* Pseudo fields. */ + +#define DE_CONTROL_SHORT_STROKE_DIR 27:24 +#define DE_CONTROL_SHORT_STROKE_DIR_225 0 +#define DE_CONTROL_SHORT_STROKE_DIR_135 1 +#define DE_CONTROL_SHORT_STROKE_DIR_315 2 +#define DE_CONTROL_SHORT_STROKE_DIR_45 3 +#define DE_CONTROL_SHORT_STROKE_DIR_270 4 +#define DE_CONTROL_SHORT_STROKE_DIR_90 5 +#define DE_CONTROL_SHORT_STROKE_DIR_180 8 +#define DE_CONTROL_SHORT_STROKE_DIR_0 10 +#define DE_CONTROL_ROTATION 25:24 +#define DE_CONTROL_ROTATION_0 0 +#define DE_CONTROL_ROTATION_270 1 +#define DE_CONTROL_ROTATION_90 2 +#define DE_CONTROL_ROTATION_180 3 + +#define DE_PITCH 0x100010 +#define DE_PITCH_DESTINATION 28:16 +#define DE_PITCH_SOURCE 12:0 + +#define DE_FOREGROUND 0x100014 +#define DE_FOREGROUND_COLOR 31:0 + +#define DE_BACKGROUND 0x100018 +#define DE_BACKGROUND_COLOR 31:0 + +#define DE_STRETCH_FORMAT 0x10001C +#define DE_STRETCH_FORMAT_PATTERN_XY 30:30 +#define DE_STRETCH_FORMAT_PATTERN_XY_NORMAL 0 +#define DE_STRETCH_FORMAT_PATTERN_XY_OVERWRITE 1 +#define DE_STRETCH_FORMAT_PATTERN_Y 29:27 +#define DE_STRETCH_FORMAT_PATTERN_X 25:23 +#define DE_STRETCH_FORMAT_PIXEL_FORMAT 21:20 +#define DE_STRETCH_FORMAT_PIXEL_FORMAT_8 0 +#define DE_STRETCH_FORMAT_PIXEL_FORMAT_16 1 +#define DE_STRETCH_FORMAT_PIXEL_FORMAT_32 2 +#define DE_STRETCH_FORMAT_ADDRESSING 19:16 +#define DE_STRETCH_FORMAT_ADDRESSING_XY 0 +#define DE_STRETCH_FORMAT_ADDRESSING_LINEAR 15 +#define DE_STRETCH_FORMAT_SOURCE_HEIGHT 11:0 + +#define DE_COLOR_COMPARE 0x100020 +#define DE_COLOR_COMPARE_COLOR 23:0 + +#define DE_COLOR_COMPARE_MASK 0x100024 +#define DE_COLOR_COMPARE_MASK_MASKS 23:0 + +#define DE_MASKS 0x100028 +#define DE_MASKS_BYTE_MASK 31:16 +#define DE_MASKS_BIT_MASK 15:0 + +#define DE_CLIP_TL 0x10002C +#define DE_CLIP_TL_TOP 31:16 +#define DE_CLIP_TL_STATUS 13:13 +#define DE_CLIP_TL_STATUS_DISABLE 0 +#define DE_CLIP_TL_STATUS_ENABLE 1 +#define DE_CLIP_TL_INHIBIT 12:12 +#define DE_CLIP_TL_INHIBIT_OUTSIDE 0 +#define DE_CLIP_TL_INHIBIT_INSIDE 1 +#define DE_CLIP_TL_LEFT 11:0 + +#define DE_CLIP_BR 0x100030 +#define DE_CLIP_BR_BOTTOM 31:16 +#define DE_CLIP_BR_RIGHT 12:0 + +#define DE_MONO_PATTERN_LOW 0x100034 +#define DE_MONO_PATTERN_LOW_PATTERN 31:0 + +#define DE_MONO_PATTERN_HIGH 0x100038 +#define DE_MONO_PATTERN_HIGH_PATTERN 31:0 + +#define DE_WINDOW_WIDTH 0x10003C +#define DE_WINDOW_WIDTH_DESTINATION 28:16 +#define DE_WINDOW_WIDTH_SOURCE 12:0 + +#define DE_WINDOW_SOURCE_BASE 0x100040 +#define DE_WINDOW_SOURCE_BASE_EXT 27:27 +#define DE_WINDOW_SOURCE_BASE_EXT_LOCAL 0 +#define DE_WINDOW_SOURCE_BASE_EXT_EXTERNAL 1 +#define DE_WINDOW_SOURCE_BASE_CS 26:26 +#define DE_WINDOW_SOURCE_BASE_CS_0 0 +#define DE_WINDOW_SOURCE_BASE_CS_1 1 +#define DE_WINDOW_SOURCE_BASE_ADDRESS 25:0 + +#define DE_WINDOW_DESTINATION_BASE 0x100044 +#define DE_WINDOW_DESTINATION_BASE_EXT 27:27 +#define DE_WINDOW_DESTINATION_BASE_EXT_LOCAL 0 +#define DE_WINDOW_DESTINATION_BASE_EXT_EXTERNAL 1 +#define DE_WINDOW_DESTINATION_BASE_CS 26:26 +#define DE_WINDOW_DESTINATION_BASE_CS_0 0 +#define DE_WINDOW_DESTINATION_BASE_CS_1 1 +#define DE_WINDOW_DESTINATION_BASE_ADDRESS 25:0 + +#define DE_ALPHA 0x100048 +#define DE_ALPHA_VALUE 7:0 + +#define DE_WRAP 0x10004C +#define DE_WRAP_X 31:16 +#define DE_WRAP_Y 15:0 + +#define DE_STATUS 0x100050 +#define DE_STATUS_CSC 1:1 +#define DE_STATUS_CSC_CLEAR 0 +#define DE_STATUS_CSC_NOT_ACTIVE 0 +#define DE_STATUS_CSC_ACTIVE 1 +#define DE_STATUS_2D 0:0 +#define DE_STATUS_2D_CLEAR 0 +#define DE_STATUS_2D_NOT_ACTIVE 0 +#define DE_STATUS_2D_ACTIVE 1 +#endif +/* Color Space Conversion registers. */ + +#define CSC_Y_SOURCE_BASE 0x1000C8 +#define CSC_Y_SOURCE_BASE_EXT 27:27 +#define CSC_Y_SOURCE_BASE_EXT_LOCAL 0 +#define CSC_Y_SOURCE_BASE_EXT_EXTERNAL 1 +#define CSC_Y_SOURCE_BASE_CS 26:26 +#define CSC_Y_SOURCE_BASE_CS_0 0 +#define CSC_Y_SOURCE_BASE_CS_1 1 +#define CSC_Y_SOURCE_BASE_ADDRESS 25:0 + +#define CSC_CONSTANTS 0x1000CC +#define CSC_CONSTANTS_Y 31:24 +#define CSC_CONSTANTS_R 23:16 +#define CSC_CONSTANTS_G 15:8 +#define CSC_CONSTANTS_B 7:0 + +#define CSC_Y_SOURCE_X 0x1000D0 +#define CSC_Y_SOURCE_X_INTEGER 26:16 +#define CSC_Y_SOURCE_X_FRACTION 15:3 + +#define CSC_Y_SOURCE_Y 0x1000D4 +#define CSC_Y_SOURCE_Y_INTEGER 27:16 +#define CSC_Y_SOURCE_Y_FRACTION 15:3 + +#define CSC_U_SOURCE_BASE 0x1000D8 +#define CSC_U_SOURCE_BASE_EXT 27:27 +#define CSC_U_SOURCE_BASE_EXT_LOCAL 0 +#define CSC_U_SOURCE_BASE_EXT_EXTERNAL 1 +#define CSC_U_SOURCE_BASE_CS 26:26 +#define CSC_U_SOURCE_BASE_CS_0 0 +#define CSC_U_SOURCE_BASE_CS_1 1 +#define CSC_U_SOURCE_BASE_ADDRESS 25:0 + +#define CSC_V_SOURCE_BASE 0x1000DC +#define CSC_V_SOURCE_BASE_EXT 27:27 +#define CSC_V_SOURCE_BASE_EXT_LOCAL 0 +#define CSC_V_SOURCE_BASE_EXT_EXTERNAL 1 +#define CSC_V_SOURCE_BASE_CS 26:26 +#define CSC_V_SOURCE_BASE_CS_0 0 +#define CSC_V_SOURCE_BASE_CS_1 1 +#define CSC_V_SOURCE_BASE_ADDRESS 25:0 + +#define CSC_SOURCE_DIMENSION 0x1000E0 +#define CSC_SOURCE_DIMENSION_X 31:16 +#define CSC_SOURCE_DIMENSION_Y 15:0 + +#define CSC_SOURCE_PITCH 0x1000E4 +#define CSC_SOURCE_PITCH_Y 31:16 +#define CSC_SOURCE_PITCH_UV 15:0 + +#define CSC_DESTINATION 0x1000E8 +#define CSC_DESTINATION_WRAP 31:31 +#define CSC_DESTINATION_WRAP_DISABLE 0 +#define CSC_DESTINATION_WRAP_ENABLE 1 +#define CSC_DESTINATION_X 27:16 +#define CSC_DESTINATION_Y 11:0 + +#define CSC_DESTINATION_DIMENSION 0x1000EC +#define CSC_DESTINATION_DIMENSION_X 31:16 +#define CSC_DESTINATION_DIMENSION_Y 15:0 + +#define CSC_DESTINATION_PITCH 0x1000F0 +#define CSC_DESTINATION_PITCH_X 31:16 +#define CSC_DESTINATION_PITCH_Y 15:0 + +#define CSC_SCALE_FACTOR 0x1000F4 +#define CSC_SCALE_FACTOR_HORIZONTAL 31:16 +#define CSC_SCALE_FACTOR_VERTICAL 15:0 + +#define CSC_DESTINATION_BASE 0x1000F8 +#define CSC_DESTINATION_BASE_EXT 27:27 +#define CSC_DESTINATION_BASE_EXT_LOCAL 0 +#define CSC_DESTINATION_BASE_EXT_EXTERNAL 1 +#define CSC_DESTINATION_BASE_CS 26:26 +#define CSC_DESTINATION_BASE_CS_0 0 +#define CSC_DESTINATION_BASE_CS_1 1 +#define CSC_DESTINATION_BASE_ADDRESS 25:0 + +#define CSC_CONTROL 0x1000FC +#define CSC_CONTROL_STATUS 31:31 +#define CSC_CONTROL_STATUS_STOP 0 +#define CSC_CONTROL_STATUS_START 1 +#define CSC_CONTROL_SOURCE_FORMAT 30:28 +#define CSC_CONTROL_SOURCE_FORMAT_YUV422 0 +#define CSC_CONTROL_SOURCE_FORMAT_YUV420I 1 +#define CSC_CONTROL_SOURCE_FORMAT_YUV420 2 +#define CSC_CONTROL_SOURCE_FORMAT_YVU9 3 +#define CSC_CONTROL_SOURCE_FORMAT_IYU1 4 +#define CSC_CONTROL_SOURCE_FORMAT_IYU2 5 +#define CSC_CONTROL_SOURCE_FORMAT_RGB565 6 +#define CSC_CONTROL_SOURCE_FORMAT_RGB8888 7 +#define CSC_CONTROL_DESTINATION_FORMAT 27:26 +#define CSC_CONTROL_DESTINATION_FORMAT_RGB565 0 +#define CSC_CONTROL_DESTINATION_FORMAT_RGB8888 1 +#define CSC_CONTROL_HORIZONTAL_FILTER 25:25 +#define CSC_CONTROL_HORIZONTAL_FILTER_DISABLE 0 +#define CSC_CONTROL_HORIZONTAL_FILTER_ENABLE 1 +#define CSC_CONTROL_VERTICAL_FILTER 24:24 +#define CSC_CONTROL_VERTICAL_FILTER_DISABLE 0 +#define CSC_CONTROL_VERTICAL_FILTER_ENABLE 1 +#define CSC_CONTROL_BYTE_ORDER 23:23 +#define CSC_CONTROL_BYTE_ORDER_YUYV 0 +#define CSC_CONTROL_BYTE_ORDER_UYVY 1 + +#define DE_DATA_PORT 0x110000 + +#define I2C_BYTE_COUNT 0x010040 +#define I2C_BYTE_COUNT_COUNT 3:0 + +#define I2C_CTRL 0x010041 +#define I2C_CTRL_INT 4:4 +#define I2C_CTRL_INT_DISABLE 0 +#define I2C_CTRL_INT_ENABLE 1 +#define I2C_CTRL_DIR 3:3 +#define I2C_CTRL_DIR_WR 0 +#define I2C_CTRL_DIR_RD 1 +#define I2C_CTRL_CTRL 2:2 +#define I2C_CTRL_CTRL_STOP 0 +#define I2C_CTRL_CTRL_START 1 +#define I2C_CTRL_MODE 1:1 +#define I2C_CTRL_MODE_STANDARD 0 +#define I2C_CTRL_MODE_FAST 1 +#define I2C_CTRL_EN 0:0 +#define I2C_CTRL_EN_DISABLE 0 +#define I2C_CTRL_EN_ENABLE 1 + +#define I2C_STATUS 0x010042 +#define I2C_STATUS_TX 3:3 +#define I2C_STATUS_TX_PROGRESS 0 +#define I2C_STATUS_TX_COMPLETED 1 +#define I2C_TX_DONE 0x08 +#define I2C_STATUS_ERR 2:2 +#define I2C_STATUS_ERR_NORMAL 0 +#define I2C_STATUS_ERR_ERROR 1 +#define I2C_STATUS_ERR_CLEAR 0 +#define I2C_STATUS_ACK 1:1 +#define I2C_STATUS_ACK_RECEIVED 0 +#define I2C_STATUS_ACK_NOT 1 +#define I2C_STATUS_BSY 0:0 +#define I2C_STATUS_BSY_IDLE 0 +#define I2C_STATUS_BSY_BUSY 1 + +#define I2C_RESET 0x010042 +#define I2C_RESET_BUS_ERROR 2:2 +#define I2C_RESET_BUS_ERROR_CLEAR 0 + +#define I2C_SLAVE_ADDRESS 0x010043 +#define I2C_SLAVE_ADDRESS_ADDRESS 7:1 +#define I2C_SLAVE_ADDRESS_RW 0:0 +#define I2C_SLAVE_ADDRESS_RW_W 0 +#define I2C_SLAVE_ADDRESS_RW_R 1 + +#define I2C_DATA0 0x010044 +#define I2C_DATA1 0x010045 +#define I2C_DATA2 0x010046 +#define I2C_DATA3 0x010047 +#define I2C_DATA4 0x010048 +#define I2C_DATA5 0x010049 +#define I2C_DATA6 0x01004A +#define I2C_DATA7 0x01004B +#define I2C_DATA8 0x01004C +#define I2C_DATA9 0x01004D +#define I2C_DATA10 0x01004E +#define I2C_DATA11 0x01004F +#define I2C_DATA12 0x010050 +#define I2C_DATA13 0x010051 +#define I2C_DATA14 0x010052 +#define I2C_DATA15 0x010053 + + +#define ZV0_CAPTURE_CTRL 0x090000 +#define ZV0_CAPTURE_CTRL_FIELD_INPUT 27:27 +#define ZV0_CAPTURE_CTRL_FIELD_INPUT_EVEN_FIELD 0 +#define ZV0_CAPTURE_CTRL_FIELD_INPUT_ODD_FIELD 1 +#define ZV0_CAPTURE_CTRL_SCAN 26:26 +#define ZV0_CAPTURE_CTRL_SCAN_PROGRESSIVE 0 +#define ZV0_CAPTURE_CTRL_SCAN_INTERLACE 1 +#define ZV0_CAPTURE_CTRL_CURRENT_BUFFER 25:25 +#define ZV0_CAPTURE_CTRL_CURRENT_BUFFER_0 0 +#define ZV0_CAPTURE_CTRL_CURRENT_BUFFER_1 1 +#define ZV0_CAPTURE_CTRL_VERTICAL_SYNC 24:24 +#define ZV0_CAPTURE_CTRL_VERTICAL_SYNC_INACTIVE 0 +#define ZV0_CAPTURE_CTRL_VERTICAL_SYNC_ACTIVE 1 +#define ZV0_CAPTURE_CTRL_ADJ 19:19 +#define ZV0_CAPTURE_CTRL_ADJ_NORMAL 0 +#define ZV0_CAPTURE_CTRL_ADJ_DELAY 1 +#define ZV0_CAPTURE_CTRL_HA 18:18 +#define ZV0_CAPTURE_CTRL_HA_DISABLE 0 +#define ZV0_CAPTURE_CTRL_HA_ENABLE 1 +#define ZV0_CAPTURE_CTRL_VSK 17:17 +#define ZV0_CAPTURE_CTRL_VSK_DISABLE 0 +#define ZV0_CAPTURE_CTRL_VSK_ENABLE 1 +#define ZV0_CAPTURE_CTRL_HSK 16:16 +#define ZV0_CAPTURE_CTRL_HSK_DISABLE 0 +#define ZV0_CAPTURE_CTRL_HSK_ENABLE 1 +#define ZV0_CAPTURE_CTRL_FD 15:15 +#define ZV0_CAPTURE_CTRL_FD_RISING 0 +#define ZV0_CAPTURE_CTRL_FD_FALLING 1 +#define ZV0_CAPTURE_CTRL_VP 14:14 +#define ZV0_CAPTURE_CTRL_VP_HIGH 0 +#define ZV0_CAPTURE_CTRL_VP_LOW 1 +#define ZV0_CAPTURE_CTRL_HP 13:13 +#define ZV0_CAPTURE_CTRL_HP_HIGH 0 +#define ZV0_CAPTURE_CTRL_HP_LOW 1 +#define ZV0_CAPTURE_CTRL_CP 12:12 +#define ZV0_CAPTURE_CTRL_CP_HIGH 0 +#define ZV0_CAPTURE_CTRL_CP_LOW 1 +#define ZV0_CAPTURE_CTRL_UVS 11:11 +#define ZV0_CAPTURE_CTRL_UVS_DISABLE 0 +#define ZV0_CAPTURE_CTRL_UVS_ENABLE 1 +#define ZV0_CAPTURE_CTRL_BS 10:10 +#define ZV0_CAPTURE_CTRL_BS_DISABLE 0 +#define ZV0_CAPTURE_CTRL_BS_ENABLE 1 +#define ZV0_CAPTURE_CTRL_CS 9:9 +#define ZV0_CAPTURE_CTRL_CS_16 0 +#define ZV0_CAPTURE_CTRL_CS_8 1 +#define ZV0_CAPTURE_CTRL_CF 8:8 +#define ZV0_CAPTURE_CTRL_CF_YUV 0 +#define ZV0_CAPTURE_CTRL_CF_RGB 1 +#define ZV0_CAPTURE_CTRL_FS 7:7 +#define ZV0_CAPTURE_CTRL_FS_DISABLE 0 +#define ZV0_CAPTURE_CTRL_FS_ENABLE 1 +#define ZV0_CAPTURE_CTRL_WEAVE 6:6 +#define ZV0_CAPTURE_CTRL_WEAVE_DISABLE 0 +#define ZV0_CAPTURE_CTRL_WEAVE_ENABLE 1 +#define ZV0_CAPTURE_CTRL_BOB 5:5 +#define ZV0_CAPTURE_CTRL_BOB_DISABLE 0 +#define ZV0_CAPTURE_CTRL_BOB_ENABLE 1 +#define ZV0_CAPTURE_CTRL_DB 4:4 +#define ZV0_CAPTURE_CTRL_DB_DISABLE 0 +#define ZV0_CAPTURE_CTRL_DB_ENABLE 1 +#define ZV0_CAPTURE_CTRL_CC 3:3 +#define ZV0_CAPTURE_CTRL_CC_CONTINUE 0 +#define ZV0_CAPTURE_CTRL_CC_CONDITION 1 +#define ZV0_CAPTURE_CTRL_RGB 2:2 +#define ZV0_CAPTURE_CTRL_RGB_DISABLE 0 +#define ZV0_CAPTURE_CTRL_RGB_ENABLE 1 +#define ZV0_CAPTURE_CTRL_656 1:1 +#define ZV0_CAPTURE_CTRL_656_DISABLE 0 +#define ZV0_CAPTURE_CTRL_656_ENABLE 1 +#define ZV0_CAPTURE_CTRL_CAP 0:0 +#define ZV0_CAPTURE_CTRL_CAP_DISABLE 0 +#define ZV0_CAPTURE_CTRL_CAP_ENABLE 1 + +#define ZV0_CAPTURE_CLIP 0x090004 +#define ZV0_CAPTURE_CLIP_YCLIP_EVEN_FIELD 25:16 +#define ZV0_CAPTURE_CLIP_YCLIP 25:16 +#define ZV0_CAPTURE_CLIP_XCLIP 9:0 + +#define ZV0_CAPTURE_SIZE 0x090008 +#define ZV0_CAPTURE_SIZE_HEIGHT 26:16 +#define ZV0_CAPTURE_SIZE_WIDTH 10:0 + +#define ZV0_CAPTURE_BUF0_ADDRESS 0x09000C +#define ZV0_CAPTURE_BUF0_ADDRESS_STATUS 31:31 +#define ZV0_CAPTURE_BUF0_ADDRESS_STATUS_CURRENT 0 +#define ZV0_CAPTURE_BUF0_ADDRESS_STATUS_PENDING 1 +#define ZV0_CAPTURE_BUF0_ADDRESS_EXT 27:27 +#define ZV0_CAPTURE_BUF0_ADDRESS_EXT_LOCAL 0 +#define ZV0_CAPTURE_BUF0_ADDRESS_EXT_EXTERNAL 1 +#define ZV0_CAPTURE_BUF0_ADDRESS_CS 26:26 +#define ZV0_CAPTURE_BUF0_ADDRESS_CS_0 0 +#define ZV0_CAPTURE_BUF0_ADDRESS_CS_1 1 +#define ZV0_CAPTURE_BUF0_ADDRESS_ADDRESS 25:0 + +#define ZV0_CAPTURE_BUF1_ADDRESS 0x090010 +#define ZV0_CAPTURE_BUF1_ADDRESS_STATUS 31:31 +#define ZV0_CAPTURE_BUF1_ADDRESS_STATUS_CURRENT 0 +#define ZV0_CAPTURE_BUF1_ADDRESS_STATUS_PENDING 1 +#define ZV0_CAPTURE_BUF1_ADDRESS_EXT 27:27 +#define ZV0_CAPTURE_BUF1_ADDRESS_EXT_LOCAL 0 +#define ZV0_CAPTURE_BUF1_ADDRESS_EXT_EXTERNAL 1 +#define ZV0_CAPTURE_BUF1_ADDRESS_CS 26:26 +#define ZV0_CAPTURE_BUF1_ADDRESS_CS_0 0 +#define ZV0_CAPTURE_BUF1_ADDRESS_CS_1 1 +#define ZV0_CAPTURE_BUF1_ADDRESS_ADDRESS 25:0 + +#define ZV0_CAPTURE_BUF_OFFSET 0x090014 +#ifndef VALIDATION_CHIP + #define ZV0_CAPTURE_BUF_OFFSET_YCLIP_ODD_FIELD 25:16 +#endif +#define ZV0_CAPTURE_BUF_OFFSET_OFFSET 15:0 + +#define ZV0_CAPTURE_FIFO_CTRL 0x090018 +#define ZV0_CAPTURE_FIFO_CTRL_FIFO 2:0 +#define ZV0_CAPTURE_FIFO_CTRL_FIFO_0 0 +#define ZV0_CAPTURE_FIFO_CTRL_FIFO_1 1 +#define ZV0_CAPTURE_FIFO_CTRL_FIFO_2 2 +#define ZV0_CAPTURE_FIFO_CTRL_FIFO_3 3 +#define ZV0_CAPTURE_FIFO_CTRL_FIFO_4 4 +#define ZV0_CAPTURE_FIFO_CTRL_FIFO_5 5 +#define ZV0_CAPTURE_FIFO_CTRL_FIFO_6 6 +#define ZV0_CAPTURE_FIFO_CTRL_FIFO_7 7 + +#define ZV0_CAPTURE_YRGB_CONST 0x09001C +#define ZV0_CAPTURE_YRGB_CONST_Y 31:24 +#define ZV0_CAPTURE_YRGB_CONST_R 23:16 +#define ZV0_CAPTURE_YRGB_CONST_G 15:8 +#define ZV0_CAPTURE_YRGB_CONST_B 7:0 + +#define ZV0_CAPTURE_LINE_COMP 0x090020 +#define ZV0_CAPTURE_LINE_COMP_LC 10:0 + +/* ZV1 */ + +#define ZV1_CAPTURE_CTRL 0x098000 +#define ZV1_CAPTURE_CTRL_FIELD_INPUT 27:27 +#define ZV1_CAPTURE_CTRL_FIELD_INPUT_EVEN_FIELD 0 +#define ZV1_CAPTURE_CTRL_FIELD_INPUT_ODD_FIELD 0 +#define ZV1_CAPTURE_CTRL_SCAN 26:26 +#define ZV1_CAPTURE_CTRL_SCAN_PROGRESSIVE 0 +#define ZV1_CAPTURE_CTRL_SCAN_INTERLACE 1 +#define ZV1_CAPTURE_CTRL_CURRENT_BUFFER 25:25 +#define ZV1_CAPTURE_CTRL_CURRENT_BUFFER_0 0 +#define ZV1_CAPTURE_CTRL_CURRENT_BUFFER_1 1 +#define ZV1_CAPTURE_CTRL_VERTICAL_SYNC 24:24 +#define ZV1_CAPTURE_CTRL_VERTICAL_SYNC_INACTIVE 0 +#define ZV1_CAPTURE_CTRL_VERTICAL_SYNC_ACTIVE 1 +#define ZV1_CAPTURE_CTRL_PANEL 20:20 +#define ZV1_CAPTURE_CTRL_PANEL_DISABLE 0 +#define ZV1_CAPTURE_CTRL_PANEL_ENABLE 1 +#define ZV1_CAPTURE_CTRL_ADJ 19:19 +#define ZV1_CAPTURE_CTRL_ADJ_NORMAL 0 +#define ZV1_CAPTURE_CTRL_ADJ_DELAY 1 +#define ZV1_CAPTURE_CTRL_HA 18:18 +#define ZV1_CAPTURE_CTRL_HA_DISABLE 0 +#define ZV1_CAPTURE_CTRL_HA_ENABLE 1 +#define ZV1_CAPTURE_CTRL_VSK 17:17 +#define ZV1_CAPTURE_CTRL_VSK_DISABLE 0 +#define ZV1_CAPTURE_CTRL_VSK_ENABLE 1 +#define ZV1_CAPTURE_CTRL_HSK 16:16 +#define ZV1_CAPTURE_CTRL_HSK_DISABLE 0 +#define ZV1_CAPTURE_CTRL_HSK_ENABLE 1 +#define ZV1_CAPTURE_CTRL_FD 15:15 +#define ZV1_CAPTURE_CTRL_FD_RISING 0 +#define ZV1_CAPTURE_CTRL_FD_FALLING 1 +#define ZV1_CAPTURE_CTRL_VP 14:14 +#define ZV1_CAPTURE_CTRL_VP_HIGH 0 +#define ZV1_CAPTURE_CTRL_VP_LOW 1 +#define ZV1_CAPTURE_CTRL_HP 13:13 +#define ZV1_CAPTURE_CTRL_HP_HIGH 0 +#define ZV1_CAPTURE_CTRL_HP_LOW 1 +#define ZV1_CAPTURE_CTRL_CP 12:12 +#define ZV1_CAPTURE_CTRL_CP_HIGH 0 +#define ZV1_CAPTURE_CTRL_CP_LOW 1 +#define ZV1_CAPTURE_CTRL_UVS 11:11 +#define ZV1_CAPTURE_CTRL_UVS_DISABLE 0 +#define ZV1_CAPTURE_CTRL_UVS_ENABLE 1 +#define ZV1_CAPTURE_CTRL_BS 10:10 +#define ZV1_CAPTURE_CTRL_BS_DISABLE 0 +#define ZV1_CAPTURE_CTRL_BS_ENABLE 1 +#define ZV1_CAPTURE_CTRL_CS 9:9 +#define ZV1_CAPTURE_CTRL_CS_16 0 +#define ZV1_CAPTURE_CTRL_CS_8 1 +#define ZV1_CAPTURE_CTRL_CF 8:8 +#define ZV1_CAPTURE_CTRL_CF_YUV 0 +#define ZV1_CAPTURE_CTRL_CF_RGB 1 +#define ZV1_CAPTURE_CTRL_FS 7:7 +#define ZV1_CAPTURE_CTRL_FS_DISABLE 0 +#define ZV1_CAPTURE_CTRL_FS_ENABLE 1 +#define ZV1_CAPTURE_CTRL_WEAVE 6:6 +#define ZV1_CAPTURE_CTRL_WEAVE_DISABLE 0 +#define ZV1_CAPTURE_CTRL_WEAVE_ENABLE 1 +#define ZV1_CAPTURE_CTRL_BOB 5:5 +#define ZV1_CAPTURE_CTRL_BOB_DISABLE 0 +#define ZV1_CAPTURE_CTRL_BOB_ENABLE 1 +#define ZV1_CAPTURE_CTRL_DB 4:4 +#define ZV1_CAPTURE_CTRL_DB_DISABLE 0 +#define ZV1_CAPTURE_CTRL_DB_ENABLE 1 +#define ZV1_CAPTURE_CTRL_CC 3:3 +#define ZV1_CAPTURE_CTRL_CC_CONTINUE 0 +#define ZV1_CAPTURE_CTRL_CC_CONDITION 1 +#define ZV1_CAPTURE_CTRL_RGB 2:2 +#define ZV1_CAPTURE_CTRL_RGB_DISABLE 0 +#define ZV1_CAPTURE_CTRL_RGB_ENABLE 1 +#define ZV1_CAPTURE_CTRL_656 1:1 +#define ZV1_CAPTURE_CTRL_656_DISABLE 0 +#define ZV1_CAPTURE_CTRL_656_ENABLE 1 +#define ZV1_CAPTURE_CTRL_CAP 0:0 +#define ZV1_CAPTURE_CTRL_CAP_DISABLE 0 +#define ZV1_CAPTURE_CTRL_CAP_ENABLE 1 + +#define ZV1_CAPTURE_CLIP 0x098004 +#define ZV1_CAPTURE_CLIP_YCLIP 25:16 +#define ZV1_CAPTURE_CLIP_XCLIP 9:0 + +#define ZV1_CAPTURE_SIZE 0x098008 +#define ZV1_CAPTURE_SIZE_HEIGHT 26:16 +#define ZV1_CAPTURE_SIZE_WIDTH 10:0 + +#define ZV1_CAPTURE_BUF0_ADDRESS 0x09800C +#define ZV1_CAPTURE_BUF0_ADDRESS_STATUS 31:31 +#define ZV1_CAPTURE_BUF0_ADDRESS_STATUS_CURRENT 0 +#define ZV1_CAPTURE_BUF0_ADDRESS_STATUS_PENDING 1 +#define ZV1_CAPTURE_BUF0_ADDRESS_EXT 27:27 +#define ZV1_CAPTURE_BUF0_ADDRESS_EXT_LOCAL 0 +#define ZV1_CAPTURE_BUF0_ADDRESS_EXT_EXTERNAL 1 +#define ZV1_CAPTURE_BUF0_ADDRESS_CS 26:26 +#define ZV1_CAPTURE_BUF0_ADDRESS_CS_0 0 +#define ZV1_CAPTURE_BUF0_ADDRESS_CS_1 1 +#define ZV1_CAPTURE_BUF0_ADDRESS_ADDRESS 25:0 + +#define ZV1_CAPTURE_BUF1_ADDRESS 0x098010 +#define ZV1_CAPTURE_BUF1_ADDRESS_STATUS 31:31 +#define ZV1_CAPTURE_BUF1_ADDRESS_STATUS_CURRENT 0 +#define ZV1_CAPTURE_BUF1_ADDRESS_STATUS_PENDING 1 +#define ZV1_CAPTURE_BUF1_ADDRESS_EXT 27:27 +#define ZV1_CAPTURE_BUF1_ADDRESS_EXT_LOCAL 0 +#define ZV1_CAPTURE_BUF1_ADDRESS_EXT_EXTERNAL 1 +#define ZV1_CAPTURE_BUF1_ADDRESS_CS 26:26 +#define ZV1_CAPTURE_BUF1_ADDRESS_CS_0 0 +#define ZV1_CAPTURE_BUF1_ADDRESS_CS_1 1 +#define ZV1_CAPTURE_BUF1_ADDRESS_ADDRESS 25:0 + +#define ZV1_CAPTURE_BUF_OFFSET 0x098014 +#define ZV1_CAPTURE_BUF_OFFSET_OFFSET 15:0 + +#define ZV1_CAPTURE_FIFO_CTRL 0x098018 +#define ZV1_CAPTURE_FIFO_CTRL_FIFO 2:0 +#define ZV1_CAPTURE_FIFO_CTRL_FIFO_0 0 +#define ZV1_CAPTURE_FIFO_CTRL_FIFO_1 1 +#define ZV1_CAPTURE_FIFO_CTRL_FIFO_2 2 +#define ZV1_CAPTURE_FIFO_CTRL_FIFO_3 3 +#define ZV1_CAPTURE_FIFO_CTRL_FIFO_4 4 +#define ZV1_CAPTURE_FIFO_CTRL_FIFO_5 5 +#define ZV1_CAPTURE_FIFO_CTRL_FIFO_6 6 +#define ZV1_CAPTURE_FIFO_CTRL_FIFO_7 7 + +#define ZV1_CAPTURE_YRGB_CONST 0x09801C +#define ZV1_CAPTURE_YRGB_CONST_Y 31:24 +#define ZV1_CAPTURE_YRGB_CONST_R 23:16 +#define ZV1_CAPTURE_YRGB_CONST_G 15:8 +#define ZV1_CAPTURE_YRGB_CONST_B 7:0 + +#define DMA_1_SOURCE 0x0D0010 +#define DMA_1_SOURCE_ADDRESS_EXT 27:27 +#define DMA_1_SOURCE_ADDRESS_EXT_LOCAL 0 +#define DMA_1_SOURCE_ADDRESS_EXT_EXTERNAL 1 +#define DMA_1_SOURCE_ADDRESS_CS 26:26 +#define DMA_1_SOURCE_ADDRESS_CS_0 0 +#define DMA_1_SOURCE_ADDRESS_CS_1 1 +#define DMA_1_SOURCE_ADDRESS 25:0 + +#define DMA_1_DESTINATION 0x0D0014 +#define DMA_1_DESTINATION_ADDRESS_EXT 27:27 +#define DMA_1_DESTINATION_ADDRESS_EXT_LOCAL 0 +#define DMA_1_DESTINATION_ADDRESS_EXT_EXTERNAL 1 +#define DMA_1_DESTINATION_ADDRESS_CS 26:26 +#define DMA_1_DESTINATION_ADDRESS_CS_0 0 +#define DMA_1_DESTINATION_ADDRESS_CS_1 1 +#define DMA_1_DESTINATION_ADDRESS 25:0 + +#define DMA_1_SIZE_CONTROL 0x0D0018 +#define DMA_1_SIZE_CONTROL_STATUS 31:31 +#define DMA_1_SIZE_CONTROL_STATUS_IDLE 0 +#define DMA_1_SIZE_CONTROL_STATUS_ACTIVE 1 +#define DMA_1_SIZE_CONTROL_SIZE 23:0 + +#define DMA_ABORT_INTERRUPT 0x0D0020 +#define DMA_ABORT_INTERRUPT_ABORT_1 5:5 +#define DMA_ABORT_INTERRUPT_ABORT_1_ENABLE 0 +#define DMA_ABORT_INTERRUPT_ABORT_1_ABORT 1 +#define DMA_ABORT_INTERRUPT_ABORT_0 4:4 +#define DMA_ABORT_INTERRUPT_ABORT_0_ENABLE 0 +#define DMA_ABORT_INTERRUPT_ABORT_0_ABORT 1 +#define DMA_ABORT_INTERRUPT_INT_1 1:1 +#define DMA_ABORT_INTERRUPT_INT_1_CLEAR 0 +#define DMA_ABORT_INTERRUPT_INT_1_FINISHED 1 +#define DMA_ABORT_INTERRUPT_INT_0 0:0 +#define DMA_ABORT_INTERRUPT_INT_0_CLEAR 0 +#define DMA_ABORT_INTERRUPT_INT_0_FINISHED 1 + + + + + +/* Default i2c CLK and Data GPIO. These are the default i2c pins */ +#define DEFAULT_I2C_SCL 30 +#define DEFAULT_I2C_SDA 31 + + +#define GPIO_DATA_SM750LE 0x020018 +#define GPIO_DATA_SM750LE_1 1:1 +#define GPIO_DATA_SM750LE_0 0:0 + +#define GPIO_DATA_DIRECTION_SM750LE 0x02001C +#define GPIO_DATA_DIRECTION_SM750LE_1 1:1 +#define GPIO_DATA_DIRECTION_SM750LE_1_INPUT 0 +#define GPIO_DATA_DIRECTION_SM750LE_1_OUTPUT 1 +#define GPIO_DATA_DIRECTION_SM750LE_0 0:0 +#define GPIO_DATA_DIRECTION_SM750LE_0_INPUT 0 +#define GPIO_DATA_DIRECTION_SM750LE_0_OUTPUT 1 + + +#endif diff --git a/drivers/staging/sm750fb/ddk750_sii164.c b/drivers/staging/sm750fb/ddk750_sii164.c new file mode 100644 index 000000000000..faf825093e7f --- /dev/null +++ b/drivers/staging/sm750fb/ddk750_sii164.c @@ -0,0 +1,425 @@ +#define USE_DVICHIP +#ifdef USE_DVICHIP + +#include "ddk750_sii164.h" +#include "ddk750_hwi2c.h" + +/* I2C Address of each SII164 chip */ +#define SII164_I2C_ADDRESS 0x70 + +/* Define this definition to use hardware i2c. */ +#define USE_HW_I2C + +#ifdef USE_HW_I2C + #define i2cWriteReg hwI2CWriteReg + #define i2cReadReg hwI2CReadReg +#else + #define i2cWriteReg swI2CWriteReg + #define i2cReadReg swI2CReadReg +#endif + +/* SII164 Vendor and Device ID */ +#define SII164_VENDOR_ID 0x0001 +#define SII164_DEVICE_ID 0x0006 + +#ifdef SII164_FULL_FUNCTIONS +/* Name of the DVI Controller chip */ +static char *gDviCtrlChipName = "Silicon Image SiI 164"; +#endif + +/* + * sii164GetVendorID + * This function gets the vendor ID of the DVI controller chip. + * + * Output: + * Vendor ID + */ +unsigned short sii164GetVendorID() +{ + unsigned short vendorID; + + vendorID = ((unsigned short) i2cReadReg(SII164_I2C_ADDRESS, SII164_VENDOR_ID_HIGH) << 8) | + (unsigned short) i2cReadReg(SII164_I2C_ADDRESS, SII164_VENDOR_ID_LOW); + + return vendorID; +} + +/* + * sii164GetDeviceID + * This function gets the device ID of the DVI controller chip. + * + * Output: + * Device ID + */ +unsigned short sii164GetDeviceID() +{ + unsigned short deviceID; + + deviceID = ((unsigned short) i2cReadReg(SII164_I2C_ADDRESS, SII164_DEVICE_ID_HIGH) << 8) | + (unsigned short) i2cReadReg(SII164_I2C_ADDRESS, SII164_DEVICE_ID_LOW); + + return deviceID; +} + + + +/* DVI.C will handle all SiI164 chip stuffs and try it best to make code minimal and useful */ + +/* + * sii164InitChip + * This function initialize and detect the DVI controller chip. + * + * Input: + * edgeSelect - Edge Select: + * 0 = Input data is falling edge latched (falling edge + * latched first in dual edge mode) + * 1 = Input data is rising edge latched (rising edge + * latched first in dual edge mode) + * busSelect - Input Bus Select: + * 0 = Input data bus is 12-bits wide + * 1 = Input data bus is 24-bits wide + * dualEdgeClkSelect - Dual Edge Clock Select + * 0 = Input data is single edge latched + * 1 = Input data is dual edge latched + * hsyncEnable - Horizontal Sync Enable: + * 0 = HSYNC input is transmitted as fixed LOW + * 1 = HSYNC input is transmitted as is + * vsyncEnable - Vertical Sync Enable: + * 0 = VSYNC input is transmitted as fixed LOW + * 1 = VSYNC input is transmitted as is + * deskewEnable - De-skewing Enable: + * 0 = De-skew disabled + * 1 = De-skew enabled + * deskewSetting - De-skewing Setting (increment of 260psec) + * 0 = 1 step --> minimum setup / maximum hold + * 1 = 2 step + * 2 = 3 step + * 3 = 4 step + * 4 = 5 step + * 5 = 6 step + * 6 = 7 step + * 7 = 8 step --> maximum setup / minimum hold + * continuousSyncEnable- SYNC Continuous: + * 0 = Disable + * 1 = Enable + * pllFilterEnable - PLL Filter Enable + * 0 = Disable PLL Filter + * 1 = Enable PLL Filter + * pllFilterValue - PLL Filter characteristics: + * 0~7 (recommended value is 4) + * + * Output: + * 0 - Success + * -1 - Fail. + */ +long sii164InitChip( + unsigned char edgeSelect, + unsigned char busSelect, + unsigned char dualEdgeClkSelect, + unsigned char hsyncEnable, + unsigned char vsyncEnable, + unsigned char deskewEnable, + unsigned char deskewSetting, + unsigned char continuousSyncEnable, + unsigned char pllFilterEnable, + unsigned char pllFilterValue +) +{ + //unsigned char ucRegIndex, ucRegValue; + //unsigned char ucDeviceAddress, + unsigned char config; + //unsigned long delayCount; + + /* Initialize the i2c bus */ +#ifdef USE_HW_I2C + /* Use fast mode. */ + hwI2CInit(1); +#else + swI2CInit(DEFAULT_I2C_SCL, DEFAULT_I2C_SDA); +#endif + + /* Check if SII164 Chip exists */ + if ((sii164GetVendorID() == SII164_VENDOR_ID) && (sii164GetDeviceID() == SII164_DEVICE_ID)) + { + +#ifdef DDKDEBUG + //sii164PrintRegisterValues(); +#endif + /* + * Initialize SII164 controller chip. + */ + + /* Select the edge */ + if (edgeSelect == 0) + config = SII164_CONFIGURATION_LATCH_FALLING; + else + config = SII164_CONFIGURATION_LATCH_RISING; + + /* Select bus wide */ + if (busSelect == 0) + config |= SII164_CONFIGURATION_BUS_12BITS; + else + config |= SII164_CONFIGURATION_BUS_24BITS; + + /* Select Dual/Single Edge Clock */ + if (dualEdgeClkSelect == 0) + config |= SII164_CONFIGURATION_CLOCK_SINGLE; + else + config |= SII164_CONFIGURATION_CLOCK_DUAL; + + /* Select HSync Enable */ + if (hsyncEnable == 0) + config |= SII164_CONFIGURATION_HSYNC_FORCE_LOW; + else + config |= SII164_CONFIGURATION_HSYNC_AS_IS; + + /* Select VSync Enable */ + if (vsyncEnable == 0) + config |= SII164_CONFIGURATION_VSYNC_FORCE_LOW; + else + config |= SII164_CONFIGURATION_VSYNC_AS_IS; + + i2cWriteReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION, config); + + /* De-skew enabled with default 111b value. + This will fix some artifacts problem in some mode on board 2.2. + Somehow this fix does not affect board 2.1. + */ + if (deskewEnable == 0) + config = SII164_DESKEW_DISABLE; + else + config = SII164_DESKEW_ENABLE; + + switch (deskewSetting) + { + case 0: + config |= SII164_DESKEW_1_STEP; + break; + case 1: + config |= SII164_DESKEW_2_STEP; + break; + case 2: + config |= SII164_DESKEW_3_STEP; + break; + case 3: + config |= SII164_DESKEW_4_STEP; + break; + case 4: + config |= SII164_DESKEW_5_STEP; + break; + case 5: + config |= SII164_DESKEW_6_STEP; + break; + case 6: + config |= SII164_DESKEW_7_STEP; + break; + case 7: + config |= SII164_DESKEW_8_STEP; + break; + } + i2cWriteReg(SII164_I2C_ADDRESS, SII164_DESKEW, config); + + /* Enable/Disable Continuous Sync. */ + if (continuousSyncEnable == 0) + config = SII164_PLL_FILTER_SYNC_CONTINUOUS_DISABLE; + else + config = SII164_PLL_FILTER_SYNC_CONTINUOUS_ENABLE; + + /* Enable/Disable PLL Filter */ + if (pllFilterEnable == 0) + config |= SII164_PLL_FILTER_DISABLE; + else + config |= SII164_PLL_FILTER_ENABLE; + + /* Set the PLL Filter value */ + config |= ((pllFilterValue & 0x07) << 1); + + i2cWriteReg(SII164_I2C_ADDRESS, SII164_PLL, config); + + /* Recover from Power Down and enable output. */ + config = i2cReadReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION); + config |= SII164_CONFIGURATION_POWER_NORMAL; + i2cWriteReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION, config); + +#ifdef DDKDEBUG + //sii164PrintRegisterValues(); +#endif + + return 0; + } + + /* Return -1 if initialization fails. */ + return (-1); +} + + + + + +/* below sii164 function is not neccessary */ + +#ifdef SII164_FULL_FUNCTIONS + +/* + * sii164ResetChip + * This function resets the DVI Controller Chip. + */ +void sii164ResetChip() +{ + /* Power down */ + sii164SetPower(0); + sii164SetPower(1); +} + + +/* + * sii164GetChipString + * This function returns a char string name of the current DVI Controller chip. + * It's convenient for application need to display the chip name. + */ +char *sii164GetChipString() +{ + return gDviCtrlChipName; +} + + +/* + * sii164SetPower + * This function sets the power configuration of the DVI Controller Chip. + * + * Input: + * powerUp - Flag to set the power down or up + */ +void sii164SetPower( + unsigned char powerUp +) +{ + unsigned char config; + + config = i2cReadReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION); + if (powerUp == 1) + { + /* Power up the chip */ + config &= ~SII164_CONFIGURATION_POWER_MASK; + config |= SII164_CONFIGURATION_POWER_NORMAL; + i2cWriteReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION, config); + } + else + { + /* Power down the chip */ + config &= ~SII164_CONFIGURATION_POWER_MASK; + config |= SII164_CONFIGURATION_POWER_DOWN; + i2cWriteReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION, config); + } +} + + +/* + * sii164SelectHotPlugDetectionMode + * This function selects the mode of the hot plug detection. + */ +static void sii164SelectHotPlugDetectionMode( + sii164_hot_plug_mode_t hotPlugMode +) +{ + unsigned char detectReg; + + detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT) & ~SII164_DETECT_MONITOR_SENSE_OUTPUT_FLAG; + switch (hotPlugMode) + { + case SII164_HOTPLUG_DISABLE: + detectReg |= SII164_DETECT_MONITOR_SENSE_OUTPUT_HIGH; + break; + case SII164_HOTPLUG_USE_MDI: + detectReg &= ~SII164_DETECT_INTERRUPT_MASK; + detectReg |= SII164_DETECT_INTERRUPT_BY_HTPLG_PIN; + detectReg |= SII164_DETECT_MONITOR_SENSE_OUTPUT_MDI; + break; + case SII164_HOTPLUG_USE_RSEN: + detectReg |= SII164_DETECT_MONITOR_SENSE_OUTPUT_RSEN; + break; + case SII164_HOTPLUG_USE_HTPLG: + detectReg |= SII164_DETECT_MONITOR_SENSE_OUTPUT_HTPLG; + break; + } + + i2cWriteReg(SII164_I2C_ADDRESS, SII164_DETECT, detectReg); +} + +/* + * sii164EnableHotPlugDetection + * This function enables the Hot Plug detection. + * + * enableHotPlug - Enable (=1) / disable (=0) Hot Plug detection + */ +void sii164EnableHotPlugDetection( + unsigned char enableHotPlug +) +{ + unsigned char detectReg; + detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT); + + /* Depending on each DVI controller, need to enable the hot plug based on each + individual chip design. */ + if (enableHotPlug != 0) + sii164SelectHotPlugDetectionMode(SII164_HOTPLUG_USE_MDI); + else + sii164SelectHotPlugDetectionMode(SII164_HOTPLUG_DISABLE); +} + +/* + * sii164IsConnected + * Check if the DVI Monitor is connected. + * + * Output: + * 0 - Not Connected + * 1 - Connected + */ +unsigned char sii164IsConnected() +{ + unsigned char hotPlugValue; + + hotPlugValue = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT) & SII164_DETECT_HOT_PLUG_STATUS_MASK; + if (hotPlugValue == SII164_DETECT_HOT_PLUG_STATUS_ON) + return 1; + else + return 0; +} + +/* + * sii164CheckInterrupt + * Checks if interrupt has occured. + * + * Output: + * 0 - No interrupt + * 1 - Interrupt occurs + */ +unsigned char sii164CheckInterrupt() +{ + unsigned char detectReg; + + detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT) & SII164_DETECT_MONITOR_STATE_MASK; + if (detectReg == SII164_DETECT_MONITOR_STATE_CHANGE) + return 1; + else + return 0; +} + +/* + * sii164ClearInterrupt + * Clear the hot plug interrupt. + */ +void sii164ClearInterrupt() +{ + unsigned char detectReg; + + /* Clear the MDI interrupt */ + detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT); + i2cWriteReg(SII164_I2C_ADDRESS, SII164_DETECT, detectReg | SII164_DETECT_MONITOR_STATE_CLEAR); +} + +#endif + +#endif + + diff --git a/drivers/staging/sm750fb/ddk750_sii164.h b/drivers/staging/sm750fb/ddk750_sii164.h new file mode 100644 index 000000000000..2b4c7d3381df --- /dev/null +++ b/drivers/staging/sm750fb/ddk750_sii164.h @@ -0,0 +1,172 @@ +#ifndef DDK750_SII164_H__ +#define DDK750_SII164_H__ + +#define USE_DVICHIP + +/* Hot Plug detection mode structure */ +typedef enum _sii164_hot_plug_mode_t +{ + SII164_HOTPLUG_DISABLE = 0, /* Disable Hot Plug output bit (always high). */ + SII164_HOTPLUG_USE_MDI, /* Use Monitor Detect Interrupt bit. */ + SII164_HOTPLUG_USE_RSEN, /* Use Receiver Sense detect bit. */ + SII164_HOTPLUG_USE_HTPLG /* Use Hot Plug detect bit. */ +} sii164_hot_plug_mode_t; + + +/* Silicon Image SiI164 chip prototype */ +long sii164InitChip( + unsigned char edgeSelect, + unsigned char busSelect, + unsigned char dualEdgeClkSelect, + unsigned char hsyncEnable, + unsigned char vsyncEnable, + unsigned char deskewEnable, + unsigned char deskewSetting, + unsigned char continuousSyncEnable, + unsigned char pllFilterEnable, + unsigned char pllFilterValue +); + +unsigned short sii164GetVendorID(void); +unsigned short sii164GetDeviceID(void); + + +#ifdef SII164_FULL_FUNCTIONS +void sii164ResetChip(void); +char *sii164GetChipString(void); +void sii164SetPower(unsigned char powerUp); +void sii164EnableHotPlugDetection(unsigned char enableHotPlug); +unsigned char sii164IsConnected(void); +unsigned char sii164CheckInterrupt(void); +void sii164ClearInterrupt(void); +#endif +/* below register definination is used for Silicon Image SiI164 DVI controller chip */ +/* + * Vendor ID registers + */ +#define SII164_VENDOR_ID_LOW 0x00 +#define SII164_VENDOR_ID_HIGH 0x01 + +/* + * Device ID registers + */ +#define SII164_DEVICE_ID_LOW 0x02 +#define SII164_DEVICE_ID_HIGH 0x03 + +/* + * Device Revision + */ +#define SII164_DEVICE_REVISION 0x04 + +/* + * Frequency Limitation registers + */ +#define SII164_FREQUENCY_LIMIT_LOW 0x06 +#define SII164_FREQUENCY_LIMIT_HIGH 0x07 + +/* + * Power Down and Input Signal Configuration registers + */ +#define SII164_CONFIGURATION 0x08 + +/* Power down (PD) */ +#define SII164_CONFIGURATION_POWER_DOWN 0x00 +#define SII164_CONFIGURATION_POWER_NORMAL 0x01 +#define SII164_CONFIGURATION_POWER_MASK 0x01 + +/* Input Edge Latch Select (EDGE) */ +#define SII164_CONFIGURATION_LATCH_FALLING 0x00 +#define SII164_CONFIGURATION_LATCH_RISING 0x02 + +/* Bus Select (BSEL) */ +#define SII164_CONFIGURATION_BUS_12BITS 0x00 +#define SII164_CONFIGURATION_BUS_24BITS 0x04 + +/* Dual Edge Clock Select (DSEL) */ +#define SII164_CONFIGURATION_CLOCK_SINGLE 0x00 +#define SII164_CONFIGURATION_CLOCK_DUAL 0x08 + +/* Horizontal Sync Enable (HEN) */ +#define SII164_CONFIGURATION_HSYNC_FORCE_LOW 0x00 +#define SII164_CONFIGURATION_HSYNC_AS_IS 0x10 + +/* Vertical Sync Enable (VEN) */ +#define SII164_CONFIGURATION_VSYNC_FORCE_LOW 0x00 +#define SII164_CONFIGURATION_VSYNC_AS_IS 0x20 + +/* + * Detection registers + */ +#define SII164_DETECT 0x09 + +/* Monitor Detect Interrupt (MDI) */ +#define SII164_DETECT_MONITOR_STATE_CHANGE 0x00 +#define SII164_DETECT_MONITOR_STATE_NO_CHANGE 0x01 +#define SII164_DETECT_MONITOR_STATE_CLEAR 0x01 +#define SII164_DETECT_MONITOR_STATE_MASK 0x01 + +/* Hot Plug detect Input (HTPLG) */ +#define SII164_DETECT_HOT_PLUG_STATUS_OFF 0x00 +#define SII164_DETECT_HOT_PLUG_STATUS_ON 0x02 +#define SII164_DETECT_HOT_PLUG_STATUS_MASK 0x02 + +/* Receiver Sense (RSEN) */ +#define SII164_DETECT_RECEIVER_SENSE_NOT_DETECTED 0x00 +#define SII164_DETECT_RECEIVER_SENSE_DETECTED 0x04 + +/* Interrupt Generation Method (TSEL) */ +#define SII164_DETECT_INTERRUPT_BY_RSEN_PIN 0x00 +#define SII164_DETECT_INTERRUPT_BY_HTPLG_PIN 0x08 +#define SII164_DETECT_INTERRUPT_MASK 0x08 + +/* Monitor Sense Output (MSEN) */ +#define SII164_DETECT_MONITOR_SENSE_OUTPUT_HIGH 0x00 +#define SII164_DETECT_MONITOR_SENSE_OUTPUT_MDI 0x10 +#define SII164_DETECT_MONITOR_SENSE_OUTPUT_RSEN 0x20 +#define SII164_DETECT_MONITOR_SENSE_OUTPUT_HTPLG 0x30 +#define SII164_DETECT_MONITOR_SENSE_OUTPUT_FLAG 0x30 + +/* + * Skewing registers + */ +#define SII164_DESKEW 0x0A + +/* General Purpose Input (CTL[3:1]) */ +#define SII164_DESKEW_GENERAL_PURPOSE_INPUT_MASK 0x0E + +/* De-skewing Enable bit (DKEN) */ +#define SII164_DESKEW_DISABLE 0x00 +#define SII164_DESKEW_ENABLE 0x10 + +/* De-skewing Setting (DK[3:1])*/ +#define SII164_DESKEW_1_STEP 0x00 +#define SII164_DESKEW_2_STEP 0x20 +#define SII164_DESKEW_3_STEP 0x40 +#define SII164_DESKEW_4_STEP 0x60 +#define SII164_DESKEW_5_STEP 0x80 +#define SII164_DESKEW_6_STEP 0xA0 +#define SII164_DESKEW_7_STEP 0xC0 +#define SII164_DESKEW_8_STEP 0xE0 + +/* + * User Configuration Data registers (CFG 7:0) + */ +#define SII164_USER_CONFIGURATION 0x0B + +/* + * PLL registers + */ +#define SII164_PLL 0x0C + +/* PLL Filter Value (PLLF) */ +#define SII164_PLL_FILTER_VALUE_MASK 0x0E + +/* PLL Filter Enable (PFEN) */ +#define SII164_PLL_FILTER_DISABLE 0x00 +#define SII164_PLL_FILTER_ENABLE 0x01 + +/* Sync Continuous (SCNT) */ +#define SII164_PLL_FILTER_SYNC_CONTINUOUS_DISABLE 0x00 +#define SII164_PLL_FILTER_SYNC_CONTINUOUS_ENABLE 0x80 + +#endif diff --git a/drivers/staging/sm750fb/ddk750_swi2c.c b/drivers/staging/sm750fb/ddk750_swi2c.c new file mode 100644 index 000000000000..b53407bb2042 --- /dev/null +++ b/drivers/staging/sm750fb/ddk750_swi2c.c @@ -0,0 +1,535 @@ +/******************************************************************* +* +* Copyright (c) 2007 by Silicon Motion, Inc. (SMI) +* +* All rights are reserved. Reproduction or in part is prohibited +* without the written consent of the copyright owner. +* +* swi2c.c --- SM750/SM718 DDK +* This file contains the source code for I2C using software +* implementation. +* +*******************************************************************/ +#include "ddk750_help.h" +#include "ddk750_reg.h" +#include "ddk750_swi2c.h" +#include "ddk750_power.h" + + +/******************************************************************* + * I2C Software Master Driver: + * =========================== + * Each i2c cycle is split into 4 sections. Each of these section marks + * a point in time where the SCL or SDA may be changed. + * + * 1 Cycle == | Section I. | Section 2. | Section 3. | Section 4. | + * +-------------+-------------+-------------+-------------+ + * | SCL set LOW |SCL no change| SCL set HIGH|SCL no change| + * + * ____________ _____________ + * SCL == XXXX _____________ ____________ / + * + * I.e. the SCL may only be changed in section 1. and section 3. while + * the SDA may only be changed in section 2. and section 4. The table + * below gives the changes for these 2 lines in the varios sections. + * + * Section changes Table: + * ====================== + * blank = no change, L = set bit LOW, H = set bit HIGH + * + * | 1.| 2.| 3.| 4.| + * ---------------+---+---+---+---+ + * Tx Start SDA | | H | | L | + * SCL | L | | H | | + * ---------------+---+---+---+---+ + * Tx Stop SDA | | L | | H | + * SCL | L | | H | | + * ---------------+---+---+---+---+ + * Tx bit H SDA | | H | | | + * SCL | L | | H | | + * ---------------+---+---+---+---+ + * Tx bit L SDA | | L | | | + * SCL | L | | H | | + * ---------------+---+---+---+---+ + * + ******************************************************************/ + +/* GPIO pins used for this I2C. It ranges from 0 to 63. */ +static unsigned char g_i2cClockGPIO = DEFAULT_I2C_SCL; +static unsigned char g_i2cDataGPIO = DEFAULT_I2C_SDA; + +/* + * Below is the variable declaration for the GPIO pin register usage + * for the i2c Clock and i2c Data. + * + * Note: + * Notice that the GPIO usage for the i2c clock and i2c Data are + * separated. This is to make this code flexible enough when + * two separate GPIO pins for the clock and data are located + * in two different GPIO register set (worst case). + */ + +/* i2c Clock GPIO Register usage */ +static unsigned long g_i2cClkGPIOMuxReg = GPIO_MUX; +static unsigned long g_i2cClkGPIODataReg = GPIO_DATA; +static unsigned long g_i2cClkGPIODataDirReg = GPIO_DATA_DIRECTION; + +/* i2c Data GPIO Register usage */ +static unsigned long g_i2cDataGPIOMuxReg = GPIO_MUX; +static unsigned long g_i2cDataGPIODataReg = GPIO_DATA; +static unsigned long g_i2cDataGPIODataDirReg = GPIO_DATA_DIRECTION; + +static unsigned char peekIO(unsigned short port,unsigned short index) +{ +#if defined(__i386__) || defined( __x86_64__) + outb_p(index,port); + return inb_p(port+1); +#endif +} + +/* + * This function puts a delay between command + */ +static void swI2CWait(void) +{ + /* find a bug: + * peekIO method works well before suspend/resume + * but after suspend, peekIO(0x3ce,0x61) & 0x10 + * always be non-zero,which makes the while loop + * never finish. + * use non-ultimate for loop below is safe + * */ +#if 0 + /* Change wait algorithm to use PCI bus clock, + it's more reliable than counter loop .. + write 0x61 to 0x3ce and read from 0x3cf + */ + while(peekIO(0x3ce,0x61) & 0x10); +#else + int i, Temp; + + for(i=0; i<600; i++) + { + Temp = i; + Temp += i; + } +#endif +} + +/* + * This function set/reset the SCL GPIO pin + * + * Parameters: + * value - Bit value to set to the SCL or SDA (0 = low, 1 = high) + * + * Notes: + * When setting SCL to high, just set the GPIO as input where the pull up + * resistor will pull the signal up. Do not use software to pull up the + * signal because the i2c will fail when other device try to drive the + * signal due to SM50x will drive the signal to always high. + */ +void swI2CSCL(unsigned char value) +{ + unsigned long ulGPIOData; + unsigned long ulGPIODirection; + + ulGPIODirection = PEEK32(g_i2cClkGPIODataDirReg); + if (value) /* High */ + { + /* Set direction as input. This will automatically pull the signal up. */ + ulGPIODirection &= ~(1 << g_i2cClockGPIO); + POKE32(g_i2cClkGPIODataDirReg, ulGPIODirection); + } + else /* Low */ + { + /* Set the signal down */ + ulGPIOData = PEEK32(g_i2cClkGPIODataReg); + ulGPIOData &= ~(1 << g_i2cClockGPIO); + POKE32(g_i2cClkGPIODataReg, ulGPIOData); + + /* Set direction as output */ + ulGPIODirection |= (1 << g_i2cClockGPIO); + POKE32(g_i2cClkGPIODataDirReg, ulGPIODirection); + } +} + +/* + * This function set/reset the SDA GPIO pin + * + * Parameters: + * value - Bit value to set to the SCL or SDA (0 = low, 1 = high) + * + * Notes: + * When setting SCL to high, just set the GPIO as input where the pull up + * resistor will pull the signal up. Do not use software to pull up the + * signal because the i2c will fail when other device try to drive the + * signal due to SM50x will drive the signal to always high. + */ +void swI2CSDA(unsigned char value) +{ + unsigned long ulGPIOData; + unsigned long ulGPIODirection; + + ulGPIODirection = PEEK32(g_i2cDataGPIODataDirReg); + if (value) /* High */ + { + /* Set direction as input. This will automatically pull the signal up. */ + ulGPIODirection &= ~(1 << g_i2cDataGPIO); + POKE32(g_i2cDataGPIODataDirReg, ulGPIODirection); + } + else /* Low */ + { + /* Set the signal down */ + ulGPIOData = PEEK32(g_i2cDataGPIODataReg); + ulGPIOData &= ~(1 << g_i2cDataGPIO); + POKE32(g_i2cDataGPIODataReg, ulGPIOData); + + /* Set direction as output */ + ulGPIODirection |= (1 << g_i2cDataGPIO); + POKE32(g_i2cDataGPIODataDirReg, ulGPIODirection); + } +} + +/* + * This function read the data from the SDA GPIO pin + * + * Return Value: + * The SDA data bit sent by the Slave + */ +static unsigned char swI2CReadSDA(void) +{ + unsigned long ulGPIODirection; + unsigned long ulGPIOData; + + /* Make sure that the direction is input (High) */ + ulGPIODirection = PEEK32(g_i2cDataGPIODataDirReg); + if ((ulGPIODirection & (1 << g_i2cDataGPIO)) != (~(1 << g_i2cDataGPIO))) + { + ulGPIODirection &= ~(1 << g_i2cDataGPIO); + POKE32(g_i2cDataGPIODataDirReg, ulGPIODirection); + } + + /* Now read the SDA line */ + ulGPIOData = PEEK32(g_i2cDataGPIODataReg); + if (ulGPIOData & (1 << g_i2cDataGPIO)) + return 1; + else + return 0; +} + +#pragma optimize( "", off ) + +/* + * This function sends ACK signal + */ +static void swI2CAck(void) +{ + return; /* Single byte read is ok without it. */ +} + +/* + * This function sends the start command to the slave device + */ +void swI2CStart(void) +{ + /* Start I2C */ + swI2CSDA(1); + swI2CSCL(1); + swI2CSDA(0); +} + +/* + * This function sends the stop command to the slave device + */ +void swI2CStop(void) +{ + /* Stop the I2C */ + swI2CSCL(1); + swI2CSDA(0); + swI2CSDA(1); +} + +/* + * This function writes one byte to the slave device + * + * Parameters: + * data - Data to be write to the slave device + * + * Return Value: + * 0 - Success + * -1 - Fail to write byte + */ +long swI2CWriteByte(unsigned char data) +{ + unsigned char value = data; + int i; + + /* Sending the data bit by bit */ + for (i=0; i<8; i++) + { + /* Set SCL to low */ + swI2CSCL(0); + + /* Send data bit */ + if ((value & 0x80) != 0) + swI2CSDA(1); + else + swI2CSDA(0); + + swI2CWait(); + + /* Toggle clk line to one */ + swI2CSCL(1); + swI2CWait(); + + /* Shift byte to be sent */ + value = value << 1; + } + + /* Set the SCL Low and SDA High (prepare to get input) */ + swI2CSCL(0); + swI2CSDA(1); + + /* Set the SCL High for ack */ + swI2CWait(); + swI2CSCL(1); + swI2CWait(); + + /* Read SDA, until SDA==0 */ + for(i=0; i<0xff; i++) + { + if (!swI2CReadSDA()) + break; + + swI2CSCL(0); + swI2CWait(); + swI2CSCL(1); + swI2CWait(); + } + + /* Set the SCL Low and SDA High */ + swI2CSCL(0); + swI2CSDA(1); + + if (i<0xff) + return 0; + else + return (-1); +} + +/* + * This function reads one byte from the slave device + * + * Parameters: + * ack - Flag to indicate either to send the acknowledge + * message to the slave device or not + * + * Return Value: + * One byte data read from the Slave device + */ +unsigned char swI2CReadByte(unsigned char ack) +{ + int i; + unsigned char data = 0; + + for(i=7; i>=0; i--) + { + /* Set the SCL to Low and SDA to High (Input) */ + swI2CSCL(0); + swI2CSDA(1); + swI2CWait(); + + /* Set the SCL High */ + swI2CSCL(1); + swI2CWait(); + + /* Read data bits from SDA */ + data |= (swI2CReadSDA() << i); + } + + if (ack) + swI2CAck(); + + /* Set the SCL Low and SDA High */ + swI2CSCL(0); + swI2CSDA(1); + + return data; +} +#pragma optimize( "", on ) + +/* + * This function initializes GPIO port for SW I2C communication. + * + * Parameters: + * i2cClkGPIO - The GPIO pin to be used as i2c SCL + * i2cDataGPIO - The GPIO pin to be used as i2c SDA + * + * Return Value: + * -1 - Fail to initialize the i2c + * 0 - Success + */ +long swI2CInit_SM750LE( + unsigned char i2cClkGPIO, + unsigned char i2cDataGPIO +) +{ + int i; + + /* Initialize the GPIO pin for the i2c Clock Register */ + g_i2cClkGPIODataReg = GPIO_DATA_SM750LE; + g_i2cClkGPIODataDirReg = GPIO_DATA_DIRECTION_SM750LE; + + /* Initialize the Clock GPIO Offset */ + g_i2cClockGPIO = i2cClkGPIO; + + /* Initialize the GPIO pin for the i2c Data Register */ + g_i2cDataGPIODataReg = GPIO_DATA_SM750LE; + g_i2cDataGPIODataDirReg = GPIO_DATA_DIRECTION_SM750LE; + + /* Initialize the Data GPIO Offset */ + g_i2cDataGPIO = i2cDataGPIO; + + /* Note that SM750LE don't have GPIO MUX and power is always on */ + + /* Clear the i2c lines. */ + for(i=0; i<9; i++) + swI2CStop(); + + return 0; +} + +/* + * This function initializes the i2c attributes and bus + * + * Parameters: + * i2cClkGPIO - The GPIO pin to be used as i2c SCL + * i2cDataGPIO - The GPIO pin to be used as i2c SDA + * + * Return Value: + * -1 - Fail to initialize the i2c + * 0 - Success + */ +long swI2CInit( + unsigned char i2cClkGPIO, + unsigned char i2cDataGPIO +) +{ + int i; + + /* Return 0 if the GPIO pins to be used is out of range. The range is only from [0..63] */ + if ((i2cClkGPIO > 31) || (i2cDataGPIO > 31)) + return (-1); + + if (getChipType() == SM750LE) + return( swI2CInit_SM750LE(i2cClkGPIO, i2cDataGPIO) ); + + /* Initialize the GPIO pin for the i2c Clock Register */ + g_i2cClkGPIOMuxReg = GPIO_MUX; + g_i2cClkGPIODataReg = GPIO_DATA; + g_i2cClkGPIODataDirReg = GPIO_DATA_DIRECTION; + + /* Initialize the Clock GPIO Offset */ + g_i2cClockGPIO = i2cClkGPIO; + + /* Initialize the GPIO pin for the i2c Data Register */ + g_i2cDataGPIOMuxReg = GPIO_MUX; + g_i2cDataGPIODataReg = GPIO_DATA; + g_i2cDataGPIODataDirReg = GPIO_DATA_DIRECTION; + + /* Initialize the Data GPIO Offset */ + g_i2cDataGPIO = i2cDataGPIO; + + /* Enable the GPIO pins for the i2c Clock and Data (GPIO MUX) */ + POKE32(g_i2cClkGPIOMuxReg, + PEEK32(g_i2cClkGPIOMuxReg) & ~(1 << g_i2cClockGPIO)); + POKE32(g_i2cDataGPIOMuxReg, + PEEK32(g_i2cDataGPIOMuxReg) & ~(1 << g_i2cDataGPIO)); + + /* Enable GPIO power */ + enableGPIO(1); + + /* Clear the i2c lines. */ + for(i=0; i<9; i++) + swI2CStop(); + + return 0; +} + +/* + * This function reads the slave device's register + * + * Parameters: + * deviceAddress - i2c Slave device address which register + * to be read from + * registerIndex - Slave device's register to be read + * + * Return Value: + * Register value + */ +unsigned char swI2CReadReg( + unsigned char deviceAddress, + unsigned char registerIndex +) +{ + unsigned char data; + + /* Send the Start signal */ + swI2CStart(); + + /* Send the device address */ + swI2CWriteByte(deviceAddress); + + /* Send the register index */ + swI2CWriteByte(registerIndex); + + /* Get the bus again and get the data from the device read address */ + swI2CStart(); + swI2CWriteByte(deviceAddress + 1); + data = swI2CReadByte(1); + + /* Stop swI2C and release the bus */ + swI2CStop(); + + return data; +} + +/* + * This function writes a value to the slave device's register + * + * Parameters: + * deviceAddress - i2c Slave device address which register + * to be written + * registerIndex - Slave device's register to be written + * data - Data to be written to the register + * + * Result: + * 0 - Success + * -1 - Fail + */ +long swI2CWriteReg( + unsigned char deviceAddress, + unsigned char registerIndex, + unsigned char data +) +{ + long returnValue = 0; + + /* Send the Start signal */ + swI2CStart(); + + /* Send the device address and read the data. All should return success + in order for the writing processed to be successful + */ + if ((swI2CWriteByte(deviceAddress) != 0) || + (swI2CWriteByte(registerIndex) != 0) || + (swI2CWriteByte(data) != 0)) + { + returnValue = -1; + } + + /* Stop i2c and release the bus */ + swI2CStop(); + + return returnValue; +} diff --git a/drivers/staging/sm750fb/ddk750_swi2c.h b/drivers/staging/sm750fb/ddk750_swi2c.h new file mode 100644 index 000000000000..ec5463b98ddf --- /dev/null +++ b/drivers/staging/sm750fb/ddk750_swi2c.h @@ -0,0 +1,92 @@ +/******************************************************************* +* +* Copyright (c) 2007 by Silicon Motion, Inc. (SMI) +* +* All rights are reserved. Reproduction or in part is prohibited +* without the written consent of the copyright owner. +* +* swi2c.h --- SM750/SM718 DDK +* This file contains the definitions for i2c using software +* implementation. +* +*******************************************************************/ +#ifndef _SWI2C_H_ +#define _SWI2C_H_ + +/* Default i2c CLK and Data GPIO. These are the default i2c pins */ +#define DEFAULT_I2C_SCL 30 +#define DEFAULT_I2C_SDA 31 + +/* + * This function initializes the i2c attributes and bus + * + * Parameters: + * i2cClkGPIO - The GPIO pin to be used as i2c SCL + * i2cDataGPIO - The GPIO pin to be used as i2c SDA + * + * Return Value: + * -1 - Fail to initialize the i2c + * 0 - Success + */ +long swI2CInit( + unsigned char i2cClkGPIO, + unsigned char i2cDataGPIO +); + +/* + * This function reads the slave device's register + * + * Parameters: + * deviceAddress - i2c Slave device address which register + * to be read from + * registerIndex - Slave device's register to be read + * + * Return Value: + * Register value + */ +unsigned char swI2CReadReg( + unsigned char deviceAddress, + unsigned char registerIndex +); + +/* + * This function writes a value to the slave device's register + * + * Parameters: + * deviceAddress - i2c Slave device address which register + * to be written + * registerIndex - Slave device's register to be written + * data - Data to be written to the register + * + * Result: + * 0 - Success + * -1 - Fail + */ +long swI2CWriteReg( + unsigned char deviceAddress, + unsigned char registerIndex, + unsigned char data +); + +/* + * These two functions are used to toggle the data on the SCL and SDA I2C lines. + * The used of these two functions are not recommended unless it is necessary. + */ + +/* + * This function set/reset the SCL GPIO pin + * + * Parameters: + * value - Bit value to set to the SCL or SDA (0 = low, 1 = high) + */ +void swI2CSCL(unsigned char value); + +/* + * This function set/reset the SDA GPIO pin + * + * Parameters: + * value - Bit value to set to the SCL or SDA (0 = low, 1 = high) + */ +void swI2CSDA(unsigned char value); + +#endif /* _SWI2C_H_ */ diff --git a/drivers/staging/sm750fb/modedb.h b/drivers/staging/sm750fb/modedb.h new file mode 100644 index 000000000000..c5275c6fffaf --- /dev/null +++ b/drivers/staging/sm750fb/modedb.h @@ -0,0 +1,221 @@ + +static const struct fb_videomode modedb2[] = { + { + /* 640x400 @ 70 Hz, 31.5 kHz hsync */ + NULL, 70, 640, 400, 39721, 40, 24, 39, 9, 96, 2, + 0, FB_VMODE_NONINTERLACED + }, { + /* 640x480 @ 60 Hz, 31.5 kHz hsync */ + NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2, + 0, FB_VMODE_NONINTERLACED + }, { + /* 800x600 @ 56 Hz, 35.15 kHz hsync */ + NULL, 56, 800, 600, 27777, 128, 24, 22, 1, 72, 2, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1024x768 @ 87 Hz interlaced, 35.5 kHz hsync */ + NULL, 87, 1024, 768, 22271, 56, 24, 33, 8, 160, 8, + 0, FB_VMODE_INTERLACED + }, { + /* 640x400 @ 85 Hz, 37.86 kHz hsync */ + NULL, 85, 640, 400, 31746, 96, 32, 41, 1, 64, 3, + FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, { + /* 640x480 @ 72 Hz, 36.5 kHz hsync */ + NULL, 72, 640, 480, 31746, 144, 40, 30, 8, 40, 3, + 0, FB_VMODE_NONINTERLACED + }, { + /* 640x480 @ 75 Hz, 37.50 kHz hsync */ + NULL, 75, 640, 480, 31746, 120, 16, 16, 1, 64, 3, + 0, FB_VMODE_NONINTERLACED + }, { + /* 800x600 @ 60 Hz, 37.8 kHz hsync */ + NULL, 60, 800, 600, 25000, 88, 40, 23, 1, 128, 4, + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, { + /* 640x480 @ 85 Hz, 43.27 kHz hsync */ + NULL, 85, 640, 480, 27777, 80, 56, 25, 1, 56, 3, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1152x864 @ 89 Hz interlaced, 44 kHz hsync */ + NULL, 69, 1152, 864, 15384, 96, 16, 110, 1, 216, 10, + 0, FB_VMODE_INTERLACED + }, { + /* 800x600 @ 72 Hz, 48.0 kHz hsync */ + NULL, 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6, + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, { + /* 1024x768 @ 60 Hz, 48.4 kHz hsync */ + NULL, 60, 1024, 768, 15384, 168, 8, 29, 3, 144, 6, + 0, FB_VMODE_NONINTERLACED + }, { + /* 640x480 @ 100 Hz, 53.01 kHz hsync */ + NULL, 100, 640, 480, 21834, 96, 32, 36, 8, 96, 6, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1152x864 @ 60 Hz, 53.5 kHz hsync */ + NULL, 60, 1152, 864, 11123, 208, 64, 16, 4, 256, 8, + 0, FB_VMODE_NONINTERLACED + }, { + /* 800x600 @ 85 Hz, 55.84 kHz hsync */ + NULL, 85, 800, 600, 16460, 160, 64, 36, 16, 64, 5, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1024x768 @ 70 Hz, 56.5 kHz hsync */ + NULL, 70, 1024, 768, 13333, 144, 24, 29, 3, 136, 6, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1280x960-60 VESA */ + NULL, 60, 1280, 960, 9259, 312, 96, 36, 1, 112, 3, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA + }, { + /* 1280x1024-60 VESA */ + NULL, 60, 1280, 1024, 9259, 248, 48, 38, 1, 112, 3, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA + }, { + /* 1280x1024 @ 87 Hz interlaced, 51 kHz hsync */ + NULL, 87, 1280, 1024, 12500, 56, 16, 128, 1, 216, 12, + 0, FB_VMODE_INTERLACED + }, { + /* 800x600 @ 100 Hz, 64.02 kHz hsync */ + NULL, 100, 800, 600, 14357, 160, 64, 30, 4, 64, 6, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1024x768 @ 76 Hz, 62.5 kHz hsync */ + NULL, 76, 1024, 768, 11764, 208, 8, 36, 16, 120, 3, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1152x864 @ 70 Hz, 62.4 kHz hsync */ + NULL, 70, 1152, 864, 10869, 106, 56, 20, 1, 160, 10, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1280x1024 @ 61 Hz, 64.2 kHz hsync */ + NULL, 61, 1280, 1024, 9090, 200, 48, 26, 1, 184, 3, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1400x1050 @ 60Hz, 63.9 kHz hsync */ + NULL, 68, 1400, 1050, 9259, 136, 40, 13, 1, 112, 3, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1400x1050 @ 75,107 Hz, 82,392 kHz +hsync +vsync*/ + NULL, 75, 1400, 1050, 9271, 120, 56, 13, 0, 112, 3, + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, { + /* 1400x1050 @ 60 Hz, ? kHz +hsync +vsync*/ + NULL, 60, 1400, 1050, 9259, 128, 40, 12, 0, 112, 3, + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, { + /* 1024x768 @ 85 Hz, 70.24 kHz hsync */ + NULL, 85, 1024, 768, 10111, 192, 32, 34, 14, 160, 6, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1152x864 @ 78 Hz, 70.8 kHz hsync */ + NULL, 78, 1152, 864, 9090, 228, 88, 32, 0, 84, 12, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1280x1024 @ 70 Hz, 74.59 kHz hsync */ + NULL, 70, 1280, 1024, 7905, 224, 32, 28, 8, 160, 8, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1600x1200 @ 60Hz, 75.00 kHz hsync */ + NULL, 60, 1600, 1200, 6172, 304, 64, 46, 1, 192, 3, + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, { + /* 1152x864 @ 84 Hz, 76.0 kHz hsync */ + NULL, 84, 1152, 864, 7407, 184, 312, 32, 0, 128, 12, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1280x1024 @ 74 Hz, 78.85 kHz hsync */ + NULL, 74, 1280, 1024, 7407, 256, 32, 34, 3, 144, 3, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1024x768 @ 100Hz, 80.21 kHz hsync */ + NULL, 100, 1024, 768, 8658, 192, 32, 21, 3, 192, 10, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1280x1024 @ 76 Hz, 81.13 kHz hsync */ + NULL, 76, 1280, 1024, 7407, 248, 32, 34, 3, 104, 3, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1600x1200 @ 70 Hz, 87.50 kHz hsync */ + NULL, 70, 1600, 1200, 5291, 304, 64, 46, 1, 192, 3, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1152x864 @ 100 Hz, 89.62 kHz hsync */ + NULL, 100, 1152, 864, 7264, 224, 32, 17, 2, 128, 19, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1280x1024 @ 85 Hz, 91.15 kHz hsync */ + NULL, 85, 1280, 1024, 6349, 224, 64, 44, 1, 160, 3, + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, { + /* 1600x1200 @ 75 Hz, 93.75 kHz hsync */ + NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3, + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, { + /* 1600x1200 @ 85 Hz, 105.77 kHz hsync */ + NULL, 85, 1600, 1200, 4545, 272, 16, 37, 4, 192, 3, + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, { + /* 1280x1024 @ 100 Hz, 107.16 kHz hsync */ + NULL, 100, 1280, 1024, 5502, 256, 32, 26, 7, 128, 15, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1800x1440 @ 64Hz, 96.15 kHz hsync */ + NULL, 64, 1800, 1440, 4347, 304, 96, 46, 1, 192, 3, + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, { + /* 1800x1440 @ 70Hz, 104.52 kHz hsync */ + NULL, 70, 1800, 1440, 4000, 304, 96, 46, 1, 192, 3, + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, { + /* 512x384 @ 78 Hz, 31.50 kHz hsync */ + NULL, 78, 512, 384, 49603, 48, 16, 16, 1, 64, 3, + 0, FB_VMODE_NONINTERLACED + }, { + /* 512x384 @ 85 Hz, 34.38 kHz hsync */ + NULL, 85, 512, 384, 45454, 48, 16, 16, 1, 64, 3, + 0, FB_VMODE_NONINTERLACED + }, { + /* 320x200 @ 70 Hz, 31.5 kHz hsync, 8:5 aspect ratio */ + NULL, 70, 320, 200, 79440, 16, 16, 20, 4, 48, 1, + 0, FB_VMODE_DOUBLE + }, { + /* 320x240 @ 60 Hz, 31.5 kHz hsync, 4:3 aspect ratio */ + NULL, 60, 320, 240, 79440, 16, 16, 16, 5, 48, 1, + 0, FB_VMODE_DOUBLE + }, { + /* 320x240 @ 72 Hz, 36.5 kHz hsync */ + NULL, 72, 320, 240, 63492, 16, 16, 16, 4, 48, 2, + 0, FB_VMODE_DOUBLE + }, { + /* 400x300 @ 56 Hz, 35.2 kHz hsync, 4:3 aspect ratio */ + NULL, 56, 400, 300, 55555, 64, 16, 10, 1, 32, 1, + 0, FB_VMODE_DOUBLE + }, { + /* 400x300 @ 60 Hz, 37.8 kHz hsync */ + NULL, 60, 400, 300, 50000, 48, 16, 11, 1, 64, 2, + 0, FB_VMODE_DOUBLE + }, { + /* 400x300 @ 72 Hz, 48.0 kHz hsync */ + NULL, 72, 400, 300, 40000, 32, 24, 11, 19, 64, 3, + 0, FB_VMODE_DOUBLE + }, { + /* 480x300 @ 56 Hz, 35.2 kHz hsync, 8:5 aspect ratio */ + NULL, 56, 480, 300, 46176, 80, 16, 10, 1, 40, 1, + 0, FB_VMODE_DOUBLE + }, { + /* 480x300 @ 60 Hz, 37.8 kHz hsync */ + NULL, 60, 480, 300, 41858, 56, 16, 11, 1, 80, 2, + 0, FB_VMODE_DOUBLE + }, { + /* 480x300 @ 63 Hz, 39.6 kHz hsync */ + NULL, 63, 480, 300, 40000, 56, 16, 11, 1, 80, 2, + 0, FB_VMODE_DOUBLE + }, { + /* 480x300 @ 72 Hz, 48.0 kHz hsync */ + NULL, 72, 480, 300, 33386, 40, 24, 11, 19, 80, 3, + 0, FB_VMODE_DOUBLE + }, +}; +static const int nmodedb2 = sizeof(modedb2); diff --git a/drivers/staging/sm750fb/readme b/drivers/staging/sm750fb/readme new file mode 100644 index 000000000000..ab9af791653d --- /dev/null +++ b/drivers/staging/sm750fb/readme @@ -0,0 +1,38 @@ +Introduction: + SM750 of Silicon MOtion is pci express display controller device. + The SM750 embedded graphics features include: + - dual display + - 2D acceleration + - 16MB integrated video memory + +About the kernel module paramter of driver: + + Use 1280,8bpp index color and 60 hz mode: + insmod ./sm750fb.ko g_option="1280x1024-8@60" + + Disable MTRR,Disable 2d acceleration,Disable hardware cursor, + and use a 800x600 mode : + insmod ./sm750fb.ko g_option="noaccel:nomtrr:nohwc:800x600" + + dual frame buffer for driver with "dual" parameter + insmod ./sm750fb.ko g_option="dual,800x600:1024x768" + it will create fb0 and fb1 (or fb1,fb2 if fb0 already exist) under /dev + and user can use con2fb to link fbX and ttyX + + Notes: + 1) if you build the driver with built-in method, the paramter + you edited in the grub config file will be also the + same format as above modular method,but additionaly add + "video=sm750fb:" + ahead of parameters,so,it looks like: + video=sm750fb:noaccel,1280x1024@60,otherparam,etc... + it equal to modular method with below command: + insmod ./sm750fb.ko g_option="noaccel:1280x1024@60:otherparm:etc..." + + 2) if you put 800x600 into the paramter without bpp and + refresh rate, kernel driver will defaulty use 16bpp and 60hz + +Important: + if you have vesafb enabled in your config then /dev/fb0 will be created by vesafb + and this driver will use fb1, fb2. In that case, you need to configure your X-server + to use fb1. Another simple althernative is to disable vesafb from your config. diff --git a/drivers/staging/sm750fb/sm750.c b/drivers/staging/sm750fb/sm750.c new file mode 100644 index 000000000000..520c69e3ab74 --- /dev/null +++ b/drivers/staging/sm750fb/sm750.c @@ -0,0 +1,1451 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_MTRR +#include +#endif +#include +#include "sm750.h" +#include "sm750_hw.h" +#include "sm750_accel.h" +#include "sm750_cursor.h" + +#include "modedb.h" + +int smi_indent = 0; + + +/* +#ifdef __BIG_ENDIAN +ssize_t lynxfb_ops_write(struct fb_info *info, const char __user *buf, + size_t count, loff_t *ppos); +ssize_t lynxfb_ops_read(struct fb_info *info, char __user *buf, + size_t count, loff_t *ppos); +#endif + */ + +typedef void (*PROC_SPEC_SETUP)(struct lynx_share*,char *); +typedef int (*PROC_SPEC_MAP)(struct lynx_share*,struct pci_dev*); +typedef int (*PROC_SPEC_INITHW)(struct lynx_share*,struct pci_dev*); + + +/* common var for all device */ +static int g_hwcursor = 1; +static int g_noaccel = 0; +#ifdef CONFIG_MTRR +static int g_nomtrr = 0; +#endif +static const char * g_fbmode[] = {NULL,NULL}; +static const char * g_def_fbmode = "800x600-16@60"; +static char * g_settings = NULL; +static int g_dualview = 0; +#ifdef MODULE +static char * g_option = NULL; +#endif + +/* if not use spin_lock,system will die if user load driver + * and immediatly unload driver frequently (dual)*/ +static inline void myspin_lock(spinlock_t * sl){ + struct lynx_share * share; + share = container_of(sl,struct lynx_share,slock); + if(share->dual){ + spin_lock(sl); + } +} + +static inline void myspin_unlock(spinlock_t * sl){ + struct lynx_share * share; + share = container_of(sl,struct lynx_share,slock); + if(share->dual){ + spin_unlock(sl); + } +} +static const struct fb_videomode lynx750_ext[] = { + /* 1024x600-60 VESA [1.71:1] */ + {NULL, 60, 1024, 600, 20423, 144, 40, 18, 1, 104, 3, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED}, + + /* 1024x600-70 VESA */ + {NULL, 70, 1024, 600, 17211, 152, 48, 21, 1, 104, 3, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED}, + + /* 1024x600-75 VESA */ + {NULL, 75, 1024, 600, 15822, 160, 56, 23, 1, 104, 3, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED}, + + /* 1024x600-85 VESA */ + {NULL, 85, 1024, 600, 13730, 168, 56, 26, 1, 112, 3, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED}, + + /* 720x480 */ + {NULL, 60, 720, 480, 37427, 88, 16, 13, 1, 72, 3, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED}, + + /* 1280x720 [1.78:1] */ + {NULL, 60, 1280, 720, 13426, 162, 86, 22, 1, 136, 3, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,FB_VMODE_NONINTERLACED}, + + /* 1280x768@60 */ + {NULL,60,1280,768,12579,192,64,20,3,128,7, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,FB_VMODE_NONINTERLACED}, + + {NULL,60,1360,768,11804,208,64,23,1,144,3, + FB_SYNC_HOR_HIGH_ACT|FB_VMODE_NONINTERLACED}, + + /* 1360 x 768 [1.77083:1] */ + {NULL, 60, 1360, 768, 11804, 208, 64, 23, 1, 144, 3, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED}, + + /* 1368 x 768 [1.78:1] */ + {NULL, 60, 1368, 768, 11647, 216, 72, 23, 1, 144, 3, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED}, + + /* 1440 x 900 [16:10] */ + {NULL, 60, 1440, 900, 9392, 232, 80, 28, 1, 152, 3, + FB_SYNC_VERT_HIGH_ACT,FB_VMODE_NONINTERLACED}, + + /* 1440x960 [15:10] */ + {NULL, 60, 1440, 960, 8733, 240, 88, 30, 1, 152, 3, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED}, + + /* 1920x1080 [16:9] */ + {NULL, 60, 1920, 1080, 6734, 148, 88, 41, 1, 44, 3, + FB_SYNC_VERT_HIGH_ACT,FB_VMODE_NONINTERLACED}, +}; + + + + +/* no hardware cursor supported under version 2.6.10, kernel bug */ +static int lynxfb_ops_cursor(struct fb_info* info,struct fb_cursor* fbcursor) +{ + struct lynxfb_par * par; + struct lynxfb_crtc * crtc; + struct lynx_cursor * cursor; + + par = info->par; + crtc = &par->crtc; + cursor = &crtc->cursor; + + if(fbcursor->image.width > cursor->maxW || + fbcursor->image.height > cursor->maxH || + fbcursor->image.depth > 1){ + return -ENXIO; + } + + cursor->disable(cursor); + if(fbcursor->set & FB_CUR_SETSIZE){ + cursor->setSize(cursor,fbcursor->image.width,fbcursor->image.height); + } + + if(fbcursor->set & FB_CUR_SETPOS){ + cursor->setPos(cursor,fbcursor->image.dx - info->var.xoffset, + fbcursor->image.dy - info->var.yoffset); + } + + if(fbcursor->set & FB_CUR_SETCMAP){ + /* get the 16bit color of kernel means */ + u16 fg,bg; + fg = ((info->cmap.red[fbcursor->image.fg_color] & 0xf800))| + ((info->cmap.green[fbcursor->image.fg_color] & 0xfc00) >> 5)| + ((info->cmap.blue[fbcursor->image.fg_color] & 0xf800) >> 11); + + bg = ((info->cmap.red[fbcursor->image.bg_color] & 0xf800))| + ((info->cmap.green[fbcursor->image.bg_color] & 0xfc00) >> 5)| + ((info->cmap.blue[fbcursor->image.bg_color] & 0xf800) >> 11); + + cursor->setColor(cursor,fg,bg); + } + + + if(fbcursor->set & (FB_CUR_SETSHAPE | FB_CUR_SETIMAGE)) + { + cursor->setData(cursor, + fbcursor->rop, + fbcursor->image.data, + fbcursor->mask); + } + + if(fbcursor->enable){ + cursor->enable(cursor); + } + + return 0; +} + +static void lynxfb_ops_fillrect(struct fb_info* info,const struct fb_fillrect* region) +{ + struct lynxfb_par * par; + struct lynx_share * share; + unsigned int base,pitch,Bpp,rop; + u32 color; + + if(info->state != FBINFO_STATE_RUNNING){ + return; + } + + par = info->par; + share = par->share; + + /* each time 2d function begin to work,below three variable always need + * be set, seems we can put them together in some place */ + base = par->crtc.oScreen; + pitch = info->fix.line_length; + Bpp = info->var.bits_per_pixel >> 3; + + color = (Bpp == 1)?region->color:((u32*)info->pseudo_palette)[region->color]; + rop = ( region->rop != ROP_COPY ) ? HW_ROP2_XOR:HW_ROP2_COPY; + + myspin_lock(&share->slock); + share->accel.de_fillrect(&share->accel, + base,pitch,Bpp, + region->dx,region->dy, + region->width,region->height, + color,rop); + myspin_unlock(&share->slock); +} + +static void lynxfb_ops_copyarea(struct fb_info * info,const struct fb_copyarea * region) +{ + struct lynxfb_par * par; + struct lynx_share * share; + unsigned int base,pitch,Bpp; + + par = info->par; + share = par->share; + + /* each time 2d function begin to work,below three variable always need + * be set, seems we can put them together in some place */ + base = par->crtc.oScreen; + pitch = info->fix.line_length; + Bpp = info->var.bits_per_pixel >> 3; + + myspin_lock(&share->slock); + share->accel.de_copyarea(&share->accel, + base,pitch,region->sx,region->sy, + base,pitch,Bpp,region->dx,region->dy, + region->width,region->height,HW_ROP2_COPY); + myspin_unlock(&share->slock); +} + +static void lynxfb_ops_imageblit(struct fb_info*info,const struct fb_image* image) +{ + unsigned int base,pitch,Bpp; + unsigned int fgcol,bgcol; + struct lynxfb_par * par; + struct lynx_share * share; + + par = info->par; + share = par->share; + /* each time 2d function begin to work,below three variable always need + * be set, seems we can put them together in some place */ + base = par->crtc.oScreen; + pitch = info->fix.line_length; + Bpp = info->var.bits_per_pixel >> 3; + + if(image->depth == 1){ + if(info->fix.visual == FB_VISUAL_TRUECOLOR || + info->fix.visual == FB_VISUAL_DIRECTCOLOR) + { + fgcol = ((u32*)info->pseudo_palette)[image->fg_color]; + bgcol = ((u32*)info->pseudo_palette)[image->bg_color]; + } + else + { + fgcol = image->fg_color; + bgcol = image->bg_color; + } + goto _do_work; + } + return; +_do_work: + myspin_lock(&share->slock); + share->accel.de_imageblit(&share->accel, + image->data,image->width>>3,0, + base,pitch,Bpp, + image->dx,image->dy, + image->width,image->height, + fgcol,bgcol,HW_ROP2_COPY); + myspin_unlock(&share->slock); +} + +static int lynxfb_ops_pan_display(struct fb_var_screeninfo *var, + struct fb_info *info) +{ + struct lynxfb_par * par; + struct lynxfb_crtc * crtc; + int ret; + + + if(!info) + return -EINVAL; + + ret = 0; + par = info->par; + crtc = &par->crtc; + ret = crtc->proc_panDisplay(crtc, var, info); + + return ret; +} + + + + +#ifdef CONFIG_PM +static int lynxfb_suspend(struct pci_dev * pdev,pm_message_t mesg) +{ + struct fb_info * info; + struct lynx_share * share; + int ret; + + + if(mesg.event == pdev->dev.power.power_state.event) + return 0; + + ret = 0; + share = pci_get_drvdata(pdev); + switch (mesg.event) { + case PM_EVENT_FREEZE: + case PM_EVENT_PRETHAW: + pdev->dev.power.power_state = mesg; + return 0; + } + + console_lock(); + if (mesg.event & PM_EVENT_SLEEP) { + info = share->fbinfo[0]; + if(info) + fb_set_suspend(info, 1);/* 1 means do suspend*/ + + info = share->fbinfo[1]; + if(info) + fb_set_suspend(info, 1);/* 1 means do suspend*/ + + ret = pci_save_state(pdev); + if(ret){ + pr_err("error:%d occured in pci_save_state\n",ret); + return ret; + } + + /* set chip to sleep mode */ + if(share->suspend) + (*share->suspend)(share); + + pci_disable_device(pdev); + ret = pci_set_power_state(pdev,pci_choose_state(pdev,mesg)); + if(ret){ + pr_err("error:%d occured in pci_set_power_state\n",ret); + return ret; + } + } + + pdev->dev.power.power_state = mesg; + console_unlock(); + return ret; +} + +static int lynxfb_ops_set_par(struct fb_info * info) +{ + struct lynxfb_par * par; + struct lynx_share * share; + struct lynxfb_crtc * crtc; + struct lynxfb_output * output; + struct fb_var_screeninfo * var; + struct fb_fix_screeninfo * fix; + int ret; + unsigned int line_length; + + + if(!info) + return -EINVAL; + + ret = 0; + par = info->par; + share = par->share; + crtc = &par->crtc; + output = &par->output; + var = &info->var; + fix = &info->fix; + + /* fix structur is not so FIX ... */ + line_length = var->xres_virtual * var->bits_per_pixel / 8; + line_length = PADDING(crtc->line_pad,line_length); + fix->line_length = line_length; + pr_err("fix->line_length = %d\n",fix->line_length); + + /* var->red,green,blue,transp are need to be set by driver + * and these data should be set before setcolreg routine + * */ + + switch(var->bits_per_pixel){ + case 8: + fix->visual = FB_VISUAL_PSEUDOCOLOR; + var->red.offset = 0; + var->red.length = 8; + var->green.offset = 0; + var->green.length = 8; + var->blue.offset = 0; + var->blue.length = 8; + var->transp.length = 0; + var->transp.offset = 0; + break; + case 16: + var->red.offset = 11; + var->red.length = 5; + var->green.offset = 5; + var->green.length = 6; + var->blue.offset = 0; + var->blue.length = 5; + var->transp.length = 0; + var->transp.offset = 0; + fix->visual = FB_VISUAL_TRUECOLOR; + break; + case 24: + case 32: + var->red.offset = 16; + var->red.length = 8; + var->green.offset = 8; + var->green.length = 8; + var->blue.offset = 0 ; + var->blue.length = 8; + fix->visual = FB_VISUAL_TRUECOLOR; + break; + default: + ret = -EINVAL; + break; + } + var->height = var->width = -1; + var->accel_flags = 0;/*FB_ACCELF_TEXT;*/ + + if(ret){ + pr_err("pixel bpp format not satisfied\n."); + return ret; + } + ret = crtc->proc_setMode(crtc,var,fix); + if(!ret) + ret = output->proc_setMode(output,var,fix); + return ret; +} +static inline unsigned int chan_to_field(unsigned int chan,struct fb_bitfield * bf) +{ + chan &= 0xffff; + chan >>= 16 - bf->length; + return chan << bf->offset; +} + + +static int lynxfb_resume(struct pci_dev* pdev) +{ + struct fb_info * info; + struct lynx_share * share; + + struct lynxfb_par * par; + struct lynxfb_crtc * crtc; + struct lynx_cursor * cursor; + + int ret; + + + ret = 0; + share = pci_get_drvdata(pdev); + + console_lock(); + + if((ret = pci_set_power_state(pdev, PCI_D0)) != 0){ + pr_err("error:%d occured in pci_set_power_state\n",ret); + return ret; + } + + + if(pdev->dev.power.power_state.event != PM_EVENT_FREEZE){ + pci_restore_state(pdev); + if ((ret = pci_enable_device(pdev)) != 0){ + pr_err("error:%d occured in pci_enable_device\n",ret); + return ret; + } + pci_set_master(pdev); + } + if(share->resume) + (*share->resume)(share); + + hw_sm750_inithw(share,pdev); + + + info = share->fbinfo[0]; + + if(info){ + par = info->par; + crtc = &par->crtc; + cursor = &crtc->cursor; + memset(cursor->vstart, 0x0, cursor->size); + memset(crtc->vScreen,0x0,crtc->vidmem_size); + lynxfb_ops_set_par(info); + fb_set_suspend(info, 0); + } + + info = share->fbinfo[1]; + + if(info){ + par = info->par; + crtc = &par->crtc; + cursor = &crtc->cursor; + memset(cursor->vstart, 0x0, cursor->size); + memset(crtc->vScreen,0x0,crtc->vidmem_size); + lynxfb_ops_set_par(info); + fb_set_suspend(info, 0); + } + + + console_unlock(); + return ret; +} +#endif + +static int lynxfb_ops_mmap(struct fb_info * info, struct vm_area_struct * vma) +{ + unsigned long off; + unsigned long start; + u32 len; + struct file *file; + + file = vma->vm_file; + + if (!info) + return -ENODEV; + if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) + return -EINVAL; + off = vma->vm_pgoff << PAGE_SHIFT; + printk("lynxfb mmap pgoff: %x\n", vma->vm_pgoff); + printk("lynxfb mmap off 1: %x\n", off); + + /* frame buffer memory */ + start = info->fix.smem_start; + len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.smem_len); + + printk("lynxfb mmap start 1: %x\n", start); + printk("lynxfb mmap len 1: %x\n", len); + + if (off >= len) { + /* memory mapped io */ + off -= len; + printk("lynxfb mmap off 2: %x\n", off); + if (info->var.accel_flags) { + printk("lynxfb mmap accel flags true"); + return -EINVAL; + } + start = info->fix.mmio_start; + len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.mmio_len); + + printk("lynxfb mmap start 2: %x\n", start); + printk("lynxfb mmap len 2: %x\n", len); + } + start &= PAGE_MASK; + printk("lynxfb mmap start 3: %x\n", start); + printk("lynxfb mmap vm start: %x\n", vma->vm_start); + printk("lynxfb mmap vm end: %x\n", vma->vm_end); + printk("lynxfb mmap len: %x\n", len); + printk("lynxfb mmap off: %x\n", off); + if ((vma->vm_end - vma->vm_start + off) > len) + { + return -EINVAL; + } + off += start; + printk("lynxfb mmap off 3: %x\n", off); + vma->vm_pgoff = off >> PAGE_SHIFT; + /* This is an IO map - tell maydump to skip this VMA */ + vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP; + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); + fb_pgprotect(file, vma, off); + printk("lynxfb mmap off 4: %x\n", off); + printk("lynxfb mmap pgprot: %x\n", vma->vm_page_prot); + if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, + vma->vm_end - vma->vm_start, vma->vm_page_prot)) + return -EAGAIN; + return 0; +} + +static int lynxfb_ops_check_var(struct fb_var_screeninfo* var,struct fb_info* info) +{ + struct lynxfb_par * par; + struct lynxfb_crtc * crtc; + struct lynxfb_output * output; + struct lynx_share * share; + int ret; + resource_size_t request; + + + par = info->par; + crtc = &par->crtc; + output = &par->output; + share = par->share; + ret = 0; + + pr_debug("check var:%dx%d-%d\n", + var->xres, + var->yres, + var->bits_per_pixel); + + + switch(var->bits_per_pixel){ + case 8: + case 16: + case 24: /* support 24 bpp for only lynx712/722/720 */ + case 32: + break; + default: + pr_err("bpp %d not supported\n",var->bits_per_pixel); + ret = -EINVAL; + goto exit; + } + + switch(var->bits_per_pixel){ + case 8: + info->fix.visual = FB_VISUAL_PSEUDOCOLOR; + var->red.offset = 0; + var->red.length = 8; + var->green.offset = 0; + var->green.length = 8; + var->blue.offset = 0; + var->blue.length = 8; + var->transp.length = 0; + var->transp.offset = 0; + break; + case 16: + var->red.offset = 11; + var->red.length = 5; + var->green.offset = 5; + var->green.length = 6; + var->blue.offset = 0; + var->blue.length = 5; + var->transp.length = 0; + var->transp.offset = 0; + info->fix.visual = FB_VISUAL_TRUECOLOR; + break; + case 24: + case 32: + var->red.offset = 16; + var->red.length = 8; + var->green.offset = 8; + var->green.length = 8; + var->blue.offset = 0 ; + var->blue.length = 8; + info->fix.visual = FB_VISUAL_TRUECOLOR; + break; + default: + ret = -EINVAL; + break; + } + var->height = var->width = -1; + var->accel_flags = 0;/*FB_ACCELF_TEXT;*/ + + /* check if current fb's video memory big enought to hold the onscreen */ + request = var->xres_virtual * (var->bits_per_pixel >> 3); + /* defaulty crtc->channel go with par->index */ + + request = PADDING(crtc->line_pad,request); + request = request * var->yres_virtual; + if(crtc->vidmem_size < request){ + pr_err("not enough video memory for mode\n"); + return -ENOMEM; + } + + ret = output->proc_checkMode(output,var); + if(!ret) + ret = crtc->proc_checkMode(crtc,var); +exit: + return ret; +} + + +static int lynxfb_ops_setcolreg(unsigned regno,unsigned red, + unsigned green,unsigned blue, + unsigned transp,struct fb_info * info) +{ + struct lynxfb_par * par; + struct lynxfb_crtc * crtc; + struct fb_var_screeninfo * var; + int ret; + + par = info->par; + crtc = &par->crtc; + var = &info->var; + ret = 0; + + //pr_debug("regno=%d,red=%d,green=%d,blue=%d\n",regno,red,green,blue); + if(regno > 256){ + pr_err("regno = %d\n",regno); + return -EINVAL; + } + + if(info->var.grayscale) + red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8; + + if(var->bits_per_pixel == 8 && info->fix.visual == FB_VISUAL_PSEUDOCOLOR) + { + red >>= 8; + green >>= 8; + blue >>= 8; + ret = crtc->proc_setColReg(crtc,regno,red,green,blue); + goto exit; + } + + + if(info->fix.visual == FB_VISUAL_TRUECOLOR && regno < 256 ) + { + u32 val; + if(var->bits_per_pixel == 16 || + var->bits_per_pixel == 32 || + var->bits_per_pixel == 24) + { + val = chan_to_field(red,&var->red); + val |= chan_to_field(green,&var->green); + val |= chan_to_field(blue,&var->blue); + par->pseudo_palette[regno] = val; + goto exit; + } + } + + ret = -EINVAL; + +exit: + return ret; +} + +static int lynxfb_ops_blank(int blank,struct fb_info* info) +{ + struct lynxfb_par * par; + struct lynxfb_output * output; + + pr_debug("blank = %d.\n",blank); + par = info->par; + output = &par->output; + return output->proc_setBLANK(output,blank); +} + +static int sm750fb_set_drv(struct lynxfb_par * par) +{ + int ret; + struct lynx_share * share; + struct sm750_share * spec_share; + struct lynxfb_output * output; + struct lynxfb_crtc * crtc; + + ret = 0; + + share = par->share; + spec_share = container_of(share,struct sm750_share,share); + output = &par->output; + crtc = &par->crtc; + + crtc->vidmem_size = (share->dual)?share->vidmem_size>>1:share->vidmem_size; + /* setup crtc and output member */ + spec_share->hwCursor = g_hwcursor; + + crtc->proc_setMode = hw_sm750_crtc_setMode; + crtc->proc_checkMode = hw_sm750_crtc_checkMode; + crtc->proc_setColReg = hw_sm750_setColReg; + crtc->proc_panDisplay = hw_sm750_pan_display; + crtc->clear = hw_sm750_crtc_clear; + crtc->line_pad = 16; + //crtc->xpanstep = crtc->ypanstep = crtc->ywrapstep = 0; + crtc->xpanstep = 8; + crtc->ypanstep = 1; + crtc->ywrapstep = 0; + + output->proc_setMode = hw_sm750_output_setMode; + output->proc_checkMode = hw_sm750_output_checkMode; + + output->proc_setBLANK = (share->revid == SM750LE_REVISION_ID)?hw_sm750le_setBLANK:hw_sm750_setBLANK; + output->clear = hw_sm750_output_clear; + /* chip specific phase */ + share->accel.de_wait = (share->revid == SM750LE_REVISION_ID)?hw_sm750le_deWait: hw_sm750_deWait; + switch (spec_share->state.dataflow) + { + case sm750_simul_pri: + output->paths = sm750_pnc; + crtc->channel = sm750_primary; + crtc->oScreen = 0; + crtc->vScreen = share->pvMem; + pr_info("use simul primary mode\n"); + break; + case sm750_simul_sec: + output->paths = sm750_pnc; + crtc->channel = sm750_secondary; + crtc->oScreen = 0; + crtc->vScreen = share->pvMem; + break; + case sm750_dual_normal: + if(par->index == 0){ + output->paths = sm750_panel; + crtc->channel = sm750_primary; + crtc->oScreen = 0; + crtc->vScreen = share->pvMem; + }else{ + output->paths = sm750_crt; + crtc->channel = sm750_secondary; + /* not consider of padding stuffs for oScreen,need fix*/ + crtc->oScreen = (share->vidmem_size >> 1); + crtc->vScreen = share->pvMem + crtc->oScreen; + } + break; + case sm750_dual_swap: + if(par->index == 0){ + output->paths = sm750_panel; + crtc->channel = sm750_secondary; + crtc->oScreen = 0; + crtc->vScreen = share->pvMem; + }else{ + output->paths = sm750_crt; + crtc->channel = sm750_primary; + /* not consider of padding stuffs for oScreen,need fix*/ + crtc->oScreen = (share->vidmem_size >> 1); + crtc->vScreen = share->pvMem + crtc->oScreen; + } + break; + default: + ret = -EINVAL; + } + + return ret; +} + +static struct fb_ops lynxfb_ops={ + .owner = THIS_MODULE, + .fb_check_var = lynxfb_ops_check_var, + .fb_set_par = lynxfb_ops_set_par, + .fb_setcolreg = lynxfb_ops_setcolreg, + .fb_blank = lynxfb_ops_blank, + /*.fb_mmap = lynxfb_ops_mmap,*/ + /* will be hooked by hardware */ + .fb_fillrect = cfb_fillrect, + .fb_imageblit = cfb_imageblit, + .fb_copyarea = cfb_copyarea, + /* cursor */ + .fb_cursor = lynxfb_ops_cursor, +}; + + +static int lynxfb_set_fbinfo(struct fb_info* info,int index) +{ + int i; + struct lynxfb_par * par; + struct lynx_share * share; + struct lynxfb_crtc * crtc; + struct lynxfb_output * output; + struct fb_var_screeninfo * var; + struct fb_fix_screeninfo * fix; + + const struct fb_videomode * pdb[] = { + lynx750_ext, NULL,vesa_modes, + }; + int cdb[] = {ARRAY_SIZE(lynx750_ext),0,VESA_MODEDB_SIZE}; + static const char * mdb_desc[] ={ + "driver prepared modes", + "kernel prepared default modedb", + "kernel HELPERS prepared vesa_modes", + }; + + + static const char * fixId[2]= + { + "sm750_fb1","sm750_fb2", + }; + + int ret,line_length; + + ret = 0; + par = (struct lynxfb_par *)info->par; + share = par->share; + crtc = &par->crtc; + output = &par->output; + var = &info->var; + fix = &info->fix; + + /* set index */ + par->index = index; + output->channel = &crtc->channel; + sm750fb_set_drv(par); + lynxfb_ops.fb_pan_display = lynxfb_ops_pan_display; + + + /* set current cursor variable and proc pointer, + * must be set after crtc member initialized */ + crtc->cursor.offset = crtc->oScreen + crtc->vidmem_size - 1024; + crtc->cursor.mmio = share->pvReg + 0x800f0 + (int)crtc->channel * 0x140; + + pr_info("crtc->cursor.mmio = %p\n",crtc->cursor.mmio); + crtc->cursor.maxH = crtc->cursor.maxW = 64; + crtc->cursor.size = crtc->cursor.maxH*crtc->cursor.maxW*2/8; + crtc->cursor.disable = hw_cursor_disable; + crtc->cursor.enable = hw_cursor_enable; + crtc->cursor.setColor = hw_cursor_setColor; + crtc->cursor.setPos = hw_cursor_setPos; + crtc->cursor.setSize = hw_cursor_setSize; + crtc->cursor.setData = hw_cursor_setData; + crtc->cursor.vstart = share->pvMem + crtc->cursor.offset; + + + crtc->cursor.share = share; + memset(crtc->cursor.vstart, 0, crtc->cursor.size); + if(!g_hwcursor){ + lynxfb_ops.fb_cursor = NULL; + crtc->cursor.disable(&crtc->cursor); + } + + + /* set info->fbops, must be set before fb_find_mode */ + if(!share->accel_off){ + /* use 2d acceleration */ + lynxfb_ops.fb_fillrect = lynxfb_ops_fillrect; + lynxfb_ops.fb_copyarea = lynxfb_ops_copyarea; + lynxfb_ops.fb_imageblit = lynxfb_ops_imageblit; + } + info->fbops = &lynxfb_ops; + + if(!g_fbmode[index]){ + g_fbmode[index] = g_def_fbmode; + if(index) + g_fbmode[index] = g_fbmode[0]; + } + + + for(i=0;i<3;i++){ + + ret = fb_find_mode(var,info,g_fbmode[index], + pdb[i],cdb[i],NULL,8); + + if(ret == 1){ + pr_info("success! use specified mode:%s in %s\n", + g_fbmode[index], + mdb_desc[i]); + break; + }else if(ret == 2){ + pr_warn("use specified mode:%s in %s,with an ignored refresh rate\n", + g_fbmode[index], + mdb_desc[i]); + break; + }else if(ret == 3){ + pr_warn("wanna use default mode\n"); +// break; + }else if(ret == 4){ + pr_warn("fall back to any valid mode\n"); + }else{ + pr_warn("ret = %d,fb_find_mode failed,with %s\n",ret,mdb_desc[i]); + } + } + + /* some member of info->var had been set by fb_find_mode */ + + pr_info("Member of info->var is :\n\ + xres=%d\n\ + yres=%d\n\ + xres_virtual=%d\n\ + yres_virtual=%d\n\ + xoffset=%d\n\ + yoffset=%d\n\ + bits_per_pixel=%d\n \ + ...\n",var->xres,var->yres,var->xres_virtual,var->yres_virtual, + var->xoffset,var->yoffset,var->bits_per_pixel); + + /* set par */ + par->info = info; + + /* set info */ + line_length = PADDING(crtc->line_pad, + (var->xres_virtual * var->bits_per_pixel/8)); + + info->pseudo_palette = &par->pseudo_palette[0]; + info->screen_base = crtc->vScreen; + pr_debug("screen_base vaddr = %p\n",info->screen_base); + info->screen_size = line_length * var->yres_virtual; + info->flags = FBINFO_FLAG_DEFAULT|0; + + /* set info->fix */ + fix->type = FB_TYPE_PACKED_PIXELS; + fix->type_aux = 0; + fix->xpanstep = crtc->xpanstep; + fix->ypanstep = crtc->ypanstep; + fix->ywrapstep = crtc->ywrapstep; + fix->accel = FB_ACCEL_SMI; + + strlcpy(fix->id,fixId[index],sizeof(fix->id)); + + + fix->smem_start = crtc->oScreen + share->vidmem_start; + pr_info("fix->smem_start = %lx\n",fix->smem_start); + /* according to mmap experiment from user space application, + * fix->mmio_len should not larger than virtual size + * (xres_virtual x yres_virtual x ByPP) + * Below line maybe buggy when user mmap fb dev node and write + * data into the bound over virtual size + * */ + fix->smem_len = crtc->vidmem_size; + pr_info("fix->smem_len = %x\n",fix->smem_len); + info->screen_size = fix->smem_len; + fix->line_length = line_length; + fix->mmio_start = share->vidreg_start; + pr_info("fix->mmio_start = %lx\n",fix->mmio_start); + fix->mmio_len = share->vidreg_size; + pr_info("fix->mmio_len = %x\n",fix->mmio_len); + switch(var->bits_per_pixel) + { + case 8: + fix->visual = FB_VISUAL_PSEUDOCOLOR; + break; + case 16: + case 32: + fix->visual = FB_VISUAL_TRUECOLOR; + break; + } + + /* set var */ + var->activate = FB_ACTIVATE_NOW; + var->accel_flags = 0; + var->vmode = FB_VMODE_NONINTERLACED; + + pr_debug("#1 show info->cmap : \nstart=%d,len=%d,red=%p,green=%p,blue=%p,transp=%p\n", + info->cmap.start,info->cmap.len, + info->cmap.red,info->cmap.green,info->cmap.blue, + info->cmap.transp); + + if((ret = fb_alloc_cmap(&info->cmap,256,0)) < 0){ + pr_err("Could not allcate memory for cmap.\n"); + goto exit; + } + + pr_debug("#2 show info->cmap : \nstart=%d,len=%d,red=%p,green=%p,blue=%p,transp=%p\n", + info->cmap.start,info->cmap.len, + info->cmap.red,info->cmap.green,info->cmap.blue, + info->cmap.transp); + +exit: + lynxfb_ops_check_var(var,info); +// lynxfb_ops_set_par(info); + return ret; +} + +/* chip specific g_option configuration routine */ +static void sm750fb_setup(struct lynx_share * share,char * src) +{ + struct sm750_share * spec_share; + char * opt; +#ifdef CAP_EXPENSION + char * exp_res; +#endif + int swap; + + + spec_share = container_of(share,struct sm750_share,share); +#ifdef CAP_EXPENSIION + exp_res = NULL; +#endif + swap = 0; + + spec_share->state.initParm.chip_clk = 0; + spec_share->state.initParm.mem_clk = 0; + spec_share->state.initParm.master_clk = 0; + spec_share->state.initParm.powerMode = 0; + spec_share->state.initParm.setAllEngOff = 0; + spec_share->state.initParm.resetMemory = 1; + + /*defaultly turn g_hwcursor on for both view */ + g_hwcursor = 3; + + if(!src || !*src){ + pr_warn("no specific g_option.\n"); + goto NO_PARAM; + } + + while((opt = strsep(&src,":")) != NULL && *opt != NULL){ + pr_err("opt=%s\n",opt); + pr_err("src=%s\n",src); + + if(!strncmp(opt,"swap",strlen("swap"))) + swap = 1; + else if(!strncmp(opt,"nocrt",strlen("nocrt"))) + spec_share->state.nocrt = 1; + else if(!strncmp(opt,"36bit",strlen("36bit"))) + spec_share->state.pnltype = sm750_doubleTFT; + else if(!strncmp(opt,"18bit",strlen("18bit"))) + spec_share->state.pnltype = sm750_dualTFT; + else if(!strncmp(opt,"24bit",strlen("24bit"))) + spec_share->state.pnltype = sm750_24TFT; +#ifdef CAP_EXPANSION + else if(!strncmp(opt,"exp:",strlen("exp:"))) + exp_res = opt + strlen("exp:"); +#endif + else if(!strncmp(opt,"nohwc0",strlen("nohwc0"))) + g_hwcursor &= ~0x1; + else if(!strncmp(opt,"nohwc1",strlen("nohwc1"))) + g_hwcursor &= ~0x2; + else if(!strncmp(opt,"nohwc",strlen("nohwc"))) + g_hwcursor = 0; + else + { + if(!g_fbmode[0]){ + g_fbmode[0] = opt; + pr_info("find fbmode0 : %s\n",g_fbmode[0]); + }else if(!g_fbmode[1]){ + g_fbmode[1] = opt; + pr_info("find fbmode1 : %s\n",g_fbmode[1]); + }else{ + pr_warn("How many view you wann set?\n"); + } + } + } +#ifdef CAP_EXPANSION + if(getExpRes(exp_res,&spec_share->state.xLCD,&spec_share->state.yLCD)) + { + /* seems exp_res is not valid*/ + spec_share->state.xLCD = spec_share->state.yLCD = 0; + } +#endif + +NO_PARAM: + if(share->revid != SM750LE_REVISION_ID){ + if(share->dual) + { + if(swap) + spec_share->state.dataflow = sm750_dual_swap; + else + spec_share->state.dataflow = sm750_dual_normal; + }else{ + if(swap) + spec_share->state.dataflow = sm750_simul_sec; + else + spec_share->state.dataflow = sm750_simul_pri; + } + }else{ + /* SM750LE only have one crt channel */ + spec_share->state.dataflow = sm750_simul_sec; + /* sm750le do not have complex attributes*/ + spec_share->state.nocrt = 0; + } +} + +static int lynxfb_pci_probe(struct pci_dev * pdev, + const struct pci_device_id * ent) +{ + struct fb_info * info[] = {NULL,NULL}; + struct lynx_share * share = NULL; + + struct sm750_share *spec_share = NULL; + size_t spec_offset = 0; + int fbidx; + + + /* enable device */ + if(pci_enable_device(pdev)){ + pr_err("can not enable device.\n"); + goto err_enable; + } + + /* though offset of share in sm750_share is 0, + * we use this marcro as the same */ + spec_offset = offsetof(struct sm750_share,share); + + spec_share = kzalloc(sizeof(*spec_share),GFP_KERNEL); + if(!spec_share){ + pr_err("Could not allocate memory for share.\n"); + goto err_share; + } + + /* setting share structure */ + share = (struct lynx_share * )(&(spec_share->share)); + share->fbinfo[0] = share->fbinfo[1] = NULL; + share->devid = pdev->device; + share->revid = pdev->revision; + + pr_info("share->revid = %02x\n",share->revid); + share->pdev = pdev; +#ifdef CONFIG_MTRR + share->mtrr_off = g_nomtrr; + share->mtrr.vram = 0; + share->mtrr.vram_added = 0; +#endif + share->accel_off = g_noaccel; + share->dual = g_dualview; + spin_lock_init(&share->slock); + + if(!share->accel_off){ + /* hook deInit and 2d routines, notes that below hw_xxx + * routine can work on most of lynx chips + * if some chip need specific function,please hook it in smXXX_set_drv + * routine */ + share->accel.de_init = hw_de_init; + share->accel.de_fillrect = hw_fillrect; + share->accel.de_copyarea = hw_copyarea; + share->accel.de_imageblit = hw_imageblit; + pr_info("enable 2d acceleration\n"); + }else{ + pr_info("disable 2d acceleration\n"); + } + + /* call chip specific setup routine */ + sm750fb_setup(share,g_settings); + + /* call chip specific mmap routine */ + if(hw_sm750_map(share,pdev)){ + pr_err("Memory map failed\n"); + goto err_map; + } + +#ifdef CONFIG_MTRR + if(!share->mtrr_off){ + pr_info("enable mtrr\n"); + share->mtrr.vram = mtrr_add(share->vidmem_start, + share->vidmem_size, + MTRR_TYPE_WRCOMB,1); + + if(share->mtrr.vram < 0){ + /* don't block driver with the failure of MTRR */ + pr_err("Unable to setup MTRR.\n"); + }else{ + share->mtrr.vram_added = 1; + pr_info("MTRR added succesfully\n"); + } + } +#endif + + memset(share->pvMem,0,share->vidmem_size); + + pr_info("sm%3x mmio address = %p\n",share->devid,share->pvReg); + + pci_set_drvdata(pdev,share); + + /* call chipInit routine */ + hw_sm750_inithw(share,pdev); + + /* allocate frame buffer info structor according to g_dualview */ + fbidx = 0; +ALLOC_FB: + info[fbidx] = framebuffer_alloc(sizeof(struct lynxfb_par),&pdev->dev); + if(!info[fbidx]) + { + pr_err("Could not allocate framebuffer #%d.\n",fbidx); + if(fbidx == 0) + goto err_info0_alloc; + else + goto err_info1_alloc; + } + else + { + struct lynxfb_par * par; + pr_info("framebuffer #%d alloc okay\n",fbidx); + share->fbinfo[fbidx] = info[fbidx]; + par = info[fbidx]->par; + par->share = share; + + /* set fb_info structure */ + if(lynxfb_set_fbinfo(info[fbidx],fbidx)){ + pr_err("Failed to initial fb_info #%d.\n",fbidx); + if(fbidx == 0) + goto err_info0_set; + else + goto err_info1_set; + } + + /* register frame buffer*/ + pr_info("Ready to register framebuffer #%d.\n",fbidx); + int errno = register_framebuffer(info[fbidx]); + if (errno < 0) { + pr_err("Failed to register fb_info #%d. err %d\n",fbidx, errno); + if(fbidx == 0) + goto err_register0; + else + goto err_register1; + } + pr_info("Accomplished register framebuffer #%d.\n",fbidx); + } + + /* no dual view by far */ + fbidx++; + if(share->dual && fbidx < 2) + goto ALLOC_FB; + + return 0; + +err_register1: +err_info1_set: + framebuffer_release(info[1]); +err_info1_alloc: + unregister_framebuffer(info[0]); +err_register0: +err_info0_set: + framebuffer_release(info[0]); +err_info0_alloc: +err_map: + kfree(spec_share); +err_share: +err_enable: + return -ENODEV; +} + +static void __exit lynxfb_pci_remove(struct pci_dev * pdev) +{ + struct fb_info * info; + struct lynx_share * share; + void * spec_share; + struct lynxfb_par * par; + int cnt; + + cnt = 2; + share = pci_get_drvdata(pdev); + + while(cnt-- > 0){ + info = share->fbinfo[cnt]; + if(!info) + continue; + par = info->par; + + unregister_framebuffer(info); + /* clean crtc & output allocations*/ + par->crtc.clear(&par->crtc); + par->output.clear(&par->output); + /* release frame buffer*/ + framebuffer_release(info); + } +#ifdef CONFIG_MTRR + if(share->mtrr.vram_added) + mtrr_del(share->mtrr.vram,share->vidmem_start,share->vidmem_size); +#endif + // pci_release_regions(pdev); + + iounmap(share->pvReg); + iounmap(share->pvMem); + spec_share = container_of(share,struct sm750_share,share); + kfree(g_settings); + kfree(spec_share); + pci_set_drvdata(pdev,NULL); +} + +static int __init lynxfb_setup(char * options) +{ + int len; + char * opt,*tmp; + + + if(!options || !*options){ + pr_warn("no options.\n"); + return 0; + } + + pr_info("options:%s\n",options); + + len = strlen(options) + 1; + g_settings = kmalloc(len,GFP_KERNEL); + if(!g_settings) + return -ENOMEM; + + memset(g_settings,0,len); + tmp = g_settings; + + /* Notes: + char * strsep(char **s,const char * ct); + @s: the string to be searched + @ct :the characters to search for + + strsep() updates @options to pointer after the first found token + it also returns the pointer ahead the token. + */ + while((opt = strsep(&options,":"))!=NULL) + { + /* options that mean for any lynx chips are configured here */ + if(!strncmp(opt,"noaccel",strlen("noaccel"))) + g_noaccel = 1; +#ifdef CONFIG_MTRR + else if(!strncmp(opt,"nomtrr",strlen("nomtrr"))) + g_nomtrr = 1; +#endif + else if(!strncmp(opt,"dual",strlen("dual"))) + g_dualview = 1; + else + { + strcat(tmp,opt); + tmp += strlen(opt); + if(options != NULL) + *tmp++ = ':'; + else + *tmp++ = 0; + } + } + + /* misc g_settings are transport to chip specific routines */ + pr_info("parameter left for chip specific analysis:%s\n",g_settings); + return 0; +} + +static struct pci_device_id smi_pci_table[] = { + { PCI_DEVICE(0x126f, 0x0750), }, + {0,} +}; + +MODULE_DEVICE_TABLE(pci,smi_pci_table); + +static struct pci_driver lynxfb_driver = { + .name = "sm750fb", + .id_table = smi_pci_table, + .probe = lynxfb_pci_probe, + .remove = lynxfb_pci_remove, +#ifdef CONFIG_PM + .suspend = lynxfb_suspend, + .resume = lynxfb_resume, +#endif +}; + + +static int __init lynxfb_init(void) +{ + char *option ; + int ret; + +#ifdef MODULE + option = g_option; +#else + if(fb_get_options("sm750fb",&option)) + return -ENODEV; +#endif + + lynxfb_setup(option); + ret = pci_register_driver(&lynxfb_driver); + return ret; +} +module_init(lynxfb_init); + +static void __exit lynxfb_exit(void) +{ + pci_unregister_driver(&lynxfb_driver); +} +module_exit(lynxfb_exit); + +module_param(g_option,charp,S_IRUGO); + +MODULE_PARM_DESC(g_option, + "\n\t\tCommon options:\n" + "\t\tnoaccel:disable 2d capabilities\n" + "\t\tnomtrr:disable MTRR attribute for video memory\n" + "\t\tdualview:dual frame buffer feature enabled\n" + "\t\tnohwc:disable hardware cursor\n" + "\t\tUsual example:\n" + "\t\tinsmod ./sm750fb.ko g_option=\"noaccel,nohwc,1280x1024-8@60\"\n" + ); + +MODULE_AUTHOR("monk liu "); +MODULE_AUTHOR("Sudip Mukherjee "); +MODULE_DESCRIPTION("Frame buffer driver for SM750 chipset"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/sm750fb/sm750.h b/drivers/staging/sm750fb/sm750.h new file mode 100644 index 000000000000..711676c58839 --- /dev/null +++ b/drivers/staging/sm750fb/sm750.h @@ -0,0 +1,185 @@ +#ifndef LYNXDRV_H_ +#define LYNXDRV_H_ + + + +#define FB_ACCEL_SMI 0xab +/* please use revision id to distinguish sm750le and sm750*/ +#define SPC_SM750 0 + +//#define SPC_SM750LE 8 + +#define MB(x) ((x)<<20) +#define MHZ(x) ((x) * 1000000) +/* align should be 2,4,8,16 */ +#define PADDING(align,data) (((data)+(align)-1)&(~((align) -1))) +extern int smi_indent; + + +struct lynx_accel{ + /* base virtual address of DPR registers */ + volatile unsigned char __iomem * dprBase; + /* base virtual address of de data port */ + volatile unsigned char __iomem * dpPortBase; + + /* function fointers */ + int (*de_init)(struct lynx_accel *); + + int (*de_wait)(void);/* see if hardware ready to work */ + + int (*de_fillrect)(struct lynx_accel *,u32,u32,u32, + u32,u32,u32,u32,u32,u32); + + int (*de_copyarea)(struct lynx_accel *,u32,u32,u32,u32, + u32,u32,u32,u32, + u32,u32,u32,u32); + + int (*de_imageblit)(struct lynx_accel *,const char *,u32,u32,u32, + u32,u32,u32,u32,u32,u32,u32,u32,u32); + +}; + +/* lynx_share stands for a presentation of two frame buffer + that use one smi adaptor , it is similar to a basic class of C++ +*/ +struct lynx_share{ + /* common members */ + u16 devid; + u8 revid; + struct pci_dev * pdev; + struct fb_info * fbinfo[2]; + struct lynx_accel accel; + int accel_off; + int dual; +#ifdef CONFIG_MTRR + int mtrr_off; + struct{ + int vram; + int vram_added; + }mtrr; +#endif + /* all smi graphic adaptor got below attributes */ + resource_size_t vidmem_start; + resource_size_t vidreg_start; + resource_size_t vidmem_size; + resource_size_t vidreg_size; + volatile unsigned char __iomem * pvReg; + unsigned char __iomem * pvMem; + /* locks*/ + spinlock_t slock; + /* function pointers */ + void (*suspend)(struct lynx_share*); + void (*resume)(struct lynx_share*); +}; + +struct lynx_cursor{ + /* cursor width ,height and size */ + int w; + int h; + int size; + /* hardware limitation */ + int maxW; + int maxH; + /* base virtual address and offset of cursor image */ + char __iomem * vstart; + int offset; + /* mmio addr of hw cursor */ + volatile char __iomem * mmio; + /* the lynx_share of this adaptor */ + struct lynx_share * share; + /* proc_routines */ + void (*enable)(struct lynx_cursor *); + void (*disable)(struct lynx_cursor *); + void (*setSize)(struct lynx_cursor *,int,int); + void (*setPos)(struct lynx_cursor *,int,int); + void (*setColor)(struct lynx_cursor *,u32,u32); + void (*setData)(struct lynx_cursor *,u16,const u8*,const u8*); +}; + +struct lynxfb_crtc{ + unsigned char __iomem * vCursor;//virtual address of cursor + unsigned char __iomem * vScreen;//virtual address of on_screen + int oCursor;//cursor address offset in vidmem + int oScreen;//onscreen address offset in vidmem + int channel;/* which channel this crtc stands for*/ + resource_size_t vidmem_size;/* this view's video memory max size */ + + /* below attributes belong to info->fix, their value depends on specific adaptor*/ + u16 line_pad;/* padding information:0,1,2,4,8,16,... */ + u16 xpanstep; + u16 ypanstep; + u16 ywrapstep; + + void * priv; + + int(*proc_setMode)(struct lynxfb_crtc*, + struct fb_var_screeninfo*, + struct fb_fix_screeninfo*); + + int(*proc_checkMode)(struct lynxfb_crtc*,struct fb_var_screeninfo*); + int(*proc_setColReg)(struct lynxfb_crtc*,ushort,ushort,ushort,ushort); + void (*clear)(struct lynxfb_crtc*); + /* pan display */ + int(*proc_panDisplay)(struct lynxfb_crtc*, struct fb_var_screeninfo*, + struct fb_info*); + /* cursor information */ + struct lynx_cursor cursor; +}; + +struct lynxfb_output{ + int dpms; + int paths; + /* which paths(s) this output stands for,for sm750: + paths=1:means output for panel paths + paths=2:means output for crt paths + paths=3:means output for both panel and crt paths + */ + + int * channel; + /* which channel these outputs linked with,for sm750: + *channel=0 means primary channel + *channel=1 means secondary channel + output->channel ==> &crtc->channel + */ + void * priv; + + int(*proc_setMode)(struct lynxfb_output*, + struct fb_var_screeninfo*, + struct fb_fix_screeninfo*); + + int(*proc_checkMode)(struct lynxfb_output*,struct fb_var_screeninfo*); + int(*proc_setBLANK)(struct lynxfb_output*,int); + void (*clear)(struct lynxfb_output*); +}; + +struct lynxfb_par{ + /* either 0 or 1 for dual head adaptor,0 is the older one registered */ + int index; + unsigned int pseudo_palette[256]; + struct lynxfb_crtc crtc; + struct lynxfb_output output; + struct fb_info * info; + struct lynx_share * share; +}; + +#ifndef offsetof +#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) +#endif + + +#define PS_TO_HZ(ps) \ + ({ \ + unsigned long long hz = 1000*1000*1000*1000ULL; \ + do_div(hz,ps); \ + (unsigned long)hz;}) + +static inline unsigned long ps_to_hz(unsigned int psvalue) +{ + unsigned long long numerator=1000*1000*1000*1000ULL; + /* 10^12 / picosecond period gives frequency in Hz */ + do_div(numerator, psvalue); + return (unsigned long)numerator; +} + + +#endif diff --git a/drivers/staging/sm750fb/sm750_accel.c b/drivers/staging/sm750fb/sm750_accel.c new file mode 100644 index 000000000000..ee211deb9975 --- /dev/null +++ b/drivers/staging/sm750fb/sm750_accel.c @@ -0,0 +1,516 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "sm750.h" +#include "sm750_accel.h" +#include "sm750_help.h" +static inline void write_dpr(struct lynx_accel * accel,int offset,u32 regValue) +{ + writel(regValue,accel->dprBase + offset); +} + +static inline u32 read_dpr(struct lynx_accel * accel,int offset) +{ + return readl(accel->dprBase + offset); +} + +static inline void write_dpPort(struct lynx_accel * accel,u32 data) +{ + writel(data,accel->dpPortBase); +} + +void hw_de_init(struct lynx_accel * accel) +{ + /* setup 2d engine registers */ + u32 reg,clr; + + write_dpr(accel,DE_MASKS,0xFFFFFFFF); + + /* dpr1c */ + reg = FIELD_SET(0,DE_STRETCH_FORMAT,PATTERN_XY,NORMAL)| + FIELD_VALUE(0,DE_STRETCH_FORMAT,PATTERN_Y,0)| + FIELD_VALUE(0,DE_STRETCH_FORMAT,PATTERN_X,0)| + FIELD_SET(0,DE_STRETCH_FORMAT,ADDRESSING,XY)| + FIELD_VALUE(0,DE_STRETCH_FORMAT,SOURCE_HEIGHT,3); + + clr = FIELD_CLEAR(DE_STRETCH_FORMAT,PATTERN_XY)& + FIELD_CLEAR(DE_STRETCH_FORMAT,PATTERN_Y)& + FIELD_CLEAR(DE_STRETCH_FORMAT,PATTERN_X)& + FIELD_CLEAR(DE_STRETCH_FORMAT,ADDRESSING)& + FIELD_CLEAR(DE_STRETCH_FORMAT,SOURCE_HEIGHT); + + /* DE_STRETCH bpp format need be initilized in setMode routine */ + write_dpr(accel,DE_STRETCH_FORMAT,(read_dpr(accel,DE_STRETCH_FORMAT) & clr) | reg); + + /* disable clipping and transparent */ + write_dpr(accel,DE_CLIP_TL,0);//dpr2c + write_dpr(accel,DE_CLIP_BR,0);//dpr30 + + write_dpr(accel,DE_COLOR_COMPARE_MASK,0);//dpr24 + write_dpr(accel,DE_COLOR_COMPARE,0); + + reg = FIELD_SET(0,DE_CONTROL,TRANSPARENCY,DISABLE)| + FIELD_SET(0,DE_CONTROL,TRANSPARENCY_MATCH,OPAQUE)| + FIELD_SET(0,DE_CONTROL,TRANSPARENCY_SELECT,SOURCE); + + clr = FIELD_CLEAR(DE_CONTROL,TRANSPARENCY)& + FIELD_CLEAR(DE_CONTROL,TRANSPARENCY_MATCH)& + FIELD_CLEAR(DE_CONTROL,TRANSPARENCY_SELECT); + + /* dpr0c */ + write_dpr(accel,DE_CONTROL,(read_dpr(accel,DE_CONTROL)&clr)|reg); +} + +/* set2dformat only be called from setmode functions + * but if you need dual framebuffer driver,need call set2dformat + * every time you use 2d function */ + +void hw_set2dformat(struct lynx_accel * accel,int fmt) +{ + u32 reg; + + /* fmt=0,1,2 for 8,16,32,bpp on sm718/750/502 */ + reg = read_dpr(accel,DE_STRETCH_FORMAT); + reg = FIELD_VALUE(reg,DE_STRETCH_FORMAT,PIXEL_FORMAT,fmt); + write_dpr(accel,DE_STRETCH_FORMAT,reg); +} + +/* seems sm712 RectFill command is broken,so need use BitBlt to + * replace it. */ + +int hw712_fillrect(struct lynx_accel * accel, + u32 base,u32 pitch,u32 Bpp, + u32 x,u32 y,u32 width,u32 height, + u32 color,u32 rop) +{ + u32 deCtrl; + if(accel->de_wait() != 0) + { + /* int time wait and always busy,seems hardware + * got something error */ + pr_debug("%s:De engine always bussy\n",__func__); + return -1; + } + /* 24bpp 2d acceleration still not work,we already support 2d on + * both 8/16/32 bpp now, so there is no harm if we disable 2d on + * 24bpp for current stage. */ +#if 0 + if(Bpp == 3){ + width *= 3; + x *= 3; + write_dpr(accel,DE_PITCH, + FIELD_VALUE(0,DE_PITCH,DESTINATION,pitch)| + FIELD_VALUE(0,DE_PITCH,SOURCE,pitch));//dpr10 + } + else +#endif + { + write_dpr(accel,DE_PITCH, + FIELD_VALUE(0,DE_PITCH,DESTINATION,pitch/Bpp)| + FIELD_VALUE(0,DE_PITCH,SOURCE,pitch/Bpp));//dpr10 + + } + + write_dpr(accel,DE_FOREGROUND,color);//DPR14 + write_dpr(accel,DE_MONO_PATTERN_HIGH,~0);//DPR34 + write_dpr(accel,DE_MONO_PATTERN_LOW,~0);//DPR38 + + write_dpr(accel,DE_WINDOW_SOURCE_BASE,base);//dpr44 + write_dpr(accel,DE_WINDOW_DESTINATION_BASE,base);//dpr40 + + + write_dpr(accel,DE_WINDOW_WIDTH, + FIELD_VALUE(0,DE_WINDOW_WIDTH,DESTINATION,pitch/Bpp)| + FIELD_VALUE(0,DE_WINDOW_WIDTH,SOURCE,pitch/Bpp));//dpr3c + + + write_dpr(accel,DE_DESTINATION, + FIELD_SET(0,DE_DESTINATION,WRAP,DISABLE)| + FIELD_VALUE(0,DE_DESTINATION,X,x)| + FIELD_VALUE(0,DE_DESTINATION,Y,y));//dpr4 + + write_dpr(accel,DE_DIMENSION, + FIELD_VALUE(0,DE_DIMENSION,X,width)| + FIELD_VALUE(0,DE_DIMENSION,Y_ET,height));//dpr8 + + deCtrl = + FIELD_SET(0,DE_CONTROL,STATUS,START)| + FIELD_SET(0,DE_CONTROL,COMMAND,BITBLT)| + FIELD_SET(0,DE_CONTROL,ROP2_SOURCE,PATTERN)| + FIELD_SET(0,DE_CONTROL,ROP_SELECT,ROP2)| + FIELD_VALUE(0,DE_CONTROL,ROP,rop);//dpr0xc +#if 0 + /* dump registers */ + int i; + inf_msg("x,y,w,h = %d,%d,%d,%d\n",x,y,width,height); + for(i=0x04;i<=0x44;i+=4){ + inf_msg("dpr%02x = %08x\n",i,read_dpr(accel,i)); + } + inf_msg("deCtrl = %08x\n",deCtrl); +#endif + + write_dpr(accel,DE_CONTROL,deCtrl); + return 0; +} + +int hw_fillrect(struct lynx_accel * accel, + u32 base,u32 pitch,u32 Bpp, + u32 x,u32 y,u32 width,u32 height, + u32 color,u32 rop) +{ + u32 deCtrl; + + if(accel->de_wait() != 0) + { + /* int time wait and always busy,seems hardware + * got something error */ + pr_debug("%s:De engine always bussy\n",__func__); + return -1; + } + + write_dpr(accel,DE_WINDOW_DESTINATION_BASE,base);//dpr40 + write_dpr(accel,DE_PITCH, + FIELD_VALUE(0,DE_PITCH,DESTINATION,pitch/Bpp)| + FIELD_VALUE(0,DE_PITCH,SOURCE,pitch/Bpp));//dpr10 + + write_dpr(accel,DE_WINDOW_WIDTH, + FIELD_VALUE(0,DE_WINDOW_WIDTH,DESTINATION,pitch/Bpp)| + FIELD_VALUE(0,DE_WINDOW_WIDTH,SOURCE,pitch/Bpp));//dpr44 + + write_dpr(accel,DE_FOREGROUND,color);//DPR14 + + write_dpr(accel,DE_DESTINATION, + FIELD_SET(0,DE_DESTINATION,WRAP,DISABLE)| + FIELD_VALUE(0,DE_DESTINATION,X,x)| + FIELD_VALUE(0,DE_DESTINATION,Y,y));//dpr4 + + write_dpr(accel,DE_DIMENSION, + FIELD_VALUE(0,DE_DIMENSION,X,width)| + FIELD_VALUE(0,DE_DIMENSION,Y_ET,height));//dpr8 + + deCtrl = + FIELD_SET(0,DE_CONTROL,STATUS,START)| + FIELD_SET(0,DE_CONTROL,DIRECTION,LEFT_TO_RIGHT)| + FIELD_SET(0,DE_CONTROL,LAST_PIXEL,ON)| + FIELD_SET(0,DE_CONTROL,COMMAND,RECTANGLE_FILL)| + FIELD_SET(0,DE_CONTROL,ROP_SELECT,ROP2)| + FIELD_VALUE(0,DE_CONTROL,ROP,rop);//dpr0xc + + write_dpr(accel,DE_CONTROL,deCtrl); + return 0; +} + +int hw_copyarea( +struct lynx_accel * accel, +unsigned int sBase, /* Address of source: offset in frame buffer */ +unsigned int sPitch, /* Pitch value of source surface in BYTE */ +unsigned int sx, +unsigned int sy, /* Starting coordinate of source surface */ +unsigned int dBase, /* Address of destination: offset in frame buffer */ +unsigned int dPitch, /* Pitch value of destination surface in BYTE */ +unsigned int Bpp, /* Color depth of destination surface */ +unsigned int dx, +unsigned int dy, /* Starting coordinate of destination surface */ +unsigned int width, +unsigned int height, /* width and height of rectangle in pixel value */ +unsigned int rop2) /* ROP value */ +{ + unsigned int nDirection, de_ctrl; + int opSign; + nDirection = LEFT_TO_RIGHT; + /* Direction of ROP2 operation: 1 = Left to Right, (-1) = Right to Left */ + opSign = 1; + de_ctrl = 0; + + /* If source and destination are the same surface, need to check for overlay cases */ + if (sBase == dBase && sPitch == dPitch) + { + /* Determine direction of operation */ + if (sy < dy) + { + /* +----------+ + |S | + | +----------+ + | | | | + | | | | + +---|------+ | + | D| + +----------+ */ + + nDirection = BOTTOM_TO_TOP; + } + else if (sy > dy) + { + /* +----------+ + |D | + | +----------+ + | | | | + | | | | + +---|------+ | + | S| + +----------+ */ + + nDirection = TOP_TO_BOTTOM; + } + else + { + /* sy == dy */ + + if (sx <= dx) + { + /* +------+---+------+ + |S | | D| + | | | | + | | | | + | | | | + +------+---+------+ */ + + nDirection = RIGHT_TO_LEFT; + } + else + { + /* sx > dx */ + + /* +------+---+------+ + |D | | S| + | | | | + | | | | + | | | | + +------+---+------+ */ + + nDirection = LEFT_TO_RIGHT; + } + } + } + + if ((nDirection == BOTTOM_TO_TOP) || (nDirection == RIGHT_TO_LEFT)) + { + sx += width - 1; + sy += height - 1; + dx += width - 1; + dy += height - 1; + opSign = (-1); + } + + /* Note: + DE_FOREGROUND are DE_BACKGROUND are don't care. + DE_COLOR_COMPARE and DE_COLOR_COMPARE_MAKS are set by set deSetTransparency(). + */ + + /* 2D Source Base. + It is an address offset (128 bit aligned) from the beginning of frame buffer. + */ + write_dpr(accel,DE_WINDOW_SOURCE_BASE, sBase);//dpr40 + + /* 2D Destination Base. + It is an address offset (128 bit aligned) from the beginning of frame buffer. + */ + write_dpr(accel,DE_WINDOW_DESTINATION_BASE, dBase);//dpr44 + +#if 0 + /* Program pitch (distance between the 1st points of two adjacent lines). + Note that input pitch is BYTE value, but the 2D Pitch register uses + pixel values. Need Byte to pixel convertion. + */ + if(Bpp == 3){ + sx *= 3; + dx *= 3; + width *= 3; + write_dpr(accel,DE_PITCH, + FIELD_VALUE(0, DE_PITCH, DESTINATION, dPitch) | + FIELD_VALUE(0, DE_PITCH, SOURCE, sPitch));//dpr10 + } + else +#endif + { + write_dpr(accel,DE_PITCH, + FIELD_VALUE(0, DE_PITCH, DESTINATION, (dPitch/Bpp)) | + FIELD_VALUE(0, DE_PITCH, SOURCE, (sPitch/Bpp)));//dpr10 + } + + /* Screen Window width in Pixels. + 2D engine uses this value to calculate the linear address in frame buffer for a given point. + */ + write_dpr(accel,DE_WINDOW_WIDTH, + FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, (dPitch/Bpp)) | + FIELD_VALUE(0, DE_WINDOW_WIDTH, SOURCE, (sPitch/Bpp)));//dpr3c + + if (accel->de_wait() != 0){ + return -1; + } + + { + + write_dpr(accel,DE_SOURCE, + FIELD_SET (0, DE_SOURCE, WRAP, DISABLE) | + FIELD_VALUE(0, DE_SOURCE, X_K1, sx) | + FIELD_VALUE(0, DE_SOURCE, Y_K2, sy));//dpr0 + write_dpr(accel,DE_DESTINATION, + FIELD_SET (0, DE_DESTINATION, WRAP, DISABLE) | + FIELD_VALUE(0, DE_DESTINATION, X, dx) | + FIELD_VALUE(0, DE_DESTINATION, Y, dy));//dpr04 + write_dpr(accel,DE_DIMENSION, + FIELD_VALUE(0, DE_DIMENSION, X, width) | + FIELD_VALUE(0, DE_DIMENSION, Y_ET, height));//dpr08 + + de_ctrl = + FIELD_VALUE(0, DE_CONTROL, ROP, rop2) | + FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) | + FIELD_SET(0, DE_CONTROL, COMMAND, BITBLT) | + ((nDirection == RIGHT_TO_LEFT) ? + FIELD_SET(0, DE_CONTROL, DIRECTION, RIGHT_TO_LEFT) + : FIELD_SET(0, DE_CONTROL, DIRECTION, LEFT_TO_RIGHT)) | + FIELD_SET(0, DE_CONTROL, STATUS, START); + write_dpr(accel,DE_CONTROL,de_ctrl);//dpr0c + } + + return 0; +} + +static unsigned int deGetTransparency(struct lynx_accel * accel) +{ + unsigned int de_ctrl; + + de_ctrl = read_dpr(accel,DE_CONTROL); + + de_ctrl &= + FIELD_MASK(DE_CONTROL_TRANSPARENCY_MATCH) | + FIELD_MASK(DE_CONTROL_TRANSPARENCY_SELECT)| + FIELD_MASK(DE_CONTROL_TRANSPARENCY); + + return de_ctrl; +} + +int hw_imageblit( +struct lynx_accel * accel, +unsigned char *pSrcbuf, /* pointer to start of source buffer in system memory */ +int srcDelta, /* Pitch value (in bytes) of the source buffer, +ive means top down and -ive mean button up */ +unsigned int startBit, /* Mono data can start at any bit in a byte, this value should be 0 to 7 */ +unsigned int dBase, /* Address of destination: offset in frame buffer */ +unsigned int dPitch, /* Pitch value of destination surface in BYTE */ +unsigned int bytePerPixel, /* Color depth of destination surface */ +unsigned int dx, +unsigned int dy, /* Starting coordinate of destination surface */ +unsigned int width, +unsigned int height, /* width and height of rectange in pixel value */ +unsigned int fColor, /* Foreground color (corresponding to a 1 in the monochrome data */ +unsigned int bColor, /* Background color (corresponding to a 0 in the monochrome data */ +unsigned int rop2) /* ROP value */ +{ + unsigned int ulBytesPerScan; + unsigned int ul4BytesPerScan; + unsigned int ulBytesRemain; + unsigned int de_ctrl = 0; + unsigned char ajRemain[4]; + int i, j; + + startBit &= 7; /* Just make sure the start bit is within legal range */ + ulBytesPerScan = (width + startBit + 7) / 8; + ul4BytesPerScan = ulBytesPerScan & ~3; + ulBytesRemain = ulBytesPerScan & 3; + + if(accel->de_wait() != 0) + { +// inf_msg("*** ImageBlit return -1 ***\n"); + return -1; + } + + /* 2D Source Base. + Use 0 for HOST Blt. + */ + write_dpr(accel,DE_WINDOW_SOURCE_BASE, 0); + + /* 2D Destination Base. + It is an address offset (128 bit aligned) from the beginning of frame buffer. + */ + write_dpr(accel,DE_WINDOW_DESTINATION_BASE, dBase); +#if 0 + /* Program pitch (distance between the 1st points of two adjacent lines). + Note that input pitch is BYTE value, but the 2D Pitch register uses + pixel values. Need Byte to pixel convertion. + */ + if(bytePerPixel == 3 ){ + dx *= 3; + width *= 3; + startBit *= 3; + write_dpr(accel,DE_PITCH, + FIELD_VALUE(0, DE_PITCH, DESTINATION, dPitch) | + FIELD_VALUE(0, DE_PITCH, SOURCE, dPitch));//dpr10 + + } + else +#endif + { + write_dpr(accel,DE_PITCH, + FIELD_VALUE(0, DE_PITCH, DESTINATION, dPitch/bytePerPixel) | + FIELD_VALUE(0, DE_PITCH, SOURCE, dPitch/bytePerPixel));//dpr10 + } + + /* Screen Window width in Pixels. + 2D engine uses this value to calculate the linear address in frame buffer for a given point. + */ + write_dpr(accel,DE_WINDOW_WIDTH, + FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, (dPitch/bytePerPixel)) | + FIELD_VALUE(0, DE_WINDOW_WIDTH, SOURCE, (dPitch/bytePerPixel))); + + /* Note: For 2D Source in Host Write, only X_K1_MONO field is needed, and Y_K2 field is not used. + For mono bitmap, use startBit for X_K1. */ + write_dpr(accel,DE_SOURCE, + FIELD_SET (0, DE_SOURCE, WRAP, DISABLE) | + FIELD_VALUE(0, DE_SOURCE, X_K1_MONO, startBit));//dpr00 + + write_dpr(accel,DE_DESTINATION, + FIELD_SET (0, DE_DESTINATION, WRAP, DISABLE) | + FIELD_VALUE(0, DE_DESTINATION, X, dx) | + FIELD_VALUE(0, DE_DESTINATION, Y, dy));//dpr04 + + write_dpr(accel,DE_DIMENSION, + FIELD_VALUE(0, DE_DIMENSION, X, width) | + FIELD_VALUE(0, DE_DIMENSION, Y_ET, height));//dpr08 + + write_dpr(accel,DE_FOREGROUND, fColor); + write_dpr(accel,DE_BACKGROUND, bColor); + + de_ctrl = FIELD_VALUE(0, DE_CONTROL, ROP, rop2) | + FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) | + FIELD_SET(0, DE_CONTROL, COMMAND, HOST_WRITE) | + FIELD_SET(0, DE_CONTROL, HOST, MONO) | + FIELD_SET(0, DE_CONTROL, STATUS, START); + + write_dpr(accel,DE_CONTROL, de_ctrl | deGetTransparency(accel)); + + /* Write MONO data (line by line) to 2D Engine data port */ + for (i=0; i +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "sm750.h" +#include "sm750_help.h" +#include "sm750_cursor.h" + + +#define PEEK32(addr) \ +readl(cursor->mmio + (addr)) + +#define POKE32(addr,data) \ +writel((data),cursor->mmio + (addr)) + +/* cursor control for voyager and 718/750*/ +#define HWC_ADDRESS 0x0 +#define HWC_ADDRESS_ENABLE 31:31 +#define HWC_ADDRESS_ENABLE_DISABLE 0 +#define HWC_ADDRESS_ENABLE_ENABLE 1 +#define HWC_ADDRESS_EXT 27:27 +#define HWC_ADDRESS_EXT_LOCAL 0 +#define HWC_ADDRESS_EXT_EXTERNAL 1 +#define HWC_ADDRESS_CS 26:26 +#define HWC_ADDRESS_CS_0 0 +#define HWC_ADDRESS_CS_1 1 +#define HWC_ADDRESS_ADDRESS 25:0 + +#define HWC_LOCATION 0x4 +#define HWC_LOCATION_TOP 27:27 +#define HWC_LOCATION_TOP_INSIDE 0 +#define HWC_LOCATION_TOP_OUTSIDE 1 +#define HWC_LOCATION_Y 26:16 +#define HWC_LOCATION_LEFT 11:11 +#define HWC_LOCATION_LEFT_INSIDE 0 +#define HWC_LOCATION_LEFT_OUTSIDE 1 +#define HWC_LOCATION_X 10:0 + +#define HWC_COLOR_12 0x8 +#define HWC_COLOR_12_2_RGB565 31:16 +#define HWC_COLOR_12_1_RGB565 15:0 + +#define HWC_COLOR_3 0xC +#define HWC_COLOR_3_RGB565 15:0 + + +/* hw_cursor_xxx works for voyager,718 and 750 */ +void hw_cursor_enable(struct lynx_cursor * cursor) +{ + u32 reg; + reg = FIELD_VALUE(0,HWC_ADDRESS,ADDRESS,cursor->offset)| + FIELD_SET(0,HWC_ADDRESS,EXT,LOCAL)| + FIELD_SET(0,HWC_ADDRESS,ENABLE,ENABLE); + POKE32(HWC_ADDRESS,reg); +} +void hw_cursor_disable(struct lynx_cursor * cursor) +{ + POKE32(HWC_ADDRESS,0); +} + +void hw_cursor_setSize(struct lynx_cursor * cursor, + int w,int h) +{ + cursor->w = w; + cursor->h = h; +} +void hw_cursor_setPos(struct lynx_cursor * cursor, + int x,int y) +{ + u32 reg; + reg = FIELD_VALUE(0,HWC_LOCATION,Y,y)| + FIELD_VALUE(0,HWC_LOCATION,X,x); + POKE32(HWC_LOCATION,reg); +} +void hw_cursor_setColor(struct lynx_cursor * cursor, + u32 fg,u32 bg) +{ + POKE32(HWC_COLOR_12,(fg<<16)|(bg&0xffff)); + POKE32(HWC_COLOR_3,0xffe0); +} + +void hw_cursor_setData(struct lynx_cursor * cursor, + u16 rop,const u8* pcol,const u8* pmsk) +{ + int i,j,count,pitch,offset; + u8 color,mask,opr; + u16 data; + u16 * pbuffer,*pstart; + static ulong odd = 0; + + /* in byte*/ + pitch = cursor->w >> 3; + + /* in byte */ + count = pitch * cursor->h; + + /* in ushort */ + offset = cursor->maxW * 2 / 8 / 2; + + data = 0; + pstart = (u16 *)cursor->vstart; + pbuffer = pstart; + +/* + if(odd &1){ + hw_cursor_setData2(cursor,rop,pcol,pmsk); + } + odd++; + if(odd > 0xfffffff0) + odd=0; +*/ + + for(i=0;i> j)) + { //use fg color,id = 2 + data |= 2 << (j*2); + }else{ + //use bg color,id = 1 + data |= 1 << (j*2); + } + } +#else + for(j=0;j<8;j++){ + if(mask & (0x80>>j)){ + if(rop == ROP_XOR) + opr = mask ^ color; + else + opr = mask & color; + + /* 2 stands for forecolor and 1 for backcolor */ + data |= ((opr & (0x80>>j))?2:1)<<(j*2); + } + } +#endif + *pbuffer = data; + + /* assume pitch is 1,2,4,8,...*/ +#if 0 + if(!((i+1)&(pitch-1))) /* below line equal to is line */ +#else + if((i+1) % pitch == 0) +#endif + { + /* need a return */ + pstart += offset; + pbuffer = pstart; + }else{ + pbuffer++; + } + + } + + +} + + +void hw_cursor_setData2(struct lynx_cursor * cursor, + u16 rop,const u8* pcol,const u8* pmsk) +{ + int i,j,count,pitch,offset; + u8 color,mask,opr; + u16 data; + u16 * pbuffer,*pstart; + + /* in byte*/ + pitch = cursor->w >> 3; + + /* in byte */ + count = pitch * cursor->h; + + /* in ushort */ + offset = cursor->maxW * 2 / 8 / 2; + + data = 0; + pstart = (u16 *)cursor->vstart; + pbuffer = pstart; + + for(i=0;i> j)) + { //use fg color,id = 2 + data |= 2 << (j*2); + }else{ + //use bg color,id = 1 + data |= 1 << (j*2); + } + } +#else + for(j=0;j<8;j++){ + if(mask & (1<> (32 - _COUNT(f))) +#define GET_MASK(f) (RAW_MASK(f) << _LSB(f)) +#define GET_FIELD(d,f) (((d) >> _LSB(f)) & RAW_MASK(f)) +#define TEST_FIELD(d,f,v) (GET_FIELD(d,f) == f ## _ ## v) +#define SET_FIELD(d,f,v) (((d) & ~GET_MASK(f)) | \ + (((f ## _ ## v) & RAW_MASK(f)) << _LSB(f))) +#define SET_FIELDV(d,f,v) (((d) & ~GET_MASK(f)) | \ + (((v) & RAW_MASK(f)) << _LSB(f))) + + +//////////////////////////////////////////////////////////////////////////////// +// // +// Internal macros // +// // +//////////////////////////////////////////////////////////////////////////////// + +#define _F_START(f) (0 ? f) +#define _F_END(f) (1 ? f) +#define _F_SIZE(f) (1 + _F_END(f) - _F_START(f)) +#define _F_MASK(f) (((1 << _F_SIZE(f)) - 1) << _F_START(f)) +#define _F_NORMALIZE(v, f) (((v) & _F_MASK(f)) >> _F_START(f)) +#define _F_DENORMALIZE(v, f) (((v) << _F_START(f)) & _F_MASK(f)) + + +//////////////////////////////////////////////////////////////////////////////// +// // +// Global macros // +// // +//////////////////////////////////////////////////////////////////////////////// + +#define FIELD_GET(x, reg, field) \ +( \ + _F_NORMALIZE((x), reg ## _ ## field) \ +) + +#define FIELD_SET(x, reg, field, value) \ +( \ + (x & ~_F_MASK(reg ## _ ## field)) \ + | _F_DENORMALIZE(reg ## _ ## field ## _ ## value, reg ## _ ## field) \ +) + +#define FIELD_VALUE(x, reg, field, value) \ +( \ + (x & ~_F_MASK(reg ## _ ## field)) \ + | _F_DENORMALIZE(value, reg ## _ ## field) \ +) + +#define FIELD_CLEAR(reg, field) \ +( \ + ~ _F_MASK(reg ## _ ## field) \ +) + + +//////////////////////////////////////////////////////////////////////////////// +// // +// Field Macros // +// // +//////////////////////////////////////////////////////////////////////////////// + +#define FIELD_START(field) (0 ? field) +#define FIELD_END(field) (1 ? field) +#define FIELD_SIZE(field) (1 + FIELD_END(field) - FIELD_START(field)) +#define FIELD_MASK(field) (((1 << (FIELD_SIZE(field)-1)) | ((1 << (FIELD_SIZE(field)-1)) - 1)) << FIELD_START(field)) +#define FIELD_NORMALIZE(reg, field) (((reg) & FIELD_MASK(field)) >> FIELD_START(field)) +#define FIELD_DENORMALIZE(field, value) (((value) << FIELD_START(field)) & FIELD_MASK(field)) + +#define FIELD_INIT(reg, field, value) FIELD_DENORMALIZE(reg ## _ ## field, \ + reg ## _ ## field ## _ ## value) +#define FIELD_INIT_VAL(reg, field, value) \ + (FIELD_DENORMALIZE(reg ## _ ## field, value)) +#define FIELD_VAL_SET(x, r, f, v) x = x & ~FIELD_MASK(r ## _ ## f) \ + | FIELD_DENORMALIZE(r ## _ ## f, r ## _ ## f ## _ ## v) + +#define RGB(r, g, b) \ +( \ + (unsigned long) (((r) << 16) | ((g) << 8) | (b)) \ +) + +#define RGB16(r, g, b) \ +( \ + (unsigned short) ((((r) & 0xF8) << 8) | (((g) & 0xFC) << 3) | (((b) & 0xF8) >> 3)) \ +) + +static inline unsigned int absDiff(unsigned int a,unsigned int b) +{ + if(a +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_MTRR +#include +#endif +#include +#include + +#include "sm750.h" +#include "sm750_hw.h" +#include "ddk750.h" +#include "sm750_accel.h" + +int hw_sm750_map(struct lynx_share* share,struct pci_dev* pdev) +{ + int ret; + struct sm750_share * spec_share; + + + spec_share = container_of(share,struct sm750_share,share); + ret = 0; + + share->vidreg_start = pci_resource_start(pdev,1); + share->vidreg_size = MB(2); + + pr_info("mmio phyAddr = %x\n",share->vidreg_start); + + /* reserve the vidreg space of smi adaptor + * if you do this, u need to add release region code + * in lynxfb_remove, or memory will not be mapped again + * successfully + * */ + + if((ret = pci_request_region(pdev,1,"sm750fb"))) + { + pr_err("Can not request PCI regions.\n"); + goto exit; + } + + /* now map mmio and vidmem*/ + share->pvReg = ioremap_nocache(share->vidreg_start,share->vidreg_size); + if(!share->pvReg){ + pr_err("mmio failed\n"); + ret = -EFAULT; + goto exit; + }else{ + pr_info("mmio virtual addr = %p\n",share->pvReg); + } + + + share->accel.dprBase = share->pvReg + DE_BASE_ADDR_TYPE1; + share->accel.dpPortBase = share->pvReg + DE_PORT_ADDR_TYPE1; + + ddk750_set_mmio(share->pvReg,share->devid,share->revid); + + share->vidmem_start = pci_resource_start(pdev,0); + /* don't use pdev_resource[x].end - resource[x].start to + * calculate the resource size,its only the maximum available + * size but not the actual size,use + * @hw_sm750_getVMSize function can be safe. + * */ + share->vidmem_size = hw_sm750_getVMSize(share); + pr_info("video memory phyAddr = %x, size = %d bytes\n", + share->vidmem_start,share->vidmem_size); + + /* reserve the vidmem space of smi adaptor */ +#if 0 + if((ret = pci_request_region(pdev,0,_moduleName_))) + { + pr_err("Can not request PCI regions.\n"); + goto exit; + } +#endif + + share->pvMem = ioremap(share->vidmem_start, + share->vidmem_size); + + if(!share->pvMem){ + pr_err("Map video memory failed\n"); + ret = -EFAULT; + goto exit; + }else{ + pr_info("video memory vaddr = %p\n",share->pvMem); + } +exit: + return ret; +} + + + +int hw_sm750_inithw(struct lynx_share* share,struct pci_dev * pdev) +{ + struct sm750_share * spec_share; + struct init_status * parm; + + spec_share = container_of(share,struct sm750_share,share); + parm = &spec_share->state.initParm; + if(parm->chip_clk == 0) + parm->chip_clk = (getChipType() == SM750LE)? + DEFAULT_SM750LE_CHIP_CLOCK : + DEFAULT_SM750_CHIP_CLOCK; + + if(parm->mem_clk == 0) + parm->mem_clk = parm->chip_clk; + if(parm->master_clk == 0) + parm->master_clk = parm->chip_clk/3; + + ddk750_initHw((initchip_param_t *)&spec_share->state.initParm); + /* for sm718,open pci burst */ + if(share->devid == 0x718){ + POKE32(SYSTEM_CTRL, + FIELD_SET(PEEK32(SYSTEM_CTRL),SYSTEM_CTRL,PCI_BURST,ON)); + } + + /* sm750 use sii164, it can be setup with default value + * by on power, so initDVIDisp can be skipped */ +#if 0 + ddk750_initDVIDisp(); +#endif + + if(getChipType() != SM750LE) + { + /* does user need CRT ?*/ + if(spec_share->state.nocrt){ + POKE32(MISC_CTRL, + FIELD_SET(PEEK32(MISC_CTRL), + MISC_CTRL, + DAC_POWER,OFF)); + /* shut off dpms */ + POKE32(SYSTEM_CTRL, + FIELD_SET(PEEK32(SYSTEM_CTRL), + SYSTEM_CTRL, + DPMS,VNHN)); + }else{ + POKE32(MISC_CTRL, + FIELD_SET(PEEK32(MISC_CTRL), + MISC_CTRL, + DAC_POWER,ON)); + /* turn on dpms */ + POKE32(SYSTEM_CTRL, + FIELD_SET(PEEK32(SYSTEM_CTRL), + SYSTEM_CTRL, + DPMS,VPHP)); + } + + switch (spec_share->state.pnltype){ + case sm750_doubleTFT: + case sm750_24TFT: + case sm750_dualTFT: + POKE32(PANEL_DISPLAY_CTRL, + FIELD_VALUE(PEEK32(PANEL_DISPLAY_CTRL), + PANEL_DISPLAY_CTRL, + TFT_DISP, + spec_share->state.pnltype)); + break; + } + }else{ + /* for 750LE ,no DVI chip initilization makes Monitor no signal */ + /* Set up GPIO for software I2C to program DVI chip in the + Xilinx SP605 board, in order to have video signal. + */ + swI2CInit(0,1); + + + /* Customer may NOT use CH7301 DVI chip, which has to be + initialized differently. + */ + if (swI2CReadReg(0xec, 0x4a) == 0x95) + { + /* The following register values for CH7301 are from + Chrontel app note and our experiment. + */ + pr_info("yes,CH7301 DVI chip found\n"); + swI2CWriteReg(0xec, 0x1d, 0x16); + swI2CWriteReg(0xec, 0x21, 0x9); + swI2CWriteReg(0xec, 0x49, 0xC0); + pr_info("okay,CH7301 DVI chip setup done\n"); + } + } + + /* init 2d engine */ + if(!share->accel_off){ + hw_sm750_initAccel(share); +// share->accel.de_wait = hw_sm750_deWait; + } + + return 0; +} + + +resource_size_t hw_sm750_getVMSize(struct lynx_share * share) +{ + resource_size_t ret; + + ret = ddk750_getVMSize(); + return ret; +} + + + +int hw_sm750_output_checkMode(struct lynxfb_output* output,struct fb_var_screeninfo* var) +{ + + return 0; +} + + +int hw_sm750_output_setMode(struct lynxfb_output* output, + struct fb_var_screeninfo* var,struct fb_fix_screeninfo* fix) +{ + int ret; + disp_output_t dispSet; + int channel; + + ret = 0; + dispSet = 0; + channel = *output->channel; + + + if(getChipType() != SM750LE){ + if(channel == sm750_primary){ + pr_info("primary channel\n"); + if(output->paths & sm750_panel) + dispSet |= do_LCD1_PRI; + if(output->paths & sm750_crt) + dispSet |= do_CRT_PRI; + + }else{ + pr_info("secondary channel\n"); + if(output->paths & sm750_panel) + dispSet |= do_LCD1_SEC; + if(output->paths & sm750_crt) + dispSet |= do_CRT_SEC; + + } + ddk750_setLogicalDispOut(dispSet); + }else{ + /* just open DISPLAY_CONTROL_750LE register bit 3:0*/ + u32 reg; + reg = PEEK32(DISPLAY_CONTROL_750LE); + reg |= 0xf; + POKE32(DISPLAY_CONTROL_750LE,reg); + } + + pr_info("ddk setlogicdispout done \n"); + return ret; +} + +void hw_sm750_output_clear(struct lynxfb_output* output) +{ + + return; +} + +int hw_sm750_crtc_checkMode(struct lynxfb_crtc* crtc,struct fb_var_screeninfo* var) +{ + struct lynx_share * share; + + + share = container_of(crtc,struct lynxfb_par,crtc)->share; + + switch (var->bits_per_pixel){ + case 8: + case 16: + break; + case 32: + if(share->revid == (unsigned char)SM750LE_REVISION_ID){ + pr_debug("750le do not support 32bpp\n"); + return -EINVAL; + } + break; + default: + return -EINVAL; + + } + + return 0; +} + + +/* + set the controller's mode for @crtc charged with @var and @fix parameters +*/ +int hw_sm750_crtc_setMode(struct lynxfb_crtc* crtc, + struct fb_var_screeninfo* var, + struct fb_fix_screeninfo* fix) +{ + int ret,fmt; + u32 reg; + mode_parameter_t modparm; + clock_type_t clock; + struct lynx_share * share; + struct lynxfb_par * par; + + + ret = 0; + par = container_of(crtc,struct lynxfb_par,crtc); + share = par->share; +#if 1 + if(!share->accel_off){ + /* set 2d engine pixel format according to mode bpp */ + switch(var->bits_per_pixel){ + case 8: + fmt = 0; + break; + case 16: + fmt = 1; + break; + case 32: + default: + fmt = 2; + break; + } + hw_set2dformat(&share->accel,fmt); + } +#endif + + /* set timing */ +// modparm.pixel_clock = PS_TO_HZ(var->pixclock); + modparm.pixel_clock = ps_to_hz(var->pixclock); + modparm.vertical_sync_polarity = (var->sync & FB_SYNC_HOR_HIGH_ACT) ? POS:NEG; + modparm.horizontal_sync_polarity = (var->sync & FB_SYNC_VERT_HIGH_ACT) ? POS:NEG; + modparm.clock_phase_polarity = (var->sync& FB_SYNC_COMP_HIGH_ACT) ? POS:NEG; + modparm.horizontal_display_end = var->xres; + modparm.horizontal_sync_width = var->hsync_len; + modparm.horizontal_sync_start = var->xres + var->right_margin; + modparm.horizontal_total = var->xres + var->left_margin + var->right_margin + var->hsync_len; + modparm.vertical_display_end = var->yres; + modparm.vertical_sync_height = var->vsync_len; + modparm.vertical_sync_start = var->yres + var->lower_margin; + modparm.vertical_total = var->yres + var->upper_margin + var->lower_margin + var->vsync_len; + + /* choose pll */ + if(crtc->channel != sm750_secondary) + clock = PRIMARY_PLL; + else + clock = SECONDARY_PLL; + + pr_debug("Request pixel clock = %lu\n",modparm.pixel_clock); + ret = ddk750_setModeTiming(&modparm,clock); + if(ret){ + pr_err("Set mode timing failed\n"); + goto exit; + } + + if(crtc->channel != sm750_secondary){ + /* set pitch, offset ,width,start address ,etc... */ + POKE32(PANEL_FB_ADDRESS, + FIELD_SET(0,PANEL_FB_ADDRESS,STATUS,CURRENT)| + FIELD_SET(0,PANEL_FB_ADDRESS,EXT,LOCAL)| + FIELD_VALUE(0,PANEL_FB_ADDRESS,ADDRESS,crtc->oScreen)); + + reg = var->xres * (var->bits_per_pixel >> 3); + /* crtc->channel is not equal to par->index on numeric,be aware of that */ + reg = PADDING(crtc->line_pad,reg); + + POKE32(PANEL_FB_WIDTH, + FIELD_VALUE(0,PANEL_FB_WIDTH,WIDTH,reg)| + FIELD_VALUE(0,PANEL_FB_WIDTH,OFFSET,fix->line_length)); + + POKE32(PANEL_WINDOW_WIDTH, + FIELD_VALUE(0,PANEL_WINDOW_WIDTH,WIDTH,var->xres -1)| + FIELD_VALUE(0,PANEL_WINDOW_WIDTH,X,var->xoffset)); + + POKE32(PANEL_WINDOW_HEIGHT, + FIELD_VALUE(0,PANEL_WINDOW_HEIGHT,HEIGHT,var->yres_virtual - 1)| + FIELD_VALUE(0,PANEL_WINDOW_HEIGHT,Y,var->yoffset)); + + POKE32(PANEL_PLANE_TL,0); + + POKE32(PANEL_PLANE_BR, + FIELD_VALUE(0,PANEL_PLANE_BR,BOTTOM,var->yres - 1)| + FIELD_VALUE(0,PANEL_PLANE_BR,RIGHT,var->xres - 1)); + + /* set pixel format */ + reg = PEEK32(PANEL_DISPLAY_CTRL); + POKE32(PANEL_DISPLAY_CTRL, + FIELD_VALUE(reg, + PANEL_DISPLAY_CTRL,FORMAT, + (var->bits_per_pixel >> 4) + )); + }else{ + /* not implemented now */ + POKE32(CRT_FB_ADDRESS,crtc->oScreen); + reg = var->xres * (var->bits_per_pixel >> 3); + /* crtc->channel is not equal to par->index on numeric,be aware of that */ + reg = PADDING(crtc->line_pad,reg); + + POKE32(CRT_FB_WIDTH, + FIELD_VALUE(0,CRT_FB_WIDTH,WIDTH,reg)| + FIELD_VALUE(0,CRT_FB_WIDTH,OFFSET,fix->line_length)); + + /* SET PIXEL FORMAT */ + reg = PEEK32(CRT_DISPLAY_CTRL); + reg = FIELD_VALUE(reg,CRT_DISPLAY_CTRL,FORMAT,var->bits_per_pixel >> 4); + POKE32(CRT_DISPLAY_CTRL,reg); + + } + + +exit: + return ret; +} + +void hw_sm750_crtc_clear(struct lynxfb_crtc* crtc) +{ + + return; +} + +int hw_sm750_setColReg(struct lynxfb_crtc* crtc,ushort index, + ushort red,ushort green,ushort blue) +{ + static unsigned int add[]={PANEL_PALETTE_RAM,CRT_PALETTE_RAM}; + POKE32(add[crtc->channel] + index*4 ,(red<<16)|(green<<8)|blue); + return 0; +} + +int hw_sm750le_setBLANK(struct lynxfb_output * output,int blank){ + int dpms,crtdb; + + switch(blank) + { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10) + case FB_BLANK_UNBLANK: +#else + case VESA_NO_BLANKING: +#endif + dpms = CRT_DISPLAY_CTRL_DPMS_0; + crtdb = CRT_DISPLAY_CTRL_BLANK_OFF; + break; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10) + case FB_BLANK_NORMAL: + dpms = CRT_DISPLAY_CTRL_DPMS_0; + crtdb = CRT_DISPLAY_CTRL_BLANK_ON; + break; +#endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10) + case FB_BLANK_VSYNC_SUSPEND: +#else + case VESA_VSYNC_SUSPEND: +#endif + dpms = CRT_DISPLAY_CTRL_DPMS_2; + crtdb = CRT_DISPLAY_CTRL_BLANK_ON; + break; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10) + case FB_BLANK_HSYNC_SUSPEND: +#else + case VESA_HSYNC_SUSPEND: +#endif + dpms = CRT_DISPLAY_CTRL_DPMS_1; + crtdb = CRT_DISPLAY_CTRL_BLANK_ON; + break; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10) + case FB_BLANK_POWERDOWN: +#else + case VESA_POWERDOWN: +#endif + dpms = CRT_DISPLAY_CTRL_DPMS_3; + crtdb = CRT_DISPLAY_CTRL_BLANK_ON; + break; + } + + if(output->paths & sm750_crt){ + POKE32(CRT_DISPLAY_CTRL,FIELD_VALUE(PEEK32(CRT_DISPLAY_CTRL),CRT_DISPLAY_CTRL,DPMS,dpms)); + POKE32(CRT_DISPLAY_CTRL,FIELD_VALUE(PEEK32(CRT_DISPLAY_CTRL),CRT_DISPLAY_CTRL,BLANK,crtdb)); + } + return 0; +} + +int hw_sm750_setBLANK(struct lynxfb_output* output,int blank) +{ + unsigned int dpms,pps,crtdb; + + dpms = pps = crtdb = 0; + + switch (blank) + { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10) + case FB_BLANK_UNBLANK: +#else + case VESA_NO_BLANKING: +#endif + pr_info("flag = FB_BLANK_UNBLANK \n"); + dpms = SYSTEM_CTRL_DPMS_VPHP; + pps = PANEL_DISPLAY_CTRL_DATA_ENABLE; + crtdb = CRT_DISPLAY_CTRL_BLANK_OFF; + break; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10) + case FB_BLANK_NORMAL: + pr_info("flag = FB_BLANK_NORMAL \n"); + dpms = SYSTEM_CTRL_DPMS_VPHP; + pps = PANEL_DISPLAY_CTRL_DATA_DISABLE; + crtdb = CRT_DISPLAY_CTRL_BLANK_ON; + break; +#endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10) + case FB_BLANK_VSYNC_SUSPEND: +#else + case VESA_VSYNC_SUSPEND: +#endif + dpms = SYSTEM_CTRL_DPMS_VNHP; + pps = PANEL_DISPLAY_CTRL_DATA_DISABLE; + crtdb = CRT_DISPLAY_CTRL_BLANK_ON; + break; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10) + case FB_BLANK_HSYNC_SUSPEND: +#else + case VESA_HSYNC_SUSPEND: +#endif + dpms = SYSTEM_CTRL_DPMS_VPHN; + pps = PANEL_DISPLAY_CTRL_DATA_DISABLE; + crtdb = CRT_DISPLAY_CTRL_BLANK_ON; + break; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10) + case FB_BLANK_POWERDOWN: +#else + case VESA_POWERDOWN: +#endif + dpms = SYSTEM_CTRL_DPMS_VNHN; + pps = PANEL_DISPLAY_CTRL_DATA_DISABLE; + crtdb = CRT_DISPLAY_CTRL_BLANK_ON; + break; + } + + if(output->paths & sm750_crt){ + + POKE32(SYSTEM_CTRL,FIELD_VALUE(PEEK32(SYSTEM_CTRL),SYSTEM_CTRL,DPMS,dpms)); + POKE32(CRT_DISPLAY_CTRL,FIELD_VALUE(PEEK32(CRT_DISPLAY_CTRL),CRT_DISPLAY_CTRL,BLANK,crtdb)); + } + + if(output->paths & sm750_panel){ + POKE32(PANEL_DISPLAY_CTRL,FIELD_VALUE(PEEK32(PANEL_DISPLAY_CTRL),PANEL_DISPLAY_CTRL,DATA,pps)); + } + + return 0; +} + + +void hw_sm750_initAccel(struct lynx_share * share) +{ + u32 reg; + enable2DEngine(1); + + if(getChipType() == SM750LE){ + reg = PEEK32(DE_STATE1); + reg = FIELD_SET(reg,DE_STATE1,DE_ABORT,ON); + POKE32(DE_STATE1,reg); + + reg = PEEK32(DE_STATE1); + reg = FIELD_SET(reg,DE_STATE1,DE_ABORT,OFF); + POKE32(DE_STATE1,reg); + + }else{ + /* engine reset */ + reg = PEEK32(SYSTEM_CTRL); + reg = FIELD_SET(reg,SYSTEM_CTRL,DE_ABORT,ON); + POKE32(SYSTEM_CTRL,reg); + + reg = PEEK32(SYSTEM_CTRL); + reg = FIELD_SET(reg,SYSTEM_CTRL,DE_ABORT,OFF); + POKE32(SYSTEM_CTRL,reg); + } + + /* call 2d init */ + share->accel.de_init(&share->accel); +} + +int hw_sm750le_deWait() +{ + int i=0x10000000; + while(i--){ + unsigned int dwVal = PEEK32(DE_STATE2); + if((FIELD_GET(dwVal,DE_STATE2,DE_STATUS) == DE_STATE2_DE_STATUS_IDLE) && + (FIELD_GET(dwVal,DE_STATE2,DE_FIFO) == DE_STATE2_DE_FIFO_EMPTY) && + (FIELD_GET(dwVal,DE_STATE2,DE_MEM_FIFO) == DE_STATE2_DE_MEM_FIFO_EMPTY)) + { + return 0; + } + } + /* timeout error */ + return -1; +} + + +int hw_sm750_deWait() +{ + int i=0x10000000; + while(i--){ + unsigned int dwVal = PEEK32(SYSTEM_CTRL); + if((FIELD_GET(dwVal,SYSTEM_CTRL,DE_STATUS) == SYSTEM_CTRL_DE_STATUS_IDLE) && + (FIELD_GET(dwVal,SYSTEM_CTRL,DE_FIFO) == SYSTEM_CTRL_DE_FIFO_EMPTY) && + (FIELD_GET(dwVal,SYSTEM_CTRL,DE_MEM_FIFO) == SYSTEM_CTRL_DE_MEM_FIFO_EMPTY)) + { + return 0; + } + } + /* timeout error */ + return -1; +} + +int hw_sm750_pan_display(struct lynxfb_crtc *crtc, + const struct fb_var_screeninfo *var, + const struct fb_info *info) +{ + uint32_t total; + //check params + if ((var->xoffset + var->xres > var->xres_virtual) || + (var->yoffset + var->yres > var->yres_virtual)) { + return -EINVAL; + } + + total = var->yoffset * info->fix.line_length + + ((var->xoffset * var->bits_per_pixel) >> 3); + total += crtc->oScreen; + if (crtc->channel == sm750_primary) { + POKE32(PANEL_FB_ADDRESS, + FIELD_VALUE(PEEK32(PANEL_FB_ADDRESS), + PANEL_FB_ADDRESS, ADDRESS, total)); + } else { + POKE32(CRT_FB_ADDRESS, + FIELD_VALUE(PEEK32(CRT_FB_ADDRESS), + CRT_FB_ADDRESS, ADDRESS, total)); + } + return 0; +} + diff --git a/drivers/staging/sm750fb/sm750_hw.h b/drivers/staging/sm750fb/sm750_hw.h new file mode 100644 index 000000000000..b05be5e99f51 --- /dev/null +++ b/drivers/staging/sm750fb/sm750_hw.h @@ -0,0 +1,104 @@ +#ifndef LYNX_HW750_H__ +#define LYNX_HW750_H__ + + +#define DEFAULT_SM750_CHIP_CLOCK 290 +#define DEFAULT_SM750LE_CHIP_CLOCK 333 +#ifndef SM750LE_REVISION_ID +#define SM750LE_REVISION_ID (unsigned char)0xfe +#endif + +//#define DEFAULT_MEM_CLOCK (DEFAULT_SM750_CHIP_CLOCK/1) +//#define DEFAULT_MASTER_CLOCK (DEFAULT_SM750_CHIP_CLOCK/3) + + +enum sm750_pnltype{ + + sm750_24TFT = 0,/* 24bit tft */ + + sm750_dualTFT = 2,/* dual 18 bit tft */ + + sm750_doubleTFT = 1,/* 36 bit double pixel tft */ +}; + +/* vga channel is not concerned */ +enum sm750_dataflow{ + sm750_simul_pri,/* primary => all head */ + + sm750_simul_sec,/* secondary => all head */ + + sm750_dual_normal,/* primary => panel head and secondary => crt */ + + sm750_dual_swap,/* primary => crt head and secondary => panel */ +}; + + +enum sm750_channel{ + sm750_primary = 0, + /* enum value equal to the register filed data */ + sm750_secondary = 1, +}; + +enum sm750_path{ + sm750_panel = 1, + sm750_crt = 2, + sm750_pnc = 3,/* panel and crt */ +}; + +struct init_status{ + ushort powerMode; + /* below three clocks are in unit of MHZ*/ + ushort chip_clk; + ushort mem_clk; + ushort master_clk; + ushort setAllEngOff; + ushort resetMemory; +}; + +struct sm750_state{ + struct init_status initParm; + enum sm750_pnltype pnltype; + enum sm750_dataflow dataflow; + int nocrt; + int xLCD; + int yLCD; +}; + +/* sm750_share stands for a presentation of two frame buffer + that use one sm750 adaptor, it is similiar to the super class of lynx_share + in C++ +*/ + +struct sm750_share{ + /* it's better to put lynx_share struct to the first place of sm750_share */ + struct lynx_share share; + struct sm750_state state; + int hwCursor; + /* 0: no hardware cursor + 1: primary crtc hw cursor enabled, + 2: secondary crtc hw cursor enabled + 3: both ctrc hw cursor enabled + */ +}; + +int hw_sm750_map(struct lynx_share* share,struct pci_dev* pdev); +int hw_sm750_inithw(struct lynx_share*,struct pci_dev *); +void hw_sm750_initAccel(struct lynx_share *); +int hw_sm750_deWait(void); +int hw_sm750le_deWait(void); + +resource_size_t hw_sm750_getVMSize(struct lynx_share *); +int hw_sm750_output_checkMode(struct lynxfb_output*,struct fb_var_screeninfo*); +int hw_sm750_output_setMode(struct lynxfb_output*,struct fb_var_screeninfo*,struct fb_fix_screeninfo*); +int hw_sm750_crtc_checkMode(struct lynxfb_crtc*,struct fb_var_screeninfo*); +int hw_sm750_crtc_setMode(struct lynxfb_crtc*,struct fb_var_screeninfo*,struct fb_fix_screeninfo*); +int hw_sm750_setColReg(struct lynxfb_crtc*,ushort,ushort,ushort,ushort); +int hw_sm750_setBLANK(struct lynxfb_output*,int); +int hw_sm750le_setBLANK(struct lynxfb_output*,int); +void hw_sm750_crtc_clear(struct lynxfb_crtc*); +void hw_sm750_output_clear(struct lynxfb_output*); +int hw_sm750_pan_display(struct lynxfb_crtc *crtc, + const struct fb_var_screeninfo *var, + const struct fb_info *info); + +#endif -- GitLab From 980ac4d7db69a3d9970f8eb545f90057afb6785e Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Tue, 3 Mar 2015 16:21:07 +0530 Subject: [PATCH 03184/11651] MAINTAINERS: update for sm750fb driver add myself and Teddy Wang as the Maintainer of the sm750 frame buffer driver. Signed-off-by: Sudip Mukherjee Signed-off-by: Greg Kroah-Hartman --- MAINTAINERS | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index ddc5a8cf9a8a..b20311947d97 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9340,6 +9340,14 @@ L: linux-fbdev@vger.kernel.org S: Maintained F: drivers/staging/sm7xxfb/ +STAGING - SILICON MOTION SM750 FRAME BUFFER DRIVER +M: Sudip Mukherjee +M: Teddy Wang +M: Sudip Mukherjee +L: linux-fbdev@vger.kernel.org +S: Maintained +F: drivers/staging/sm750fb/ + STAGING - SLICOSS M: Lior Dotan M: Christopher Harrer -- GitLab From d9fabbde633e2d567a2c0f9e29e4e4d2f9bf5196 Mon Sep 17 00:00:00 2001 From: Drew Fustini Date: Wed, 4 Mar 2015 02:10:11 -0600 Subject: [PATCH 03185/11651] Staging: fbtft: add header for internal functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove extern keyword from function prototypes to suppress warning from checkpatch.pl with --strict option: https://lkml.org/lkml/2013/7/23/422 fbtft maintainer Noralf Tronnes advised these functions are internal to this module & suggested moving these prototypes to new internal.h file. He also advised fbtft.h file will eventually live in include/linux/fbtft.h Suggested-by: Noralf Trønnes Signed-off-by: Drew Fustini Signed-off-by: Greg Kroah-Hartman --- drivers/staging/fbtft/fbtft-core.c | 7 +------ drivers/staging/fbtft/internal.h | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 6 deletions(-) create mode 100644 drivers/staging/fbtft/internal.h diff --git a/drivers/staging/fbtft/fbtft-core.c b/drivers/staging/fbtft/fbtft-core.c index fd9f92e2dba6..16c726030f37 100644 --- a/drivers/staging/fbtft/fbtft-core.c +++ b/drivers/staging/fbtft/fbtft-core.c @@ -41,12 +41,7 @@ #include #include "fbtft.h" - -extern void fbtft_sysfs_init(struct fbtft_par *par); -extern void fbtft_sysfs_exit(struct fbtft_par *par); -extern void fbtft_expand_debug_value(unsigned long *debug); -extern int fbtft_gamma_parse_str(struct fbtft_par *par, unsigned long *curves, - const char *str, int size); +#include "internal.h" static unsigned long debug; module_param(debug, ulong, 0); diff --git a/drivers/staging/fbtft/internal.h b/drivers/staging/fbtft/internal.h new file mode 100644 index 000000000000..f69db8289151 --- /dev/null +++ b/drivers/staging/fbtft/internal.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2013 Noralf Tronnes + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 __LINUX_FBTFT__INTERNAL_H +#define __LINUX_FBTFT_INTERNAL_H + +void fbtft_sysfs_init(struct fbtft_par *par); +void fbtft_sysfs_exit(struct fbtft_par *par); +void fbtft_expand_debug_value(unsigned long *debug); +int fbtft_gamma_parse_str(struct fbtft_par *par, unsigned long *curves, + const char *str, int size); + +#endif /* __LINUX_FBTFT_INTERNAL_H */ -- GitLab From 4de57acbb6fddea4159dfcb62440b1e1309e3d9e Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Wed, 4 Mar 2015 12:14:21 -0500 Subject: [PATCH 03186/11651] staging: unisys: remove DBGINF, DBGVER, DEBUGDEV, and DEBUGDRV macros The messages put out by these macros are for driver debugging and aren't needed any more, so just remove all use of them, and the macros too. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/timskmod.h | 2 - drivers/staging/unisys/include/uniklog.h | 39 ------------ drivers/staging/unisys/uislib/uislib.c | 5 -- drivers/staging/unisys/uislib/uisutils.c | 1 - drivers/staging/unisys/virthba/virthba.c | 69 +++------------------- drivers/staging/unisys/virtpci/virtpci.c | 28 --------- drivers/staging/unisys/visorchipset/file.c | 10 ---- 7 files changed, 9 insertions(+), 145 deletions(-) diff --git a/drivers/staging/unisys/include/timskmod.h b/drivers/staging/unisys/include/timskmod.h index 4019a0d63645..eef29e73099b 100644 --- a/drivers/staging/unisys/include/timskmod.h +++ b/drivers/staging/unisys/include/timskmod.h @@ -94,7 +94,6 @@ #define WARNDRV(fmt, args...) LOGWRN(fmt, ## args) #define SECUREDRV(fmt, args...) LOGWRN(fmt, ## args) #define INFODRV(fmt, args...) LOGINF(fmt, ## args) -#define DEBUGDRV(fmt, args...) DBGINF(fmt, ## args) #define PRINTKDEV(devname, fmt, args...) LOGINFDEV(devname, fmt, ## args) #define TBDDEV(devname, fmt, args...) LOGERRDEV(devname, fmt, ## args) @@ -105,7 +104,6 @@ #define SECUREDEV(devname, fmt, args...) LOGWRNDEV(devname, fmt, ## args) #define INFODEV(devname, fmt, args...) LOGINFDEV(devname, fmt, ## args) #define INFODEVX(devno, fmt, args...) LOGINFDEVX(devno, fmt, ## args) -#define DEBUGDEV(devname, fmt, args...) DBGINFDEV(devname, fmt, ## args) /** Verifies the consistency of your PRIVATEDEVICEDATA structure using * conventional "signature" fields: diff --git a/drivers/staging/unisys/include/uniklog.h b/drivers/staging/unisys/include/uniklog.h index ecd1bdb6d097..10171a185871 100644 --- a/drivers/staging/unisys/include/uniklog.h +++ b/drivers/staging/unisys/include/uniklog.h @@ -25,45 +25,6 @@ #include -/* - * # DBGINF - * - * \brief Log debug informational message - log a LOG_INFO message only - * if DEBUG compiletime option enabled - * - * \param devname the device name of the device reporting this message, or - * NULL if this message is NOT device-related. - * \param fmt printf()-style format string containing the message to log. - * \param args Optional arguments to be formatted and inserted into the - * format string. - * \return nothing - * - * Log a message at the LOG_INFO level, but only if DEBUG is enabled. If - * DEBUG is disabled, this expands to a no-op. - */ - -/* - * # DBGVER - * - * \brief Log debug verbose message - log a LOG_DEBUG message only if - * DEBUG compiletime option enabled - * - * \param devname the device name of the device reporting this message, or - * NULL if this message is NOT device-related. - * \param fmt printf()-style format string containing the message to log. - * \param args Optional arguments to be formatted and inserted into the - * format string. - * \return nothing - * - * Log a message at the LOG_DEBUG level, but only if DEBUG is enabled. If - * DEBUG is disabled, this expands to a no-op. Note also that LOG_DEBUG - * messages can be enabled/disabled at runtime as well. - */ -#define DBGINFDEV(devname, fmt, args...) do { } while (0) -#define DBGVERDEV(devname, fmt, args...) do { } while (0) -#define DBGINF(fmt, args...) do { } while (0) -#define DBGVER(fmt, args...) do { } while (0) - /* * # LOGINF * diff --git a/drivers/staging/unisys/uislib/uislib.c b/drivers/staging/unisys/uislib/uislib.c index 6d2432bed267..4fdddc301157 100644 --- a/drivers/staging/unisys/uislib/uislib.c +++ b/drivers/staging/unisys/uislib/uislib.c @@ -1161,7 +1161,6 @@ static ssize_t info_debugfs_read(struct file *file, char __user *buf, /* *start = buf; */ if (debug_buf == NULL) { - DBGINF("debug_buf == NULL; allocating buffer.\n."); debug_buf = vmalloc(PROC_READ_BUFFER_SIZE); if (debug_buf == NULL) { @@ -1173,7 +1172,6 @@ static ssize_t info_debugfs_read(struct file *file, char __user *buf, temp = debug_buf; if ((*offset == 0) || (!debug_buf_valid)) { - DBGINF("calling info_debugfs_read_helper.\n"); /* if the read fails, then -1 will be returned */ total_bytes = info_debugfs_read_helper(&temp, &remaining_bytes); debug_buf_valid = 1; @@ -1333,7 +1331,6 @@ static int process_incoming(void *v) idle_cycles = idle_cycles + delta_cycles; } } - DBGINF("exiting.\n"); complete_and_exit(&incoming_ti.has_stopped, 0); } @@ -1512,8 +1509,6 @@ uislib_mod_exit(void) debugfs_remove(cycles_before_wait_debugfs_read); debugfs_remove(platformnumber_debugfs_read); debugfs_remove(dir_debugfs); - - DBGINF("goodbye.\n"); } module_init(uislib_mod_init); diff --git a/drivers/staging/unisys/uislib/uisutils.c b/drivers/staging/unisys/uislib/uisutils.c index 1ba6c15bcbe0..2fbada3471a6 100644 --- a/drivers/staging/unisys/uislib/uisutils.c +++ b/drivers/staging/unisys/uislib/uisutils.c @@ -53,7 +53,6 @@ uisutil_add_proc_line_ex(int *total, char **buffer, int *buffer_remaining, va_list args; int len; - DBGINF("buffer = 0x%p : *buffer = 0x%p.\n", buffer, *buffer); va_start(args, format); len = vsnprintf(*buffer, *buffer_remaining, format, args); va_end(args); diff --git a/drivers/staging/unisys/virthba/virthba.c b/drivers/staging/unisys/virthba/virthba.c index 2ad0c1939623..a19dac12b9c0 100644 --- a/drivers/staging/unisys/virthba/virthba.c +++ b/drivers/staging/unisys/virthba/virthba.c @@ -26,8 +26,6 @@ * which start with an 8 digit sequence number, a colon, and then * letters after that */ -#undef DBGINF - #include #ifdef CONFIG_MODVERSIONS #include @@ -482,7 +480,6 @@ virthba_probe(struct virtpci_dev *virtpcidev, const struct pci_device_id *id) * initialization. The host is not published to the scsi * midlayer until scsi_add_host is called. */ - DBGINF("calling scsi_host_alloc.\n"); /* arg 2 passed in length of extra space we want allocated * with scsi_host struct for our own use scsi_host_alloc @@ -493,9 +490,6 @@ virthba_probe(struct virtpci_dev *virtpcidev, const struct pci_device_id *id) if (scsihost == NULL) return -ENODEV; - DBGINF("scsihost: 0x%p, scsihost->this_id: %d, host_no: %d.\n", - scsihost, scsihost->this_id, scsihost->host_no); - scsihost->this_id = UIS_MAGIC_VHBA; /* linux treats max-channel differently than max-id & max-lun. * In the latter cases, those two values result in 0 to max-1 @@ -527,8 +521,6 @@ virthba_probe(struct virtpci_dev *virtpcidev, const struct pci_device_id *id) scsihost->can_queue, scsihost->cmd_per_lun, scsihost->max_sectors, scsihost->sg_tablesize); - DBGINF("calling scsi_add_host\n"); - /* this creates "host%d" in sysfs. If 2nd argument is NULL, * then this generic /sys/devices/platform/host? device is * created and /sys/scsi_host/host? -> @@ -560,9 +552,6 @@ virthba_probe(struct virtpci_dev *virtpcidev, const struct pci_device_id *id) virthbainfo->virtpcidev = virtpcidev; spin_lock_init(&virthbainfo->chinfo.insertlock); - DBGINF("generic_dev: 0x%p, queueinfo: 0x%p.\n", - &virtpcidev->generic_dev, &virtpcidev->queueinfo); - init_waitqueue_head(&virthbainfo->rsp_queue); spin_lock_init(&virthbainfo->privlock); memset(&virthbainfo->pending, 0, sizeof(virthbainfo->pending)); @@ -584,8 +573,6 @@ virthba_probe(struct virtpci_dev *virtpcidev, const struct pci_device_id *id) ULTRA_IO_CHANNEL_IS_POLLING, &virthbainfo->chinfo.queueinfo->chan->features); /* start thread that will receive scsicmnd responses */ - DBGINF("starting rsp thread -- queueinfo: 0x%p, threadinfo: 0x%p.\n", - virthbainfo->chinfo.queueinfo, &virthbainfo->chinfo.threadinfo); channel_header = virthbainfo->chinfo.queueinfo->chan; pqhdr = (struct signal_queue_header __iomem *) @@ -635,9 +622,7 @@ virthba_probe(struct virtpci_dev *virtpcidev, const struct pci_device_id *id) rsltq_wait_usecs = 4000000; } - DBGINF("calling scsi_scan_host.\n"); scsi_scan_host(scsihost); - DBGINF("return from scsi_scan_host.\n"); LOGINF("virthba added scsihost:0x%p\n", scsihost); POSTCODE_LINUX_2(VHBA_PROBE_EXIT_PC, POSTCODE_SEVERITY_INFO); @@ -659,15 +644,10 @@ virthba_remove(struct virtpci_dev *virtpcidev) LOGINF("Removing virtpcidev: 0x%p, virthbainfo: 0x%p\n", virtpcidev, virthbainfo); - DBGINF("removing scsihost: 0x%p, scsihost->this_id: %d\n", scsihost, - scsihost->this_id); scsi_remove_host(scsihost); - DBGINF("stopping thread.\n"); uisthread_stop(&virthbainfo->chinfo.threadinfo); - DBGINF("calling scsi_host_put\n"); - /* decr refcount on scsihost which was incremented by * scsi_add_host so the scsi_host gets deleted */ @@ -689,10 +669,8 @@ forward_vdiskmgmt_command(enum vdisk_mgmt_types vdiskcmdtype, LOGINF("vDiskMgmt:%d %d:%d:%d\n", vdiskcmdtype, vdest->channel, vdest->id, vdest->lun); - if (virthbainfo->serverdown || virthbainfo->serverchangingstate) { - DBGINF("Server is down/changing state. Returning Failure.\n"); + if (virthbainfo->serverdown || virthbainfo->serverchangingstate) return FAILED; - } cmdrsp = kzalloc(SIZEOF_CMDRSP, GFP_ATOMIC); if (cmdrsp == NULL) @@ -750,10 +728,8 @@ forward_taskmgmt_command(enum task_mgmt_types tasktype, LOGINF("TaskMgmt:%d %d:%d:%llu\n", tasktype, scsidev->channel, scsidev->id, scsidev->lun); - if (virthbainfo->serverdown || virthbainfo->serverchangingstate) { - DBGINF("Server is down/changing state. Returning Failure.\n"); + if (virthbainfo->serverdown || virthbainfo->serverchangingstate) return FAILED; - } cmdrsp = kzalloc(SIZEOF_CMDRSP, GFP_ATOMIC); if (cmdrsp == NULL) @@ -895,7 +871,6 @@ virthba_get_info(struct Scsi_Host *shp) static int virthba_ioctl(struct scsi_device *dev, int cmd, void __user *arg) { - DBGINF("In virthba_ioctl: ioctl: cmd=0x%x\n", cmd); return -EINVAL; } @@ -919,11 +894,8 @@ virthba_queue_command_lck(struct scsi_cmnd *scsicmd, struct scatterlist *sgl = NULL; int sg_failed = 0; - if (virthbainfo->serverdown || virthbainfo->serverchangingstate) { - DBGINF("Server is down/changing state. Returning SCSI_MLQUEUE_DEVICE_BUSY.\n"); + if (virthbainfo->serverdown || virthbainfo->serverchangingstate) return SCSI_MLQUEUE_DEVICE_BUSY; - } - cmdrsp = kzalloc(SIZEOF_CMDRSP, GFP_ATOMIC); if (cmdrsp == NULL) return 1; /* reject the command */ @@ -979,8 +951,6 @@ virthba_queue_command_lck(struct scsi_cmnd *scsicmd, LOGERR("**** FAILED No scatter list for bufflen > 0\n"); BUG_ON(scsi_sg_count(scsicmd) == 0); } - DBGINF("No sg; buffer:0x%p bufflen:%d\n", - scsi_sglist(scsicmd), scsi_bufflen(scsicmd)); } else { /* buffer is scatterlist - copy it out */ sgl = scsi_sglist(scsicmd); @@ -1191,8 +1161,6 @@ do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd) sg = scsi_sglist(scsicmd); for (i = 0; i < scsi_sg_count(scsicmd); i++) { - DBGVER("copying OUT OF buf into 0x%p %d\n", - sg_page(sg + i), sg[i].length); thispage_orig = kmap_atomic(sg_page(sg + i)); thispage = (void *)((unsigned long)thispage_orig | sg[i].offset); @@ -1222,8 +1190,6 @@ do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd) static void complete_scsi_command(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd) { - DBGINF("cmdrsp: 0x%p, scsistat:0x%x.\n", cmdrsp, cmdrsp->scsi.scsistat); - /* take what we need out of cmdrsp and complete the scsicmd */ scsicmd->result = cmdrsp->scsi.linuxstat; if (cmdrsp->scsi.linuxstat) @@ -1231,10 +1197,8 @@ complete_scsi_command(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd) else do_scsi_nolinuxstat(cmdrsp, scsicmd); - if (scsicmd->scsi_done) { - DBGVER("Scsi_DONE\n"); + if (scsicmd->scsi_done) scsicmd->scsi_done(scsicmd); - } } static inline void @@ -1352,7 +1316,6 @@ process_incoming_rsps(void *v) kfree(cmdrsp); - DBGINF("exiting processing incoming rsps.\n"); complete_and_exit(&dc->threadinfo.has_stopped, 0); } @@ -1475,13 +1438,9 @@ virthba_serverup(struct virtpci_dev *virtpcidev) (struct virthba_info *)((struct Scsi_Host *)virtpcidev->scsi. scsihost)->hostdata; - DBGINF("virtpcidev bus_no<<%d>>devNo<<%d>>", virtpcidev->bus_no, - virtpcidev->device_no); - - if (!virthbainfo->serverdown) { - DBGINF("Server up message received while server is already up.\n"); + if (!virthbainfo->serverdown) return 1; - } + if (virthbainfo->serverchangingstate) { LOGERR("Server already processing change state message\n"); return 0; @@ -1540,12 +1499,10 @@ virthba_serverdown_complete(struct work_struct *work) break; case CMD_SCSITASKMGMT_TYPE: cmdrsp = (struct uiscmdrsp *)pendingdel->sent; - DBGINF("cmdrsp=0x%x, notify=0x%x\n", cmdrsp, - cmdrsp->scsitaskmgmt.notify); - *(int *)cmdrsp->scsitaskmgmt.notifyresult = - TASK_MGMT_FAILED; wake_up_all((wait_queue_head_t *) cmdrsp->scsitaskmgmt.notify); + *(int *)cmdrsp->scsitaskmgmt.notifyresult = + TASK_MGMT_FAILED; break; case CMD_VDISKMGMT_TYPE: cmdrsp = (struct uiscmdrsp *)pendingdel->sent; @@ -1566,8 +1523,6 @@ virthba_serverdown_complete(struct work_struct *work) virtpcidev = virthbainfo->virtpcidev; - DBGINF("virtpcidev bus_no<<%d>>devNo<<%d>>", virtpcidev->bus_no, - virtpcidev->device_no); virthbainfo->serverdown = true; virthbainfo->serverchangingstate = false; /* Return the ServerDown response to Command */ @@ -1585,10 +1540,6 @@ virthba_serverdown(struct virtpci_dev *virtpcidev, u32 state) (struct virthba_info *)((struct Scsi_Host *)virtpcidev->scsi. scsihost)->hostdata; - DBGINF("virthba_serverdown"); - DBGINF("virtpcidev bus_no<<%d>>devNo<<%d>>", virtpcidev->bus_no, - virtpcidev->device_no); - if (!virthbainfo->serverdown && !virthbainfo->serverchangingstate) { virthbainfo->serverchangingstate = true; queue_work(virthba_serverdown_workqueue, @@ -1610,7 +1561,6 @@ virthba_serverdown(struct virtpci_dev *virtpcidev, u32 state) static int __init virthba_parse_line(char *str) { - DBGINF("In virthba_parse_line %s\n", str); return 1; } @@ -1626,8 +1576,7 @@ virthba_parse_options(char *line) next = strchr(line, ' '); if (next != NULL) *next++ = 0; - if (!virthba_parse_line(line)) - DBGINF("Unknown option '%s'\n", line); + virthba_parse_line(line); } POSTCODE_LINUX_2(VHBA_CREATE_EXIT_PC, POSTCODE_SEVERITY_INFO); diff --git a/drivers/staging/unisys/virtpci/virtpci.c b/drivers/staging/unisys/virtpci/virtpci.c index edaf43f5a77d..a20af632c38a 100644 --- a/drivers/staging/unisys/virtpci/virtpci.c +++ b/drivers/staging/unisys/virtpci/virtpci.c @@ -708,9 +708,6 @@ virtpci_match_device(const struct pci_device_id *ids, const struct virtpci_dev *dev) { while (ids->vendor || ids->subvendor || ids->class_mask) { - DBGINF("ids->vendor:%x dev->vendor:%x ids->device:%x dev->device:%x\n", - ids->vendor, dev->vendor, ids->device, dev->device); - if ((ids->vendor == dev->vendor) && (ids->device == dev->device)) return ids; @@ -731,20 +728,15 @@ static int virtpci_bus_match(struct device *dev, struct device_driver *drv) struct virtpci_driver *virtpcidrv = driver_to_virtpci_driver(drv); int match = 0; - DBGINF("In virtpci_bus_match dev->bus_id:%s drv->name:%s\n", - dev->bus_id, drv->name); - /* check ids list for a match */ if (virtpci_match_device(virtpcidrv->id_table, virtpcidev)) match = 1; - DBGINF("returning match:%d\n", match); return match; /* 0 - no match; 1 - yes it matches */ } static int virtpci_uevent(struct device *dev, struct kobj_uevent_env *env) { - DBGINF("In virtpci_hotplug\n"); /* add variables to the environment prior to the generation of * hotplug events to user space */ @@ -876,10 +868,7 @@ static int virtpci_device_remove(struct device *dev_) virtpcidev->mydriver = NULL; } - DBGINF("calling putdevice\n"); put_device(dev_); - - DBGINF("Leaving\n"); return 0; } @@ -889,11 +878,6 @@ static int virtpci_device_remove(struct device *dev_) static void virtpci_bus_release(struct device *dev) { - /* this function is called when the last reference to the - * device is removed - */ - DBGINF("In virtpci_bus_release\n"); - /* what else is supposed to happen here? */ } /*****************************************************/ @@ -1023,8 +1007,6 @@ static int virtpci_device_add(struct device *parentbus, int devtype, * list. Otherwise, a device_unregister from this function can * cause a "scheduling while atomic". */ - DBGINF("registering device:%p with bus_id:%s\n", - &virtpcidev->generic_dev, virtpcidev->generic_dev.bus_id); ret = device_register(&virtpcidev->generic_dev); /* NOTE: THIS IS CALLING HOTPLUG virtpci_hotplug!!! * This call to device_register results in virtpci_bus_match @@ -1323,8 +1305,6 @@ static ssize_t virtpci_driver_attr_show(struct kobject *kobj, struct driver_private *dprivate = to_driver(kobj); struct device_driver *driver = dprivate->driver; - DBGINF("In virtpci_driver_attr_show driver->name:%s\n", driver->name); - if (dattr->show) ret = dattr->show(driver, buf); @@ -1341,8 +1321,6 @@ static ssize_t virtpci_driver_attr_store(struct kobject *kobj, struct driver_private *dprivate = to_driver(kobj); struct device_driver *driver = dprivate->driver; - DBGINF("In virtpci_driver_attr_store driver->name:%s\n", driver->name); - if (dattr->store) ret = dattr->store(driver, buf, count); @@ -1354,8 +1332,6 @@ int virtpci_register_driver(struct virtpci_driver *drv) { int result = 0; - DBGINF("In virtpci_register_driver\n"); - if (drv->id_table == NULL) { LOGERR("id_table missing\n"); return 1; @@ -1388,7 +1364,6 @@ EXPORT_SYMBOL_GPL(virtpci_register_driver); void virtpci_unregister_driver(struct virtpci_driver *drv) { - DBGINF("In virtpci_unregister_driver drv:%p\n", drv); driver_unregister(&drv->core_driver); /* driver_unregister calls bus_remove_driver * bus_remove_driver calls device_detach @@ -1398,7 +1373,6 @@ void virtpci_unregister_driver(struct virtpci_driver *drv) * virtpci_device_remove * virtpci_device_remove calls virthba_remove */ - DBGINF("Leaving\n"); } EXPORT_SYMBOL_GPL(virtpci_unregister_driver); @@ -1511,7 +1485,6 @@ static int __init virtpci_mod_init(void) POSTCODE_SEVERITY_ERR); return ret; } - DBGINF("bus_register successful\n"); bus_device_info_init(&bus_driver_info, "clientbus", "virtpci", VERSION, NULL); @@ -1524,7 +1497,6 @@ static int __init virtpci_mod_init(void) POSTCODE_SEVERITY_ERR); return ret; } - DBGINF("device_register successful ret:%x\n", ret); if (!uisctrl_register_req_handler(2, (void *)&virtpci_ctrlchan_func, &chipset_driver_info)) { diff --git a/drivers/staging/unisys/visorchipset/file.c b/drivers/staging/unisys/visorchipset/file.c index b2b1b619c0b4..f580fb6f1ee0 100644 --- a/drivers/staging/unisys/visorchipset/file.c +++ b/drivers/staging/unisys/visorchipset/file.c @@ -106,7 +106,6 @@ visorchipset_open(struct inode *inode, struct file *file) { unsigned minor_number = iminor(inode); - DEBUGDRV("%s", __func__); if (minor_number != 0) return -ENODEV; file->private_data = NULL; @@ -116,7 +115,6 @@ visorchipset_open(struct inode *inode, struct file *file) static int visorchipset_release(struct inode *inode, struct file *file) { - DEBUGDRV("%s", __func__); return 0; } @@ -128,7 +126,6 @@ visorchipset_mmap(struct file *file, struct vm_area_struct *vma) GUEST_PHYSICAL_ADDRESS addr = 0; /* sv_enable_dfp(); */ - DEBUGDRV("%s", __func__); if (offset & (PAGE_SIZE - 1)) { ERRDRV("%s virtual address NOT page-aligned!", __func__); return -ENXIO; /* need aligned offsets */ @@ -149,7 +146,6 @@ visorchipset_mmap(struct file *file, struct vm_area_struct *vma) return -ENXIO; } physaddr = (ulong)addr; - DEBUGDRV("mapping physical address = 0x%lx", physaddr); if (remap_pfn_range(vma, vma->vm_start, physaddr >> PAGE_SHIFT, vma->vm_end - vma->vm_start, @@ -162,7 +158,6 @@ visorchipset_mmap(struct file *file, struct vm_area_struct *vma) default: return -ENOSYS; } - DEBUGDRV("%s success!", __func__); return 0; } @@ -172,7 +167,6 @@ static long visorchipset_ioctl(struct file *file, unsigned int cmd, s64 adjustment; s64 vrtc_offset; - DBGINF("entered visorchipset_ioctl, cmd=%d", cmd); switch (cmd) { case VMCALL_QUERY_GUEST_VIRTUAL_TIME_OFFSET: /* get the physical rtc offset */ @@ -181,16 +175,12 @@ static long visorchipset_ioctl(struct file *file, unsigned int cmd, ((void __user *)arg, &vrtc_offset, sizeof(vrtc_offset))) { return -EFAULT; } - DBGINF("insde visorchipset_ioctl, cmd=%d, vrtc_offset=%lld", - cmd, vrtc_offset); return SUCCESS; case VMCALL_UPDATE_PHYSICAL_TIME: if (copy_from_user (&adjustment, (void __user *)arg, sizeof(adjustment))) { return -EFAULT; } - DBGINF("insde visorchipset_ioctl, cmd=%d, adjustment=%lld", cmd, - adjustment); return issue_vmcall_update_physical_time(adjustment); default: LOGERR("visorchipset_ioctl received invalid command"); -- GitLab From 2098dbd1b2a8e428001e0d075ae148124af6f57d Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Wed, 4 Mar 2015 12:14:22 -0500 Subject: [PATCH 03187/11651] staging: unisys: remove LOGINF macros Remove the LOGINF, LOGINFDEV, LOGINFDEVX, LOGINFNAME, PRINTKDRV, and INFODRV macros entirely from the driver set. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/timskmod.h | 2 - drivers/staging/unisys/include/uniklog.h | 29 ------ drivers/staging/unisys/uislib/uislib.c | 31 ------- drivers/staging/unisys/uislib/uisthread.c | 5 -- drivers/staging/unisys/uislib/uisutils.c | 2 - drivers/staging/unisys/virthba/virthba.c | 54 ----------- drivers/staging/unisys/virtpci/virtpci.c | 89 +------------------ .../unisys/visorchannel/visorchannel_main.c | 2 - drivers/staging/unisys/visorchipset/file.c | 4 - .../unisys/visorchipset/visorchipset_main.c | 78 +--------------- 10 files changed, 5 insertions(+), 291 deletions(-) diff --git a/drivers/staging/unisys/include/timskmod.h b/drivers/staging/unisys/include/timskmod.h index eef29e73099b..ff0fc167413c 100644 --- a/drivers/staging/unisys/include/timskmod.h +++ b/drivers/staging/unisys/include/timskmod.h @@ -87,13 +87,11 @@ (void *)(p2) = SWAPPOINTERS_TEMP; \ } while (0) -#define PRINTKDRV(fmt, args...) LOGINF(fmt, ## args) #define TBDDRV(fmt, args...) LOGERR(fmt, ## args) #define HUHDRV(fmt, args...) LOGERR(fmt, ## args) #define ERRDRV(fmt, args...) LOGERR(fmt, ## args) #define WARNDRV(fmt, args...) LOGWRN(fmt, ## args) #define SECUREDRV(fmt, args...) LOGWRN(fmt, ## args) -#define INFODRV(fmt, args...) LOGINF(fmt, ## args) #define PRINTKDEV(devname, fmt, args...) LOGINFDEV(devname, fmt, ## args) #define TBDDEV(devname, fmt, args...) LOGERRDEV(devname, fmt, ## args) diff --git a/drivers/staging/unisys/include/uniklog.h b/drivers/staging/unisys/include/uniklog.h index 10171a185871..e3c374cfe26e 100644 --- a/drivers/staging/unisys/include/uniklog.h +++ b/drivers/staging/unisys/include/uniklog.h @@ -25,35 +25,6 @@ #include -/* - * # LOGINF - * - * \brief Log informational message - logs a message at the LOG_INFO level - * - * \param devname the device name of the device reporting this message, or - * NULL if this message is NOT device-related. - * \param fmt printf()-style format string containing the message to log. - * \param args Optional arguments to be formatted and inserted into the - * format string. - * \return nothing - * - * Logs the specified message at the LOG_INFO level. - */ - -#define LOGINF(fmt, args...) pr_info(fmt, ## args) -#define LOGINFDEV(devname, fmt, args...) \ - pr_info("%s " fmt, devname, ## args) -#define LOGINFDEVX(devno, fmt, args...) \ - pr_info("dev%d " fmt, devno, ## args) -#define LOGINFNAME(vnic, fmt, args...) \ - do { \ - if (vnic != NULL) { \ - pr_info("%s " fmt, vnic->name, ## args); \ - } else { \ - pr_info(fmt, ## args); \ - } \ - } while (0) - /* * # LOGVER * diff --git a/drivers/staging/unisys/uislib/uislib.c b/drivers/staging/unisys/uislib/uislib.c index 4fdddc301157..93b471412bd5 100644 --- a/drivers/staging/unisys/uislib/uislib.c +++ b/drivers/staging/unisys/uislib/uislib.c @@ -671,8 +671,6 @@ static int destroy_device(struct controlvm_message *msg, char *buf) dev_no = msg->cmd.destroy_device.bus_no; read_lock(&bus_list_lock); - LOGINF("destroy_device called for bus_no=%u, dev_no=%u", bus_no, - dev_no); for (bus = bus_list; bus; bus = bus->next) { if (bus->bus_no == bus_no) { /* make sure the device number is valid */ @@ -733,12 +731,10 @@ static int destroy_device(struct controlvm_message *msg, char *buf) * kernel paging request" */ if (dev->polling) { - LOGINF("calling uislib_disable_channel_interrupts"); uislib_disable_channel_interrupts(bus_no, dev_no); } /* unmap the channel memory for the device. */ if (!msg->hdr.flags.test_message) { - LOGINF("destroy_device, doing iounmap"); uislib_iounmap(dev->chanptr); } kfree(dev); @@ -806,7 +802,6 @@ uislib_client_inject_add_bus(u32 bus_no, uuid_le inst_uuid, { struct controlvm_message msg; - LOGINF("enter busNo=0x%x\n", bus_no); /* step 0: init the chipset */ POSTCODE_LINUX_3(CHIPSET_INIT_ENTRY_PC, bus_no, POSTCODE_SEVERITY_INFO); @@ -826,7 +821,6 @@ uislib_client_inject_add_bus(u32 bus_no, uuid_le inst_uuid, LOGERR("init_chipset failed.\n"); return 0; } - LOGINF("chipset initialized\n"); POSTCODE_LINUX_3(CHIPSET_INIT_EXIT_PC, bus_no, POSTCODE_SEVERITY_INFO); } @@ -906,7 +900,6 @@ uislib_client_inject_add_vhba(u32 bus_no, u32 dev_no, { struct controlvm_message msg; - LOGINF(" enter busNo=0x%x devNo=0x%x\n", bus_no, dev_no); /* chipset init'ed with bus bus has been previously created - * Verify it still exists step 2: create the VHBA device on the * bus @@ -965,7 +958,6 @@ uislib_client_inject_add_vnic(u32 bus_no, u32 dev_no, { struct controlvm_message msg; - LOGINF(" enter busNo=0x%x devNo=0x%x\n", bus_no, dev_no); /* chipset init'ed with bus bus has been previously created - * Verify it still exists step 2: create the VNIC device on the * bus @@ -1249,7 +1241,6 @@ static int process_incoming(void *v) wait_cycles = (cur_cycles - old_cycles); } } - LOGINF("wait_cycles=%llu", wait_cycles); cycles_before_wait = wait_cycles; idle_cycles = 0; poll_dev_start = 0; @@ -1310,7 +1301,6 @@ static int process_incoming(void *v) if (kthread_should_stop()) break; if (en_smart_wakeup == 0xFF) { - LOGINF("en_smart_wakeup set to 0xff, to force exiting process_incoming"); break; } /* wait for POLLJIFFIES_NORMAL jiffies, or until @@ -1441,27 +1431,6 @@ uislib_mod_init(void) if (!unisys_spar_platform) return -ENODEV; - LOGINF("MONITORAPIS"); - - LOGINF("sizeof(struct uiscmdrsp):%lu bytes\n", - (ulong)sizeof(struct uiscmdrsp)); - LOGINF("sizeof(struct phys_info):%lu\n", - (ulong)sizeof(struct phys_info)); - LOGINF("sizeof(uiscmdrsp_scsi):%lu\n", - (ulong)sizeof(struct uiscmdrsp_scsi)); - LOGINF("sizeof(uiscmdrsp_net):%lu\n", - (ulong)sizeof(struct uiscmdrsp_net)); - LOGINF("sizeof(CONTROLVM_MESSAGE):%lu bytes\n", - (ulong)sizeof(struct controlvm_message)); - LOGINF("sizeof(struct spar_controlvm_channel_protocol):%lu bytes\n", - (ulong)sizeof(struct spar_controlvm_channel_protocol)); - LOGINF("sizeof(CHANNEL_HEADER):%lu bytes\n", - (ulong)sizeof(struct channel_header)); - LOGINF("sizeof(struct spar_io_channel_protocol):%lu bytes\n", - (ulong)sizeof(struct spar_io_channel_protocol)); - LOGINF("SIZEOF_CMDRSP:%lu bytes\n", SIZEOF_CMDRSP); - LOGINF("SIZEOF_PROTOCOL:%lu bytes\n", SIZEOF_PROTOCOL); - /* initialize global pointers to NULL */ bus_list = NULL; bus_list_count = 0; diff --git a/drivers/staging/unisys/uislib/uisthread.c b/drivers/staging/unisys/uislib/uisthread.c index d54005d8f50d..5b0041c4a137 100644 --- a/drivers/staging/unisys/uislib/uisthread.c +++ b/drivers/staging/unisys/uislib/uisthread.c @@ -47,7 +47,6 @@ uisthread_start(struct uisthread_info *thrinfo, return 0; /* failure */ } thrinfo->id = thrinfo->task->pid; - LOGINF("started thread pid:%d\n", thrinfo->id); return 1; } EXPORT_SYMBOL_GPL(uisthread_start); @@ -60,16 +59,12 @@ uisthread_stop(struct uisthread_info *thrinfo) if (thrinfo->id == 0) return; /* thread not running */ - LOGINF("uisthread_stop stopping id:%d\n", thrinfo->id); kthread_stop(thrinfo->task); /* give up if the thread has NOT died in 1 minute */ if (wait_for_completion_timeout(&thrinfo->has_stopped, 60 * HZ)) stopped = 1; - else - LOGERR("timed out trying to signal thread\n"); if (stopped) { - LOGINF("uisthread_stop stopped id:%d\n", thrinfo->id); thrinfo->id = 0; } } diff --git a/drivers/staging/unisys/uislib/uisutils.c b/drivers/staging/unisys/uislib/uisutils.c index 2fbada3471a6..7d7f408505f2 100644 --- a/drivers/staging/unisys/uislib/uisutils.c +++ b/drivers/staging/unisys/uislib/uisutils.c @@ -74,8 +74,6 @@ int uisctrl_register_req_handler(int type, void *fptr, struct ultra_vbus_deviceinfo *chipset_driver_info) { - LOGINF("type = %d, fptr = 0x%p.\n", type, fptr); - switch (type) { case 2: if (fptr) { diff --git a/drivers/staging/unisys/virthba/virthba.c b/drivers/staging/unisys/virthba/virthba.c index a19dac12b9c0..5ec2423a4138 100644 --- a/drivers/staging/unisys/virthba/virthba.c +++ b/drivers/staging/unisys/virthba/virthba.c @@ -469,9 +469,6 @@ virthba_probe(struct virtpci_dev *virtpcidev, const struct pci_device_id *id) LOGVER("virtpcidev bus_no<<%d>>devNo<<%d>>", virtpcidev->bus_no, virtpcidev->device_no); - LOGINF("entering virthba_probe...\n"); - LOGINF("virtpcidev bus_no<<%d>>devNo<<%d>>", virtpcidev->bus_no, - virtpcidev->device_no); POSTCODE_LINUX_2(VHBA_PROBE_ENTRY_PC, POSTCODE_SEVERITY_INFO); /* call scsi_host_alloc to register a scsi host adapter * instance - this virthba that has just been created is an @@ -497,12 +494,6 @@ virthba_probe(struct virtpci_dev *virtpcidev, const struct pci_device_id *id) * scan is 0 to max (inclusive); so we will subtract one from * the max-channel value. */ - LOGINF("virtpcidev->scsi.max.max_channel=%u, max_id=%u, max_lun=%u, cmd_per_lun=%u, max_io_size=%u\n", - (unsigned)virtpcidev->scsi.max.max_channel - 1, - (unsigned)virtpcidev->scsi.max.max_id, - (unsigned)virtpcidev->scsi.max.max_lun, - (unsigned)virtpcidev->scsi.max.cmd_per_lun, - (unsigned)virtpcidev->scsi.max.max_io_size); scsihost->max_channel = (unsigned)virtpcidev->scsi.max.max_channel; scsihost->max_id = (unsigned)virtpcidev->scsi.max.max_id; scsihost->max_lun = (unsigned)virtpcidev->scsi.max.max_lun; @@ -513,13 +504,6 @@ virthba_probe(struct virtpci_dev *virtpcidev, const struct pci_device_id *id) (unsigned short)(virtpcidev->scsi.max.max_io_size / PAGE_SIZE); if (scsihost->sg_tablesize > MAX_PHYS_INFO) scsihost->sg_tablesize = MAX_PHYS_INFO; - LOGINF("scsihost->max_channel=%u, max_id=%u, max_lun=%llu, cmd_per_lun=%u, max_sectors=%hu, sg_tablesize=%hu\n", - scsihost->max_channel, scsihost->max_id, scsihost->max_lun, - scsihost->cmd_per_lun, scsihost->max_sectors, - scsihost->sg_tablesize); - LOGINF("scsihost->can_queue=%u, scsihost->cmd_per_lun=%u, max_sectors=%hu, sg_tablesize=%hu\n", - scsihost->can_queue, scsihost->cmd_per_lun, scsihost->max_sectors, - scsihost->sg_tablesize); /* this creates "host%d" in sysfs. If 2nd argument is NULL, * then this generic /sys/devices/platform/host? device is @@ -591,15 +575,6 @@ virthba_probe(struct virtpci_dev *virtpcidev, const struct pci_device_id *id) scsi_host_put(scsihost); return -ENODEV; } - LOGINF("sendInterruptHandle=0x%16llX", - virthbainfo->intr.send_irq_handle); - LOGINF("recvInterruptHandle=0x%16llX", - virthbainfo->intr.recv_irq_handle); - LOGINF("recvInterruptVector=0x%8X", - virthbainfo->intr.recv_irq_vector); - LOGINF("recvInterruptShared=0x%2X", - virthbainfo->intr.recv_irq_shared); - LOGINF("scsihost.hostt->name=%s", scsihost->hostt->name); virthbainfo->interrupt_vector = virthbainfo->intr.recv_irq_handle & INTERRUPT_VECTOR_MASK; rsp = request_irq(virthbainfo->interrupt_vector, handler, IRQF_SHARED, @@ -624,7 +599,6 @@ virthba_probe(struct virtpci_dev *virtpcidev, const struct pci_device_id *id) scsi_scan_host(scsihost); - LOGINF("virthba added scsihost:0x%p\n", scsihost); POSTCODE_LINUX_2(VHBA_PROBE_EXIT_PC, POSTCODE_SEVERITY_INFO); return 0; } @@ -636,13 +610,9 @@ virthba_remove(struct virtpci_dev *virtpcidev) struct Scsi_Host *scsihost = (struct Scsi_Host *)virtpcidev->scsi.scsihost; - LOGINF("virtpcidev bus_no<<%d>>devNo<<%d>>", virtpcidev->bus_no, - virtpcidev->device_no); virthbainfo = (struct virthba_info *)scsihost->hostdata; if (virthbainfo->interrupt_vector != -1) free_irq(virthbainfo->interrupt_vector, virthbainfo); - LOGINF("Removing virtpcidev: 0x%p, virthbainfo: 0x%p\n", virtpcidev, - virthbainfo); scsi_remove_host(scsihost); @@ -652,7 +622,6 @@ virthba_remove(struct virtpci_dev *virtpcidev) * scsi_add_host so the scsi_host gets deleted */ scsi_host_put(scsihost); - LOGINF("virthba removed scsi_host.\n"); } static int @@ -666,9 +635,6 @@ forward_vdiskmgmt_command(enum vdisk_mgmt_types vdiskcmdtype, int notifyresult = 0xffff; wait_queue_head_t notifyevent; - LOGINF("vDiskMgmt:%d %d:%d:%d\n", vdiskcmdtype, - vdest->channel, vdest->id, vdest->lun); - if (virthbainfo->serverdown || virthbainfo->serverchangingstate) return FAILED; @@ -703,10 +669,7 @@ forward_vdiskmgmt_command(enum vdisk_mgmt_types vdiskcmdtype, &virthbainfo->chinfo.insertlock, DONT_ISSUE_INTERRUPT, (u64)NULL, OK_TO_WAIT, "vhba"); - LOGINF("VdiskMgmt waiting on event notifyevent=0x%p\n", - cmdrsp->scsitaskmgmt.notify); wait_event(notifyevent, notifyresult != 0xffff); - LOGINF("VdiskMgmt complete; result:%d\n", cmdrsp->vdiskmgmt.result); kfree(cmdrsp); return SUCCESS; } @@ -725,9 +688,6 @@ forward_taskmgmt_command(enum task_mgmt_types tasktype, int notifyresult = 0xffff; wait_queue_head_t notifyevent; - LOGINF("TaskMgmt:%d %d:%d:%llu\n", tasktype, - scsidev->channel, scsidev->id, scsidev->lun); - if (virthbainfo->serverdown || virthbainfo->serverchangingstate) return FAILED; @@ -761,10 +721,7 @@ forward_taskmgmt_command(enum task_mgmt_types tasktype, &virthbainfo->chinfo.insertlock, DONT_ISSUE_INTERRUPT, (u64)NULL, OK_TO_WAIT, "vhba"); - LOGINF("TaskMgmt waiting on event notifyevent=0x%p\n", - cmdrsp->scsitaskmgmt.notify); wait_event(notifyevent, notifyresult != 0xffff); - LOGINF("TaskMgmt complete; result:%d\n", cmdrsp->scsitaskmgmt.result); kfree(cmdrsp); return SUCCESS; } @@ -958,9 +915,6 @@ virthba_queue_command_lck(struct scsi_cmnd *scsicmd, for_each_sg(sgl, sg, scsi_sg_count(scsicmd), i) { cmdrsp->scsi.gpi_list[i].address = sg_phys(sg); cmdrsp->scsi.gpi_list[i].length = sg->length; - if ((i != 0) && (sg->offset != 0)) - LOGINF("Offset on a sg_entry other than zero =<<%d>>.\n", - sg->offset); } if (sg_failed) { @@ -1208,7 +1162,6 @@ complete_vdiskmgmt_command(struct uiscmdrsp *cmdrsp) /* wake up the error handler that is waiting for this */ *(int *)cmdrsp->vdiskmgmt.notifyresult = cmdrsp->vdiskmgmt.result; wake_up_all((wait_queue_head_t *)cmdrsp->vdiskmgmt.notify); - LOGINF("set notify result to %d\n", cmdrsp->vdiskmgmt.result); } static inline void @@ -1219,7 +1172,6 @@ complete_taskmgmt_command(struct uiscmdrsp *cmdrsp) *(int *)cmdrsp->scsitaskmgmt.notifyresult = cmdrsp->scsitaskmgmt.result; wake_up_all((wait_queue_head_t *)cmdrsp->scsitaskmgmt.notify); - LOGINF("set notify result to %d\n", cmdrsp->scsitaskmgmt.result); } static void @@ -1591,8 +1543,6 @@ virthba_mod_init(void) if (!unisys_spar_platform) return -ENODEV; - LOGINF("Entering virthba_mod_init...\n"); - POSTCODE_LINUX_2(VHBA_CREATE_ENTRY_PC, POSTCODE_SEVERITY_INFO); virthba_parse_options(virthba_options); @@ -1630,7 +1580,6 @@ virthba_mod_init(void) } POSTCODE_LINUX_2(VHBA_CREATE_EXIT_PC, POSTCODE_SEVERITY_INFO); - LOGINF("Leaving virthba_mod_init\n"); return error; } @@ -1680,8 +1629,6 @@ static DEVICE_ATTRIBUTE *virthba_shost_attrs[] = { static void __exit virthba_mod_exit(void) { - LOGINF("entering virthba_mod_exit...\n"); - virtpci_unregister_driver(&virthba_driver); /* unregister is going to call virthba_remove */ /* destroy serverdown completion workqueue */ @@ -1691,7 +1638,6 @@ virthba_mod_exit(void) } debugfs_remove_recursive(virthba_debugfs_dir); - LOGINF("Leaving virthba_mod_exit\n"); } /* specify function to be run at module insertion time */ diff --git a/drivers/staging/unisys/virtpci/virtpci.c b/drivers/staging/unisys/virtpci/virtpci.c index a20af632c38a..d87ebcc615d4 100644 --- a/drivers/staging/unisys/virtpci/virtpci.c +++ b/drivers/staging/unisys/virtpci/virtpci.c @@ -279,8 +279,6 @@ static int add_vbus(struct add_vbus_guestpart *addparams) &chipset_driver_info); write_vbus_bus_info(vbus->platform_data /* chanptr */, &bus_driver_info); - LOGINF("Added vbus %d; device %s created successfully\n", - addparams->bus_no, BUS_ID(vbus)); POSTCODE_LINUX_2(VPCI_CREATE_EXIT_PC, POSTCODE_SEVERITY_INFO); return 1; } @@ -328,14 +326,8 @@ static int add_vhba(struct add_virt_guestpart *addparams) return 0; } - LOGINF("Adding vhba wwnn:%x:%x config:%d-%d-%d-%d chanptr:%p\n", - scsi.wwnn.wwnn1, scsi.wwnn.wwnn2, - scsi.max.max_channel, scsi.max.max_id, scsi.max.max_lun, - scsi.max.cmd_per_lun, addparams->chanptr); i = virtpci_device_add(vbus, VIRTHBA_TYPE, addparams, &scsi, NULL); if (i) { - LOGINF("Added vhba wwnn:%x:%x chanptr:%p\n", scsi.wwnn.wwnn1, - scsi.wwnn.wwnn2, addparams->chanptr); POSTCODE_LINUX_3(VPCI_CREATE_EXIT_PC, i, POSTCODE_SEVERITY_INFO); } @@ -391,15 +383,8 @@ add_vnic(struct add_virt_guestpart *addparams) return 0; } - LOGINF("Adding vnic macaddr:%02x:%02x:%02x:%02x:%02x:%02x rcvbufs:%d mtu:%d chanptr:%p%pUL\n", - net.mac_addr[0], net.mac_addr[1], net.mac_addr[2], - net.mac_addr[3], net.mac_addr[4], net.mac_addr[5], - net.num_rcv_bufs, net.mtu, addparams->chanptr, &net.zone_uuid); i = virtpci_device_add(vbus, VIRTNIC_TYPE, addparams, NULL, &net); if (i) { - LOGINF("Added vnic macaddr:%02x:%02x:%02x:%02x:%02x:%02x\n", - net.mac_addr[0], net.mac_addr[1], net.mac_addr[2], - net.mac_addr[3], net.mac_addr[4], net.mac_addr[5]); POSTCODE_LINUX_3(VPCI_CREATE_EXIT_PC, i, POSTCODE_SEVERITY_INFO); return 1; @@ -426,10 +411,6 @@ delete_vbus(struct del_vbus_guestpart *delparams) } /* ensure that bus has no devices? -- TBD */ - LOGINF("Deleting %s\n", BUS_ID(vbus)); - if (delete_vbus_device(vbus, NULL)) - return 0; /* failure */ - LOGINF("Deleted vbus %d\n", delparams->bus_no); return 1; } @@ -441,13 +422,10 @@ delete_vbus_device(struct device *vbus, void *data) if ((checkforroot) && match_busid(vbus, (void *)BUS_ID(dev))) { /* skip it - don't delete root bus */ - LOGINF("skipping root bus\n"); return 0; /* pretend no error */ } - LOGINF("Calling unregister for %s\n", BUS_ID(vbus)); device_unregister(vbus); kfree(vbus); - LOGINF("VBus unregister and freed\n"); return 0; /* no error */ } @@ -461,12 +439,8 @@ static int pause_vhba(struct pause_virt_guestpart *pauseparams) GET_SCSIADAPINFO_FROM_CHANPTR(pauseparams->chanptr); - LOGINF("Pausing vhba wwnn:%x:%x\n", scsi.wwnn.wwnn1, scsi.wwnn.wwnn2); i = virtpci_device_serverdown(NULL /*no parent bus */, VIRTHBA_TYPE, &scsi.wwnn, NULL); - if (i) - LOGINF("Paused vhba wwnn:%x:%x\n", scsi.wwnn.wwnn1, - scsi.wwnn.wwnn2); return i; } @@ -480,16 +454,8 @@ static int pause_vnic(struct pause_virt_guestpart *pauseparams) GET_NETADAPINFO_FROM_CHANPTR(pauseparams->chanptr); - LOGINF("Pausing vnic macaddr:%02x:%02x:%02x:%02x:%02x:%02x\n", - net.mac_addr[0], net.mac_addr[1], net.mac_addr[2], - net.mac_addr[3], net.mac_addr[4], net.mac_addr[5]); i = virtpci_device_serverdown(NULL /*no parent bus */, VIRTNIC_TYPE, NULL, net.mac_addr); - if (i) { - LOGINF(" Paused vnic macaddr:%02x:%02x:%02x:%02x:%02x:%02x\n", - net.mac_addr[0], net.mac_addr[1], net.mac_addr[2], - net.mac_addr[3], net.mac_addr[4], net.mac_addr[5]); - } return i; } @@ -503,12 +469,8 @@ static int resume_vhba(struct resume_virt_guestpart *resumeparams) GET_SCSIADAPINFO_FROM_CHANPTR(resumeparams->chanptr); - LOGINF("Resuming vhba wwnn:%x:%x\n", scsi.wwnn.wwnn1, scsi.wwnn.wwnn2); i = virtpci_device_serverup(NULL /*no parent bus */, VIRTHBA_TYPE, &scsi.wwnn, NULL); - if (i) - LOGINF("Resumed vhba wwnn:%x:%x\n", scsi.wwnn.wwnn1, - scsi.wwnn.wwnn2); return i; } @@ -523,16 +485,8 @@ resume_vnic(struct resume_virt_guestpart *resumeparams) GET_NETADAPINFO_FROM_CHANPTR(resumeparams->chanptr); - LOGINF("Resuming vnic macaddr:%02x:%02x:%02x:%02x:%02x:%02x\n", - net.mac_addr[0], net.mac_addr[1], net.mac_addr[2], - net.mac_addr[3], net.mac_addr[4], net.mac_addr[5]); i = virtpci_device_serverup(NULL /*no parent bus */, VIRTNIC_TYPE, NULL, net.mac_addr); - if (i) { - LOGINF(" Resumed vnic macaddr:%02x:%02x:%02x:%02x:%02x:%02x\n", - net.mac_addr[0], net.mac_addr[1], net.mac_addr[2], - net.mac_addr[3], net.mac_addr[4], net.mac_addr[5]); - } return i; } @@ -546,12 +500,9 @@ static int delete_vhba(struct del_virt_guestpart *delparams) GET_SCSIADAPINFO_FROM_CHANPTR(delparams->chanptr); - LOGINF("Deleting vhba wwnn:%x:%x\n", scsi.wwnn.wwnn1, scsi.wwnn.wwnn2); i = virtpci_device_del(NULL /*no parent bus */, VIRTHBA_TYPE, &scsi.wwnn, NULL); if (i) { - LOGINF("Deleted vhba wwnn:%x:%x\n", scsi.wwnn.wwnn1, - scsi.wwnn.wwnn2); return 1; } return 0; @@ -567,23 +518,13 @@ static int delete_vnic(struct del_virt_guestpart *delparams) GET_NETADAPINFO_FROM_CHANPTR(delparams->chanptr); - LOGINF("Deleting vnic macaddr:%02x:%02x:%02x:%02x:%02x:%02x\n", - net.mac_addr[0], net.mac_addr[1], net.mac_addr[2], - net.mac_addr[3], net.mac_addr[4], net.mac_addr[5]); i = virtpci_device_del(NULL /*no parent bus */, VIRTNIC_TYPE, NULL, net.mac_addr); - if (i) { - LOGINF("Deleted vnic macaddr:%02x:%02x:%02x:%02x:%02x:%02x\n", - net.mac_addr[0], net.mac_addr[1], net.mac_addr[2], - net.mac_addr[3], net.mac_addr[4], net.mac_addr[5]); - } return i; } #define DELETE_ONE_VPCIDEV(vpcidev) { \ - LOGINF("calling device_unregister:%p\n", &vpcidev->generic_dev); \ device_unregister(&vpcidev->generic_dev); \ - LOGINF("Deleted %p\n", vpcidev); \ kfree(vpcidev); \ } @@ -610,12 +551,10 @@ static void delete_all(void) tmpvpcidev = nextvpcidev; count++; } - LOGINF("Deleted %d vhbas/vnics.\n", count); /* now delete each vbus */ - if (bus_for_each_dev - (&virtpci_bus_type, NULL, (void *)1, delete_vbus_device)) - LOGERR("delete of all vbus failed\n"); + bus_for_each_dev(&virtpci_bus_type, NULL, (void *)1, + delete_vbus_device); } /* deletes all vnics or vhbas @@ -643,13 +582,8 @@ static int delete_all_virt(enum virtpci_dev_type devtype, return 0; } - LOGINF("Deleting all %s in vbus %s\n", - devtype == VIRTHBA_TYPE ? "vhbas" : "vnics", busid); /* delete all vhbas/vnics */ i = virtpci_device_del(vbus, devtype, NULL, NULL); - if (i > 0) - LOGINF("Deleted %d %s\n", i, - devtype == VIRTHBA_TYPE ? "vhbas" : "vnics"); return 1; } @@ -812,8 +746,6 @@ static int virtpci_device_probe(struct device *dev) const struct pci_device_id *id; int error = 0; - LOGINF("In virtpci_device_probe dev:%p virtpcidev:%p virtpcidrv:%p\n", - dev, virtpcidev, virtpcidrv); /* VERBOSE/DEBUG ? */ POSTCODE_LINUX_2(VPCI_PROBE_ENTRY_PC, POSTCODE_SEVERITY_INFO); /* static match and static probe vs dynamic match & dynamic * probe - do we care?. @@ -858,9 +790,6 @@ static int virtpci_device_remove(struct device *dev_) struct virtpci_dev *virtpcidev = device_to_virtpci_dev(dev_); struct virtpci_driver *virtpcidrv = virtpcidev->mydriver; - LOGINF("In virtpci_device_remove bus_id:%s dev_:%p virtpcidev:%p dev->driver:%p drivername:%s\n", - BUS_ID(dev_), dev_, virtpcidev, dev_->driver, - dev_->driver->name); /* VERBOSE/DEBUG */ if (virtpcidrv) { /* TEMP: assuming we have only one such driver for now */ if (virtpcidrv->remove) @@ -899,9 +828,6 @@ static int virtpci_device_add(struct device *parentbus, int devtype, struct spar_io_channel_protocol __iomem *io_chan = NULL; struct device *dev; - LOGINF("virtpci_device_add parentbus:%p chanptr:%p\n", parentbus, - addparams->chanptr); - POSTCODE_LINUX_2(VPCI_CREATE_ENTRY_PC, POSTCODE_SEVERITY_INFO); if ((devtype != VIRTHBA_TYPE) && (devtype != VIRTNIC_TYPE)) { @@ -1041,10 +967,6 @@ static int virtpci_device_add(struct device *parentbus, int devtype, return 0; } - LOGINF("Added %s:%d:%d &virtpcidev->generic_dev:%p\n", - (devtype == VIRTHBA_TYPE) ? "virthba" : "virtnic", - addparams->bus_no, addparams->device_no, - &virtpcidev->generic_dev); POSTCODE_LINUX_2(VPCI_CREATE_EXIT_PC, POSTCODE_SEVERITY_INFO); return 1; } @@ -1284,7 +1206,6 @@ static void virtpci_device_release(struct device *dev_) /* this function is called when the last reference to the * device is removed */ - LOGINF("In virtpci_device_release:%p - NOT YET IMPLEMENTED\n", dev_); } /*****************************************************/ @@ -1507,21 +1428,16 @@ static int __init virtpci_mod_init(void) return -1; } - LOGINF("successfully registered virtpci_ctrlchan_func (0x%p) as callback.\n", - (void *)&virtpci_ctrlchan_func); /* create debugfs directory and info file inside. */ virtpci_debugfs_dir = debugfs_create_dir("virtpci", NULL); debugfs_create_file("info", S_IRUSR, virtpci_debugfs_dir, NULL, &debugfs_info_fops); - LOGINF("Leaving\n"); POSTCODE_LINUX_2(VPCI_CREATE_EXIT_PC, POSTCODE_SEVERITY_INFO); return 0; } static void __exit virtpci_mod_exit(void) { - LOGINF("virtpci_mod_exit...\n"); - /* unregister the callback function */ if (!uisctrl_register_req_handler(2, NULL, NULL)) LOGERR("uisctrl_register_req_handler ****FAILED.\n"); @@ -1529,7 +1445,6 @@ static void __exit virtpci_mod_exit(void) device_unregister(&virtpci_rootbus_device); bus_unregister(&virtpci_bus_type); debugfs_remove_recursive(virtpci_debugfs_dir); - LOGINF("Leaving\n"); } module_init(virtpci_mod_init); diff --git a/drivers/staging/unisys/visorchannel/visorchannel_main.c b/drivers/staging/unisys/visorchannel/visorchannel_main.c index f4be2e62c97d..787d4774b199 100644 --- a/drivers/staging/unisys/visorchannel/visorchannel_main.c +++ b/drivers/staging/unisys/visorchannel/visorchannel_main.c @@ -32,14 +32,12 @@ visorchannel_init(void) if (!unisys_spar_platform) return -ENODEV; - INFODRV("driver version %s loaded", VERSION); return 0; } static void visorchannel_exit(void) { - INFODRV("driver unloaded"); } module_init(visorchannel_init); diff --git a/drivers/staging/unisys/visorchipset/file.c b/drivers/staging/unisys/visorchipset/file.c index f580fb6f1ee0..b37113263151 100644 --- a/drivers/staging/unisys/visorchipset/file.c +++ b/drivers/staging/unisys/visorchipset/file.c @@ -66,7 +66,6 @@ visorchipset_file_init(dev_t major_dev, struct visorchannel **controlvm_channel) return -1; } registered = TRUE; - INFODRV("New major number %d registered\n", MAJOR(majordev)); } else { /* static major device number registration required */ if (register_chrdev_region(majordev, 1, MYDRVNAME) < 0) { @@ -74,15 +73,12 @@ visorchipset_file_init(dev_t major_dev, struct visorchannel **controlvm_channel) return -1; } registered = TRUE; - INFODRV("Static major number %d registered\n", MAJOR(majordev)); } rc = cdev_add(&file_cdev, MKDEV(MAJOR(majordev), 0), 1); if (rc < 0) { ERRDRV("failed to create char device: (status=%d)\n", rc); return -1; } - INFODRV("Registered char device for %s (major=%d)", - MYDRVNAME, MAJOR(majordev)); return 0; } diff --git a/drivers/staging/unisys/visorchipset/visorchipset_main.c b/drivers/staging/unisys/visorchipset/visorchipset_main.c index 4b5def838ebb..a49ba6141544 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset_main.c +++ b/drivers/staging/unisys/visorchipset/visorchipset_main.c @@ -712,11 +712,9 @@ controlvm_respond(struct controlvm_message_header *msgHdr, int response) && g_DeviceChangeStatePacket.device_change_state.dev_no == g_diagpoolDevNo) outmsg.cmd = g_DeviceChangeStatePacket; - if (outmsg.hdr.flags.test_message == 1) { - LOGINF("%s controlvm_msg=0x%x response=%d for test message", - __func__, outmsg.hdr.id, response); + if (outmsg.hdr.flags.test_message == 1) return; - } + if (!visorchannel_signalinsert(ControlVm_channel, CONTROLVM_QUEUE_REQUEST, &outmsg)) { LOGERR("signalinsert failed!"); @@ -1063,8 +1061,6 @@ device_epilog(u32 busNo, u32 devNo, struct spar_segment_state state, u32 cmd, */ if (busNo == g_diagpoolBusNo && devNo == g_diagpoolDevNo) { - LOGINF("DEVICE_CHANGESTATE(DiagpoolChannel busNo=%d devNo=%d is pausing...)", - busNo, devNo); /* this will trigger the * diag_shutdown.sh script in * the visorchipset hotplug */ @@ -1292,8 +1288,6 @@ Away: is_diagpool_channel(pDevInfo->chan_info.channel_type_uuid)) { g_diagpoolBusNo = busNo; g_diagpoolDevNo = devNo; - LOGINF("CONTROLVM_DEVICE_CREATE for DiagPool channel: busNo=%lu, devNo=%lu", - g_diagpoolBusNo, g_diagpoolDevNo); } device_epilog(busNo, devNo, segment_state_running, CONTROLVM_DEVICE_CREATE, &inmsg->hdr, rc, @@ -1404,8 +1398,6 @@ initialize_controlvm_payload_info(HOSTADDRESS phys_addr, u64 offset, u32 bytes, info->offset = offset; info->bytes = bytes; info->ptr = payload; - LOGINF("offset=%llu, bytes=%lu, ptr=%p", - (u64) (info->offset), (ulong) (info->bytes), info->ptr); Away: if (rc < 0) { @@ -1506,7 +1498,6 @@ chipset_ready(struct controlvm_message_header *msgHdr) * and disks mounted for the partition */ g_ChipSetMsgHdr = *msgHdr; - LOGINF("Holding CHIPSET_READY response"); } } @@ -1643,12 +1634,6 @@ parahotplug_request_kickoff(struct parahotplug_request *req) sprintf(env_func, "SPAR_PARAHOTPLUG_FUNCTION=%d", cmd->device_change_state.dev_no & 0x7); - LOGINF("parahotplug_request_kickoff: state=%d, bdf=%d/%d/%d, id=%u\n", - cmd->device_change_state.state.active, - cmd->device_change_state.bus_no, - cmd->device_change_state.dev_no >> 3, - cmd->device_change_state.dev_no & 7, req->id); - kobject_uevent_env(&Visorchipset_platform_device.dev.kobj, KOBJ_CHANGE, envp); } @@ -1827,43 +1812,24 @@ handle_command(struct controlvm_message inmsg, HOSTADDRESS channel_addr) } switch (inmsg.hdr.id) { case CONTROLVM_CHIPSET_INIT: - LOGINF("CHIPSET_INIT(#busses=%lu,#switches=%lu)", - (ulong) inmsg.cmd.init_chipset.bus_count, - (ulong) inmsg.cmd.init_chipset.switch_count); chipset_init(&inmsg); break; case CONTROLVM_BUS_CREATE: - LOGINF("BUS_CREATE(%lu,#devs=%lu)", - (ulong) cmd->create_bus.bus_no, - (ulong) cmd->create_bus.dev_count); bus_create(&inmsg); break; case CONTROLVM_BUS_DESTROY: - LOGINF("BUS_DESTROY(%lu)", (ulong) cmd->destroy_bus.bus_no); bus_destroy(&inmsg); break; case CONTROLVM_BUS_CONFIGURE: - LOGINF("BUS_CONFIGURE(%lu)", (ulong) cmd->configure_bus.bus_no); bus_configure(&inmsg, parser_ctx); break; case CONTROLVM_DEVICE_CREATE: - LOGINF("DEVICE_CREATE(%lu,%lu)", - (ulong) cmd->create_device.bus_no, - (ulong) cmd->create_device.dev_no); my_device_create(&inmsg); break; case CONTROLVM_DEVICE_CHANGESTATE: if (cmd->device_change_state.flags.phys_device) { - LOGINF("DEVICE_CHANGESTATE for physical device (%lu,%lu, active=%lu)", - (ulong) cmd->device_change_state.bus_no, - (ulong) cmd->device_change_state.dev_no, - (ulong) cmd->device_change_state.state.active); parahotplug_process_message(&inmsg); } else { - LOGINF("DEVICE_CHANGESTATE for virtual device (%lu,%lu, state.Alive=0x%lx)", - (ulong) cmd->device_change_state.bus_no, - (ulong) cmd->device_change_state.dev_no, - (ulong) cmd->device_change_state.state.alive); /* save the hdr and cmd structures for later use */ /* when sending back the response to Command */ my_device_changestate(&inmsg); @@ -1873,29 +1839,20 @@ handle_command(struct controlvm_message inmsg, HOSTADDRESS channel_addr) } break; case CONTROLVM_DEVICE_DESTROY: - LOGINF("DEVICE_DESTROY(%lu,%lu)", - (ulong) cmd->destroy_device.bus_no, - (ulong) cmd->destroy_device.dev_no); my_device_destroy(&inmsg); break; case CONTROLVM_DEVICE_CONFIGURE: - LOGINF("DEVICE_CONFIGURE(%lu,%lu)", - (ulong) cmd->configure_device.bus_no, - (ulong) cmd->configure_device.dev_no); /* no op for now, just send a respond that we passed */ if (inmsg.hdr.flags.response_expected) controlvm_respond(&inmsg.hdr, CONTROLVM_RESP_SUCCESS); break; case CONTROLVM_CHIPSET_READY: - LOGINF("CHIPSET_READY"); chipset_ready(&inmsg.hdr); break; case CONTROLVM_CHIPSET_SELFTEST: - LOGINF("CHIPSET_SELFTEST"); chipset_selftest(&inmsg.hdr); break; case CONTROLVM_CHIPSET_STOP: - LOGINF("CHIPSET_STOP"); chipset_notready(&inmsg.hdr); break; default: @@ -1923,7 +1880,6 @@ static HOSTADDRESS controlvm_get_channel_address(void) __func__); return 0; } - INFODRV("controlvm addr=%Lx", addr); return addr; } @@ -1956,7 +1912,6 @@ controlvm_periodic_work(struct work_struct *work) if (visorchipset_holdchipsetready && (g_ChipSetMsgHdr.id != CONTROLVM_INVALID)) { if (check_chipset_events() == 1) { - LOGINF("Sending CHIPSET_READY response"); controlvm_respond(&g_ChipSetMsgHdr, 0); clear_chipset_events(); memset(&g_ChipSetMsgHdr, 0, @@ -2019,13 +1974,11 @@ Away: * polling */ if (Poll_jiffies != POLLJIFFIES_CONTROLVMCHANNEL_SLOW) { - LOGINF("switched to slow controlvm polling"); Poll_jiffies = POLLJIFFIES_CONTROLVMCHANNEL_SLOW; } } else { if (Poll_jiffies != POLLJIFFIES_CONTROLVMCHANNEL_FAST) { Poll_jiffies = POLLJIFFIES_CONTROLVMCHANNEL_FAST; - LOGINF("switched to fast controlvm polling"); } } @@ -2135,7 +2088,6 @@ setup_crash_devices_work_queue(struct work_struct *work) POSTCODE_SEVERITY_ERR); return; } - LOGINF("Bus and device ready for dumping"); POSTCODE_LINUX_2(CRASH_DEV_EXIT_PC, POSTCODE_SEVERITY_INFO); return; @@ -2344,25 +2296,11 @@ static int __init visorchipset_init(void) { int rc = 0, x = 0; - char s[64]; HOSTADDRESS addr; if (!unisys_spar_platform) return -ENODEV; - LOGINF("chipset driver version %s loaded", VERSION); - /* process module options */ - POSTCODE_LINUX_2(DRIVER_ENTRY_PC, POSTCODE_SEVERITY_INFO); - - LOGINF("option - testvnic=%d", visorchipset_testvnic); - LOGINF("option - testvnicclient=%d", visorchipset_testvnicclient); - LOGINF("option - testmsg=%d", visorchipset_testmsg); - LOGINF("option - testteardown=%d", visorchipset_testteardown); - LOGINF("option - major=%d", visorchipset_major); - LOGINF("option - serverregwait=%d", visorchipset_serverregwait); - LOGINF("option - clientregwait=%d", visorchipset_clientregwait); - LOGINF("option - holdchipsetready=%d", visorchipset_holdchipsetready); - memset(&BusDev_Server_Notifiers, 0, sizeof(BusDev_Server_Notifiers)); memset(&BusDev_Client_Notifiers, 0, sizeof(BusDev_Client_Notifiers)); memset(&ControlVm_payload_info, 0, sizeof(ControlVm_payload_info)); @@ -2386,8 +2324,6 @@ visorchipset_init(void) spar_controlvm_channel_protocol_uuid); if (SPAR_CONTROLVM_CHANNEL_OK_CLIENT( visorchannel_get_header(ControlVm_channel))) { - LOGINF("Channel %s (ControlVm) discovered", - visorchannel_id(ControlVm_channel, s)); initialize_controlvm_payload(); } else { LOGERR("controlvm channel is invalid"); @@ -2424,9 +2360,7 @@ visorchipset_init(void) rc = -1; goto Away; } - if (visorchipset_disable_controlvm) { - LOGINF("visorchipset_init:controlvm disabled"); - } else { + if (!visorchipset_disable_controlvm) { /* if booting in a crash kernel */ if (visorchipset_crash_kernel) INIT_DELAYED_WORK(&Periodic_controlvm_work, @@ -2465,7 +2399,6 @@ visorchipset_init(void) rc = -1; goto Away; } - LOGINF("visorchipset device created"); POSTCODE_LINUX_2(CHIPSET_INIT_SUCCESS_PC, POSTCODE_SEVERITY_INFO); rc = 0; Away: @@ -2480,8 +2413,6 @@ Away: static void visorchipset_exit(void) { - char s[99]; - POSTCODE_LINUX_2(DRIVER_EXIT_PC, POSTCODE_SEVERITY_INFO); if (visorchipset_disable_controlvm) { @@ -2507,13 +2438,10 @@ visorchipset_exit(void) memset(&g_DelDumpMsgHdr, 0, sizeof(struct controlvm_message_header)); - LOGINF("Channel %s (ControlVm) disconnected", - visorchannel_id(ControlVm_channel, s)); visorchannel_destroy(ControlVm_channel); visorchipset_file_cleanup(); POSTCODE_LINUX_2(DRIVER_EXIT_PC, POSTCODE_SEVERITY_INFO); - LOGINF("chipset driver unloaded"); } module_param_named(testvnic, visorchipset_testvnic, int, S_IRUGO); -- GitLab From 1a84fec17106f03100aa7f41c96b78f9c0b6531b Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Wed, 4 Mar 2015 12:14:23 -0500 Subject: [PATCH 03188/11651] staging: unisys: remove ASSERT() macro Remove the ASSERT macro from timskmod.h, and replace its single use with WARN_ON() instead. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/timskmod.h | 9 --------- drivers/staging/unisys/visorutil/periodic_work.c | 2 +- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/drivers/staging/unisys/include/timskmod.h b/drivers/staging/unisys/include/timskmod.h index ff0fc167413c..667eae6b9477 100644 --- a/drivers/staging/unisys/include/timskmod.h +++ b/drivers/staging/unisys/include/timskmod.h @@ -68,15 +68,6 @@ #define HOSTADDRESS unsigned long long #endif -/** Try to evaulate the provided expression, and do a RETINT(x) iff - * the expression evaluates to < 0. - */ -#define ASSERT(cond) \ - do { if (!(cond)) \ - HUHDRV("ASSERT failed - %s", \ - __stringify(cond)); \ - } while (0) - #define sizeofmember(TYPE, MEMBER) (sizeof(((TYPE *)0)->MEMBER)) /** "Covered quotient" function */ #define COVQ(v, d) (((v) + (d) - 1) / (d)) diff --git a/drivers/staging/unisys/visorutil/periodic_work.c b/drivers/staging/unisys/visorutil/periodic_work.c index 0908bf929401..411fd1ea0784 100644 --- a/drivers/staging/unisys/visorutil/periodic_work.c +++ b/drivers/staging/unisys/visorutil/periodic_work.c @@ -182,7 +182,7 @@ BOOL visor_periodic_work_stop(struct periodic_work *pw) /* We get here if the delayed work was pending as * delayed work, but was NOT run. */ - ASSERT(pw->is_scheduled); + WARN_ON(!pw->is_scheduled); pw->is_scheduled = FALSE; } else { /* If we get here, either the delayed work: -- GitLab From 61620a1b187f645a13e77763b367e52ac129f411 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Wed, 4 Mar 2015 12:14:24 -0500 Subject: [PATCH 03189/11651] staging: unisys: remove LOGVER macro Remove the LOGVER macro from the drivers entirely. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/uniklog.h | 28 ------------------------ drivers/staging/unisys/virthba/virthba.c | 4 ---- 2 files changed, 32 deletions(-) diff --git a/drivers/staging/unisys/include/uniklog.h b/drivers/staging/unisys/include/uniklog.h index e3c374cfe26e..799c5710850a 100644 --- a/drivers/staging/unisys/include/uniklog.h +++ b/drivers/staging/unisys/include/uniklog.h @@ -25,34 +25,6 @@ #include -/* - * # LOGVER - * - * \brief Log verbose message - logs a message at the LOG_DEBUG level, - * which can be disabled at runtime - * - * \param devname the device name of the device reporting this message, or - * NULL if this message is NOT device-related. - * \param fmt printf()-style format string containing the message to log. - * \param args Optional arguments to be formatted and inserted into the format - * \param string. - * \return nothing - * - * Logs the specified message at the LOG_DEBUG level. Note also that - * LOG_DEBUG messages can be enabled/disabled at runtime as well. - */ -#define LOGVER(fmt, args...) pr_debug(fmt, ## args) -#define LOGVERDEV(devname, fmt, args...) \ - pr_debug("%s " fmt, devname, ## args) -#define LOGVERNAME(vnic, fmt, args...) \ - do { \ - if (vnic != NULL) { \ - pr_debug("%s " fmt, vnic->name, ## args); \ - } else { \ - pr_debug(fmt, ## args); \ - } \ - } while (0) - /* * # LOGERR * diff --git a/drivers/staging/unisys/virthba/virthba.c b/drivers/staging/unisys/virthba/virthba.c index 5ec2423a4138..5445863c2bab 100644 --- a/drivers/staging/unisys/virthba/virthba.c +++ b/drivers/staging/unisys/virthba/virthba.c @@ -465,10 +465,6 @@ virthba_probe(struct virtpci_dev *virtpcidev, const struct pci_device_id *id) struct signal_queue_header __iomem *pqhdr; u64 mask; - LOGVER("entering virthba_probe...\n"); - LOGVER("virtpcidev bus_no<<%d>>devNo<<%d>>", virtpcidev->bus_no, - virtpcidev->device_no); - POSTCODE_LINUX_2(VHBA_PROBE_ENTRY_PC, POSTCODE_SEVERITY_INFO); /* call scsi_host_alloc to register a scsi host adapter * instance - this virthba that has just been created is an -- GitLab From 0aca78449b58603586df83cca1e9eaba1acc1cfd Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Wed, 4 Mar 2015 12:14:25 -0500 Subject: [PATCH 03190/11651] staging: unisys: remove ERRDEV macros Remove the LOGERR, LOGERRDEV, LOGERRDEVX, LOGERRNAME, LOGORDUMPERR macros from all the drivers. In one case the removal of the ERRDRV() changed things such that a macro which returned a value was needed, but the return value was no longer being used. In this case the macro was replaced with the contents of the macro, but with the truth calculation removed so that it would not generate a warning. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/timskmod.h | 3 - drivers/staging/unisys/include/uisutils.h | 2 - drivers/staging/unisys/include/uniklog.h | 38 ---- drivers/staging/unisys/uislib/uislib.c | 156 +++------------- drivers/staging/unisys/uislib/uisqueue.c | 6 +- drivers/staging/unisys/uislib/uisutils.c | 2 - drivers/staging/unisys/virthba/virthba.c | 95 +--------- drivers/staging/unisys/virtpci/virtpci.c | 113 ++++-------- .../unisys/visorchannel/visorchannel_funcs.c | 66 +++---- drivers/staging/unisys/visorchipset/file.c | 22 +-- drivers/staging/unisys/visorchipset/parser.c | 66 ++----- .../unisys/visorchipset/visorchipset_main.c | 167 ++++-------------- drivers/staging/unisys/visorutil/charqueue.c | 5 +- drivers/staging/unisys/visorutil/easyproc.c | 26 +-- .../unisys/visorutil/memregion_direct.c | 36 ++-- .../staging/unisys/visorutil/periodic_work.c | 4 - .../staging/unisys/visorutil/procobjecttree.c | 25 +-- 17 files changed, 154 insertions(+), 678 deletions(-) diff --git a/drivers/staging/unisys/include/timskmod.h b/drivers/staging/unisys/include/timskmod.h index 667eae6b9477..5a933d7bf39f 100644 --- a/drivers/staging/unisys/include/timskmod.h +++ b/drivers/staging/unisys/include/timskmod.h @@ -78,9 +78,6 @@ (void *)(p2) = SWAPPOINTERS_TEMP; \ } while (0) -#define TBDDRV(fmt, args...) LOGERR(fmt, ## args) -#define HUHDRV(fmt, args...) LOGERR(fmt, ## args) -#define ERRDRV(fmt, args...) LOGERR(fmt, ## args) #define WARNDRV(fmt, args...) LOGWRN(fmt, ## args) #define SECUREDRV(fmt, args...) LOGWRN(fmt, ## args) diff --git a/drivers/staging/unisys/include/uisutils.h b/drivers/staging/unisys/include/uisutils.h index e2dfb2e784de..c7d0ba8aafd8 100644 --- a/drivers/staging/unisys/include/uisutils.h +++ b/drivers/staging/unisys/include/uisutils.h @@ -184,10 +184,8 @@ wait_for_valid_guid(uuid_le __iomem *guid) (void __iomem *)guid, sizeof(uuid_le)); if (uuid_le_cmp(tmpguid, NULL_UUID_LE) != 0) break; - LOGERR("Waiting for non-0 GUID (why???)...\n"); UIS_THREAD_WAIT_SEC(5); } - LOGERR("OK... GUID is non-0 now\n"); } static inline unsigned int diff --git a/drivers/staging/unisys/include/uniklog.h b/drivers/staging/unisys/include/uniklog.h index 799c5710850a..cca662a3f3e4 100644 --- a/drivers/staging/unisys/include/uniklog.h +++ b/drivers/staging/unisys/include/uniklog.h @@ -25,44 +25,6 @@ #include -/* - * # LOGERR - * - * \brief Log error message - logs a message at the LOG_ERR level, - * including source line number information - * - * \param devname the device name of the device reporting this message, or - * NULL if this message is NOT device-related. - * \param fmt printf()-style format string containing the message to log. - * \param args Optional arguments to be formatted and inserted into the format - * \param string. - * \return nothing - * - * Logs the specified error message at the LOG_ERR level. It will also - * include the file, line number, and function name of where the error - * originated in the log message. - */ -#define LOGERR(fmt, args...) pr_err(fmt, ## args) -#define LOGERRDEV(devname, fmt, args...) \ - pr_err("%s " fmt, devname, ## args) -#define LOGERRDEVX(devno, fmt, args...) \ - pr_err("dev%d " fmt, devno, ## args) -#define LOGERRNAME(vnic, fmt, args...) \ - do { \ - if (vnic != NULL) { \ - pr_err("%s " fmt, vnic->name, ## args); \ - } else { \ - pr_err(fmt, ## args); \ - } \ - } while (0) -#define LOGORDUMPERR(seqfile, fmt, args...) do { \ - if (seqfile) { \ - seq_printf(seqfile, fmt, ## args); \ - } else { \ - LOGERR(fmt, ## args); \ - } \ - } while (0) - /* * # LOGWRN * diff --git a/drivers/staging/unisys/uislib/uislib.c b/drivers/staging/unisys/uislib/uislib.c index 93b471412bd5..9fe96e7d5693 100644 --- a/drivers/staging/unisys/uislib/uislib.c +++ b/drivers/staging/unisys/uislib/uislib.c @@ -132,14 +132,10 @@ static __iomem void *init_vbus_channel(u64 ch_addr, u32 ch_bytes) { void __iomem *ch = uislib_ioremap_cache(ch_addr, ch_bytes); - if (!ch) { - LOGERR("CONTROLVM_BUS_CREATE error: ioremap_cache of channelAddr:%Lx for channelBytes:%llu failed", - (unsigned long long)ch_addr, - (unsigned long long)ch_bytes); + if (!ch) return NULL; - } + if (!SPAR_VBUS_CHANNEL_OK_CLIENT(ch)) { - ERRDRV("%s channel cannot be used", __func__); uislib_iounmap(ch); return NULL; } @@ -154,8 +150,6 @@ create_bus(struct controlvm_message *msg, char *buf) size_t size; if (max_bus_count == bus_list_count) { - LOGERR("CONTROLVM_BUS_CREATE Failed: max buses:%d already created\n", - max_bus_count); POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, max_bus_count, POSTCODE_SEVERITY_ERR); return CONTROLVM_RESP_ERROR_MAX_BUSES; @@ -208,8 +202,6 @@ create_bus(struct controlvm_message *msg, char *buf) /* found a bus already in the list with same bus_no - * reject add */ - LOGERR("CONTROLVM_BUS_CREATE Failed: bus %d already exists.\n", - bus->bus_no); POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus->bus_no, POSTCODE_SEVERITY_ERR); kfree(bus); @@ -233,14 +225,12 @@ create_bus(struct controlvm_message *msg, char *buf) cmd.add_vbus.bus_uuid = msg->cmd.create_bus.bus_data_type_uuid; cmd.add_vbus.instance_uuid = msg->cmd.create_bus.bus_inst_uuid; if (!virt_control_chan_func) { - LOGERR("CONTROLVM_BUS_CREATE Failed: virtpci callback not registered."); POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus->bus_no, POSTCODE_SEVERITY_ERR); kfree(bus); return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE; } if (!virt_control_chan_func(&cmd)) { - LOGERR("CONTROLVM_BUS_CREATE Failed: virtpci GUEST_ADD_VBUS returned error."); POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus->bus_no, POSTCODE_SEVERITY_ERR); kfree(bus); @@ -286,8 +276,6 @@ destroy_bus(struct controlvm_message *msg, char *buf) } if (!bus) { - LOGERR("CONTROLVM_BUS_DESTROY Failed: failed to find bus %d.\n", - bus_no); read_unlock(&bus_list_lock); return CONTROLVM_RESP_ERROR_ALREADY_DONE; } @@ -295,8 +283,6 @@ destroy_bus(struct controlvm_message *msg, char *buf) /* verify that this bus has no devices. */ for (i = 0; i < bus->device_count; i++) { if (bus->device[i] != NULL) { - LOGERR("CONTROLVM_BUS_DESTROY Failed: device %i attached to bus %d.", - i, bus_no); read_unlock(&bus_list_lock); return CONTROLVM_RESP_ERROR_BUS_DEVICE_ATTACHED; } @@ -310,14 +296,11 @@ destroy_bus(struct controlvm_message *msg, char *buf) with this bus. */ cmd.msgtype = GUEST_DEL_VBUS; cmd.del_vbus.bus_no = bus_no; - if (!virt_control_chan_func) { - LOGERR("CONTROLVM_BUS_DESTROY Failed: virtpci callback not registered."); + if (!virt_control_chan_func) return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE; - } - if (!virt_control_chan_func(&cmd)) { - LOGERR("CONTROLVM_BUS_DESTROY Failed: virtpci GUEST_DEL_VBUS returned error."); + + if (!virt_control_chan_func(&cmd)) return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR; - } /* finally, remove the bus from the list */ remove: @@ -379,9 +362,6 @@ static int create_device(struct controlvm_message *msg, char *buf) */ min_size = req_handler->min_channel_bytes; if (min_size > msg->cmd.create_device.channel_bytes) { - LOGERR("CONTROLVM_DEVICE_CREATE Failed: channel size is too small, channel size:0x%lx, required size:0x%lx", - (ulong)msg->cmd.create_device.channel_bytes, - (ulong)min_size); POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no, POSTCODE_SEVERITY_ERR); result = CONTROLVM_RESP_ERROR_CHANNEL_SIZE_TOO_SMALL; @@ -391,9 +371,6 @@ static int create_device(struct controlvm_message *msg, char *buf) uislib_ioremap_cache(dev->channel_addr, msg->cmd.create_device.channel_bytes); if (!dev->chanptr) { - LOGERR("CONTROLVM_DEVICE_CREATE Failed: ioremap_cache of channelAddr:%Lx for channelBytes:%llu failed", - dev->channel_addr, - msg->cmd.create_device.channel_bytes); result = CONTROLVM_RESP_ERROR_IOREMAP_FAILED; POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no, POSTCODE_SEVERITY_ERR); @@ -409,8 +386,6 @@ static int create_device(struct controlvm_message *msg, char *buf) continue; /* make sure the device number is valid */ if (dev_no >= bus->device_count) { - LOGERR("CONTROLVM_DEVICE_CREATE Failed: device (%d) >= deviceCount (%d).", - dev_no, bus->device_count); result = CONTROLVM_RESP_ERROR_MAX_DEVICES; POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no, POSTCODE_SEVERITY_ERR); @@ -419,8 +394,6 @@ static int create_device(struct controlvm_message *msg, char *buf) } /* make sure this device is not already set */ if (bus->device[dev_no]) { - LOGERR("CONTROLVM_DEVICE_CREATE Failed: device %d is already exists.", - dev_no); POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no, POSTCODE_SEVERITY_ERR); @@ -443,8 +416,6 @@ static int create_device(struct controlvm_message *msg, char *buf) wait_for_valid_guid(&((struct channel_header __iomem *) (dev->chanptr))->chtype); if (!SPAR_VHBA_CHANNEL_OK_CLIENT(dev->chanptr)) { - LOGERR("CONTROLVM_DEVICE_CREATE Failed:[CLIENT]VHBA dev %d chan invalid.", - dev_no); POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no, POSTCODE_SEVERITY_ERR); @@ -462,8 +433,6 @@ static int create_device(struct controlvm_message *msg, char *buf) wait_for_valid_guid(&((struct channel_header __iomem *) (dev->chanptr))->chtype); if (!SPAR_VNIC_CHANNEL_OK_CLIENT(dev->chanptr)) { - LOGERR("CONTROLVM_DEVICE_CREATE Failed: VNIC[CLIENT] dev %d chan invalid.", - dev_no); POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no, POSTCODE_SEVERITY_ERR); @@ -477,7 +446,6 @@ static int create_device(struct controlvm_message *msg, char *buf) cmd.add_vnic.instance_uuid = dev->instance_uuid; cmd.add_vhba.intr = dev->intr; } else { - LOGERR("CONTROLVM_DEVICE_CREATE Failed: unknown channelTypeGuid.\n"); POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no, POSTCODE_SEVERITY_ERR); result = CONTROLVM_RESP_ERROR_CHANNEL_TYPE_UNKNOWN; @@ -485,7 +453,6 @@ static int create_device(struct controlvm_message *msg, char *buf) } if (!virt_control_chan_func) { - LOGERR("CONTROLVM_DEVICE_CREATE Failed: virtpci callback not registered."); POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no, POSTCODE_SEVERITY_ERR); result = CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE; @@ -493,7 +460,6 @@ static int create_device(struct controlvm_message *msg, char *buf) } if (!virt_control_chan_func(&cmd)) { - LOGERR("CONTROLVM_DEVICE_CREATE Failed: virtpci GUEST_ADD_[VHBA||VNIC] returned error."); POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no, POSTCODE_SEVERITY_ERR); result = @@ -508,8 +474,6 @@ static int create_device(struct controlvm_message *msg, char *buf) } read_unlock(&bus_list_lock); - LOGERR("CONTROLVM_DEVICE_CREATE Failed: failed to find bus %d.", - bus_no); POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no, POSTCODE_SEVERITY_ERR); result = CONTROLVM_RESP_ERROR_BUS_INVALID; @@ -540,15 +504,11 @@ static int pause_device(struct controlvm_message *msg) if (bus->bus_no == bus_no) { /* make sure the device number is valid */ if (dev_no >= bus->device_count) { - LOGERR("CONTROLVM_DEVICE_CHANGESTATE:pause Failed: device(%d) >= deviceCount(%d).", - dev_no, bus->device_count); retval = CONTROLVM_RESP_ERROR_DEVICE_INVALID; } else { /* make sure this device exists */ dev = bus->device[dev_no]; if (!dev) { - LOGERR("CONTROLVM_DEVICE_CHANGESTATE:pause Failed: device %d does not exist.", - dev_no); retval = CONTROLVM_RESP_ERROR_ALREADY_DONE; } @@ -556,11 +516,9 @@ static int pause_device(struct controlvm_message *msg) break; } } - if (!bus) { - LOGERR("CONTROLVM_DEVICE_CHANGESTATE:pause Failed: bus %d does not exist", - bus_no); + if (!bus) retval = CONTROLVM_RESP_ERROR_BUS_INVALID; - } + read_unlock(&bus_list_lock); if (retval == CONTROLVM_RESP_SUCCESS) { /* the msg is bound for virtpci; send @@ -575,15 +533,12 @@ static int pause_device(struct controlvm_message *msg) cmd.msgtype = GUEST_PAUSE_VNIC; cmd.pause_vnic.chanptr = dev->chanptr; } else { - LOGERR("CONTROLVM_DEVICE_CHANGESTATE:pause Failed: unknown channelTypeGuid.\n"); return CONTROLVM_RESP_ERROR_CHANNEL_TYPE_UNKNOWN; } if (!virt_control_chan_func) { - LOGERR("CONTROLVM_DEVICE_CHANGESTATE Failed: virtpci callback not registered."); return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE; } if (!virt_control_chan_func(&cmd)) { - LOGERR("CONTROLVM_DEVICE_CHANGESTATE:pause Failed: virtpci GUEST_PAUSE_[VHBA||VNIC] returned error."); return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR; } @@ -607,15 +562,11 @@ static int resume_device(struct controlvm_message *msg) if (bus->bus_no == bus_no) { /* make sure the device number is valid */ if (dev_no >= bus->device_count) { - LOGERR("CONTROLVM_DEVICE_CHANGESTATE:resume Failed: device(%d) >= deviceCount(%d).", - dev_no, bus->device_count); retval = CONTROLVM_RESP_ERROR_DEVICE_INVALID; } else { /* make sure this device exists */ dev = bus->device[dev_no]; if (!dev) { - LOGERR("CONTROLVM_DEVICE_CHANGESTATE:resume Failed: device %d does not exist.", - dev_no); retval = CONTROLVM_RESP_ERROR_ALREADY_DONE; } @@ -624,11 +575,9 @@ static int resume_device(struct controlvm_message *msg) } } - if (!bus) { - LOGERR("CONTROLVM_DEVICE_CHANGESTATE:resume Failed: bus %d does not exist", - bus_no); + if (!bus) retval = CONTROLVM_RESP_ERROR_BUS_INVALID; - } + read_unlock(&bus_list_lock); /* the msg is bound for virtpci; send * guest_msgs struct to callback @@ -643,15 +592,12 @@ static int resume_device(struct controlvm_message *msg) cmd.msgtype = GUEST_RESUME_VNIC; cmd.resume_vnic.chanptr = dev->chanptr; } else { - LOGERR("CONTROLVM_DEVICE_CHANGESTATE:resume Failed: unknown channelTypeGuid.\n"); return CONTROLVM_RESP_ERROR_CHANNEL_TYPE_UNKNOWN; } if (!virt_control_chan_func) { - LOGERR("CONTROLVM_DEVICE_CHANGESTATE Failed: virtpci callback not registered."); return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE; } if (!virt_control_chan_func(&cmd)) { - LOGERR("CONTROLVM_DEVICE_CHANGESTATE:resume Failed: virtpci GUEST_RESUME_[VHBA||VNIC] returned error."); return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR; } @@ -675,15 +621,11 @@ static int destroy_device(struct controlvm_message *msg, char *buf) if (bus->bus_no == bus_no) { /* make sure the device number is valid */ if (dev_no >= bus->device_count) { - LOGERR("CONTROLVM_DEVICE_DESTROY Failed: device(%d) >= device_count(%d).", - dev_no, bus->device_count); retval = CONTROLVM_RESP_ERROR_DEVICE_INVALID; } else { /* make sure this device exists */ dev = bus->device[dev_no]; if (!dev) { - LOGERR("CONTROLVM_DEVICE_DESTROY Failed: device %d does not exist.", - dev_no); retval = CONTROLVM_RESP_ERROR_ALREADY_DONE; } @@ -692,11 +634,8 @@ static int destroy_device(struct controlvm_message *msg, char *buf) } } - if (!bus) { - LOGERR("CONTROLVM_DEVICE_DESTROY Failed: bus %d does not exist", - bus_no); + if (!bus) retval = CONTROLVM_RESP_ERROR_BUS_INVALID; - } read_unlock(&bus_list_lock); if (retval == CONTROLVM_RESP_SUCCESS) { /* the msg is bound for virtpci; send @@ -711,17 +650,14 @@ static int destroy_device(struct controlvm_message *msg, char *buf) cmd.msgtype = GUEST_DEL_VNIC; cmd.del_vnic.chanptr = dev->chanptr; } else { - LOGERR("CONTROLVM_DEVICE_DESTROY Failed: unknown channelTypeGuid.\n"); return CONTROLVM_RESP_ERROR_CHANNEL_TYPE_UNKNOWN; } if (!virt_control_chan_func) { - LOGERR("CONTROLVM_DEVICE_DESTROY Failed: virtpci callback not registered."); return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE; } if (!virt_control_chan_func(&cmd)) { - LOGERR("CONTROLVM_DEVICE_DESTROY Failed: virtpci GUEST_DEL_[VHBA||VNIC] returned error."); return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR; } @@ -774,10 +710,8 @@ static int delete_bus_glue(u32 bus_no) init_msg_header(&msg, CONTROLVM_BUS_DESTROY, 0, 0); msg.cmd.destroy_bus.bus_no = bus_no; - if (destroy_bus(&msg, NULL) != CONTROLVM_RESP_SUCCESS) { - LOGERR("destroy_bus failed. bus_no=0x%x\n", bus_no); + if (destroy_bus(&msg, NULL) != CONTROLVM_RESP_SUCCESS) return 0; - } return 1; } @@ -788,11 +722,8 @@ static int delete_device_glue(u32 bus_no, u32 dev_no) init_msg_header(&msg, CONTROLVM_DEVICE_DESTROY, 0, 0); msg.cmd.destroy_device.bus_no = bus_no; msg.cmd.destroy_device.dev_no = dev_no; - if (destroy_device(&msg, NULL) != CONTROLVM_RESP_SUCCESS) { - LOGERR("destroy_device failed. bus_no=0x%x dev_no=0x%x\n", - bus_no, dev_no); + if (destroy_device(&msg, NULL) != CONTROLVM_RESP_SUCCESS) return 0; - } return 1; } @@ -817,10 +748,8 @@ uislib_client_inject_add_bus(u32 bus_no, uuid_le inst_uuid, */ msg.cmd.init_chipset.bus_count = 23; msg.cmd.init_chipset.switch_count = 0; - if (init_chipset(&msg, NULL) != CONTROLVM_RESP_SUCCESS) { - LOGERR("init_chipset failed.\n"); + if (init_chipset(&msg, NULL) != CONTROLVM_RESP_SUCCESS) return 0; - } POSTCODE_LINUX_3(CHIPSET_INIT_EXIT_PC, bus_no, POSTCODE_SEVERITY_INFO); } @@ -834,7 +763,6 @@ uislib_client_inject_add_bus(u32 bus_no, uuid_le inst_uuid, msg.cmd.create_bus.channel_addr = channel_addr; msg.cmd.create_bus.channel_bytes = n_channel_bytes; if (create_bus(&msg, NULL) != CONTROLVM_RESP_SUCCESS) { - LOGERR("create_bus failed.\n"); POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus_no, POSTCODE_SEVERITY_ERR); return 0; @@ -863,11 +791,8 @@ uislib_client_inject_pause_vhba(u32 bus_no, u32 dev_no) msg.cmd.device_change_state.dev_no = dev_no; msg.cmd.device_change_state.state = segment_state_standby; rc = pause_device(&msg); - if (rc != CONTROLVM_RESP_SUCCESS) { - LOGERR("VHBA pause_device failed. busNo=0x%x devNo=0x%x\n", - bus_no, dev_no); + if (rc != CONTROLVM_RESP_SUCCESS) return rc; - } return 0; } EXPORT_SYMBOL_GPL(uislib_client_inject_pause_vhba); @@ -883,11 +808,8 @@ uislib_client_inject_resume_vhba(u32 bus_no, u32 dev_no) msg.cmd.device_change_state.dev_no = dev_no; msg.cmd.device_change_state.state = segment_state_running; rc = resume_device(&msg); - if (rc != CONTROLVM_RESP_SUCCESS) { - LOGERR("VHBA resume_device failed. busNo=0x%x devNo=0x%x\n", - bus_no, dev_no); + if (rc != CONTROLVM_RESP_SUCCESS) return rc; - } return 0; } EXPORT_SYMBOL_GPL(uislib_client_inject_resume_vhba); @@ -923,8 +845,6 @@ uislib_client_inject_add_vhba(u32 bus_no, u32 dev_no, sizeof(struct irq_info)); msg.cmd.create_device.channel_addr = phys_chan_addr; if (chan_bytes < MIN_IO_CHANNEL_SIZE) { - LOGERR("wrong channel size.chan_bytes = 0x%x IO_CHANNEL_SIZE= 0x%x\n", - chan_bytes, (unsigned int)MIN_IO_CHANNEL_SIZE); POSTCODE_LINUX_4(VHBA_CREATE_FAILURE_PC, chan_bytes, MIN_IO_CHANNEL_SIZE, POSTCODE_SEVERITY_ERR); return 0; @@ -932,7 +852,6 @@ uislib_client_inject_add_vhba(u32 bus_no, u32 dev_no, msg.cmd.create_device.channel_bytes = chan_bytes; msg.cmd.create_device.data_type_uuid = spar_vhba_channel_protocol_uuid; if (create_device(&msg, NULL) != CONTROLVM_RESP_SUCCESS) { - LOGERR("VHBA create_device failed.\n"); POSTCODE_LINUX_4(VHBA_CREATE_FAILURE_PC, dev_no, bus_no, POSTCODE_SEVERITY_ERR); return 0; @@ -981,8 +900,6 @@ uislib_client_inject_add_vnic(u32 bus_no, u32 dev_no, sizeof(struct irq_info)); msg.cmd.create_device.channel_addr = phys_chan_addr; if (chan_bytes < MIN_IO_CHANNEL_SIZE) { - LOGERR("wrong channel size.chan_bytes = 0x%x IO_CHANNEL_SIZE= 0x%x\n", - chan_bytes, (unsigned int)MIN_IO_CHANNEL_SIZE); POSTCODE_LINUX_4(VNIC_CREATE_FAILURE_PC, chan_bytes, MIN_IO_CHANNEL_SIZE, POSTCODE_SEVERITY_ERR); return 0; @@ -990,7 +907,6 @@ uislib_client_inject_add_vnic(u32 bus_no, u32 dev_no, msg.cmd.create_device.channel_bytes = chan_bytes; msg.cmd.create_device.data_type_uuid = spar_vnic_channel_protocol_uuid; if (create_device(&msg, NULL) != CONTROLVM_RESP_SUCCESS) { - LOGERR("VNIC create_device failed.\n"); POSTCODE_LINUX_4(VNIC_CREATE_FAILURE_PC, dev_no, bus_no, POSTCODE_SEVERITY_ERR); return 0; @@ -1014,8 +930,6 @@ uislib_client_inject_pause_vnic(u32 bus_no, u32 dev_no) msg.cmd.device_change_state.state = segment_state_standby; rc = pause_device(&msg); if (rc != CONTROLVM_RESP_SUCCESS) { - LOGERR("VNIC pause_device failed. busNo=0x%x devNo=0x%x\n", - bus_no, dev_no); return -1; } return 0; @@ -1033,11 +947,8 @@ uislib_client_inject_resume_vnic(u32 bus_no, u32 dev_no) msg.cmd.device_change_state.dev_no = dev_no; msg.cmd.device_change_state.state = segment_state_running; rc = resume_device(&msg); - if (rc != CONTROLVM_RESP_SUCCESS) { - LOGERR("VNIC resume_device failed. busNo=0x%x devNo=0x%x\n", - bus_no, dev_no); + if (rc != CONTROLVM_RESP_SUCCESS) return -1; - } return 0; } EXPORT_SYMBOL_GPL(uislib_client_inject_resume_vnic); @@ -1059,11 +970,8 @@ uislib_cache_alloc(struct kmem_cache *cur_pool, char *fn, int ln) */ void *p = kmem_cache_alloc(cur_pool, GFP_ATOMIC | __GFP_NORETRY); - if (p == NULL) { - LOGERR("uislib_malloc failed to alloc uiscmdrsp @%s:%d", - fn, ln); + if (p == NULL) return NULL; - } return p; } EXPORT_SYMBOL_GPL(uislib_cache_alloc); @@ -1071,10 +979,8 @@ EXPORT_SYMBOL_GPL(uislib_cache_alloc); void uislib_cache_free(struct kmem_cache *cur_pool, void *p, char *fn, int ln) { - if (p == NULL) { - LOGERR("uislib_free NULL pointer @%s:%d", fn, ln); + if (p == NULL) return; - } kmem_cache_free(cur_pool, p); } EXPORT_SYMBOL_GPL(uislib_cache_free); @@ -1155,10 +1061,8 @@ static ssize_t info_debugfs_read(struct file *file, char __user *buf, if (debug_buf == NULL) { debug_buf = vmalloc(PROC_READ_BUFFER_SIZE); - if (debug_buf == NULL) { - LOGERR("failed to allocate buffer to provide proc data.\n"); + if (debug_buf == NULL) return -ENOMEM; - } } temp = debug_buf; @@ -1184,17 +1088,9 @@ static struct device_info *find_dev(u32 bus_no, u32 dev_no) for (bus = bus_list; bus; bus = bus->next) { if (bus->bus_no == bus_no) { /* make sure the device number is valid */ - if (dev_no >= bus->device_count) { - LOGERR("%s bad bus_no, dev_no=%d,%d", - __func__, - (int)bus_no, (int)dev_no); + if (dev_no >= bus->device_count) break; - } dev = bus->device[dev_no]; - if (!dev) - LOGERR("%s bad bus_no, dev_no=%d,%d", - __func__, - (int)bus_no, (int)dev_no); break; } } @@ -1331,7 +1227,6 @@ initialize_incoming_thread(void) return TRUE; if (!uisthread_start(&incoming_ti, &process_incoming, NULL, "dev_incoming")) { - LOGERR("uisthread_start initialize_incoming_thread ****FAILED"); return FALSE; } incoming_started = TRUE; @@ -1352,11 +1247,9 @@ uislib_enable_channel_interrupts(u32 bus_no, u32 dev_no, struct device_info *dev; dev = find_dev(bus_no, dev_no); - if (!dev) { - LOGERR("%s busNo=%d, devNo=%d", __func__, (int)(bus_no), - (int)(dev_no)); + if (!dev) return; - } + down(&poll_dev_lock); initialize_incoming_thread(); dev->interrupt = interrupt; @@ -1377,11 +1270,8 @@ uislib_disable_channel_interrupts(u32 bus_no, u32 dev_no) struct device_info *dev; dev = find_dev(bus_no, dev_no); - if (!dev) { - LOGERR("%s busNo=%d, devNo=%d", __func__, (int)(bus_no), - (int)(dev_no)); + if (!dev) return; - } down(&poll_dev_lock); list_del(&dev->list_polling_device_channels); dev->polling = FALSE; diff --git a/drivers/staging/unisys/uislib/uisqueue.c b/drivers/staging/unisys/uislib/uisqueue.c index 71bb7b608e9a..d46dd7428a30 100644 --- a/drivers/staging/unisys/uislib/uisqueue.c +++ b/drivers/staging/unisys/uislib/uisqueue.c @@ -295,12 +295,10 @@ uisqueue_put_cmdrsp_with_lock_client(struct uisqueue_info *queueinfo, while (!do_locked_client_insert(queueinfo, whichqueue, cmdrsp, (spinlock_t *)insertlock, channel_id)) { - if (oktowait != OK_TO_WAIT) { - LOGERR("****FAILED visor_signal_insert failed; cannot wait; insert aborted\n"); + if (oktowait != OK_TO_WAIT) return 0; /* failed to queue */ - } + /* try again */ - LOGERR("****FAILED visor_signal_insert failed; waiting to try again\n"); set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(msecs_to_jiffies(10)); } diff --git a/drivers/staging/unisys/uislib/uisutils.c b/drivers/staging/unisys/uislib/uisutils.c index 7d7f408505f2..9f3f0ab6ca49 100644 --- a/drivers/staging/unisys/uislib/uisutils.c +++ b/drivers/staging/unisys/uislib/uisutils.c @@ -60,7 +60,6 @@ uisutil_add_proc_line_ex(int *total, char **buffer, int *buffer_remaining, *buffer += *buffer_remaining; *total += *buffer_remaining; *buffer_remaining = 0; - LOGERR("bytes remaining is too small!\n"); return -1; } *buffer_remaining -= len; @@ -88,7 +87,6 @@ uisctrl_register_req_handler(int type, void *fptr, break; default: - LOGERR("invalid type %d.\n", type); return 0; } if (chipset_driver_info) diff --git a/drivers/staging/unisys/virthba/virthba.c b/drivers/staging/unisys/virthba/virthba.c index 5445863c2bab..23874de4e354 100644 --- a/drivers/staging/unisys/virthba/virthba.c +++ b/drivers/staging/unisys/virthba/virthba.c @@ -262,8 +262,6 @@ add_scsipending_entry(struct virthba_info *vhbainfo, char cmdtype, void *new) while (vhbainfo->pending[insert_location].sent != NULL) { insert_location = (insert_location + 1) % MAX_PENDING_REQUESTS; if (insert_location == (int)vhbainfo->nextinsert) { - LOGERR("Queue should be full. insert_location<<%d>> Unable to find open slot for pending commands.\n", - insert_location); spin_unlock_irqrestore(&vhbainfo->privlock, flags); return -1; } @@ -284,7 +282,6 @@ add_scsipending_entry_with_wait(struct virthba_info *vhbainfo, char cmdtype, int insert_location = add_scsipending_entry(vhbainfo, cmdtype, new); while (insert_location == -1) { - LOGERR("Failed to find empty queue slot. Waiting to try again\n"); set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(msecs_to_jiffies(10)); insert_location = add_scsipending_entry(vhbainfo, cmdtype, new); @@ -299,16 +296,8 @@ del_scsipending_entry(struct virthba_info *vhbainfo, uintptr_t del) unsigned long flags; void *sent = NULL; - if (del >= MAX_PENDING_REQUESTS) { - LOGERR("Invalid queue position <<%lu>> given to delete. MAX_PENDING_REQUESTS <<%d>>\n", - (unsigned long)del, MAX_PENDING_REQUESTS); - } else { + if (del < MAX_PENDING_REQUESTS) { spin_lock_irqsave(&vhbainfo->privlock, flags); - - if (vhbainfo->pending[del].sent == NULL) - LOGERR("Deleting already cleared queue entry at <<%lu>>.\n", - (unsigned long)del); - sent = vhbainfo->pending[del].sent; vhbainfo->pending[del].cmdtype = 0; @@ -355,13 +344,7 @@ send_disk_add_remove(struct diskaddremove *dar) error = scsi_add_device(dar->shost, dar->channel, dar->id, dar->lun); - if (error) - LOGERR("Failed scsi_add_device: host_no=%d[chan=%d:id=%d:lun=%d]\n", - dar->shost->host_no, dar->channel, dar->id, - dar->lun); - } else - LOGERR("Failed scsi_device_lookup:[chan=%d:id=%d:lun=%d]\n", - dar->channel, dar->id, dar->lun); + } kfree(dar); } @@ -406,10 +389,6 @@ process_disk_notify(struct Scsi_Host *shost, struct uiscmdrsp *cmdrsp) dar->id = cmdrsp->disknotify.id; dar->lun = cmdrsp->disknotify.lun; QUEUE_DISKADDREMOVE(dar); - } else { - LOGERR("kmalloc failed for dar. host_no=%d[chan=%d:id=%d:lun=%d]\n", - shost->host_no, cmdrsp->disknotify.channel, - cmdrsp->disknotify.id, cmdrsp->disknotify.lun); } } @@ -510,7 +489,6 @@ virthba_probe(struct virtpci_dev *virtpcidev, const struct pci_device_id *id) */ error = scsi_add_host(scsihost, &virtpcidev->generic_dev); if (error) { - LOGERR("scsi_add_host ****FAILED 0x%x TBD - RECOVER\n", error); POSTCODE_LINUX_2(VHBA_PROBE_FAILURE_PC, POSTCODE_SEVERITY_ERR); /* decr refcount on scsihost which was incremented by * scsi_add_host so the scsi_host gets deleted @@ -563,7 +541,6 @@ virthba_probe(struct virtpci_dev *virtpcidev, const struct pci_device_id *id) if (!uisthread_start(&virthbainfo->chinfo.threadinfo, process_incoming_rsps, virthbainfo, "vhba_incoming")) { - LOGERR("uisthread_start rsp ****FAILED\n"); /* decr refcount on scsihost which was incremented by * scsi_add_host so the scsi_host gets deleted */ @@ -576,15 +553,11 @@ virthba_probe(struct virtpci_dev *virtpcidev, const struct pci_device_id *id) rsp = request_irq(virthbainfo->interrupt_vector, handler, IRQF_SHARED, scsihost->hostt->name, virthbainfo); if (rsp != 0) { - LOGERR("request_irq(%d) uislib_virthba_ISR request failed with rsp=%d\n", - virthbainfo->interrupt_vector, rsp); virthbainfo->interrupt_vector = -1; POSTCODE_LINUX_2(VHBA_PROBE_FAILURE_PC, POSTCODE_SEVERITY_ERR); } else { u64 __iomem *Features_addr = &virthbainfo->chinfo.queueinfo->chan->features; - LOGERR("request_irq(%d) uislib_virthba_ISR request succeeded\n", - virthbainfo->interrupt_vector); mask = ~(ULTRA_IO_CHANNEL_IS_POLLING | ULTRA_IO_DRIVER_DISABLES_INTS); uisqueue_interlocked_and(Features_addr, mask); @@ -807,7 +780,6 @@ static int virthba_host_reset_handler(struct scsi_cmnd *scsicmd) { /* issue TASK_MGMT_TARGET_RESET for each target on each bus for host */ - LOGERR("virthba_host_reset_handler Not yet implemented\n"); return SUCCESS; } @@ -866,7 +838,6 @@ virthba_queue_command_lck(struct scsi_cmnd *scsicmd, if (insert_location != -1) { cmdrsp->scsi.scsicmd = (void *)(uintptr_t)insert_location; } else { - LOGERR("Queue is full. Returning busy.\n"); kfree(cmdrsp); return SCSI_MLQUEUE_DEVICE_BUSY; } @@ -887,8 +858,6 @@ virthba_queue_command_lck(struct scsi_cmnd *scsicmd, max_buff_len = cmdrsp->scsi.bufflen; if (scsi_sg_count(scsicmd) > MAX_PHYS_INFO) { - LOGERR("scsicmd use_sg:%d greater than MAX:%d\n", - scsi_sg_count(scsicmd), MAX_PHYS_INFO); del_scsipending_entry(virthbainfo, (uintptr_t)insert_location); kfree(cmdrsp); return 1; /* reject the command */ @@ -901,7 +870,6 @@ virthba_queue_command_lck(struct scsi_cmnd *scsicmd, /* convert buffer to phys information */ if (scsi_sg_count(scsicmd) == 0) { if (scsi_bufflen(scsicmd) > 0) { - LOGERR("**** FAILED No scatter list for bufflen > 0\n"); BUG_ON(scsi_sg_count(scsicmd) == 0); } } else { @@ -914,15 +882,6 @@ virthba_queue_command_lck(struct scsi_cmnd *scsicmd, } if (sg_failed) { - LOGERR("Start sg_list dump (entries %d, bufflen %d)...\n", - scsi_sg_count(scsicmd), cmdrsp->scsi.bufflen); - for_each_sg(sgl, sg, scsi_sg_count(scsicmd), i) { - LOGERR(" Entry(%d): page->[0x%p], phys->[0x%Lx], off(%d), len(%d)\n", - i, sg_page(sg), - (unsigned long long)sg_phys(sg), - sg->offset, sg->length); - } - LOGERR("Done sg_list dump.\n"); /* BUG(); ***** For now, let it fail in uissd * if it is a problem, as it might just * work @@ -941,7 +900,6 @@ virthba_queue_command_lck(struct scsi_cmnd *scsicmd, (u64)NULL, DONT_WAIT, "vhba"); if (i == 0) { /* queue must be full - and we said don't wait - return busy */ - LOGERR("uisqueue_put_cmdrsp_with_lock ****FAILED\n"); kfree(cmdrsp); del_scsipending_entry(virthbainfo, (uintptr_t)insert_location); return SCSI_MLQUEUE_DEVICE_BUSY; @@ -966,10 +924,9 @@ virthba_slave_alloc(struct scsi_device *scsidev) struct Scsi_Host *scsihost = (struct Scsi_Host *)scsidev->host; virthbainfo = (struct virthba_info *)scsihost->hostdata; - if (!virthbainfo) { - LOGERR("Could not find virthba_info for scsihost\n"); + if (!virthbainfo) return 0; /* even though we errored, treat as success */ - } + for (vdisk = &virthbainfo->head; vdisk->next; vdisk = vdisk->next) { if (vdisk->next->valid && (vdisk->next->channel == scsidev->channel) && @@ -1006,8 +963,6 @@ virthba_slave_destroy(struct scsi_device *scsidev) struct Scsi_Host *scsihost = (struct Scsi_Host *)scsidev->host; virthbainfo = (struct virthba_info *)scsihost->hostdata; - if (!virthbainfo) - LOGERR("Could not find virthba_info for scsihost\n"); for (vdisk = &virthbainfo->head; vdisk->next; vdisk = vdisk->next) { if (vdisk->next->valid && (vdisk->next->channel == scsidev->channel) && @@ -1052,19 +1007,6 @@ do_scsi_linuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd) if (atomic_read(&vdisk->error_count) < VIRTHBA_ERROR_COUNT) { atomic_inc(&vdisk->error_count); - LOGERR("SCSICMD ****FAILED scsicmd:0x%p op:0x%x <%d:%d:%d:%llu> 0x%x-0x%x-0x%x-0x%x-0x%x.\n", - scsicmd, cmdrsp->scsi.cmnd[0], - scsidev->host->host_no, scsidev->id, - scsidev->channel, scsidev->lun, - cmdrsp->scsi.linuxstat, sd->valid, sd->sense_key, - sd->additional_sense_code, - sd->additional_sense_code_qualifier); - if (atomic_read(&vdisk->error_count) == - VIRTHBA_ERROR_COUNT) { - LOGERR("Throtling SCSICMD errors disk <%d:%d:%d:%llu>\n", - scsidev->host->host_no, scsidev->id, - scsidev->channel, scsidev->lun); - } atomic_set(&vdisk->ios_threshold, IOS_ERROR_THRESHOLD); } } @@ -1100,7 +1042,6 @@ do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd) if (scsi_sg_count(scsicmd) == 0) { if (scsi_bufflen(scsicmd) > 0) { - LOGERR("**** FAILED No scatter list for bufflen > 0\n"); BUG_ON(scsi_sg_count(scsicmd) == 0); } @@ -1129,7 +1070,6 @@ do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd) if (atomic_read(&vdisk->ios_threshold) > 0) { atomic_dec(&vdisk->ios_threshold); if (atomic_read(&vdisk->ios_threshold) == 0) { - LOGERR("Resetting error count for disk\n"); atomic_set(&vdisk->error_count, 0); } } @@ -1223,8 +1163,7 @@ drain_queue(struct virthba_info *virthbainfo, struct chaninfo *dc, cmdrsp->vdiskmgmt.scsicmd)) break; complete_vdiskmgmt_command(cmdrsp); - } else - LOGERR("Invalid cmdtype %d\n", cmdrsp->cmdtype); + } /* cmdrsp is now available for reuse */ } } @@ -1338,19 +1277,13 @@ static ssize_t enable_ints_write(struct file *file, const char __user *buffer, return -EINVAL; buf[count] = '\0'; - if (copy_from_user(buf, buffer, count)) { - LOGERR("copy_from_user failed. buf<<%.*s>> count<<%lu>>\n", - (int)count, buf, count); + if (copy_from_user(buf, buffer, count)) return -EFAULT; - } i = kstrtoint(buf, 10, &new_value); - if (i != 0) { - LOGERR("Failed to scan value for enable_ints, buf<<%.*s>>", - (int)count, buf); + if (i != 0) return -EFAULT; - } /* set all counts to new_value usually 0 */ for (i = 0; i < VIRTHBASOPENMAX; i++) { @@ -1389,10 +1322,8 @@ virthba_serverup(struct virtpci_dev *virtpcidev) if (!virthbainfo->serverdown) return 1; - if (virthbainfo->serverchangingstate) { - LOGERR("Server already processing change state message\n"); + if (virthbainfo->serverchangingstate) return 0; - } virthbainfo->serverchangingstate = true; /* Must transition channel to ATTACHED state BEFORE we @@ -1406,7 +1337,6 @@ virthba_serverup(struct virtpci_dev *virtpcidev) if (!uisthread_start(&virthbainfo->chinfo.threadinfo, process_incoming_rsps, virthbainfo, "vhba_incoming")) { - LOGERR("uisthread_start rsp ****FAILED\n"); return 0; } virthbainfo->serverdown = false; @@ -1460,9 +1390,7 @@ virthba_serverdown_complete(struct work_struct *work) cmdrsp->vdiskmgmt.notify); break; default: - if (pendingdel->sent != NULL) - LOGERR("Unknown command type: 0x%x. Only freeing list structure.\n", - pendingdel->cmdtype); + break; } pendingdel->cmdtype = 0; pendingdel->sent = NULL; @@ -1493,10 +1421,7 @@ virthba_serverdown(struct virtpci_dev *virtpcidev, u32 state) queue_work(virthba_serverdown_workqueue, &virthbainfo->serverdown_completion); } else if (virthbainfo->serverchangingstate) { - LOGERR("Server already processing change state message\n"); stat = 0; - } else { - LOGERR("Server already down, but another server down message received."); } return stat; @@ -1544,7 +1469,6 @@ virthba_mod_init(void) error = virtpci_register_driver(&virthba_driver); if (error < 0) { - LOGERR("register ****FAILED 0x%x\n", error); POSTCODE_LINUX_3(VHBA_CREATE_FAILURE_PC, error, POSTCODE_SEVERITY_ERR); } else { @@ -1568,7 +1492,6 @@ virthba_mod_init(void) virthba_serverdown_workqueue = create_singlethread_workqueue("virthba_serverdown"); if (virthba_serverdown_workqueue == NULL) { - LOGERR("**** FAILED virthba_serverdown_workqueue creation\n"); POSTCODE_LINUX_2(VHBA_CREATE_FAILURE_PC, POSTCODE_SEVERITY_ERR); error = -1; diff --git a/drivers/staging/unisys/virtpci/virtpci.c b/drivers/staging/unisys/virtpci/virtpci.c index d87ebcc615d4..87336b6591ba 100644 --- a/drivers/staging/unisys/virtpci/virtpci.c +++ b/drivers/staging/unisys/virtpci/virtpci.c @@ -187,13 +187,11 @@ static int write_vbus_chp_info(struct spar_vbus_channel_protocol *chan, { int off; - if (!chan) { - LOGERR("vbus channel not present"); + if (!chan) return -1; - } + off = sizeof(struct channel_header) + chan->hdr_info.chp_info_offset; if (chan->hdr_info.chp_info_offset == 0) { - LOGERR("vbus channel not used, because chp_info_offset == 0"); return -1; } memcpy(((u8 *)(chan)) + off, info, sizeof(*info)); @@ -206,15 +204,12 @@ static int write_vbus_bus_info(struct spar_vbus_channel_protocol *chan, { int off; - if (!chan) { - LOGERR("vbus channel not present"); + if (!chan) return -1; - } + off = sizeof(struct channel_header) + chan->hdr_info.bus_info_offset; - if (chan->hdr_info.bus_info_offset == 0) { - LOGERR("vbus channel not used, because bus_info_offset == 0"); + if (chan->hdr_info.bus_info_offset == 0) return -1; - } memcpy(((u8 *)(chan)) + off, info, sizeof(*info)); return 0; } @@ -228,18 +223,16 @@ write_vbus_dev_info(struct spar_vbus_channel_protocol *chan, { int off; - if (!chan) { - LOGERR("vbus channel not present"); + if (!chan) return -1; - } + off = (sizeof(struct channel_header) + chan->hdr_info.dev_info_offset) + (chan->hdr_info.device_info_struct_bytes * devix); - if (chan->hdr_info.dev_info_offset == 0) { - LOGERR("vbus channel not used, because dev_info_offset == 0"); + if (chan->hdr_info.dev_info_offset == 0) return -1; - } + memcpy(((u8 *)(chan)) + off, info, sizeof(*info)); return 0; } @@ -271,7 +264,6 @@ static int add_vbus(struct add_vbus_guestpart *addparams) */ ret = device_register(vbus); if (ret) { - LOGERR("device_register FAILED:%d\n", ret); POSTCODE_LINUX_2(VPCI_CREATE_FAILURE_PC, POSTCODE_SEVERITY_ERR); return 0; } @@ -310,7 +302,6 @@ static int add_vhba(struct add_virt_guestpart *addparams) POSTCODE_LINUX_2(VPCI_CREATE_ENTRY_PC, POSTCODE_SEVERITY_INFO); if (!WAIT_FOR_IO_CHANNEL ((struct spar_io_channel_protocol __iomem *)addparams->chanptr)) { - LOGERR("Timed out. Channel not ready\n"); POSTCODE_LINUX_2(VPCI_CREATE_FAILURE_PC, POSTCODE_SEVERITY_ERR); return 0; } @@ -321,10 +312,8 @@ static int add_vhba(struct add_virt_guestpart *addparams) sprintf(busid, "vbus%d", addparams->bus_no); vbus = bus_find_device(&virtpci_bus_type, NULL, (void *)busid, match_busid); - if (!vbus) { - LOGERR("**** FAILED to find vbus %s\n", busid); + if (!vbus) return 0; - } i = virtpci_device_add(vbus, VIRTHBA_TYPE, addparams, &scsi, NULL); if (i) { @@ -367,7 +356,6 @@ add_vnic(struct add_virt_guestpart *addparams) POSTCODE_LINUX_2(VPCI_CREATE_ENTRY_PC, POSTCODE_SEVERITY_INFO); if (!WAIT_FOR_IO_CHANNEL ((struct spar_io_channel_protocol __iomem *)addparams->chanptr)) { - LOGERR("Timed out, channel not ready\n"); POSTCODE_LINUX_2(VPCI_CREATE_FAILURE_PC, POSTCODE_SEVERITY_ERR); return 0; } @@ -378,10 +366,8 @@ add_vnic(struct add_virt_guestpart *addparams) sprintf(busid, "vbus%d", addparams->bus_no); vbus = bus_find_device(&virtpci_bus_type, NULL, (void *)busid, match_busid); - if (!vbus) { - LOGERR("**** FAILED to find vbus %s\n", busid); + if (!vbus) return 0; - } i = virtpci_device_add(vbus, VIRTNIC_TYPE, addparams, NULL, &net); if (i) { @@ -405,10 +391,8 @@ delete_vbus(struct del_vbus_guestpart *delparams) sprintf(busid, "vbus%d", delparams->bus_no); vbus = bus_find_device(&virtpci_bus_type, NULL, (void *)busid, match_busid); - if (!vbus) { - LOGERR("**** FAILED to find vbus %s\n", busid); + if (!vbus) return 0; - } /* ensure that bus has no devices? -- TBD */ return 1; @@ -571,16 +555,11 @@ static int delete_all_virt(enum virtpci_dev_type devtype, sprintf(busid, "vbus%d", delparams->bus_no); vbus = bus_find_device(&virtpci_bus_type, NULL, (void *)busid, match_busid); - if (!vbus) { - LOGERR("**** FAILED to find vbus %s\n", busid); + if (!vbus) return 0; - } - if ((devtype != VIRTHBA_TYPE) && (devtype != VIRTNIC_TYPE)) { - LOGERR("**** FAILED to delete all devices; devtype:%d not vhba:%d or vnic:%d\n", - devtype, VIRTHBA_TYPE, VIRTNIC_TYPE); + if ((devtype != VIRTHBA_TYPE) && (devtype != VIRTNIC_TYPE)) return 0; - } /* delete all vhbas/vnics */ i = virtpci_device_del(vbus, devtype, NULL, NULL); @@ -618,7 +597,6 @@ static int virtpci_ctrlchan_func(struct guest_msgs *msg) case GUEST_RESUME_VNIC: return resume_vnic(&msg->resume_vnic); default: - LOGERR("invalid message type %d.\n", msg->msgtype); return 0; } } @@ -692,24 +670,19 @@ static void fix_vbus_dev_info(struct device *dev, int dev_no, int dev_type, struct ultra_vbus_deviceinfo dev_info; const char *stype; - if (!dev) { - LOGERR("%s dev is NULL", __func__); + if (!dev) return; - } - if (!virtpcidrv) { - LOGERR("%s driver is NULL", __func__); + if (!virtpcidrv) return; - } + vbus = dev->parent; - if (!vbus) { - LOGERR("%s dev has no parent bus", __func__); + if (!vbus) return; - } + chan = vbus->platform_data; - if (!chan) { - LOGERR("%s dev bus has no channel", __func__); + if (!chan) return; - } + switch (dev_type) { case PCI_DEVICE_ID_VIRTHBA: stype = "vHBA"; @@ -831,8 +804,6 @@ static int virtpci_device_add(struct device *parentbus, int devtype, POSTCODE_LINUX_2(VPCI_CREATE_ENTRY_PC, POSTCODE_SEVERITY_INFO); if ((devtype != VIRTHBA_TYPE) && (devtype != VIRTNIC_TYPE)) { - LOGERR("**** FAILED to add device; devtype:%d not vhba:%d or vnic:%d\n", - devtype, VIRTHBA_TYPE, VIRTNIC_TYPE); POSTCODE_LINUX_3(VPCI_CREATE_FAILURE_PC, devtype, POSTCODE_SEVERITY_ERR); return 0; @@ -902,7 +873,6 @@ static int virtpci_device_add(struct device *parentbus, int devtype, */ write_unlock_irqrestore(&vpcidev_list_lock, flags); kfree(virtpcidev); - LOGERR("**** FAILED vhba/vnic already exists in the list\n"); POSTCODE_LINUX_2(VPCI_CREATE_FAILURE_PC, POSTCODE_SEVERITY_ERR); return 0; } @@ -944,7 +914,6 @@ static int virtpci_device_add(struct device *parentbus, int devtype, * virtpci_device_probe is successful */ if (ret) { - LOGERR("device_register returned %d\n", ret); dev = &virtpcidev->generic_dev; SPAR_CHANNEL_CLIENT_TRANSITION(addparams->chanptr, BUS_ID(dev), @@ -983,11 +952,8 @@ static int virtpci_device_serverdown(struct device *parentbus, unsigned long flags; int rc = 0; - if ((devtype != VIRTHBA_TYPE) && (devtype != VIRTNIC_TYPE)) { - LOGERR("**** FAILED to pause device; devtype:%d not vhba:%d or vnic:%d\n", - devtype, VIRTHBA_TYPE, VIRTNIC_TYPE); + if ((devtype != VIRTHBA_TYPE) && (devtype != VIRTNIC_TYPE)) return 0; - } /* find the vhba or vnic in virtpci device list */ write_lock_irqsave(&vpcidev_list_lock, flags); @@ -1022,10 +988,8 @@ static int virtpci_device_serverdown(struct device *parentbus, } write_unlock_irqrestore(&vpcidev_list_lock, flags); - if (!found) { - LOGERR("**** FAILED to find vhba/vnic in the list\n"); + if (!found) return 0; - } return rc; } @@ -1042,11 +1006,9 @@ static int virtpci_device_serverup(struct device *parentbus, unsigned long flags; int rc = 0; - if ((devtype != VIRTHBA_TYPE) && (devtype != VIRTNIC_TYPE)) { - LOGERR("**** FAILED to resume device; devtype:%d not vhba:%d or vnic:%d\n", - devtype, VIRTHBA_TYPE, VIRTNIC_TYPE); + if ((devtype != VIRTHBA_TYPE) && (devtype != VIRTNIC_TYPE)) return 0; - } + /* find the vhba or vnic in virtpci device list */ write_lock_irqsave(&vpcidev_list_lock, flags); @@ -1090,10 +1052,8 @@ static int virtpci_device_serverup(struct device *parentbus, write_unlock_irqrestore(&vpcidev_list_lock, flags); - if (!found) { - LOGERR("**** FAILED to find vhba/vnic in the list\n"); + if (!found) return 0; - } return rc; } @@ -1112,11 +1072,8 @@ static int virtpci_device_del(struct device *parentbus, continue; \ } - if ((devtype != VIRTHBA_TYPE) && (devtype != VIRTNIC_TYPE)) { - LOGERR("**** FAILED to delete device; devtype:%d not vhba:%d or vnic:%d\n", - devtype, VIRTHBA_TYPE, VIRTNIC_TYPE); + if ((devtype != VIRTHBA_TYPE) && (devtype != VIRTNIC_TYPE)) return 0; - } /* see if we are to delete all - NOTE: all implies we have a * valid parentbus @@ -1183,10 +1140,8 @@ static int virtpci_device_del(struct device *parentbus, } write_unlock_irqrestore(&vpcidev_list_lock, flags); - if (!all && (count == 0)) { - LOGERR("**** FAILED to find vhba/vnic in the list\n"); + if (!all && (count == 0)) return 0; - } /* now delete each one from delete list */ while (dellist) { @@ -1253,10 +1208,9 @@ int virtpci_register_driver(struct virtpci_driver *drv) { int result = 0; - if (drv->id_table == NULL) { - LOGERR("id_table missing\n"); + if (drv->id_table == NULL) return 1; - } + /* initialize core driver fields needed to call driver_register */ drv->core_driver.name = drv->name; /* name of driver in sysfs */ drv->core_driver.bus = &virtpci_bus_type; /* type of bus this @@ -1338,7 +1292,6 @@ static ssize_t info_debugfs_read(struct file *file, char __user *buf, printparam.len = &len; if (bus_for_each_dev(&virtpci_bus_type, NULL, (void *)&printparam, print_vbus)) - LOGERR("Failed to find bus\n"); str_pos += scnprintf(vbuf + str_pos, len - str_pos, "\n Virtual PCI devices\n"); @@ -1401,7 +1354,6 @@ static int __init virtpci_mod_init(void) * drivers directory */ if (ret) { - LOGERR("bus_register ****FAILED:%d\n", ret); POSTCODE_LINUX_3(VPCI_CREATE_FAILURE_PC, ret, POSTCODE_SEVERITY_ERR); return ret; @@ -1412,7 +1364,6 @@ static int __init virtpci_mod_init(void) /* create a root bus used to parent all the virtpci buses. */ ret = device_register(&virtpci_rootbus_device); if (ret) { - LOGERR("device_register FAILED:%d\n", ret); bus_unregister(&virtpci_bus_type); POSTCODE_LINUX_3(VPCI_CREATE_FAILURE_PC, ret, POSTCODE_SEVERITY_ERR); @@ -1421,7 +1372,6 @@ static int __init virtpci_mod_init(void) if (!uisctrl_register_req_handler(2, (void *)&virtpci_ctrlchan_func, &chipset_driver_info)) { - LOGERR("uisctrl_register_req_handler ****FAILED.\n"); POSTCODE_LINUX_2(VPCI_CREATE_FAILURE_PC, POSTCODE_SEVERITY_ERR); device_unregister(&virtpci_rootbus_device); bus_unregister(&virtpci_bus_type); @@ -1439,9 +1389,6 @@ static int __init virtpci_mod_init(void) static void __exit virtpci_mod_exit(void) { /* unregister the callback function */ - if (!uisctrl_register_req_handler(2, NULL, NULL)) - LOGERR("uisctrl_register_req_handler ****FAILED.\n"); - device_unregister(&virtpci_rootbus_device); bus_unregister(&virtpci_bus_type); debugfs_remove_recursive(virtpci_debugfs_dir); diff --git a/drivers/staging/unisys/visorchannel/visorchannel_funcs.c b/drivers/staging/unisys/visorchannel/visorchannel_funcs.c index 01b0b200feb6..de0a64624e3d 100644 --- a/drivers/staging/unisys/visorchannel/visorchannel_funcs.c +++ b/drivers/staging/unisys/visorchannel/visorchannel_funcs.c @@ -77,13 +77,11 @@ visorchannel_create_guts(HOSTADDRESS physaddr, ulong channel_bytes, visor_memregion_create_overlapped(parent->memregion, off, sizeof(struct channel_header)); if (p->memregion == NULL) { - ERRDRV("visor_memregion_create failed failed: (status=0)\n"); rc = NULL; goto cleanup; } if (visor_memregion_read(p->memregion, 0, &p->chan_hdr, sizeof(struct channel_header)) < 0) { - ERRDRV("visor_memregion_read failed: (status=0)\n"); rc = NULL; goto cleanup; } @@ -94,7 +92,6 @@ visorchannel_create_guts(HOSTADDRESS physaddr, ulong channel_bytes, /* we had better be a CLIENT of this channel */ guid = p->chan_hdr.chtype; if (visor_memregion_resize(p->memregion, channel_bytes) < 0) { - ERRDRV("visor_memregion_resize failed: (status=0)\n"); rc = NULL; goto cleanup; } @@ -255,10 +252,9 @@ visorchannel_clear(struct visorchannel *channel, ulong offset, u8 ch, int written = 0; u8 *buf = vmalloc(bufsize); - if (buf == NULL) { - ERRDRV("%s failed memory allocation", __func__); + if (buf == NULL) goto cleanup; - } + memset(buf, ch, bufsize); while (nbytes > 0) { ulong thisbytes = bufsize; @@ -323,10 +319,8 @@ sig_read_header(struct visorchannel *channel, u32 queue, { BOOL rc = FALSE; - if (channel->chan_hdr.ch_space_offset < sizeof(struct channel_header)) { - ERRDRV("oChannelSpace too small: (status=%d)\n", rc); + if (channel->chan_hdr.ch_space_offset < sizeof(struct channel_header)) goto cleanup; - } /* Read the appropriate SIGNAL_QUEUE_HEADER into local memory. */ @@ -334,10 +328,6 @@ sig_read_header(struct visorchannel *channel, u32 queue, SIG_QUEUE_OFFSET(&channel->chan_hdr, queue), sig_hdr, sizeof(struct signal_queue_header)) < 0) { - ERRDRV("queue=%d SIG_QUEUE_OFFSET=%d", - queue, (int)SIG_QUEUE_OFFSET(&channel->chan_hdr, queue)); - ERRDRV("visor_memregion_read of signal queue failed: (status=%d)\n", - rc); goto cleanup; } rc = TRUE; @@ -357,15 +347,11 @@ sig_do_data(struct visorchannel *channel, u32 queue, if (visor_memregion_write(channel->memregion, signal_data_offset, data, sig_hdr->signal_size) < 0) { - ERRDRV("visor_memregion_write of signal data failed: (status=%d)\n", - rc); goto cleanup; } } else { if (visor_memregion_read(channel->memregion, signal_data_offset, data, sig_hdr->signal_size) < 0) { - ERRDRV("visor_memregion_read of signal data failed: (status=%d)\n", - rc); goto cleanup; } } @@ -403,8 +389,6 @@ safe_sig_queue_validate(struct signal_queue_header *psafe_sqh, punsafe_sqh->head = *phead; punsafe_sqh->tail = *ptail; - ERRDRV("safe_sig_queue_validate: head = 0x%x, tail = 0x%x, MaxSlots = 0x%x", - *phead, *ptail, psafe_sqh->max_slots); return 0; } return 1; @@ -422,7 +406,6 @@ signalremove_inner(struct visorchannel *channel, u32 queue, void *msg) sig_hdr.tail = (sig_hdr.tail + 1) % sig_hdr.max_slots; if (!sig_read_data(channel, queue, &sig_hdr, sig_hdr.tail, msg)) { - ERRDRV("sig_read_data failed\n"); return FALSE; } sig_hdr.num_received++; @@ -431,14 +414,10 @@ signalremove_inner(struct visorchannel *channel, u32 queue, void *msg) * update host memory. */ mb(); /* required for channel synch */ - if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, tail)) { - ERRDRV("visor_memregion_write of Tail failed\n"); + if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, tail)) return FALSE; - } - if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_received)) { - ERRDRV("visor_memregion_write of NumSignalsReceived failed\n"); + if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_received)) return FALSE; - } return TRUE; } @@ -470,28 +449,28 @@ signalinsert_inner(struct visorchannel *channel, u32 queue, void *msg) sig_hdr.head = ((sig_hdr.head + 1) % sig_hdr.max_slots); if (sig_hdr.head == sig_hdr.tail) { sig_hdr.num_overflows++; - if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_overflows)) - ERRDRV("visor_memregion_write of NumOverflows failed\n"); - + visor_memregion_write(channel->memregion, + SIG_QUEUE_OFFSET(&channel->chan_hdr, + queue) + + offsetof(struct signal_queue_header, + num_overflows), + &(sig_hdr.num_overflows), + sizeof(sig_hdr.num_overflows)); return FALSE; } - if (!sig_write_data(channel, queue, &sig_hdr, sig_hdr.head, msg)) { - ERRDRV("sig_write_data failed\n"); + if (!sig_write_data(channel, queue, &sig_hdr, sig_hdr.head, msg)) return FALSE; - } + sig_hdr.num_sent++; /* For each data field in SIGNAL_QUEUE_HEADER that was modified, * update host memory. */ mb(); /* required for channel synch */ - if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, head)) { - ERRDRV("visor_memregion_write of Head failed\n"); + if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, head)) return FALSE; - } if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_sent)) { - ERRDRV("visor_memregion_write of NumSignalsSent failed\n"); return FALSE; } @@ -581,15 +560,13 @@ visorchannel_debug(struct visorchannel *channel, int num_queues, int i = 0; int errcode = 0; - if (channel == NULL) { - ERRDRV("%s no channel", __func__); + if (channel == NULL) return; - } + memregion = channel->memregion; - if (memregion == NULL) { - ERRDRV("%s no memregion", __func__); + if (memregion == NULL) return; - } + addr = visor_memregion_get_physaddr(memregion); nbytes_region = visor_memregion_get_nbytes(memregion); errcode = visorchannel_read(channel, off, @@ -669,11 +646,8 @@ visorchannel_dump_section(struct visorchannel *chan, char *s, goto fmt_failed; errcode = visorchannel_read(chan, off, buf, len); - if (errcode < 0) { - ERRDRV("%s failed to read %s from channel errcode=%d", - s, __func__, errcode); + if (errcode < 0) goto read_failed; - } seq_printf(seq, "channel %s:\n", s); tbuf = buf; while (len > 0) { diff --git a/drivers/staging/unisys/visorchipset/file.c b/drivers/staging/unisys/visorchipset/file.c index b37113263151..9ca7f1eb1e7e 100644 --- a/drivers/staging/unisys/visorchipset/file.c +++ b/drivers/staging/unisys/visorchipset/file.c @@ -60,25 +60,18 @@ visorchipset_file_init(dev_t major_dev, struct visorchannel **controlvm_channel) file_cdev.owner = THIS_MODULE; if (MAJOR(majordev) == 0) { /* dynamic major device number registration required */ - if (alloc_chrdev_region(&majordev, 0, 1, MYDRVNAME) < 0) { - ERRDRV("Unable to allocate+register char device %s", - MYDRVNAME); + if (alloc_chrdev_region(&majordev, 0, 1, MYDRVNAME) < 0) return -1; - } registered = TRUE; } else { /* static major device number registration required */ - if (register_chrdev_region(majordev, 1, MYDRVNAME) < 0) { - ERRDRV("Unable to register char device %s", MYDRVNAME); + if (register_chrdev_region(majordev, 1, MYDRVNAME) < 0) return -1; - } registered = TRUE; } rc = cdev_add(&file_cdev, MKDEV(MAJOR(majordev), 0), 1); - if (rc < 0) { - ERRDRV("failed to create char device: (status=%d)\n", rc); + if (rc < 0) return -1; - } return 0; } @@ -122,15 +115,13 @@ visorchipset_mmap(struct file *file, struct vm_area_struct *vma) GUEST_PHYSICAL_ADDRESS addr = 0; /* sv_enable_dfp(); */ - if (offset & (PAGE_SIZE - 1)) { - ERRDRV("%s virtual address NOT page-aligned!", __func__); + if (offset & (PAGE_SIZE - 1)) return -ENXIO; /* need aligned offsets */ - } + switch (offset) { case VISORCHIPSET_MMAP_CONTROLCHANOFFSET: vma->vm_flags |= VM_IO; if (*file_controlvm_channel == NULL) { - ERRDRV("%s no controlvm channel yet", __func__); return -ENXIO; } visorchannel_read(*file_controlvm_channel, @@ -138,7 +129,6 @@ visorchipset_mmap(struct file *file, struct vm_area_struct *vma) gp_control_channel), &addr, sizeof(addr)); if (addr == 0) { - ERRDRV("%s control channel address is 0", __func__); return -ENXIO; } physaddr = (ulong)addr; @@ -147,7 +137,6 @@ visorchipset_mmap(struct file *file, struct vm_area_struct *vma) vma->vm_end - vma->vm_start, /*pgprot_noncached */ (vma->vm_page_prot))) { - ERRDRV("%s remap_pfn_range failed", __func__); return -EAGAIN; } break; @@ -179,7 +168,6 @@ static long visorchipset_ioctl(struct file *file, unsigned int cmd, } return issue_vmcall_update_physical_time(adjustment); default: - LOGERR("visorchipset_ioctl received invalid command"); return -EFAULT; } } diff --git a/drivers/staging/unisys/visorchipset/parser.c b/drivers/staging/unisys/visorchipset/parser.c index 686fe6474ee3..0683472ba47c 100644 --- a/drivers/staging/unisys/visorchipset/parser.c +++ b/drivers/staging/unisys/visorchipset/parser.c @@ -59,9 +59,6 @@ parser_init_guts(u64 addr, u32 bytes, BOOL isLocal, allocbytes++; if ((Controlvm_Payload_Bytes_Buffered + bytes) > MAX_CONTROLVM_PAYLOAD_BYTES) { - ERRDRV("%s (%s:%d) - prevented allocation of %d bytes to prevent exceeding throttling max (%d)", - __func__, __FILE__, __LINE__, allocbytes, - MAX_CONTROLVM_PAYLOAD_BYTES); if (tryAgain) *tryAgain = TRUE; rc = NULL; @@ -84,9 +81,6 @@ parser_init_guts(u64 addr, u32 bytes, BOOL isLocal, void *p; if (addr > virt_to_phys(high_memory - 1)) { - ERRDRV("%s - bad local address (0x%-16.16Lx for %lu)", - __func__, - (unsigned long long) addr, (ulong) bytes); rc = NULL; goto Away; } @@ -110,27 +104,15 @@ parser_init_guts(u64 addr, u32 bytes, BOOL isLocal, } phdr = (struct spar_controlvm_parameters_header *)(ctx->data); if (phdr->total_length != bytes) { - ERRDRV("%s - bad total length %lu (should be %lu)", - __func__, - (ulong) (phdr->total_length), (ulong) (bytes)); rc = NULL; goto Away; } if (phdr->total_length < phdr->header_length) { - ERRDRV("%s - total length < header length (%lu < %lu)", - __func__, - (ulong) (phdr->total_length), - (ulong) (phdr->header_length)); rc = NULL; goto Away; } if (phdr->header_length < sizeof(struct spar_controlvm_parameters_header)) { - ERRDRV("%s - header is too small (%lu < %lu)", - __func__, - (ulong) (phdr->header_length), - (ulong)(sizeof( - struct spar_controlvm_parameters_header))); rc = NULL; goto Away; } @@ -198,11 +180,8 @@ parser_id_get(PARSER_CONTEXT *ctx) { struct spar_controlvm_parameters_header *phdr = NULL; - if (ctx == NULL) { - ERRDRV("%s (%s:%d) - no context", - __func__, __FILE__, __LINE__); + if (ctx == NULL) return NULL_UUID_LE; - } phdr = (struct spar_controlvm_parameters_header *)(ctx->data); return phdr->id; } @@ -212,11 +191,8 @@ parser_param_start(PARSER_CONTEXT *ctx, PARSER_WHICH_STRING which_string) { struct spar_controlvm_parameters_header *phdr = NULL; - if (ctx == NULL) { - ERRDRV("%s (%s:%d) - no context", - __func__, __FILE__, __LINE__); + if (ctx == NULL) goto Away; - } phdr = (struct spar_controlvm_parameters_header *)(ctx->data); switch (which_string) { case PARSERSTRING_INITIATOR: @@ -236,7 +212,6 @@ parser_param_start(PARSER_CONTEXT *ctx, PARSER_WHICH_STRING which_string) ctx->bytes_remaining = phdr->name_length; break; default: - ERRDRV("%s - bad which_string %d", __func__, which_string); break; } @@ -319,25 +294,18 @@ parser_param_get(PARSER_CONTEXT *ctx, char *nam, int namesize) } while (*pscan != ':') { - if (namesize <= 0) { - ERRDRV("%s - name too big", __func__); + if (namesize <= 0) return NULL; - } *pnam = toupper(*pscan); pnam++; namesize--; pscan++; nscan--; - if (nscan == 0) { - ERRDRV("%s - unexpected end of input parsing name", - __func__); + if (nscan == 0) return NULL; - } } - if (namesize <= 0) { - ERRDRV("%s - name too big", __func__); + if (namesize <= 0) return NULL; - } *pnam = '\0'; nam[string_length_no_trail(nam, strlen(nam))] = '\0'; @@ -348,26 +316,17 @@ parser_param_get(PARSER_CONTEXT *ctx, char *nam, int namesize) while (isspace(*pscan)) { pscan++; nscan--; - if (nscan == 0) { - ERRDRV("%s - unexpected end of input looking for value", - __func__); + if (nscan == 0) return NULL; - } } - if (nscan == 0) { - ERRDRV("%s - unexpected end of input looking for value", - __func__); + if (nscan == 0) return NULL; - } if (*pscan == '\'' || *pscan == '"') { closing_quote = *pscan; pscan++; nscan--; - if (nscan == 0) { - ERRDRV("%s - unexpected end of input after %c", - __func__, closing_quote); + if (nscan == 0) return NULL; - } } /* look for a separator character, terminator character, or @@ -375,10 +334,8 @@ parser_param_get(PARSER_CONTEXT *ctx, char *nam, int namesize) */ for (i = 0, value_length = -1; i < nscan; i++) { if (closing_quote) { - if (pscan[i] == '\0') { - ERRDRV("%s - unexpected end of input parsing quoted value", __func__); + if (pscan[i] == '\0') return NULL; - } if (pscan[i] == closing_quote) { value_length = i; break; @@ -391,10 +348,8 @@ parser_param_get(PARSER_CONTEXT *ctx, char *nam, int namesize) } } if (value_length < 0) { - if (closing_quote) { - ERRDRV("%s - unexpected end of input parsing quoted value", __func__); + if (closing_quote) return NULL; - } value_length = nscan; } orig_value_length = value_length; @@ -431,7 +386,6 @@ parser_param_get(PARSER_CONTEXT *ctx, char *nam, int namesize) pscan++; nscan--; } else if (*pscan != '\0') { - ERRDRV("%s - missing separator after quoted string", __func__); kfree(value); value = NULL; return NULL; diff --git a/drivers/staging/unisys/visorchipset/visorchipset_main.c b/drivers/staging/unisys/visorchipset/visorchipset_main.c index a49ba6141544..74a27e37f437 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset_main.c +++ b/drivers/staging/unisys/visorchipset/visorchipset_main.c @@ -659,7 +659,6 @@ chipset_init(struct controlvm_message *inmsg) POSTCODE_LINUX_2(CHIPSET_INIT_ENTRY_PC, POSTCODE_SEVERITY_INFO); if (chipset_inited) { - LOGERR("CONTROLVM_CHIPSET_INIT Failed: Already Done."); rc = -CONTROLVM_RESP_ERROR_ALREADY_DONE; goto Away; } @@ -717,7 +716,6 @@ controlvm_respond(struct controlvm_message_header *msgHdr, int response) if (!visorchannel_signalinsert(ControlVm_channel, CONTROLVM_QUEUE_REQUEST, &outmsg)) { - LOGERR("signalinsert failed!"); return; } } @@ -733,7 +731,6 @@ controlvm_respond_chipset_init(struct controlvm_message_header *msgHdr, outmsg.cmd.init_chipset.features = features; if (!visorchannel_signalinsert(ControlVm_channel, CONTROLVM_QUEUE_REQUEST, &outmsg)) { - LOGERR("signalinsert failed!"); return; } } @@ -749,7 +746,6 @@ static void controlvm_respond_physdev_changestate( outmsg.cmd.device_change_state.flags.phys_device = 1; if (!visorchannel_signalinsert(ControlVm_channel, CONTROLVM_QUEUE_REQUEST, &outmsg)) { - LOGERR("signalinsert failed!"); return; } } @@ -766,15 +762,12 @@ visorchipset_save_message(struct controlvm_message *msg, offsetof(struct spar_controlvm_channel_protocol, saved_crash_message_count), &localSavedCrashMsgCount, sizeof(u16)) < 0) { - LOGERR("failed to get Saved Message Count"); POSTCODE_LINUX_2(CRASH_DEV_CTRL_RD_FAILURE_PC, POSTCODE_SEVERITY_ERR); return; } if (localSavedCrashMsgCount != CONTROLVM_CRASHMSG_MAX) { - LOGERR("Saved Message Count incorrect %d", - localSavedCrashMsgCount); POSTCODE_LINUX_3(CRASH_DEV_COUNT_FAILURE_PC, localSavedCrashMsgCount, POSTCODE_SEVERITY_ERR); @@ -786,7 +779,6 @@ visorchipset_save_message(struct controlvm_message *msg, offsetof(struct spar_controlvm_channel_protocol, saved_crash_message_offset), &localSavedCrashMsgOffset, sizeof(u32)) < 0) { - LOGERR("failed to get Saved Message Offset"); POSTCODE_LINUX_2(CRASH_DEV_CTRL_RD_FAILURE_PC, POSTCODE_SEVERITY_ERR); return; @@ -797,7 +789,6 @@ visorchipset_save_message(struct controlvm_message *msg, localSavedCrashMsgOffset, msg, sizeof(struct controlvm_message)) < 0) { - LOGERR("SAVE_MSG_BUS_FAILURE: Failed to write CrashCreateBusMsg!"); POSTCODE_LINUX_2(SAVE_MSG_BUS_FAILURE_PC, POSTCODE_SEVERITY_ERR); return; @@ -807,7 +798,6 @@ visorchipset_save_message(struct controlvm_message *msg, localSavedCrashMsgOffset + sizeof(struct controlvm_message), msg, sizeof(struct controlvm_message)) < 0) { - LOGERR("SAVE_MSG_DEV_FAILURE: Failed to write CrashCreateDevMsg!"); POSTCODE_LINUX_2(SAVE_MSG_DEV_FAILURE_PC, POSTCODE_SEVERITY_ERR); return; @@ -823,10 +813,9 @@ bus_responder(enum controlvm_id cmdId, ulong busNo, int response) BOOL need_clear = FALSE; p = findbus(&BusInfoList, busNo); - if (!p) { - LOGERR("internal error busNo=%lu", busNo); + if (!p) return; - } + if (response < 0) { if ((cmdId == CONTROLVM_BUS_CREATE) && (response != (-CONTROLVM_RESP_ERROR_ALREADY_DONE))) @@ -839,14 +828,10 @@ bus_responder(enum controlvm_id cmdId, ulong busNo, int response) need_clear = TRUE; } - if (p->pending_msg_hdr.id == CONTROLVM_INVALID) { - LOGERR("bus_responder no pending msg"); + if (p->pending_msg_hdr.id == CONTROLVM_INVALID) return; /* no controlvm response needed */ - } - if (p->pending_msg_hdr.id != (u32) cmdId) { - LOGERR("expected=%d, found=%d", cmdId, p->pending_msg_hdr.id); + if (p->pending_msg_hdr.id != (u32) cmdId) return; - } controlvm_respond(&p->pending_msg_hdr, response); p->pending_msg_hdr.id = CONTROLVM_INVALID; if (need_clear) { @@ -864,18 +849,12 @@ device_changestate_responder(enum controlvm_id cmdId, struct controlvm_message outmsg; p = finddevice(&DevInfoList, busNo, devNo); - if (!p) { - LOGERR("internal error; busNo=%lu, devNo=%lu", busNo, devNo); + if (!p) return; - } - if (p->pending_msg_hdr.id == CONTROLVM_INVALID) { - LOGERR("device_responder no pending msg"); + if (p->pending_msg_hdr.id == CONTROLVM_INVALID) return; /* no controlvm response needed */ - } - if (p->pending_msg_hdr.id != cmdId) { - LOGERR("expected=%d, found=%d", cmdId, p->pending_msg_hdr.id); + if (p->pending_msg_hdr.id != cmdId) return; - } controlvm_init_response(&outmsg, &p->pending_msg_hdr, response); @@ -884,10 +863,8 @@ device_changestate_responder(enum controlvm_id cmdId, outmsg.cmd.device_change_state.state = responseState; if (!visorchannel_signalinsert(ControlVm_channel, - CONTROLVM_QUEUE_REQUEST, &outmsg)) { - LOGERR("signalinsert failed!"); + CONTROLVM_QUEUE_REQUEST, &outmsg)) return; - } p->pending_msg_hdr.id = CONTROLVM_INVALID; } @@ -900,10 +877,8 @@ device_responder(enum controlvm_id cmdId, ulong busNo, ulong devNo, BOOL need_clear = FALSE; p = finddevice(&DevInfoList, busNo, devNo); - if (!p) { - LOGERR("internal error; busNo=%lu, devNo=%lu", busNo, devNo); + if (!p) return; - } if (response >= 0) { if (cmdId == CONTROLVM_DEVICE_CREATE) p->state.created = 1; @@ -911,14 +886,12 @@ device_responder(enum controlvm_id cmdId, ulong busNo, ulong devNo, need_clear = TRUE; } - if (p->pending_msg_hdr.id == CONTROLVM_INVALID) { - LOGERR("device_responder no pending msg"); + if (p->pending_msg_hdr.id == CONTROLVM_INVALID) return; /* no controlvm response needed */ - } - if (p->pending_msg_hdr.id != (u32) cmdId) { - LOGERR("expected=%d, found=%d", cmdId, p->pending_msg_hdr.id); + + if (p->pending_msg_hdr.id != (u32) cmdId) return; - } + controlvm_respond(&p->pending_msg_hdr, response); p->pending_msg_hdr.id = CONTROLVM_INVALID; if (need_clear) @@ -934,10 +907,9 @@ bus_epilog(u32 busNo, struct visorchipset_bus_info *pBusInfo = findbus(&BusInfoList, busNo); - if (!pBusInfo) { - LOGERR("HUH? bad busNo=%d", busNo); + if (!pBusInfo) return; - } + if (needResponse) { memcpy(&pBusInfo->pending_msg_hdr, msgHdr, sizeof(struct controlvm_message_header)); @@ -1007,10 +979,9 @@ device_epilog(u32 busNo, u32 devNo, struct spar_segment_state state, u32 cmd, NULL }; - if (!pDevInfo) { - LOGERR("HUH? bad busNo=%d, devNo=%d", busNo, devNo); + if (!pDevInfo) return; - } + if (for_visorbus) notifiers = &BusDev_Server_Notifiers; else @@ -1100,8 +1071,6 @@ bus_create(struct controlvm_message *inmsg) pBusInfo = findbus(&BusInfoList, busNo); if (pBusInfo && (pBusInfo->state.created == 1)) { - LOGERR("CONTROLVM_BUS_CREATE Failed: bus %lu already exists", - busNo); POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, busNo, POSTCODE_SEVERITY_ERR); rc = -CONTROLVM_RESP_ERROR_ALREADY_DONE; @@ -1152,13 +1121,10 @@ bus_destroy(struct controlvm_message *inmsg) pBusInfo = findbus(&BusInfoList, busNo); if (!pBusInfo) { - LOGERR("CONTROLVM_BUS_DESTROY Failed: bus %lu invalid", busNo); rc = -CONTROLVM_RESP_ERROR_BUS_INVALID; goto Away; } if (pBusInfo->state.created == 0) { - LOGERR("CONTROLVM_BUS_DESTROY Failed: bus %lu already destroyed", - busNo); rc = -CONTROLVM_RESP_ERROR_ALREADY_DONE; goto Away; } @@ -1182,16 +1148,12 @@ bus_configure(struct controlvm_message *inmsg, PARSER_CONTEXT *parser_ctx) pBusInfo = findbus(&BusInfoList, busNo); if (!pBusInfo) { - LOGERR("CONTROLVM_BUS_CONFIGURE Failed: bus %lu invalid", - busNo); POSTCODE_LINUX_3(BUS_CONFIGURE_FAILURE_PC, busNo, POSTCODE_SEVERITY_ERR); rc = -CONTROLVM_RESP_ERROR_BUS_INVALID; goto Away; } if (pBusInfo->state.created == 0) { - LOGERR("CONTROLVM_BUS_CONFIGURE Failed: Invalid bus %lu - not created yet", - busNo); POSTCODE_LINUX_3(BUS_CONFIGURE_FAILURE_PC, busNo, POSTCODE_SEVERITY_ERR); rc = -CONTROLVM_RESP_ERROR_BUS_INVALID; @@ -1199,8 +1161,6 @@ bus_configure(struct controlvm_message *inmsg, PARSER_CONTEXT *parser_ctx) } /* TBD - add this check to other commands also... */ if (pBusInfo->pending_msg_hdr.id != CONTROLVM_INVALID) { - LOGERR("CONTROLVM_BUS_CONFIGURE Failed: bus %lu MsgId=%u outstanding", - busNo, (uint) pBusInfo->pending_msg_hdr.id); POSTCODE_LINUX_3(BUS_CONFIGURE_FAILURE_PC, busNo, POSTCODE_SEVERITY_ERR); rc = -CONTROLVM_RESP_ERROR_MESSAGE_ID_INVALID_FOR_CLIENT; @@ -1231,8 +1191,6 @@ my_device_create(struct controlvm_message *inmsg) pDevInfo = finddevice(&DevInfoList, busNo, devNo); if (pDevInfo && (pDevInfo->state.created == 1)) { - LOGERR("CONTROLVM_DEVICE_CREATE Failed: busNo=%lu, devNo=%lu already exists", - busNo, devNo); POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, devNo, busNo, POSTCODE_SEVERITY_ERR); rc = -CONTROLVM_RESP_ERROR_ALREADY_DONE; @@ -1240,16 +1198,12 @@ my_device_create(struct controlvm_message *inmsg) } pBusInfo = findbus(&BusInfoList, busNo); if (!pBusInfo) { - LOGERR("CONTROLVM_DEVICE_CREATE Failed: Invalid bus %lu - out of range", - busNo); POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, devNo, busNo, POSTCODE_SEVERITY_ERR); rc = -CONTROLVM_RESP_ERROR_BUS_INVALID; goto Away; } if (pBusInfo->state.created == 0) { - LOGERR("CONTROLVM_DEVICE_CREATE Failed: Invalid bus %lu - not created yet", - busNo); POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, devNo, busNo, POSTCODE_SEVERITY_ERR); rc = -CONTROLVM_RESP_ERROR_BUS_INVALID; @@ -1307,16 +1261,12 @@ my_device_changestate(struct controlvm_message *inmsg) pDevInfo = finddevice(&DevInfoList, busNo, devNo); if (!pDevInfo) { - LOGERR("CONTROLVM_DEVICE_CHANGESTATE Failed: busNo=%lu, devNo=%lu invalid (doesn't exist)", - busNo, devNo); POSTCODE_LINUX_4(DEVICE_CHANGESTATE_FAILURE_PC, devNo, busNo, POSTCODE_SEVERITY_ERR); rc = -CONTROLVM_RESP_ERROR_DEVICE_INVALID; goto Away; } if (pDevInfo->state.created == 0) { - LOGERR("CONTROLVM_DEVICE_CHANGESTATE Failed: busNo=%lu, devNo=%lu invalid (not created)", - busNo, devNo); POSTCODE_LINUX_4(DEVICE_CHANGESTATE_FAILURE_PC, devNo, busNo, POSTCODE_SEVERITY_ERR); rc = -CONTROLVM_RESP_ERROR_DEVICE_INVALID; @@ -1341,14 +1291,10 @@ my_device_destroy(struct controlvm_message *inmsg) pDevInfo = finddevice(&DevInfoList, busNo, devNo); if (!pDevInfo) { - LOGERR("CONTROLVM_DEVICE_DESTROY Failed: busNo=%lu, devNo=%lu invalid", - busNo, devNo); rc = -CONTROLVM_RESP_ERROR_DEVICE_INVALID; goto Away; } if (pDevInfo->state.created == 0) { - LOGERR("CONTROLVM_DEVICE_DESTROY Failed: busNo=%lu, devNo=%lu already destroyed", - busNo, devNo); rc = -CONTROLVM_RESP_ERROR_ALREADY_DONE; } @@ -1375,22 +1321,16 @@ initialize_controlvm_payload_info(HOSTADDRESS phys_addr, u64 offset, u32 bytes, int rc = CONTROLVM_RESP_SUCCESS; if (info == NULL) { - LOGERR("HUH ? CONTROLVM_PAYLOAD_INIT Failed : Programmer check at %s:%d", - __FILE__, __LINE__); rc = -CONTROLVM_RESP_ERROR_PAYLOAD_INVALID; goto Away; } memset(info, 0, sizeof(struct controlvm_payload_info)); if ((offset == 0) || (bytes == 0)) { - LOGERR("CONTROLVM_PAYLOAD_INIT Failed: request_payload_offset=%llu request_payload_bytes=%llu!", - (u64) offset, (u64) bytes); rc = -CONTROLVM_RESP_ERROR_PAYLOAD_INVALID; goto Away; } payload = ioremap_cache(phys_addr + offset, bytes); if (payload == NULL) { - LOGERR("CONTROLVM_PAYLOAD_INIT Failed: ioremap_cache %llu for %llu bytes failed", - (u64) offset, (u64) bytes); rc = -CONTROLVM_RESP_ERROR_IOREMAP_FAILED; goto Away; } @@ -1430,7 +1370,6 @@ initialize_controlvm_payload(void) offsetof(struct spar_controlvm_channel_protocol, request_payload_offset), &payloadOffset, sizeof(payloadOffset)) < 0) { - LOGERR("CONTROLVM_PAYLOAD_INIT Failed to read controlvm channel!"); POSTCODE_LINUX_2(CONTROLVM_INIT_FAILURE_PC, POSTCODE_SEVERITY_ERR); return; @@ -1439,7 +1378,6 @@ initialize_controlvm_payload(void) offsetof(struct spar_controlvm_channel_protocol, request_payload_bytes), &payloadBytes, sizeof(payloadBytes)) < 0) { - LOGERR("CONTROLVM_PAYLOAD_INIT Failed to read controlvm channel!"); POSTCODE_LINUX_2(CONTROLVM_INIT_FAILURE_PC, POSTCODE_SEVERITY_ERR); return; @@ -1532,11 +1470,8 @@ read_controlvm_event(struct controlvm_message *msg) if (visorchannel_signalremove(ControlVm_channel, CONTROLVM_QUEUE_EVENT, msg)) { /* got a message */ - if (msg->hdr.flags.test_message == 1) { - LOGERR("ignoring bad CONTROLVM_QUEUE_EVENT msg with controlvm_msg_id=0x%x because Flags.testMessage is nonsensical (=1)", - msg->hdr.id); + if (msg->hdr.flags.test_message == 1) return FALSE; - } return TRUE; } return FALSE; @@ -1714,10 +1649,8 @@ parahotplug_process_message(struct controlvm_message *inmsg) req = parahotplug_request_create(inmsg); - if (req == NULL) { - LOGERR("parahotplug_process_message: couldn't allocate request"); + if (req == NULL) return; - } if (inmsg->cmd.device_change_state.state.active) { /* For enable messages, just respond with success @@ -1771,10 +1704,8 @@ handle_command(struct controlvm_message inmsg, HOSTADDRESS channel_addr) /* create parsing context if necessary */ isLocalAddr = (inmsg.hdr.flags.test_message == 1); - if (channel_addr == 0) { - LOGERR("HUH? channel_addr is 0!"); + if (channel_addr == 0) return TRUE; - } parametersAddr = channel_addr + inmsg.hdr.payload_vm_offset; parametersBytes = inmsg.hdr.payload_bytes; @@ -1856,7 +1787,6 @@ handle_command(struct controlvm_message inmsg, HOSTADDRESS channel_addr) chipset_notready(&inmsg.hdr); break; default: - LOGERR("unrecognized controlvm cmd=%d", (int) inmsg.hdr.id); if (inmsg.hdr.flags.response_expected) controlvm_respond(&inmsg.hdr, -CONTROLVM_RESP_ERROR_MESSAGE_ID_UNKNOWN); @@ -1875,11 +1805,9 @@ static HOSTADDRESS controlvm_get_channel_address(void) u64 addr = 0; u32 size = 0; - if (!VMCALL_SUCCESSFUL(issue_vmcall_io_controlvm_addr(&addr, &size))) { - ERRDRV("%s - vmcall to determine controlvm channel addr failed", - __func__); + if (!VMCALL_SUCCESSFUL(issue_vmcall_io_controlvm_addr(&addr, &size))) return 0; - } + return addr; } @@ -1922,12 +1850,6 @@ controlvm_periodic_work(struct work_struct *work) while (visorchannel_signalremove(ControlVm_channel, CONTROLVM_QUEUE_RESPONSE, &inmsg)) { - if (inmsg.hdr.payload_max_bytes != 0) { - LOGERR("Payload of size %lu returned @%lu with unexpected message id %d.", - (ulong) inmsg.hdr.payload_max_bytes, - (ulong) inmsg.hdr.payload_vm_offset, - inmsg.hdr.id); - } } if (!gotACommand) { if (ControlVm_Pending_Msg_Valid) { @@ -2020,15 +1942,12 @@ setup_crash_devices_work_queue(struct work_struct *work) offsetof(struct spar_controlvm_channel_protocol, saved_crash_message_count), &localSavedCrashMsgCount, sizeof(u16)) < 0) { - LOGERR("failed to get Saved Message Count"); POSTCODE_LINUX_2(CRASH_DEV_CTRL_RD_FAILURE_PC, POSTCODE_SEVERITY_ERR); return; } if (localSavedCrashMsgCount != CONTROLVM_CRASHMSG_MAX) { - LOGERR("Saved Message Count incorrect %d", - localSavedCrashMsgCount); POSTCODE_LINUX_3(CRASH_DEV_COUNT_FAILURE_PC, localSavedCrashMsgCount, POSTCODE_SEVERITY_ERR); @@ -2040,7 +1959,6 @@ setup_crash_devices_work_queue(struct work_struct *work) offsetof(struct spar_controlvm_channel_protocol, saved_crash_message_offset), &localSavedCrashMsgOffset, sizeof(u32)) < 0) { - LOGERR("failed to get Saved Message Offset"); POSTCODE_LINUX_2(CRASH_DEV_CTRL_RD_FAILURE_PC, POSTCODE_SEVERITY_ERR); return; @@ -2051,7 +1969,6 @@ setup_crash_devices_work_queue(struct work_struct *work) localSavedCrashMsgOffset, &localCrashCreateBusMsg, sizeof(struct controlvm_message)) < 0) { - LOGERR("CRASH_DEV_RD_BUS_FAIULRE: Failed to read CrashCreateBusMsg!"); POSTCODE_LINUX_2(CRASH_DEV_RD_BUS_FAIULRE_PC, POSTCODE_SEVERITY_ERR); return; @@ -2063,7 +1980,6 @@ setup_crash_devices_work_queue(struct work_struct *work) sizeof(struct controlvm_message), &localCrashCreateDevMsg, sizeof(struct controlvm_message)) < 0) { - LOGERR("CRASH_DEV_RD_DEV_FAIULRE: Failed to read CrashCreateDevMsg!"); POSTCODE_LINUX_2(CRASH_DEV_RD_DEV_FAIULRE_PC, POSTCODE_SEVERITY_ERR); return; @@ -2073,7 +1989,6 @@ setup_crash_devices_work_queue(struct work_struct *work) if (localCrashCreateBusMsg.cmd.create_bus.channel_addr != 0) bus_create(&localCrashCreateBusMsg); else { - LOGERR("CrashCreateBusMsg is null, no dump will be taken"); POSTCODE_LINUX_2(CRASH_DEV_BUS_NULL_FAILURE_PC, POSTCODE_SEVERITY_ERR); return; @@ -2083,7 +1998,6 @@ setup_crash_devices_work_queue(struct work_struct *work) if (localCrashCreateDevMsg.cmd.create_device.channel_addr != 0) my_device_create(&localCrashCreateDevMsg); else { - LOGERR("CrashCreateDevMsg is null, no dump will be taken"); POSTCODE_LINUX_2(CRASH_DEV_DEV_NULL_FAILURE_PC, POSTCODE_SEVERITY_ERR); return; @@ -2146,10 +2060,8 @@ visorchipset_get_bus_info(ulong bus_no, struct visorchipset_bus_info *bus_info) { void *p = findbus(&BusInfoList, bus_no); - if (!p) { - LOGERR("(%lu) failed", bus_no); + if (!p) return FALSE; - } memcpy(bus_info, p, sizeof(struct visorchipset_bus_info)); return TRUE; } @@ -2160,10 +2072,8 @@ visorchipset_set_bus_context(ulong bus_no, void *context) { struct visorchipset_bus_info *p = findbus(&BusInfoList, bus_no); - if (!p) { - LOGERR("(%lu) failed", bus_no); + if (!p) return FALSE; - } p->bus_driver_context = context; return TRUE; } @@ -2175,10 +2085,8 @@ visorchipset_get_device_info(ulong bus_no, ulong dev_no, { void *p = finddevice(&DevInfoList, bus_no, dev_no); - if (!p) { - LOGERR("(%lu,%lu) failed", bus_no, dev_no); + if (!p) return FALSE; - } memcpy(dev_info, p, sizeof(struct visorchipset_device_info)); return TRUE; } @@ -2190,10 +2098,8 @@ visorchipset_set_device_context(ulong bus_no, ulong dev_no, void *context) struct visorchipset_device_info *p = finddevice(&DevInfoList, bus_no, dev_no); - if (!p) { - LOGERR("(%lu,%lu) failed", bus_no, dev_no); + if (!p) return FALSE; - } p->bus_driver_context = context; return TRUE; } @@ -2221,10 +2127,9 @@ visorchipset_cache_alloc(struct kmem_cache *pool, BOOL ok_to_block, */ gfp |= __GFP_NORETRY; p = kmem_cache_alloc(pool, gfp); - if (!p) { - LOGERR("kmem_cache_alloc failed early @%s:%d\n", fn, ln); + if (!p) return NULL; - } + atomic_inc(&Visorchipset_cache_buffers_in_use); return p; } @@ -2234,10 +2139,9 @@ visorchipset_cache_alloc(struct kmem_cache *pool, BOOL ok_to_block, void visorchipset_cache_free(struct kmem_cache *pool, void *p, char *fn, int ln) { - if (!p) { - LOGERR("NULL pointer @%s:%d\n", fn, ln); + if (!p) return; - } + atomic_dec(&Visorchipset_cache_buffers_in_use); kmem_cache_free(pool, p); } @@ -2308,8 +2212,6 @@ visorchipset_init(void) atomic_set(&LiveDump_info.buffers_in_use, 0); if (visorchipset_testvnic) { - ERRDRV("testvnic option no longer supported: (status = %d)\n", - x); POSTCODE_LINUX_3(CHIPSET_INIT_FAILURE_PC, x, DIAG_SEVERITY_ERR); rc = x; goto Away; @@ -2326,20 +2228,17 @@ visorchipset_init(void) visorchannel_get_header(ControlVm_channel))) { initialize_controlvm_payload(); } else { - LOGERR("controlvm channel is invalid"); visorchannel_destroy(ControlVm_channel); ControlVm_channel = NULL; return -ENODEV; } } else { - LOGERR("no controlvm channel discovered"); return -ENODEV; } MajorDev = MKDEV(visorchipset_major, 0); rc = visorchipset_file_init(MajorDev, &ControlVm_channel); if (rc < 0) { - ERRDRV("visorchipset_file_init(MajorDev, &ControlVm_channel): error (status=%d)\n", rc); POSTCODE_LINUX_2(CHIPSET_INIT_FAILURE_PC, DIAG_SEVERITY_ERR); goto Away; } @@ -2355,7 +2254,6 @@ visorchipset_init(void) sizeof(struct putfile_buffer_entry), 0, SLAB_HWCACHE_ALIGN, NULL); if (!Putfile_buffer_list_pool) { - ERRDRV("failed to alloc Putfile_buffer_list_pool: (status=-1)\n"); POSTCODE_LINUX_2(CHIPSET_INIT_FAILURE_PC, DIAG_SEVERITY_ERR); rc = -1; goto Away; @@ -2372,8 +2270,6 @@ visorchipset_init(void) create_singlethread_workqueue("visorchipset_controlvm"); if (Periodic_controlvm_workqueue == NULL) { - ERRDRV("cannot create controlvm workqueue: (status=%d)\n", - -ENOMEM); POSTCODE_LINUX_2(CREATE_WORKQUEUE_FAILED_PC, DIAG_SEVERITY_ERR); rc = -ENOMEM; @@ -2384,7 +2280,6 @@ visorchipset_init(void) rc = queue_delayed_work(Periodic_controlvm_workqueue, &Periodic_controlvm_work, Poll_jiffies); if (rc < 0) { - ERRDRV("queue_delayed_work(Periodic_controlvm_workqueue, &Periodic_controlvm_work, Poll_jiffies): error (status=%d)\n", rc); POSTCODE_LINUX_2(QUEUE_DELAYED_WORK_PC, DIAG_SEVERITY_ERR); goto Away; @@ -2394,7 +2289,6 @@ visorchipset_init(void) Visorchipset_platform_device.dev.devt = MajorDev; if (platform_device_register(&Visorchipset_platform_device) < 0) { - ERRDRV("platform_device_register(visorchipset) failed: (status=-1)\n"); POSTCODE_LINUX_2(DEVICE_REGISTER_FAILURE_PC, DIAG_SEVERITY_ERR); rc = -1; goto Away; @@ -2403,7 +2297,6 @@ visorchipset_init(void) rc = 0; Away: if (rc) { - LOGERR("visorchipset_init failed"); POSTCODE_LINUX_3(CHIPSET_INIT_FAILURE_PC, rc, POSTCODE_SEVERITY_ERR); } diff --git a/drivers/staging/unisys/visorutil/charqueue.c b/drivers/staging/unisys/visorutil/charqueue.c index e2ee5ee7585e..c91752a2d06b 100644 --- a/drivers/staging/unisys/visorutil/charqueue.c +++ b/drivers/staging/unisys/visorutil/charqueue.c @@ -39,11 +39,8 @@ struct charqueue *visor_charqueue_create(ulong nslots) struct charqueue *cq; cq = kmalloc(alloc_size, GFP_KERNEL|__GFP_NORETRY); - if (cq == NULL) { - ERRDRV("visor_charqueue_create allocation failed (alloc_size=%d)", - alloc_size); + if (cq == NULL) return NULL; - } cq->alloc_size = alloc_size; cq->nslots = nslots; cq->head = 0; diff --git a/drivers/staging/unisys/visorutil/easyproc.c b/drivers/staging/unisys/visorutil/easyproc.c index 40f1ae9a155c..53408056268e 100644 --- a/drivers/staging/unisys/visorutil/easyproc.c +++ b/drivers/staging/unisys/visorutil/easyproc.c @@ -61,9 +61,6 @@ static struct proc_dir_entry * createProcDir(char *name, struct proc_dir_entry *parent) { struct proc_dir_entry *p = proc_mkdir_mode(name, S_IFDIR, parent); - - if (p == NULL) - ERRDRV("failed to create /proc directory %s", name); return p; } @@ -114,8 +111,6 @@ void visor_easyproc_InitDriver(struct easyproc_driver_info *pdriver, { memset(pdriver, 0, sizeof(struct easyproc_driver_info)); pdriver->ProcId = procId; - if (pdriver->ProcId == NULL) - ERRDRV("ProcId cannot be NULL (trouble ahead)!"); pdriver->Show_driver_info = show_driver_info; pdriver->Show_device_info = show_device_info; if (pdriver->ProcDir == NULL) @@ -132,9 +127,6 @@ void visor_easyproc_InitDriver(struct easyproc_driver_info *pdriver, proc_create_data("diag", 0, pdriver->ProcDriverDir, &proc_fops_driver, pdriver); - if (pdriver->ProcDriverDiagFile == NULL) - ERRDRV("failed to register /proc/%s/driver/diag entry", - pdriver->ProcId); } } EXPORT_SYMBOL_GPL(visor_easyproc_InitDriver); @@ -209,10 +201,6 @@ void visor_easyproc_InitDevice(struct easyproc_driver_info *pdriver, p->procDevicexDiagFile = proc_create_data("diag", 0, p->procDevicexDir, &proc_fops_device, p); - if (p->procDevicexDiagFile == NULL) - ERRDEVX(devno, "failed to register /proc/%s/device/%d/diag entry", - pdriver->ProcId, devno - ); } memset(&(p->device_property_info[0]), 0, sizeof(p->device_property_info)); @@ -229,34 +217,26 @@ void visor_easyproc_CreateDeviceProperty(struct easyproc_device_info *p, size_t i; struct easyproc_device_property_info *px = NULL; - if (p->procDevicexDir == NULL) { - ERRDRV("state error"); + if (p->procDevicexDir == NULL) return; - } for (i = 0; i < ARRAY_SIZE(p->device_property_info); i++) { if (p->device_property_info[i].procEntry == NULL) { px = &(p->device_property_info[i]); break; } } - if (!px) { - ERRDEVX(p->devno, "too many device properties"); + if (!px) return; - } + px->devdata = p->devdata; px->pdriver = p->pdriver; px->procEntry = proc_create_data(property_name, 0, p->procDevicexDir, &proc_fops_device_property, px); if (strlen(property_name)+1 > sizeof(px->property_name)) { - ERRDEVX(p->devno, "device property name %s too long", - property_name); return; } strcpy(px->property_name, property_name); if (px->procEntry == NULL) { - ERRDEVX(p->devno, - "failed to register /proc/%s/device/%d/%s entry", - p->pdriver->ProcId, p->devno, property_name); return; } px->show_device_property_info = show_property_info; diff --git a/drivers/staging/unisys/visorutil/memregion_direct.c b/drivers/staging/unisys/visorutil/memregion_direct.c index aa52a6fd1bf0..07aa2975bd6a 100644 --- a/drivers/staging/unisys/visorutil/memregion_direct.c +++ b/drivers/staging/unisys/visorutil/memregion_direct.c @@ -44,10 +44,9 @@ visor_memregion_create(HOSTADDRESS physaddr, ulong nbytes) struct memregion *memregion; memregion = kzalloc(sizeof(*memregion), GFP_KERNEL | __GFP_NORETRY); - if (memregion == NULL) { - ERRDRV("visor_memregion_create allocation failed"); + if (memregion == NULL) return NULL; - } + memregion->physaddr = physaddr; memregion->nbytes = nbytes; memregion->overlapped = FALSE; @@ -71,20 +70,16 @@ visor_memregion_create_overlapped(struct memregion *parent, ulong offset, { struct memregion *memregion = NULL; - if (parent == NULL) { - ERRDRV("%s parent is NULL", __func__); + if (parent == NULL) return NULL; - } - if (parent->mapped == NULL) { - ERRDRV("%s parent is not mapped!", __func__); + + if (parent->mapped == NULL) return NULL; - } + if ((offset >= parent->nbytes) || - ((offset + nbytes) >= parent->nbytes)) { - ERRDRV("%s range (%lu,%lu) out of parent range", - __func__, offset, nbytes); + ((offset + nbytes) >= parent->nbytes)) return NULL; - } + memregion = kzalloc(sizeof(*memregion), GFP_KERNEL|__GFP_NORETRY); if (memregion == NULL) return NULL; @@ -105,17 +100,11 @@ mapit(struct memregion *memregion) ulong nbytes = memregion->nbytes; memregion->requested = FALSE; - if (!request_mem_region(physaddr, nbytes, MYDRVNAME)) - ERRDRV("cannot reserve channel memory @0x%lx for 0x%lx-- no big deal", - physaddr, nbytes); - else + if (request_mem_region(physaddr, nbytes, MYDRVNAME)) memregion->requested = TRUE; memregion->mapped = ioremap_cache(physaddr, nbytes); - if (memregion->mapped == NULL) { - ERRDRV("cannot ioremap_cache channel memory @0x%lx for 0x%lx", - physaddr, nbytes); + if (!memregion->mapped) return FALSE; - } return TRUE; } @@ -179,10 +168,9 @@ memregion_readwrite(BOOL is_write, struct memregion *memregion, ulong offset, void *local, ulong nbytes) { - if (offset + nbytes > memregion->nbytes) { - ERRDRV("memregion_readwrite offset out of range!!"); + if (offset + nbytes > memregion->nbytes) return -EIO; - } + if (is_write) memcpy_toio(memregion->mapped + offset, local, nbytes); else diff --git a/drivers/staging/unisys/visorutil/periodic_work.c b/drivers/staging/unisys/visorutil/periodic_work.c index 411fd1ea0784..f8f2e2461b2e 100644 --- a/drivers/staging/unisys/visorutil/periodic_work.c +++ b/drivers/staging/unisys/visorutil/periodic_work.c @@ -90,7 +90,6 @@ BOOL visor_periodic_work_nextperiod(struct periodic_work *pw) goto unlock; } else if (queue_delayed_work(pw->workqueue, &pw->work, pw->jiffy_interval) < 0) { - ERRDEV(pw->devnam, "queue_delayed_work failed!"); pw->is_scheduled = FALSE; rc = FALSE; goto unlock; @@ -116,15 +115,12 @@ BOOL visor_periodic_work_start(struct periodic_work *pw) goto unlock; } if (pw->want_to_stop) { - ERRDEV(pw->devnam, - "dev_start_periodic_work failed!"); rc = FALSE; goto unlock; } INIT_DELAYED_WORK(&pw->work, &periodic_work_func); if (queue_delayed_work(pw->workqueue, &pw->work, pw->jiffy_interval) < 0) { - ERRDEV(pw->devnam, "%s queue_delayed_work failed!", __func__); rc = FALSE; goto unlock; } diff --git a/drivers/staging/unisys/visorutil/procobjecttree.c b/drivers/staging/unisys/visorutil/procobjecttree.c index 0672e8c9f686..0ba75547b2c5 100644 --- a/drivers/staging/unisys/visorutil/procobjecttree.c +++ b/drivers/staging/unisys/visorutil/procobjecttree.c @@ -96,8 +96,6 @@ createProcDir(const char *name, struct proc_dir_entry *parent) { struct proc_dir_entry *p = proc_mkdir_mode(name, S_IFDIR, parent); - if (p == NULL) - ERRDRV("failed to create /proc directory %s", name); return p; } @@ -107,8 +105,6 @@ createProcFile(const char *name, struct proc_dir_entry *parent, { struct proc_dir_entry *p = proc_create_data(name, 0, parent, fops, data); - if (p == NULL) - ERRDRV("failed to create /proc file %s", name); return p; } @@ -137,17 +133,16 @@ MYPROCTYPE *visor_proc_CreateType(struct proc_dir_entry *procDirRoot, MYPROCTYPE *rc = NULL, *type = NULL; struct proc_dir_entry *parent = NULL; - if (procDirRoot == NULL) { - ERRDRV("procDirRoot cannot be NULL!\n"); + if (procDirRoot == NULL) goto Away; - } - if (name == NULL || name[0] == NULL) { - ERRDRV("name must contain at least 1 node name!\n"); + + if (name == NULL || name[0] == NULL) goto Away; - } + type = kzalloc(sizeof(MYPROCTYPE), GFP_KERNEL | __GFP_NORETRY); if (type == NULL) goto Away; + type->name = name; type->propertyNames = propertyNames; type->nProperties = 0; @@ -222,13 +217,13 @@ MYPROCOBJECT *visor_proc_CreateObject(MYPROCTYPE *type, MYPROCOBJECT *obj = NULL, *rc = NULL; int i = 0; - if (type == NULL) { - ERRDRV("type cannot be NULL\n"); + if (type == NULL) goto Away; - } + obj = kzalloc(sizeof(MYPROCOBJECT), GFP_KERNEL | __GFP_NORETRY); if (obj == NULL) goto Away; + obj->type = type; obj->context = context; if (name == NULL) { @@ -332,10 +327,8 @@ static int seq_show(struct seq_file *seq, void *offset) { struct proc_dir_entry_context *ctx = seq->private; - if (ctx == NULL) { - ERRDRV("I don't have a freakin' clue..."); + if (ctx == NULL) return 0; - } (*ctx->show_property)(seq, ctx->procObject->context, ctx->propertyIndex); return 0; -- GitLab From 1b08872e59309458a54ed00cded95eeda43426e5 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Wed, 4 Mar 2015 12:14:26 -0500 Subject: [PATCH 03191/11651] staging: unisys: remove LOGWRN() macros and uniklog.h Remove the last set of macros from uniklog.h. Without LOGWRN() and friends, uniklog.h is empty so we can delete the file itself as well. This macro was not used a lot but the file was included in many places. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../staging/unisys/include/procobjecttree.h | 1 - drivers/staging/unisys/include/uisqueue.h | 1 - drivers/staging/unisys/include/uniklog.h | 57 ------------------- drivers/staging/unisys/uislib/uislib.c | 1 - drivers/staging/unisys/uislib/uisthread.c | 1 - drivers/staging/unisys/uislib/uisutils.c | 1 - drivers/staging/unisys/virthba/virthba.c | 1 - drivers/staging/unisys/virtpci/virtpci.c | 1 - drivers/staging/unisys/visorchannel/globals.h | 1 - drivers/staging/unisys/visorchipset/globals.h | 1 - drivers/staging/unisys/visorchipset/parser.h | 1 - .../unisys/visorchipset/visorchipset_main.c | 23 ++------ drivers/staging/unisys/visorutil/charqueue.h | 1 - drivers/staging/unisys/visorutil/easyproc.c | 1 - .../unisys/visorutil/memregion_direct.c | 1 - .../staging/unisys/visorutil/periodic_work.c | 9 --- .../staging/unisys/visorutil/visorkmodutils.c | 1 - 17 files changed, 6 insertions(+), 97 deletions(-) delete mode 100644 drivers/staging/unisys/include/uniklog.h diff --git a/drivers/staging/unisys/include/procobjecttree.h b/drivers/staging/unisys/include/procobjecttree.h index 1174056ec3d9..809c6794290e 100644 --- a/drivers/staging/unisys/include/procobjecttree.h +++ b/drivers/staging/unisys/include/procobjecttree.h @@ -26,7 +26,6 @@ #ifndef __PROCOBJECTTREE_H__ #define __PROCOBJECTTREE_H__ -#include "uniklog.h" #include "timskmod.h" /* These are opaque structures to users. diff --git a/drivers/staging/unisys/include/uisqueue.h b/drivers/staging/unisys/include/uisqueue.h index 25b6181d78af..08ba16ea840e 100644 --- a/drivers/staging/unisys/include/uisqueue.h +++ b/drivers/staging/unisys/include/uisqueue.h @@ -25,7 +25,6 @@ #include "linux/version.h" #include "iochannel.h" -#include "uniklog.h" #include #include #include diff --git a/drivers/staging/unisys/include/uniklog.h b/drivers/staging/unisys/include/uniklog.h deleted file mode 100644 index cca662a3f3e4..000000000000 --- a/drivers/staging/unisys/include/uniklog.h +++ /dev/null @@ -1,57 +0,0 @@ -/* uniklog.h - * - * Copyright (C) 2010 - 2013 UNISYS CORPORATION - * 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 as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * 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, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for more - * details. - */ - -/* This module contains macros to aid developers in logging messages. - * - * This module is affected by the DEBUG compiletime option. - * - */ -#ifndef __UNIKLOG_H__ -#define __UNIKLOG_H__ - -#include - -/* - * # LOGWRN - * - * \brief Log warning message - Logs a message at the LOG_WARNING level, - * including source line number information - * - * \param devname the device name of the device reporting this message, or - * NULL if this message is NOT device-related. - * \param fmt printf()-style format string containing the message to log. - * \param args Optional arguments to be formatted and inserted into the format - * \param string. - * \return nothing - * - * Logs the specified error message at the LOG_WARNING level. It will also - * include the file, line number, and function name of where the error - * originated in the log message. - */ -#define LOGWRN(fmt, args...) pr_warn(fmt, ## args) -#define LOGWRNDEV(devname, fmt, args...) \ - pr_warn("%s " fmt, devname, ## args) -#define LOGWRNNAME(vnic, fmt, args...) \ - do { \ - if (vnic != NULL) { \ - pr_warn("%s " fmt, vnic->name, ## args); \ - } else { \ - pr_warn(fmt, ## args); \ - } \ - } while (0) - -#endif /* __UNIKLOG_H__ */ diff --git a/drivers/staging/unisys/uislib/uislib.c b/drivers/staging/unisys/uislib/uislib.c index 9fe96e7d5693..4318f06f6e7e 100644 --- a/drivers/staging/unisys/uislib/uislib.c +++ b/drivers/staging/unisys/uislib/uislib.c @@ -29,7 +29,6 @@ #include #include -#include "uniklog.h" #include "diagnostics/appos_subsystems.h" #include "uisutils.h" #include "vbuschannel.h" diff --git a/drivers/staging/unisys/uislib/uisthread.c b/drivers/staging/unisys/uislib/uisthread.c index 5b0041c4a137..bbe2a23784a5 100644 --- a/drivers/staging/unisys/uislib/uisthread.c +++ b/drivers/staging/unisys/uislib/uisthread.c @@ -20,7 +20,6 @@ #include #include #include -#include "uniklog.h" #include "uisutils.h" #include "uisthread.h" diff --git a/drivers/staging/unisys/uislib/uisutils.c b/drivers/staging/unisys/uislib/uisutils.c index 9f3f0ab6ca49..26ab76526813 100644 --- a/drivers/staging/unisys/uislib/uisutils.c +++ b/drivers/staging/unisys/uislib/uisutils.c @@ -21,7 +21,6 @@ #include #include #include -#include "uniklog.h" #include "uisutils.h" #include "version.h" #include "vbushelper.h" diff --git a/drivers/staging/unisys/virthba/virthba.c b/drivers/staging/unisys/virthba/virthba.c index 23874de4e354..e5b0dd8b4719 100644 --- a/drivers/staging/unisys/virthba/virthba.c +++ b/drivers/staging/unisys/virthba/virthba.c @@ -31,7 +31,6 @@ #include #endif -#include "uniklog.h" #include "diagnostics/appos_subsystems.h" #include "uisutils.h" #include "uisqueue.h" diff --git a/drivers/staging/unisys/virtpci/virtpci.c b/drivers/staging/unisys/virtpci/virtpci.c index 87336b6591ba..43b573611d51 100644 --- a/drivers/staging/unisys/virtpci/virtpci.c +++ b/drivers/staging/unisys/virtpci/virtpci.c @@ -21,7 +21,6 @@ #ifdef CONFIG_MODVERSIONS #include #endif -#include "uniklog.h" #include "diagnostics/appos_subsystems.h" #include "uisutils.h" #include "vbuschannel.h" diff --git a/drivers/staging/unisys/visorchannel/globals.h b/drivers/staging/unisys/visorchannel/globals.h index 581ed83fe6d0..0ed8e1d8033a 100644 --- a/drivers/staging/unisys/visorchannel/globals.h +++ b/drivers/staging/unisys/visorchannel/globals.h @@ -18,7 +18,6 @@ #ifndef __VISORCHANNEL_GLOBALS_H__ #define __VISORCHANNEL_GLOBALS_H__ -#include "uniklog.h" #include "timskmod.h" #include "memregion.h" #include "version.h" diff --git a/drivers/staging/unisys/visorchipset/globals.h b/drivers/staging/unisys/visorchipset/globals.h index a1d35d4bef2e..f76e498a36b5 100644 --- a/drivers/staging/unisys/visorchipset/globals.h +++ b/drivers/staging/unisys/visorchipset/globals.h @@ -18,7 +18,6 @@ #ifndef __VISORCHIPSET_GLOBALS_H__ #define __VISORCHIPSET_GLOBALS_H__ -#include "uniklog.h" #include "diagnostics/appos_subsystems.h" #include "timskmod.h" #include "visorchipset.h" diff --git a/drivers/staging/unisys/visorchipset/parser.h b/drivers/staging/unisys/visorchipset/parser.h index 9fbe3b5b7cc3..7e015d1e744d 100644 --- a/drivers/staging/unisys/visorchipset/parser.h +++ b/drivers/staging/unisys/visorchipset/parser.h @@ -20,7 +20,6 @@ #include -#include "uniklog.h" #include "timskmod.h" #include "channel.h" diff --git a/drivers/staging/unisys/visorchipset/visorchipset_main.c b/drivers/staging/unisys/visorchipset/visorchipset_main.c index 74a27e37f437..ec258aeba768 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset_main.c +++ b/drivers/staging/unisys/visorchipset/visorchipset_main.c @@ -22,7 +22,6 @@ #include "periodic_work.h" #include "file.h" #include "parser.h" -#include "uniklog.h" #include "uisutils.h" #include "controlvmcompletionstatus.h" #include "guestlinuxdebug.h" @@ -1719,27 +1718,17 @@ handle_command(struct controlvm_message inmsg, HOSTADDRESS channel_addr) parser_ctx = parser_init_byteStream(parametersAddr, parametersBytes, isLocalAddr, &retry); - if (!parser_ctx) { - if (retry) { - LOGWRN("throttling to copy payload"); - return FALSE; - } - LOGWRN("parsing failed"); - LOGWRN("inmsg.hdr.Id=0x%lx", (ulong) inmsg.hdr.id); - LOGWRN("parametersAddr=0x%llx", (u64) parametersAddr); - LOGWRN("parametersBytes=%lu", (ulong) parametersBytes); - LOGWRN("isLocalAddr=%d", isLocalAddr); - } + if (!parser_ctx && retry) + return FALSE; } if (!isLocalAddr) { controlvm_init_response(&ackmsg, &inmsg.hdr, CONTROLVM_RESP_SUCCESS); - if ((ControlVm_channel) - && - (!visorchannel_signalinsert - (ControlVm_channel, CONTROLVM_QUEUE_ACK, &ackmsg))) - LOGWRN("failed to send ACK failed"); + if (ControlVm_channel) + visorchannel_signalinsert(ControlVm_channel, + CONTROLVM_QUEUE_ACK, + &ackmsg); } switch (inmsg.hdr.id) { case CONTROLVM_CHIPSET_INIT: diff --git a/drivers/staging/unisys/visorutil/charqueue.h b/drivers/staging/unisys/visorutil/charqueue.h index 56c1f79a54b0..f46a776b935b 100644 --- a/drivers/staging/unisys/visorutil/charqueue.h +++ b/drivers/staging/unisys/visorutil/charqueue.h @@ -18,7 +18,6 @@ #ifndef __CHARQUEUE_H__ #define __CHARQUEUE_H__ -#include "uniklog.h" #include "timskmod.h" /* struct charqueue is an opaque structure to users. diff --git a/drivers/staging/unisys/visorutil/easyproc.c b/drivers/staging/unisys/visorutil/easyproc.c index 53408056268e..3cb55d39370b 100644 --- a/drivers/staging/unisys/visorutil/easyproc.c +++ b/drivers/staging/unisys/visorutil/easyproc.c @@ -34,7 +34,6 @@ #include -#include "uniklog.h" #include "timskmod.h" #include "easyproc.h" diff --git a/drivers/staging/unisys/visorutil/memregion_direct.c b/drivers/staging/unisys/visorutil/memregion_direct.c index 07aa2975bd6a..eb7422fbe20f 100644 --- a/drivers/staging/unisys/visorutil/memregion_direct.c +++ b/drivers/staging/unisys/visorutil/memregion_direct.c @@ -20,7 +20,6 @@ * channel memory (in main memory of the host system) from code running in * a virtual partition. */ -#include "uniklog.h" #include "timskmod.h" #include "memregion.h" diff --git a/drivers/staging/unisys/visorutil/periodic_work.c b/drivers/staging/unisys/visorutil/periodic_work.c index f8f2e2461b2e..abbfb48894f3 100644 --- a/drivers/staging/unisys/visorutil/periodic_work.c +++ b/drivers/staging/unisys/visorutil/periodic_work.c @@ -19,7 +19,6 @@ * Helper functions to schedule periodic work in Linux kernel mode. */ -#include "uniklog.h" #include "timskmod.h" #include "periodic_work.h" @@ -193,14 +192,6 @@ BOOL visor_periodic_work_stop(struct periodic_work *pw) } if (pw->is_scheduled) { write_unlock(&pw->lock); - WARNDEV(pw->devnam, - "waiting for delayed work..."); - /* We rely on the delayed work function running here, - * and eventually calling - * visor_periodic_work_nextperiod(), - * which will see that want_to_stop is set, and - * subsequently clear is_scheduled. - */ SLEEPJIFFIES(10); write_lock(&pw->lock); } else { diff --git a/drivers/staging/unisys/visorutil/visorkmodutils.c b/drivers/staging/unisys/visorutil/visorkmodutils.c index 556e2642d2d9..62f0f7046e17 100644 --- a/drivers/staging/unisys/visorutil/visorkmodutils.c +++ b/drivers/staging/unisys/visorutil/visorkmodutils.c @@ -15,7 +15,6 @@ * details. */ -#include "uniklog.h" #include "timskmod.h" #define MYDRVNAME "timskmodutils" -- GitLab From 535f2e7df820d84fd8a4395bb52f19846f6a2290 Mon Sep 17 00:00:00 2001 From: Rickard Strandqvist Date: Sat, 7 Feb 2015 15:56:10 +0100 Subject: [PATCH 03192/11651] staging: rtl8192u: r8192U_core: Fix driver_info dereference as a null pointer Fix possible use of use of driver_info as a null pointer in query_rxdesc_status() This could happen if stats->RxIs40MHzPacket still has the default value of zero. Signed-off-by: Rickard Strandqvist Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/r8192U_core.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c index 0d64d2dfd38c..8f7a3219eff1 100644 --- a/drivers/staging/rtl8192u/r8192U_core.c +++ b/drivers/staging/rtl8192u/r8192U_core.c @@ -4476,13 +4476,10 @@ static void query_rxdesc_status(struct sk_buff *skb, skb_pull(skb, stats->RxBufShift + stats->RxDrvInfoSize); } - /* for debug 2008.5.29 */ - - //added by vivi, for MP, 20080108 - stats->RxIs40MHzPacket = driver_info->BW; - if (stats->RxDrvInfoSize != 0) + if (driver_info) { + stats->RxIs40MHzPacket = driver_info->BW; TranslateRxSignalStuff819xUsb(skb, stats, driver_info); - + } } static void rtl8192_rx_nomal(struct sk_buff *skb) -- GitLab From 8edd9e7cf1a051688923c66bdba0cab38cdb7d9d Mon Sep 17 00:00:00 2001 From: Tolga Ceylan Date: Thu, 19 Feb 2015 21:54:08 -0800 Subject: [PATCH 03193/11651] Staging: rtl8192u: r819xU_firmware: removed commented out variable Removed commented out variable Signed-off-by: Tolga Ceylan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/r819xU_firmware.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/rtl8192u/r819xU_firmware.c b/drivers/staging/rtl8192u/r819xU_firmware.c index 1a3a09f81895..f0ae3abd1185 100644 --- a/drivers/staging/rtl8192u/r819xU_firmware.c +++ b/drivers/staging/rtl8192u/r819xU_firmware.c @@ -37,7 +37,6 @@ static bool fw_download_code(struct net_device *dev, u8 *code_virtual_address, bool rt_status = true; u16 frag_threshold; u16 frag_length, frag_offset = 0; - //u16 total_size; int i; rt_firmware *pfirmware = priv->pFirmware; -- GitLab From 23723ea046d7ee7cdf0144cf244170a7c39a2e60 Mon Sep 17 00:00:00 2001 From: Tolga Ceylan Date: Thu, 19 Feb 2015 21:54:09 -0800 Subject: [PATCH 03194/11651] Staging: rtl8192u: r819xU_firmware: removed commented out assert Removed an assert that was commented out. The comment provides no documentation value as rt_status is properly handled. Signed-off-by: Tolga Ceylan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/r819xU_firmware.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/rtl8192u/r819xU_firmware.c b/drivers/staging/rtl8192u/r819xU_firmware.c index f0ae3abd1185..ff4ce790355f 100644 --- a/drivers/staging/rtl8192u/r819xU_firmware.c +++ b/drivers/staging/rtl8192u/r819xU_firmware.c @@ -329,8 +329,6 @@ bool init_firmware(struct net_device *dev) } RT_TRACE(COMP_FIRMWARE, "Firmware Download Success\n"); - //assert(pfirmware->firmware_status == FW_STATUS_5_READY, ("Firmware Download Fail\n")); - return rt_status; download_firmware_fail: -- GitLab From 6f4380427bf8447c8282930d8aeb5949b37ee4d3 Mon Sep 17 00:00:00 2001 From: Tolga Ceylan Date: Thu, 19 Feb 2015 21:54:10 -0800 Subject: [PATCH 03195/11651] Staging: rtl9182u: r819xU_firmware: Replaced C99 comments with C89 Replaced C99 comments with C89. Signed-off-by: Tolga Ceylan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/r819xU_firmware.c | 33 +++++++++++----------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/drivers/staging/rtl8192u/r819xU_firmware.c b/drivers/staging/rtl8192u/r819xU_firmware.c index ff4ce790355f..e208c899bc5e 100644 --- a/drivers/staging/rtl8192u/r819xU_firmware.c +++ b/drivers/staging/rtl8192u/r819xU_firmware.c @@ -47,7 +47,7 @@ static bool fw_download_code(struct net_device *dev, u8 *code_virtual_address, u8 index; firmware_init_param(dev); - //Fragmentation might be required + /* Fragmentation might be required */ frag_threshold = pfirmware->cmdpacket_frag_thresold; do { if ((buffer_len - frag_offset) > frag_threshold) { @@ -106,19 +106,20 @@ static bool fw_download_code(struct net_device *dev, u8 *code_virtual_address, } -//----------------------------------------------------------------------------- -// Procedure: Check whether main code is download OK. If OK, turn on CPU -// -// Description: CPU register locates in different page against general register. -// Switch to CPU register in the begin and switch back before return -// -// -// Arguments: The pointer of the adapter -// -// Returns: -// NDIS_STATUS_FAILURE - the following initialization process should be terminated -// NDIS_STATUS_SUCCESS - if firmware initialization process success -//----------------------------------------------------------------------------- +/* + * Procedure: Check whether main code is download OK. If OK, turn on CPU + * + * Description: CPU register locates in different page against general register. + * Switch to CPU register in the begin and switch back before return + * + * + * Arguments: The pointer of the adapter + * + * Returns: + * NDIS_STATUS_FAILURE - the following initialization process should + * be terminated + * NDIS_STATUS_SUCCESS - if firmware initialization process success + */ static bool CPUcheck_maincodeok_turnonCPU(struct net_device *dev) { bool rt_status = true; @@ -221,7 +222,7 @@ bool init_firmware(struct net_device *dev) /* it is called by reset */ rst_opt = OPT_SYSTEM_RESET; starting_state = FW_INIT_STEP0_BOOT; - // TODO: system reset + /* TODO: system reset */ } else if (pfirmware->firmware_status == FW_STATUS_5_READY) { /* it is called by Initialize */ @@ -290,7 +291,7 @@ bool init_firmware(struct net_device *dev) * will set polling bit when firmware code is also configured */ pfirmware->firmware_status = FW_STATUS_1_MOVE_BOOT_CODE; - //mdelay(1000); + /* mdelay(1000); */ /* * To initialize IMEM, CPU move code from 0x80000080, * hence, we send 0x80 byte packet -- GitLab From 5877ecc3f70fc3af1fb36c25503391a0244b461f Mon Sep 17 00:00:00 2001 From: Tolga Ceylan Date: Fri, 20 Feb 2015 18:14:24 -0800 Subject: [PATCH 03196/11651] Staging: rtl8192u: ieee80211: dot11d: added parenthesis to RESET_CIE_WATCHDOG macro Added parenthesis to RESET_CIE_WATCHDOG macro to resolve checkpatch error. Signed-off-by: Tolga Ceylan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/ieee80211/dot11d.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8192u/ieee80211/dot11d.h b/drivers/staging/rtl8192u/ieee80211/dot11d.h index bd75e29adc2c..8ae673b217d8 100644 --- a/drivers/staging/rtl8192u/ieee80211/dot11d.h +++ b/drivers/staging/rtl8192u/ieee80211/dot11d.h @@ -53,7 +53,7 @@ typedef struct _RT_DOT11D_INFO { #define CIE_WATCHDOG_TH 1 #define GET_CIE_WATCHDOG(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog) -#define RESET_CIE_WATCHDOG(__pIeeeDev) GET_CIE_WATCHDOG(__pIeeeDev) = 0 +#define RESET_CIE_WATCHDOG(__pIeeeDev) (GET_CIE_WATCHDOG(__pIeeeDev) = 0) #define UPDATE_CIE_WATCHDOG(__pIeeeDev) (++GET_CIE_WATCHDOG(__pIeeeDev)) #define IS_DOT11D_STATE_DONE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE) -- GitLab From d08c028c75e293598b9f3e2c8ad87fb43199298c Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sat, 21 Feb 2015 18:53:45 -0800 Subject: [PATCH 03197/11651] staging: rtl8192x: Remove use of seq_printf return value The seq_printf return value, because it's frequently misused, will eventually be converted to void. See: commit 1f33c41c03da ("seq_file: Rename seq_overflow() to seq_has_overflowed() and make public") Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtllib_module.c | 4 +++- drivers/staging/rtl8192u/ieee80211/ieee80211_module.c | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rtl8192e/rtllib_module.c b/drivers/staging/rtl8192e/rtllib_module.c index 0cf38091f8c5..248cc0d352ad 100644 --- a/drivers/staging/rtl8192e/rtllib_module.c +++ b/drivers/staging/rtl8192e/rtllib_module.c @@ -207,7 +207,9 @@ static struct proc_dir_entry *rtllib_proc; static int show_debug_level(struct seq_file *m, void *v) { - return seq_printf(m, "0x%08X\n", rtllib_debug_level); + seq_printf(m, "0x%08X\n", rtllib_debug_level); + + return 0; } static ssize_t write_debug_level(struct file *file, const char __user *buffer, diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c index 014922565588..9a607253823c 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c @@ -245,7 +245,9 @@ static struct proc_dir_entry *ieee80211_proc; static int show_debug_level(struct seq_file *m, void *v) { - return seq_printf(m, "0x%08X\n", ieee80211_debug_level); + seq_printf(m, "0x%08X\n", ieee80211_debug_level); + + return 0; } static ssize_t write_debug_level(struct file *file, const char __user *buffer, -- GitLab From b6b0012c2d410704782301299d36d311f9a39334 Mon Sep 17 00:00:00 2001 From: Quentin Lambert Date: Thu, 5 Mar 2015 14:12:15 +0100 Subject: [PATCH 03198/11651] staging: rtl8192e: Remove unnecessary OOM message This patch reduces the kernel size by removing error messages that duplicate the normal OOM message. A simplified version of the semantic patch that finds this problem is as follows: (http://coccinelle.lip6.fr) @@ identifier f,print,l; expression e; constant char[] c; @@ e = \(kzalloc\|kmalloc\|devm_kzalloc\|devm_kmalloc\)(...); if (e == NULL) { <+... - print(...,c,...); ... when any ( goto l; | return ...; ) ...+> } Signed-off-by: Quentin Lambert Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtllib_module.c | 10 +++------- drivers/staging/rtl8192e/rtllib_rx.c | 11 ++++------- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/drivers/staging/rtl8192e/rtllib_module.c b/drivers/staging/rtl8192e/rtllib_module.c index 248cc0d352ad..32cc8df9d3a7 100644 --- a/drivers/staging/rtl8192e/rtllib_module.c +++ b/drivers/staging/rtl8192e/rtllib_module.c @@ -72,11 +72,8 @@ static inline int rtllib_networks_allocate(struct rtllib_device *ieee) ieee->networks = kzalloc( MAX_NETWORK_COUNT * sizeof(struct rtllib_network), GFP_KERNEL); - if (!ieee->networks) { - printk(KERN_WARNING "%s: Out of memory allocating beacons\n", - ieee->dev->name); + if (!ieee->networks) return -ENOMEM; - } return 0; } @@ -161,10 +158,9 @@ struct net_device *alloc_rtllib(int sizeof_priv) rtllib_softmac_init(ieee); ieee->pHTInfo = kzalloc(sizeof(struct rt_hi_throughput), GFP_KERNEL); - if (ieee->pHTInfo == NULL) { - RTLLIB_DEBUG(RTLLIB_DL_ERR, "can't alloc memory for HTInfo\n"); + if (ieee->pHTInfo == NULL) return NULL; - } + HTUpdateDefaultSetting(ieee); HTInitializeHTInfo(ieee); TSInitialize(ieee); diff --git a/drivers/staging/rtl8192e/rtllib_rx.c b/drivers/staging/rtl8192e/rtllib_rx.c index 1664040efdab..0a9cf445a0ef 100644 --- a/drivers/staging/rtl8192e/rtllib_rx.c +++ b/drivers/staging/rtl8192e/rtllib_rx.c @@ -394,10 +394,9 @@ static int is_duplicate_packet(struct rtllib_device *ieee, } if (p == &ieee->ibss_mac_hash[index]) { entry = kmalloc(sizeof(struct ieee_ibss_seq), GFP_ATOMIC); - if (!entry) { - printk(KERN_WARNING "Cannot malloc new mac entry\n"); + if (!entry) return 0; - } + memcpy(entry->mac, mac, ETH_ALEN); entry->seq_num[tid] = seq; entry->frag_num[tid] = frag; @@ -1345,11 +1344,9 @@ static int rtllib_rx_InfraAdhoc(struct rtllib_device *ieee, struct sk_buff *skb, /* skb: hdr + (possible reassembled) full plaintext payload */ payload = skb->data + hdrlen; rxb = kmalloc(sizeof(struct rtllib_rxb), GFP_ATOMIC); - if (rxb == NULL) { - RTLLIB_DEBUG(RTLLIB_DL_ERR, - "%s(): kmalloc rxb error\n", __func__); + if (rxb == NULL) goto rx_dropped; - } + /* to parse amsdu packets */ /* qos data packets & reserved bit is 1 */ if (parse_subframe(ieee, skb, rx_stats, rxb, src, dst) == 0) { -- GitLab From ad22d55c4b304a163c7372c00768f50adaecc686 Mon Sep 17 00:00:00 2001 From: Matteo Semenzato Date: Wed, 4 Mar 2015 19:53:10 +0100 Subject: [PATCH 03199/11651] Staging: rtl8192e: remove assignment of function parameter This patch removes the assignment of a function parameter that has no effect. Signed-off-by: Matteo Semenzato Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtllib_rx.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/rtl8192e/rtllib_rx.c b/drivers/staging/rtl8192e/rtllib_rx.c index 0a9cf445a0ef..d640420f0076 100644 --- a/drivers/staging/rtl8192e/rtllib_rx.c +++ b/drivers/staging/rtl8192e/rtllib_rx.c @@ -1225,7 +1225,6 @@ static void rtllib_rx_indicate_pkt_legacy(struct rtllib_device *ieee, } } kfree(rxb); - rxb = NULL; } static int rtllib_rx_InfraAdhoc(struct rtllib_device *ieee, struct sk_buff *skb, -- GitLab From 0cd189a42da07c89c809debc1f6a75f5ec0f5c43 Mon Sep 17 00:00:00 2001 From: Dmitry Kalinkin Date: Thu, 26 Feb 2015 18:53:09 +0300 Subject: [PATCH 03200/11651] staging: vme: use image mutex for ioctl() This implements more granular locking in vme_user_ioctl() by using separate locks for each devfs device. This also provides a synchronization between vme_user_read(), vme_user_write() and vme_user_ioctl(). Signed-off-by: Dmitry Kalinkin Cc: Martyn Welch Cc: Igor Alekseev Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme/devices/vme_user.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/staging/vme/devices/vme_user.c b/drivers/staging/vme/devices/vme_user.c index 8b1f53331433..87318386034b 100644 --- a/drivers/staging/vme/devices/vme_user.c +++ b/drivers/staging/vme/devices/vme_user.c @@ -41,7 +41,6 @@ #include "vme_user.h" -static DEFINE_MUTEX(vme_user_mutex); static const char driver_name[] = "vme_user"; static int bus[VME_USER_BUS_MAX]; @@ -555,10 +554,12 @@ static long vme_user_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { int ret; + struct inode *inode = file_inode(file); + unsigned int minor = MINOR(inode->i_rdev); - mutex_lock(&vme_user_mutex); - ret = vme_user_ioctl(file_inode(file), file, cmd, arg); - mutex_unlock(&vme_user_mutex); + mutex_lock(&image[minor].mutex); + ret = vme_user_ioctl(inode, file, cmd, arg); + mutex_unlock(&image[minor].mutex); return ret; } -- GitLab From c74a804f115bdedcac72ea52ca33f46cfae3b74f Mon Sep 17 00:00:00 2001 From: Dmitry Kalinkin Date: Thu, 26 Feb 2015 18:53:10 +0300 Subject: [PATCH 03201/11651] staging: vme: mmap() support for vme_user We also make sure that user won't be able to reconfigure the window while it is mmap'ed. Signed-off-by: Dmitry Kalinkin Cc: Martyn Welch Cc: Igor Alekseev Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme/devices/vme_user.c | 85 ++++++++++++++++++++++++++ drivers/vme/vme.c | 26 ++++++++ include/linux/vme.h | 1 + 3 files changed, 112 insertions(+) diff --git a/drivers/staging/vme/devices/vme_user.c b/drivers/staging/vme/devices/vme_user.c index 87318386034b..19ba749bb122 100644 --- a/drivers/staging/vme/devices/vme_user.c +++ b/drivers/staging/vme/devices/vme_user.c @@ -17,6 +17,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#include #include #include #include @@ -99,6 +100,7 @@ struct image_desc { struct device *device; /* Sysfs device */ struct vme_resource *resource; /* VME resource */ int users; /* Number of current users */ + int mmap_count; /* Number of current mmap's */ }; static struct image_desc image[VME_DEVS]; @@ -134,6 +136,10 @@ static ssize_t vme_user_write(struct file *, const char __user *, size_t, loff_t *); static loff_t vme_user_llseek(struct file *, loff_t, int); static long vme_user_unlocked_ioctl(struct file *, unsigned int, unsigned long); +static int vme_user_mmap(struct file *file, struct vm_area_struct *vma); + +static void vme_user_vm_open(struct vm_area_struct *vma); +static void vme_user_vm_close(struct vm_area_struct *vma); static int vme_user_match(struct vme_dev *); static int vme_user_probe(struct vme_dev *); @@ -147,6 +153,17 @@ static const struct file_operations vme_user_fops = { .llseek = vme_user_llseek, .unlocked_ioctl = vme_user_unlocked_ioctl, .compat_ioctl = vme_user_unlocked_ioctl, + .mmap = vme_user_mmap, +}; + +struct vme_user_vma_priv { + unsigned int minor; + atomic_t refcnt; +}; + +static const struct vm_operations_struct vme_user_vm_ops = { + .open = vme_user_vm_open, + .close = vme_user_vm_close, }; @@ -488,6 +505,11 @@ static int vme_user_ioctl(struct inode *inode, struct file *file, case VME_SET_MASTER: + if (image[minor].mmap_count != 0) { + pr_warn("Can't adjust mapped window\n"); + return -EPERM; + } + copied = copy_from_user(&master, argp, sizeof(master)); if (copied != 0) { pr_warn("Partial copy from userspace\n"); @@ -564,6 +586,69 @@ vme_user_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg) return ret; } +static void vme_user_vm_open(struct vm_area_struct *vma) +{ + struct vme_user_vma_priv *vma_priv = vma->vm_private_data; + + atomic_inc(&vma_priv->refcnt); +} + +static void vme_user_vm_close(struct vm_area_struct *vma) +{ + struct vme_user_vma_priv *vma_priv = vma->vm_private_data; + unsigned int minor = vma_priv->minor; + + if (!atomic_dec_and_test(&vma_priv->refcnt)) + return; + + mutex_lock(&image[minor].mutex); + image[minor].mmap_count--; + mutex_unlock(&image[minor].mutex); + + kfree(vma_priv); +} + +static int vme_user_master_mmap(unsigned int minor, struct vm_area_struct *vma) +{ + int err; + struct vme_user_vma_priv *vma_priv; + + mutex_lock(&image[minor].mutex); + + err = vme_master_mmap(image[minor].resource, vma); + if (err) { + mutex_unlock(&image[minor].mutex); + return err; + } + + vma_priv = kmalloc(sizeof(struct vme_user_vma_priv), GFP_KERNEL); + if (vma_priv == NULL) { + mutex_unlock(&image[minor].mutex); + return -ENOMEM; + } + + vma_priv->minor = minor; + atomic_set(&vma_priv->refcnt, 1); + vma->vm_ops = &vme_user_vm_ops; + vma->vm_private_data = vma_priv; + + image[minor].mmap_count++; + + mutex_unlock(&image[minor].mutex); + + return 0; +} + +static int vme_user_mmap(struct file *file, struct vm_area_struct *vma) +{ + unsigned int minor = MINOR(file_inode(file)->i_rdev); + + if (type[minor] == MASTER_MINOR) + return vme_user_master_mmap(minor, vma); + + return -ENODEV; +} + /* * Unallocate a previously allocated buffer diff --git a/drivers/vme/vme.c b/drivers/vme/vme.c index d95fb848dd03..6bab2c4ed77c 100644 --- a/drivers/vme/vme.c +++ b/drivers/vme/vme.c @@ -609,6 +609,32 @@ unsigned int vme_master_rmw(struct vme_resource *resource, unsigned int mask, } EXPORT_SYMBOL(vme_master_rmw); +int vme_master_mmap(struct vme_resource *resource, struct vm_area_struct *vma) +{ + struct vme_master_resource *image; + phys_addr_t phys_addr; + unsigned long vma_size; + + if (resource->type != VME_MASTER) { + pr_err("Not a master resource\n"); + return -EINVAL; + } + + image = list_entry(resource->entry, struct vme_master_resource, list); + phys_addr = image->bus_resource.start + (vma->vm_pgoff << PAGE_SHIFT); + vma_size = vma->vm_end - vma->vm_start; + + if (phys_addr + vma_size > image->bus_resource.end + 1) { + pr_err("Map size cannot exceed the window size\n"); + return -EFAULT; + } + + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + + return vm_iomap_memory(vma, phys_addr, vma->vm_end - vma->vm_start); +} +EXPORT_SYMBOL(vme_master_mmap); + void vme_master_free(struct vme_resource *resource) { struct vme_master_resource *master_image; diff --git a/include/linux/vme.h b/include/linux/vme.h index 8cd6f19ca518..79242e9c06b8 100644 --- a/include/linux/vme.h +++ b/include/linux/vme.h @@ -137,6 +137,7 @@ ssize_t vme_master_read(struct vme_resource *, void *, size_t, loff_t); ssize_t vme_master_write(struct vme_resource *, void *, size_t, loff_t); unsigned int vme_master_rmw(struct vme_resource *, unsigned int, unsigned int, unsigned int, loff_t); +int vme_master_mmap(struct vme_resource *resource, struct vm_area_struct *vma); void vme_master_free(struct vme_resource *); struct vme_resource *vme_dma_request(struct vme_dev *, u32); -- GitLab From 08e03c268e3af302649bb85f79fb7c78c9e22ec8 Mon Sep 17 00:00:00 2001 From: Martyn Welch Date: Thu, 26 Feb 2015 18:53:11 +0300 Subject: [PATCH 03202/11651] vme: tsi148: Master windows support USERx and CR/CSR accesses, not slaves The tsi148 driver is registering the slave images as supporting the "USER" access modes and CR/CSR access mode rather than the master images as it should. Remove the incorrect case entries for these modes from the tsi148_slave_set() function, stop registering slave_images as supporting these modes and instead register master windows as supporting these modes. Signed-off-by: Martyn Welch Acked-by: Dmitry Kalinkin Signed-off-by: Greg Kroah-Hartman --- drivers/vme/bridges/vme_tsi148.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/vme/bridges/vme_tsi148.c b/drivers/vme/bridges/vme_tsi148.c index e07cfa8001bb..895c2a31918d 100644 --- a/drivers/vme/bridges/vme_tsi148.c +++ b/drivers/vme/bridges/vme_tsi148.c @@ -587,11 +587,6 @@ static int tsi148_slave_set(struct vme_slave_resource *image, int enabled, granularity = 0x10000; addr |= TSI148_LCSR_ITAT_AS_A64; break; - case VME_CRCSR: - case VME_USER1: - case VME_USER2: - case VME_USER3: - case VME_USER4: default: dev_err(tsi148_bridge->parent, "Invalid address space\n"); return -EINVAL; @@ -2471,7 +2466,8 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id) master_image->locked = 0; master_image->number = i; master_image->address_attr = VME_A16 | VME_A24 | VME_A32 | - VME_A64; + VME_A64 | VME_CRCSR | VME_USER1 | VME_USER2 | + VME_USER3 | VME_USER4; master_image->cycle_attr = VME_SCT | VME_BLT | VME_MBLT | VME_2eVME | VME_2eSST | VME_2eSSTB | VME_2eSST160 | VME_2eSST267 | VME_2eSST320 | VME_SUPER | VME_USER | @@ -2500,8 +2496,7 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id) slave_image->locked = 0; slave_image->number = i; slave_image->address_attr = VME_A16 | VME_A24 | VME_A32 | - VME_A64 | VME_CRCSR | VME_USER1 | VME_USER2 | - VME_USER3 | VME_USER4; + VME_A64; slave_image->cycle_attr = VME_SCT | VME_BLT | VME_MBLT | VME_2eVME | VME_2eSST | VME_2eSSTB | VME_2eSST160 | VME_2eSST267 | VME_2eSST320 | VME_SUPER | VME_USER | -- GitLab From 4c1d2dcb64db1d881d1822b5789022a03bc6abe4 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 3 Mar 2015 09:55:43 -0300 Subject: [PATCH 03203/11651] staging: dgap: Avoid name collision Building for ARM64 leads to the following build warning: In file included from drivers/staging/dgap/dgap.c:66:0: drivers/staging/dgap/dgap.h:124:0: warning: "PCI_IO_SIZE" redefined #define PCI_IO_SIZE 0x00200000 ^ In file included from ./arch/arm64/include/asm/page.h:66:0, from include/linux/mm_types.h:15, from include/linux/sched.h:27, from ./arch/arm64/include/asm/compat.h:25, from ./arch/arm64/include/asm/stat.h:23, from include/linux/stat.h:5, from include/linux/module.h:10, from drivers/staging/dgap/dgap.c:47: ./arch/arm64/include/asm/memory.h:39:0: note: this is the location of the previous definition #define PCI_IO_SIZE SZ_16M ^ Use PCI_IO_SIZE_DGAP to avoid the name collision. Reported-by: Olof's autobuilder Signed-off-by: Fabio Estevam Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgap/dgap.c | 2 +- drivers/staging/dgap/dgap.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/dgap/dgap.c b/drivers/staging/dgap/dgap.c index 914e332e13a1..d4d98a78f3ac 100644 --- a/drivers/staging/dgap/dgap.c +++ b/drivers/staging/dgap/dgap.c @@ -2196,7 +2196,7 @@ static struct board_t *dgap_found_board(struct pci_dev *pdev, int id, * will be mapped into the low 2MB of the 4MB memory space */ brd->port = brd->membase + PCI_IO_OFFSET; - brd->port_end = brd->port + PCI_IO_SIZE; + brd->port_end = brd->port + PCI_IO_SIZE_DGAP; /* * Special initialization for non-PLX boards diff --git a/drivers/staging/dgap/dgap.h b/drivers/staging/dgap/dgap.h index 684033156e8c..a2e5b26c673a 100644 --- a/drivers/staging/dgap/dgap.h +++ b/drivers/staging/dgap/dgap.h @@ -121,7 +121,7 @@ #define PCI_IO_OFFSET 0x00200000 /* Size of IO (2MB) */ -#define PCI_IO_SIZE 0x00200000 +#define PCI_IO_SIZE_DGAP 0x00200000 /* Number of boards we support at once. */ #define MAXBOARDS 32 -- GitLab From dae7f15e538537d58eb1b9f7046600d98af16cd7 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Sat, 28 Feb 2015 21:54:42 +0100 Subject: [PATCH 03204/11651] staging: iio: hmc5843: Set iio name property in sysfs Without this change file name for hmc5843 is empty in /sys/bus/iio/devices/iio\:device*/name With this change name is reported correctly: cat /sys/bus/iio/devices/iio\:device*/name hmc5843 Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/magnetometer/hmc5843_core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/iio/magnetometer/hmc5843_core.c b/drivers/staging/iio/magnetometer/hmc5843_core.c index fd171d8b38fb..90cc18b703cf 100644 --- a/drivers/staging/iio/magnetometer/hmc5843_core.c +++ b/drivers/staging/iio/magnetometer/hmc5843_core.c @@ -592,6 +592,7 @@ int hmc5843_common_probe(struct device *dev, struct regmap *regmap, mutex_init(&data->lock); indio_dev->dev.parent = dev; + indio_dev->name = dev->driver->name; indio_dev->info = &hmc5843_info; indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->channels = data->variant->channels; -- GitLab From a104662052b5863663d11895667f0f8a755cd826 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 27 Feb 2015 18:48:38 +0100 Subject: [PATCH 03205/11651] ARM: shmobile: ape6evm dts: Enable pull-up for GPIO switches The switches on r8a73a4/ape6evm do not have pull-up registers. The schematics say: "Need to use APE6 internal PullUp", hence enable pull-up using pinctrl. Without this, the switches don't really work, as the GPIO inputs are more likely to pick up ghost signals through capacitive coupling than actual keypresses. Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a73a4-ape6evm.dts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/arm/boot/dts/r8a73a4-ape6evm.dts b/arch/arm/boot/dts/r8a73a4-ape6evm.dts index e8f3f386a1d6..9734dd74e162 100644 --- a/arch/arm/boot/dts/r8a73a4-ape6evm.dts +++ b/arch/arm/boot/dts/r8a73a4-ape6evm.dts @@ -123,6 +123,9 @@ keyboard { compatible = "gpio-keys"; + pinctrl-names = "default"; + pinctrl-0 = <&keyboard_pins>; + zero-key { gpios = <&pfc 324 GPIO_ACTIVE_LOW>; linux,code = ; @@ -208,6 +211,12 @@ renesas,groups = "sdhi1_data4", "sdhi1_ctrl"; renesas,function = "sdhi1"; }; + + keyboard_pins: keyboard { + renesas,pins = "PORT324", "PORT325", "PORT326", "PORT327", + "PORT328", "PORT329"; + bias-pull-up; + }; }; &mmcif0 { -- GitLab From 90ca409a1e6b9b72d1b6ae716cd7a63335fd0e87 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 27 Feb 2015 18:48:39 +0100 Subject: [PATCH 03206/11651] ARM: shmobile: ape6evm dts: Configure the custom switch as wake-up source Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a73a4-ape6evm.dts | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/r8a73a4-ape6evm.dts b/arch/arm/boot/dts/r8a73a4-ape6evm.dts index 9734dd74e162..d1b6a07253ae 100644 --- a/arch/arm/boot/dts/r8a73a4-ape6evm.dts +++ b/arch/arm/boot/dts/r8a73a4-ape6evm.dts @@ -130,6 +130,7 @@ gpios = <&pfc 324 GPIO_ACTIVE_LOW>; linux,code = ; label = "S16"; + gpio-key,wakeup; }; menu-key { -- GitLab From c2073f3b0df8d22ed368bb27f0c3cc87487a25d4 Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Thu, 5 Mar 2015 14:24:34 -0500 Subject: [PATCH 03207/11651] staging: rtl8723au: Remove unused struct rx_hp Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/include/odm.h | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/drivers/staging/rtl8723au/include/odm.h b/drivers/staging/rtl8723au/include/odm.h index 0d1285c1bff0..d097465e4c14 100644 --- a/drivers/staging/rtl8723au/include/odm.h +++ b/drivers/staging/rtl8723au/include/odm.h @@ -158,19 +158,6 @@ struct false_alarm_stats { u32 Cnt_BW_LSC; /* Gary */ }; -struct rx_hp { - u8 RXHP_flag; - u8 PSD_func_trigger; - u8 PSD_bitmap_RXHP[80]; - u8 Pre_IGI; - u8 Cur_IGI; - u8 Pre_pw_th; - u8 Cur_pw_th; - bool First_time_enter; - bool RXHP_enable; - u8 TP_Mode; -}; - #define ASSOCIATE_ENTRY_NUM 32 /* Max size of AsocEntry[]. */ #define ODM_ASSOCIATE_ENTRY_NUM ASSOCIATE_ENTRY_NUM @@ -649,7 +636,6 @@ struct dm_odm_t { /* */ struct dig_t DM_DigTable; struct dynamic_pwr_sav DM_PSTable; - struct rx_hp DM_RXHP_Table; struct false_alarm_stats FalseAlmCnt; struct false_alarm_stats FlaseAlmCntBuddyAdapter; struct sw_ant_sw DM_SWAT_Table; -- GitLab From bb514494539196965e9b884a335ccc33b494ff13 Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Thu, 5 Mar 2015 14:24:35 -0500 Subject: [PATCH 03208/11651] staging: rtl8723au: Remove a number of unused entries from struct dm_odm_t Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/hal/odm.c | 9 -------- drivers/staging/rtl8723au/include/odm.h | 28 +------------------------ 2 files changed, 1 insertion(+), 36 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/odm.c b/drivers/staging/rtl8723au/hal/odm.c index 2d3653e784d2..937b6d79ce96 100644 --- a/drivers/staging/rtl8723au/hal/odm.c +++ b/drivers/staging/rtl8723au/hal/odm.c @@ -330,15 +330,6 @@ void ODM_CmnInfoInit23a(struct dm_odm_t *pDM_Odm, /* do nothing */ break; } - - /* */ - /* Tx power tracking BB swing table. */ - /* The base index = 12. +((12-n)/2)dB 13~?? = decrease tx pwr by -((n-12)/2)dB */ - /* */ - pDM_Odm->BbSwingIdxOfdm = 12; /* Set defalut value as index 12. */ - pDM_Odm->BbSwingIdxOfdmCurrent = 12; - pDM_Odm->BbSwingFlagOfdm = false; - } void ODM_CmnInfoPtrArrayHook23a(struct dm_odm_t *pDM_Odm, enum odm_cmninfo CmnInfo, diff --git a/drivers/staging/rtl8723au/include/odm.h b/drivers/staging/rtl8723au/include/odm.h index d097465e4c14..24f2f28c473f 100644 --- a/drivers/staging/rtl8723au/include/odm.h +++ b/drivers/staging/rtl8723au/include/odm.h @@ -609,14 +609,6 @@ struct dm_odm_t { /* 2012/01/12 MH For MP, we need to reduce one array pointer for default port.?? */ struct sta_info * pODM_StaInfo[ODM_ASSOCIATE_ENTRY_NUM]; - /* */ - /* 2012/02/14 MH Add to share 88E ra with other SW team. */ - /* We need to colelct all support abilit to a proper area. */ - /* */ - bool RaSupport88E; - - /* Define ........... */ - /* Latest packet phy info (ODM write) */ struct odm_phy_dbg_info PhyDbgInfo; /* PHY_INFO_88E PhyInfo; */ @@ -648,29 +640,11 @@ struct dm_odm_t { /* */ /* PSD */ - bool bUserAssignLevel; - u8 RSSI_BT; /* come from BT */ - bool bPSDinProcess; - + u8 RSSI_BT; /* come from BT */ struct odm_rate_adapt RateAdaptive; struct odm_rf_cal_t RFCalibrateInfo; - - /* */ - /* TX power tracking */ - /* */ - u8 BbSwingIdxOfdm; - u8 BbSwingIdxOfdmCurrent; - u8 BbSwingIdxOfdmBase; - bool BbSwingFlagOfdm; - u8 BbSwingIdxCck; - u8 BbSwingIdxCckCurrent; - u8 BbSwingIdxCckBase; - bool BbSwingFlagCck; - /* */ - /* ODM system resource. */ - /* */ }; /* DM_Dynamic_Mechanism_Structure */ enum odm_rf_content { -- GitLab From def0c450585089be57bf090c37dbd85d53587053 Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Thu, 5 Mar 2015 14:24:36 -0500 Subject: [PATCH 03209/11651] staging: rtl8723au: Remove pointless wrappers around odm_TXPowerTrackingInit() Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/hal/odm.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/odm.c b/drivers/staging/rtl8723au/hal/odm.c index 937b6d79ce96..79a78dfce1ee 100644 --- a/drivers/staging/rtl8723au/hal/odm.c +++ b/drivers/staging/rtl8723au/hal/odm.c @@ -198,9 +198,7 @@ static void odm_RefreshRateAdaptiveMask(struct dm_odm_t *pDM_Odm); void odm_RateAdaptiveMaskInit23a(struct dm_odm_t *pDM_Odm); -void odm_TXPowerTrackingThermalMeterInit23a(struct dm_odm_t *pDM_Odm); - -void odm_TXPowerTrackingInit23a(struct dm_odm_t *pDM_Odm); +static void odm_TXPowerTrackingInit(struct dm_odm_t *pDM_Odm); static void odm_EdcaTurboCheck23a(struct dm_odm_t *pDM_Odm); static void ODM_EdcaTurboInit23a(struct dm_odm_t *pDM_Odm); @@ -234,7 +232,7 @@ void ODM23a_DMInit(struct dm_odm_t *pDM_Odm) odm23a_DynBBPSInit(pDM_Odm); odm_DynamicTxPower23aInit(pDM_Odm); - odm_TXPowerTrackingInit23a(pDM_Odm); + odm_TXPowerTrackingInit(pDM_Odm); ODM_EdcaTurboInit23a(pDM_Odm); } @@ -1242,12 +1240,7 @@ static void odm_RSSIMonitorCheck(struct dm_odm_t *pDM_Odm) /* 3 Tx Power Tracking */ /* 3 ============================================================ */ -void odm_TXPowerTrackingInit23a(struct dm_odm_t *pDM_Odm) -{ - odm_TXPowerTrackingThermalMeterInit23a(pDM_Odm); -} - -void odm_TXPowerTrackingThermalMeterInit23a(struct dm_odm_t *pDM_Odm) +static void odm_TXPowerTrackingInit(struct dm_odm_t *pDM_Odm) { struct rtw_adapter *Adapter = pDM_Odm->Adapter; struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); -- GitLab From bfd83bbe92e89b27b7809ae1cffc142dfb763db6 Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Thu, 5 Mar 2015 14:24:37 -0500 Subject: [PATCH 03210/11651] staging: rtl8723au: Reduce the usage of ODM_[GS]et_BBReg() The vendor code has at least three different APIs for accessing registers. One more ugly than the other. This is the start to move away from ODM_[GS]et_BBReg() Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/hal/odm.c | 89 +++++++++++++++-------------- 1 file changed, 46 insertions(+), 43 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/odm.c b/drivers/staging/rtl8723au/hal/odm.c index 79a78dfce1ee..7a5cff5431c7 100644 --- a/drivers/staging/rtl8723au/hal/odm.c +++ b/drivers/staging/rtl8723au/hal/odm.c @@ -1366,8 +1366,10 @@ dm_CheckEdcaTurbo_EXIT: precvpriv->last_rx_bytes = precvpriv->rx_bytes; } -u32 GetPSDData(struct dm_odm_t *pDM_Odm, unsigned int point, u8 initial_gain_psd) +u32 GetPSDData(struct dm_odm_t *pDM_Odm, unsigned int point, + u8 initial_gain_psd) { + struct rtw_adapter *adapter = pDM_Odm->Adapter; u32 psd_report; /* Set DCO frequency index, offset = (40MHz/SamplePts)*point */ @@ -1379,7 +1381,7 @@ u32 GetPSDData(struct dm_odm_t *pDM_Odm, unsigned int point, u8 initial_gain_psd udelay(30); ODM_SetBBReg(pDM_Odm, 0x808, BIT(22), 0); /* Read PSD report, Reg8B4[15:0] */ - psd_report = ODM_GetBBReg(pDM_Odm, 0x8B4, bMaskDWord) & 0x0000FFFF; + psd_report = rtl8723au_read32(adapter, 0x8B4) & 0x0000FFFF; psd_report = (u32)(ConvertTo_dB23a(psd_report)) + (u32)(initial_gain_psd-0x1c); @@ -1436,7 +1438,7 @@ static void odm_PHY_SaveAFERegisters(struct dm_odm_t *pDM_Odm, u32 *AFEReg, u32 i; for (i = 0 ; i < RegisterNum ; i++) - AFEBackup[i] = ODM_GetBBReg(pDM_Odm, AFEReg[i], bMaskDWord); + AFEBackup[i] = rtl8723au_read32(pDM_Odm->Adapter, AFEReg[i]); } static void odm_PHY_ReloadAFERegisters(struct dm_odm_t *pDM_Odm, u32 *AFEReg, @@ -1445,7 +1447,7 @@ static void odm_PHY_ReloadAFERegisters(struct dm_odm_t *pDM_Odm, u32 *AFEReg, u32 i; for (i = 0 ; i < RegiesterNum; i++) - ODM_SetBBReg(pDM_Odm, AFEReg[i], bMaskDWord, AFEBackup[i]); + rtl8723au_write32(pDM_Odm->Adapter, AFEReg[i], AFEBackup[i]); } /* 2 8723A ANT DETECT */ @@ -1455,6 +1457,7 @@ static void odm_PHY_ReloadAFERegisters(struct dm_odm_t *pDM_Odm, u32 *AFEReg, bool ODM_SingleDualAntennaDetection(struct dm_odm_t *pDM_Odm, u8 mode) { struct sw_ant_sw *pDM_SWAT_Table = &pDM_Odm->DM_SWAT_Table; + struct rtw_adapter *adapter = pDM_Odm->Adapter; u32 CurrentChannel, RfLoopReg; u8 n; u32 Reg88c, Regc08, Reg874, Regc50; @@ -1490,10 +1493,10 @@ bool ODM_SingleDualAntennaDetection(struct dm_odm_t *pDM_Odm, u8 mode) udelay(10); /* Store A Path Register 88c, c08, 874, c50 */ - Reg88c = ODM_GetBBReg(pDM_Odm, rFPGA0_AnalogParameter4, bMaskDWord); - Regc08 = ODM_GetBBReg(pDM_Odm, rOFDM0_TRMuxPar, bMaskDWord); - Reg874 = ODM_GetBBReg(pDM_Odm, rFPGA0_XCD_RFInterfaceSW, bMaskDWord); - Regc50 = ODM_GetBBReg(pDM_Odm, rOFDM0_XAAGCCore1, bMaskDWord); + Reg88c = rtl8723au_read32(adapter, rFPGA0_AnalogParameter4); + Regc08 = rtl8723au_read32(adapter, rOFDM0_TRMuxPar); + Reg874 = rtl8723au_read32(adapter, rFPGA0_XCD_RFInterfaceSW); + Regc50 = rtl8723au_read32(adapter, rOFDM0_XAAGCCore1); /* Store AFE Registers */ odm_PHY_SaveAFERegisters(pDM_Odm, AFE_REG_8723A, AFE_Backup, 16); @@ -1505,49 +1508,49 @@ bool ODM_SingleDualAntennaDetection(struct dm_odm_t *pDM_Odm, u8 mode) ODM_SetRFReg(pDM_Odm, RF_PATH_A, ODM_CHANNEL, bRFRegOffsetMask, 0x01); /* AFE all on step */ - ODM_SetBBReg(pDM_Odm, rRx_Wait_CCA, bMaskDWord, 0x6FDB25A4); - ODM_SetBBReg(pDM_Odm, rTx_CCK_RFON, bMaskDWord, 0x6FDB25A4); - ODM_SetBBReg(pDM_Odm, rTx_CCK_BBON, bMaskDWord, 0x6FDB25A4); - ODM_SetBBReg(pDM_Odm, rTx_OFDM_RFON, bMaskDWord, 0x6FDB25A4); - ODM_SetBBReg(pDM_Odm, rTx_OFDM_BBON, bMaskDWord, 0x6FDB25A4); - ODM_SetBBReg(pDM_Odm, rTx_To_Rx, bMaskDWord, 0x6FDB25A4); - ODM_SetBBReg(pDM_Odm, rTx_To_Tx, bMaskDWord, 0x6FDB25A4); - ODM_SetBBReg(pDM_Odm, rRx_CCK, bMaskDWord, 0x6FDB25A4); - ODM_SetBBReg(pDM_Odm, rRx_OFDM, bMaskDWord, 0x6FDB25A4); - ODM_SetBBReg(pDM_Odm, rRx_Wait_RIFS, bMaskDWord, 0x6FDB25A4); - ODM_SetBBReg(pDM_Odm, rRx_TO_Rx, bMaskDWord, 0x6FDB25A4); - ODM_SetBBReg(pDM_Odm, rStandby, bMaskDWord, 0x6FDB25A4); - ODM_SetBBReg(pDM_Odm, rSleep, bMaskDWord, 0x6FDB25A4); - ODM_SetBBReg(pDM_Odm, rPMPD_ANAEN, bMaskDWord, 0x6FDB25A4); - ODM_SetBBReg(pDM_Odm, rFPGA0_XCD_SwitchControl, bMaskDWord, 0x6FDB25A4); - ODM_SetBBReg(pDM_Odm, rBlue_Tooth, bMaskDWord, 0x6FDB25A4); + rtl8723au_write32(adapter, rRx_Wait_CCA, 0x6FDB25A4); + rtl8723au_write32(adapter, rTx_CCK_RFON, 0x6FDB25A4); + rtl8723au_write32(adapter, rTx_CCK_BBON, 0x6FDB25A4); + rtl8723au_write32(adapter, rTx_OFDM_RFON, 0x6FDB25A4); + rtl8723au_write32(adapter, rTx_OFDM_BBON, 0x6FDB25A4); + rtl8723au_write32(adapter, rTx_To_Rx, 0x6FDB25A4); + rtl8723au_write32(adapter, rTx_To_Tx, 0x6FDB25A4); + rtl8723au_write32(adapter, rRx_CCK, 0x6FDB25A4); + rtl8723au_write32(adapter, rRx_OFDM, 0x6FDB25A4); + rtl8723au_write32(adapter, rRx_Wait_RIFS, 0x6FDB25A4); + rtl8723au_write32(adapter, rRx_TO_Rx, 0x6FDB25A4); + rtl8723au_write32(adapter, rStandby, 0x6FDB25A4); + rtl8723au_write32(adapter, rSleep, 0x6FDB25A4); + rtl8723au_write32(adapter, rPMPD_ANAEN, 0x6FDB25A4); + rtl8723au_write32(adapter, rFPGA0_XCD_SwitchControl, 0x6FDB25A4); + rtl8723au_write32(adapter, rBlue_Tooth, 0x6FDB25A4); /* 3 wire Disable */ - ODM_SetBBReg(pDM_Odm, rFPGA0_AnalogParameter4, bMaskDWord, 0xCCF000C0); + rtl8723au_write32(adapter, rFPGA0_AnalogParameter4, 0xCCF000C0); /* BB IQK Setting */ - ODM_SetBBReg(pDM_Odm, rOFDM0_TRMuxPar, bMaskDWord, 0x000800E4); - ODM_SetBBReg(pDM_Odm, rFPGA0_XCD_RFInterfaceSW, bMaskDWord, 0x22208000); + rtl8723au_write32(adapter, rOFDM0_TRMuxPar, 0x000800E4); + rtl8723au_write32(adapter, rFPGA0_XCD_RFInterfaceSW, 0x22208000); /* IQK setting tone@ 4.34Mhz */ - ODM_SetBBReg(pDM_Odm, rTx_IQK_Tone_A, bMaskDWord, 0x10008C1C); - ODM_SetBBReg(pDM_Odm, rTx_IQK, bMaskDWord, 0x01007c00); + rtl8723au_write32(adapter, rTx_IQK_Tone_A, 0x10008C1C); + rtl8723au_write32(adapter, rTx_IQK, 0x01007c00); /* Page B init */ - ODM_SetBBReg(pDM_Odm, rConfig_AntA, bMaskDWord, 0x00080000); - ODM_SetBBReg(pDM_Odm, rConfig_AntA, bMaskDWord, 0x0f600000); - ODM_SetBBReg(pDM_Odm, rRx_IQK, bMaskDWord, 0x01004800); - ODM_SetBBReg(pDM_Odm, rRx_IQK_Tone_A, bMaskDWord, 0x10008c1f); - ODM_SetBBReg(pDM_Odm, rTx_IQK_PI_A, bMaskDWord, 0x82150008); - ODM_SetBBReg(pDM_Odm, rRx_IQK_PI_A, bMaskDWord, 0x28150008); - ODM_SetBBReg(pDM_Odm, rIQK_AGC_Rsp, bMaskDWord, 0x001028d0); + rtl8723au_write32(adapter, rConfig_AntA, 0x00080000); + rtl8723au_write32(adapter, rConfig_AntA, 0x0f600000); + rtl8723au_write32(adapter, rRx_IQK, 0x01004800); + rtl8723au_write32(adapter, rRx_IQK_Tone_A, 0x10008c1f); + rtl8723au_write32(adapter, rTx_IQK_PI_A, 0x82150008); + rtl8723au_write32(adapter, rRx_IQK_PI_A, 0x28150008); + rtl8723au_write32(adapter, rIQK_AGC_Rsp, 0x001028d0); /* RF loop Setting */ ODM_SetRFReg(pDM_Odm, RF_PATH_A, 0x0, 0xFFFFF, 0x50008); /* IQK Single tone start */ - ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, bMaskDWord, 0x80800000); - ODM_SetBBReg(pDM_Odm, rIQK_AGC_Pts, bMaskDWord, 0xf8000000); + rtl8723au_write32(adapter, rFPGA0_IQK, 0x80800000); + rtl8723au_write32(adapter, rIQK_AGC_Pts, 0xf8000000); udelay(1000); PSD_report_tmp = 0x0; @@ -1580,16 +1583,16 @@ bool ODM_SingleDualAntennaDetection(struct dm_odm_t *pDM_Odm, u8 mode) } /* Close IQK Single Tone function */ - ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, bMaskDWord, 0x00000000); + rtl8723au_write32(adapter, rFPGA0_IQK, 0x00000000); PSD_report_tmp = 0x0; /* 1 Return to antanna A */ ODM_SetBBReg(pDM_Odm, rFPGA0_XA_RFInterfaceOE, 0x300, Antenna_A); - ODM_SetBBReg(pDM_Odm, rFPGA0_AnalogParameter4, bMaskDWord, Reg88c); - ODM_SetBBReg(pDM_Odm, rOFDM0_TRMuxPar, bMaskDWord, Regc08); - ODM_SetBBReg(pDM_Odm, rFPGA0_XCD_RFInterfaceSW, bMaskDWord, Reg874); + rtl8723au_write32(adapter, rFPGA0_AnalogParameter4, Reg88c); + rtl8723au_write32(adapter, rOFDM0_TRMuxPar, Regc08); + rtl8723au_write32(adapter, rFPGA0_XCD_RFInterfaceSW, Reg874); ODM_SetBBReg(pDM_Odm, rOFDM0_XAAGCCore1, 0x7F, 0x40); - ODM_SetBBReg(pDM_Odm, rOFDM0_XAAGCCore1, bMaskDWord, Regc50); + rtl8723au_write32(adapter, rOFDM0_XAAGCCore1, Regc50); ODM_SetRFReg(pDM_Odm, RF_PATH_A, RF_CHNLBW, bRFRegOffsetMask, CurrentChannel); ODM_SetRFReg(pDM_Odm, RF_PATH_A, 0x00, bRFRegOffsetMask, RfLoopReg); -- GitLab From 598fda7b1c16e79ca363b20c4ae9c1321bfe0c14 Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Thu, 5 Mar 2015 14:24:38 -0500 Subject: [PATCH 03211/11651] staging: rtl8723au: Clean up PHY_{Query,Set}BBReg() 32 bit read/writes This switches pure 32 bit read/writes to use the rtl8723au_{read,write}32() functions directly. Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- .../rtl8723au/hal/HalDMOutSrc8723A_CE.c | 209 ++++++++++-------- 1 file changed, 116 insertions(+), 93 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/HalDMOutSrc8723A_CE.c b/drivers/staging/rtl8723au/hal/HalDMOutSrc8723A_CE.c index 163e4d28eef0..ba373744ece9 100644 --- a/drivers/staging/rtl8723au/hal/HalDMOutSrc8723A_CE.c +++ b/drivers/staging/rtl8723au/hal/HalDMOutSrc8723A_CE.c @@ -65,8 +65,8 @@ odm_TXPowerTrackingCallback_ThermalMeter_92C(struct rtw_adapter *Adapter) if (ThermalValue) { /* Query OFDM path A default setting */ - ele_D = PHY_QueryBBReg(Adapter, rOFDM0_XATxIQImbalance, - bMaskDWord)&bMaskOFDM_D; + ele_D = rtl8723au_read32(Adapter, rOFDM0_XATxIQImbalance) & + bMaskOFDM_D; for (i = 0; i < OFDM_TABLE_SIZE_92C; i++) { /* find the index */ if (ele_D == (OFDMSwingTable23A[i]&bMaskOFDM_D)) { @@ -77,8 +77,9 @@ odm_TXPowerTrackingCallback_ThermalMeter_92C(struct rtw_adapter *Adapter) /* Query OFDM path B default setting */ if (pHalData->rf_type == RF_2T2R) { - ele_D = PHY_QueryBBReg(Adapter, rOFDM0_XBTxIQImbalance, - bMaskDWord)&bMaskOFDM_D; + ele_D = rtl8723au_read32(Adapter, + rOFDM0_XBTxIQImbalance); + ele_D &= bMaskOFDM_D; for (i = 0; i < OFDM_TABLE_SIZE_92C; i++) { /* find the index */ if (ele_D == (OFDMSwingTable23A[i]&bMaskOFDM_D)) { OFDM_index_old[1] = (u8)i; @@ -88,8 +89,7 @@ odm_TXPowerTrackingCallback_ThermalMeter_92C(struct rtw_adapter *Adapter) } /* Query CCK default setting From 0xa24 */ - TempCCk = PHY_QueryBBReg(Adapter, rCCK0_TxFilter2, - bMaskDWord)&bMaskCCK; + TempCCk = rtl8723au_read32(Adapter, rCCK0_TxFilter2) & bMaskCCK; for (i = 0 ; i < CCK_TABLE_SIZE ; i++) { if (pdmpriv->bCCKinCH14) { if (!memcmp(&TempCCk, @@ -227,7 +227,8 @@ odm_TXPowerTrackingCallback_ThermalMeter_92C(struct rtw_adapter *Adapter) CCK_index = 0; } - if (pdmpriv->TxPowerTrackControl && (delta != 0 || delta_HP != 0)) { + if (pdmpriv->TxPowerTrackControl && + (delta != 0 || delta_HP != 0)) { /* Adujst OFDM Ant_A according to IQK result */ ele_D = (OFDMSwingTable23A[OFDM_index[0]] & 0xFFC00000)>>22; X = pdmpriv->RegE94; @@ -245,7 +246,9 @@ odm_TXPowerTrackingCallback_ThermalMeter_92C(struct rtw_adapter *Adapter) /* write new elements A, C, D to regC80 and regC94, element B is always 0 */ value32 = (ele_D<<22)|((ele_C&0x3F)<<16)|ele_A; - PHY_SetBBReg(Adapter, rOFDM0_XATxIQImbalance, bMaskDWord, value32); + rtl8723au_write32(Adapter, + rOFDM0_XATxIQImbalance, + value32); value32 = (ele_C&0x000003C0)>>6; PHY_SetBBReg(Adapter, rOFDM0_XCTxAFE, bMaskH4Bits, value32); @@ -258,9 +261,9 @@ odm_TXPowerTrackingCallback_ThermalMeter_92C(struct rtw_adapter *Adapter) PHY_SetBBReg(Adapter, rOFDM0_ECCAThreshold, BIT(29), value32); } else { - PHY_SetBBReg(Adapter, rOFDM0_XATxIQImbalance, - bMaskDWord, - OFDMSwingTable23A[OFDM_index[0]]); + rtl8723au_write32(Adapter, + rOFDM0_XATxIQImbalance, + OFDMSwingTable23A[OFDM_index[0]]); PHY_SetBBReg(Adapter, rOFDM0_XCTxAFE, bMaskH4Bits, 0x00); PHY_SetBBReg(Adapter, rOFDM0_ECCAThreshold, @@ -307,7 +310,7 @@ odm_TXPowerTrackingCallback_ThermalMeter_92C(struct rtw_adapter *Adapter) /* write new elements A, C, D to regC88 and regC9C, element B is always 0 */ value32 = (ele_D<<22)|((ele_C&0x3F)<<16) | ele_A; - PHY_SetBBReg(Adapter, rOFDM0_XBTxIQImbalance, bMaskDWord, value32); + rtl8723au_write32(Adapter, rOFDM0_XBTxIQImbalance, value32); value32 = (ele_C&0x000003C0)>>6; PHY_SetBBReg(Adapter, rOFDM0_XDTxAFE, bMaskH4Bits, value32); @@ -322,10 +325,9 @@ odm_TXPowerTrackingCallback_ThermalMeter_92C(struct rtw_adapter *Adapter) rOFDM0_ECCAThreshold, BIT(25), value32); } else { - PHY_SetBBReg(Adapter, - rOFDM0_XBTxIQImbalance, - bMaskDWord, - OFDMSwingTable23A[OFDM_index[1]]); + rtl8723au_write32(Adapter, + rOFDM0_XBTxIQImbalance, + OFDMSwingTable23A[OFDM_index[1]]); PHY_SetBBReg(Adapter, rOFDM0_XDTxAFE, bMaskH4Bits, 0x00); @@ -386,36 +388,37 @@ static u8 _PHY_PathA_IQK(struct rtw_adapter *pAdapter, bool configPathB) struct hal_data_8723a *pHalData = GET_HAL_DATA(pAdapter); /* path-A IQK setting */ - PHY_SetBBReg(pAdapter, rTx_IQK_Tone_A, bMaskDWord, 0x10008c1f); - PHY_SetBBReg(pAdapter, rRx_IQK_Tone_A, bMaskDWord, 0x10008c1f); - PHY_SetBBReg(pAdapter, rTx_IQK_PI_A, bMaskDWord, 0x82140102); + rtl8723au_write32(pAdapter, rTx_IQK_Tone_A, 0x10008c1f); + rtl8723au_write32(pAdapter, rRx_IQK_Tone_A, 0x10008c1f); + rtl8723au_write32(pAdapter, rTx_IQK_PI_A, 0x82140102); - PHY_SetBBReg(pAdapter, rRx_IQK_PI_A, bMaskDWord, configPathB ? 0x28160202 : + rtl8723au_write32(pAdapter, rRx_IQK_PI_A, configPathB ? 0x28160202 : IS_81xxC_VENDOR_UMC_B_CUT(pHalData->VersionID)?0x28160202:0x28160502); /* path-B IQK setting */ if (configPathB) { - PHY_SetBBReg(pAdapter, rTx_IQK_Tone_B, bMaskDWord, 0x10008c22); - PHY_SetBBReg(pAdapter, rRx_IQK_Tone_B, bMaskDWord, 0x10008c22); - PHY_SetBBReg(pAdapter, rTx_IQK_PI_B, bMaskDWord, 0x82140102); - PHY_SetBBReg(pAdapter, rRx_IQK_PI_B, bMaskDWord, 0x28160202); + rtl8723au_write32(pAdapter, rTx_IQK_Tone_B, 0x10008c22); + rtl8723au_write32(pAdapter, rRx_IQK_Tone_B, 0x10008c22); + rtl8723au_write32(pAdapter, rTx_IQK_PI_B, 0x82140102); + rtl8723au_write32(pAdapter, rRx_IQK_PI_B, 0x28160202); } /* LO calibration setting */ - PHY_SetBBReg(pAdapter, rIQK_AGC_Rsp, bMaskDWord, 0x001028d1); + rtl8723au_write32(pAdapter, rIQK_AGC_Rsp, 0x001028d1); /* One shot, path A LOK & IQK */ - PHY_SetBBReg(pAdapter, rIQK_AGC_Pts, bMaskDWord, 0xf9000000); - PHY_SetBBReg(pAdapter, rIQK_AGC_Pts, bMaskDWord, 0xf8000000); + rtl8723au_write32(pAdapter, rIQK_AGC_Pts, 0xf9000000); + rtl8723au_write32(pAdapter, rIQK_AGC_Pts, 0xf8000000); /* delay x ms */ - udelay(IQK_DELAY_TIME*1000);/* PlatformStallExecution(IQK_DELAY_TIME*1000); */ + /* PlatformStallExecution(IQK_DELAY_TIME*1000); */ + udelay(IQK_DELAY_TIME*1000); /* Check failed */ - regEAC = PHY_QueryBBReg(pAdapter, rRx_Power_After_IQK_A_2, bMaskDWord); - regE94 = PHY_QueryBBReg(pAdapter, rTx_Power_Before_IQK_A, bMaskDWord); - regE9C = PHY_QueryBBReg(pAdapter, rTx_Power_After_IQK_A, bMaskDWord); - regEA4 = PHY_QueryBBReg(pAdapter, rRx_Power_Before_IQK_A_2, bMaskDWord); + regEAC = rtl8723au_read32(pAdapter, rRx_Power_After_IQK_A_2); + regE94 = rtl8723au_read32(pAdapter, rTx_Power_Before_IQK_A); + regE9C = rtl8723au_read32(pAdapter, rTx_Power_After_IQK_A); + regEA4 = rtl8723au_read32(pAdapter, rRx_Power_Before_IQK_A_2); if (!(regEAC & BIT(28)) && (((regE94 & 0x03FF0000)>>16) != 0x142) && @@ -424,7 +427,7 @@ static u8 _PHY_PathA_IQK(struct rtw_adapter *pAdapter, bool configPathB) else /* if Tx not OK, ignore Rx */ return result; - if (!(regEAC & BIT(27)) && /* if Tx is OK, check whether Rx is OK */ + if (!(regEAC & BIT(27)) && /* if Tx is OK, check whether Rx is OK */ (((regEA4 & 0x03FF0000)>>16) != 0x132) && (((regEAC & 0x03FF0000)>>16) != 0x36)) result |= 0x02; @@ -439,18 +442,18 @@ static u8 _PHY_PathB_IQK(struct rtw_adapter *pAdapter) u8 result = 0x00; /* One shot, path B LOK & IQK */ - PHY_SetBBReg(pAdapter, rIQK_AGC_Cont, bMaskDWord, 0x00000002); - PHY_SetBBReg(pAdapter, rIQK_AGC_Cont, bMaskDWord, 0x00000000); + rtl8723au_write32(pAdapter, rIQK_AGC_Cont, 0x00000002); + rtl8723au_write32(pAdapter, rIQK_AGC_Cont, 0x00000000); /* delay x ms */ udelay(IQK_DELAY_TIME*1000); /* Check failed */ - regEAC = PHY_QueryBBReg(pAdapter, rRx_Power_After_IQK_A_2, bMaskDWord); - regEB4 = PHY_QueryBBReg(pAdapter, rTx_Power_Before_IQK_B, bMaskDWord); - regEBC = PHY_QueryBBReg(pAdapter, rTx_Power_After_IQK_B, bMaskDWord); - regEC4 = PHY_QueryBBReg(pAdapter, rRx_Power_Before_IQK_B_2, bMaskDWord); - regECC = PHY_QueryBBReg(pAdapter, rRx_Power_After_IQK_B_2, bMaskDWord); + regEAC = rtl8723au_read32(pAdapter, rRx_Power_After_IQK_A_2); + regEB4 = rtl8723au_read32(pAdapter, rTx_Power_Before_IQK_B); + regEBC = rtl8723au_read32(pAdapter, rTx_Power_After_IQK_B); + regEC4 = rtl8723au_read32(pAdapter, rRx_Power_Before_IQK_B_2); + regECC = rtl8723au_read32(pAdapter, rRx_Power_After_IQK_B_2); if (!(regEAC & BIT(31)) && (((regEB4 & 0x03FF0000)>>16) != 0x142) && @@ -483,22 +486,27 @@ static void _PHY_PathAFillIQKMatrix(struct rtw_adapter *pAdapter, if (final_candidate == 0xFF) { return; } else if (bIQKOK) { - Oldval_0 = (PHY_QueryBBReg(pAdapter, rOFDM0_XATxIQImbalance, bMaskDWord) >> 22) & 0x3FF; + Oldval_0 = rtl8723au_read32(pAdapter, rOFDM0_XATxIQImbalance); + Oldval_0 = (Oldval_0 >> 22) & 0x3FF; X = result[final_candidate][0]; if ((X & 0x00000200) != 0) X = X | 0xFFFFFC00; TX0_A = (X * Oldval_0) >> 8; PHY_SetBBReg(pAdapter, rOFDM0_XATxIQImbalance, 0x3FF, TX0_A); - PHY_SetBBReg(pAdapter, rOFDM0_ECCAThreshold, BIT(31), ((X * Oldval_0>>7) & 0x1)); + PHY_SetBBReg(pAdapter, rOFDM0_ECCAThreshold, BIT(31), + ((X * Oldval_0>>7) & 0x1)); Y = result[final_candidate][1]; if ((Y & 0x00000200) != 0) Y = Y | 0xFFFFFC00; TX0_C = (Y * Oldval_0) >> 8; - PHY_SetBBReg(pAdapter, rOFDM0_XCTxAFE, 0xF0000000, ((TX0_C&0x3C0)>>6)); - PHY_SetBBReg(pAdapter, rOFDM0_XATxIQImbalance, 0x003F0000, (TX0_C&0x3F)); - PHY_SetBBReg(pAdapter, rOFDM0_ECCAThreshold, BIT(29), ((Y * Oldval_0>>7) & 0x1)); + PHY_SetBBReg(pAdapter, rOFDM0_XCTxAFE, 0xF0000000, + ((TX0_C&0x3C0)>>6)); + PHY_SetBBReg(pAdapter, rOFDM0_XATxIQImbalance, 0x003F0000, + (TX0_C&0x3F)); + PHY_SetBBReg(pAdapter, rOFDM0_ECCAThreshold, BIT(29), + ((Y * Oldval_0>>7) & 0x1)); if (bTxOnly) { DBG_8723A("_PHY_PathAFillIQKMatrix only Tx OK\n"); @@ -526,22 +534,27 @@ static void _PHY_PathBFillIQKMatrix(struct rtw_adapter *pAdapter, bool bIQKOK, i if (final_candidate == 0xFF) { return; } else if (bIQKOK) { - Oldval_1 = (PHY_QueryBBReg(pAdapter, rOFDM0_XBTxIQImbalance, bMaskDWord) >> 22) & 0x3FF; + Oldval_1 = rtl8723au_read32(pAdapter, rOFDM0_XBTxIQImbalance); + Oldval_1 = (Oldval_1 >> 22) & 0x3FF; X = result[final_candidate][4]; if ((X & 0x00000200) != 0) X = X | 0xFFFFFC00; TX1_A = (X * Oldval_1) >> 8; PHY_SetBBReg(pAdapter, rOFDM0_XBTxIQImbalance, 0x3FF, TX1_A); - PHY_SetBBReg(pAdapter, rOFDM0_ECCAThreshold, BIT(27), ((X * Oldval_1>>7) & 0x1)); + PHY_SetBBReg(pAdapter, rOFDM0_ECCAThreshold, BIT(27), + ((X * Oldval_1 >> 7) & 0x1)); Y = result[final_candidate][5]; if ((Y & 0x00000200) != 0) Y = Y | 0xFFFFFC00; TX1_C = (Y * Oldval_1) >> 8; - PHY_SetBBReg(pAdapter, rOFDM0_XDTxAFE, 0xF0000000, ((TX1_C&0x3C0)>>6)); - PHY_SetBBReg(pAdapter, rOFDM0_XBTxIQImbalance, 0x003F0000, (TX1_C&0x3F)); - PHY_SetBBReg(pAdapter, rOFDM0_ECCAThreshold, BIT(25), ((Y * Oldval_1>>7) & 0x1)); + PHY_SetBBReg(pAdapter, rOFDM0_XDTxAFE, 0xF0000000, + ((TX1_C & 0x3C0) >> 6)); + PHY_SetBBReg(pAdapter, rOFDM0_XBTxIQImbalance, 0x003F0000, + (TX1_C & 0x3F)); + PHY_SetBBReg(pAdapter, rOFDM0_ECCAThreshold, BIT(25), + ((Y * Oldval_1 >> 7) & 0x1)); if (bTxOnly) return; @@ -562,11 +575,12 @@ static void _PHY_SaveADDARegisters(struct rtw_adapter *pAdapter, u32 *ADDAReg, u u32 i; for (i = 0 ; i < RegisterNum ; i++) { - ADDABackup[i] = PHY_QueryBBReg(pAdapter, ADDAReg[i], bMaskDWord); + ADDABackup[i] = rtl8723au_read32(pAdapter, ADDAReg[i]); } } -static void _PHY_SaveMACRegisters(struct rtw_adapter *pAdapter, u32 *MACReg, u32 *MACBackup) +static void _PHY_SaveMACRegisters(struct rtw_adapter *pAdapter, u32 *MACReg, + u32 *MACBackup) { u32 i; @@ -576,16 +590,19 @@ static void _PHY_SaveMACRegisters(struct rtw_adapter *pAdapter, u32 *MACReg, u32 MACBackup[i] = rtl8723au_read32(pAdapter, MACReg[i]); } -static void _PHY_ReloadADDARegisters(struct rtw_adapter *pAdapter, u32 *ADDAReg, u32 *ADDABackup, u32 RegiesterNum) +static void _PHY_ReloadADDARegisters(struct rtw_adapter *pAdapter, + u32 *ADDAReg, u32 *ADDABackup, + u32 RegiesterNum) { u32 i; for (i = 0 ; i < RegiesterNum ; i++) { - PHY_SetBBReg(pAdapter, ADDAReg[i], bMaskDWord, ADDABackup[i]); + rtl8723au_write32(pAdapter, ADDAReg[i], ADDABackup[i]); } } -static void _PHY_ReloadMACRegisters(struct rtw_adapter *pAdapter, u32 *MACReg, u32 *MACBackup) +static void _PHY_ReloadMACRegisters(struct rtw_adapter *pAdapter, + u32 *MACReg, u32 *MACBackup) { u32 i; @@ -595,7 +612,8 @@ static void _PHY_ReloadMACRegisters(struct rtw_adapter *pAdapter, u32 *MACReg, u rtl8723au_write32(pAdapter, MACReg[i], MACBackup[i]); } -static void _PHY_PathADDAOn(struct rtw_adapter *pAdapter, u32 *ADDAReg, bool isPathAOn, bool is2T) +static void _PHY_PathADDAOn(struct rtw_adapter *pAdapter, u32 *ADDAReg, + bool isPathAOn, bool is2T) { u32 pathOn; u32 i; @@ -603,16 +621,17 @@ static void _PHY_PathADDAOn(struct rtw_adapter *pAdapter, u32 *ADDAReg, bool isP pathOn = isPathAOn ? 0x04db25a4 : 0x0b1b25a4; if (!is2T) { pathOn = 0x0bdb25a0; - PHY_SetBBReg(pAdapter, ADDAReg[0], bMaskDWord, 0x0b1b25a0); + rtl8723au_write32(pAdapter, ADDAReg[0], 0x0b1b25a0); } else { - PHY_SetBBReg(pAdapter, ADDAReg[0], bMaskDWord, pathOn); + rtl8723au_write32(pAdapter, ADDAReg[0], pathOn); } for (i = 1 ; i < IQK_ADDA_REG_NUM ; i++) - PHY_SetBBReg(pAdapter, ADDAReg[i], bMaskDWord, pathOn); + rtl8723au_write32(pAdapter, ADDAReg[i], pathOn); } -static void _PHY_MACSettingCalibration(struct rtw_adapter *pAdapter, u32 *MACReg, u32 *MACBackup) +static void _PHY_MACSettingCalibration(struct rtw_adapter *pAdapter, + u32 *MACReg, u32 *MACBackup) { u32 i = 0; @@ -627,9 +646,9 @@ static void _PHY_MACSettingCalibration(struct rtw_adapter *pAdapter, u32 *MACReg static void _PHY_PathAStandBy(struct rtw_adapter *pAdapter) { - PHY_SetBBReg(pAdapter, rFPGA0_IQK, bMaskDWord, 0x0); - PHY_SetBBReg(pAdapter, 0x840, bMaskDWord, 0x00010000); - PHY_SetBBReg(pAdapter, rFPGA0_IQK, bMaskDWord, 0x80800000); + rtl8723au_write32(pAdapter, rFPGA0_IQK, 0x0); + rtl8723au_write32(pAdapter, 0x840, 0x00010000); + rtl8723au_write32(pAdapter, rFPGA0_IQK, 0x80800000); } static void _PHY_PIModeSwitch(struct rtw_adapter *pAdapter, bool PIMode) @@ -637,8 +656,8 @@ static void _PHY_PIModeSwitch(struct rtw_adapter *pAdapter, bool PIMode) u32 mode; mode = PIMode ? 0x01000100 : 0x01000000; - PHY_SetBBReg(pAdapter, 0x820, bMaskDWord, mode); - PHY_SetBBReg(pAdapter, 0x828, bMaskDWord, mode); + rtl8723au_write32(pAdapter, 0x820, mode); + rtl8723au_write32(pAdapter, 0x828, mode); } /* @@ -735,7 +754,7 @@ static void _PHY_IQCalibrate(struct rtw_adapter *pAdapter, int result[][8], u8 t u32 bbvalue; if (t == 0) { - bbvalue = PHY_QueryBBReg(pAdapter, rFPGA0_RFMOD, bMaskDWord); + bbvalue = rtl8723au_read32(pAdapter, rFPGA0_RFMOD); /* Save ADDA parameters, turn Path A ADDA on */ _PHY_SaveADDARegisters(pAdapter, ADDA_REG, pdmpriv->ADDA_backup, IQK_ADDA_REG_NUM); @@ -755,48 +774,50 @@ static void _PHY_IQCalibrate(struct rtw_adapter *pAdapter, int result[][8], u8 t } PHY_SetBBReg(pAdapter, rFPGA0_RFMOD, BIT(24), 0x00); - PHY_SetBBReg(pAdapter, rOFDM0_TRxPathEnable, bMaskDWord, 0x03a05600); - PHY_SetBBReg(pAdapter, rOFDM0_TRMuxPar, bMaskDWord, 0x000800e4); - PHY_SetBBReg(pAdapter, rFPGA0_XCD_RFInterfaceSW, bMaskDWord, 0x22204000); + rtl8723au_write32(pAdapter, rOFDM0_TRxPathEnable, 0x03a05600); + rtl8723au_write32(pAdapter, rOFDM0_TRMuxPar, 0x000800e4); + rtl8723au_write32(pAdapter, rFPGA0_XCD_RFInterfaceSW, 0x22204000); PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFInterfaceSW, BIT(10), 0x01); PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFInterfaceSW, BIT(26), 0x01); PHY_SetBBReg(pAdapter, rFPGA0_XA_RFInterfaceOE, BIT(10), 0x00); PHY_SetBBReg(pAdapter, rFPGA0_XB_RFInterfaceOE, BIT(10), 0x00); if (is2T) { - PHY_SetBBReg(pAdapter, rFPGA0_XA_LSSIParameter, bMaskDWord, 0x00010000); - PHY_SetBBReg(pAdapter, rFPGA0_XB_LSSIParameter, bMaskDWord, 0x00010000); + rtl8723au_write32(pAdapter, + rFPGA0_XA_LSSIParameter, 0x00010000); + rtl8723au_write32(pAdapter, + rFPGA0_XB_LSSIParameter, 0x00010000); } /* MAC settings */ _PHY_MACSettingCalibration(pAdapter, IQK_MAC_REG, pdmpriv->IQK_MAC_backup); /* Page B init */ - PHY_SetBBReg(pAdapter, rConfig_AntA, bMaskDWord, 0x00080000); + rtl8723au_write32(pAdapter, rConfig_AntA, 0x00080000); if (is2T) - PHY_SetBBReg(pAdapter, rConfig_AntB, bMaskDWord, 0x00080000); + rtl8723au_write32(pAdapter, rConfig_AntB, 0x00080000); /* IQ calibration setting */ - PHY_SetBBReg(pAdapter, rFPGA0_IQK, bMaskDWord, 0x80800000); - PHY_SetBBReg(pAdapter, rTx_IQK, bMaskDWord, 0x01007c00); - PHY_SetBBReg(pAdapter, rRx_IQK, bMaskDWord, 0x01004800); + rtl8723au_write32(pAdapter, rFPGA0_IQK, 0x80800000); + rtl8723au_write32(pAdapter, rTx_IQK, 0x01007c00); + rtl8723au_write32(pAdapter, rRx_IQK, 0x01004800); for (i = 0 ; i < retryCount ; i++) { PathAOK = _PHY_PathA_IQK(pAdapter, is2T); if (PathAOK == 0x03) { DBG_8723A("Path A IQK Success!!\n"); - result[t][0] = (PHY_QueryBBReg(pAdapter, rTx_Power_Before_IQK_A, bMaskDWord)&0x3FF0000)>>16; - result[t][1] = (PHY_QueryBBReg(pAdapter, rTx_Power_After_IQK_A, bMaskDWord)&0x3FF0000)>>16; - result[t][2] = (PHY_QueryBBReg(pAdapter, rRx_Power_Before_IQK_A_2, bMaskDWord)&0x3FF0000)>>16; - result[t][3] = (PHY_QueryBBReg(pAdapter, rRx_Power_After_IQK_A_2, bMaskDWord)&0x3FF0000)>>16; + result[t][0] = (rtl8723au_read32(pAdapter, rTx_Power_Before_IQK_A)&0x3FF0000)>>16; + result[t][1] = (rtl8723au_read32(pAdapter, rTx_Power_After_IQK_A)&0x3FF0000)>>16; + result[t][2] = (rtl8723au_read32(pAdapter, rRx_Power_Before_IQK_A_2)&0x3FF0000)>>16; + result[t][3] = (rtl8723au_read32(pAdapter, rRx_Power_After_IQK_A_2)&0x3FF0000)>>16; break; } else if (i == (retryCount-1) && PathAOK == 0x01) { /* Tx IQK OK */ DBG_8723A("Path A IQK Only Tx Success!!\n"); - result[t][0] = (PHY_QueryBBReg(pAdapter, rTx_Power_Before_IQK_A, bMaskDWord)&0x3FF0000)>>16; - result[t][1] = (PHY_QueryBBReg(pAdapter, rTx_Power_After_IQK_A, bMaskDWord)&0x3FF0000)>>16; + result[t][0] = (rtl8723au_read32(pAdapter, rTx_Power_Before_IQK_A)&0x3FF0000)>>16; + result[t][1] = (rtl8723au_read32(pAdapter, rTx_Power_After_IQK_A)&0x3FF0000)>>16; } } @@ -814,16 +835,16 @@ static void _PHY_IQCalibrate(struct rtw_adapter *pAdapter, int result[][8], u8 t PathBOK = _PHY_PathB_IQK(pAdapter); if (PathBOK == 0x03) { DBG_8723A("Path B IQK Success!!\n"); - result[t][4] = (PHY_QueryBBReg(pAdapter, rTx_Power_Before_IQK_B, bMaskDWord)&0x3FF0000)>>16; - result[t][5] = (PHY_QueryBBReg(pAdapter, rTx_Power_After_IQK_B, bMaskDWord)&0x3FF0000)>>16; - result[t][6] = (PHY_QueryBBReg(pAdapter, rRx_Power_Before_IQK_B_2, bMaskDWord)&0x3FF0000)>>16; - result[t][7] = (PHY_QueryBBReg(pAdapter, rRx_Power_After_IQK_B_2, bMaskDWord)&0x3FF0000)>>16; + result[t][4] = (rtl8723au_read32(pAdapter, rTx_Power_Before_IQK_B)&0x3FF0000)>>16; + result[t][5] = (rtl8723au_read32(pAdapter, rTx_Power_After_IQK_B)&0x3FF0000)>>16; + result[t][6] = (rtl8723au_read32(pAdapter, rRx_Power_Before_IQK_B_2)&0x3FF0000)>>16; + result[t][7] = (rtl8723au_read32(pAdapter, rRx_Power_After_IQK_B_2)&0x3FF0000)>>16; break; } else if (i == (retryCount - 1) && PathBOK == 0x01) { /* Tx IQK OK */ DBG_8723A("Path B Only Tx IQK Success!!\n"); - result[t][4] = (PHY_QueryBBReg(pAdapter, rTx_Power_Before_IQK_B, bMaskDWord)&0x3FF0000)>>16; - result[t][5] = (PHY_QueryBBReg(pAdapter, rTx_Power_After_IQK_B, bMaskDWord)&0x3FF0000)>>16; + result[t][4] = (rtl8723au_read32(pAdapter, rTx_Power_Before_IQK_B)&0x3FF0000)>>16; + result[t][5] = (rtl8723au_read32(pAdapter, rTx_Power_After_IQK_B)&0x3FF0000)>>16; } } @@ -833,7 +854,7 @@ static void _PHY_IQCalibrate(struct rtw_adapter *pAdapter, int result[][8], u8 t } /* Back to BB mode, load original value */ - PHY_SetBBReg(pAdapter, rFPGA0_IQK, bMaskDWord, 0); + rtl8723au_write32(pAdapter, rFPGA0_IQK, 0); if (t != 0) { if (!pdmpriv->bRfPiEnable) { @@ -851,14 +872,16 @@ static void _PHY_IQCalibrate(struct rtw_adapter *pAdapter, int result[][8], u8 t _PHY_ReloadADDARegisters(pAdapter, IQK_BB_REG_92C, pdmpriv->IQK_BB_backup, IQK_BB_REG_NUM); /* Restore RX initial gain */ - PHY_SetBBReg(pAdapter, rFPGA0_XA_LSSIParameter, bMaskDWord, 0x00032ed3); + rtl8723au_write32(pAdapter, + rFPGA0_XA_LSSIParameter, 0x00032ed3); if (is2T) { - PHY_SetBBReg(pAdapter, rFPGA0_XB_LSSIParameter, bMaskDWord, 0x00032ed3); + rtl8723au_write32(pAdapter, + rFPGA0_XB_LSSIParameter, 0x00032ed3); } /* load 0xe30 IQC default value */ - PHY_SetBBReg(pAdapter, rTx_IQK_Tone_A, bMaskDWord, 0x01008c00); - PHY_SetBBReg(pAdapter, rRx_IQK_Tone_A, bMaskDWord, 0x01008c00); + rtl8723au_write32(pAdapter, rTx_IQK_Tone_A, 0x01008c00); + rtl8723au_write32(pAdapter, rRx_IQK_Tone_A, 0x01008c00); } } -- GitLab From b3ced7caa245e5cf2bd628e6fd8b6581f30acb50 Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Thu, 5 Mar 2015 14:24:39 -0500 Subject: [PATCH 03212/11651] staging: rtl8723au: writeOFDMPowerReg() use rtl8723au_write32() Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/hal/rtl8723a_rf6052.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_rf6052.c b/drivers/staging/rtl8723au/hal/rtl8723a_rf6052.c index 1aad4384471c..32c58c6124b0 100644 --- a/drivers/staging/rtl8723au/hal/rtl8723a_rf6052.c +++ b/drivers/staging/rtl8723au/hal/rtl8723a_rf6052.c @@ -353,7 +353,7 @@ static void writeOFDMPowerReg(struct rtw_adapter *Adapter, u8 index, else RegOffset = RegOffset_B[index]; - PHY_SetBBReg(Adapter, RegOffset, bMaskDWord, writeVal); + rtl8723au_write32(Adapter, RegOffset, writeVal); /* 201005115 Joseph: Set Tx Power diff for Tx power training mechanism. */ -- GitLab From dbe2d4dfde1941aa14c0a13e9dbc9044b522086e Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Thu, 5 Mar 2015 14:24:40 -0500 Subject: [PATCH 03213/11651] staging: rtl8723au: rtl8723a_phycfg.c: Use proper register read/write functions Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- .../staging/rtl8723au/hal/rtl8723a_phycfg.c | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_phycfg.c b/drivers/staging/rtl8723au/hal/rtl8723a_phycfg.c index 6d597169c11c..d34a1481b13a 100644 --- a/drivers/staging/rtl8723au/hal/rtl8723a_phycfg.c +++ b/drivers/staging/rtl8723au/hal/rtl8723a_phycfg.c @@ -190,25 +190,24 @@ phy_RFSerialRead(struct rtw_adapter *Adapter, enum RF_RADIO_PATH eRFPath, /* For 92S LSSI Read RFLSSIRead */ /* For RF A/B write 0x824/82c(does not work in the future) */ /* We must use 0x824 for RF A and B to execute read trigger */ - tmplong = PHY_QueryBBReg(Adapter, rFPGA0_XA_HSSIParameter2, bMaskDWord); + tmplong = rtl8723au_read32(Adapter, rFPGA0_XA_HSSIParameter2); if (eRFPath == RF_PATH_A) tmplong2 = tmplong; else - tmplong2 = PHY_QueryBBReg(Adapter, pPhyReg->rfHSSIPara2, - bMaskDWord); + tmplong2 = rtl8723au_read32(Adapter, pPhyReg->rfHSSIPara2); tmplong2 = (tmplong2 & ~bLSSIReadAddress) | (NewOffset << 23) | bLSSIReadEdge; /* T65 RF */ - PHY_SetBBReg(Adapter, rFPGA0_XA_HSSIParameter2, - bMaskDWord, tmplong & (~bLSSIReadEdge)); + rtl8723au_write32(Adapter, rFPGA0_XA_HSSIParameter2, + tmplong & (~bLSSIReadEdge)); udelay(10);/* PlatformStallExecution(10); */ - PHY_SetBBReg(Adapter, pPhyReg->rfHSSIPara2, bMaskDWord, tmplong2); + rtl8723au_write32(Adapter, pPhyReg->rfHSSIPara2, tmplong2); udelay(100);/* PlatformStallExecution(100); */ - PHY_SetBBReg(Adapter, rFPGA0_XA_HSSIParameter2, bMaskDWord, - tmplong | bLSSIReadEdge); + rtl8723au_write32(Adapter, rFPGA0_XA_HSSIParameter2, + tmplong | bLSSIReadEdge); udelay(10);/* PlatformStallExecution(10); */ if (eRFPath == RF_PATH_A) @@ -319,9 +318,7 @@ phy_RFSerialWrite(struct rtw_adapter *Adapter, enum RF_RADIO_PATH eRFPath, /* */ /* Write Operation */ /* */ - PHY_SetBBReg(Adapter, pPhyReg->rf3wireOffset, bMaskDWord, DataAndAddr); - /* RTPRINT(FPHY, PHY_RFW, ("RFW-%d Addr[0x%lx]= 0x%lx\n", eRFPath, pPhyReg->rf3wireOffset, DataAndAddr)); */ - + rtl8723au_write32(Adapter, pPhyReg->rf3wireOffset, DataAndAddr); } /** @@ -830,7 +827,7 @@ PHY_BBConfig8723A(struct rtw_adapter *Adapter) (CrystalCap | (CrystalCap << 6))); } - PHY_SetBBReg(Adapter, REG_LDOA15_CTRL, bMaskDWord, 0x01572505); + rtl8723au_write32(Adapter, REG_LDOA15_CTRL, 0x01572505); return rtStatus; } -- GitLab From 2c177a8c7799651c1a62b007d16300e50688c287 Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Thu, 5 Mar 2015 14:24:41 -0500 Subject: [PATCH 03214/11651] staging: rtl8723au: usb_halinit.c: Use rtl8723au_{read,write}32() Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/hal/usb_halinit.c | 43 ++++++++++----------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/usb_halinit.c b/drivers/staging/rtl8723au/hal/usb_halinit.c index 57518dc67509..bd9c549f4a0a 100644 --- a/drivers/staging/rtl8723au/hal/usb_halinit.c +++ b/drivers/staging/rtl8723au/hal/usb_halinit.c @@ -609,17 +609,22 @@ int rtl8723au_hal_init(struct rtw_adapter *Adapter) } /* reducing 80M spur */ - PHY_SetBBReg(Adapter, REG_AFE_XTAL_CTRL, bMaskDWord, 0x0381808d); - PHY_SetBBReg(Adapter, REG_AFE_PLL_CTRL, bMaskDWord, 0xf0ffff83); - PHY_SetBBReg(Adapter, REG_AFE_PLL_CTRL, bMaskDWord, 0xf0ffff82); - PHY_SetBBReg(Adapter, REG_AFE_PLL_CTRL, bMaskDWord, 0xf0ffff83); + rtl8723au_write32(Adapter, REG_AFE_XTAL_CTRL, 0x0381808d); + rtl8723au_write32(Adapter, REG_AFE_PLL_CTRL, 0xf0ffff83); + rtl8723au_write32(Adapter, REG_AFE_PLL_CTRL, 0xf0ffff82); + rtl8723au_write32(Adapter, REG_AFE_PLL_CTRL, 0xf0ffff83); /* RFSW Control */ - PHY_SetBBReg(Adapter, rFPGA0_TxInfo, bMaskDWord, 0x00000003); /* 0x804[14]= 0 */ - PHY_SetBBReg(Adapter, rFPGA0_XAB_RFInterfaceSW, bMaskDWord, 0x07000760); /* 0x870[6:5]= b'11 */ - PHY_SetBBReg(Adapter, rFPGA0_XA_RFInterfaceOE, bMaskDWord, 0x66F60210); /* 0x860[6:5]= b'00 */ + /* 0x804[14]= 0 */ + rtl8723au_write32(Adapter, rFPGA0_TxInfo, 0x00000003); + /* 0x870[6:5]= b'11 */ + rtl8723au_write32(Adapter, rFPGA0_XAB_RFInterfaceSW, 0x07000760); + /* 0x860[6:5]= b'00 */ + rtl8723au_write32(Adapter, rFPGA0_XA_RFInterfaceOE, 0x66F60210); - RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("%s: 0x870 = value 0x%x\n", __func__, PHY_QueryBBReg(Adapter, 0x870, bMaskDWord))); + RT_TRACE(_module_hci_hal_init_c_, _drv_info_, + ("%s: 0x870 = value 0x%x\n", __func__, + rtl8723au_read32(Adapter, 0x870))); /* */ /* Joseph Note: Keep RfRegChnlVal for later use. */ @@ -790,11 +795,9 @@ static void phy_SsPwrSwitch92CU(struct rtw_adapter *Adapter, /* AFE */ if (pHalData->rf_type == RF_2T2R) - PHY_SetBBReg(Adapter, rRx_Wait_CCA, bMaskDWord, - 0x63DB25A0); + rtl8723au_write32(Adapter, rRx_Wait_CCA, 0x63DB25A0); else if (pHalData->rf_type == RF_1T1R) - PHY_SetBBReg(Adapter, rRx_Wait_CCA, bMaskDWord, - 0x631B25A0); + rtl8723au_write32(Adapter, rRx_Wait_CCA, 0x631B25A0); /* 4. issue 3-wire command that RF set to Rx idle mode. This is used to re-write the RX idle mode. */ @@ -825,13 +828,11 @@ static void phy_SsPwrSwitch92CU(struct rtw_adapter *Adapter, for packet detection */ /* (4) Reg800[1] = 1 enable preamble power saving */ Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_RF0] = - PHY_QueryBBReg(Adapter, rFPGA0_XAB_RFParameter, - bMaskDWord); + rtl8723au_read32(Adapter, rFPGA0_XAB_RFParameter); Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_RF1] = - PHY_QueryBBReg(Adapter, rOFDM0_TRxPathEnable, - bMaskDWord); + rtl8723au_read32(Adapter, rOFDM0_TRxPathEnable); Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_RF2] = - PHY_QueryBBReg(Adapter, rFPGA0_RFMOD, bMaskDWord); + rtl8723au_read32(Adapter, rFPGA0_RFMOD); if (pHalData->rf_type == RF_2T2R) { PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter, 0x380038, 0); @@ -843,13 +844,11 @@ static void phy_SsPwrSwitch92CU(struct rtw_adapter *Adapter, /* 2 .AFE control register to power down. bit[30:22] */ Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_AFE0] = - PHY_QueryBBReg(Adapter, rRx_Wait_CCA, bMaskDWord); + rtl8723au_read32(Adapter, rRx_Wait_CCA); if (pHalData->rf_type == RF_2T2R) - PHY_SetBBReg(Adapter, rRx_Wait_CCA, bMaskDWord, - 0x00DB25A0); + rtl8723au_write32(Adapter, rRx_Wait_CCA, 0x00DB25A0); else if (pHalData->rf_type == RF_1T1R) - PHY_SetBBReg(Adapter, rRx_Wait_CCA, bMaskDWord, - 0x001B25A0); + rtl8723au_write32(Adapter, rRx_Wait_CCA, 0x001B25A0); /* 3. issue 3-wire command that RF set to power down.*/ PHY_SetRFReg(Adapter, RF_PATH_A, RF_AC, bRFRegOffsetMask, 0); -- GitLab From a39bd1f53c5cea79db22b37a59b75dbee6e36aa3 Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Thu, 5 Mar 2015 14:24:42 -0500 Subject: [PATCH 03215/11651] staging: rtl8723au: odm.c: Use rtl8723au_{read, write}32() for 32 bit register access Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/hal/odm.c | 35 +++++++++++++---------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/odm.c b/drivers/staging/rtl8723au/hal/odm.c index 7a5cff5431c7..5220a0b535a3 100644 --- a/drivers/staging/rtl8723au/hal/odm.c +++ b/drivers/staging/rtl8723au/hal/odm.c @@ -714,28 +714,25 @@ void odm_DIG23a(struct rtw_adapter *adapter) void odm_FalseAlarmCounterStatistics23a(struct dm_odm_t *pDM_Odm) { - u32 ret_value; + struct rtw_adapter *adapter = pDM_Odm->Adapter; struct false_alarm_stats *FalseAlmCnt = &pDM_Odm->FalseAlmCnt; + u32 ret_value; /* hold ofdm counter */ - /* hold page C counter */ + /* hold page C counter */ ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_HOLDC_11N, BIT(31), 1); /* hold page D counter */ ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RSTD_11N, BIT(31), 1); - ret_value = - ODM_GetBBReg(pDM_Odm, ODM_REG_OFDM_FA_TYPE1_11N, bMaskDWord); + ret_value = rtl8723au_read32(adapter, ODM_REG_OFDM_FA_TYPE1_11N); FalseAlmCnt->Cnt_Fast_Fsync = (ret_value&0xffff); FalseAlmCnt->Cnt_SB_Search_fail = (ret_value & 0xffff0000)>>16; - ret_value = - ODM_GetBBReg(pDM_Odm, ODM_REG_OFDM_FA_TYPE2_11N, bMaskDWord); + ret_value = rtl8723au_read32(adapter, ODM_REG_OFDM_FA_TYPE2_11N); FalseAlmCnt->Cnt_OFDM_CCA = (ret_value&0xffff); FalseAlmCnt->Cnt_Parity_Fail = (ret_value & 0xffff0000)>>16; - ret_value = - ODM_GetBBReg(pDM_Odm, ODM_REG_OFDM_FA_TYPE3_11N, bMaskDWord); + ret_value = rtl8723au_read32(adapter, ODM_REG_OFDM_FA_TYPE3_11N); FalseAlmCnt->Cnt_Rate_Illegal = (ret_value&0xffff); FalseAlmCnt->Cnt_Crc8_fail = (ret_value & 0xffff0000)>>16; - ret_value = - ODM_GetBBReg(pDM_Odm, ODM_REG_OFDM_FA_TYPE4_11N, bMaskDWord); + ret_value = rtl8723au_read32(adapter, ODM_REG_OFDM_FA_TYPE4_11N); FalseAlmCnt->Cnt_Mcs_fail = (ret_value&0xffff); FalseAlmCnt->Cnt_Ofdm_fail = FalseAlmCnt->Cnt_Parity_Fail + @@ -753,7 +750,7 @@ void odm_FalseAlarmCounterStatistics23a(struct dm_odm_t *pDM_Odm) ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_CCK_FA_MSB_11N, bMaskByte3); FalseAlmCnt->Cnt_Cck_fail += (ret_value & 0xff) << 8; - ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_CCK_CCA_CNT_11N, bMaskDWord); + ret_value = rtl8723au_read32(adapter, ODM_REG_CCK_CCA_CNT_11N); FalseAlmCnt->Cnt_CCK_CCA = ((ret_value&0xFF)<<8) | ((ret_value&0xFF00)>>8); @@ -881,19 +878,19 @@ void odm_DynamicBBPowerSaving23a(struct dm_odm_t *pDM_Odm) void ODM_RF_Saving23a(struct dm_odm_t *pDM_Odm, u8 bForceInNormal) { struct dynamic_pwr_sav *pDM_PSTable = &pDM_Odm->DM_PSTable; + struct rtw_adapter *adapter = pDM_Odm->Adapter; u8 Rssi_Up_bound = 30; u8 Rssi_Low_bound = 25; if (pDM_PSTable->initialize == 0) { - pDM_PSTable->Reg874 = (ODM_GetBBReg(pDM_Odm, 0x874, - bMaskDWord)&0x1CC000) >> 14; + pDM_PSTable->Reg874 = + (rtl8723au_read32(adapter, 0x874) & 0x1CC000) >> 14; pDM_PSTable->RegC70 = - (ODM_GetBBReg(pDM_Odm, 0xc70, bMaskDWord) & BIT(3)) >>3; - pDM_PSTable->Reg85C = (ODM_GetBBReg(pDM_Odm, 0x85c, - bMaskDWord)&0xFF000000)>>24; - pDM_PSTable->RegA74 = (ODM_GetBBReg(pDM_Odm, 0xa74, - bMaskDWord)&0xF000)>>12; - /* Reg818 = PHY_QueryBBReg(pAdapter, 0x818, bMaskDWord); */ + (rtl8723au_read32(adapter, 0xc70) & BIT(3)) >>3; + pDM_PSTable->Reg85C = + (rtl8723au_read32(adapter, 0x85c) & 0xFF000000) >> 24; + pDM_PSTable->RegA74 = + (rtl8723au_read32(adapter, 0xa74) & 0xF000) >> 12; pDM_PSTable->initialize = 1; } -- GitLab From 539b61bfd79bee0663f438009d21013abd36f17b Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Thu, 5 Mar 2015 14:24:43 -0500 Subject: [PATCH 03216/11651] staging: rtl8723au: odm_ConfigBB_AGC_8723A() always does 32 bit writes Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/hal/HalHWImg8723A_BB.c | 5 ++--- drivers/staging/rtl8723au/hal/odm_RegConfig8723A.c | 14 ++++---------- .../staging/rtl8723au/include/odm_RegConfig8723A.h | 3 +-- 3 files changed, 7 insertions(+), 15 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/HalHWImg8723A_BB.c b/drivers/staging/rtl8723au/hal/HalHWImg8723A_BB.c index 577b9113b212..efeb82cfa4a2 100644 --- a/drivers/staging/rtl8723au/hal/HalHWImg8723A_BB.c +++ b/drivers/staging/rtl8723au/hal/HalHWImg8723A_BB.c @@ -215,7 +215,6 @@ static u32 Array_AGC_TAB_1T_8723A[] = { void ODM_ReadAndConfig_AGC_TAB_1T_8723A(struct dm_odm_t *pDM_Odm) { - u32 hex; u32 i; u8 platform = 0x04; @@ -233,7 +232,7 @@ void ODM_ReadAndConfig_AGC_TAB_1T_8723A(struct dm_odm_t *pDM_Odm) /* This (offset, data) pair meets the condition. */ if (v1 < 0xCDCDCDCD) { - odm_ConfigBB_AGC_8723A(pDM_Odm, v1, bMaskDWord, v2); + odm_ConfigBB_AGC_8723A(pDM_Odm, v1, v2); continue; } else { if (!CheckCondition(Array[i], hex)) { @@ -250,7 +249,7 @@ void ODM_ReadAndConfig_AGC_TAB_1T_8723A(struct dm_odm_t *pDM_Odm) while (v2 != 0xDEAD && v2 != 0xCDEF && v2 != 0xCDCD && i < ArrayLen - 2) { - odm_ConfigBB_AGC_8723A(pDM_Odm, v1, bMaskDWord, v2); + odm_ConfigBB_AGC_8723A(pDM_Odm, v1, v2); READ_NEXT_PAIR(v1, v2, i); } while (v2 != 0xDEAD && i < ArrayLen - 2) diff --git a/drivers/staging/rtl8723au/hal/odm_RegConfig8723A.c b/drivers/staging/rtl8723au/hal/odm_RegConfig8723A.c index 88e0126e855a..7fa1b38f83a0 100644 --- a/drivers/staging/rtl8723au/hal/odm_RegConfig8723A.c +++ b/drivers/staging/rtl8723au/hal/odm_RegConfig8723A.c @@ -14,6 +14,7 @@ ******************************************************************************/ #include "odm_precomp.h" +#include "usb_ops_linux.h" void odm_ConfigRFReg_8723A( @@ -54,21 +55,14 @@ void odm_ConfigMAC_8723A(struct dm_odm_t *pDM_Odm, Addr, Data)); } -void -odm_ConfigBB_AGC_8723A( - struct dm_odm_t *pDM_Odm, - u32 Addr, - u32 Bitmask, - u32 Data - ) +void odm_ConfigBB_AGC_8723A(struct dm_odm_t *pDM_Odm, u32 addr, u32 data) { - ODM_SetBBReg(pDM_Odm, Addr, Bitmask, Data); + rtl8723au_write32(pDM_Odm->Adapter, addr, data); /* Add 1us delay between BB/RF register setting. */ udelay(1); ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, - ("===> ODM_ConfigBBWithHeaderFile23a: [AGC_TAB] %08X %08X\n", - Addr, Data)); + ("===> %s: [AGC_TAB] %08X %08X\n", __func__, addr, data)); } void diff --git a/drivers/staging/rtl8723au/include/odm_RegConfig8723A.h b/drivers/staging/rtl8723au/include/odm_RegConfig8723A.h index a6cfb6df4cf7..5f6bc30b43af 100644 --- a/drivers/staging/rtl8723au/include/odm_RegConfig8723A.h +++ b/drivers/staging/rtl8723au/include/odm_RegConfig8723A.h @@ -20,8 +20,7 @@ void odm_ConfigRFReg_8723A(struct dm_odm_t *pDM_Odm, u32 Addr, u32 Data, void odm_ConfigMAC_8723A(struct dm_odm_t *pDM_Odm, u32 Addr, u8 Data); -void odm_ConfigBB_AGC_8723A(struct dm_odm_t *pDM_Odm, u32 Addr, - u32 Bitmask, u32 Data); +void odm_ConfigBB_AGC_8723A(struct dm_odm_t *pDM_Odm, u32 addr, u32 data); void odm_ConfigBB_PHY_8723A(struct dm_odm_t *pDM_Odm, u32 Addr, u32 Bitmask, u32 Data); -- GitLab From 2f3cf84fceb77a62e0d9ea0d003fea619c99db4e Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Thu, 5 Mar 2015 14:24:44 -0500 Subject: [PATCH 03217/11651] staging: rtl8723au: odm_ConfigBB_PHY_8723A() always issues 32 bit writes Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- .../staging/rtl8723au/hal/HalHWImg8723A_BB.c | 35 ++++++++++--------- .../rtl8723au/hal/odm_RegConfig8723A.c | 28 ++++++--------- .../rtl8723au/include/odm_RegConfig8723A.h | 2 +- 3 files changed, 31 insertions(+), 34 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/HalHWImg8723A_BB.c b/drivers/staging/rtl8723au/hal/HalHWImg8723A_BB.c index efeb82cfa4a2..e8cab9e97385 100644 --- a/drivers/staging/rtl8723au/hal/HalHWImg8723A_BB.c +++ b/drivers/staging/rtl8723au/hal/HalHWImg8723A_BB.c @@ -236,7 +236,7 @@ void ODM_ReadAndConfig_AGC_TAB_1T_8723A(struct dm_odm_t *pDM_Odm) continue; } else { if (!CheckCondition(Array[i], hex)) { - /* Discard the following (offset, data) pairs. */ + /* Discard the following (offset, data) pairs */ READ_NEXT_PAIR(v1, v2, i); while (v2 != 0xDEAD && v2 != 0xCDEF && @@ -244,7 +244,8 @@ void ODM_ReadAndConfig_AGC_TAB_1T_8723A(struct dm_odm_t *pDM_Odm) READ_NEXT_PAIR(v1, v2, i); i -= 2; /* prevent from for-loop += 2 */ } else { - /* Configure matched pairs and skip to end of if-else. */ + /* Configure matched pairs and skip to + end of if-else. */ READ_NEXT_PAIR(v1, v2, i); while (v2 != 0xDEAD && v2 != 0xCDEF && @@ -479,11 +480,11 @@ void ODM_ReadAndConfig_PHY_REG_1T_8723A(struct dm_odm_t *pDM_Odm) /* This (offset, data) pair meets the condition. */ if (v1 < 0xCDCDCDCD) { - odm_ConfigBB_PHY_8723A(pDM_Odm, v1, bMaskDWord, v2); + odm_ConfigBB_PHY_8723A(pDM_Odm, v1, v2); continue; } else { if (!CheckCondition(Array[i], hex)) { - /* Discard the following (offset, data) pairs. */ + /* Discard the following (offset, data) pairs */ READ_NEXT_PAIR(v1, v2, i); while (v2 != 0xDEAD && v2 != 0xCDEF && @@ -491,12 +492,13 @@ void ODM_ReadAndConfig_PHY_REG_1T_8723A(struct dm_odm_t *pDM_Odm) READ_NEXT_PAIR(v1, v2, i); i -= 2; /* prevent from for-loop += 2 */ } else { - /* Configure matched pairs and skip to end of if-else. */ + /* Configure matched pairs and skip to + end of if-else. */ READ_NEXT_PAIR(v1, v2, i); while (v2 != 0xDEAD && v2 != 0xCDEF && v2 != 0xCDCD && i < ArrayLen - 2) { - odm_ConfigBB_PHY_8723A(pDM_Odm, v1, bMaskDWord, v2); + odm_ConfigBB_PHY_8723A(pDM_Odm, v1, v2); READ_NEXT_PAIR(v1, v2, i); } while (v2 != 0xDEAD && i < ArrayLen - 2) @@ -517,12 +519,12 @@ static u32 Array_PHY_REG_MP_8723A[] = { void ODM_ReadAndConfig_PHY_REG_MP_8723A(struct dm_odm_t *pDM_Odm) { - u32 hex = 0; - u32 i = 0; - u8 platform = 0x04; - u8 board = pDM_Odm->BoardType; - u32 ArrayLen = sizeof(Array_PHY_REG_MP_8723A)/sizeof(u32); - u32 *Array = Array_PHY_REG_MP_8723A; + u32 hex = 0; + u32 i; + u8 platform = 0x04; + u8 board = pDM_Odm->BoardType; + u32 ArrayLen = sizeof(Array_PHY_REG_MP_8723A)/sizeof(u32); + u32 *Array = Array_PHY_REG_MP_8723A; hex += board; hex += ODM_ITRF_USB << 8; @@ -534,11 +536,11 @@ void ODM_ReadAndConfig_PHY_REG_MP_8723A(struct dm_odm_t *pDM_Odm) /* This (offset, data) pair meets the condition. */ if (v1 < 0xCDCDCDCD) { - odm_ConfigBB_PHY_8723A(pDM_Odm, v1, bMaskDWord, v2); + odm_ConfigBB_PHY_8723A(pDM_Odm, v1, v2); continue; } else { if (!CheckCondition(Array[i], hex)) { - /* Discard the following (offset, data) pairs. */ + /* Discard the following (offset, data) pairs */ READ_NEXT_PAIR(v1, v2, i); while (v2 != 0xDEAD && v2 != 0xCDEF && @@ -546,12 +548,13 @@ void ODM_ReadAndConfig_PHY_REG_MP_8723A(struct dm_odm_t *pDM_Odm) READ_NEXT_PAIR(v1, v2, i); i -= 2; /* prevent from for-loop += 2 */ } else { - /* Configure matched pairs and skip to end of if-else. */ + /* Configure matched pairs and skip to + end of if-else. */ READ_NEXT_PAIR(v1, v2, i); while (v2 != 0xDEAD && v2 != 0xCDEF && v2 != 0xCDCD && i < ArrayLen - 2) { - odm_ConfigBB_PHY_8723A(pDM_Odm, v1, bMaskDWord, v2); + odm_ConfigBB_PHY_8723A(pDM_Odm, v1, v2); READ_NEXT_PAIR(v1, v2, i); } while (v2 != 0xDEAD && i < ArrayLen - 2) diff --git a/drivers/staging/rtl8723au/hal/odm_RegConfig8723A.c b/drivers/staging/rtl8723au/hal/odm_RegConfig8723A.c index 7fa1b38f83a0..fb84f6ce5a91 100644 --- a/drivers/staging/rtl8723au/hal/odm_RegConfig8723A.c +++ b/drivers/staging/rtl8723au/hal/odm_RegConfig8723A.c @@ -66,33 +66,27 @@ void odm_ConfigBB_AGC_8723A(struct dm_odm_t *pDM_Odm, u32 addr, u32 data) } void -odm_ConfigBB_PHY_8723A( - struct dm_odm_t *pDM_Odm, - u32 Addr, - u32 Bitmask, - u32 Data - ) +odm_ConfigBB_PHY_8723A(struct dm_odm_t *pDM_Odm, u32 addr, u32 data) { - if (Addr == 0xfe) + if (addr == 0xfe) msleep(50); - else if (Addr == 0xfd) + else if (addr == 0xfd) mdelay(5); - else if (Addr == 0xfc) + else if (addr == 0xfc) mdelay(1); - else if (Addr == 0xfb) + else if (addr == 0xfb) udelay(50); - else if (Addr == 0xfa) + else if (addr == 0xfa) udelay(5); - else if (Addr == 0xf9) + else if (addr == 0xf9) udelay(1); - else if (Addr == 0xa24) - pDM_Odm->RFCalibrateInfo.RegA24 = Data; - ODM_SetBBReg(pDM_Odm, Addr, Bitmask, Data); + else if (addr == 0xa24) + pDM_Odm->RFCalibrateInfo.RegA24 = data; + rtl8723au_write32(pDM_Odm->Adapter, addr, data); /* Add 1us delay between BB/RF register setting. */ udelay(1); ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, - ("===> ODM_ConfigBBWithHeaderFile23a: [PHY_REG] %08X %08X\n", - Addr, Data)); + ("===> %s: [PHY_REG] %08X %08X\n", __func__, addr, data)); } diff --git a/drivers/staging/rtl8723au/include/odm_RegConfig8723A.h b/drivers/staging/rtl8723au/include/odm_RegConfig8723A.h index 5f6bc30b43af..f2a54d829ed5 100644 --- a/drivers/staging/rtl8723au/include/odm_RegConfig8723A.h +++ b/drivers/staging/rtl8723au/include/odm_RegConfig8723A.h @@ -22,6 +22,6 @@ void odm_ConfigMAC_8723A(struct dm_odm_t *pDM_Odm, u32 Addr, u8 Data); void odm_ConfigBB_AGC_8723A(struct dm_odm_t *pDM_Odm, u32 addr, u32 data); -void odm_ConfigBB_PHY_8723A(struct dm_odm_t *pDM_Odm, u32 Addr, u32 Bitmask, u32 Data); +void odm_ConfigBB_PHY_8723A(struct dm_odm_t *pDM_Odm, u32 addr, u32 data); #endif /* end of SUPPORT */ -- GitLab From 4f092cc7eacb35cf9a7f0a86813094b5c78e476f Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Thu, 5 Mar 2015 14:24:45 -0500 Subject: [PATCH 03218/11651] staging: rtl8723au: Eliminate ODM_Write1Byte() Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/hal/odm.c | 4 ++-- drivers/staging/rtl8723au/hal/odm_RegConfig8723A.c | 10 +++------- drivers/staging/rtl8723au/hal/odm_interface.c | 7 ------- drivers/staging/rtl8723au/include/odm_interface.h | 1 - 4 files changed, 5 insertions(+), 17 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/odm.c b/drivers/staging/rtl8723au/hal/odm.c index 5220a0b535a3..247ae631077f 100644 --- a/drivers/staging/rtl8723au/hal/odm.c +++ b/drivers/staging/rtl8723au/hal/odm.c @@ -849,8 +849,8 @@ void ODM_Write_CCK_CCA_Thres23a(struct dm_odm_t *pDM_Odm, u8 CurCCK_CCAThres) struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable; if (pDM_DigTable->CurCCK_CCAThres != CurCCK_CCAThres) - ODM_Write1Byte(pDM_Odm, ODM_REG(CCK_CCA, pDM_Odm), - CurCCK_CCAThres); + rtl8723au_write8(pDM_Odm->Adapter, ODM_REG(CCK_CCA, pDM_Odm), + CurCCK_CCAThres); pDM_DigTable->PreCCK_CCAThres = pDM_DigTable->CurCCK_CCAThres; pDM_DigTable->CurCCK_CCAThres = CurCCK_CCAThres; } diff --git a/drivers/staging/rtl8723au/hal/odm_RegConfig8723A.c b/drivers/staging/rtl8723au/hal/odm_RegConfig8723A.c index fb84f6ce5a91..342dec3e939f 100644 --- a/drivers/staging/rtl8723au/hal/odm_RegConfig8723A.c +++ b/drivers/staging/rtl8723au/hal/odm_RegConfig8723A.c @@ -44,15 +44,11 @@ odm_ConfigRFReg_8723A( } } -void odm_ConfigMAC_8723A(struct dm_odm_t *pDM_Odm, - u32 Addr, - u8 Data - ) +void odm_ConfigMAC_8723A(struct dm_odm_t *pDM_Odm, u32 addr, u8 data) { - ODM_Write1Byte(pDM_Odm, Addr, Data); + rtl8723au_write8(pDM_Odm->Adapter, addr, data); ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, - ("===> ODM_ConfigMACWithHeaderFile23a: [MAC_REG] %08X %08X\n", - Addr, Data)); + ("===> %s: [MAC_REG] %08X %08X\n", __func__, addr, data)); } void odm_ConfigBB_AGC_8723A(struct dm_odm_t *pDM_Odm, u32 addr, u32 data) diff --git a/drivers/staging/rtl8723au/hal/odm_interface.c b/drivers/staging/rtl8723au/hal/odm_interface.c index f03f6d4a3888..36fe7b711905 100644 --- a/drivers/staging/rtl8723au/hal/odm_interface.c +++ b/drivers/staging/rtl8723au/hal/odm_interface.c @@ -46,13 +46,6 @@ u32 ODM_Read4Byte(struct dm_odm_t *pDM_Odm, u32 RegAddr) return rtl8723au_read32(Adapter, RegAddr); } -void ODM_Write1Byte(struct dm_odm_t *pDM_Odm, u32 RegAddr, u8 Data) -{ - struct rtw_adapter *Adapter = pDM_Odm->Adapter; - - rtl8723au_write8(Adapter, RegAddr, Data); -} - void ODM_Write2Byte(struct dm_odm_t *pDM_Odm, u32 RegAddr, u16 Data) { struct rtw_adapter *Adapter = pDM_Odm->Adapter; diff --git a/drivers/staging/rtl8723au/include/odm_interface.h b/drivers/staging/rtl8723au/include/odm_interface.h index ea35070b744f..e993d8d3ffc2 100644 --- a/drivers/staging/rtl8723au/include/odm_interface.h +++ b/drivers/staging/rtl8723au/include/odm_interface.h @@ -58,7 +58,6 @@ typedef void (*RT_WORKITEM_CALL_BACK)(struct work_struct *pContext); u8 ODM_Read1Byte(struct dm_odm_t *pDM_Odm, u32 RegAddr); u16 ODM_Read2Byte(struct dm_odm_t *pDM_Odm, u32 RegAddr); u32 ODM_Read4Byte(struct dm_odm_t *pDM_Odm, u32 RegAddr); -void ODM_Write1Byte(struct dm_odm_t *pDM_Odm, u32 RegAddr, u8 Data); void ODM_Write2Byte(struct dm_odm_t *pDM_Odm, u32 RegAddr, u16 Data); void ODM_Write4Byte(struct dm_odm_t *pDM_Odm, u32 RegAddr, u32 Data); void ODM_SetMACReg(struct dm_odm_t *pDM_Odm, u32 RegAddr, u32 BitMask, u32 Data); -- GitLab From c43b3e319f558acebd2e05bd24b5ba0bed27c3f2 Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Thu, 5 Mar 2015 14:24:46 -0500 Subject: [PATCH 03219/11651] staging: rtl8723au: Remove various ODM_* register access wrappers Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/hal/odm_interface.c | 53 ------------------- .../staging/rtl8723au/include/odm_interface.h | 6 --- 2 files changed, 59 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/odm_interface.c b/drivers/staging/rtl8723au/hal/odm_interface.c index 36fe7b711905..01413006e11d 100644 --- a/drivers/staging/rtl8723au/hal/odm_interface.c +++ b/drivers/staging/rtl8723au/hal/odm_interface.c @@ -23,22 +23,6 @@ /* */ #include -u8 ODM_Read1Byte(struct dm_odm_t *pDM_Odm, - u32 RegAddr - ) -{ - struct rtw_adapter *Adapter = pDM_Odm->Adapter; - - return rtl8723au_read8(Adapter, RegAddr); -} - -u16 ODM_Read2Byte(struct dm_odm_t *pDM_Odm, u32 RegAddr) -{ - struct rtw_adapter *Adapter = pDM_Odm->Adapter; - - return rtl8723au_read16(Adapter, RegAddr); -} - u32 ODM_Read4Byte(struct dm_odm_t *pDM_Odm, u32 RegAddr) { struct rtw_adapter *Adapter = pDM_Odm->Adapter; @@ -46,43 +30,6 @@ u32 ODM_Read4Byte(struct dm_odm_t *pDM_Odm, u32 RegAddr) return rtl8723au_read32(Adapter, RegAddr); } -void ODM_Write2Byte(struct dm_odm_t *pDM_Odm, u32 RegAddr, u16 Data) -{ - struct rtw_adapter *Adapter = pDM_Odm->Adapter; - - rtl8723au_write16(Adapter, RegAddr, Data); -} - -void ODM_Write4Byte(struct dm_odm_t *pDM_Odm, u32 RegAddr, u32 Data) -{ - struct rtw_adapter *Adapter = pDM_Odm->Adapter; - - rtl8723au_write32(Adapter, RegAddr, Data); -} - -void ODM_SetMACReg( - struct dm_odm_t *pDM_Odm, - u32 RegAddr, - u32 BitMask, - u32 Data - ) -{ - struct rtw_adapter *Adapter = pDM_Odm->Adapter; - - PHY_SetBBReg(Adapter, RegAddr, BitMask, Data); -} - -u32 ODM_GetMACReg( - struct dm_odm_t *pDM_Odm, - u32 RegAddr, - u32 BitMask - ) -{ - struct rtw_adapter *Adapter = pDM_Odm->Adapter; - - return PHY_QueryBBReg(Adapter, RegAddr, BitMask); -} - void ODM_SetBBReg( struct dm_odm_t *pDM_Odm, u32 RegAddr, diff --git a/drivers/staging/rtl8723au/include/odm_interface.h b/drivers/staging/rtl8723au/include/odm_interface.h index e993d8d3ffc2..a4ce5ce6400a 100644 --- a/drivers/staging/rtl8723au/include/odm_interface.h +++ b/drivers/staging/rtl8723au/include/odm_interface.h @@ -55,13 +55,7 @@ typedef void (*RT_WORKITEM_CALL_BACK)(struct work_struct *pContext); /* */ -u8 ODM_Read1Byte(struct dm_odm_t *pDM_Odm, u32 RegAddr); -u16 ODM_Read2Byte(struct dm_odm_t *pDM_Odm, u32 RegAddr); u32 ODM_Read4Byte(struct dm_odm_t *pDM_Odm, u32 RegAddr); -void ODM_Write2Byte(struct dm_odm_t *pDM_Odm, u32 RegAddr, u16 Data); -void ODM_Write4Byte(struct dm_odm_t *pDM_Odm, u32 RegAddr, u32 Data); -void ODM_SetMACReg(struct dm_odm_t *pDM_Odm, u32 RegAddr, u32 BitMask, u32 Data); -u32 ODM_GetMACReg(struct dm_odm_t *pDM_Odm, u32 RegAddr, u32 BitMask); void ODM_SetBBReg(struct dm_odm_t *pDM_Odm, u32 RegAddr, u32 BitMask, u32 Data); u32 ODM_GetBBReg(struct dm_odm_t *pDM_Odm, u32 RegAddr, u32 BitMask); void ODM_SetRFReg(struct dm_odm_t *pDM_Odm, enum RF_RADIO_PATH eRFPath, -- GitLab From 53de9947e3488b743a6cec200e967237af481b11 Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Thu, 5 Mar 2015 14:24:47 -0500 Subject: [PATCH 03220/11651] staging: rtl8723au: Get rid of ODM_Read4Byte() Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/hal/odm.c | 9 ++++----- drivers/staging/rtl8723au/hal/odm_interface.c | 7 ------- drivers/staging/rtl8723au/include/odm_interface.h | 2 -- 3 files changed, 4 insertions(+), 14 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/odm.c b/drivers/staging/rtl8723au/hal/odm.c index 247ae631077f..59af7bcdb647 100644 --- a/drivers/staging/rtl8723au/hal/odm.c +++ b/drivers/staging/rtl8723au/hal/odm.c @@ -1256,7 +1256,6 @@ static void odm_TXPowerTrackingInit(struct dm_odm_t *pDM_Odm) /* EDCA Turbo */ static void ODM_EdcaTurboInit23a(struct dm_odm_t *pDM_Odm) { - struct rtw_adapter *Adapter = pDM_Odm->Adapter; pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA = false; @@ -1264,16 +1263,16 @@ static void ODM_EdcaTurboInit23a(struct dm_odm_t *pDM_Odm) ODM_RT_TRACE(pDM_Odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD, ("Orginial VO PARAM: 0x%x\n", - ODM_Read4Byte(pDM_Odm, ODM_EDCA_VO_PARAM))); + rtl8723au_read32(Adapter, ODM_EDCA_VO_PARAM))); ODM_RT_TRACE(pDM_Odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD, ("Orginial VI PARAM: 0x%x\n", - ODM_Read4Byte(pDM_Odm, ODM_EDCA_VI_PARAM))); + rtl8723au_read32(Adapter, ODM_EDCA_VI_PARAM))); ODM_RT_TRACE(pDM_Odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD, ("Orginial BE PARAM: 0x%x\n", - ODM_Read4Byte(pDM_Odm, ODM_EDCA_BE_PARAM))); + rtl8723au_read32(Adapter, ODM_EDCA_BE_PARAM))); ODM_RT_TRACE(pDM_Odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD, ("Orginial BK PARAM: 0x%x\n", - ODM_Read4Byte(pDM_Odm, ODM_EDCA_BK_PARAM))); + rtl8723au_read32(Adapter, ODM_EDCA_BK_PARAM))); } static void odm_EdcaTurboCheck23a(struct dm_odm_t *pDM_Odm) diff --git a/drivers/staging/rtl8723au/hal/odm_interface.c b/drivers/staging/rtl8723au/hal/odm_interface.c index 01413006e11d..5b57641d0c00 100644 --- a/drivers/staging/rtl8723au/hal/odm_interface.c +++ b/drivers/staging/rtl8723au/hal/odm_interface.c @@ -23,13 +23,6 @@ /* */ #include -u32 ODM_Read4Byte(struct dm_odm_t *pDM_Odm, u32 RegAddr) -{ - struct rtw_adapter *Adapter = pDM_Odm->Adapter; - - return rtl8723au_read32(Adapter, RegAddr); -} - void ODM_SetBBReg( struct dm_odm_t *pDM_Odm, u32 RegAddr, diff --git a/drivers/staging/rtl8723au/include/odm_interface.h b/drivers/staging/rtl8723au/include/odm_interface.h index a4ce5ce6400a..62a46c03e98b 100644 --- a/drivers/staging/rtl8723au/include/odm_interface.h +++ b/drivers/staging/rtl8723au/include/odm_interface.h @@ -54,8 +54,6 @@ typedef void (*RT_WORKITEM_CALL_BACK)(struct work_struct *pContext); /* =========== EXtern Function Prototype */ /* */ - -u32 ODM_Read4Byte(struct dm_odm_t *pDM_Odm, u32 RegAddr); void ODM_SetBBReg(struct dm_odm_t *pDM_Odm, u32 RegAddr, u32 BitMask, u32 Data); u32 ODM_GetBBReg(struct dm_odm_t *pDM_Odm, u32 RegAddr, u32 BitMask); void ODM_SetRFReg(struct dm_odm_t *pDM_Odm, enum RF_RADIO_PATH eRFPath, -- GitLab From 3f9cb6a093030f8deb5785b4cddcbffdf1aa4c3e Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Thu, 5 Mar 2015 14:24:48 -0500 Subject: [PATCH 03221/11651] staging: rtl8723au: Eliminate ODM_GetBBReg() Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/hal/odm.c | 28 +++++++++++-------- drivers/staging/rtl8723au/hal/odm_interface.c | 11 -------- .../staging/rtl8723au/include/odm_interface.h | 1 - 3 files changed, 17 insertions(+), 23 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/odm.c b/drivers/staging/rtl8723au/hal/odm.c index 59af7bcdb647..20499d2b2945 100644 --- a/drivers/staging/rtl8723au/hal/odm.c +++ b/drivers/staging/rtl8723au/hal/odm.c @@ -379,13 +379,18 @@ void ODM_CmnInfoUpdate23a(struct dm_odm_t *pDM_Odm, u32 CmnInfo, u64 Value) } -void odm_CommonInfoSelfInit23a(struct dm_odm_t *pDM_Odm - ) +void odm_CommonInfoSelfInit23a(struct dm_odm_t *pDM_Odm) { - pDM_Odm->bCckHighPower = - (bool) ODM_GetBBReg(pDM_Odm, rFPGA0_XA_HSSIParameter2, BIT(9)); + u32 val32; + + val32 = rtl8723au_read32(pDM_Odm->Adapter, rFPGA0_XA_HSSIParameter2); + if (val32 & BIT(9)) + pDM_Odm->bCckHighPower = true; + else + pDM_Odm->bCckHighPower = false; + pDM_Odm->RFPathRxEnable = - (u8) ODM_GetBBReg(pDM_Odm, rOFDM0_TRxPathEnable, 0x0F); + rtl8723au_read32(pDM_Odm->Adapter, rOFDM0_TRxPathEnable) & 0x0F; ODM_InitDebugSetting23a(pDM_Odm); } @@ -504,10 +509,11 @@ void odm_DIG23abyRSSI_LPS(struct dm_odm_t *pDM_Odm) void odm_DIG23aInit(struct dm_odm_t *pDM_Odm) { struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable; + u32 val32; + + val32 = rtl8723au_read32(pDM_Odm->Adapter, ODM_REG_IGI_A_11N); + pDM_DigTable->CurIGValue = val32 & ODM_BIT_IGI_11N; - pDM_DigTable->CurIGValue = (u8) ODM_GetBBReg(pDM_Odm, - ODM_REG(IGI_A, pDM_Odm), - ODM_BIT(IGI, pDM_Odm)); pDM_DigTable->RssiLowThresh = DM_DIG_THRESH_LOW; pDM_DigTable->RssiHighThresh = DM_DIG_THRESH_HIGH; pDM_DigTable->FALowThresh = DM_FALSEALARM_THRESH_LOW; @@ -745,10 +751,10 @@ void odm_FalseAlarmCounterStatistics23a(struct dm_odm_t *pDM_Odm) ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11N, BIT(12), 1); ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11N, BIT(14), 1); - ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_CCK_FA_LSB_11N, bMaskByte0); + ret_value = rtl8723au_read32(adapter, ODM_REG_CCK_FA_LSB_11N) & 0xff; FalseAlmCnt->Cnt_Cck_fail = ret_value; - ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_CCK_FA_MSB_11N, bMaskByte3); - FalseAlmCnt->Cnt_Cck_fail += (ret_value & 0xff) << 8; + ret_value = rtl8723au_read32(adapter, ODM_REG_CCK_FA_MSB_11N) >> 16; + FalseAlmCnt->Cnt_Cck_fail += (ret_value & 0xff00); ret_value = rtl8723au_read32(adapter, ODM_REG_CCK_CCA_CNT_11N); FalseAlmCnt->Cnt_CCK_CCA = diff --git a/drivers/staging/rtl8723au/hal/odm_interface.c b/drivers/staging/rtl8723au/hal/odm_interface.c index 5b57641d0c00..e005bfa38944 100644 --- a/drivers/staging/rtl8723au/hal/odm_interface.c +++ b/drivers/staging/rtl8723au/hal/odm_interface.c @@ -35,17 +35,6 @@ void ODM_SetBBReg( PHY_SetBBReg(Adapter, RegAddr, BitMask, Data); } -u32 ODM_GetBBReg( - struct dm_odm_t *pDM_Odm, - u32 RegAddr, - u32 BitMask - ) -{ - struct rtw_adapter *Adapter = pDM_Odm->Adapter; - - return PHY_QueryBBReg(Adapter, RegAddr, BitMask); -} - void ODM_SetRFReg( struct dm_odm_t *pDM_Odm, enum RF_RADIO_PATH eRFPath, diff --git a/drivers/staging/rtl8723au/include/odm_interface.h b/drivers/staging/rtl8723au/include/odm_interface.h index 62a46c03e98b..b1d505dc9776 100644 --- a/drivers/staging/rtl8723au/include/odm_interface.h +++ b/drivers/staging/rtl8723au/include/odm_interface.h @@ -55,7 +55,6 @@ typedef void (*RT_WORKITEM_CALL_BACK)(struct work_struct *pContext); /* */ void ODM_SetBBReg(struct dm_odm_t *pDM_Odm, u32 RegAddr, u32 BitMask, u32 Data); -u32 ODM_GetBBReg(struct dm_odm_t *pDM_Odm, u32 RegAddr, u32 BitMask); void ODM_SetRFReg(struct dm_odm_t *pDM_Odm, enum RF_RADIO_PATH eRFPath, u32 RegAddr, u32 BitMask, u32 Data); u32 ODM_GetRFReg(struct dm_odm_t *pDM_Odm, enum RF_RADIO_PATH eRFPath, -- GitLab From bfd30caebaba7f00c13eec3c538799202d36d12a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Br=C3=BCns?= Date: Thu, 5 Mar 2015 23:15:07 -0800 Subject: [PATCH 03222/11651] Input: rename KEY_DIRECTION to KEY_ROTATE_DISPLAY MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The new name better reflects intended usage (but we are keeping the old name as an alias for compatibility). Signed-off-by: Stefan Brüns Signed-off-by: Dmitry Torokhov --- include/uapi/linux/input.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/uapi/linux/input.h b/include/uapi/linux/input.h index a1d7e931ab72..eff1cf18031e 100644 --- a/include/uapi/linux/input.h +++ b/include/uapi/linux/input.h @@ -368,7 +368,8 @@ struct input_keymap_entry { #define KEY_MSDOS 151 #define KEY_COFFEE 152 /* AL Terminal Lock/Screensaver */ #define KEY_SCREENLOCK KEY_COFFEE -#define KEY_DIRECTION 153 +#define KEY_ROTATE_DISPLAY 153 /* Display orientation for e.g. tablets */ +#define KEY_DIRECTION KEY_ROTATE_DISPLAY #define KEY_CYCLEWINDOWS 154 #define KEY_MAIL 155 #define KEY_BOOKMARKS 156 /* AC Bookmarks */ -- GitLab From e92865edebe90cde1eef968cf85acb6613e5695f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Br=C3=BCns?= Date: Thu, 5 Mar 2015 23:25:51 -0800 Subject: [PATCH 03223/11651] Input: use more descriptive KEY_ROTATE_DISPLAY instead of KEY_DIRECTION MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stefan Brüns Acked-by: Jiri Kosina Signed-off-by: Dmitry Torokhov --- drivers/hid/hid-debug.c | 2 +- drivers/platform/x86/fujitsu-tablet.c | 6 +++--- drivers/platform/x86/hp-wmi.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c index 8bf61d295ffd..1086800693b2 100644 --- a/drivers/hid/hid-debug.c +++ b/drivers/hid/hid-debug.c @@ -814,7 +814,7 @@ static const char *keys[KEY_MAX + 1] = { [KEY_DELETEFILE] = "DeleteFile", [KEY_XFER] = "X-fer", [KEY_PROG1] = "Prog1", [KEY_PROG2] = "Prog2", [KEY_WWW] = "WWW", [KEY_MSDOS] = "MSDOS", - [KEY_COFFEE] = "Coffee", [KEY_DIRECTION] = "Direction", + [KEY_COFFEE] = "Coffee", [KEY_ROTATE_DISPLAY] = "RotateDisplay", [KEY_CYCLEWINDOWS] = "CycleWindows", [KEY_MAIL] = "Mail", [KEY_BOOKMARKS] = "Bookmarks", [KEY_COMPUTER] = "Computer", [KEY_BACK] = "Back", [KEY_FORWARD] = "Forward", diff --git a/drivers/platform/x86/fujitsu-tablet.c b/drivers/platform/x86/fujitsu-tablet.c index 53bdbb01bd3f..baea077a02cc 100644 --- a/drivers/platform/x86/fujitsu-tablet.c +++ b/drivers/platform/x86/fujitsu-tablet.c @@ -59,7 +59,7 @@ static unsigned short keymap_Lifebook_Tseries[KEYMAP_LEN] __initdata = { KEY_RESERVED, KEY_SCROLLDOWN, KEY_SCROLLUP, - KEY_DIRECTION, + KEY_ROTATE_DISPLAY, KEY_LEFTCTRL, KEY_BRIGHTNESSUP, KEY_BRIGHTNESSDOWN, @@ -116,7 +116,7 @@ static unsigned short keymap_Lifebook_U810[KEYMAP_LEN] __initdata = { KEY_RESERVED, KEY_PROG1, KEY_PROG2, - KEY_DIRECTION, + KEY_ROTATE_DISPLAY, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, @@ -153,7 +153,7 @@ static unsigned short keymap_Stylistic_ST5xxx[KEYMAP_LEN] __initdata = { KEY_RESERVED, KEY_RESERVED, KEY_MAIL, - KEY_DIRECTION, + KEY_ROTATE_DISPLAY, KEY_ESC, KEY_ENTER, KEY_BRIGHTNESSUP, diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c index 0ab2b377a778..06697315a088 100644 --- a/drivers/platform/x86/hp-wmi.c +++ b/drivers/platform/x86/hp-wmi.c @@ -144,7 +144,7 @@ static const struct key_entry hp_wmi_keymap[] = { { KE_KEY, 0x20e8, { KEY_MEDIA } }, { KE_KEY, 0x2142, { KEY_MEDIA } }, { KE_KEY, 0x213b, { KEY_INFO } }, - { KE_KEY, 0x2169, { KEY_DIRECTION } }, + { KE_KEY, 0x2169, { KEY_ROTATE_DISPLAY } }, { KE_KEY, 0x216a, { KEY_SETUP } }, { KE_KEY, 0x231b, { KEY_HELP } }, { KE_END, 0 } -- GitLab From a7ac7c95d4682883d141c5d7a7544d2818f0a09f Mon Sep 17 00:00:00 2001 From: Aleksei Mamlin Date: Fri, 6 Mar 2015 16:38:16 -0800 Subject: [PATCH 03224/11651] Input: goodix - use max touch number from device config Use max number of touches from device config instead of hardcoding. Signed-off-by: Aleksei Mamlin Tested-by: Bastien Nocera Acked-by: Bastien Nocera Tested-by: Antonio Ospite Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/goodix.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c index ca196689f025..3ab7232ac1af 100644 --- a/drivers/input/touchscreen/goodix.c +++ b/drivers/input/touchscreen/goodix.c @@ -48,6 +48,7 @@ struct goodix_ts_data { #define GOODIX_REG_VERSION 0x8140 #define RESOLUTION_LOC 1 +#define MAX_CONTACTS_LOC 5 #define TRIGGER_LOC 6 static const unsigned long goodix_irq_flags[] = { @@ -99,7 +100,7 @@ static int goodix_ts_read_input_report(struct goodix_ts_data *ts, u8 *data) } touch_num = data[0] & 0x0f; - if (touch_num > GOODIX_MAX_CONTACTS) + if (touch_num > ts->max_touch_num) return -EPROTO; if (touch_num > 1) { @@ -141,7 +142,7 @@ static void goodix_ts_report_touch(struct goodix_ts_data *ts, u8 *coor_data) */ static void goodix_process_events(struct goodix_ts_data *ts) { - u8 point_data[1 + GOODIX_CONTACT_SIZE * GOODIX_MAX_CONTACTS]; + u8 point_data[1 + GOODIX_CONTACT_SIZE * ts->max_touch_num]; int touch_num; int i; @@ -202,21 +203,23 @@ static void goodix_read_config(struct goodix_ts_data *ts) ts->abs_x_max = GOODIX_MAX_WIDTH; ts->abs_y_max = GOODIX_MAX_HEIGHT; ts->int_trigger_type = GOODIX_INT_TRIGGER; + ts->max_touch_num = GOODIX_MAX_CONTACTS; return; } ts->abs_x_max = get_unaligned_le16(&config[RESOLUTION_LOC]); ts->abs_y_max = get_unaligned_le16(&config[RESOLUTION_LOC + 2]); - ts->int_trigger_type = (config[TRIGGER_LOC]) & 0x03; - if (!ts->abs_x_max || !ts->abs_y_max) { + ts->int_trigger_type = config[TRIGGER_LOC] & 0x03; + ts->max_touch_num = config[MAX_CONTACTS_LOC] & 0x0f; + if (!ts->abs_x_max || !ts->abs_y_max || !ts->max_touch_num) { dev_err(&ts->client->dev, "Invalid config, using defaults\n"); ts->abs_x_max = GOODIX_MAX_WIDTH; ts->abs_y_max = GOODIX_MAX_HEIGHT; + ts->max_touch_num = GOODIX_MAX_CONTACTS; } } - /** * goodix_read_version - Read goodix touchscreen version * @@ -295,7 +298,7 @@ static int goodix_request_input_dev(struct goodix_ts_data *ts) input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0); input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); - input_mt_init_slots(ts->input_dev, GOODIX_MAX_CONTACTS, + input_mt_init_slots(ts->input_dev, ts->max_touch_num, INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED); ts->input_dev->name = "Goodix Capacitive TouchScreen"; -- GitLab From 771d8f1b178e7e09fcc641fccd48852958dbc329 Mon Sep 17 00:00:00 2001 From: Aleksei Mamlin Date: Fri, 6 Mar 2015 16:43:38 -0800 Subject: [PATCH 03225/11651] Input: goodix - add device tree support This change adds device tree support and binding information for Goodix GT9xx series touchscreen controller. It also adds support for 5-finger chips, like GT911 and GT912, which can be found on ARM tablets, such as Wexler TAB7200 and MSI Primo73. Datasheets can be found here: https://drive.google.com/folderview?id=0BxCVOQS3ZymGfmJyY2RKbE5XbVlKNlktVTlwV0lxNEdxd2dzeWZER094cmJPVnMxN1F0Yzg&usp=sharing Signed-off-by: Aleksei Mamlin Reviewed-by: Bastien Nocera Signed-off-by: Dmitry Torokhov --- .../bindings/input/touchscreen/goodix.txt | 29 +++++++++++++++++++ .../devicetree/bindings/vendor-prefixes.txt | 1 + drivers/input/touchscreen/Kconfig | 5 ++-- drivers/input/touchscreen/goodix.c | 21 +++++++++++++- 4 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 Documentation/devicetree/bindings/input/touchscreen/goodix.txt diff --git a/Documentation/devicetree/bindings/input/touchscreen/goodix.txt b/Documentation/devicetree/bindings/input/touchscreen/goodix.txt new file mode 100644 index 000000000000..8ba98eec765b --- /dev/null +++ b/Documentation/devicetree/bindings/input/touchscreen/goodix.txt @@ -0,0 +1,29 @@ +Device tree bindings for Goodix GT9xx series touchscreen controller + +Required properties: + + - compatible : Should be "goodix,gt911" + or "goodix,gt9110" + or "goodix,gt912" + or "goodix,gt927" + or "goodix,gt9271" + or "goodix,gt928" + or "goodix,gt967" + - reg : I2C address of the chip. Should be 0x5d or 0x14 + - interrupt-parent : Interrupt controller to which the chip is connected + - interrupts : Interrupt to which the chip is connected + +Example: + + i2c@00000000 { + /* ... */ + + gt928@5d { + compatible = "goodix,gt928"; + reg = <0x5d>; + interrupt-parent = <&gpio>; + interrupts = <0 0>; + }; + + /* ... */ + }; diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index 96a17541391e..943ed01f9fe5 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -65,6 +65,7 @@ gef GE Fanuc Intelligent Platforms Embedded Systems, Inc. geniatech Geniatech, Inc. globalscale Globalscale Technologies, Inc. gmt Global Mixed-mode Technology, Inc. +goodix Shenzhen Huiding Technology Co., Ltd. google Google, Inc. gumstix Gumstix, Inc. gw Gateworks Corporation diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 58917525126e..2adf7244b025 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -297,11 +297,12 @@ config TOUCHSCREEN_FUJITSU config TOUCHSCREEN_GOODIX tristate "Goodix I2C touchscreen" - depends on I2C && ACPI + depends on I2C help Say Y here if you have the Goodix touchscreen (such as one installed in Onda v975w tablets) connected to your - system. + system. It also supports 5-finger chip models, which can be + found on ARM tablets, like Wexler TAB7200 and MSI Primo73. If unsure, say N. diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c index 3ab7232ac1af..3af16984d57c 100644 --- a/drivers/input/touchscreen/goodix.c +++ b/drivers/input/touchscreen/goodix.c @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include struct goodix_ts_data { @@ -375,11 +377,27 @@ static const struct i2c_device_id goodix_ts_id[] = { { } }; +#ifdef CONFIG_ACPI static const struct acpi_device_id goodix_acpi_match[] = { { "GDIX1001", 0 }, { } }; MODULE_DEVICE_TABLE(acpi, goodix_acpi_match); +#endif + +#ifdef CONFIG_OF +static const struct of_device_id goodix_of_match[] = { + { .compatible = "goodix,gt911" }, + { .compatible = "goodix,gt9110" }, + { .compatible = "goodix,gt912" }, + { .compatible = "goodix,gt927" }, + { .compatible = "goodix,gt9271" }, + { .compatible = "goodix,gt928" }, + { .compatible = "goodix,gt967" }, + { } +}; +MODULE_DEVICE_TABLE(of, goodix_of_match); +#endif static struct i2c_driver goodix_ts_driver = { .probe = goodix_ts_probe, @@ -387,7 +405,8 @@ static struct i2c_driver goodix_ts_driver = { .driver = { .name = "Goodix-TS", .owner = THIS_MODULE, - .acpi_match_table = goodix_acpi_match, + .acpi_match_table = ACPI_PTR(goodix_acpi_match), + .of_match_table = of_match_ptr(goodix_of_match), }, }; module_i2c_driver(goodix_ts_driver); -- GitLab From 902cb3afab8d4c924376de51ec5c02d171992914 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Szymanski?= Date: Fri, 6 Mar 2015 16:49:38 -0800 Subject: [PATCH 03226/11651] Input: add support for Semtech SX8654 I2C touchscreen controller MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sébastien Szymanski Signed-off-by: Dmitry Torokhov --- .../bindings/input/touchscreen/sx8654.txt | 16 + drivers/input/touchscreen/Kconfig | 11 + drivers/input/touchscreen/Makefile | 1 + drivers/input/touchscreen/sx8654.c | 286 ++++++++++++++++++ 4 files changed, 314 insertions(+) create mode 100644 Documentation/devicetree/bindings/input/touchscreen/sx8654.txt create mode 100644 drivers/input/touchscreen/sx8654.c diff --git a/Documentation/devicetree/bindings/input/touchscreen/sx8654.txt b/Documentation/devicetree/bindings/input/touchscreen/sx8654.txt new file mode 100644 index 000000000000..5aaa6b3aa90c --- /dev/null +++ b/Documentation/devicetree/bindings/input/touchscreen/sx8654.txt @@ -0,0 +1,16 @@ +* Semtech SX8654 I2C Touchscreen Controller + +Required properties: +- compatible: must be "semtech,sx8654" +- reg: i2c slave address +- interrupt-parent: the phandle for the interrupt controller +- interrupts: touch controller interrupt + +Example: + + sx8654@48 { + compatible = "semtech,sx8654"; + reg = <0x48>; + interrupt-parent = <&gpio6>; + interrupts = <3 IRQ_TYPE_EDGE_FALLING>; + }; diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 2adf7244b025..2310d863a6f1 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -962,6 +962,17 @@ config TOUCHSCREEN_SUR40 To compile this driver as a module, choose M here: the module will be called sur40. +config TOUCHSCREEN_SX8654 + tristate "Semtech SX8654 touchscreen" + depends on I2C + help + Say Y here if you have a Semtech SX8654 touchscreen controller. + + If unsure, say N + + To compile this driver as a module, choose M here: the + module will be called sx8654. + config TOUCHSCREEN_TPS6507X tristate "TPS6507x based touchscreens" depends on I2C diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 0242fea2102a..a06a752966fe 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -79,5 +79,6 @@ obj-$(CONFIG_TOUCHSCREEN_WM97XX_ATMEL) += atmel-wm97xx.o obj-$(CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE) += mainstone-wm97xx.o obj-$(CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE) += zylonite-wm97xx.o obj-$(CONFIG_TOUCHSCREEN_W90X900) += w90p910_ts.o +obj-$(CONFIG_TOUCHSCREEN_SX8654) += sx8654.o obj-$(CONFIG_TOUCHSCREEN_TPS6507X) += tps6507x-ts.o obj-$(CONFIG_TOUCHSCREEN_ZFORCE) += zforce_ts.o diff --git a/drivers/input/touchscreen/sx8654.c b/drivers/input/touchscreen/sx8654.c new file mode 100644 index 000000000000..8e531ac0ecde --- /dev/null +++ b/drivers/input/touchscreen/sx8654.c @@ -0,0 +1,286 @@ +/* + * Driver for Semtech SX8654 I2C touchscreen controller. + * + * Copyright (c) 2015 Armadeus Systems + * Sébastien Szymanski + * + * Using code from: + * - sx865x.c + * Copyright (c) 2013 U-MoBo Srl + * Pierluigi Passaro + * - sx8650.c + * Copyright (c) 2009 Wayne Roberts + * - tsc2007.c + * Copyright (c) 2008 Kwangwoo Lee + * - ads7846.c + * Copyright (c) 2005 David Brownell + * Copyright (c) 2006 Nokia Corporation + * - corgi_ts.c + * Copyright (C) 2004-2005 Richard Purdie + * - omap_ts.[hc], ads7846.h, ts_osk.c + * Copyright (C) 2002 MontaVista Software + * Copyright (C) 2004 Texas Instruments + * Copyright (C) 2005 Dirk Behme + * + * 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 +#include +#include +#include +#include +#include + +/* register addresses */ +#define I2C_REG_TOUCH0 0x00 +#define I2C_REG_TOUCH1 0x01 +#define I2C_REG_CHANMASK 0x04 +#define I2C_REG_IRQMASK 0x22 +#define I2C_REG_IRQSRC 0x23 +#define I2C_REG_SOFTRESET 0x3f + +/* commands */ +#define CMD_READ_REGISTER 0x40 +#define CMD_MANUAL 0xc0 +#define CMD_PENTRG 0xe0 + +/* value for I2C_REG_SOFTRESET */ +#define SOFTRESET_VALUE 0xde + +/* bits for I2C_REG_IRQSRC */ +#define IRQ_PENTOUCH_TOUCHCONVDONE 0x08 +#define IRQ_PENRELEASE 0x04 + +/* bits for RegTouch1 */ +#define CONDIRQ 0x20 +#define FILT_7SA 0x03 + +/* bits for I2C_REG_CHANMASK */ +#define CONV_X 0x80 +#define CONV_Y 0x40 + +/* coordinates rate: higher nibble of CTRL0 register */ +#define RATE_MANUAL 0x00 +#define RATE_5000CPS 0xf0 + +/* power delay: lower nibble of CTRL0 register */ +#define POWDLY_1_1MS 0x0b + +#define MAX_12BIT ((1 << 12) - 1) + +struct sx8654 { + struct input_dev *input; + struct i2c_client *client; +}; + +static irqreturn_t sx8654_irq(int irq, void *handle) +{ + struct sx8654 *sx8654 = handle; + u8 irqsrc; + u8 data[4]; + unsigned int x, y; + int retval; + + irqsrc = i2c_smbus_read_byte_data(sx8654->client, + CMD_READ_REGISTER | I2C_REG_IRQSRC); + dev_dbg(&sx8654->client->dev, "irqsrc = 0x%x", irqsrc); + + if (irqsrc < 0) + goto out; + + if (irqsrc & IRQ_PENRELEASE) { + dev_dbg(&sx8654->client->dev, "pen release interrupt"); + + input_report_key(sx8654->input, BTN_TOUCH, 0); + input_sync(sx8654->input); + } + + if (irqsrc & IRQ_PENTOUCH_TOUCHCONVDONE) { + dev_dbg(&sx8654->client->dev, "pen touch interrupt"); + + retval = i2c_master_recv(sx8654->client, data, sizeof(data)); + if (retval != sizeof(data)) + goto out; + + /* invalid data */ + if (unlikely(data[0] & 0x80 || data[2] & 0x80)) + goto out; + + x = ((data[0] & 0xf) << 8) | (data[1]); + y = ((data[2] & 0xf) << 8) | (data[3]); + + input_report_abs(sx8654->input, ABS_X, x); + input_report_abs(sx8654->input, ABS_Y, y); + input_report_key(sx8654->input, BTN_TOUCH, 1); + input_sync(sx8654->input); + + dev_dbg(&sx8654->client->dev, "point(%4d,%4d)\n", x, y); + } + +out: + return IRQ_HANDLED; +} + +static int sx8654_open(struct input_dev *dev) +{ + struct sx8654 *sx8654 = input_get_drvdata(dev); + struct i2c_client *client = sx8654->client; + int error; + + /* enable pen trigger mode */ + error = i2c_smbus_write_byte_data(client, I2C_REG_TOUCH0, + RATE_5000CPS | POWDLY_1_1MS); + if (error) { + dev_err(&client->dev, "writing to I2C_REG_TOUCH0 failed"); + return error; + } + + error = i2c_smbus_write_byte(client, CMD_PENTRG); + if (error) { + dev_err(&client->dev, "writing command CMD_PENTRG failed"); + return error; + } + + enable_irq(client->irq); + + return 0; +} + +static void sx8654_close(struct input_dev *dev) +{ + struct sx8654 *sx8654 = input_get_drvdata(dev); + struct i2c_client *client = sx8654->client; + int error; + + disable_irq(client->irq); + + /* enable manual mode mode */ + error = i2c_smbus_write_byte(client, CMD_MANUAL); + if (error) { + dev_err(&client->dev, "writing command CMD_MANUAL failed"); + return; + } + + error = i2c_smbus_write_byte_data(client, I2C_REG_TOUCH0, 0); + if (error) { + dev_err(&client->dev, "writing to I2C_REG_TOUCH0 failed"); + return; + } +} + +static int sx8654_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct sx8654 *sx8654; + struct input_dev *input; + int error; + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_READ_WORD_DATA)) + return -ENXIO; + + sx8654 = devm_kzalloc(&client->dev, sizeof(*sx8654), GFP_KERNEL); + if (!sx8654) + return -ENOMEM; + + input = devm_input_allocate_device(&client->dev); + if (!sx8654) + return -ENOMEM; + + input->name = "SX8654 I2C Touchscreen"; + input->id.bustype = BUS_I2C; + input->dev.parent = &client->dev; + input->open = sx8654_open; + input->close = sx8654_close; + + __set_bit(INPUT_PROP_DIRECT, input->propbit); + input_set_capability(input, EV_KEY, BTN_TOUCH); + input_set_abs_params(input, ABS_X, 0, MAX_12BIT, 0, 0); + input_set_abs_params(input, ABS_Y, 0, MAX_12BIT, 0, 0); + + sx8654->client = client; + sx8654->input = input; + + input_set_drvdata(sx8654->input, sx8654); + + error = i2c_smbus_write_byte_data(client, I2C_REG_SOFTRESET, + SOFTRESET_VALUE); + if (error) { + dev_err(&client->dev, "writing softreset value failed"); + return error; + } + + error = i2c_smbus_write_byte_data(client, I2C_REG_CHANMASK, + CONV_X | CONV_Y); + if (error) { + dev_err(&client->dev, "writing to I2C_REG_CHANMASK failed"); + return error; + } + + error = i2c_smbus_write_byte_data(client, I2C_REG_IRQMASK, + IRQ_PENTOUCH_TOUCHCONVDONE | + IRQ_PENRELEASE); + if (error) { + dev_err(&client->dev, "writing to I2C_REG_IRQMASK failed"); + return error; + } + + error = i2c_smbus_write_byte_data(client, I2C_REG_TOUCH1, + CONDIRQ | FILT_7SA); + if (error) { + dev_err(&client->dev, "writing to I2C_REG_TOUCH1 failed"); + return error; + } + + error = devm_request_threaded_irq(&client->dev, client->irq, + NULL, sx8654_irq, + IRQF_TRIGGER_FALLING | IRQF_ONESHOT, + client->name, sx8654); + if (error) { + dev_err(&client->dev, + "Failed to enable IRQ %d, error: %d\n", + client->irq, error); + return error; + } + + /* Disable the IRQ, we'll enable it in sx8654_open() */ + disable_irq(client->irq); + + error = input_register_device(sx8654->input); + if (error) + return error; + + i2c_set_clientdata(client, sx8654); + return 0; +} + +#ifdef CONFIG_OF +static const struct of_device_id sx8654_of_match[] = { + { .compatible = "semtech,sx8654", }, + { }, +}; +MODULE_DEVICE_TABLE(of, sx8654_of_match); +#endif + +static const struct i2c_device_id sx8654_id_table[] = { + { "semtech_sx8654", 0 }, + { }, +}; +MODULE_DEVICE_TABLE(i2c, sx8654_id_table); + +static struct i2c_driver sx8654_driver = { + .driver = { + .name = "sx8654", + .of_match_table = of_match_ptr(sx8654_of_match), + }, + .id_table = sx8654_id_table, + .probe = sx8654_probe, +}; +module_i2c_driver(sx8654_driver); + +MODULE_AUTHOR("Sébastien Szymanski "); +MODULE_DESCRIPTION("Semtech SX8654 I2C Touchscreen Driver"); +MODULE_LICENSE("GPL"); -- GitLab From 2635f19c7aeed25d90ac69958c249dd3fe2f787a Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Thu, 5 Mar 2015 14:24:49 -0500 Subject: [PATCH 03227/11651] staging: rtl8723au: odm.c: Further reduce the use of ODM_SetBBReg() Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/hal/odm.c | 168 ++++++++++++++++++++-------- 1 file changed, 119 insertions(+), 49 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/odm.c b/drivers/staging/rtl8723au/hal/odm.c index 20499d2b2945..7a01a8a7340a 100644 --- a/drivers/staging/rtl8723au/hal/odm.c +++ b/drivers/staging/rtl8723au/hal/odm.c @@ -441,15 +441,15 @@ void odm_CmnInfoUpdate_Debug23a(struct dm_odm_t *pDM_Odm) void ODM_Write_DIG23a(struct dm_odm_t *pDM_Odm, u8 CurrentIGI) { + struct rtw_adapter *adapter = pDM_Odm->Adapter; struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable; - - ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, - ("ODM_REG(IGI_A, pDM_Odm) = 0x%x, ODM_BIT(IGI, pDM_Odm) = 0x%x \n", - ODM_REG(IGI_A, pDM_Odm), ODM_BIT(IGI, pDM_Odm))); + u32 val32; if (pDM_DigTable->CurIGValue != CurrentIGI) { - ODM_SetBBReg(pDM_Odm, ODM_REG(IGI_A, pDM_Odm), - ODM_BIT(IGI, pDM_Odm), CurrentIGI); + val32 = rtl8723au_read32(adapter, ODM_REG_IGI_A_11N); + val32 &= ~ODM_BIT_IGI_11N; + val32 |= CurrentIGI; + rtl8723au_write32(adapter, ODM_REG_IGI_A_11N, val32); ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("CurrentIGI(0x%02x). \n", CurrentIGI)); pDM_DigTable->CurIGValue = CurrentIGI; @@ -722,13 +722,17 @@ void odm_FalseAlarmCounterStatistics23a(struct dm_odm_t *pDM_Odm) { struct rtw_adapter *adapter = pDM_Odm->Adapter; struct false_alarm_stats *FalseAlmCnt = &pDM_Odm->FalseAlmCnt; - u32 ret_value; + u32 ret_value, val32; /* hold ofdm counter */ /* hold page C counter */ - ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_HOLDC_11N, BIT(31), 1); + val32 = rtl8723au_read32(adapter, ODM_REG_OFDM_FA_HOLDC_11N); + val32 |= BIT(31); + rtl8723au_write32(adapter, ODM_REG_OFDM_FA_HOLDC_11N, val32); /* hold page D counter */ - ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RSTD_11N, BIT(31), 1); + val32 = rtl8723au_read32(adapter, ODM_REG_OFDM_FA_RSTD_11N); + val32 |= BIT(31); + rtl8723au_write32(adapter, ODM_REG_OFDM_FA_RSTD_11N, val32); ret_value = rtl8723au_read32(adapter, ODM_REG_OFDM_FA_TYPE1_11N); FalseAlmCnt->Cnt_Fast_Fsync = (ret_value&0xffff); FalseAlmCnt->Cnt_SB_Search_fail = (ret_value & 0xffff0000)>>16; @@ -748,8 +752,9 @@ void odm_FalseAlarmCounterStatistics23a(struct dm_odm_t *pDM_Odm) FalseAlmCnt->Cnt_Fast_Fsync + FalseAlmCnt->Cnt_SB_Search_fail; /* hold cck counter */ - ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11N, BIT(12), 1); - ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11N, BIT(14), 1); + val32 = rtl8723au_read32(adapter, ODM_REG_CCK_FA_RST_11N); + val32 |= (BIT(12) | BIT(14)); + rtl8723au_write32(adapter, ODM_REG_CCK_FA_RST_11N, val32); ret_value = rtl8723au_read32(adapter, ODM_REG_CCK_FA_LSB_11N) & 0xff; FalseAlmCnt->Cnt_Cck_fail = ret_value; @@ -773,26 +778,39 @@ void odm_FalseAlarmCounterStatistics23a(struct dm_odm_t *pDM_Odm) if (pDM_Odm->SupportICType >= ODM_RTL8723A) { /* reset false alarm counter registers */ - ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RSTC_11N, BIT(31), 1); - ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RSTC_11N, BIT(31), 0); - ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RSTD_11N, BIT(27), 1); - ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RSTD_11N, BIT(27), 0); + val32 = rtl8723au_read32(adapter, ODM_REG_OFDM_FA_RSTC_11N); + val32 |= BIT(31); + rtl8723au_write32(adapter, ODM_REG_OFDM_FA_RSTC_11N, val32); + val32 = rtl8723au_read32(adapter, ODM_REG_OFDM_FA_RSTC_11N); + val32 &= ~BIT(31); + rtl8723au_write32(adapter, ODM_REG_OFDM_FA_RSTC_11N, val32); + + val32 = rtl8723au_read32(adapter, ODM_REG_OFDM_FA_RSTD_11N); + val32 |= BIT(27); + rtl8723au_write32(adapter, ODM_REG_OFDM_FA_RSTD_11N, val32); + val32 = rtl8723au_read32(adapter, ODM_REG_OFDM_FA_RSTD_11N); + val32 &= ~BIT(27); + rtl8723au_write32(adapter, ODM_REG_OFDM_FA_RSTD_11N, val32); + /* update ofdm counter */ /* update page C counter */ - ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_HOLDC_11N, BIT(31), 0); + val32 = rtl8723au_read32(adapter, ODM_REG_OFDM_FA_HOLDC_11N); + val32 &= ~BIT(31); + rtl8723au_write32(adapter, ODM_REG_OFDM_FA_HOLDC_11N, val32); + /* update page D counter */ - ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RSTD_11N, BIT(31), 0); + val32 = rtl8723au_read32(adapter, ODM_REG_OFDM_FA_RSTD_11N); + val32 &= ~BIT(31); + rtl8723au_write32(adapter, ODM_REG_OFDM_FA_RSTD_11N, val32); /* reset CCK CCA counter */ - ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11N, - BIT(13) | BIT(12), 0); - ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11N, - BIT(13) | BIT(12), 2); - /* reset CCK FA counter */ - ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11N, - BIT(15) | BIT(14), 0); - ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11N, - BIT(15) | BIT(14), 2); + val32 = rtl8723au_read32(adapter, ODM_REG_CCK_FA_RST_11N); + val32 &= ~(BIT(12) | BIT(13) | BIT(14) | BIT(15)); + rtl8723au_write32(adapter, ODM_REG_CCK_FA_RST_11N, val32); + + val32 = rtl8723au_read32(adapter, ODM_REG_CCK_FA_RST_11N); + val32 |= (BIT(13) | BIT(15)); + rtl8723au_write32(adapter, ODM_REG_CCK_FA_RST_11N, val32); } ODM_RT_TRACE(pDM_Odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, @@ -885,6 +903,7 @@ void ODM_RF_Saving23a(struct dm_odm_t *pDM_Odm, u8 bForceInNormal) { struct dynamic_pwr_sav *pDM_PSTable = &pDM_Odm->DM_PSTable; struct rtw_adapter *adapter = pDM_Odm->Adapter; + u32 val32; u8 Rssi_Up_bound = 30; u8 Rssi_Low_bound = 25; if (pDM_PSTable->initialize == 0) { @@ -926,22 +945,43 @@ void ODM_RF_Saving23a(struct dm_odm_t *pDM_Odm, u8 bForceInNormal) * Set 0x874[5]= 1 when enter BB power saving mode. */ /* Suggested by SD3 Yu-Nan. 2011.01.20. */ /* Reg874[5]= 1b'1 */ - if (pDM_Odm->SupportICType == ODM_RTL8723A) - ODM_SetBBReg(pDM_Odm, 0x874, BIT(5), 0x1); + if (pDM_Odm->SupportICType == ODM_RTL8723A) { + val32 = rtl8723au_read32(adapter, 0x874); + val32 |= BIT(5); + rtl8723au_write32(adapter, 0x874, val32); + } /* Reg874[20:18]= 3'b010 */ - ODM_SetBBReg(pDM_Odm, 0x874, 0x1C0000, 0x2); + val32 = rtl8723au_read32(adapter, 0x874); + val32 &= ~(BIT(18) | BIT(20)); + val32 |= BIT(19); + rtl8723au_write32(adapter, 0x874, val32); /* RegC70[3]= 1'b0 */ - ODM_SetBBReg(pDM_Odm, 0xc70, BIT(3), 0); + val32 = rtl8723au_read32(adapter, 0xc70); + val32 &= ~BIT(3); + rtl8723au_write32(adapter, 0xc70, val32); /* Reg85C[31:24]= 0x63 */ - ODM_SetBBReg(pDM_Odm, 0x85c, 0xFF000000, 0x63); + val32 = rtl8723au_read32(adapter, 0x85c); + val32 &= 0x00ffffff; + val32 |= 0x63000000; + rtl8723au_write32(adapter, 0x85c, val32); /* Reg874[15:14]= 2'b10 */ - ODM_SetBBReg(pDM_Odm, 0x874, 0xC000, 0x2); + val32 = rtl8723au_read32(adapter, 0x874); + val32 &= ~BIT(14); + val32 |= BIT(15); + rtl8723au_write32(adapter, 0x874, val32); /* RegA75[7:4]= 0x3 */ - ODM_SetBBReg(pDM_Odm, 0xa74, 0xF000, 0x3); + val32 = rtl8723au_read32(adapter, 0xa74); + val32 &= ~(BIT(14) | BIT(15)); + val32 |= (BIT(12) | BIT(13)); + rtl8723au_write32(adapter, 0xa74, val32); /* Reg818[28]= 1'b0 */ - ODM_SetBBReg(pDM_Odm, 0x818, BIT(28), 0x0); + val32 = rtl8723au_read32(adapter, 0x818); + val32 &= ~BIT(28); + rtl8723au_write32(adapter, 0x818, val32); /* Reg818[28]= 1'b1 */ - ODM_SetBBReg(pDM_Odm, 0x818, BIT(28), 0x1); + val32 = rtl8723au_read32(adapter, 0x818); + val32 |= BIT(28); + rtl8723au_write32(adapter, 0x818, val32); } else { ODM_SetBBReg(pDM_Odm, 0x874, 0x1CC000, pDM_PSTable->Reg874); @@ -951,11 +991,16 @@ void ODM_RF_Saving23a(struct dm_odm_t *pDM_Odm, u8 bForceInNormal) pDM_PSTable->Reg85C); ODM_SetBBReg(pDM_Odm, 0xa74, 0xF000, pDM_PSTable->RegA74); - ODM_SetBBReg(pDM_Odm, 0x818, BIT(28), 0x0); + val32 = rtl8723au_read32(adapter, 0x818); + val32 &= ~BIT(28); + rtl8723au_write32(adapter, 0x818, val32); /* Reg874[5]= 1b'0 */ - if (pDM_Odm->SupportICType == ODM_RTL8723A) - ODM_SetBBReg(pDM_Odm, 0x874, BIT(5), 0x0); + if (pDM_Odm->SupportICType == ODM_RTL8723A) { + val32 = rtl8723au_read32(adapter, 0x874); + val32 &= ~BIT(5); + rtl8723au_write32(adapter, 0x874, val32); + } } pDM_PSTable->PreRFState = pDM_PSTable->CurRFState; } @@ -1372,16 +1417,23 @@ u32 GetPSDData(struct dm_odm_t *pDM_Odm, unsigned int point, u8 initial_gain_psd) { struct rtw_adapter *adapter = pDM_Odm->Adapter; - u32 psd_report; + u32 psd_report, val32; /* Set DCO frequency index, offset = (40MHz/SamplePts)*point */ - ODM_SetBBReg(pDM_Odm, 0x808, 0x3FF, point); + val32 = rtl8723au_read32(adapter, 0x808); + val32 &= ~0x3ff; + val32 |= (point & 0x3ff); + rtl8723au_write32(adapter, 0x808, val32); /* Start PSD calculation, Reg808[22]= 0->1 */ - ODM_SetBBReg(pDM_Odm, 0x808, BIT(22), 1); + val32 = rtl8723au_read32(adapter, 0x808); + val32 |= BIT(22); + rtl8723au_write32(adapter, 0x808, val32); /* Need to wait for HW PSD report */ udelay(30); - ODM_SetBBReg(pDM_Odm, 0x808, BIT(22), 0); + val32 = rtl8723au_read32(adapter, 0x808); + val32 &= ~BIT(22); + rtl8723au_write32(adapter, 0x808, val32); /* Read PSD report, Reg8B4[15:0] */ psd_report = rtl8723au_read32(adapter, 0x8B4) & 0x0000FFFF; @@ -1462,7 +1514,7 @@ bool ODM_SingleDualAntennaDetection(struct dm_odm_t *pDM_Odm, u8 mode) struct rtw_adapter *adapter = pDM_Odm->Adapter; u32 CurrentChannel, RfLoopReg; u8 n; - u32 Reg88c, Regc08, Reg874, Regc50; + u32 Reg88c, Regc08, Reg874, Regc50, val32; u8 initial_gain = 0x5a; u32 PSD_report_tmp; u32 AntA_report = 0x0, AntB_report = 0x0, AntO_report = 0x0; @@ -1489,7 +1541,11 @@ bool ODM_SingleDualAntennaDetection(struct dm_odm_t *pDM_Odm, u8 mode) bRFRegOffsetMask); RfLoopReg = ODM_GetRFReg(pDM_Odm, RF_PATH_A, 0x00, bRFRegOffsetMask); /* change to Antenna A */ - ODM_SetBBReg(pDM_Odm, rFPGA0_XA_RFInterfaceOE, ODM_DPDT, Antenna_A); + val32 = rtl8723au_read32(adapter, rFPGA0_XA_RFInterfaceOE); + val32 &= ~0x300; + val32 |= 0x100; /* Enable antenna A */ + rtl8723au_write32(adapter, rFPGA0_XA_RFInterfaceOE, val32); + /* Step 1: USE IQK to transmitter single tone */ udelay(10); @@ -1504,7 +1560,9 @@ bool ODM_SingleDualAntennaDetection(struct dm_odm_t *pDM_Odm, u8 mode) odm_PHY_SaveAFERegisters(pDM_Odm, AFE_REG_8723A, AFE_Backup, 16); /* Set PSD 128 pts */ - ODM_SetBBReg(pDM_Odm, rFPGA0_PSDFunction, BIT(14) | BIT(15), 0x0); + val32 = rtl8723au_read32(adapter, rFPGA0_PSDFunction); + val32 &= ~(BIT(14) | BIT(15)); + rtl8723au_write32(adapter, rFPGA0_PSDFunction, val32); /* To SET CH1 to do */ ODM_SetRFReg(pDM_Odm, RF_PATH_A, ODM_CHANNEL, bRFRegOffsetMask, 0x01); @@ -1564,7 +1622,10 @@ bool ODM_SingleDualAntennaDetection(struct dm_odm_t *pDM_Odm, u8 mode) PSD_report_tmp = 0x0; - ODM_SetBBReg(pDM_Odm, rFPGA0_XA_RFInterfaceOE, 0x300, Antenna_B); /* change to Antenna B */ + val32 = rtl8723au_read32(adapter, rFPGA0_XA_RFInterfaceOE); + val32 &= ~0x300; + val32 |= 0x200; /* Enable antenna B */ + rtl8723au_write32(adapter, rFPGA0_XA_RFInterfaceOE, val32); udelay(10); for (n = 0; n < 2; n++) { @@ -1575,7 +1636,9 @@ bool ODM_SingleDualAntennaDetection(struct dm_odm_t *pDM_Odm, u8 mode) /* change to open case */ /* change to Ant A and B all open case */ - ODM_SetBBReg(pDM_Odm, rFPGA0_XA_RFInterfaceOE, 0x300, 0); + val32 = rtl8723au_read32(adapter, rFPGA0_XA_RFInterfaceOE); + val32 &= ~0x300; + rtl8723au_write32(adapter, rFPGA0_XA_RFInterfaceOE, val32); udelay(10); for (n = 0; n < 2; n++) { @@ -1589,11 +1652,18 @@ bool ODM_SingleDualAntennaDetection(struct dm_odm_t *pDM_Odm, u8 mode) PSD_report_tmp = 0x0; /* 1 Return to antanna A */ - ODM_SetBBReg(pDM_Odm, rFPGA0_XA_RFInterfaceOE, 0x300, Antenna_A); + val32 = rtl8723au_read32(adapter, rFPGA0_XA_RFInterfaceOE); + val32 &= ~0x300; + val32 |= 0x100; /* Enable antenna A */ + rtl8723au_write32(adapter, rFPGA0_XA_RFInterfaceOE, val32); rtl8723au_write32(adapter, rFPGA0_AnalogParameter4, Reg88c); rtl8723au_write32(adapter, rOFDM0_TRMuxPar, Regc08); rtl8723au_write32(adapter, rFPGA0_XCD_RFInterfaceSW, Reg874); - ODM_SetBBReg(pDM_Odm, rOFDM0_XAAGCCore1, 0x7F, 0x40); + val32 = rtl8723au_read32(adapter, rOFDM0_XAAGCCore1); + val32 &= ~0x7f; + val32 |= 0x40; + rtl8723au_write32(adapter, rOFDM0_XAAGCCore1, val32); + rtl8723au_write32(adapter, rOFDM0_XAAGCCore1, Regc50); ODM_SetRFReg(pDM_Odm, RF_PATH_A, RF_CHNLBW, bRFRegOffsetMask, CurrentChannel); -- GitLab From 6725e52d22a4d99ea752fa0d0422a3a544545b03 Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Thu, 5 Mar 2015 14:24:50 -0500 Subject: [PATCH 03228/11651] staging: rtl8723au: Eliminate ODM_SetBBReg() Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/hal/odm.c | 33 +++++++++++-------- drivers/staging/rtl8723au/hal/odm_interface.c | 12 ------- .../staging/rtl8723au/include/odm_interface.h | 1 - 3 files changed, 20 insertions(+), 26 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/odm.c b/drivers/staging/rtl8723au/hal/odm.c index 7a01a8a7340a..428b2b308f27 100644 --- a/drivers/staging/rtl8723au/hal/odm.c +++ b/drivers/staging/rtl8723au/hal/odm.c @@ -909,13 +909,12 @@ void ODM_RF_Saving23a(struct dm_odm_t *pDM_Odm, u8 bForceInNormal) if (pDM_PSTable->initialize == 0) { pDM_PSTable->Reg874 = - (rtl8723au_read32(adapter, 0x874) & 0x1CC000) >> 14; + rtl8723au_read32(adapter, 0x874) & 0x1CC000; pDM_PSTable->RegC70 = - (rtl8723au_read32(adapter, 0xc70) & BIT(3)) >>3; + rtl8723au_read32(adapter, 0xc70) & BIT(3); pDM_PSTable->Reg85C = - (rtl8723au_read32(adapter, 0x85c) & 0xFF000000) >> 24; - pDM_PSTable->RegA74 = - (rtl8723au_read32(adapter, 0xa74) & 0xF000) >> 12; + rtl8723au_read32(adapter, 0x85c) & 0xFF000000; + pDM_PSTable->RegA74 = rtl8723au_read32(adapter, 0xa74) & 0xF000; pDM_PSTable->initialize = 1; } @@ -983,14 +982,22 @@ void ODM_RF_Saving23a(struct dm_odm_t *pDM_Odm, u8 bForceInNormal) val32 |= BIT(28); rtl8723au_write32(adapter, 0x818, val32); } else { - ODM_SetBBReg(pDM_Odm, 0x874, 0x1CC000, - pDM_PSTable->Reg874); - ODM_SetBBReg(pDM_Odm, 0xc70, BIT(3), - pDM_PSTable->RegC70); - ODM_SetBBReg(pDM_Odm, 0x85c, 0xFF000000, - pDM_PSTable->Reg85C); - ODM_SetBBReg(pDM_Odm, 0xa74, 0xF000, - pDM_PSTable->RegA74); + val32 = rtl8723au_read32(adapter, 0x874); + val32 |= pDM_PSTable->Reg874; + rtl8723au_write32(adapter, 0x874, val32); + + val32 = rtl8723au_read32(adapter, 0xc70); + val32 |= pDM_PSTable->RegC70; + rtl8723au_write32(adapter, 0xc70, val32); + + val32 = rtl8723au_read32(adapter, 0x85c); + val32 |= pDM_PSTable->Reg85C; + rtl8723au_write32(adapter, 0x85c, val32); + + val32 = rtl8723au_read32(adapter, 0xa74); + val32 |= pDM_PSTable->RegA74; + rtl8723au_write32(adapter, 0xa74, val32); + val32 = rtl8723au_read32(adapter, 0x818); val32 &= ~BIT(28); rtl8723au_write32(adapter, 0x818, val32); diff --git a/drivers/staging/rtl8723au/hal/odm_interface.c b/drivers/staging/rtl8723au/hal/odm_interface.c index e005bfa38944..d8f67902708e 100644 --- a/drivers/staging/rtl8723au/hal/odm_interface.c +++ b/drivers/staging/rtl8723au/hal/odm_interface.c @@ -23,18 +23,6 @@ /* */ #include -void ODM_SetBBReg( - struct dm_odm_t *pDM_Odm, - u32 RegAddr, - u32 BitMask, - u32 Data - ) -{ - struct rtw_adapter *Adapter = pDM_Odm->Adapter; - - PHY_SetBBReg(Adapter, RegAddr, BitMask, Data); -} - void ODM_SetRFReg( struct dm_odm_t *pDM_Odm, enum RF_RADIO_PATH eRFPath, diff --git a/drivers/staging/rtl8723au/include/odm_interface.h b/drivers/staging/rtl8723au/include/odm_interface.h index b1d505dc9776..1d3bf03b59ea 100644 --- a/drivers/staging/rtl8723au/include/odm_interface.h +++ b/drivers/staging/rtl8723au/include/odm_interface.h @@ -54,7 +54,6 @@ typedef void (*RT_WORKITEM_CALL_BACK)(struct work_struct *pContext); /* =========== EXtern Function Prototype */ /* */ -void ODM_SetBBReg(struct dm_odm_t *pDM_Odm, u32 RegAddr, u32 BitMask, u32 Data); void ODM_SetRFReg(struct dm_odm_t *pDM_Odm, enum RF_RADIO_PATH eRFPath, u32 RegAddr, u32 BitMask, u32 Data); u32 ODM_GetRFReg(struct dm_odm_t *pDM_Odm, enum RF_RADIO_PATH eRFPath, -- GitLab From de904bf0e4610a7651f3eb0c8b7b63e2ae32b805 Mon Sep 17 00:00:00 2001 From: Quentin Lambert Date: Wed, 4 Mar 2015 11:31:01 +0100 Subject: [PATCH 03229/11651] staging: rts5208: Convert non-returned local variable to boolean when relevant This patch was produced using Coccinelle. A simplified version of the semantic patch is: @r exists@ identifier f; local idexpression u8 x; identifier xname; @@ f(...) { ...when any ( x@xname = 1; | x@xname = 0; ) ...when any } @bad exists@ identifier r.f; local idexpression u8 r.x expression e1 != {0, 1}, e2; @@ f(...) { ...when any ( x = e1; | x + e2 ) ...when any } @depends on !bad@ identifier r.f; local idexpression u8 r.x; identifier r.xname; @@ f(...) { ... ++ bool xname; - int xname; <... ( x = - 1 + true | x = - -1 + false ) ...> } Signed-off-by: Quentin Lambert Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rts5208/ms.c | 14 +++-- drivers/staging/rts5208/rtsx_chip.c | 56 +++++++++--------- drivers/staging/rts5208/rtsx_scsi.c | 38 +++++++------ drivers/staging/rts5208/sd.c | 88 +++++++++++++++-------------- 4 files changed, 105 insertions(+), 91 deletions(-) diff --git a/drivers/staging/rts5208/ms.c b/drivers/staging/rts5208/ms.c index a47a19135d49..050bc4709c36 100644 --- a/drivers/staging/rts5208/ms.c +++ b/drivers/staging/rts5208/ms.c @@ -1560,7 +1560,8 @@ static int ms_copy_page(struct rtsx_chip *chip, u16 old_blk, u16 new_blk, u16 log_blk, u8 start_page, u8 end_page) { struct ms_info *ms_card = &(chip->ms_card); - int retval, rty_cnt, uncorrect_flag = 0; + bool uncorrect_flag = false; + int retval, rty_cnt; u8 extra[MS_EXTRA_SIZE], val, i, j, data[16]; dev_dbg(rtsx_dev(chip), "Copy page from 0x%x to 0x%x, logical block is 0x%x\n", @@ -1642,10 +1643,10 @@ static int ms_copy_page(struct rtsx_chip *chip, u16 old_blk, u16 new_blk, if (val & INT_REG_ERR) { retval = ms_read_status_reg(chip); if (retval != STATUS_SUCCESS) { - uncorrect_flag = 1; + uncorrect_flag = true; dev_dbg(rtsx_dev(chip), "Uncorrectable error\n"); } else { - uncorrect_flag = 0; + uncorrect_flag = false; } retval = ms_transfer_tpc(chip, @@ -2187,7 +2188,8 @@ static int ms_build_l2p_tbl(struct rtsx_chip *chip, int seg_no) { struct ms_info *ms_card = &(chip->ms_card); struct zone_entry *segment; - int retval, table_size, disable_cnt, defect_flag, i; + bool defect_flag; + int retval, table_size, disable_cnt, i; u16 start, end, phy_blk, log_blk, tmp_blk; u8 extra[MS_EXTRA_SIZE], us1, us2; @@ -2236,10 +2238,10 @@ static int ms_build_l2p_tbl(struct rtsx_chip *chip, int seg_no) for (phy_blk = start; phy_blk < end; phy_blk++) { if (disable_cnt) { - defect_flag = 0; + defect_flag = false; for (i = 0; i < segment->disable_count; i++) { if (phy_blk == segment->defect_list[i]) { - defect_flag = 1; + defect_flag = true; break; } } diff --git a/drivers/staging/rts5208/rtsx_chip.c b/drivers/staging/rts5208/rtsx_chip.c index 9593d8132938..35fa19d8b7a2 100644 --- a/drivers/staging/rts5208/rtsx_chip.c +++ b/drivers/staging/rts5208/rtsx_chip.c @@ -153,22 +153,22 @@ static int rtsx_pre_handle_sdio_old(struct rtsx_chip *chip) static int rtsx_pre_handle_sdio_new(struct rtsx_chip *chip) { u8 tmp; - int sw_bypass_sd = 0; + bool sw_bypass_sd = false; int retval; if (chip->driver_first_load) { if (CHECK_PID(chip, 0x5288)) { RTSX_READ_REG(chip, 0xFE5A, &tmp); if (tmp & 0x08) - sw_bypass_sd = 1; + sw_bypass_sd = true; } else if (CHECK_PID(chip, 0x5208)) { RTSX_READ_REG(chip, 0xFE70, &tmp); if (tmp & 0x80) - sw_bypass_sd = 1; + sw_bypass_sd = true; } } else { if (chip->sdio_in_charge) - sw_bypass_sd = 1; + sw_bypass_sd = true; } dev_dbg(rtsx_dev(chip), "chip->sdio_in_charge = %d\n", chip->sdio_in_charge); @@ -501,13 +501,14 @@ nextcard: static inline int check_sd_speed_prior(u32 sd_speed_prior) { - int i, fake_para = 0; + bool fake_para = false; + int i; for (i = 0; i < 4; i++) { u8 tmp = (u8)(sd_speed_prior >> (i*8)); if ((tmp < 0x01) || (tmp > 0x04)) { - fake_para = 1; + fake_para = true; break; } } @@ -517,13 +518,14 @@ static inline int check_sd_speed_prior(u32 sd_speed_prior) static inline int check_sd_current_prior(u32 sd_current_prior) { - int i, fake_para = 0; + bool fake_para = false; + int i; for (i = 0; i < 4; i++) { u8 tmp = (u8)(sd_current_prior >> (i*8)); if (tmp > 0x03) { - fake_para = 1; + fake_para = true; break; } } @@ -784,31 +786,31 @@ static inline void rtsx_blink_led(struct rtsx_chip *chip) static void rtsx_monitor_aspm_config(struct rtsx_chip *chip) { - int maybe_support_aspm, reg_changed; + bool reg_changed, maybe_support_aspm; u32 tmp = 0; u8 reg0 = 0, reg1 = 0; - maybe_support_aspm = 0; - reg_changed = 0; + maybe_support_aspm = false; + reg_changed = false; rtsx_read_config_byte(chip, LCTLR, ®0); if (chip->aspm_level[0] != reg0) { - reg_changed = 1; + reg_changed = true; chip->aspm_level[0] = reg0; } if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip)) { rtsx_read_cfg_dw(chip, 1, 0xC0, &tmp); reg1 = (u8)tmp; if (chip->aspm_level[1] != reg1) { - reg_changed = 1; + reg_changed = true; chip->aspm_level[1] = reg1; } if ((reg0 & 0x03) && (reg1 & 0x03)) - maybe_support_aspm = 1; + maybe_support_aspm = true; } else { if (reg0 & 0x03) - maybe_support_aspm = 1; + maybe_support_aspm = true; } if (reg_changed) { @@ -835,7 +837,7 @@ void rtsx_polling_func(struct rtsx_chip *chip) #ifdef SUPPORT_SD_LOCK struct sd_info *sd_card = &chip->sd_card; #endif - int ss_allowed; + bool ss_allowed; if (rtsx_chk_stat(chip, RTSX_STAT_SUSPEND)) return; @@ -887,21 +889,21 @@ void rtsx_polling_func(struct rtsx_chip *chip) rtsx_init_cards(chip); if (chip->ss_en) { - ss_allowed = 1; + ss_allowed = true; if (CHECK_PID(chip, 0x5288)) { - ss_allowed = 0; + ss_allowed = false; } else { if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip)) { u32 val; rtsx_read_cfg_dw(chip, 1, 0x04, &val); if (val & 0x07) - ss_allowed = 0; + ss_allowed = false; } } } else { - ss_allowed = 0; + ss_allowed = false; } if (ss_allowed && !chip->sd_io) { @@ -1358,7 +1360,8 @@ int rtsx_read_cfg_seq(struct rtsx_chip *chip, u8 func, u16 addr, u8 *buf, int rtsx_write_phy_register(struct rtsx_chip *chip, u8 addr, u16 val) { - int i, finished = 0; + bool finished = false; + int i; u8 tmp; RTSX_WRITE_REG(chip, PHYDATA0, 0xFF, (u8)val); @@ -1369,7 +1372,7 @@ int rtsx_write_phy_register(struct rtsx_chip *chip, u8 addr, u16 val) for (i = 0; i < 100000; i++) { RTSX_READ_REG(chip, PHYRWCTL, &tmp); if (!(tmp & 0x80)) { - finished = 1; + finished = true; break; } } @@ -1382,7 +1385,8 @@ int rtsx_write_phy_register(struct rtsx_chip *chip, u8 addr, u16 val) int rtsx_read_phy_register(struct rtsx_chip *chip, u8 addr, u16 *val) { - int i, finished = 0; + bool finished = false; + int i; u16 data = 0; u8 tmp; @@ -1392,7 +1396,7 @@ int rtsx_read_phy_register(struct rtsx_chip *chip, u8 addr, u16 *val) for (i = 0; i < 100000; i++) { RTSX_READ_REG(chip, PHYRWCTL, &tmp); if (!(tmp & 0x80)) { - finished = 1; + finished = true; break; } } @@ -1615,7 +1619,7 @@ void rtsx_exit_ss(struct rtsx_chip *chip) int rtsx_pre_handle_interrupt(struct rtsx_chip *chip) { u32 status, int_enable; - int exit_ss = 0; + bool exit_ss = false; #ifdef SUPPORT_OCP u32 ocp_int = 0; @@ -1625,7 +1629,7 @@ int rtsx_pre_handle_interrupt(struct rtsx_chip *chip) if (chip->ss_en) { chip->ss_counter = 0; if (rtsx_get_stat(chip) == RTSX_STAT_SS) { - exit_ss = 1; + exit_ss = true; rtsx_exit_L1(chip); rtsx_set_stat(chip, RTSX_STAT_RUN); } diff --git a/drivers/staging/rts5208/rtsx_scsi.c b/drivers/staging/rts5208/rtsx_scsi.c index 426458345534..a00ba217ebae 100644 --- a/drivers/staging/rts5208/rtsx_scsi.c +++ b/drivers/staging/rts5208/rtsx_scsi.c @@ -39,7 +39,8 @@ void scsi_show_command(struct rtsx_chip *chip) { struct scsi_cmnd *srb = chip->srb; char *what = NULL; - int unknown_cmd = 0, len; + bool unknown_cmd = false; + int len; switch (srb->cmnd[0]) { case TEST_UNIT_READY: @@ -310,7 +311,8 @@ void scsi_show_command(struct rtsx_chip *chip) what = "Realtek's vendor command"; break; default: - what = "(unknown command)"; unknown_cmd = 1; + what = "(unknown command)"; + unknown_cmd = true; break; } @@ -485,7 +487,7 @@ static int inquiry(struct scsi_cmnd *srb, struct rtsx_chip *chip) unsigned char sendbytes; unsigned char *buf; u8 card = get_lun_card(chip, lun); - int pro_formatter_flag = 0; + bool pro_formatter_flag = false; unsigned char inquiry_buf[] = { QULIFIRE|DRCT_ACCESS_DEV, RMB_DISC|0x0D, @@ -520,7 +522,7 @@ static int inquiry(struct scsi_cmnd *srb, struct rtsx_chip *chip) if (chip->mspro_formatter_enable) #endif if (!card || (card == MS_CARD)) - pro_formatter_flag = 1; + pro_formatter_flag = true; if (pro_formatter_flag) { if (scsi_bufflen(srb) < 56) @@ -663,7 +665,7 @@ static void ms_mode_sense(struct rtsx_chip *chip, u8 cmd, struct ms_info *ms_card = &(chip->ms_card); int sys_info_offset; int data_size = buf_len; - int support_format = 0; + bool support_format = false; int i = 0; if (cmd == MODE_SENSE) { @@ -684,10 +686,10 @@ static void ms_mode_sense(struct rtsx_chip *chip, u8 cmd, /* Medium Type Code */ if (check_card_ready(chip, lun)) { if (CHK_MSXC(ms_card)) { - support_format = 1; + support_format = true; buf[i++] = 0x40; } else if (CHK_MSPRO(ms_card)) { - support_format = 1; + support_format = true; buf[i++] = 0x20; } else { buf[i++] = 0x10; @@ -755,7 +757,7 @@ static int mode_sense(struct scsi_cmnd *srb, struct rtsx_chip *chip) unsigned int lun = SCSI_LUN(srb); unsigned int dataSize; int status; - int pro_formatter_flag; + bool pro_formatter_flag; unsigned char pageCode, *buf; u8 card = get_lun_card(chip, lun); @@ -767,20 +769,20 @@ static int mode_sense(struct scsi_cmnd *srb, struct rtsx_chip *chip) } #endif - pro_formatter_flag = 0; + pro_formatter_flag = false; dataSize = 8; #ifdef SUPPORT_MAGIC_GATE if ((chip->lun2card[lun] & MS_CARD)) { if (!card || (card == MS_CARD)) { dataSize = 108; if (chip->mspro_formatter_enable) - pro_formatter_flag = 1; + pro_formatter_flag = true; } } #else if (card == MS_CARD) { if (chip->mspro_formatter_enable) { - pro_formatter_flag = 1; + pro_formatter_flag = true; dataSize = 108; } } @@ -2295,7 +2297,8 @@ Exit: static int read_cfg_byte(struct scsi_cmnd *srb, struct rtsx_chip *chip) { int retval; - u8 func, func_max; + bool func_max; + u8 func; u16 addr, len; u8 *buf; @@ -2315,9 +2318,9 @@ static int read_cfg_byte(struct scsi_cmnd *srb, struct rtsx_chip *chip) __func__, func, addr, len); if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip)) - func_max = 1; + func_max = true; else - func_max = 0; + func_max = false; if (func > func_max) { set_sense_type(chip, SCSI_LUN(srb), @@ -2349,7 +2352,8 @@ static int read_cfg_byte(struct scsi_cmnd *srb, struct rtsx_chip *chip) static int write_cfg_byte(struct scsi_cmnd *srb, struct rtsx_chip *chip) { int retval; - u8 func, func_max; + bool func_max; + u8 func; u16 addr, len; u8 *buf; @@ -2369,9 +2373,9 @@ static int write_cfg_byte(struct scsi_cmnd *srb, struct rtsx_chip *chip) __func__, func, addr); if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip)) - func_max = 1; + func_max = true; else - func_max = 0; + func_max = false; if (func > func_max) { set_sense_type(chip, SCSI_LUN(srb), diff --git a/drivers/staging/rts5208/sd.c b/drivers/staging/rts5208/sd.c index c28a92773f05..62bf570d59d4 100644 --- a/drivers/staging/rts5208/sd.c +++ b/drivers/staging/rts5208/sd.c @@ -791,7 +791,7 @@ static int sd_change_phase(struct rtsx_chip *chip, u8 sample_point, u8 tune_dir) u16 SD_VP_CTL, SD_DCMPS_CTL; u8 val; int retval; - int ddr_rx = 0; + bool ddr_rx = false; dev_dbg(rtsx_dev(chip), "sd_change_phase (sample_point = %d, tune_dir = %d)\n", sample_point, tune_dir); @@ -800,7 +800,7 @@ static int sd_change_phase(struct rtsx_chip *chip, u8 sample_point, u8 tune_dir) SD_VP_CTL = SD_VPRX_CTL; SD_DCMPS_CTL = SD_DCMPS_RX_CTL; if (CHK_SD_DDR50(sd_card)) - ddr_rx = 1; + ddr_rx = true; } else { SD_VP_CTL = SD_VPTX_CTL; SD_DCMPS_CTL = SD_DCMPS_TX_CTL; @@ -1121,7 +1121,7 @@ static int sd_check_switch(struct rtsx_chip *chip, { int retval; int i; - int switch_good = 0; + bool switch_good = false; for (i = 0; i < 3; i++) { if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { @@ -1137,7 +1137,7 @@ static int sd_check_switch(struct rtsx_chip *chip, retval = sd_check_switch_mode(chip, SD_SWITCH_MODE, func_group, func_to_switch, bus_width); if (retval == STATUS_SUCCESS) { - switch_good = 1; + switch_good = true; break; } @@ -1524,7 +1524,8 @@ static u8 sd_search_final_phase(struct rtsx_chip *chip, u32 phase_map, struct sd_info *sd_card = &(chip->sd_card); struct timing_phase_path path[MAX_PHASE + 1]; int i, j, cont_path_cnt; - int new_block, max_len, final_path_idx; + bool new_block; + int max_len, final_path_idx; u8 final_phase = 0xFF; if (phase_map == 0xFFFFFFFF) { @@ -1537,12 +1538,12 @@ static u8 sd_search_final_phase(struct rtsx_chip *chip, u32 phase_map, } cont_path_cnt = 0; - new_block = 1; + new_block = true; j = 0; for (i = 0; i < MAX_PHASE + 1; i++) { if (phase_map & (1 << i)) { if (new_block) { - new_block = 0; + new_block = false; j = cont_path_cnt++; path[j].start = i; path[j].end = i; @@ -1550,7 +1551,7 @@ static u8 sd_search_final_phase(struct rtsx_chip *chip, u32 phase_map, path[j].end = i; } } else { - new_block = 1; + new_block = true; if (cont_path_cnt) { int idx = cont_path_cnt - 1; @@ -2141,14 +2142,15 @@ static int sd_check_wp_state(struct rtsx_chip *chip) static int reset_sd(struct rtsx_chip *chip) { struct sd_info *sd_card = &(chip->sd_card); - int retval, i = 0, j = 0, k = 0, hi_cap_flow = 0; - int sd_dont_switch = 0; - int support_1v8 = 0; - int try_sdio = 1; + bool hi_cap_flow = false; + int retval, i = 0, j = 0, k = 0; + bool sd_dont_switch = false; + bool support_1v8 = false; + bool try_sdio = true; u8 rsp[16]; u8 switch_bus_width; u32 voltage = 0; - int sd20_mode = 0; + bool sd20_mode = false; SET_SD(sd_card); @@ -2157,7 +2159,7 @@ Switch_Fail: i = 0; j = 0; k = 0; - hi_cap_flow = 0; + hi_cap_flow = false; #ifdef SUPPORT_SD_LOCK if (sd_card->sd_lock_status & SD_UNLOCK_POW_ON) @@ -2217,7 +2219,7 @@ RTY_SD_RST: SD_RSP_TYPE_R7, rsp, 5); if (retval == STATUS_SUCCESS) { if ((rsp[4] == 0xAA) && ((rsp[3] & 0x0f) == 0x01)) { - hi_cap_flow = 1; + hi_cap_flow = true; voltage = SUPPORT_VOLTAGE | 0x40000000; } } @@ -2272,10 +2274,10 @@ RTY_SD_RST: else CLR_SD_HCXC(sd_card); - support_1v8 = 0; + support_1v8 = false; } else { CLR_SD_HCXC(sd_card); - support_1v8 = 0; + support_1v8 = false; } dev_dbg(rtsx_dev(chip), "support_1v8 = %d\n", support_1v8); @@ -2361,7 +2363,7 @@ SD_UNLOCK_ENTRY: TRACE_RET(chip, STATUS_FAIL); if (!(sd_card->raw_csd[4] & 0x40)) - sd_dont_switch = 1; + sd_dont_switch = true; if (!sd_dont_switch) { if (sd20_mode) { @@ -2378,16 +2380,16 @@ SD_UNLOCK_ENTRY: retval = sd_switch_function(chip, switch_bus_width); if (retval != STATUS_SUCCESS) { sd_init_power(chip); - sd_dont_switch = 1; - try_sdio = 0; + sd_dont_switch = true; + try_sdio = false; goto Switch_Fail; } } else { if (support_1v8) { sd_init_power(chip); - sd_dont_switch = 1; - try_sdio = 0; + sd_dont_switch = true; + try_sdio = false; goto Switch_Fail; } @@ -2433,8 +2435,8 @@ SD_UNLOCK_ENTRY: if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - try_sdio = 0; - sd20_mode = 1; + try_sdio = false; + sd20_mode = true; goto Switch_Fail; } } @@ -2458,8 +2460,8 @@ SD_UNLOCK_ENTRY: if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - try_sdio = 0; - sd20_mode = 1; + try_sdio = false; + sd20_mode = true; goto Switch_Fail; } } @@ -3702,7 +3704,7 @@ int sd_execute_no_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) unsigned int lun = SCSI_LUN(srb); int retval, rsp_len; u8 cmd_idx, rsp_type; - u8 standby = 0, acmd = 0; + bool standby = false, acmd = false; u32 arg; if (!sd_card->sd_pass_thru_en) { @@ -3722,10 +3724,10 @@ int sd_execute_no_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) cmd_idx = srb->cmnd[2] & 0x3F; if (srb->cmnd[1] & 0x02) - standby = 1; + standby = true; if (srb->cmnd[1] & 0x01) - acmd = 1; + acmd = true; arg = ((u32)srb->cmnd[3] << 24) | ((u32)srb->cmnd[4] << 16) | ((u32)srb->cmnd[5] << 8) | srb->cmnd[6]; @@ -3812,9 +3814,10 @@ int sd_execute_read_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) struct sd_info *sd_card = &(chip->sd_card); unsigned int lun = SCSI_LUN(srb); int retval, rsp_len, i; - int cmd13_checkbit = 0, read_err = 0; + int cmd13_checkbit = 0; + bool read_err = false; u8 cmd_idx, rsp_type, bus_width; - u8 send_cmd12 = 0, standby = 0, acmd = 0; + bool standby = false, send_cmd12 = false, acmd = false; u32 data_len; if (!sd_card->sd_pass_thru_en) { @@ -3834,13 +3837,13 @@ int sd_execute_read_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) cmd_idx = srb->cmnd[2] & 0x3F; if (srb->cmnd[1] & 0x04) - send_cmd12 = 1; + send_cmd12 = true; if (srb->cmnd[1] & 0x02) - standby = 1; + standby = true; if (srb->cmnd[1] & 0x01) - acmd = 1; + acmd = true; data_len = ((u32)srb->cmnd[7] << 16) | ((u32)srb->cmnd[8] << 8) | srb->cmnd[9]; @@ -3915,7 +3918,7 @@ int sd_execute_read_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) retval = sd_read_data(chip, SD_TM_NORMAL_READ, cmd, 5, byte_cnt, blk_cnt, bus_width, buf, data_len, 2000); if (retval != STATUS_SUCCESS) { - read_err = 1; + read_err = true; kfree(buf); rtsx_clear_sd_error(chip); TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); @@ -3964,7 +3967,7 @@ int sd_execute_read_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) scsi_bufflen(srb), scsi_sg_count(srb), DMA_FROM_DEVICE, 10000); if (retval < 0) { - read_err = 1; + read_err = true; rtsx_clear_sd_error(chip); TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); } @@ -4041,9 +4044,10 @@ int sd_execute_write_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) struct sd_info *sd_card = &(chip->sd_card); unsigned int lun = SCSI_LUN(srb); int retval, rsp_len, i; - int cmd13_checkbit = 0, write_err = 0; + int cmd13_checkbit = 0; + bool write_err = false; u8 cmd_idx, rsp_type; - u8 send_cmd12 = 0, standby = 0, acmd = 0; + bool standby = false, send_cmd12 = false, acmd = false; u32 data_len, arg; #ifdef SUPPORT_SD_LOCK int lock_cmd_fail = 0; @@ -4068,13 +4072,13 @@ int sd_execute_write_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) cmd_idx = srb->cmnd[2] & 0x3F; if (srb->cmnd[1] & 0x04) - send_cmd12 = 1; + send_cmd12 = true; if (srb->cmnd[1] & 0x02) - standby = 1; + standby = true; if (srb->cmnd[1] & 0x01) - acmd = 1; + acmd = true; data_len = ((u32)srb->cmnd[7] << 16) | ((u32)srb->cmnd[8] << 8) | srb->cmnd[9]; @@ -4247,7 +4251,7 @@ int sd_execute_write_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) } if (retval < 0) { - write_err = 1; + write_err = true; rtsx_clear_sd_error(chip); TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); } -- GitLab From 11201769d17ffe4b826035315aa03715938ae4b2 Mon Sep 17 00:00:00 2001 From: Quentin Lambert Date: Wed, 4 Mar 2015 11:31:53 +0100 Subject: [PATCH 03230/11651] staging: rts5208: Convert variable from int to bool and propagate the change to function parameters This patch convert local variables declared as int into booleans. It also propagates the conversion when these variables were used as function parameters. Coccinelle was used to generate this patch. Signed-off-by: Quentin Lambert Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rts5208/ms.c | 9 +++--- drivers/staging/rts5208/ms.h | 2 +- drivers/staging/rts5208/rtsx_scsi.c | 7 +++-- drivers/staging/rts5208/sd.c | 44 ++++++++++++++--------------- drivers/staging/rts5208/sd.h | 2 +- 5 files changed, 32 insertions(+), 32 deletions(-) diff --git a/drivers/staging/rts5208/ms.c b/drivers/staging/rts5208/ms.c index 050bc4709c36..7638f802a878 100644 --- a/drivers/staging/rts5208/ms.c +++ b/drivers/staging/rts5208/ms.c @@ -107,7 +107,7 @@ static int ms_transfer_tpc(struct rtsx_chip *chip, u8 trans_mode, } static int ms_transfer_data(struct rtsx_chip *chip, u8 trans_mode, - u8 tpc, u16 sec_cnt, u8 cfg, int mode_2k, + u8 tpc, u16 sec_cnt, u8 cfg, bool mode_2k, int use_sg, void *buf, int buf_len) { int retval; @@ -2524,7 +2524,8 @@ static int mspro_rw_multi_sector(struct scsi_cmnd *srb, u16 sector_cnt) { struct ms_info *ms_card = &(chip->ms_card); - int retval, mode_2k = 0; + bool mode_2k = false; + int retval; u16 count; u8 val, trans_mode, rw_tpc, rw_cmd; @@ -2549,7 +2550,7 @@ static int mspro_rw_multi_sector(struct scsi_cmnd *srb, rw_tpc = PRO_WRITE_QUAD_DATA; rw_cmd = PRO_WRITE_2K_DATA; } - mode_2k = 1; + mode_2k = true; } } else { if (srb->sc_data_direction == DMA_FROM_DEVICE) { @@ -2782,7 +2783,7 @@ void mspro_polling_format_status(struct rtsx_chip *chip) } int mspro_format(struct scsi_cmnd *srb, struct rtsx_chip *chip, - int short_data_len, int quick_format) + int short_data_len, bool quick_format) { struct ms_info *ms_card = &(chip->ms_card); int retval, i; diff --git a/drivers/staging/rts5208/ms.h b/drivers/staging/rts5208/ms.h index 26c5b03d535e..d919170f2720 100644 --- a/drivers/staging/rts5208/ms.h +++ b/drivers/staging/rts5208/ms.h @@ -205,7 +205,7 @@ int reset_ms_card(struct rtsx_chip *chip); int ms_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 start_sector, u16 sector_cnt); int mspro_format(struct scsi_cmnd *srb, struct rtsx_chip *chip, - int short_data_len, int quick_format); + int short_data_len, bool quick_format); void ms_free_l2p_tbl(struct rtsx_chip *chip); void ms_cleanup_work(struct rtsx_chip *chip); int ms_power_off_card3v3(struct rtsx_chip *chip); diff --git a/drivers/staging/rts5208/rtsx_scsi.c b/drivers/staging/rts5208/rtsx_scsi.c index a00ba217ebae..98f102b78e6d 100644 --- a/drivers/staging/rts5208/rtsx_scsi.c +++ b/drivers/staging/rts5208/rtsx_scsi.c @@ -2799,7 +2799,8 @@ static int ms_format_cmnd(struct scsi_cmnd *srb, struct rtsx_chip *chip) { struct ms_info *ms_card = &(chip->ms_card); unsigned int lun = SCSI_LUN(srb); - int retval, quick_format; + bool quick_format; + int retval; if (get_lun_card(chip, lun) != MS_CARD) { set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); @@ -2828,9 +2829,9 @@ static int ms_format_cmnd(struct scsi_cmnd *srb, struct rtsx_chip *chip) rtsx_set_stat(chip, RTSX_STAT_RUN); if (srb->cmnd[8] & 0x01) - quick_format = 0; + quick_format = false; else - quick_format = 1; + quick_format = true; if (!(chip->card_ready & MS_CARD)) { set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); diff --git a/drivers/staging/rts5208/sd.c b/drivers/staging/rts5208/sd.c index 62bf570d59d4..a03cbe93722a 100644 --- a/drivers/staging/rts5208/sd.c +++ b/drivers/staging/rts5208/sd.c @@ -2606,7 +2606,7 @@ static int mmc_test_switch_bus(struct rtsx_chip *chip, u8 width) } -static int mmc_switch_timing_bus(struct rtsx_chip *chip, int switch_ddr) +static int mmc_switch_timing_bus(struct rtsx_chip *chip, bool switch_ddr) { struct sd_info *sd_card = &(chip->sd_card); int retval; @@ -2729,7 +2729,7 @@ static int reset_mmc(struct rtsx_chip *chip) { struct sd_info *sd_card = &(chip->sd_card); int retval, i = 0, j = 0, k = 0; - int switch_ddr = 1; + bool switch_ddr = true; u8 rsp[16]; u8 spec_ver = 0; u32 temp; @@ -2860,7 +2860,7 @@ MMC_UNLOCK_ENTRY: if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - switch_ddr = 0; + switch_ddr = false; TRACE_GOTO(chip, Switch_Fail); } @@ -2872,7 +2872,7 @@ MMC_UNLOCK_ENTRY: if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - switch_ddr = 0; + switch_ddr = false; TRACE_GOTO(chip, Switch_Fail); } } @@ -3419,7 +3419,7 @@ int soft_reset_sd_card(struct rtsx_chip *chip) } int ext_sd_send_cmd_get_rsp(struct rtsx_chip *chip, u8 cmd_idx, - u32 arg, u8 rsp_type, u8 *rsp, int rsp_len, int special_check) + u32 arg, u8 rsp_type, u8 *rsp, int rsp_len, bool special_check) { int retval; int timeout = 100; @@ -3513,7 +3513,7 @@ RTY_SEND_CMD: if ((cmd_idx == SELECT_CARD) || (cmd_idx == APP_CMD) || (cmd_idx == SEND_STATUS) || (cmd_idx == STOP_TRANSMISSION)) { - if ((cmd_idx != STOP_TRANSMISSION) && (special_check == 0)) { + if ((cmd_idx != STOP_TRANSMISSION) && !special_check) { if (ptr[1] & 0x80) TRACE_RET(chip, STATUS_FAIL); } @@ -3773,13 +3773,13 @@ int sd_execute_no_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) if (acmd) { retval = ext_sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0, 0); + SD_RSP_TYPE_R1, NULL, 0, false); if (retval != STATUS_SUCCESS) TRACE_GOTO(chip, SD_Execute_Cmd_Failed); } retval = ext_sd_send_cmd_get_rsp(chip, cmd_idx, arg, rsp_type, - sd_card->rsp, rsp_len, 0); + sd_card->rsp, rsp_len, false); if (retval != STATUS_SUCCESS) TRACE_GOTO(chip, SD_Execute_Cmd_Failed); @@ -3814,8 +3814,7 @@ int sd_execute_read_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) struct sd_info *sd_card = &(chip->sd_card); unsigned int lun = SCSI_LUN(srb); int retval, rsp_len, i; - int cmd13_checkbit = 0; - bool read_err = false; + bool read_err = false, cmd13_checkbit = false; u8 cmd_idx, rsp_type, bus_width; bool standby = false, send_cmd12 = false, acmd = false; u32 data_len; @@ -3877,7 +3876,7 @@ int sd_execute_read_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) if (data_len < 512) { retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, data_len, - SD_RSP_TYPE_R1, NULL, 0, 0); + SD_RSP_TYPE_R1, NULL, 0, false); if (retval != STATUS_SUCCESS) TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); } @@ -3891,7 +3890,7 @@ int sd_execute_read_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) if (acmd) { retval = ext_sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0, 0); + SD_RSP_TYPE_R1, NULL, 0, false); if (retval != STATUS_SUCCESS) TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); } @@ -3988,14 +3987,14 @@ int sd_execute_read_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) if (send_cmd12) { retval = ext_sd_send_cmd_get_rsp(chip, STOP_TRANSMISSION, - 0, SD_RSP_TYPE_R1b, NULL, 0, 0); + 0, SD_RSP_TYPE_R1b, NULL, 0, false); if (retval != STATUS_SUCCESS) TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); } if (data_len < 512) { retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, 0x200, - SD_RSP_TYPE_R1, NULL, 0, 0); + SD_RSP_TYPE_R1, NULL, 0, false); if (retval != STATUS_SUCCESS) TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); @@ -4009,7 +4008,7 @@ int sd_execute_read_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) } if ((srb->cmnd[1] & 0x02) || (srb->cmnd[1] & 0x04)) - cmd13_checkbit = 1; + cmd13_checkbit = true; for (i = 0; i < 3; i++) { retval = ext_sd_send_cmd_get_rsp(chip, SEND_STATUS, @@ -4044,8 +4043,7 @@ int sd_execute_write_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) struct sd_info *sd_card = &(chip->sd_card); unsigned int lun = SCSI_LUN(srb); int retval, rsp_len, i; - int cmd13_checkbit = 0; - bool write_err = false; + bool write_err = false, cmd13_checkbit = false; u8 cmd_idx, rsp_type; bool standby = false, send_cmd12 = false, acmd = false; u32 data_len, arg; @@ -4126,7 +4124,7 @@ int sd_execute_write_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) if (data_len < 512) { retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, data_len, - SD_RSP_TYPE_R1, NULL, 0, 0); + SD_RSP_TYPE_R1, NULL, 0, false); if (retval != STATUS_SUCCESS) TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); } @@ -4140,13 +4138,13 @@ int sd_execute_write_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) if (acmd) { retval = ext_sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0, 0); + SD_RSP_TYPE_R1, NULL, 0, false); if (retval != STATUS_SUCCESS) TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); } retval = ext_sd_send_cmd_get_rsp(chip, cmd_idx, arg, rsp_type, - sd_card->rsp, rsp_len, 0); + sd_card->rsp, rsp_len, false); if (retval != STATUS_SUCCESS) TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); @@ -4285,14 +4283,14 @@ int sd_execute_write_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) if (send_cmd12) { retval = ext_sd_send_cmd_get_rsp(chip, STOP_TRANSMISSION, - 0, SD_RSP_TYPE_R1b, NULL, 0, 0); + 0, SD_RSP_TYPE_R1b, NULL, 0, false); if (retval != STATUS_SUCCESS) TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); } if (data_len < 512) { retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, 0x200, - SD_RSP_TYPE_R1, NULL, 0, 0); + SD_RSP_TYPE_R1, NULL, 0, false); if (retval != STATUS_SUCCESS) TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); @@ -4306,7 +4304,7 @@ int sd_execute_write_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) } if ((srb->cmnd[1] & 0x02) || (srb->cmnd[1] & 0x04)) - cmd13_checkbit = 1; + cmd13_checkbit = true; for (i = 0; i < 3; i++) { retval = ext_sd_send_cmd_get_rsp(chip, SEND_STATUS, diff --git a/drivers/staging/rts5208/sd.h b/drivers/staging/rts5208/sd.h index 735b2d0f5a78..60b79280fb5f 100644 --- a/drivers/staging/rts5208/sd.h +++ b/drivers/staging/rts5208/sd.h @@ -287,7 +287,7 @@ int release_sd_card(struct rtsx_chip *chip); #ifdef SUPPORT_CPRM int soft_reset_sd_card(struct rtsx_chip *chip); int ext_sd_send_cmd_get_rsp(struct rtsx_chip *chip, u8 cmd_idx, - u32 arg, u8 rsp_type, u8 *rsp, int rsp_len, int special_check); + u32 arg, u8 rsp_type, u8 *rsp, int rsp_len, bool special_check); int ext_sd_get_rsp(struct rtsx_chip *chip, int len, u8 *rsp, u8 rsp_type); int sd_pass_thru_mode(struct scsi_cmnd *srb, struct rtsx_chip *chip); -- GitLab From 31c889653c10ddaf1d2b4a47740e07fa4f10f375 Mon Sep 17 00:00:00 2001 From: "J. German Rivera" Date: Thu, 5 Mar 2015 19:29:09 -0600 Subject: [PATCH 03231/11651] staging: fsl-mc: Added Freescale Management Complex APIs APIs to access the Management Complex (MC) hardware module of Freescale LS2 SoCs. This patch includes APIs to check the MC firmware version and to manipulate DPRC objects in the MC. Signed-off-by: J. German Rivera Signed-off-by: Stuart Yoder Acked-by: Alexander Graf Signed-off-by: Greg Kroah-Hartman --- MAINTAINERS | 6 + drivers/staging/fsl-mc/TODO | 12 + drivers/staging/fsl-mc/bus/dpmng-cmd.h | 47 ++ drivers/staging/fsl-mc/bus/dpmng.c | 78 ++ drivers/staging/fsl-mc/bus/dprc-cmd.h | 84 +++ drivers/staging/fsl-mc/bus/dprc.c | 913 ++++++++++++++++++++++++ drivers/staging/fsl-mc/bus/mc-sys.c | 283 ++++++++ drivers/staging/fsl-mc/include/dpmng.h | 80 +++ drivers/staging/fsl-mc/include/dprc.h | 801 +++++++++++++++++++++ drivers/staging/fsl-mc/include/mc-cmd.h | 113 +++ drivers/staging/fsl-mc/include/mc-sys.h | 70 ++ 11 files changed, 2487 insertions(+) create mode 100644 drivers/staging/fsl-mc/TODO create mode 100644 drivers/staging/fsl-mc/bus/dpmng-cmd.h create mode 100644 drivers/staging/fsl-mc/bus/dpmng.c create mode 100644 drivers/staging/fsl-mc/bus/dprc-cmd.h create mode 100644 drivers/staging/fsl-mc/bus/dprc.c create mode 100644 drivers/staging/fsl-mc/bus/mc-sys.c create mode 100644 drivers/staging/fsl-mc/include/dpmng.h create mode 100644 drivers/staging/fsl-mc/include/dprc.h create mode 100644 drivers/staging/fsl-mc/include/mc-cmd.h create mode 100644 drivers/staging/fsl-mc/include/mc-sys.h diff --git a/MAINTAINERS b/MAINTAINERS index b20311947d97..db15919dbf1c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4145,6 +4145,12 @@ F: sound/soc/fsl/fsl* F: sound/soc/fsl/imx* F: sound/soc/fsl/mpc8610_hpcd.c +FREESCALE QORIQ MANAGEMENT COMPLEX DRIVER +M: J. German Rivera +L: linux-kernel@vger.kernel.org +S: Maintained +F: drivers/staging/fsl-mc/ + FREEVXFS FILESYSTEM M: Christoph Hellwig W: ftp://ftp.openlinux.org/pub/people/hch/vxfs diff --git a/drivers/staging/fsl-mc/TODO b/drivers/staging/fsl-mc/TODO new file mode 100644 index 000000000000..49ebfd90438f --- /dev/null +++ b/drivers/staging/fsl-mc/TODO @@ -0,0 +1,12 @@ +* Add README file (with ASCII art) describing relationships between + DPAA2 objects and how combine them to make a NIC, an LS2 switch, etc. + Also, define all acronyms used. + +* Decide if multiple root fsl-mc buses will be supported per Linux instance, + and if so add support for this. + +* Add at least one device driver for a DPAA2 object (child device of the + fsl-mc bus). + +Please send any patches to Greg Kroah-Hartman , +devel@driverdev.osuosl.org, linux-kernel@vger.kernel.org diff --git a/drivers/staging/fsl-mc/bus/dpmng-cmd.h b/drivers/staging/fsl-mc/bus/dpmng-cmd.h new file mode 100644 index 000000000000..ba8cfa9635dd --- /dev/null +++ b/drivers/staging/fsl-mc/bus/dpmng-cmd.h @@ -0,0 +1,47 @@ +/* Copyright 2013-2014 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the above-listed copyright holders nor the + * names of any contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/*************************************************************************//* + dpmng-cmd.h + + defines portal commands + + *//**************************************************************************/ + +#ifndef __FSL_DPMNG_CMD_H +#define __FSL_DPMNG_CMD_H + +/* Command IDs */ +#define DPMNG_CMDID_GET_CONT_ID 0x830 +#define DPMNG_CMDID_GET_VERSION 0x831 + +#endif /* __FSL_DPMNG_CMD_H */ diff --git a/drivers/staging/fsl-mc/bus/dpmng.c b/drivers/staging/fsl-mc/bus/dpmng.c new file mode 100644 index 000000000000..58328e8118e9 --- /dev/null +++ b/drivers/staging/fsl-mc/bus/dpmng.c @@ -0,0 +1,78 @@ +/* Copyright 2013-2014 Freescale Semiconductor Inc. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of the above-listed copyright holders nor the +* names of any contributors may be used to endorse or promote products +* derived from this software without specific prior written permission. +* +* +* ALTERNATIVELY, this software may be distributed under the terms of the +* GNU General Public License ("GPL") as published by the Free Software +* Foundation, either version 2 of that License or (at your option) any +* later version. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ +#include "../include/mc-sys.h" +#include "../include/mc-cmd.h" +#include "../include/dpmng.h" +#include "dpmng-cmd.h" + +int mc_get_version(struct fsl_mc_io *mc_io, struct mc_version *mc_ver_info) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPMNG_CMDID_GET_VERSION, + MC_CMD_PRI_LOW, 0); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + mc_ver_info->revision = mc_dec(cmd.params[0], 0, 32); + mc_ver_info->major = mc_dec(cmd.params[0], 32, 32); + mc_ver_info->minor = mc_dec(cmd.params[1], 0, 32); + + return 0; +} + +int dpmng_get_container_id(struct fsl_mc_io *mc_io, int *container_id) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPMNG_CMDID_GET_CONT_ID, + MC_CMD_PRI_LOW, 0); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + *container_id = mc_dec(cmd.params[0], 0, 32); + + return 0; +} + diff --git a/drivers/staging/fsl-mc/bus/dprc-cmd.h b/drivers/staging/fsl-mc/bus/dprc-cmd.h new file mode 100644 index 000000000000..09202489c2b2 --- /dev/null +++ b/drivers/staging/fsl-mc/bus/dprc-cmd.h @@ -0,0 +1,84 @@ +/* Copyright 2013-2014 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the above-listed copyright holders nor the + * names of any contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/*************************************************************************//* + dprc-cmd.h + + defines dprc portal commands + + *//**************************************************************************/ + +#ifndef _FSL_DPRC_CMD_H +#define _FSL_DPRC_CMD_H + +/* DPRC Version */ +#define DPRC_VER_MAJOR 3 +#define DPRC_VER_MINOR 0 + +/* Command IDs */ +#define DPRC_CMDID_CLOSE 0x800 +#define DPRC_CMDID_OPEN 0x805 +#define DPRC_CMDID_CREATE 0x905 + +#define DPRC_CMDID_GET_ATTR 0x004 +#define DPRC_CMDID_RESET_CONT 0x005 + +#define DPRC_CMDID_SET_IRQ 0x010 +#define DPRC_CMDID_GET_IRQ 0x011 +#define DPRC_CMDID_SET_IRQ_ENABLE 0x012 +#define DPRC_CMDID_GET_IRQ_ENABLE 0x013 +#define DPRC_CMDID_SET_IRQ_MASK 0x014 +#define DPRC_CMDID_GET_IRQ_MASK 0x015 +#define DPRC_CMDID_GET_IRQ_STATUS 0x016 +#define DPRC_CMDID_CLEAR_IRQ_STATUS 0x017 + +#define DPRC_CMDID_CREATE_CONT 0x151 +#define DPRC_CMDID_DESTROY_CONT 0x152 +#define DPRC_CMDID_SET_RES_QUOTA 0x155 +#define DPRC_CMDID_GET_RES_QUOTA 0x156 +#define DPRC_CMDID_ASSIGN 0x157 +#define DPRC_CMDID_UNASSIGN 0x158 +#define DPRC_CMDID_GET_OBJ_COUNT 0x159 +#define DPRC_CMDID_GET_OBJ 0x15A +#define DPRC_CMDID_GET_RES_COUNT 0x15B +#define DPRC_CMDID_GET_RES_IDS 0x15C +#define DPRC_CMDID_GET_OBJ_REG 0x15E + +#define DPRC_CMDID_CONNECT 0x167 +#define DPRC_CMDID_DISCONNECT 0x168 +#define DPRC_CMDID_GET_POOL 0x169 +#define DPRC_CMDID_GET_POOL_COUNT 0x16A +#define DPRC_CMDID_GET_PORTAL_PADDR 0x16B + +#define DPRC_CMDID_GET_CONNECTION 0x16C + +#endif /* _FSL_DPRC_CMD_H */ diff --git a/drivers/staging/fsl-mc/bus/dprc.c b/drivers/staging/fsl-mc/bus/dprc.c new file mode 100644 index 000000000000..19b26e630b62 --- /dev/null +++ b/drivers/staging/fsl-mc/bus/dprc.c @@ -0,0 +1,913 @@ +/* Copyright 2013-2014 Freescale Semiconductor Inc. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of the above-listed copyright holders nor the +* names of any contributors may be used to endorse or promote products +* derived from this software without specific prior written permission. +* +* +* ALTERNATIVELY, this software may be distributed under the terms of the +* GNU General Public License ("GPL") as published by the Free Software +* Foundation, either version 2 of that License or (at your option) any +* later version. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ +#include "../include/mc-sys.h" +#include "../include/mc-cmd.h" +#include "../include/dprc.h" +#include "dprc-cmd.h" + +int dprc_open(struct fsl_mc_io *mc_io, int container_id, uint16_t *token) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_OPEN, MC_CMD_PRI_LOW, + 0); + cmd.params[0] |= mc_enc(0, 32, container_id); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + *token = MC_CMD_HDR_READ_TOKEN(cmd.header); + + return 0; +} +EXPORT_SYMBOL(dprc_open); + +int dprc_close(struct fsl_mc_io *mc_io, uint16_t token) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_CLOSE, MC_CMD_PRI_HIGH, + token); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} +EXPORT_SYMBOL(dprc_close); + +int dprc_create_container(struct fsl_mc_io *mc_io, + uint16_t token, + struct dprc_cfg *cfg, + int *child_container_id, + uint64_t *child_portal_paddr) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.params[0] |= mc_enc(32, 16, cfg->icid); + cmd.params[0] |= mc_enc(0, 32, cfg->options); + cmd.params[1] |= mc_enc(32, 32, cfg->portal_id); + + cmd.header = mc_encode_cmd_header(DPRC_CMDID_CREATE_CONT, + MC_CMD_PRI_LOW, token); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + *child_container_id = mc_dec(cmd.params[1], 0, 32); + *child_portal_paddr = mc_dec(cmd.params[2], 0, 64); + + return 0; +} + +int dprc_destroy_container(struct fsl_mc_io *mc_io, + uint16_t token, + int child_container_id) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_DESTROY_CONT, + MC_CMD_PRI_LOW, token); + cmd.params[0] |= mc_enc(0, 32, child_container_id); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dprc_reset_container(struct fsl_mc_io *mc_io, + uint16_t token, + int child_container_id) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_RESET_CONT, + MC_CMD_PRI_LOW, token); + cmd.params[0] |= mc_enc(0, 32, child_container_id); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dprc_get_irq(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + int *type, + uint64_t *irq_paddr, + uint32_t *irq_val, + int *user_irq_id) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_IRQ, + MC_CMD_PRI_LOW, + token); + cmd.params[0] |= mc_enc(32, 8, irq_index); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + *irq_val = mc_dec(cmd.params[0], 0, 32); + *irq_paddr = mc_dec(cmd.params[1], 0, 64); + *user_irq_id = mc_dec(cmd.params[2], 0, 32); + *type = mc_dec(cmd.params[2], 32, 32); + + return 0; +} + +int dprc_set_irq(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint64_t irq_paddr, + uint32_t irq_val, + int user_irq_id) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_SET_IRQ, + MC_CMD_PRI_LOW, + token); + cmd.params[0] |= mc_enc(32, 8, irq_index); + cmd.params[0] |= mc_enc(0, 32, irq_val); + cmd.params[1] |= mc_enc(0, 64, irq_paddr); + cmd.params[2] |= mc_enc(0, 32, user_irq_id); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dprc_get_irq_enable(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint8_t *en) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_IRQ_ENABLE, + MC_CMD_PRI_LOW, token); + cmd.params[0] |= mc_enc(32, 8, irq_index); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + *en = mc_dec(cmd.params[0], 0, 8); + + return 0; +} + +int dprc_set_irq_enable(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint8_t en) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_SET_IRQ_ENABLE, + MC_CMD_PRI_LOW, token); + cmd.params[0] |= mc_enc(0, 8, en); + cmd.params[0] |= mc_enc(32, 8, irq_index); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dprc_get_irq_mask(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint32_t *mask) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_IRQ_MASK, + MC_CMD_PRI_LOW, token); + cmd.params[0] |= mc_enc(32, 8, irq_index); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + *mask = mc_dec(cmd.params[0], 0, 32); + + return 0; +} + +int dprc_set_irq_mask(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint32_t mask) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_SET_IRQ_MASK, + MC_CMD_PRI_LOW, token); + cmd.params[0] |= mc_enc(0, 32, mask); + cmd.params[0] |= mc_enc(32, 8, irq_index); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dprc_get_irq_status(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint32_t *status) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_IRQ_STATUS, + MC_CMD_PRI_LOW, token); + cmd.params[0] |= mc_enc(32, 8, irq_index); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + *status = mc_dec(cmd.params[0], 0, 32); + + return 0; +} + +int dprc_clear_irq_status(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint32_t status) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_CLEAR_IRQ_STATUS, + MC_CMD_PRI_LOW, token); + cmd.params[0] |= mc_enc(0, 32, status); + cmd.params[0] |= mc_enc(32, 8, irq_index); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dprc_get_attributes(struct fsl_mc_io *mc_io, + uint16_t token, + struct dprc_attributes *attr) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_ATTR, + MC_CMD_PRI_LOW, + token); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + attr->container_id = mc_dec(cmd.params[0], 0, 32); + attr->icid = mc_dec(cmd.params[0], 32, 16); + attr->options = mc_dec(cmd.params[1], 0, 32); + attr->portal_id = mc_dec(cmd.params[1], 32, 32); + attr->version.major = mc_dec(cmd.params[2], 0, 16); + attr->version.minor = mc_dec(cmd.params[2], 16, 16); + + return 0; +} + +int dprc_set_res_quota(struct fsl_mc_io *mc_io, + uint16_t token, + int child_container_id, + char *type, + uint16_t quota) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_SET_RES_QUOTA, + MC_CMD_PRI_LOW, token); + cmd.params[0] |= mc_enc(0, 32, child_container_id); + cmd.params[0] |= mc_enc(32, 16, quota); + cmd.params[1] |= mc_enc(0, 8, type[0]); + cmd.params[1] |= mc_enc(8, 8, type[1]); + cmd.params[1] |= mc_enc(16, 8, type[2]); + cmd.params[1] |= mc_enc(24, 8, type[3]); + cmd.params[1] |= mc_enc(32, 8, type[4]); + cmd.params[1] |= mc_enc(40, 8, type[5]); + cmd.params[1] |= mc_enc(48, 8, type[6]); + cmd.params[1] |= mc_enc(56, 8, type[7]); + cmd.params[2] |= mc_enc(0, 8, type[8]); + cmd.params[2] |= mc_enc(8, 8, type[9]); + cmd.params[2] |= mc_enc(16, 8, type[10]); + cmd.params[2] |= mc_enc(24, 8, type[11]); + cmd.params[2] |= mc_enc(32, 8, type[12]); + cmd.params[2] |= mc_enc(40, 8, type[13]); + cmd.params[2] |= mc_enc(48, 8, type[14]); + cmd.params[2] |= mc_enc(56, 8, '\0'); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dprc_get_res_quota(struct fsl_mc_io *mc_io, + uint16_t token, + int child_container_id, + char *type, + uint16_t *quota) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_RES_QUOTA, + MC_CMD_PRI_LOW, token); + cmd.params[0] |= mc_enc(0, 32, child_container_id); + cmd.params[1] |= mc_enc(0, 8, type[0]); + cmd.params[1] |= mc_enc(8, 8, type[1]); + cmd.params[1] |= mc_enc(16, 8, type[2]); + cmd.params[1] |= mc_enc(24, 8, type[3]); + cmd.params[1] |= mc_enc(32, 8, type[4]); + cmd.params[1] |= mc_enc(40, 8, type[5]); + cmd.params[1] |= mc_enc(48, 8, type[6]); + cmd.params[1] |= mc_enc(56, 8, type[7]); + cmd.params[2] |= mc_enc(0, 8, type[8]); + cmd.params[2] |= mc_enc(8, 8, type[9]); + cmd.params[2] |= mc_enc(16, 8, type[10]); + cmd.params[2] |= mc_enc(24, 8, type[11]); + cmd.params[2] |= mc_enc(32, 8, type[12]); + cmd.params[2] |= mc_enc(40, 8, type[13]); + cmd.params[2] |= mc_enc(48, 8, type[14]); + cmd.params[2] |= mc_enc(56, 8, '\0'); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + *quota = mc_dec(cmd.params[0], 32, 16); + + return 0; +} + +int dprc_assign(struct fsl_mc_io *mc_io, + uint16_t token, + int container_id, + struct dprc_res_req *res_req) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_ASSIGN, + MC_CMD_PRI_LOW, token); + cmd.params[0] |= mc_enc(0, 32, container_id); + cmd.params[0] |= mc_enc(32, 32, res_req->options); + cmd.params[1] |= mc_enc(0, 32, res_req->num); + cmd.params[1] |= mc_enc(32, 32, res_req->id_base_align); + cmd.params[2] |= mc_enc(0, 8, res_req->type[0]); + cmd.params[2] |= mc_enc(8, 8, res_req->type[1]); + cmd.params[2] |= mc_enc(16, 8, res_req->type[2]); + cmd.params[2] |= mc_enc(24, 8, res_req->type[3]); + cmd.params[2] |= mc_enc(32, 8, res_req->type[4]); + cmd.params[2] |= mc_enc(40, 8, res_req->type[5]); + cmd.params[2] |= mc_enc(48, 8, res_req->type[6]); + cmd.params[2] |= mc_enc(56, 8, res_req->type[7]); + cmd.params[3] |= mc_enc(0, 8, res_req->type[8]); + cmd.params[3] |= mc_enc(8, 8, res_req->type[9]); + cmd.params[3] |= mc_enc(16, 8, res_req->type[10]); + cmd.params[3] |= mc_enc(24, 8, res_req->type[11]); + cmd.params[3] |= mc_enc(32, 8, res_req->type[12]); + cmd.params[3] |= mc_enc(40, 8, res_req->type[13]); + cmd.params[3] |= mc_enc(48, 8, res_req->type[14]); + cmd.params[3] |= mc_enc(56, 8, res_req->type[15]); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dprc_unassign(struct fsl_mc_io *mc_io, + uint16_t token, + int child_container_id, + struct dprc_res_req *res_req) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_UNASSIGN, + MC_CMD_PRI_LOW, + token); + cmd.params[0] |= mc_enc(0, 32, child_container_id); + cmd.params[0] |= mc_enc(32, 32, res_req->options); + cmd.params[1] |= mc_enc(0, 32, res_req->num); + cmd.params[1] |= mc_enc(32, 32, res_req->id_base_align); + cmd.params[2] |= mc_enc(0, 8, res_req->type[0]); + cmd.params[2] |= mc_enc(8, 8, res_req->type[1]); + cmd.params[2] |= mc_enc(16, 8, res_req->type[2]); + cmd.params[2] |= mc_enc(24, 8, res_req->type[3]); + cmd.params[2] |= mc_enc(32, 8, res_req->type[4]); + cmd.params[2] |= mc_enc(40, 8, res_req->type[5]); + cmd.params[2] |= mc_enc(48, 8, res_req->type[6]); + cmd.params[2] |= mc_enc(56, 8, res_req->type[7]); + cmd.params[3] |= mc_enc(0, 8, res_req->type[8]); + cmd.params[3] |= mc_enc(8, 8, res_req->type[9]); + cmd.params[3] |= mc_enc(16, 8, res_req->type[10]); + cmd.params[3] |= mc_enc(24, 8, res_req->type[11]); + cmd.params[3] |= mc_enc(32, 8, res_req->type[12]); + cmd.params[3] |= mc_enc(40, 8, res_req->type[13]); + cmd.params[3] |= mc_enc(48, 8, res_req->type[14]); + cmd.params[3] |= mc_enc(56, 8, res_req->type[15]); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dprc_get_pool_count(struct fsl_mc_io *mc_io, + uint16_t token, + int *pool_count) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_POOL_COUNT, + MC_CMD_PRI_LOW, token); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + *pool_count = mc_dec(cmd.params[0], 0, 32); + + return 0; +} + +int dprc_get_pool(struct fsl_mc_io *mc_io, + uint16_t token, + int pool_index, + char *type) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_POOL, + MC_CMD_PRI_LOW, + token); + cmd.params[0] |= mc_enc(0, 32, pool_index); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + type[0] = mc_dec(cmd.params[1], 0, 8); + type[1] = mc_dec(cmd.params[1], 8, 8); + type[2] = mc_dec(cmd.params[1], 16, 8); + type[3] = mc_dec(cmd.params[1], 24, 8); + type[4] = mc_dec(cmd.params[1], 32, 8); + type[5] = mc_dec(cmd.params[1], 40, 8); + type[6] = mc_dec(cmd.params[1], 48, 8); + type[7] = mc_dec(cmd.params[1], 56, 8); + type[8] = mc_dec(cmd.params[2], 0, 8); + type[9] = mc_dec(cmd.params[2], 8, 8); + type[10] = mc_dec(cmd.params[2], 16, 8); + type[11] = mc_dec(cmd.params[2], 24, 8); + type[12] = mc_dec(cmd.params[2], 32, 8); + type[13] = mc_dec(cmd.params[2], 40, 8); + type[14] = mc_dec(cmd.params[2], 48, 8); + type[15] = '\0'; + + return 0; +} + +int dprc_get_obj_count(struct fsl_mc_io *mc_io, uint16_t token, int *obj_count) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJ_COUNT, + MC_CMD_PRI_LOW, token); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + *obj_count = mc_dec(cmd.params[0], 32, 32); + + return 0; +} +EXPORT_SYMBOL(dprc_get_obj_count); + +int dprc_get_obj(struct fsl_mc_io *mc_io, + uint16_t token, + int obj_index, + struct dprc_obj_desc *obj_desc) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJ, + MC_CMD_PRI_LOW, + token); + cmd.params[0] |= mc_enc(0, 32, obj_index); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + obj_desc->id = mc_dec(cmd.params[0], 32, 32); + obj_desc->vendor = mc_dec(cmd.params[1], 0, 16); + obj_desc->irq_count = mc_dec(cmd.params[1], 16, 8); + obj_desc->region_count = mc_dec(cmd.params[1], 24, 8); + obj_desc->state = mc_dec(cmd.params[1], 32, 32); + obj_desc->ver_major = mc_dec(cmd.params[2], 0, 16); + obj_desc->ver_minor = mc_dec(cmd.params[2], 16, 16); + obj_desc->type[0] = mc_dec(cmd.params[3], 0, 8); + obj_desc->type[1] = mc_dec(cmd.params[3], 8, 8); + obj_desc->type[2] = mc_dec(cmd.params[3], 16, 8); + obj_desc->type[3] = mc_dec(cmd.params[3], 24, 8); + obj_desc->type[4] = mc_dec(cmd.params[3], 32, 8); + obj_desc->type[5] = mc_dec(cmd.params[3], 40, 8); + obj_desc->type[6] = mc_dec(cmd.params[3], 48, 8); + obj_desc->type[7] = mc_dec(cmd.params[3], 56, 8); + obj_desc->type[8] = mc_dec(cmd.params[4], 0, 8); + obj_desc->type[9] = mc_dec(cmd.params[4], 8, 8); + obj_desc->type[10] = mc_dec(cmd.params[4], 16, 8); + obj_desc->type[11] = mc_dec(cmd.params[4], 24, 8); + obj_desc->type[12] = mc_dec(cmd.params[4], 32, 8); + obj_desc->type[13] = mc_dec(cmd.params[4], 40, 8); + obj_desc->type[14] = mc_dec(cmd.params[4], 48, 8); + obj_desc->type[15] = '\0'; + + return 0; +} +EXPORT_SYMBOL(dprc_get_obj); + +int dprc_get_res_count(struct fsl_mc_io *mc_io, + uint16_t token, + char *type, + int *res_count) +{ + struct mc_command cmd = { 0 }; + int err; + + *res_count = 0; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_RES_COUNT, + MC_CMD_PRI_LOW, token); + cmd.params[1] |= mc_enc(0, 8, type[0]); + cmd.params[1] |= mc_enc(8, 8, type[1]); + cmd.params[1] |= mc_enc(16, 8, type[2]); + cmd.params[1] |= mc_enc(24, 8, type[3]); + cmd.params[1] |= mc_enc(32, 8, type[4]); + cmd.params[1] |= mc_enc(40, 8, type[5]); + cmd.params[1] |= mc_enc(48, 8, type[6]); + cmd.params[1] |= mc_enc(56, 8, type[7]); + cmd.params[2] |= mc_enc(0, 8, type[8]); + cmd.params[2] |= mc_enc(8, 8, type[9]); + cmd.params[2] |= mc_enc(16, 8, type[10]); + cmd.params[2] |= mc_enc(24, 8, type[11]); + cmd.params[2] |= mc_enc(32, 8, type[12]); + cmd.params[2] |= mc_enc(40, 8, type[13]); + cmd.params[2] |= mc_enc(48, 8, type[14]); + cmd.params[2] |= mc_enc(56, 8, '\0'); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + *res_count = mc_dec(cmd.params[0], 0, 32); + + return 0; +} +EXPORT_SYMBOL(dprc_get_res_count); + +int dprc_get_res_ids(struct fsl_mc_io *mc_io, + uint16_t token, + char *type, + struct dprc_res_ids_range_desc *range_desc) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_RES_IDS, + MC_CMD_PRI_LOW, token); + cmd.params[0] |= mc_enc(42, 7, range_desc->iter_status); + cmd.params[1] |= mc_enc(0, 32, range_desc->base_id); + cmd.params[1] |= mc_enc(32, 32, range_desc->last_id); + cmd.params[2] |= mc_enc(0, 8, type[0]); + cmd.params[2] |= mc_enc(8, 8, type[1]); + cmd.params[2] |= mc_enc(16, 8, type[2]); + cmd.params[2] |= mc_enc(24, 8, type[3]); + cmd.params[2] |= mc_enc(32, 8, type[4]); + cmd.params[2] |= mc_enc(40, 8, type[5]); + cmd.params[2] |= mc_enc(48, 8, type[6]); + cmd.params[2] |= mc_enc(56, 8, type[7]); + cmd.params[3] |= mc_enc(0, 8, type[8]); + cmd.params[3] |= mc_enc(8, 8, type[9]); + cmd.params[3] |= mc_enc(16, 8, type[10]); + cmd.params[3] |= mc_enc(24, 8, type[11]); + cmd.params[3] |= mc_enc(32, 8, type[12]); + cmd.params[3] |= mc_enc(40, 8, type[13]); + cmd.params[3] |= mc_enc(48, 8, type[14]); + cmd.params[3] |= mc_enc(56, 8, '\0'); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + range_desc->iter_status = mc_dec(cmd.params[0], 42, 7); + range_desc->base_id = mc_dec(cmd.params[1], 0, 32); + range_desc->last_id = mc_dec(cmd.params[1], 32, 32); + + return 0; +} +EXPORT_SYMBOL(dprc_get_res_ids); + +int dprc_get_portal_paddr(struct fsl_mc_io *mc_io, + uint16_t token, + int portal_id, + uint64_t *portal_addr) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_PORTAL_PADDR, + MC_CMD_PRI_LOW, token); + cmd.params[0] |= mc_enc(0, 32, portal_id); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + *portal_addr = mc_dec(cmd.params[1], 0, 64); + + return 0; +} +EXPORT_SYMBOL(dprc_get_portal_paddr); + +int dprc_get_obj_region(struct fsl_mc_io *mc_io, + uint16_t token, + char *obj_type, + int obj_id, + uint8_t region_index, + struct dprc_region_desc *region_desc) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJ_REG, + MC_CMD_PRI_LOW, token); + cmd.params[0] |= mc_enc(0, 32, obj_id); + cmd.params[0] |= mc_enc(48, 8, region_index); + cmd.params[3] |= mc_enc(0, 8, obj_type[0]); + cmd.params[3] |= mc_enc(8, 8, obj_type[1]); + cmd.params[3] |= mc_enc(16, 8, obj_type[2]); + cmd.params[3] |= mc_enc(24, 8, obj_type[3]); + cmd.params[3] |= mc_enc(32, 8, obj_type[4]); + cmd.params[3] |= mc_enc(40, 8, obj_type[5]); + cmd.params[3] |= mc_enc(48, 8, obj_type[6]); + cmd.params[3] |= mc_enc(56, 8, obj_type[7]); + cmd.params[4] |= mc_enc(0, 8, obj_type[8]); + cmd.params[4] |= mc_enc(8, 8, obj_type[9]); + cmd.params[4] |= mc_enc(16, 8, obj_type[10]); + cmd.params[4] |= mc_enc(24, 8, obj_type[11]); + cmd.params[4] |= mc_enc(32, 8, obj_type[12]); + cmd.params[4] |= mc_enc(40, 8, obj_type[13]); + cmd.params[4] |= mc_enc(48, 8, obj_type[14]); + cmd.params[4] |= mc_enc(56, 8, '\0'); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + region_desc->base_paddr = mc_dec(cmd.params[1], 0, 64); + region_desc->size = mc_dec(cmd.params[2], 0, 32); + + return 0; +} +EXPORT_SYMBOL(dprc_get_obj_region); + +int dprc_connect(struct fsl_mc_io *mc_io, + uint16_t token, + const struct dprc_endpoint *endpoint1, + const struct dprc_endpoint *endpoint2) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_CONNECT, + MC_CMD_PRI_LOW, + token); + cmd.params[0] |= mc_enc(0, 32, endpoint1->id); + cmd.params[0] |= mc_enc(32, 32, endpoint1->interface_id); + cmd.params[1] |= mc_enc(0, 32, endpoint2->id); + cmd.params[1] |= mc_enc(32, 32, endpoint2->interface_id); + cmd.params[2] |= mc_enc(0, 8, endpoint1->type[0]); + cmd.params[2] |= mc_enc(8, 8, endpoint1->type[1]); + cmd.params[2] |= mc_enc(16, 8, endpoint1->type[2]); + cmd.params[2] |= mc_enc(24, 8, endpoint1->type[3]); + cmd.params[2] |= mc_enc(32, 8, endpoint1->type[4]); + cmd.params[2] |= mc_enc(40, 8, endpoint1->type[5]); + cmd.params[2] |= mc_enc(48, 8, endpoint1->type[6]); + cmd.params[2] |= mc_enc(56, 8, endpoint1->type[7]); + cmd.params[3] |= mc_enc(0, 8, endpoint1->type[8]); + cmd.params[3] |= mc_enc(8, 8, endpoint1->type[9]); + cmd.params[3] |= mc_enc(16, 8, endpoint1->type[10]); + cmd.params[3] |= mc_enc(24, 8, endpoint1->type[11]); + cmd.params[3] |= mc_enc(32, 8, endpoint1->type[12]); + cmd.params[3] |= mc_enc(40, 8, endpoint1->type[13]); + cmd.params[3] |= mc_enc(48, 8, endpoint1->type[14]); + cmd.params[3] |= mc_enc(56, 8, endpoint1->type[15]); + cmd.params[5] |= mc_enc(0, 8, endpoint2->type[0]); + cmd.params[5] |= mc_enc(8, 8, endpoint2->type[1]); + cmd.params[5] |= mc_enc(16, 8, endpoint2->type[2]); + cmd.params[5] |= mc_enc(24, 8, endpoint2->type[3]); + cmd.params[5] |= mc_enc(32, 8, endpoint2->type[4]); + cmd.params[5] |= mc_enc(40, 8, endpoint2->type[5]); + cmd.params[5] |= mc_enc(48, 8, endpoint2->type[6]); + cmd.params[5] |= mc_enc(56, 8, endpoint2->type[7]); + cmd.params[6] |= mc_enc(0, 8, endpoint2->type[8]); + cmd.params[6] |= mc_enc(8, 8, endpoint2->type[9]); + cmd.params[6] |= mc_enc(16, 8, endpoint2->type[10]); + cmd.params[6] |= mc_enc(24, 8, endpoint2->type[11]); + cmd.params[6] |= mc_enc(32, 8, endpoint2->type[12]); + cmd.params[6] |= mc_enc(40, 8, endpoint2->type[13]); + cmd.params[6] |= mc_enc(48, 8, endpoint2->type[14]); + cmd.params[6] |= mc_enc(56, 8, endpoint2->type[15]); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dprc_disconnect(struct fsl_mc_io *mc_io, + uint16_t token, + const struct dprc_endpoint *endpoint) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_DISCONNECT, + MC_CMD_PRI_LOW, + token); + cmd.params[0] |= mc_enc(0, 32, endpoint->id); + cmd.params[0] |= mc_enc(32, 32, endpoint->interface_id); + cmd.params[1] |= mc_enc(0, 8, endpoint->type[0]); + cmd.params[1] |= mc_enc(8, 8, endpoint->type[1]); + cmd.params[1] |= mc_enc(16, 8, endpoint->type[2]); + cmd.params[1] |= mc_enc(24, 8, endpoint->type[3]); + cmd.params[1] |= mc_enc(32, 8, endpoint->type[4]); + cmd.params[1] |= mc_enc(40, 8, endpoint->type[5]); + cmd.params[1] |= mc_enc(48, 8, endpoint->type[6]); + cmd.params[1] |= mc_enc(56, 8, endpoint->type[7]); + cmd.params[2] |= mc_enc(0, 8, endpoint->type[8]); + cmd.params[2] |= mc_enc(8, 8, endpoint->type[9]); + cmd.params[2] |= mc_enc(16, 8, endpoint->type[10]); + cmd.params[2] |= mc_enc(24, 8, endpoint->type[11]); + cmd.params[2] |= mc_enc(32, 8, endpoint->type[12]); + cmd.params[2] |= mc_enc(40, 8, endpoint->type[13]); + cmd.params[2] |= mc_enc(48, 8, endpoint->type[14]); + cmd.params[2] |= mc_enc(56, 8, endpoint->type[15]); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dprc_get_connection(struct fsl_mc_io *mc_io, + uint16_t token, + const struct dprc_endpoint *endpoint1, + struct dprc_endpoint *endpoint2, + int *state) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_CONNECTION, + MC_CMD_PRI_LOW, + token); + cmd.params[0] |= mc_enc(0, 32, endpoint1->id); + cmd.params[0] |= mc_enc(32, 32, endpoint1->interface_id); + cmd.params[1] |= mc_enc(0, 8, endpoint1->type[0]); + cmd.params[1] |= mc_enc(8, 8, endpoint1->type[1]); + cmd.params[1] |= mc_enc(16, 8, endpoint1->type[2]); + cmd.params[1] |= mc_enc(24, 8, endpoint1->type[3]); + cmd.params[1] |= mc_enc(32, 8, endpoint1->type[4]); + cmd.params[1] |= mc_enc(40, 8, endpoint1->type[5]); + cmd.params[1] |= mc_enc(48, 8, endpoint1->type[6]); + cmd.params[1] |= mc_enc(56, 8, endpoint1->type[7]); + cmd.params[2] |= mc_enc(0, 8, endpoint1->type[8]); + cmd.params[2] |= mc_enc(8, 8, endpoint1->type[9]); + cmd.params[2] |= mc_enc(16, 8, endpoint1->type[10]); + cmd.params[2] |= mc_enc(24, 8, endpoint1->type[11]); + cmd.params[2] |= mc_enc(32, 8, endpoint1->type[12]); + cmd.params[2] |= mc_enc(40, 8, endpoint1->type[13]); + cmd.params[2] |= mc_enc(48, 8, endpoint1->type[14]); + cmd.params[2] |= mc_enc(56, 8, endpoint1->type[15]); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + endpoint2->id = mc_dec(cmd.params[3], 0, 32); + endpoint2->interface_id = mc_dec(cmd.params[3], 32, 32); + endpoint2->type[0] = mc_dec(cmd.params[4], 0, 8); + endpoint2->type[1] = mc_dec(cmd.params[4], 8, 8); + endpoint2->type[2] = mc_dec(cmd.params[4], 16, 8); + endpoint2->type[3] = mc_dec(cmd.params[4], 24, 8); + endpoint2->type[4] = mc_dec(cmd.params[4], 32, 8); + endpoint2->type[5] = mc_dec(cmd.params[4], 40, 8); + endpoint2->type[6] = mc_dec(cmd.params[4], 48, 8); + endpoint2->type[7] = mc_dec(cmd.params[4], 56, 8); + endpoint2->type[8] = mc_dec(cmd.params[5], 0, 8); + endpoint2->type[9] = mc_dec(cmd.params[5], 8, 8); + endpoint2->type[10] = mc_dec(cmd.params[5], 16, 8); + endpoint2->type[11] = mc_dec(cmd.params[5], 24, 8); + endpoint2->type[12] = mc_dec(cmd.params[5], 32, 8); + endpoint2->type[13] = mc_dec(cmd.params[5], 40, 8); + endpoint2->type[14] = mc_dec(cmd.params[5], 48, 8); + endpoint2->type[15] = mc_dec(cmd.params[5], 56, 8); + *state = mc_dec(cmd.params[6], 0, 32); + + return 0; +} diff --git a/drivers/staging/fsl-mc/bus/mc-sys.c b/drivers/staging/fsl-mc/bus/mc-sys.c new file mode 100644 index 000000000000..a07064a9bc9a --- /dev/null +++ b/drivers/staging/fsl-mc/bus/mc-sys.c @@ -0,0 +1,283 @@ +/* Copyright 2013-2014 Freescale Semiconductor Inc. + * + * I/O services to send MC commands to the MC hardware + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the above-listed copyright holders nor the + * names of any contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "../include/mc-sys.h" +#include "../include/mc-cmd.h" +#include +#include +#include +#include + +/** + * Timeout in jiffies to wait for the completion of an MC command + */ +#define MC_CMD_COMPLETION_TIMEOUT_JIFFIES (HZ / 2) /* 500 ms */ + +/* + * usleep_range() min and max values used to throttle down polling + * iterations while waiting for MC command completion + */ +#define MC_CMD_COMPLETION_POLLING_MIN_SLEEP_USECS 10 +#define MC_CMD_COMPLETION_POLLING_MAX_SLEEP_USECS 500 + +#define MC_CMD_HDR_READ_CMDID(_hdr) \ + ((uint16_t)mc_dec((_hdr), MC_CMD_HDR_CMDID_O, MC_CMD_HDR_CMDID_S)) + +/** + * Creates an MC I/O object + * + * @dev: device to be associated with the MC I/O object + * @mc_portal_phys_addr: physical address of the MC portal to use + * @mc_portal_size: size in bytes of the MC portal + * @flags: flags for the new MC I/O object + * @new_mc_io: Area to return pointer to newly created MC I/O object + * + * Returns '0' on Success; Error code otherwise. + */ +int __must_check fsl_create_mc_io(struct device *dev, + phys_addr_t mc_portal_phys_addr, + uint32_t mc_portal_size, + uint32_t flags, struct fsl_mc_io **new_mc_io) +{ + struct fsl_mc_io *mc_io; + void __iomem *mc_portal_virt_addr; + struct resource *res; + + mc_io = devm_kzalloc(dev, sizeof(*mc_io), GFP_KERNEL); + if (!mc_io) + return -ENOMEM; + + mc_io->dev = dev; + mc_io->flags = flags; + mc_io->portal_phys_addr = mc_portal_phys_addr; + mc_io->portal_size = mc_portal_size; + res = devm_request_mem_region(dev, + mc_portal_phys_addr, + mc_portal_size, + "mc_portal"); + if (!res) { + dev_err(dev, + "devm_request_mem_region failed for MC portal %#llx\n", + mc_portal_phys_addr); + return -EBUSY; + } + + mc_portal_virt_addr = devm_ioremap_nocache(dev, + mc_portal_phys_addr, + mc_portal_size); + if (!mc_portal_virt_addr) { + dev_err(dev, + "devm_ioremap_nocache failed for MC portal %#llx\n", + mc_portal_phys_addr); + return -ENXIO; + } + + mc_io->portal_virt_addr = mc_portal_virt_addr; + *new_mc_io = mc_io; + return 0; +} +EXPORT_SYMBOL_GPL(fsl_create_mc_io); + +/** + * Destroys an MC I/O object + * + * @mc_io: MC I/O object to destroy + */ +void fsl_destroy_mc_io(struct fsl_mc_io *mc_io) +{ + devm_iounmap(mc_io->dev, mc_io->portal_virt_addr); + devm_release_mem_region(mc_io->dev, + mc_io->portal_phys_addr, + mc_io->portal_size); + + mc_io->portal_virt_addr = NULL; + devm_kfree(mc_io->dev, mc_io); +} +EXPORT_SYMBOL_GPL(fsl_destroy_mc_io); + +static int mc_status_to_error(enum mc_cmd_status status) +{ + static const int mc_status_to_error_map[] = { + [MC_CMD_STATUS_OK] = 0, + [MC_CMD_STATUS_AUTH_ERR] = -EACCES, + [MC_CMD_STATUS_NO_PRIVILEGE] = -EPERM, + [MC_CMD_STATUS_DMA_ERR] = -EIO, + [MC_CMD_STATUS_CONFIG_ERR] = -ENXIO, + [MC_CMD_STATUS_TIMEOUT] = -ETIMEDOUT, + [MC_CMD_STATUS_NO_RESOURCE] = -ENAVAIL, + [MC_CMD_STATUS_NO_MEMORY] = -ENOMEM, + [MC_CMD_STATUS_BUSY] = -EBUSY, + [MC_CMD_STATUS_UNSUPPORTED_OP] = -ENOTSUPP, + [MC_CMD_STATUS_INVALID_STATE] = -ENODEV, + }; + + if (WARN_ON((u32)status >= ARRAY_SIZE(mc_status_to_error_map))) + return -EINVAL; + + return mc_status_to_error_map[status]; +} + +static const char *mc_status_to_string(enum mc_cmd_status status) +{ + static const char *const status_strings[] = { + [MC_CMD_STATUS_OK] = "Command completed successfully", + [MC_CMD_STATUS_READY] = "Command ready to be processed", + [MC_CMD_STATUS_AUTH_ERR] = "Authentication error", + [MC_CMD_STATUS_NO_PRIVILEGE] = "No privilege", + [MC_CMD_STATUS_DMA_ERR] = "DMA or I/O error", + [MC_CMD_STATUS_CONFIG_ERR] = "Configuration error", + [MC_CMD_STATUS_TIMEOUT] = "Operation timed out", + [MC_CMD_STATUS_NO_RESOURCE] = "No resources", + [MC_CMD_STATUS_NO_MEMORY] = "No memory available", + [MC_CMD_STATUS_BUSY] = "Device is busy", + [MC_CMD_STATUS_UNSUPPORTED_OP] = "Unsupported operation", + [MC_CMD_STATUS_INVALID_STATE] = "Invalid state" + }; + + if ((unsigned int)status >= ARRAY_SIZE(status_strings)) + return "Unknown MC error"; + + return status_strings[status]; +} + +/** + * mc_write_command - writes a command to a Management Complex (MC) portal + * + * @portal: pointer to an MC portal + * @cmd: pointer to a filled command + */ +static inline void mc_write_command(struct mc_command __iomem *portal, + struct mc_command *cmd) +{ + int i; + + /* copy command parameters into the portal */ + for (i = 0; i < MC_CMD_NUM_OF_PARAMS; i++) + writeq(cmd->params[i], &portal->params[i]); + + /* submit the command by writing the header */ + writeq(cmd->header, &portal->header); +} + +/** + * mc_read_response - reads the response for the last MC command from a + * Management Complex (MC) portal + * + * @portal: pointer to an MC portal + * @resp: pointer to command response buffer + * + * Returns MC_CMD_STATUS_OK on Success; Error code otherwise. + */ +static inline enum mc_cmd_status mc_read_response(struct mc_command __iomem * + portal, + struct mc_command *resp) +{ + int i; + enum mc_cmd_status status; + + /* Copy command response header from MC portal: */ + resp->header = readq(&portal->header); + status = MC_CMD_HDR_READ_STATUS(resp->header); + if (status != MC_CMD_STATUS_OK) + return status; + + /* Copy command response data from MC portal: */ + for (i = 0; i < MC_CMD_NUM_OF_PARAMS; i++) + resp->params[i] = readq(&portal->params[i]); + + return status; +} + +/** + * Sends an command to the MC device using the given MC I/O object + * + * @mc_io: MC I/O object to be used + * @cmd: command to be sent + * + * Returns '0' on Success; Error code otherwise. + * + * NOTE: This function cannot be invoked from from atomic contexts. + */ +int mc_send_command(struct fsl_mc_io *mc_io, struct mc_command *cmd) +{ + enum mc_cmd_status status; + unsigned long jiffies_until_timeout = + jiffies + MC_CMD_COMPLETION_TIMEOUT_JIFFIES; + + /* + * Send command to the MC hardware: + */ + mc_write_command(mc_io->portal_virt_addr, cmd); + + /* + * Wait for response from the MC hardware: + */ + for (;;) { + status = mc_read_response(mc_io->portal_virt_addr, cmd); + if (status != MC_CMD_STATUS_READY) + break; + + /* + * TODO: When MC command completion interrupts are supported + * call wait function here instead of usleep_range() + */ + usleep_range(MC_CMD_COMPLETION_POLLING_MIN_SLEEP_USECS, + MC_CMD_COMPLETION_POLLING_MAX_SLEEP_USECS); + + if (time_after_eq(jiffies, jiffies_until_timeout)) { + pr_debug("MC command timed out (portal: %#llx, obj handle: %#x, command: %#x)\n", + mc_io->portal_phys_addr, + (unsigned int) + MC_CMD_HDR_READ_TOKEN(cmd->header), + (unsigned int) + MC_CMD_HDR_READ_CMDID(cmd->header)); + + return -ETIMEDOUT; + } + } + + if (status != MC_CMD_STATUS_OK) { + pr_debug("MC command failed: portal: %#llx, obj handle: %#x, command: %#x, status: %s (%#x)\n", + mc_io->portal_phys_addr, + (unsigned int)MC_CMD_HDR_READ_TOKEN(cmd->header), + (unsigned int)MC_CMD_HDR_READ_CMDID(cmd->header), + mc_status_to_string(status), + (unsigned int)status); + + return mc_status_to_error(status); + } + + return 0; +} +EXPORT_SYMBOL(mc_send_command); diff --git a/drivers/staging/fsl-mc/include/dpmng.h b/drivers/staging/fsl-mc/include/dpmng.h new file mode 100644 index 000000000000..0fc0a57490bb --- /dev/null +++ b/drivers/staging/fsl-mc/include/dpmng.h @@ -0,0 +1,80 @@ +/* Copyright 2013-2015 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the above-listed copyright holders nor the + * names of any contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef __FSL_DPMNG_H +#define __FSL_DPMNG_H + +/* Management Complex General API + * Contains general API for the Management Complex firmware + */ + +struct fsl_mc_io; + +/** + * Management Complex firmware version information + */ +#define MC_VER_MAJOR 5 +#define MC_VER_MINOR 0 + +/** + * struct mc_versoin + * @major: Major version number: incremented on API compatibility changes + * @minor: Minor version number: incremented on API additions (that are + * backward compatible); reset when major version is incremented + * @revision: Internal revision number: incremented on implementation changes + * and/or bug fixes that have no impact on API + */ +struct mc_version { + uint32_t major; + uint32_t minor; + uint32_t revision; +}; + +/** + * mc_get_version() - Retrieves the Management Complex firmware + * version information + * @mc_io: Pointer to opaque I/O object + * @mc_ver_info: Returned version information structure + * + * Return: '0' on Success; Error code otherwise. + */ +int mc_get_version(struct fsl_mc_io *mc_io, struct mc_version *mc_ver_info); + +/** + * dpmng_get_container_id() - Get container ID associated with a given portal. + * @mc_io: Pointer to MC portal's I/O object + * @container_id: Requested container ID + * + * Return: '0' on Success; Error code otherwise. + */ +int dpmng_get_container_id(struct fsl_mc_io *mc_io, int *container_id); + +#endif /* __FSL_DPMNG_H */ diff --git a/drivers/staging/fsl-mc/include/dprc.h b/drivers/staging/fsl-mc/include/dprc.h new file mode 100644 index 000000000000..f1862a78a409 --- /dev/null +++ b/drivers/staging/fsl-mc/include/dprc.h @@ -0,0 +1,801 @@ +/* Copyright 2013-2015 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the above-listed copyright holders nor the + * names of any contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_DPRC_H +#define _FSL_DPRC_H + +/* Data Path Resource Container API + * Contains DPRC API for managing and querying DPAA resources + */ + +struct fsl_mc_io; + +/** + * Set this value as the icid value in dprc_cfg structure when creating a + * container, in case the ICID is not selected by the user and should be + * allocated by the DPRC from the pool of ICIDs. + */ +#define DPRC_GET_ICID_FROM_POOL (uint16_t)(~(0)) + +/** + * Set this value as the portal_id value in dprc_cfg structure when creating a + * container, in case the portal ID is not specifically selected by the + * user and should be allocated by the DPRC from the pool of portal ids. + */ +#define DPRC_GET_PORTAL_ID_FROM_POOL (int)(~(0)) + +/** + * dprc_open() - Open DPRC object for use + * @mc_io: Pointer to MC portal's I/O object + * @container_id: Container ID to open + * @token: Returned token of DPRC object + * + * Return: '0' on Success; Error code otherwise. + * + * @warning Required before any operation on the object. + */ +int dprc_open(struct fsl_mc_io *mc_io, int container_id, uint16_t *token); + +/** + * dprc_close() - Close the control session of the object + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * + * After this function is called, no further operations are + * allowed on the object without opening a new control session. + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_close(struct fsl_mc_io *mc_io, uint16_t token); + +/** + * Container general options + * + * These options may be selected at container creation by the container creator + * and can be retrieved using dprc_get_attributes() + */ + +/* Spawn Policy Option allowed - Indicates that the new container is allowed + * to spawn and have its own child containers. + */ +#define DPRC_CFG_OPT_SPAWN_ALLOWED 0x00000001 + +/* General Container allocation policy - Indicates that the new container is + * allowed to allocate requested resources from its parent container; if not + * set, the container is only allowed to use resources in its own pools; Note + * that this is a container's global policy, but the parent container may + * override it and set specific quota per resource type. + */ +#define DPRC_CFG_OPT_ALLOC_ALLOWED 0x00000002 + +/* Object initialization allowed - software context associated with this + * container is allowed to invoke object initialization operations. + */ +#define DPRC_CFG_OPT_OBJ_CREATE_ALLOWED 0x00000004 + +/* Topology change allowed - software context associated with this + * container is allowed to invoke topology operations, such as attach/detach + * of network objects. + */ +#define DPRC_CFG_OPT_TOPOLOGY_CHANGES_ALLOWED 0x00000008 + +/* IOMMU bypass - indicates whether objects of this container are permitted + * to bypass the IOMMU. + */ +#define DPRC_CFG_OPT_IOMMU_BYPASS 0x00000010 + +/* AIOP - Indicates that container belongs to AIOP. */ +#define DPRC_CFG_OPT_AIOP 0x00000020 + +/** + * struct dprc_cfg - Container configuration options + * @icid: Container's ICID; if set to 'DPRC_GET_ICID_FROM_POOL', a free + * ICID value is allocated by the DPRC + * @portal_id: Portal ID; if set to 'DPRC_GET_PORTAL_ID_FROM_POOL', a free + * portal ID is allocated by the DPRC + * @options: Combination of 'DPRC_CFG_OPT_' options + */ +struct dprc_cfg { + uint16_t icid; + int portal_id; + uint64_t options; +}; + +/** + * dprc_create_container() - Create child container + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @cfg: Child container configuration + * @child_container_id: Returned child container ID + * @child_portal_paddr: Returned base physical address of the + * child portal + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_create_container(struct fsl_mc_io *mc_io, + uint16_t token, + struct dprc_cfg *cfg, + int *child_container_id, + uint64_t *child_portal_paddr); + +/** + * dprc_destroy_container() - Destroy child container. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @child_container_id: ID of the container to destroy + * + * This function terminates the child container, so following this call the + * child container ID becomes invalid. + * + * Notes: + * - All resources and objects of the destroyed container are returned to the + * parent container or destroyed if were created be the destroyed container. + * - This function destroy all the child containers of the specified + * container prior to destroying the container itself. + * + * warning: Only the parent container is allowed to destroy a child policy + * Container 0 can't be destroyed + * + * Return: '0' on Success; Error code otherwise. + * + */ +int dprc_destroy_container(struct fsl_mc_io *mc_io, + uint16_t token, + int child_container_id); + +/** + * dprc_reset_container - Reset child container. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @child_container_id: ID of the container to reset + * + * In case a software context crashes or becomes non-responsive, the parent + * may wish to reset its resources container before the software context is + * restarted. + * + * This routine informs all objects assigned to the child container that the + * container is being reset, so they may perform any cleanup operations that are + * needed. All objects handles that were owned by the child container shall be + * closed. + * + * Note that such request may be submitted even if the child software context + * has not crashed, but the resulting object cleanup operations will not be + * aware of that. + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_reset_container(struct fsl_mc_io *mc_io, + uint16_t token, + int child_container_id); + +/* IRQ */ + +/* Number of dprc's IRQs */ +#define DPRC_NUM_OF_IRQS 1 + +/* Object irq events */ + +/* IRQ event - Indicates that a new object assigned to the container */ +#define DPRC_IRQ_EVENT_OBJ_ADDED 0x00000001 +/* IRQ event - Indicates that an object was unassigned from the container */ +#define DPRC_IRQ_EVENT_OBJ_REMOVED 0x00000002 +/* IRQ event - Indicates that resources assigned to the container */ +#define DPRC_IRQ_EVENT_RES_ADDED 0x00000004 +/* IRQ event - Indicates that resources unassigned from the container */ +#define DPRC_IRQ_EVENT_RES_REMOVED 0x00000008 +/* IRQ event - Indicates that one of the descendant containers that opened by + * this container is destroyed + */ +#define DPRC_IRQ_EVENT_CONTAINER_DESTROYED 0x00000010 + +/* IRQ event - Indicates that on one of the container's opened object is + * destroyed + */ +#define DPRC_IRQ_EVENT_OBJ_DESTROYED 0x00000020 + +/* Irq event - Indicates that object is created at the container */ +#define DPRC_IRQ_EVENT_OBJ_CREATED 0x00000040 + +/** + * dprc_set_irq() - Set IRQ information for the DPRC to trigger an interrupt. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @irq_index: Identifies the interrupt index to configure + * @irq_addr: Address that must be written to + * signal a message-based interrupt + * @irq_val: Value to write into irq_addr address + * @user_irq_id: Returned a user defined number associated with this IRQ + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_set_irq(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint64_t irq_addr, + uint32_t irq_val, + int user_irq_id); + +/** + * dprc_get_irq() - Get IRQ information from the DPRC. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @irq_index: The interrupt index to configure + * @type: Returned interrupt type: 0 represents message interrupt + * type (both irq_addr and irq_val are valid) + * @irq_addr: Returned address that must be written to + * signal the message-based interrupt + * @irq_val: Value to write into irq_addr address + * @user_irq_id: A user defined number associated with this IRQ + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_get_irq(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + int *type, + uint64_t *irq_addr, + uint32_t *irq_val, + int *user_irq_id); + +/** + * dprc_set_irq_enable() - Set overall interrupt state. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @irq_index: The interrupt index to configure + * @en: Interrupt state - enable = 1, disable = 0 + * + * Allows GPP software to control when interrupts are generated. + * Each interrupt can have up to 32 causes. The enable/disable control's the + * overall interrupt state. if the interrupt is disabled no causes will cause + * an interrupt. + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_set_irq_enable(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint8_t en); + +/** + * dprc_get_irq_enable() - Get overall interrupt state. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @irq_index: The interrupt index to configure + * @en: Returned interrupt state - enable = 1, disable = 0 + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_get_irq_enable(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint8_t *en); + +/** + * dprc_set_irq_mask() - Set interrupt mask. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @irq_index: The interrupt index to configure + * @mask: event mask to trigger interrupt; + * each bit: + * 0 = ignore event + * 1 = consider event for asserting irq + * + * Every interrupt can have up to 32 causes and the interrupt model supports + * masking/unmasking each cause independently + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_set_irq_mask(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint32_t mask); + +/** + * dprc_get_irq_mask() - Get interrupt mask. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @irq_index: The interrupt index to configure + * @mask: Returned event mask to trigger interrupt + * + * Every interrupt can have up to 32 causes and the interrupt model supports + * masking/unmasking each cause independently + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_get_irq_mask(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint32_t *mask); + +/** + * dprc_get_irq_status() - Get the current status of any pending interrupts. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @irq_index: The interrupt index to configure + * @status: Returned interrupts status - one bit per cause: + * 0 = no interrupt pending + * 1 = interrupt pending + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_get_irq_status(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint32_t *status); + +/** + * dprc_clear_irq_status() - Clear a pending interrupt's status + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @irq_index: The interrupt index to configure + * @status: bits to clear (W1C) - one bit per cause: + * 0 = don't change + * 1 = clear status bit + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_clear_irq_status(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint32_t status); + +/** + * struct dprc_attributes - Container attributes + * @container_id: Container's ID + * @icid: Container's ICID + * @portal_id: Container's portal ID + * @options: Container's options as set at container's creation + * @version: DPRC version + */ +struct dprc_attributes { + int container_id; + uint16_t icid; + int portal_id; + uint64_t options; + /** + * struct version - DPRC version + * @major: DPRC major version + * @minor: DPRC minor version + */ + struct { + uint16_t major; + uint16_t minor; + } version; +}; + +/** + * dprc_get_attributes() - Obtains container attributes + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @attributes Returned container attributes + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_get_attributes(struct fsl_mc_io *mc_io, + uint16_t token, + struct dprc_attributes *attributes); + +/** + * dprc_set_res_quota() - Set allocation policy for a specific resource/object + * type in a child container + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @child_container_id: ID of the child container + * @type: Resource/object type + * @quota: Sets the maximum number of resources of the selected type + * that the child container is allowed to allocate from its parent; + * when quota is set to -1, the policy is the same as container's + * general policy. + * + * Allocation policy determines whether or not a container may allocate + * resources from its parent. Each container has a 'global' allocation policy + * that is set when the container is created. + * + * This function sets allocation policy for a specific resource type. + * The default policy for all resource types matches the container's 'global' + * allocation policy. + * + * Return: '0' on Success; Error code otherwise. + * + * @warning Only the parent container is allowed to change a child policy. + */ +int dprc_set_res_quota(struct fsl_mc_io *mc_io, + uint16_t token, + int child_container_id, + char *type, + uint16_t quota); + +/** + * dprc_get_res_quota() - Gets the allocation policy of a specific + * resource/object type in a child container + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @child_container_id; ID of the child container + * @type: resource/object type + * @quota: Returnes the maximum number of resources of the selected type + * that the child container is allowed to allocate from the parent; + * when quota is set to -1, the policy is the same as container's + * general policy. + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_get_res_quota(struct fsl_mc_io *mc_io, + uint16_t token, + int child_container_id, + char *type, + uint16_t *quota); + +/* Resource request options */ + +/* Explicit resource ID request - The requested objects/resources + * are explicit and sequential (in case of resources). + * The base ID is given at res_req at base_align field + */ +#define DPRC_RES_REQ_OPT_EXPLICIT 0x00000001 + +/* Aligned resources request - Relevant only for resources + * request (and not objects). Indicates that resources base ID should be + * sequential and aligned to the value given at dprc_res_req base_align field + */ +#define DPRC_RES_REQ_OPT_ALIGNED 0x00000002 + +/* Plugged Flag - Relevant only for object assignment request. + * Indicates that after all objects assigned. An interrupt will be invoked at + * the relevant GPP. The assigned object will be marked as plugged. + * plugged objects can't be assigned from their container + */ +#define DPRC_RES_REQ_OPT_PLUGGED 0x00000004 + +/** + * struct dprc_res_req - Resource request descriptor, to be used in assignment + * or un-assignment of resources and objects. + * @type: Resource/object type: Represent as a NULL terminated string. + * This string may received by using dprc_get_pool() to get resource + * type and dprc_get_obj() to get object type; + * Note: it is not possible to assign/un-assign DPRC objects + * @num: Number of resources + * @options: Request options: combination of DPRC_RES_REQ_OPT_ options + * @id_base_align: In case of explicit assignment (DPRC_RES_REQ_OPT_EXPLICIT + * is set at option), this field represents the required base ID + * for resource allocation; In case of aligned assignment + * (DPRC_RES_REQ_OPT_ALIGNED is set at option), this field + * indicates the required alignment for the resource ID(s) - + * use 0 if there is no alignment or explicit ID requirements + */ +struct dprc_res_req { + char type[16]; + uint32_t num; + uint32_t options; + int id_base_align; +}; + +/** + * dprc_assign() - Assigns objects or resource to a child container. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @container_id: ID of the child container + * @res_req: Describes the type and amount of resources to + * assign to the given container + * + * Assignment is usually done by a parent (this DPRC) to one of its child + * containers. + * + * According to the DPRC allocation policy, the assigned resources may be taken + * (allocated) from the container's ancestors, if not enough resources are + * available in the container itself. + * + * The type of assignment depends on the dprc_res_req options, as follows: + * - DPRC_RES_REQ_OPT_EXPLICIT: indicates that assigned resources should have + * the explicit base ID specified at the id_base_align field of res_req. + * - DPRC_RES_REQ_OPT_ALIGNED: indicates that the assigned resources should be + * aligned to the value given at id_base_align field of res_req. + * - DPRC_RES_REQ_OPT_PLUGGED: Relevant only for object assignment, + * and indicates that the object must be set to the plugged state. + * + * A container may use this function with its own ID in order to change a + * object state to plugged or unplugged. + * + * If IRQ information has been set in the child DPRC, it will signal an + * interrupt following every change in its object assignment. + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_assign(struct fsl_mc_io *mc_io, + uint16_t token, + int container_id, + struct dprc_res_req *res_req); + +/** + * dprc_unassign() - Un-assigns objects or resources from a child container + * and moves them into this (parent) DPRC. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @child_container_id: ID of the child container + * @res_req: Describes the type and amount of resources to un-assign from + * the child container + * + * Un-assignment of objects can succeed only if the object is not in the + * plugged or opened state. + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_unassign(struct fsl_mc_io *mc_io, + uint16_t token, + int child_container_id, + struct dprc_res_req *res_req); + +/** + * dprc_get_pool_count() - Get the number of dprc's pools + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @pool_count: Returned number of resource pools in the dprc + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_get_pool_count(struct fsl_mc_io *mc_io, + uint16_t token, + int *pool_count); + +/** + * dprc_get_pool() - Get the type (string) of a certain dprc's pool + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @pool_index; Index of the pool to be queried (< pool_count) + * @type: The type of the pool + * + * The pool types retrieved one by one by incrementing + * pool_index up to (not including) the value of pool_count returned + * from dprc_get_pool_count(). dprc_get_pool_count() must + * be called prior to dprc_get_pool(). + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_get_pool(struct fsl_mc_io *mc_io, + uint16_t token, + int pool_index, + char *type); + +/** + * dprc_get_obj_count() - Obtains the number of objects in the DPRC + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @obj_count: Number of objects assigned to the DPRC + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_get_obj_count(struct fsl_mc_io *mc_io, uint16_t token, int *obj_count); + +/* Objects Attributes Flags */ + +/* Opened state - Indicates that an object is open by at least one owner */ +#define DPRC_OBJ_STATE_OPEN 0x00000001 +/* Plugged state - Indicates that the object is plugged */ +#define DPRC_OBJ_STATE_PLUGGED 0x00000002 + +/** + * struct dprc_obj_desc - Object descriptor, returned from dprc_get_obj() + * @type: Type of object: NULL terminated string + * @id: ID of logical object resource + * @vendor: Object vendor identifier + * @ver_major: Major version number + * @ver_minor: Minor version number + * @irq_count: Number of interrupts supported by the object + * @region_count: Number of mappable regions supported by the object + * @state: Object state: combination of DPRC_OBJ_STATE_ states + */ +struct dprc_obj_desc { + char type[16]; + int id; + uint16_t vendor; + uint16_t ver_major; + uint16_t ver_minor; + uint8_t irq_count; + uint8_t region_count; + uint32_t state; +}; + +/** + * dprc_get_obj() - Get general information on an object + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @obj_index: Index of the object to be queried (< obj_count) + * @obj_desc: Returns the requested object descriptor + * + * The object descriptors are retrieved one by one by incrementing + * obj_index up to (not including) the value of obj_count returned + * from dprc_get_obj_count(). dprc_get_obj_count() must + * be called prior to dprc_get_obj(). + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_get_obj(struct fsl_mc_io *mc_io, + uint16_t token, + int obj_index, + struct dprc_obj_desc *obj_desc); + +/** + * dprc_get_res_count() - Obtains the number of free resources that are assigned + * to this container, by pool type + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @type: pool type + * @res_count: Returned number of free resources of the given + * resource type that are assigned to this DPRC + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_get_res_count(struct fsl_mc_io *mc_io, + uint16_t token, + char *type, + int *res_count); + +/** + * enum dprc_iter_status - Iteration status + * @DPRC_ITER_STATUS_FIRST: Perform first iteration + * @DPRC_ITER_STATUS_MORE: Indicates more/next iteration is needed + * @DPRC_ITER_STATUS_LAST: Indicates last iteration + */ +enum dprc_iter_status { + DPRC_ITER_STATUS_FIRST = 0, + DPRC_ITER_STATUS_MORE = 1, + DPRC_ITER_STATUS_LAST = 2 +}; + +/** + * struct dprc_res_ids_range_desc - Resource ID range descriptor + * @base_id: Base resource ID of this range + * @last_id: Last resource ID of this range + * @iter_status: Iteration status - should be set to DPRC_ITER_STATUS_FIRST at + * first iteration; while the returned marker is DPRC_ITER_STATUS_MORE, + * additional iterations are needed, until the returned marker is + * DPRC_ITER_STATUS_LAST + */ +struct dprc_res_ids_range_desc { + int base_id; + int last_id; + enum dprc_iter_status iter_status; +}; + +/** + * dprc_get_res_ids() - Obtains IDs of free resources in the container + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @type: pool type + * @range_desc: range descriptor + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_get_res_ids(struct fsl_mc_io *mc_io, + uint16_t token, + char *type, + struct dprc_res_ids_range_desc *range_desc); + +/** + * dprc_get_portal_paddr() - Get the physical address of MC portals + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @portal_id: MC portal ID + * @portal_addr: The physical address of the MC portal ID + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_get_portal_paddr(struct fsl_mc_io *mc_io, + uint16_t token, + int portal_id, + uint64_t *portal_addr); + +/** + * struct dprc_region_desc - Mappable region descriptor + * @base_paddr: Region base physical address + * @size: Region size (in bytes) + */ +struct dprc_region_desc { + uint64_t base_paddr; + uint32_t size; +}; + +/** + * dprc_get_obj_region() - Get region information for a specified object. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @obj_type; Object type as returned in dprc_get_obj() + * @obj_id: Unique object instance as returned in dprc_get_obj() + * @region_index: The specific region to query + * @region_desc: Returns the requested region descriptor + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_get_obj_region(struct fsl_mc_io *mc_io, + uint16_t token, + char *obj_type, + int obj_id, + uint8_t region_index, + struct dprc_region_desc *region_desc); + +/** + * struct dprc_endpoint - Endpoint description for link connect/disconnect + * operations + * @type: Endpoint object type: NULL terminated string + * @id: Endpoint object ID + * @interface_id: Interface ID; should be set for endpoints with multiple + * interfaces ("dpsw", "dpdmux"); for others, always set to 0 + */ +struct dprc_endpoint { + char type[16]; + int id; + int interface_id; +}; + +/** + * dprc_connect() - Connect two endpoints to create a network link between them + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @endpoint1: Endpoint 1 configuration parameters + * @endpoint2: Endpoint 2 configuration parameters + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_connect(struct fsl_mc_io *mc_io, + uint16_t token, + const struct dprc_endpoint *endpoint1, + const struct dprc_endpoint *endpoint2); + +/** + * dprc_disconnect() - Disconnect one endpoint to remove its network connection + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @endpoint: Endpoint configuration parameters + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_disconnect(struct fsl_mc_io *mc_io, + uint16_t token, + const struct dprc_endpoint *endpoint); + +/** +* dprc_get_connection() - Get connected endpoint and link status if connection +* exists. +* @mc_io Pointer to MC portal's I/O object +* @token Token of DPRC object +* @endpoint1 Endpoint 1 configuration parameters +* @endpoint2 Returned endpoint 2 configuration parameters +* @state: Returned link state: 1 - link is up, 0 - link is down +* +* Return: '0' on Success; -ENAVAIL if connection does not exist. +*/ +int dprc_get_connection(struct fsl_mc_io *mc_io, + uint16_t token, + const struct dprc_endpoint *endpoint1, + struct dprc_endpoint *endpoint2, + int *state); + +#endif /* _FSL_DPRC_H */ + diff --git a/drivers/staging/fsl-mc/include/mc-cmd.h b/drivers/staging/fsl-mc/include/mc-cmd.h new file mode 100644 index 000000000000..32501e020054 --- /dev/null +++ b/drivers/staging/fsl-mc/include/mc-cmd.h @@ -0,0 +1,113 @@ +/* Copyright 2013-2015 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the above-listed copyright holders nor the + * names of any contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef __FSL_MC_CMD_H +#define __FSL_MC_CMD_H + +#define MC_CMD_NUM_OF_PARAMS 7 + +#define MAKE_UMASK64(_width) \ + ((uint64_t)((_width) < 64 ? ((uint64_t)1 << (_width)) - 1 : -1)) + +static inline uint64_t mc_enc(int lsoffset, int width, uint64_t val) +{ + return (uint64_t)(((uint64_t)val & MAKE_UMASK64(width)) << lsoffset); +} + +static inline uint64_t mc_dec(uint64_t val, int lsoffset, int width) +{ + return (uint64_t)((val >> lsoffset) & MAKE_UMASK64(width)); +} + +struct mc_command { + uint64_t header; + uint64_t params[MC_CMD_NUM_OF_PARAMS]; +}; + +enum mc_cmd_status { + MC_CMD_STATUS_OK = 0x0, /* Completed successfully */ + MC_CMD_STATUS_READY = 0x1, /* Ready to be processed */ + MC_CMD_STATUS_AUTH_ERR = 0x3, /* Authentication error */ + MC_CMD_STATUS_NO_PRIVILEGE = 0x4, /* No privilege */ + MC_CMD_STATUS_DMA_ERR = 0x5, /* DMA or I/O error */ + MC_CMD_STATUS_CONFIG_ERR = 0x6, /* Configuration error */ + MC_CMD_STATUS_TIMEOUT = 0x7, /* Operation timed out */ + MC_CMD_STATUS_NO_RESOURCE = 0x8, /* No resources */ + MC_CMD_STATUS_NO_MEMORY = 0x9, /* No memory available */ + MC_CMD_STATUS_BUSY = 0xA, /* Device is busy */ + MC_CMD_STATUS_UNSUPPORTED_OP = 0xB, /* Unsupported operation */ + MC_CMD_STATUS_INVALID_STATE = 0xC /* Invalid state */ +}; + +#define MC_CMD_HDR_CMDID_O 52 /* Command ID field offset */ +#define MC_CMD_HDR_CMDID_S 12 /* Command ID field size */ +#define MC_CMD_HDR_TOKEN_O 38 /* Token field offset */ +#define MC_CMD_HDR_TOKEN_S 10 /* Token field size */ +#define MC_CMD_HDR_STATUS_O 16 /* Status field offset */ +#define MC_CMD_HDR_STATUS_S 8 /* Status field size*/ +#define MC_CMD_HDR_PRI_O 15 /* Priority field offset */ +#define MC_CMD_HDR_PRI_S 1 /* Priority field size */ + +#define MC_CMD_HDR_READ_STATUS(_hdr) \ + ((enum mc_cmd_status)mc_dec((_hdr), \ + MC_CMD_HDR_STATUS_O, MC_CMD_HDR_STATUS_S)) + +#define MC_CMD_HDR_READ_TOKEN(_hdr) \ + ((uint16_t)mc_dec((_hdr), MC_CMD_HDR_TOKEN_O, MC_CMD_HDR_TOKEN_S)) + +#define MC_CMD_PRI_LOW 0 /* Low Priority command indication */ +#define MC_CMD_PRI_HIGH 1 /* High Priority command indication */ + +#define MC_EXT_OP(_ext, _param, _offset, _width, _type, _arg) \ + ((_ext)[_param] |= mc_enc((_offset), (_width), _arg)) + +#define MC_CMD_OP(_cmd, _param, _offset, _width, _type, _arg) \ + ((_cmd).params[_param] |= mc_enc((_offset), (_width), _arg)) + +#define MC_RSP_OP(_cmd, _param, _offset, _width, _type, _arg) \ + (_arg = (_type)mc_dec(_cmd.params[_param], (_offset), (_width))) + +static inline uint64_t mc_encode_cmd_header(uint16_t cmd_id, + uint8_t priority, + uint16_t token) +{ + uint64_t hdr; + + hdr = mc_enc(MC_CMD_HDR_CMDID_O, MC_CMD_HDR_CMDID_S, cmd_id); + hdr |= mc_enc(MC_CMD_HDR_TOKEN_O, MC_CMD_HDR_TOKEN_S, token); + hdr |= mc_enc(MC_CMD_HDR_PRI_O, MC_CMD_HDR_PRI_S, priority); + hdr |= mc_enc(MC_CMD_HDR_STATUS_O, MC_CMD_HDR_STATUS_S, + MC_CMD_STATUS_READY); + + return hdr; +} + +#endif /* __FSL_MC_CMD_H */ diff --git a/drivers/staging/fsl-mc/include/mc-sys.h b/drivers/staging/fsl-mc/include/mc-sys.h new file mode 100644 index 000000000000..abfd6a233ada --- /dev/null +++ b/drivers/staging/fsl-mc/include/mc-sys.h @@ -0,0 +1,70 @@ +/* Copyright 2013-2014 Freescale Semiconductor Inc. + * + * Interface of the I/O services to send MC commands to the MC hardware + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the above-listed copyright holders nor the + * names of any contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_MC_SYS_H +#define _FSL_MC_SYS_H + +#include +#include +#include +#include + +struct mc_command; + +/** + * struct fsl_mc_io - MC I/O object to be passed-in to mc_send_command() + * @dev: device associated with this Mc I/O object + * @flags: flags for mc_send_command() + * @portal_size: MC command portal size in bytes + * @portal_phys_addr: MC command portal physical address + * @portal_virt_addr: MC command portal virtual address + */ +struct fsl_mc_io { + struct device *dev; + uint32_t flags; + uint32_t portal_size; + phys_addr_t portal_phys_addr; + void __iomem *portal_virt_addr; +}; + +int __must_check fsl_create_mc_io(struct device *dev, + phys_addr_t mc_portal_phys_addr, + uint32_t mc_portal_size, + uint32_t flags, struct fsl_mc_io **new_mc_io); + +void fsl_destroy_mc_io(struct fsl_mc_io *mc_io); + +int mc_send_command(struct fsl_mc_io *mc_io, struct mc_command *cmd); + +#endif /* _FSL_MC_SYS_H */ -- GitLab From bbf9d17d987544bd784fa0a6b99d756b0492e715 Mon Sep 17 00:00:00 2001 From: "J. German Rivera" Date: Thu, 5 Mar 2015 19:29:10 -0600 Subject: [PATCH 03232/11651] staging: fsl-mc: Freescale Management Complex (fsl-mc) bus driver Platform device driver that sets up the basic bus infrastructure for the fsl-mc bus type, including support for adding/removing fsl-mc devices, register/unregister of fsl-mc drivers, and bus match support to bind devices to drivers. Signed-off-by: J. German Rivera Signed-off-by: Stuart Yoder Acked-by: Alexander Graf Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 + drivers/staging/Makefile | 1 + drivers/staging/fsl-mc/Kconfig | 1 + drivers/staging/fsl-mc/Makefile | 2 + drivers/staging/fsl-mc/bus/Kconfig | 24 + drivers/staging/fsl-mc/bus/Makefile | 14 + drivers/staging/fsl-mc/bus/mc-bus.c | 755 ++++++++++++++++++++ drivers/staging/fsl-mc/include/mc-private.h | 67 ++ drivers/staging/fsl-mc/include/mc.h | 136 ++++ 9 files changed, 1002 insertions(+) create mode 100644 drivers/staging/fsl-mc/Kconfig create mode 100644 drivers/staging/fsl-mc/Makefile create mode 100644 drivers/staging/fsl-mc/bus/Kconfig create mode 100644 drivers/staging/fsl-mc/bus/Makefile create mode 100644 drivers/staging/fsl-mc/bus/mc-bus.c create mode 100644 drivers/staging/fsl-mc/include/mc-private.h create mode 100644 drivers/staging/fsl-mc/include/mc.h diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 5da70fddd036..bfacf69f68f4 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -110,4 +110,6 @@ source "drivers/staging/fbtft/Kconfig" source "drivers/staging/i2o/Kconfig" +source "drivers/staging/fsl-mc/Kconfig" + endif # STAGING diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 0b922ae30356..2bbd1bf04c55 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -47,3 +47,4 @@ obj-$(CONFIG_UNISYSSPAR) += unisys/ obj-$(CONFIG_COMMON_CLK_XLNX_CLKWZRD) += clocking-wizard/ obj-$(CONFIG_FB_TFT) += fbtft/ obj-$(CONFIG_I2O) += i2o/ +obj-$(CONFIG_FSL_MC_BUS) += fsl-mc/ diff --git a/drivers/staging/fsl-mc/Kconfig b/drivers/staging/fsl-mc/Kconfig new file mode 100644 index 000000000000..32df07b15e09 --- /dev/null +++ b/drivers/staging/fsl-mc/Kconfig @@ -0,0 +1 @@ +source "drivers/staging/fsl-mc/bus/Kconfig" diff --git a/drivers/staging/fsl-mc/Makefile b/drivers/staging/fsl-mc/Makefile new file mode 100644 index 000000000000..9c6a00128c65 --- /dev/null +++ b/drivers/staging/fsl-mc/Makefile @@ -0,0 +1,2 @@ +# Freescale Management Complex (MC) bus drivers +obj-$(CONFIG_FSL_MC_BUS) += bus/ diff --git a/drivers/staging/fsl-mc/bus/Kconfig b/drivers/staging/fsl-mc/bus/Kconfig new file mode 100644 index 000000000000..0d779d9ccbd8 --- /dev/null +++ b/drivers/staging/fsl-mc/bus/Kconfig @@ -0,0 +1,24 @@ +# +# Freescale Management Complex (MC) bus drivers +# +# Copyright (C) 2014 Freescale Semiconductor, Inc. +# +# This file is released under the GPLv2 +# + +config FSL_MC_BUS + tristate "Freescale Management Complex (MC) bus driver" + depends on OF && ARM64 + help + Driver to enable the bus infrastructure for the Freescale + QorIQ Management Complex (fsl-mc). The fsl-mc is a hardware + module of the QorIQ LS2 SoCs, that does resource management + for hardware building-blocks in the SoC that can be used + to dynamically create networking hardware objects such as + network interfaces (NICs), crypto accelerator instances, + or L2 switches. + + Only enable this option when building the kernel for + Freescale QorQIQ LS2xxxx SoCs. + + diff --git a/drivers/staging/fsl-mc/bus/Makefile b/drivers/staging/fsl-mc/bus/Makefile new file mode 100644 index 000000000000..decd3390215d --- /dev/null +++ b/drivers/staging/fsl-mc/bus/Makefile @@ -0,0 +1,14 @@ +# +# Freescale Management Complex (MC) bus drivers +# +# Copyright (C) 2014 Freescale Semiconductor, Inc. +# +# This file is released under the GPLv2 +# +obj-$(CONFIG_FSL_MC_BUS) += mc-bus-driver.o + +mc-bus-driver-objs := mc-bus.o \ + mc-sys.o \ + dprc.o \ + dpmng.o + diff --git a/drivers/staging/fsl-mc/bus/mc-bus.c b/drivers/staging/fsl-mc/bus/mc-bus.c new file mode 100644 index 000000000000..ce1de52bf030 --- /dev/null +++ b/drivers/staging/fsl-mc/bus/mc-bus.c @@ -0,0 +1,755 @@ +/* + * Freescale Management Complex (MC) bus driver + * + * Copyright (C) 2014 Freescale Semiconductor, Inc. + * Author: German Rivera + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include "../include/mc-private.h" +#include +#include +#include +#include +#include +#include +#include "../include/dpmng.h" +#include "../include/mc-sys.h" +#include "dprc-cmd.h" + +static struct kmem_cache *mc_dev_cache; + +/** + * fsl_mc_bus_match - device to driver matching callback + * @dev: the MC object device structure to match against + * @drv: the device driver to search for matching MC object device id + * structures + * + * Returns 1 on success, 0 otherwise. + */ +static int fsl_mc_bus_match(struct device *dev, struct device_driver *drv) +{ + const struct fsl_mc_device_match_id *id; + struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev); + struct fsl_mc_driver *mc_drv = to_fsl_mc_driver(drv); + bool found = false; + + if (WARN_ON(!fsl_mc_bus_type.dev_root)) + goto out; + + if (!mc_drv->match_id_table) + goto out; + + /* + * If the object is not 'plugged' don't match. + * Only exception is the root DPRC, which is a special case. + */ + if ((mc_dev->obj_desc.state & DPRC_OBJ_STATE_PLUGGED) == 0 && + &mc_dev->dev != fsl_mc_bus_type.dev_root) + goto out; + + /* + * Traverse the match_id table of the given driver, trying to find + * a matching for the given MC object device. + */ + for (id = mc_drv->match_id_table; id->vendor != 0x0; id++) { + if (id->vendor == mc_dev->obj_desc.vendor && + strcmp(id->obj_type, mc_dev->obj_desc.type) == 0 && + id->ver_major == mc_dev->obj_desc.ver_major && + id->ver_minor == mc_dev->obj_desc.ver_minor) { + found = true; + break; + } + } + +out: + dev_dbg(dev, "%smatched\n", found ? "" : "not "); + return found; +} + +/** + * fsl_mc_bus_uevent - callback invoked when a device is added + */ +static int fsl_mc_bus_uevent(struct device *dev, struct kobj_uevent_env *env) +{ + pr_debug("%s invoked\n", __func__); + return 0; +} + +struct bus_type fsl_mc_bus_type = { + .name = "fsl-mc", + .match = fsl_mc_bus_match, + .uevent = fsl_mc_bus_uevent, +}; +EXPORT_SYMBOL_GPL(fsl_mc_bus_type); + +static int fsl_mc_driver_probe(struct device *dev) +{ + struct fsl_mc_driver *mc_drv; + struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev); + int error; + + if (WARN_ON(!dev->driver)) + return -EINVAL; + + mc_drv = to_fsl_mc_driver(dev->driver); + if (WARN_ON(!mc_drv->probe)) + return -EINVAL; + + error = mc_drv->probe(mc_dev); + if (error < 0) { + dev_err(dev, "MC object device probe callback failed: %d\n", + error); + return error; + } + + return 0; +} + +static int fsl_mc_driver_remove(struct device *dev) +{ + struct fsl_mc_driver *mc_drv = to_fsl_mc_driver(dev->driver); + struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev); + int error; + + if (WARN_ON(!dev->driver)) + return -EINVAL; + + error = mc_drv->remove(mc_dev); + if (error < 0) { + dev_err(dev, + "MC object device remove callback failed: %d\n", + error); + return error; + } + + return 0; +} + +static void fsl_mc_driver_shutdown(struct device *dev) +{ + struct fsl_mc_driver *mc_drv = to_fsl_mc_driver(dev->driver); + struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev); + + mc_drv->shutdown(mc_dev); +} + +/** + * __fsl_mc_driver_register - registers a child device driver with the + * MC bus + * + * This function is implicitly invoked from the registration function of + * fsl_mc device drivers, which is generated by the + * module_fsl_mc_driver() macro. + */ +int __fsl_mc_driver_register(struct fsl_mc_driver *mc_driver, + struct module *owner) +{ + int error; + + mc_driver->driver.owner = owner; + mc_driver->driver.bus = &fsl_mc_bus_type; + + if (mc_driver->probe) + mc_driver->driver.probe = fsl_mc_driver_probe; + + if (mc_driver->remove) + mc_driver->driver.remove = fsl_mc_driver_remove; + + if (mc_driver->shutdown) + mc_driver->driver.shutdown = fsl_mc_driver_shutdown; + + error = driver_register(&mc_driver->driver); + if (error < 0) { + pr_err("driver_register() failed for %s: %d\n", + mc_driver->driver.name, error); + return error; + } + + pr_info("MC object device driver %s registered\n", + mc_driver->driver.name); + return 0; +} +EXPORT_SYMBOL_GPL(__fsl_mc_driver_register); + +/** + * fsl_mc_driver_unregister - unregisters a device driver from the + * MC bus + */ +void fsl_mc_driver_unregister(struct fsl_mc_driver *mc_driver) +{ + driver_unregister(&mc_driver->driver); +} +EXPORT_SYMBOL_GPL(fsl_mc_driver_unregister); + +static int get_dprc_icid(struct fsl_mc_io *mc_io, + int container_id, uint16_t *icid) +{ + uint16_t dprc_handle; + struct dprc_attributes attr; + int error; + + error = dprc_open(mc_io, container_id, &dprc_handle); + if (error < 0) { + pr_err("dprc_open() failed: %d\n", error); + return error; + } + + memset(&attr, 0, sizeof(attr)); + error = dprc_get_attributes(mc_io, dprc_handle, &attr); + if (error < 0) { + pr_err("dprc_get_attributes() failed: %d\n", error); + goto common_cleanup; + } + + *icid = attr.icid; + error = 0; + +common_cleanup: + (void)dprc_close(mc_io, dprc_handle); + return error; +} + +static int translate_mc_addr(uint64_t mc_addr, phys_addr_t *phys_addr) +{ + int i; + struct fsl_mc *mc = dev_get_drvdata(fsl_mc_bus_type.dev_root->parent); + + if (mc->num_translation_ranges == 0) { + /* + * Do identity mapping: + */ + *phys_addr = mc_addr; + return 0; + } + + for (i = 0; i < mc->num_translation_ranges; i++) { + struct fsl_mc_addr_translation_range *range = + &mc->translation_ranges[i]; + + if (mc_addr >= range->start_mc_addr && + mc_addr < range->end_mc_addr) { + *phys_addr = range->start_phys_addr + + (mc_addr - range->start_mc_addr); + return 0; + } + } + + return -EFAULT; +} + +static int fsl_mc_device_get_mmio_regions(struct fsl_mc_device *mc_dev, + struct fsl_mc_device *mc_bus_dev) +{ + int i; + int error; + struct resource *regions; + struct dprc_obj_desc *obj_desc = &mc_dev->obj_desc; + struct device *parent_dev = mc_dev->dev.parent; + + regions = kmalloc_array(obj_desc->region_count, + sizeof(regions[0]), GFP_KERNEL); + if (!regions) + return -ENOMEM; + + for (i = 0; i < obj_desc->region_count; i++) { + struct dprc_region_desc region_desc; + + error = dprc_get_obj_region(mc_bus_dev->mc_io, + mc_bus_dev->mc_handle, + obj_desc->type, + obj_desc->id, i, ®ion_desc); + if (error < 0) { + dev_err(parent_dev, + "dprc_get_obj_region() failed: %d\n", error); + goto error_cleanup_regions; + } + + WARN_ON(region_desc.base_paddr == 0x0); + WARN_ON(region_desc.size == 0); + error = translate_mc_addr(region_desc.base_paddr, + ®ions[i].start); + if (error < 0) { + dev_err(parent_dev, + "Invalid MC address: %#llx\n", + region_desc.base_paddr); + goto error_cleanup_regions; + } + + regions[i].end = regions[i].start + region_desc.size - 1; + regions[i].name = "fsl-mc object MMIO region"; + regions[i].flags = IORESOURCE_IO; + } + + mc_dev->regions = regions; + return 0; + +error_cleanup_regions: + kfree(regions); + return error; +} + +/** + * Add a newly discovered MC object device to be visible in Linux + */ +int fsl_mc_device_add(struct dprc_obj_desc *obj_desc, + struct fsl_mc_io *mc_io, + struct device *parent_dev, + struct fsl_mc_device **new_mc_dev) +{ + int error; + struct fsl_mc_device *mc_dev = NULL; + struct fsl_mc_bus *mc_bus = NULL; + struct fsl_mc_device *parent_mc_dev; + + if (parent_dev->bus == &fsl_mc_bus_type) + parent_mc_dev = to_fsl_mc_device(parent_dev); + else + parent_mc_dev = NULL; + + if (strcmp(obj_desc->type, "dprc") == 0) { + /* + * Allocate an MC bus device object: + */ + mc_bus = devm_kzalloc(parent_dev, sizeof(*mc_bus), GFP_KERNEL); + if (!mc_bus) + return -ENOMEM; + + mc_dev = &mc_bus->mc_dev; + } else { + /* + * Allocate a regular fsl_mc_device object: + */ + mc_dev = kmem_cache_zalloc(mc_dev_cache, GFP_KERNEL); + if (!mc_dev) + return -ENOMEM; + } + + mc_dev->obj_desc = *obj_desc; + mc_dev->mc_io = mc_io; + device_initialize(&mc_dev->dev); + mc_dev->dev.parent = parent_dev; + mc_dev->dev.bus = &fsl_mc_bus_type; + dev_set_name(&mc_dev->dev, "%s.%x", obj_desc->type, obj_desc->id); + + if (strcmp(obj_desc->type, "dprc") == 0) { + struct fsl_mc_io *mc_io2; + + mc_dev->flags |= FSL_MC_IS_DPRC; + + /* + * To get the DPRC's ICID, we need to open the DPRC + * in get_dprc_icid(). For child DPRCs, we do so using the + * parent DPRC's MC portal instead of the child DPRC's MC + * portal, in case the child DPRC is already opened with + * its own portal (e.g., the DPRC used by AIOP). + * + * NOTE: There cannot be more than one active open for a + * given MC object, using the same MC portal. + */ + if (parent_mc_dev) { + /* + * device being added is a child DPRC device + */ + mc_io2 = parent_mc_dev->mc_io; + } else { + /* + * device being added is the root DPRC device + */ + if (WARN_ON(!mc_io)) { + error = -EINVAL; + goto error_cleanup_dev; + } + + mc_io2 = mc_io; + + if (!fsl_mc_bus_type.dev_root) + fsl_mc_bus_type.dev_root = &mc_dev->dev; + } + + error = get_dprc_icid(mc_io2, obj_desc->id, &mc_dev->icid); + if (error < 0) + goto error_cleanup_dev; + } else { + /* + * A non-DPRC MC object device has to be a child of another + * MC object (specifically a DPRC object) + */ + mc_dev->icid = parent_mc_dev->icid; + mc_dev->dma_mask = FSL_MC_DEFAULT_DMA_MASK; + mc_dev->dev.dma_mask = &mc_dev->dma_mask; + } + + /* + * Get MMIO regions for the device from the MC: + * + * NOTE: the root DPRC is a special case as its MMIO region is + * obtained from the device tree + */ + if (parent_mc_dev && obj_desc->region_count != 0) { + error = fsl_mc_device_get_mmio_regions(mc_dev, + parent_mc_dev); + if (error < 0) + goto error_cleanup_dev; + } + + /* + * The device-specific probe callback will get invoked by device_add() + */ + error = device_add(&mc_dev->dev); + if (error < 0) { + dev_err(parent_dev, + "device_add() failed for device %s: %d\n", + dev_name(&mc_dev->dev), error); + goto error_cleanup_dev; + } + + (void)get_device(&mc_dev->dev); + dev_dbg(parent_dev, "Added MC object device %s\n", + dev_name(&mc_dev->dev)); + + *new_mc_dev = mc_dev; + return 0; + +error_cleanup_dev: + kfree(mc_dev->regions); + if (mc_bus) + devm_kfree(parent_dev, mc_bus); + else + kmem_cache_free(mc_dev_cache, mc_dev); + + return error; +} +EXPORT_SYMBOL_GPL(fsl_mc_device_add); + +/** + * fsl_mc_device_remove - Remove a MC object device from being visible to + * Linux + * + * @mc_dev: Pointer to a MC object device object + */ +void fsl_mc_device_remove(struct fsl_mc_device *mc_dev) +{ + struct fsl_mc_bus *mc_bus = NULL; + + kfree(mc_dev->regions); + + /* + * The device-specific remove callback will get invoked by device_del() + */ + device_del(&mc_dev->dev); + put_device(&mc_dev->dev); + + if (strcmp(mc_dev->obj_desc.type, "dprc") == 0) { + struct fsl_mc_io *mc_io = mc_dev->mc_io; + + mc_bus = to_fsl_mc_bus(mc_dev); + fsl_destroy_mc_io(mc_io); + if (&mc_dev->dev == fsl_mc_bus_type.dev_root) + fsl_mc_bus_type.dev_root = NULL; + } + + mc_dev->mc_io = NULL; + if (mc_bus) + devm_kfree(mc_dev->dev.parent, mc_bus); + else + kmem_cache_free(mc_dev_cache, mc_dev); +} +EXPORT_SYMBOL_GPL(fsl_mc_device_remove); + +static int parse_mc_ranges(struct device *dev, + int *paddr_cells, + int *mc_addr_cells, + int *mc_size_cells, + const __be32 **ranges_start, + uint8_t *num_ranges) +{ + const __be32 *prop; + int range_tuple_cell_count; + int ranges_len; + int tuple_len; + struct device_node *mc_node = dev->of_node; + + *ranges_start = of_get_property(mc_node, "ranges", &ranges_len); + if (!(*ranges_start) || !ranges_len) { + dev_warn(dev, + "missing or empty ranges property for device tree node '%s'\n", + mc_node->name); + + *num_ranges = 0; + return 0; + } + + *paddr_cells = of_n_addr_cells(mc_node); + + prop = of_get_property(mc_node, "#address-cells", NULL); + if (prop) + *mc_addr_cells = be32_to_cpup(prop); + else + *mc_addr_cells = *paddr_cells; + + prop = of_get_property(mc_node, "#size-cells", NULL); + if (prop) + *mc_size_cells = be32_to_cpup(prop); + else + *mc_size_cells = of_n_size_cells(mc_node); + + range_tuple_cell_count = *paddr_cells + *mc_addr_cells + + *mc_size_cells; + + tuple_len = range_tuple_cell_count * sizeof(__be32); + if (ranges_len % tuple_len != 0) { + dev_err(dev, "malformed ranges property '%s'\n", mc_node->name); + return -EINVAL; + } + + *num_ranges = ranges_len / tuple_len; + return 0; +} + +static int get_mc_addr_translation_ranges(struct device *dev, + struct fsl_mc_addr_translation_range + **ranges, + uint8_t *num_ranges) +{ + int error; + int paddr_cells; + int mc_addr_cells; + int mc_size_cells; + int i; + const __be32 *ranges_start; + const __be32 *cell; + + error = parse_mc_ranges(dev, + &paddr_cells, + &mc_addr_cells, + &mc_size_cells, + &ranges_start, + num_ranges); + if (error < 0) + return error; + + if (!(*num_ranges)) { + /* + * Missing or empty ranges property ("ranges;") for the + * 'fsl,qoriq-mc' node. In this case, identity mapping + * will be used. + */ + *ranges = NULL; + return 0; + } + + *ranges = devm_kcalloc(dev, *num_ranges, + sizeof(struct fsl_mc_addr_translation_range), + GFP_KERNEL); + if (!(*ranges)) + return -ENOMEM; + + cell = ranges_start; + for (i = 0; i < *num_ranges; ++i) { + struct fsl_mc_addr_translation_range *range = &(*ranges)[i]; + + range->start_mc_addr = of_read_number(cell, mc_addr_cells); + cell += mc_addr_cells; + range->start_phys_addr = of_read_number(cell, paddr_cells); + cell += paddr_cells; + range->end_mc_addr = range->start_mc_addr + + of_read_number(cell, mc_size_cells); + + cell += mc_size_cells; + } + + return 0; +} + +/** + * fsl_mc_bus_probe - callback invoked when the root MC bus is being + * added + */ +static int fsl_mc_bus_probe(struct platform_device *pdev) +{ + struct dprc_obj_desc obj_desc; + int error; + struct fsl_mc *mc; + struct fsl_mc_device *mc_bus_dev = NULL; + struct fsl_mc_io *mc_io = NULL; + int container_id; + phys_addr_t mc_portal_phys_addr; + uint32_t mc_portal_size; + struct mc_version mc_version; + struct resource res; + + dev_info(&pdev->dev, "Root MC bus device probed"); + + mc = devm_kzalloc(&pdev->dev, sizeof(*mc), GFP_KERNEL); + if (!mc) + return -ENOMEM; + + platform_set_drvdata(pdev, mc); + + /* + * Get physical address of MC portal for the root DPRC: + */ + error = of_address_to_resource(pdev->dev.of_node, 0, &res); + if (error < 0) { + dev_err(&pdev->dev, + "of_address_to_resource() failed for %s\n", + pdev->dev.of_node->full_name); + return error; + } + + mc_portal_phys_addr = res.start; + mc_portal_size = resource_size(&res); + error = fsl_create_mc_io(&pdev->dev, mc_portal_phys_addr, + mc_portal_size, 0, &mc_io); + if (error < 0) + return error; + + error = mc_get_version(mc_io, &mc_version); + if (error != 0) { + dev_err(&pdev->dev, + "mc_get_version() failed with error %d\n", error); + goto error_cleanup_mc_io; + } + + dev_info(&pdev->dev, + "Freescale Management Complex Firmware version: %u.%u.%u\n", + mc_version.major, mc_version.minor, mc_version.revision); + + if (mc_version.major < MC_VER_MAJOR) { + dev_err(&pdev->dev, + "ERROR: MC firmware version not supported by driver (driver version: %u.%u)\n", + MC_VER_MAJOR, MC_VER_MINOR); + error = -ENOTSUPP; + goto error_cleanup_mc_io; + } + + if (mc_version.major > MC_VER_MAJOR) { + dev_warn(&pdev->dev, + "WARNING: driver may not support newer MC firmware features (driver version: %u.%u)\n", + MC_VER_MAJOR, MC_VER_MINOR); + } + + error = get_mc_addr_translation_ranges(&pdev->dev, + &mc->translation_ranges, + &mc->num_translation_ranges); + if (error < 0) + goto error_cleanup_mc_io; + + error = dpmng_get_container_id(mc_io, &container_id); + if (error < 0) { + dev_err(&pdev->dev, + "dpmng_get_container_id() failed: %d\n", error); + goto error_cleanup_mc_io; + } + + obj_desc.vendor = FSL_MC_VENDOR_FREESCALE; + strcpy(obj_desc.type, "dprc"); + obj_desc.id = container_id; + obj_desc.ver_major = DPRC_VER_MAJOR; + obj_desc.ver_minor = DPRC_VER_MINOR; + obj_desc.region_count = 0; + + error = fsl_mc_device_add(&obj_desc, mc_io, &pdev->dev, &mc_bus_dev); + if (error < 0) + goto error_cleanup_mc_io; + + mc->root_mc_bus_dev = mc_bus_dev; + return 0; + +error_cleanup_mc_io: + fsl_destroy_mc_io(mc_io); + return error; +} + +/** + * fsl_mc_bus_remove - callback invoked when the root MC bus is being + * removed + */ +static int fsl_mc_bus_remove(struct platform_device *pdev) +{ + struct fsl_mc *mc = platform_get_drvdata(pdev); + + if (WARN_ON(&mc->root_mc_bus_dev->dev != fsl_mc_bus_type.dev_root)) + return -EINVAL; + + fsl_mc_device_remove(mc->root_mc_bus_dev); + dev_info(&pdev->dev, "Root MC bus device removed"); + return 0; +} + +static const struct of_device_id fsl_mc_bus_match_table[] = { + {.compatible = "fsl,qoriq-mc",}, + {}, +}; + +MODULE_DEVICE_TABLE(of, fsl_mc_bus_match_table); + +static struct platform_driver fsl_mc_bus_driver = { + .driver = { + .name = "fsl_mc_bus", + .owner = THIS_MODULE, + .pm = NULL, + .of_match_table = fsl_mc_bus_match_table, + }, + .probe = fsl_mc_bus_probe, + .remove = fsl_mc_bus_remove, +}; + +static int __init fsl_mc_bus_driver_init(void) +{ + int error; + + mc_dev_cache = kmem_cache_create("fsl_mc_device", + sizeof(struct fsl_mc_device), 0, 0, + NULL); + if (!mc_dev_cache) { + pr_err("Could not create fsl_mc_device cache\n"); + return -ENOMEM; + } + + error = bus_register(&fsl_mc_bus_type); + if (error < 0) { + pr_err("fsl-mc bus type registration failed: %d\n", error); + goto error_cleanup_cache; + } + + pr_info("fsl-mc bus type registered\n"); + + error = platform_driver_register(&fsl_mc_bus_driver); + if (error < 0) { + pr_err("platform_driver_register() failed: %d\n", error); + goto error_cleanup_bus; + } + + return 0; + +error_cleanup_bus: + bus_unregister(&fsl_mc_bus_type); + +error_cleanup_cache: + kmem_cache_destroy(mc_dev_cache); + return error; +} + +postcore_initcall(fsl_mc_bus_driver_init); + +static void __exit fsl_mc_bus_driver_exit(void) +{ + if (WARN_ON(!mc_dev_cache)) + return; + + platform_driver_unregister(&fsl_mc_bus_driver); + bus_unregister(&fsl_mc_bus_type); + kmem_cache_destroy(mc_dev_cache); + pr_info("MC bus unregistered\n"); +} + +module_exit(fsl_mc_bus_driver_exit); + +MODULE_AUTHOR("Freescale Semiconductor Inc."); +MODULE_DESCRIPTION("Freescale Management Complex (MC) bus driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/fsl-mc/include/mc-private.h b/drivers/staging/fsl-mc/include/mc-private.h new file mode 100644 index 000000000000..5c957c452fdd --- /dev/null +++ b/drivers/staging/fsl-mc/include/mc-private.h @@ -0,0 +1,67 @@ +/* + * Freescale Management Complex (MC) bus private declarations + * + * Copyright (C) 2014 Freescale Semiconductor, Inc. + * Author: German Rivera + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ +#ifndef _FSL_MC_PRIVATE_H_ +#define _FSL_MC_PRIVATE_H_ + +#include "../include/mc.h" +#include +#include + +#define FSL_MC_DEVICE_MATCH(_mc_dev, _obj_desc) \ + (strcmp((_mc_dev)->obj_desc.type, (_obj_desc)->type) == 0 && \ + (_mc_dev)->obj_desc.id == (_obj_desc)->id) + +/** + * struct fsl_mc - Private data of a "fsl,qoriq-mc" platform device + * @root_mc_bus_dev: MC object device representing the root DPRC + * @addr_translation_ranges: array of bus to system address translation ranges + */ +struct fsl_mc { + struct fsl_mc_device *root_mc_bus_dev; + uint8_t num_translation_ranges; + struct fsl_mc_addr_translation_range *translation_ranges; +}; + +/** + * struct fsl_mc_bus - logical bus that corresponds to a physical DPRC + * @mc_dev: fsl-mc device for the bus device itself. + * @scan_mutex: Serializes bus scanning + */ +struct fsl_mc_bus { + struct fsl_mc_device mc_dev; + struct mutex scan_mutex; /* serializes bus scanning */ +}; + +#define to_fsl_mc_bus(_mc_dev) \ + container_of(_mc_dev, struct fsl_mc_bus, mc_dev) + +/** + * struct fsl_mc_addr_translation_range - bus to system address translation + * range + * @start_mc_addr: Start MC address of the range being translated + * @end_mc_addr: MC address of the first byte after the range (last MC + * address of the range is end_mc_addr - 1) + * @start_phys_addr: system physical address corresponding to start_mc_addr + */ +struct fsl_mc_addr_translation_range { + uint64_t start_mc_addr; + uint64_t end_mc_addr; + phys_addr_t start_phys_addr; +}; + +int __must_check fsl_mc_device_add(struct dprc_obj_desc *obj_desc, + struct fsl_mc_io *mc_io, + struct device *parent_dev, + struct fsl_mc_device **new_mc_dev); + +void fsl_mc_device_remove(struct fsl_mc_device *mc_dev); + +#endif /* _FSL_MC_PRIVATE_H_ */ diff --git a/drivers/staging/fsl-mc/include/mc.h b/drivers/staging/fsl-mc/include/mc.h new file mode 100644 index 000000000000..5cd237b31704 --- /dev/null +++ b/drivers/staging/fsl-mc/include/mc.h @@ -0,0 +1,136 @@ +/* + * Freescale Management Complex (MC) bus public interface + * + * Copyright (C) 2014 Freescale Semiconductor, Inc. + * Author: German Rivera + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ +#ifndef _FSL_MC_H_ +#define _FSL_MC_H_ + +#include +#include +#include +#include "../include/dprc.h" + +#define FSL_MC_VENDOR_FREESCALE 0x1957 + +struct fsl_mc_device; +struct fsl_mc_io; + +/** + * struct fsl_mc_driver - MC object device driver object + * @driver: Generic device driver + * @match_id_table: table of supported device matching Ids + * @probe: Function called when a device is added + * @remove: Function called when a device is removed + * @shutdown: Function called at shutdown time to quiesce the device + * @suspend: Function called when a device is stopped + * @resume: Function called when a device is resumed + * + * Generic DPAA device driver object for device drivers that are registered + * with a DPRC bus. This structure is to be embedded in each device-specific + * driver structure. + */ +struct fsl_mc_driver { + struct device_driver driver; + const struct fsl_mc_device_match_id *match_id_table; + int (*probe)(struct fsl_mc_device *dev); + int (*remove)(struct fsl_mc_device *dev); + void (*shutdown)(struct fsl_mc_device *dev); + int (*suspend)(struct fsl_mc_device *dev, pm_message_t state); + int (*resume)(struct fsl_mc_device *dev); +}; + +#define to_fsl_mc_driver(_drv) \ + container_of(_drv, struct fsl_mc_driver, driver) + +/** + * struct fsl_mc_device_match_id - MC object device Id entry for driver matching + * @vendor: vendor ID + * @obj_type: MC object type + * @ver_major: MC object version major number + * @ver_minor: MC object version minor number + * + * Type of entries in the "device Id" table for MC object devices supported by + * a MC object device driver. The last entry of the table has vendor set to 0x0 + */ +struct fsl_mc_device_match_id { + uint16_t vendor; + const char obj_type[16]; + uint32_t ver_major; + uint32_t ver_minor; +}; + +/** + * Bit masks for a MC object device (struct fsl_mc_device) flags + */ +#define FSL_MC_IS_DPRC 0x0001 + +/** + * Default DMA mask for devices on a fsl-mc bus + */ +#define FSL_MC_DEFAULT_DMA_MASK (~0ULL) + +/** + * struct fsl_mc_device - MC object device object + * @dev: Linux driver model device object + * @dma_mask: Default DMA mask + * @flags: MC object device flags + * @icid: Isolation context ID for the device + * @mc_handle: MC handle for the corresponding MC object opened + * @mc_io: Pointer to MC IO object assigned to this device or + * NULL if none. + * @obj_desc: MC description of the DPAA device + * @regions: pointer to array of MMIO region entries + * + * Generic device object for MC object devices that are "attached" to a + * MC bus. + * + * NOTES: + * - For a non-DPRC object its icid is the same as its parent DPRC's icid. + * - The SMMU notifier callback gets invoked after device_add() has been + * called for an MC object device, but before the device-specific probe + * callback gets called. + */ +struct fsl_mc_device { + struct device dev; + uint64_t dma_mask; + uint16_t flags; + uint16_t icid; + uint16_t mc_handle; + struct fsl_mc_io *mc_io; + struct dprc_obj_desc obj_desc; + struct resource *regions; +}; + +#define to_fsl_mc_device(_dev) \ + container_of(_dev, struct fsl_mc_device, dev) + +/* + * module_fsl_mc_driver() - Helper macro for drivers that don't do + * anything special in module init/exit. This eliminates a lot of + * boilerplate. Each module may only use this macro once, and + * calling it replaces module_init() and module_exit() + */ +#define module_fsl_mc_driver(__fsl_mc_driver) \ + module_driver(__fsl_mc_driver, fsl_mc_driver_register, \ + fsl_mc_driver_unregister) + +/* + * Macro to avoid include chaining to get THIS_MODULE + */ +#define fsl_mc_driver_register(drv) \ + __fsl_mc_driver_register(drv, THIS_MODULE) + +int __must_check __fsl_mc_driver_register(struct fsl_mc_driver *fsl_mc_driver, + struct module *owner); + +void fsl_mc_driver_unregister(struct fsl_mc_driver *driver); + +extern struct bus_type fsl_mc_bus_type; + +#endif /* _FSL_MC_H_ */ -- GitLab From f2f2726b62f59424782516fd6d0d164892493ada Mon Sep 17 00:00:00 2001 From: "J. German Rivera" Date: Thu, 5 Mar 2015 19:29:11 -0600 Subject: [PATCH 03233/11651] staging: fsl-mc: Device driver for FSL-MC DPRC devices A DPRC (Data Path Resource Container) is an isolation device that contains a set of DPAA networking devices to be assigned to an isolation domain (e.g., a virtual machine). Signed-off-by: J. German Rivera Signed-off-by: Stuart Yoder Acked-by: Alexander Graf Signed-off-by: Greg Kroah-Hartman --- drivers/staging/fsl-mc/bus/Makefile | 3 +- drivers/staging/fsl-mc/bus/dprc-driver.c | 384 ++++++++++++++++++++ drivers/staging/fsl-mc/bus/mc-bus.c | 8 + drivers/staging/fsl-mc/include/mc-private.h | 10 + 4 files changed, 404 insertions(+), 1 deletion(-) create mode 100644 drivers/staging/fsl-mc/bus/dprc-driver.c diff --git a/drivers/staging/fsl-mc/bus/Makefile b/drivers/staging/fsl-mc/bus/Makefile index decd3390215d..424e58e1ea7e 100644 --- a/drivers/staging/fsl-mc/bus/Makefile +++ b/drivers/staging/fsl-mc/bus/Makefile @@ -10,5 +10,6 @@ obj-$(CONFIG_FSL_MC_BUS) += mc-bus-driver.o mc-bus-driver-objs := mc-bus.o \ mc-sys.o \ dprc.o \ - dpmng.o + dpmng.o \ + dprc-driver.o diff --git a/drivers/staging/fsl-mc/bus/dprc-driver.c b/drivers/staging/fsl-mc/bus/dprc-driver.c new file mode 100644 index 000000000000..f5d1deb77c95 --- /dev/null +++ b/drivers/staging/fsl-mc/bus/dprc-driver.c @@ -0,0 +1,384 @@ +/* + * Freescale data path resource container (DPRC) driver + * + * Copyright (C) 2014 Freescale Semiconductor, Inc. + * Author: German Rivera + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include "../include/mc-private.h" +#include "../include/mc-sys.h" +#include +#include +#include "dprc-cmd.h" + +struct dprc_child_objs { + int child_count; + struct dprc_obj_desc *child_array; +}; + +static int __fsl_mc_device_remove_if_not_in_mc(struct device *dev, void *data) +{ + int i; + struct dprc_child_objs *objs; + struct fsl_mc_device *mc_dev; + + WARN_ON(!dev); + WARN_ON(!data); + mc_dev = to_fsl_mc_device(dev); + objs = data; + + for (i = 0; i < objs->child_count; i++) { + struct dprc_obj_desc *obj_desc = &objs->child_array[i]; + + if (strlen(obj_desc->type) != 0 && + FSL_MC_DEVICE_MATCH(mc_dev, obj_desc)) + break; + } + + if (i == objs->child_count) + fsl_mc_device_remove(mc_dev); + + return 0; +} + +static int __fsl_mc_device_remove(struct device *dev, void *data) +{ + WARN_ON(!dev); + WARN_ON(data); + fsl_mc_device_remove(to_fsl_mc_device(dev)); + return 0; +} + +/** + * dprc_remove_devices - Removes devices for objects removed from a DPRC + * + * @mc_bus_dev: pointer to the fsl-mc device that represents a DPRC object + * @obj_desc_array: array of object descriptors for child objects currently + * present in the DPRC in the MC. + * @num_child_objects_in_mc: number of entries in obj_desc_array + * + * Synchronizes the state of the Linux bus driver with the actual state of + * the MC by removing devices that represent MC objects that have + * been dynamically removed in the physical DPRC. + */ +static void dprc_remove_devices(struct fsl_mc_device *mc_bus_dev, + struct dprc_obj_desc *obj_desc_array, + int num_child_objects_in_mc) +{ + if (num_child_objects_in_mc != 0) { + /* + * Remove child objects that are in the DPRC in Linux, + * but not in the MC: + */ + struct dprc_child_objs objs; + + objs.child_count = num_child_objects_in_mc; + objs.child_array = obj_desc_array; + device_for_each_child(&mc_bus_dev->dev, &objs, + __fsl_mc_device_remove_if_not_in_mc); + } else { + /* + * There are no child objects for this DPRC in the MC. + * So, remove all the child devices from Linux: + */ + device_for_each_child(&mc_bus_dev->dev, NULL, + __fsl_mc_device_remove); + } +} + +static int __fsl_mc_device_match(struct device *dev, void *data) +{ + struct dprc_obj_desc *obj_desc = data; + struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev); + + return FSL_MC_DEVICE_MATCH(mc_dev, obj_desc); +} + +static struct fsl_mc_device *fsl_mc_device_lookup(struct dprc_obj_desc + *obj_desc, + struct fsl_mc_device + *mc_bus_dev) +{ + struct device *dev; + + dev = device_find_child(&mc_bus_dev->dev, obj_desc, + __fsl_mc_device_match); + + return dev ? to_fsl_mc_device(dev) : NULL; +} + +/** + * dprc_add_new_devices - Adds devices to the logical bus for a DPRC + * + * @mc_bus_dev: pointer to the fsl-mc device that represents a DPRC object + * @obj_desc_array: array of device descriptors for child devices currently + * present in the physical DPRC. + * @num_child_objects_in_mc: number of entries in obj_desc_array + * + * Synchronizes the state of the Linux bus driver with the actual + * state of the MC by adding objects that have been newly discovered + * in the physical DPRC. + */ +static void dprc_add_new_devices(struct fsl_mc_device *mc_bus_dev, + struct dprc_obj_desc *obj_desc_array, + int num_child_objects_in_mc) +{ + int error; + int i; + + for (i = 0; i < num_child_objects_in_mc; i++) { + struct fsl_mc_device *child_dev; + struct fsl_mc_io *mc_io = NULL; + struct dprc_obj_desc *obj_desc = &obj_desc_array[i]; + + if (strlen(obj_desc->type) == 0) + continue; + + /* + * Check if device is already known to Linux: + */ + child_dev = fsl_mc_device_lookup(obj_desc, mc_bus_dev); + if (child_dev) + continue; + + error = fsl_mc_device_add(obj_desc, mc_io, &mc_bus_dev->dev, + &child_dev); + if (error < 0) { + if (mc_io) + fsl_destroy_mc_io(mc_io); + + continue; + } + } +} + +/** + * dprc_scan_objects - Discover objects in a DPRC + * + * @mc_bus_dev: pointer to the fsl-mc device that represents a DPRC object + * + * Detects objects added and removed from a DPRC and synchronizes the + * state of the Linux bus driver, MC by adding and removing + * devices accordingly. + */ +int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev) +{ + int num_child_objects; + int dprc_get_obj_failures; + int error; + struct dprc_obj_desc *child_obj_desc_array = NULL; + + error = dprc_get_obj_count(mc_bus_dev->mc_io, + mc_bus_dev->mc_handle, + &num_child_objects); + if (error < 0) { + dev_err(&mc_bus_dev->dev, "dprc_get_obj_count() failed: %d\n", + error); + return error; + } + + if (num_child_objects != 0) { + int i; + + child_obj_desc_array = + devm_kmalloc_array(&mc_bus_dev->dev, num_child_objects, + sizeof(*child_obj_desc_array), + GFP_KERNEL); + if (!child_obj_desc_array) + return -ENOMEM; + + /* + * Discover objects currently present in the physical DPRC: + */ + dprc_get_obj_failures = 0; + for (i = 0; i < num_child_objects; i++) { + struct dprc_obj_desc *obj_desc = + &child_obj_desc_array[i]; + + error = dprc_get_obj(mc_bus_dev->mc_io, + mc_bus_dev->mc_handle, + i, obj_desc); + if (error < 0) { + dev_err(&mc_bus_dev->dev, + "dprc_get_obj(i=%d) failed: %d\n", + i, error); + /* + * Mark the obj entry as "invalid", by using the + * empty string as obj type: + */ + obj_desc->type[0] = '\0'; + obj_desc->id = error; + dprc_get_obj_failures++; + continue; + } + + dev_dbg(&mc_bus_dev->dev, + "Discovered object: type %s, id %d\n", + obj_desc->type, obj_desc->id); + } + + if (dprc_get_obj_failures != 0) { + dev_err(&mc_bus_dev->dev, + "%d out of %d devices could not be retrieved\n", + dprc_get_obj_failures, num_child_objects); + } + } + + dprc_remove_devices(mc_bus_dev, child_obj_desc_array, + num_child_objects); + + dprc_add_new_devices(mc_bus_dev, child_obj_desc_array, + num_child_objects); + + if (child_obj_desc_array) + devm_kfree(&mc_bus_dev->dev, child_obj_desc_array); + + return 0; +} +EXPORT_SYMBOL_GPL(dprc_scan_objects); + +/** + * dprc_scan_container - Scans a physical DPRC and synchronizes Linux bus state + * + * @mc_bus_dev: pointer to the fsl-mc device that represents a DPRC object + * + * Scans the physical DPRC and synchronizes the state of the Linux + * bus driver with the actual state of the MC by adding and removing + * devices as appropriate. + */ +int dprc_scan_container(struct fsl_mc_device *mc_bus_dev) +{ + int error; + struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_bus_dev); + + /* + * Discover objects in the DPRC: + */ + mutex_lock(&mc_bus->scan_mutex); + error = dprc_scan_objects(mc_bus_dev); + mutex_unlock(&mc_bus->scan_mutex); + return error; +} +EXPORT_SYMBOL_GPL(dprc_scan_container); + +/** + * dprc_probe - callback invoked when a DPRC is being bound to this driver + * + * @mc_dev: Pointer to fsl-mc device representing a DPRC + * + * It opens the physical DPRC in the MC. + * It scans the DPRC to discover the MC objects contained in it. + */ +static int dprc_probe(struct fsl_mc_device *mc_dev) +{ + int error; + size_t region_size; + struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev); + + if (WARN_ON(strcmp(mc_dev->obj_desc.type, "dprc") != 0)) + return -EINVAL; + + if (!mc_dev->mc_io) { + /* + * This is a child DPRC: + */ + if (WARN_ON(mc_dev->obj_desc.region_count == 0)) + return -EINVAL; + + region_size = mc_dev->regions[0].end - + mc_dev->regions[0].start + 1; + + error = fsl_create_mc_io(&mc_dev->dev, + mc_dev->regions[0].start, + region_size, + 0, &mc_dev->mc_io); + if (error < 0) + return error; + } + + error = dprc_open(mc_dev->mc_io, mc_dev->obj_desc.id, + &mc_dev->mc_handle); + if (error < 0) { + dev_err(&mc_dev->dev, "dprc_open() failed: %d\n", error); + goto error_cleanup_mc_io; + } + + mutex_init(&mc_bus->scan_mutex); + + /* + * Discover MC objects in DPRC object: + */ + error = dprc_scan_container(mc_dev); + if (error < 0) + goto error_cleanup_open; + + dev_info(&mc_dev->dev, "DPRC device bound to driver"); + return 0; + +error_cleanup_open: + (void)dprc_close(mc_dev->mc_io, mc_dev->mc_handle); + +error_cleanup_mc_io: + fsl_destroy_mc_io(mc_dev->mc_io); + return error; +} + +/** + * dprc_remove - callback invoked when a DPRC is being unbound from this driver + * + * @mc_dev: Pointer to fsl-mc device representing the DPRC + * + * It removes the DPRC's child objects from Linux (not from the MC) and + * closes the DPRC device in the MC. + */ +static int dprc_remove(struct fsl_mc_device *mc_dev) +{ + int error; + + if (WARN_ON(strcmp(mc_dev->obj_desc.type, "dprc") != 0)) + return -EINVAL; + if (WARN_ON(!mc_dev->mc_io)) + return -EINVAL; + + device_for_each_child(&mc_dev->dev, NULL, __fsl_mc_device_remove); + error = dprc_close(mc_dev->mc_io, mc_dev->mc_handle); + if (error < 0) + dev_err(&mc_dev->dev, "dprc_close() failed: %d\n", error); + + dev_info(&mc_dev->dev, "DPRC device unbound from driver"); + return 0; +} + +static const struct fsl_mc_device_match_id match_id_table[] = { + { + .vendor = FSL_MC_VENDOR_FREESCALE, + .obj_type = "dprc", + .ver_major = DPRC_VER_MAJOR, + .ver_minor = DPRC_VER_MINOR}, + {.vendor = 0x0}, +}; + +static struct fsl_mc_driver dprc_driver = { + .driver = { + .name = FSL_MC_DPRC_DRIVER_NAME, + .owner = THIS_MODULE, + .pm = NULL, + }, + .match_id_table = match_id_table, + .probe = dprc_probe, + .remove = dprc_remove, +}; + +int __init dprc_driver_init(void) +{ + return fsl_mc_driver_register(&dprc_driver); +} + +void __exit dprc_driver_exit(void) +{ + fsl_mc_driver_unregister(&dprc_driver); +} diff --git a/drivers/staging/fsl-mc/bus/mc-bus.c b/drivers/staging/fsl-mc/bus/mc-bus.c index ce1de52bf030..72551e3c23b6 100644 --- a/drivers/staging/fsl-mc/bus/mc-bus.c +++ b/drivers/staging/fsl-mc/bus/mc-bus.c @@ -725,8 +725,15 @@ static int __init fsl_mc_bus_driver_init(void) goto error_cleanup_bus; } + error = dprc_driver_init(); + if (error < 0) + goto error_cleanup_driver; + return 0; +error_cleanup_driver: + platform_driver_unregister(&fsl_mc_bus_driver); + error_cleanup_bus: bus_unregister(&fsl_mc_bus_type); @@ -742,6 +749,7 @@ static void __exit fsl_mc_bus_driver_exit(void) if (WARN_ON(!mc_dev_cache)) return; + dprc_driver_exit(); platform_driver_unregister(&fsl_mc_bus_driver); bus_unregister(&fsl_mc_bus_type); kmem_cache_destroy(mc_dev_cache); diff --git a/drivers/staging/fsl-mc/include/mc-private.h b/drivers/staging/fsl-mc/include/mc-private.h index 5c957c452fdd..197544447404 100644 --- a/drivers/staging/fsl-mc/include/mc-private.h +++ b/drivers/staging/fsl-mc/include/mc-private.h @@ -15,6 +15,8 @@ #include #include +#define FSL_MC_DPRC_DRIVER_NAME "fsl_mc_dprc" + #define FSL_MC_DEVICE_MATCH(_mc_dev, _obj_desc) \ (strcmp((_mc_dev)->obj_desc.type, (_obj_desc)->type) == 0 && \ (_mc_dev)->obj_desc.id == (_obj_desc)->id) @@ -64,4 +66,12 @@ int __must_check fsl_mc_device_add(struct dprc_obj_desc *obj_desc, void fsl_mc_device_remove(struct fsl_mc_device *mc_dev); +int dprc_scan_container(struct fsl_mc_device *mc_bus_dev); + +int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev); + +int __init dprc_driver_init(void); + +void __exit dprc_driver_exit(void); + #endif /* _FSL_MC_PRIVATE_H_ */ -- GitLab From 197f4d6a4a00915b29fa7ec71f8010b9c763e676 Mon Sep 17 00:00:00 2001 From: "J. German Rivera" Date: Thu, 5 Mar 2015 19:35:25 -0600 Subject: [PATCH 03234/11651] staging: fsl-mc: fsl-mc object allocator driver The fsl-mc object allocator driver manages "allocatable" fsl-mc objects such as DPBPs, DPMCPs and DPCONs. It provides services to other fsl-mc drivers to allocate/deallocate these types of objects. Signed-off-by: J. German Rivera Signed-off-by: Stuart Yoder Acked-by: Alexander Graf Signed-off-by: Greg Kroah-Hartman --- drivers/staging/fsl-mc/bus/Makefile | 6 +- drivers/staging/fsl-mc/bus/dpbp.c | 358 ++++++++++++ drivers/staging/fsl-mc/bus/dpmcp-cmd.h | 136 +++++ drivers/staging/fsl-mc/bus/dpmcp.c | 308 +++++++++++ drivers/staging/fsl-mc/bus/dpmcp.h | 311 +++++++++++ drivers/staging/fsl-mc/bus/dprc-driver.c | 104 +++- drivers/staging/fsl-mc/bus/mc-allocator.c | 569 ++++++++++++++++++++ drivers/staging/fsl-mc/bus/mc-bus.c | 2 +- drivers/staging/fsl-mc/bus/mc-sys.c | 4 + drivers/staging/fsl-mc/include/dpbp-cmd.h | 60 +++ drivers/staging/fsl-mc/include/dpbp.h | 330 ++++++++++++ drivers/staging/fsl-mc/include/dpcon-cmd.h | 62 +++ drivers/staging/fsl-mc/include/mc-private.h | 61 ++- drivers/staging/fsl-mc/include/mc-sys.h | 6 + drivers/staging/fsl-mc/include/mc.h | 65 +++ 15 files changed, 2366 insertions(+), 16 deletions(-) create mode 100644 drivers/staging/fsl-mc/bus/dpbp.c create mode 100644 drivers/staging/fsl-mc/bus/dpmcp-cmd.h create mode 100644 drivers/staging/fsl-mc/bus/dpmcp.c create mode 100644 drivers/staging/fsl-mc/bus/dpmcp.h create mode 100644 drivers/staging/fsl-mc/bus/mc-allocator.c create mode 100644 drivers/staging/fsl-mc/include/dpbp-cmd.h create mode 100644 drivers/staging/fsl-mc/include/dpbp.h create mode 100644 drivers/staging/fsl-mc/include/dpcon-cmd.h diff --git a/drivers/staging/fsl-mc/bus/Makefile b/drivers/staging/fsl-mc/bus/Makefile index 424e58e1ea7e..bd09fc8cf650 100644 --- a/drivers/staging/fsl-mc/bus/Makefile +++ b/drivers/staging/fsl-mc/bus/Makefile @@ -5,7 +5,8 @@ # # This file is released under the GPLv2 # -obj-$(CONFIG_FSL_MC_BUS) += mc-bus-driver.o +obj-$(CONFIG_FSL_MC_BUS) += mc-bus-driver.o \ + mc-allocator-driver.o mc-bus-driver-objs := mc-bus.o \ mc-sys.o \ @@ -13,3 +14,6 @@ mc-bus-driver-objs := mc-bus.o \ dpmng.o \ dprc-driver.o +mc-allocator-driver-objs := mc-allocator.o \ + dpmcp.o \ + dpbp.o diff --git a/drivers/staging/fsl-mc/bus/dpbp.c b/drivers/staging/fsl-mc/bus/dpbp.c new file mode 100644 index 000000000000..d99ab6d0bbb1 --- /dev/null +++ b/drivers/staging/fsl-mc/bus/dpbp.c @@ -0,0 +1,358 @@ +/* Copyright 2013-2014 Freescale Semiconductor Inc. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of the above-listed copyright holders nor the +* names of any contributors may be used to endorse or promote products +* derived from this software without specific prior written permission. +* +* +* ALTERNATIVELY, this software may be distributed under the terms of the +* GNU General Public License ("GPL") as published by the Free Software +* Foundation, either version 2 of that License or (at your option) any +* later version. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ +#include "../include/mc-sys.h" +#include "../include/mc-cmd.h" +#include "../include/dpbp.h" +#include "../include/dpbp-cmd.h" + +int dpbp_open(struct fsl_mc_io *mc_io, int dpbp_id, uint16_t *token) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPBP_CMDID_OPEN, + MC_CMD_PRI_LOW, 0); + cmd.params[0] |= mc_enc(0, 32, dpbp_id); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + *token = MC_CMD_HDR_READ_TOKEN(cmd.header); + + return err; +} +EXPORT_SYMBOL(dpbp_open); + +int dpbp_close(struct fsl_mc_io *mc_io, uint16_t token) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPBP_CMDID_CLOSE, MC_CMD_PRI_HIGH, + token); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} +EXPORT_SYMBOL(dpbp_close); + +int dpbp_create(struct fsl_mc_io *mc_io, + const struct dpbp_cfg *cfg, + uint16_t *token) +{ + struct mc_command cmd = { 0 }; + int err; + + (void)(cfg); /* unused */ + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPBP_CMDID_CREATE, + MC_CMD_PRI_LOW, 0); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + *token = MC_CMD_HDR_READ_TOKEN(cmd.header); + + return 0; +} + +int dpbp_destroy(struct fsl_mc_io *mc_io, uint16_t token) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPBP_CMDID_DESTROY, + MC_CMD_PRI_LOW, token); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dpbp_enable(struct fsl_mc_io *mc_io, uint16_t token) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPBP_CMDID_ENABLE, MC_CMD_PRI_LOW, + token); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} +EXPORT_SYMBOL(dpbp_enable); + +int dpbp_disable(struct fsl_mc_io *mc_io, uint16_t token) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPBP_CMDID_DISABLE, + MC_CMD_PRI_LOW, token); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} +EXPORT_SYMBOL(dpbp_disable); + +int dpbp_is_enabled(struct fsl_mc_io *mc_io, uint16_t token, int *en) +{ + struct mc_command cmd = { 0 }; + int err; + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPBP_CMDID_IS_ENABLED, MC_CMD_PRI_LOW, + token); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + *en = (int)mc_dec(cmd.params[0], 0, 1); + + return 0; +} + +int dpbp_reset(struct fsl_mc_io *mc_io, uint16_t token) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPBP_CMDID_RESET, + MC_CMD_PRI_LOW, token); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dpbp_set_irq(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint64_t irq_paddr, + uint32_t irq_val, + int user_irq_id) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPBP_CMDID_SET_IRQ, + MC_CMD_PRI_LOW, token); + cmd.params[0] |= mc_enc(0, 8, irq_index); + cmd.params[0] |= mc_enc(32, 32, irq_val); + cmd.params[1] |= mc_enc(0, 64, irq_paddr); + cmd.params[2] |= mc_enc(0, 32, user_irq_id); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dpbp_get_irq(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + int *type, + uint64_t *irq_paddr, + uint32_t *irq_val, + int *user_irq_id) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPBP_CMDID_GET_IRQ, + MC_CMD_PRI_LOW, token); + cmd.params[0] |= mc_enc(32, 8, irq_index); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + *irq_val = (uint32_t)mc_dec(cmd.params[0], 0, 32); + *irq_paddr = (uint64_t)mc_dec(cmd.params[1], 0, 64); + *user_irq_id = (int)mc_dec(cmd.params[2], 0, 32); + *type = (int)mc_dec(cmd.params[2], 32, 32); + return 0; +} + +int dpbp_set_irq_enable(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint8_t en) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPBP_CMDID_SET_IRQ_ENABLE, + MC_CMD_PRI_LOW, token); + cmd.params[0] |= mc_enc(0, 8, en); + cmd.params[0] |= mc_enc(32, 8, irq_index); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dpbp_get_irq_enable(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint8_t *en) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPBP_CMDID_GET_IRQ_ENABLE, + MC_CMD_PRI_LOW, token); + cmd.params[0] |= mc_enc(32, 8, irq_index); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + *en = (uint8_t)mc_dec(cmd.params[0], 0, 8); + return 0; +} + +int dpbp_set_irq_mask(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint32_t mask) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPBP_CMDID_SET_IRQ_MASK, + MC_CMD_PRI_LOW, token); + cmd.params[0] |= mc_enc(0, 32, mask); + cmd.params[0] |= mc_enc(32, 8, irq_index); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dpbp_get_irq_mask(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint32_t *mask) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPBP_CMDID_GET_IRQ_MASK, + MC_CMD_PRI_LOW, token); + cmd.params[0] |= mc_enc(32, 8, irq_index); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + *mask = (uint32_t)mc_dec(cmd.params[0], 0, 32); + return 0; +} + +int dpbp_get_irq_status(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint32_t *status) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPBP_CMDID_GET_IRQ_STATUS, + MC_CMD_PRI_LOW, token); + cmd.params[0] |= mc_enc(32, 8, irq_index); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + *status = (uint32_t)mc_dec(cmd.params[0], 0, 32); + return 0; +} + +int dpbp_clear_irq_status(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint32_t status) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPBP_CMDID_CLEAR_IRQ_STATUS, + MC_CMD_PRI_LOW, token); + cmd.params[0] |= mc_enc(0, 32, status); + cmd.params[0] |= mc_enc(32, 8, irq_index); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dpbp_get_attributes(struct fsl_mc_io *mc_io, + uint16_t token, + struct dpbp_attr *attr) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPBP_CMDID_GET_ATTR, + MC_CMD_PRI_LOW, token); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + attr->bpid = (uint16_t)mc_dec(cmd.params[0], 16, 16); + attr->id = (int)mc_dec(cmd.params[0], 32, 32); + attr->version.major = (uint16_t)mc_dec(cmd.params[1], 0, 16); + attr->version.minor = (uint16_t)mc_dec(cmd.params[1], 16, 16); + return 0; +} +EXPORT_SYMBOL(dpbp_get_attributes); diff --git a/drivers/staging/fsl-mc/bus/dpmcp-cmd.h b/drivers/staging/fsl-mc/bus/dpmcp-cmd.h new file mode 100644 index 000000000000..57f326b60b76 --- /dev/null +++ b/drivers/staging/fsl-mc/bus/dpmcp-cmd.h @@ -0,0 +1,136 @@ +/* Copyright 2013-2015 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the above-listed copyright holders nor the + * names of any contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_DPMCP_CMD_H +#define _FSL_DPMCP_CMD_H + +/* DPMCP Version */ +#define DPMCP_VER_MAJOR 2 +#define DPMCP_VER_MINOR 0 + +/* Command IDs */ +#define DPMCP_CMDID_CLOSE 0x800 +#define DPMCP_CMDID_OPEN 0x80b +#define DPMCP_CMDID_CREATE 0x90b +#define DPMCP_CMDID_DESTROY 0x900 + +#define DPMCP_CMDID_GET_ATTR 0x004 +#define DPMCP_CMDID_RESET 0x005 + +#define DPMCP_CMDID_SET_IRQ 0x010 +#define DPMCP_CMDID_GET_IRQ 0x011 +#define DPMCP_CMDID_SET_IRQ_ENABLE 0x012 +#define DPMCP_CMDID_GET_IRQ_ENABLE 0x013 +#define DPMCP_CMDID_SET_IRQ_MASK 0x014 +#define DPMCP_CMDID_GET_IRQ_MASK 0x015 +#define DPMCP_CMDID_GET_IRQ_STATUS 0x016 +#define DPMCP_CMDID_CLEAR_IRQ_STATUS 0x017 + +/* cmd, param, offset, width, type, arg_name */ +#define DPMCP_CMD_CREATE(cmd, cfg) \ + MC_CMD_OP(cmd, 0, 0, 32, int, cfg->portal_id) + +/* cmd, param, offset, width, type, arg_name */ +#define DPMCP_CMD_SET_IRQ(cmd, irq_index, irq_addr, irq_val, user_irq_id) \ +do { \ + MC_CMD_OP(cmd, 0, 0, 8, uint8_t, irq_index);\ + MC_CMD_OP(cmd, 0, 32, 32, uint32_t, irq_val);\ + MC_CMD_OP(cmd, 1, 0, 64, uint64_t, irq_addr); \ + MC_CMD_OP(cmd, 2, 0, 32, int, user_irq_id); \ +} while (0) + +/* cmd, param, offset, width, type, arg_name */ +#define DPMCP_CMD_GET_IRQ(cmd, irq_index) \ + MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index) + +/* cmd, param, offset, width, type, arg_name */ +#define DPMCP_RSP_GET_IRQ(cmd, type, irq_addr, irq_val, user_irq_id) \ +do { \ + MC_RSP_OP(cmd, 0, 0, 32, uint32_t, irq_val); \ + MC_RSP_OP(cmd, 1, 0, 64, uint64_t, irq_addr); \ + MC_RSP_OP(cmd, 2, 0, 32, int, user_irq_id); \ + MC_RSP_OP(cmd, 2, 32, 32, int, type); \ +} while (0) + +/* cmd, param, offset, width, type, arg_name */ +#define DPMCP_CMD_SET_IRQ_ENABLE(cmd, irq_index, en) \ +do { \ + MC_CMD_OP(cmd, 0, 0, 8, uint8_t, en); \ + MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index);\ +} while (0) + +/* cmd, param, offset, width, type, arg_name */ +#define DPMCP_CMD_GET_IRQ_ENABLE(cmd, irq_index) \ + MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index) + +/* cmd, param, offset, width, type, arg_name */ +#define DPMCP_RSP_GET_IRQ_ENABLE(cmd, en) \ + MC_RSP_OP(cmd, 0, 0, 8, uint8_t, en) + +/* cmd, param, offset, width, type, arg_name */ +#define DPMCP_CMD_SET_IRQ_MASK(cmd, irq_index, mask) \ +do { \ + MC_CMD_OP(cmd, 0, 0, 32, uint32_t, mask);\ + MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index);\ +} while (0) + +/* cmd, param, offset, width, type, arg_name */ +#define DPMCP_CMD_GET_IRQ_MASK(cmd, irq_index) \ + MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index) + +/* cmd, param, offset, width, type, arg_name */ +#define DPMCP_RSP_GET_IRQ_MASK(cmd, mask) \ + MC_RSP_OP(cmd, 0, 0, 32, uint32_t, mask) + +/* cmd, param, offset, width, type, arg_name */ +#define DPMCP_CMD_GET_IRQ_STATUS(cmd, irq_index) \ + MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index) + +/* cmd, param, offset, width, type, arg_name */ +#define DPMCP_RSP_GET_IRQ_STATUS(cmd, status) \ + MC_RSP_OP(cmd, 0, 0, 32, uint32_t, status) + +/* cmd, param, offset, width, type, arg_name */ +#define DPMCP_CMD_CLEAR_IRQ_STATUS(cmd, irq_index, status) \ +do { \ + MC_CMD_OP(cmd, 0, 0, 32, uint32_t, status); \ + MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index);\ +} while (0) + +/* cmd, param, offset, width, type, arg_name */ +#define DPMCP_RSP_GET_ATTRIBUTES(cmd, attr) \ +do { \ + MC_RSP_OP(cmd, 0, 32, 32, int, attr->id);\ + MC_RSP_OP(cmd, 1, 0, 16, uint16_t, attr->version.major);\ + MC_RSP_OP(cmd, 1, 16, 16, uint16_t, attr->version.minor);\ +} while (0) + +#endif /* _FSL_DPMCP_CMD_H */ diff --git a/drivers/staging/fsl-mc/bus/dpmcp.c b/drivers/staging/fsl-mc/bus/dpmcp.c new file mode 100644 index 000000000000..6b9da5b7fd00 --- /dev/null +++ b/drivers/staging/fsl-mc/bus/dpmcp.c @@ -0,0 +1,308 @@ +/* Copyright 2013-2015 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the above-listed copyright holders nor the + * names of any contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include "../include/mc-sys.h" +#include "../include/mc-cmd.h" +#include "dpmcp.h" +#include "dpmcp-cmd.h" + +int dpmcp_open(struct fsl_mc_io *mc_io, int dpmcp_id, uint16_t *token) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPMCP_CMDID_OPEN, + MC_CMD_PRI_LOW, 0); + cmd.params[0] |= mc_enc(0, 32, dpmcp_id); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + *token = MC_CMD_HDR_READ_TOKEN(cmd.header); + + return err; +} + +int dpmcp_close(struct fsl_mc_io *mc_io, uint16_t token) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPMCP_CMDID_CLOSE, MC_CMD_PRI_HIGH, + token); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dpmcp_create(struct fsl_mc_io *mc_io, + const struct dpmcp_cfg *cfg, + uint16_t *token) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPMCP_CMDID_CREATE, + MC_CMD_PRI_LOW, 0); + cmd.params[0] |= mc_enc(0, 32, cfg->portal_id); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + *token = MC_CMD_HDR_READ_TOKEN(cmd.header); + + return 0; +} + +int dpmcp_destroy(struct fsl_mc_io *mc_io, uint16_t token) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPMCP_CMDID_DESTROY, + MC_CMD_PRI_LOW, token); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dpmcp_reset(struct fsl_mc_io *mc_io, uint16_t token) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPMCP_CMDID_RESET, + MC_CMD_PRI_LOW, token); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dpmcp_set_irq(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint64_t irq_addr, + uint32_t irq_val, + int user_irq_id) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPMCP_CMDID_SET_IRQ, + MC_CMD_PRI_LOW, token); + cmd.params[0] |= mc_enc(0, 8, irq_index); + cmd.params[0] |= mc_enc(32, 32, irq_val); + cmd.params[1] |= mc_enc(0, 64, irq_addr); + cmd.params[2] |= mc_enc(0, 32, user_irq_id); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dpmcp_get_irq(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + int *type, + uint64_t *irq_addr, + uint32_t *irq_val, + int *user_irq_id) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPMCP_CMDID_GET_IRQ, + MC_CMD_PRI_LOW, token); + cmd.params[0] |= mc_enc(32, 8, irq_index); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + *irq_val = (uint32_t)mc_dec(cmd.params[0], 0, 32); + *irq_addr = (uint64_t)mc_dec(cmd.params[1], 0, 64); + *user_irq_id = (int)mc_dec(cmd.params[2], 0, 32); + *type = (int)mc_dec(cmd.params[2], 32, 32); + return 0; +} + +int dpmcp_set_irq_enable(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint8_t en) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPMCP_CMDID_SET_IRQ_ENABLE, + MC_CMD_PRI_LOW, token); + cmd.params[0] |= mc_enc(0, 8, en); + cmd.params[0] |= mc_enc(32, 8, irq_index); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dpmcp_get_irq_enable(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint8_t *en) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPMCP_CMDID_GET_IRQ_ENABLE, + MC_CMD_PRI_LOW, token); + cmd.params[0] |= mc_enc(32, 8, irq_index); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + *en = (uint8_t)mc_dec(cmd.params[0], 0, 8); + return 0; +} + +int dpmcp_set_irq_mask(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint32_t mask) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPMCP_CMDID_SET_IRQ_MASK, + MC_CMD_PRI_LOW, token); + cmd.params[0] |= mc_enc(0, 32, mask); + cmd.params[0] |= mc_enc(32, 8, irq_index); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dpmcp_get_irq_mask(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint32_t *mask) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPMCP_CMDID_GET_IRQ_MASK, + MC_CMD_PRI_LOW, token); + cmd.params[0] |= mc_enc(32, 8, irq_index); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + *mask = (uint32_t)mc_dec(cmd.params[0], 0, 32); + return 0; +} + +int dpmcp_get_irq_status(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint32_t *status) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPMCP_CMDID_GET_IRQ_STATUS, + MC_CMD_PRI_LOW, token); + cmd.params[0] |= mc_enc(32, 8, irq_index); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + *status = (uint32_t)mc_dec(cmd.params[0], 0, 32); + return 0; +} + +int dpmcp_clear_irq_status(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint32_t status) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPMCP_CMDID_CLEAR_IRQ_STATUS, + MC_CMD_PRI_LOW, token); + cmd.params[0] |= mc_enc(0, 32, status); + cmd.params[0] |= mc_enc(32, 8, irq_index); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dpmcp_get_attributes(struct fsl_mc_io *mc_io, + uint16_t token, + struct dpmcp_attr *attr) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPMCP_CMDID_GET_ATTR, + MC_CMD_PRI_LOW, token); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + attr->id = (int)mc_dec(cmd.params[0], 32, 32); + attr->version.major = (uint16_t)mc_dec(cmd.params[1], 0, 16); + attr->version.minor = (uint16_t)mc_dec(cmd.params[1], 16, 16); + return 0; +} diff --git a/drivers/staging/fsl-mc/bus/dpmcp.h b/drivers/staging/fsl-mc/bus/dpmcp.h new file mode 100644 index 000000000000..5e7c21952ce5 --- /dev/null +++ b/drivers/staging/fsl-mc/bus/dpmcp.h @@ -0,0 +1,311 @@ +/* Copyright 2013-2015 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the above-listed copyright holders nor the + * names of any contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef __FSL_DPMCP_H +#define __FSL_DPMCP_H + +/* Data Path Management Command Portal API + * Contains initialization APIs and runtime control APIs for DPMCP + */ + +struct fsl_mc_io; + +/** + * dpmcp_open() - Open a control session for the specified object. + * @mc_io: Pointer to MC portal's I/O object + * @dpmcp_id: DPMCP unique ID + * @token: Returned token; use in subsequent API calls + * + * This function can be used to open a control session for an + * already created object; an object may have been declared in + * the DPL or by calling the dpmcp_create function. + * This function returns a unique authentication token, + * associated with the specific object ID and the specific MC + * portal; this token must be used in all subsequent commands for + * this specific object + * + * Return: '0' on Success; Error code otherwise. + */ +int dpmcp_open(struct fsl_mc_io *mc_io, int dpmcp_id, uint16_t *token); + +/* Get portal ID from pool */ +#define DPMCP_GET_PORTAL_ID_FROM_POOL (-1) + +/** + * dpmcp_close() - Close the control session of the object + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPMCP object + * + * After this function is called, no further operations are + * allowed on the object without opening a new control session. + * + * Return: '0' on Success; Error code otherwise. + */ +int dpmcp_close(struct fsl_mc_io *mc_io, uint16_t token); + +/** + * struct dpmcp_cfg() - Structure representing DPMCP configuration + * @portal_id: Portal ID; 'DPMCP_GET_PORTAL_ID_FROM_POOL' to get the portal ID + * from pool + */ +struct dpmcp_cfg { + int portal_id; +}; + +/** + * dpmcp_create() - Create the DPMCP object. + * @mc_io: Pointer to MC portal's I/O object + * @cfg: Configuration structure + * @token: Returned token; use in subsequent API calls + * + * Create the DPMCP object, allocate required resources and + * perform required initialization. + * + * The object can be created either by declaring it in the + * DPL file, or by calling this function. + * This function returns a unique authentication token, + * associated with the specific object ID and the specific MC + * portal; this token must be used in all subsequent calls to + * this specific object. For objects that are created using the + * DPL file, call dpmcp_open function to get an authentication + * token first. + * + * Return: '0' on Success; Error code otherwise. + */ +int dpmcp_create(struct fsl_mc_io *mc_io, + const struct dpmcp_cfg *cfg, + uint16_t *token); + +/** + * dpmcp_destroy() - Destroy the DPMCP object and release all its resources. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPMCP object + * + * Return: '0' on Success; error code otherwise. + */ +int dpmcp_destroy(struct fsl_mc_io *mc_io, uint16_t token); + +/** + * dpmcp_reset() - Reset the DPMCP, returns the object to initial state. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPMCP object + * + * Return: '0' on Success; Error code otherwise. + */ +int dpmcp_reset(struct fsl_mc_io *mc_io, uint16_t token); + +/* IRQ */ +/*! + * @name dpmcp IRQ Index and Events + */ +#define DPMCP_IRQ_INDEX 0 +/*!< Irq index */ +#define DPMCP_IRQ_EVENT_CMD_DONE 0x00000001 +/*!< irq event - Indicates that the link state changed */ +/* @} */ + +/** + * dpmcp_set_irq() - Set IRQ information for the DPMCP to trigger an interrupt. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPMCP object + * @irq_index: Identifies the interrupt index to configure + * @irq_addr: Address that must be written to + * signal a message-based interrupt + * @irq_val: Value to write into irq_addr address + * @user_irq_id: A user defined number associated with this IRQ + * + * Return: '0' on Success; Error code otherwise. + */ +int dpmcp_set_irq(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint64_t irq_addr, + uint32_t irq_val, + int user_irq_id); + +/** + * dpmcp_get_irq() - Get IRQ information from the DPMCP. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPMCP object + * @irq_index: The interrupt index to configure + * @type: Interrupt type: 0 represents message interrupt + * type (both irq_addr and irq_val are valid) + * @irq_addr: Returned address that must be written to + * signal the message-based interrupt + * @irq_val: Value to write into irq_addr address + * @user_irq_id: A user defined number associated with this IRQ + * + * Return: '0' on Success; Error code otherwise. + */ +int dpmcp_get_irq(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + int *type, + uint64_t *irq_addr, + uint32_t *irq_val, + int *user_irq_id); + +/** + * dpmcp_set_irq_enable() - Set overall interrupt state. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPMCP object + * @irq_index: The interrupt index to configure + * @en: Interrupt state - enable = 1, disable = 0 + * + * Allows GPP software to control when interrupts are generated. + * Each interrupt can have up to 32 causes. The enable/disable control's the + * overall interrupt state. if the interrupt is disabled no causes will cause + * an interrupt. + * + * Return: '0' on Success; Error code otherwise. + */ +int dpmcp_set_irq_enable(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint8_t en); + +/** + * dpmcp_get_irq_enable() - Get overall interrupt state + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPMCP object + * @irq_index: The interrupt index to configure + * @en: Returned interrupt state - enable = 1, disable = 0 + * + * Return: '0' on Success; Error code otherwise. + */ +int dpmcp_get_irq_enable(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint8_t *en); + +/** + * dpmcp_set_irq_mask() - Set interrupt mask. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPMCP object + * @irq_index: The interrupt index to configure + * @mask: Event mask to trigger interrupt; + * each bit: + * 0 = ignore event + * 1 = consider event for asserting IRQ + * + * Every interrupt can have up to 32 causes and the interrupt model supports + * masking/unmasking each cause independently + * + * Return: '0' on Success; Error code otherwise. + */ +int dpmcp_set_irq_mask(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint32_t mask); + +/** + * dpmcp_get_irq_mask() - Get interrupt mask. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPMCP object + * @irq_index: The interrupt index to configure + * @mask: Returned event mask to trigger interrupt + * + * Every interrupt can have up to 32 causes and the interrupt model supports + * masking/unmasking each cause independently + * + * Return: '0' on Success; Error code otherwise. + */ +int dpmcp_get_irq_mask(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint32_t *mask); + +/** + * dpmcp_get_irq_status() - Get the current status of any pending interrupts. + * + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPMCP object + * @irq_index: The interrupt index to configure + * @status: Returned interrupts status - one bit per cause: + * 0 = no interrupt pending + * 1 = interrupt pending + * + * Return: '0' on Success; Error code otherwise. + */ +int dpmcp_get_irq_status(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint32_t *status); + +/** + * dpmcp_clear_irq_status() - Clear a pending interrupt's status + * + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPMCP object + * @irq_index: The interrupt index to configure + * @status: Bits to clear (W1C) - one bit per cause: + * 0 = don't change + * 1 = clear status bit + * + * Return: '0' on Success; Error code otherwise. + */ +int dpmcp_clear_irq_status(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint32_t status); + +/** + * struct dpmcp_attr - Structure representing DPMCP attributes + * @id: DPMCP object ID + * @version: DPMCP version + */ +struct dpmcp_attr { + int id; + /** + * struct version - Structure representing DPMCP version + * @major: DPMCP major version + * @minor: DPMCP minor version + */ + struct { + uint16_t major; + uint16_t minor; + } version; +}; + +/** + * dpmcp_get_attributes - Retrieve DPMCP attributes. + * + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPMCP object + * @attr: Returned object's attributes + * + * Return: '0' on Success; Error code otherwise. + */ +int dpmcp_get_attributes(struct fsl_mc_io *mc_io, + uint16_t token, + struct dpmcp_attr *attr); + +#endif /* __FSL_DPMCP_H */ diff --git a/drivers/staging/fsl-mc/bus/dprc-driver.c b/drivers/staging/fsl-mc/bus/dprc-driver.c index f5d1deb77c95..65de1d758a56 100644 --- a/drivers/staging/fsl-mc/bus/dprc-driver.c +++ b/drivers/staging/fsl-mc/bus/dprc-driver.c @@ -156,6 +156,85 @@ static void dprc_add_new_devices(struct fsl_mc_device *mc_bus_dev, } } +static void dprc_init_all_resource_pools(struct fsl_mc_device *mc_bus_dev) +{ + int pool_type; + struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_bus_dev); + + for (pool_type = 0; pool_type < FSL_MC_NUM_POOL_TYPES; pool_type++) { + struct fsl_mc_resource_pool *res_pool = + &mc_bus->resource_pools[pool_type]; + + res_pool->type = pool_type; + res_pool->max_count = 0; + res_pool->free_count = 0; + res_pool->mc_bus = mc_bus; + INIT_LIST_HEAD(&res_pool->free_list); + mutex_init(&res_pool->mutex); + } +} + +static void dprc_cleanup_resource_pool(struct fsl_mc_device *mc_bus_dev, + enum fsl_mc_pool_type pool_type) +{ + struct fsl_mc_resource *resource; + struct fsl_mc_resource *next; + struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_bus_dev); + struct fsl_mc_resource_pool *res_pool = + &mc_bus->resource_pools[pool_type]; + int free_count = 0; + + WARN_ON(res_pool->type != pool_type); + WARN_ON(res_pool->free_count != res_pool->max_count); + + list_for_each_entry_safe(resource, next, &res_pool->free_list, node) { + free_count++; + WARN_ON(resource->type != res_pool->type); + WARN_ON(resource->parent_pool != res_pool); + devm_kfree(&mc_bus_dev->dev, resource); + } + + WARN_ON(free_count != res_pool->free_count); +} + +static void dprc_cleanup_all_resource_pools(struct fsl_mc_device *mc_bus_dev) +{ + int pool_type; + + for (pool_type = 0; pool_type < FSL_MC_NUM_POOL_TYPES; pool_type++) + dprc_cleanup_resource_pool(mc_bus_dev, pool_type); +} + +static void reorder_obj_desc_array(struct dprc_obj_desc *obj_desc_array, + int num_devs) +{ + struct dprc_obj_desc tmp; + struct dprc_obj_desc *top_cursor = &obj_desc_array[0]; + struct dprc_obj_desc *bottom_cursor = &obj_desc_array[num_devs - 1]; + + /* + * Reorder entries in obj_desc_array so that all allocatable devices + * are placed before all non-allocatable devices: + * + * Loop Invariant: everything before top_cursor is allocatable and + * everything after bottom_cursor is non-allocatable. + */ + while (top_cursor < bottom_cursor) { + if (FSL_MC_IS_ALLOCATABLE(top_cursor->type)) { + top_cursor++; + } else { + if (FSL_MC_IS_ALLOCATABLE(bottom_cursor->type)) { + tmp = *bottom_cursor; + *bottom_cursor = *top_cursor; + *top_cursor = tmp; + top_cursor++; + } + + bottom_cursor--; + } + } +} + /** * dprc_scan_objects - Discover objects in a DPRC * @@ -164,6 +243,14 @@ static void dprc_add_new_devices(struct fsl_mc_device *mc_bus_dev, * Detects objects added and removed from a DPRC and synchronizes the * state of the Linux bus driver, MC by adding and removing * devices accordingly. + * Two types of devices can be found in a DPRC: allocatable objects (e.g., + * dpbp, dpmcp) and non-allocatable devices (e.g., dprc, dpni). + * All allocatable devices needed to be probed before all non-allocatable + * devices, to ensure that device drivers for non-allocatable + * devices can allocate any type of allocatable devices. + * That is, we need to ensure that the corresponding resource pools are + * populated before they can get allocation requests from probe callbacks + * of the device drivers for the non-allocatable devices. */ int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev) { @@ -226,6 +313,8 @@ int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev) "%d out of %d devices could not be retrieved\n", dprc_get_obj_failures, num_child_objects); } + + reorder_obj_desc_array(child_obj_desc_array, num_child_objects); } dprc_remove_devices(mc_bus_dev, child_obj_desc_array, @@ -255,12 +344,20 @@ int dprc_scan_container(struct fsl_mc_device *mc_bus_dev) int error; struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_bus_dev); + dprc_init_all_resource_pools(mc_bus_dev); + /* * Discover objects in the DPRC: */ mutex_lock(&mc_bus->scan_mutex); error = dprc_scan_objects(mc_bus_dev); mutex_unlock(&mc_bus->scan_mutex); + if (error < 0) + goto error; + + return 0; +error: + dprc_cleanup_all_resource_pools(mc_bus_dev); return error; } EXPORT_SYMBOL_GPL(dprc_scan_container); @@ -272,6 +369,8 @@ EXPORT_SYMBOL_GPL(dprc_scan_container); * * It opens the physical DPRC in the MC. * It scans the DPRC to discover the MC objects contained in it. + * It creates the interrupt pool for the MC bus associated with the DPRC. + * It configures the interrupts for the DPRC device itself. */ static int dprc_probe(struct fsl_mc_device *mc_dev) { @@ -295,7 +394,7 @@ static int dprc_probe(struct fsl_mc_device *mc_dev) error = fsl_create_mc_io(&mc_dev->dev, mc_dev->regions[0].start, region_size, - 0, &mc_dev->mc_io); + NULL, 0, &mc_dev->mc_io); if (error < 0) return error; } @@ -334,6 +433,8 @@ error_cleanup_mc_io: * * It removes the DPRC's child objects from Linux (not from the MC) and * closes the DPRC device in the MC. + * It tears down the interrupts that were configured for the DPRC device. + * It destroys the interrupt pool associated with this MC bus. */ static int dprc_remove(struct fsl_mc_device *mc_dev) { @@ -345,6 +446,7 @@ static int dprc_remove(struct fsl_mc_device *mc_dev) return -EINVAL; device_for_each_child(&mc_dev->dev, NULL, __fsl_mc_device_remove); + dprc_cleanup_all_resource_pools(mc_dev); error = dprc_close(mc_dev->mc_io, mc_dev->mc_handle); if (error < 0) dev_err(&mc_dev->dev, "dprc_close() failed: %d\n", error); diff --git a/drivers/staging/fsl-mc/bus/mc-allocator.c b/drivers/staging/fsl-mc/bus/mc-allocator.c new file mode 100644 index 000000000000..cc4a7d316990 --- /dev/null +++ b/drivers/staging/fsl-mc/bus/mc-allocator.c @@ -0,0 +1,569 @@ +/* + * Freescale MC object device allocator driver + * + * Copyright (C) 2013 Freescale Semiconductor, Inc. + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include "../include/mc-private.h" +#include "../include/mc-sys.h" +#include +#include "../include/dpbp-cmd.h" +#include "../include/dpcon-cmd.h" +#include "dpmcp-cmd.h" +#include "dpmcp.h" + +/** + * fsl_mc_resource_pool_add_device - add allocatable device to a resource + * pool of a given MC bus + * + * @mc_bus: pointer to the MC bus + * @pool_type: MC bus pool type + * @mc_dev: Pointer to allocatable MC object device + * + * It adds an allocatable MC object device to a container's resource pool of + * the given resource type + */ +static int __must_check fsl_mc_resource_pool_add_device(struct fsl_mc_bus + *mc_bus, + enum fsl_mc_pool_type + pool_type, + struct fsl_mc_device + *mc_dev) +{ + struct fsl_mc_resource_pool *res_pool; + struct fsl_mc_resource *resource; + struct fsl_mc_device *mc_bus_dev = &mc_bus->mc_dev; + int error = -EINVAL; + bool mutex_locked = false; + + if (WARN_ON(pool_type < 0 || pool_type >= FSL_MC_NUM_POOL_TYPES)) + goto out; + if (WARN_ON(!FSL_MC_IS_ALLOCATABLE(mc_dev->obj_desc.type))) + goto out; + if (WARN_ON(mc_dev->resource)) + goto out; + + res_pool = &mc_bus->resource_pools[pool_type]; + if (WARN_ON(res_pool->type != pool_type)) + goto out; + if (WARN_ON(res_pool->mc_bus != mc_bus)) + goto out; + + mutex_lock(&res_pool->mutex); + mutex_locked = true; + + if (WARN_ON(res_pool->max_count < 0)) + goto out; + if (WARN_ON(res_pool->free_count < 0 || + res_pool->free_count > res_pool->max_count)) + goto out; + + resource = devm_kzalloc(&mc_bus_dev->dev, sizeof(*resource), + GFP_KERNEL); + if (!resource) { + error = -ENOMEM; + dev_err(&mc_bus_dev->dev, + "Failed to allocate memory for fsl_mc_resource\n"); + goto out; + } + + resource->type = pool_type; + resource->id = mc_dev->obj_desc.id; + resource->data = mc_dev; + resource->parent_pool = res_pool; + INIT_LIST_HEAD(&resource->node); + list_add_tail(&resource->node, &res_pool->free_list); + mc_dev->resource = resource; + res_pool->free_count++; + res_pool->max_count++; + error = 0; +out: + if (mutex_locked) + mutex_unlock(&res_pool->mutex); + + return error; +} + +/** + * fsl_mc_resource_pool_remove_device - remove an allocatable device from a + * resource pool + * + * @mc_dev: Pointer to allocatable MC object device + * + * It permanently removes an allocatable MC object device from the resource + * pool, the device is currently in, as long as it is in the pool's free list. + */ +static int __must_check fsl_mc_resource_pool_remove_device(struct fsl_mc_device + *mc_dev) +{ + struct fsl_mc_device *mc_bus_dev; + struct fsl_mc_bus *mc_bus; + struct fsl_mc_resource_pool *res_pool; + struct fsl_mc_resource *resource; + int error = -EINVAL; + bool mutex_locked = false; + + if (WARN_ON(!FSL_MC_IS_ALLOCATABLE(mc_dev->obj_desc.type))) + goto out; + + resource = mc_dev->resource; + if (WARN_ON(resource->data != mc_dev)) + goto out; + + mc_bus_dev = to_fsl_mc_device(mc_dev->dev.parent); + mc_bus = to_fsl_mc_bus(mc_bus_dev); + res_pool = resource->parent_pool; + if (WARN_ON(res_pool != &mc_bus->resource_pools[resource->type])) + goto out; + + mutex_lock(&res_pool->mutex); + mutex_locked = true; + + if (WARN_ON(res_pool->max_count <= 0)) + goto out; + if (WARN_ON(res_pool->free_count <= 0 || + res_pool->free_count > res_pool->max_count)) + goto out; + + /* + * If the device is currently allocated, its resource is not + * in the free list and thus, the device cannot be removed. + */ + if (list_empty(&resource->node)) { + error = -EBUSY; + dev_err(&mc_bus_dev->dev, + "Device %s cannot be removed from resource pool\n", + dev_name(&mc_dev->dev)); + goto out; + } + + list_del(&resource->node); + INIT_LIST_HEAD(&resource->node); + res_pool->free_count--; + res_pool->max_count--; + + devm_kfree(&mc_bus_dev->dev, resource); + mc_dev->resource = NULL; + error = 0; +out: + if (mutex_locked) + mutex_unlock(&res_pool->mutex); + + return error; +} + +static const char *const fsl_mc_pool_type_strings[] = { + [FSL_MC_POOL_DPMCP] = "dpmcp", + [FSL_MC_POOL_DPBP] = "dpbp", + [FSL_MC_POOL_DPCON] = "dpcon", +}; + +static int __must_check object_type_to_pool_type(const char *object_type, + enum fsl_mc_pool_type + *pool_type) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(fsl_mc_pool_type_strings); i++) { + if (strcmp(object_type, fsl_mc_pool_type_strings[i]) == 0) { + *pool_type = i; + return 0; + } + } + + return -EINVAL; +} + +int __must_check fsl_mc_resource_allocate(struct fsl_mc_bus *mc_bus, + enum fsl_mc_pool_type pool_type, + struct fsl_mc_resource **new_resource) +{ + struct fsl_mc_resource_pool *res_pool; + struct fsl_mc_resource *resource; + struct fsl_mc_device *mc_bus_dev = &mc_bus->mc_dev; + int error = -EINVAL; + bool mutex_locked = false; + + BUILD_BUG_ON(ARRAY_SIZE(fsl_mc_pool_type_strings) != + FSL_MC_NUM_POOL_TYPES); + + *new_resource = NULL; + if (WARN_ON(pool_type < 0 || pool_type >= FSL_MC_NUM_POOL_TYPES)) + goto error; + + res_pool = &mc_bus->resource_pools[pool_type]; + if (WARN_ON(res_pool->mc_bus != mc_bus)) + goto error; + + mutex_lock(&res_pool->mutex); + mutex_locked = true; + resource = list_first_entry_or_null(&res_pool->free_list, + struct fsl_mc_resource, node); + + if (!resource) { + WARN_ON(res_pool->free_count != 0); + error = -ENXIO; + dev_err(&mc_bus_dev->dev, + "No more resources of type %s left\n", + fsl_mc_pool_type_strings[pool_type]); + goto error; + } + + if (WARN_ON(resource->type != pool_type)) + goto error; + if (WARN_ON(resource->parent_pool != res_pool)) + goto error; + if (WARN_ON(res_pool->free_count <= 0 || + res_pool->free_count > res_pool->max_count)) + goto error; + + list_del(&resource->node); + INIT_LIST_HEAD(&resource->node); + + res_pool->free_count--; + mutex_unlock(&res_pool->mutex); + *new_resource = resource; + return 0; +error: + if (mutex_locked) + mutex_unlock(&res_pool->mutex); + + return error; +} +EXPORT_SYMBOL_GPL(fsl_mc_resource_allocate); + +void fsl_mc_resource_free(struct fsl_mc_resource *resource) +{ + struct fsl_mc_resource_pool *res_pool; + bool mutex_locked = false; + + res_pool = resource->parent_pool; + if (WARN_ON(resource->type != res_pool->type)) + goto out; + + mutex_lock(&res_pool->mutex); + mutex_locked = true; + if (WARN_ON(res_pool->free_count < 0 || + res_pool->free_count >= res_pool->max_count)) + goto out; + + if (WARN_ON(!list_empty(&resource->node))) + goto out; + + list_add_tail(&resource->node, &res_pool->free_list); + res_pool->free_count++; +out: + if (mutex_locked) + mutex_unlock(&res_pool->mutex); +} +EXPORT_SYMBOL_GPL(fsl_mc_resource_free); + +/** + * fsl_mc_portal_allocate - Allocates an MC portal + * + * @mc_dev: MC device for which the MC portal is to be allocated + * @mc_io_flags: Flags for the fsl_mc_io object that wraps the allocated + * MC portal. + * @new_mc_io: Pointer to area where the pointer to the fsl_mc_io object + * that wraps the allocated MC portal is to be returned + * + * This function allocates an MC portal from the device's parent DPRC, + * from the corresponding MC bus' pool of MC portals and wraps + * it in a new fsl_mc_io object. If 'mc_dev' is a DPRC itself, the + * portal is allocated from its own MC bus. + */ +int __must_check fsl_mc_portal_allocate(struct fsl_mc_device *mc_dev, + uint16_t mc_io_flags, + struct fsl_mc_io **new_mc_io) +{ + struct fsl_mc_device *mc_bus_dev; + struct fsl_mc_bus *mc_bus; + phys_addr_t mc_portal_phys_addr; + size_t mc_portal_size; + struct fsl_mc_device *mc_adev; + int error = -EINVAL; + struct fsl_mc_resource *resource = NULL; + struct fsl_mc_io *mc_io = NULL; + + if (mc_dev->flags & FSL_MC_IS_DPRC) { + mc_bus_dev = mc_dev; + } else { + if (WARN_ON(mc_dev->dev.parent->bus != &fsl_mc_bus_type)) + return error; + + mc_bus_dev = to_fsl_mc_device(mc_dev->dev.parent); + } + + mc_bus = to_fsl_mc_bus(mc_bus_dev); + *new_mc_io = NULL; + error = fsl_mc_resource_allocate(mc_bus, FSL_MC_POOL_DPMCP, &resource); + if (error < 0) + return error; + + mc_adev = resource->data; + if (WARN_ON(!mc_adev)) + goto error_cleanup_resource; + + if (WARN_ON(mc_adev->obj_desc.region_count == 0)) + goto error_cleanup_resource; + + mc_portal_phys_addr = mc_adev->regions[0].start; + mc_portal_size = mc_adev->regions[0].end - + mc_adev->regions[0].start + 1; + + if (WARN_ON(mc_portal_size != mc_bus_dev->mc_io->portal_size)) + goto error_cleanup_resource; + + error = fsl_create_mc_io(&mc_bus_dev->dev, + mc_portal_phys_addr, + mc_portal_size, resource, + mc_io_flags, &mc_io); + if (error < 0) + goto error_cleanup_resource; + + *new_mc_io = mc_io; + return 0; + +error_cleanup_resource: + fsl_mc_resource_free(resource); + return error; +} +EXPORT_SYMBOL_GPL(fsl_mc_portal_allocate); + +/** + * fsl_mc_portal_free - Returns an MC portal to the pool of free MC portals + * of a given MC bus + * + * @mc_io: Pointer to the fsl_mc_io object that wraps the MC portal to free + */ +void fsl_mc_portal_free(struct fsl_mc_io *mc_io) +{ + struct fsl_mc_resource *resource; + + resource = mc_io->resource; + if (WARN_ON(resource->type != FSL_MC_POOL_DPMCP)) + return; + if (WARN_ON(!resource->data)) + return; + + fsl_destroy_mc_io(mc_io); + fsl_mc_resource_free(resource); +} +EXPORT_SYMBOL_GPL(fsl_mc_portal_free); + +/** + * fsl_mc_portal_reset - Resets the dpmcp object for a given fsl_mc_io object + * + * @mc_io: Pointer to the fsl_mc_io object that wraps the MC portal to free + */ +int fsl_mc_portal_reset(struct fsl_mc_io *mc_io) +{ + int error; + uint16_t token; + struct fsl_mc_resource *resource = mc_io->resource; + struct fsl_mc_device *mc_dev = resource->data; + + if (WARN_ON(resource->type != FSL_MC_POOL_DPMCP)) + return -EINVAL; + + if (WARN_ON(!mc_dev)) + return -EINVAL; + + error = dpmcp_open(mc_io, mc_dev->obj_desc.id, &token); + if (error < 0) { + dev_err(&mc_dev->dev, "dpmcp_open() failed: %d\n", error); + return error; + } + + error = dpmcp_reset(mc_io, token); + if (error < 0) { + dev_err(&mc_dev->dev, "dpmcp_reset() failed: %d\n", error); + return error; + } + + error = dpmcp_close(mc_io, token); + if (error < 0) { + dev_err(&mc_dev->dev, "dpmcp_close() failed: %d\n", error); + return error; + } + + return 0; +} +EXPORT_SYMBOL_GPL(fsl_mc_portal_reset); + +/** + * fsl_mc_object_allocate - Allocates a MC object device of the given + * pool type from a given MC bus + * + * @mc_dev: MC device for which the MC object device is to be allocated + * @pool_type: MC bus resource pool type + * @new_mc_dev: Pointer to area where the pointer to the allocated + * MC object device is to be returned + * + * This function allocates a MC object device from the device's parent DPRC, + * from the corresponding MC bus' pool of allocatable MC object devices of + * the given resource type. mc_dev cannot be a DPRC itself. + * + * NOTE: pool_type must be different from FSL_MC_POOL_MCP, since MC + * portals are allocated using fsl_mc_portal_allocate(), instead of + * this function. + */ +int __must_check fsl_mc_object_allocate(struct fsl_mc_device *mc_dev, + enum fsl_mc_pool_type pool_type, + struct fsl_mc_device **new_mc_adev) +{ + struct fsl_mc_device *mc_bus_dev; + struct fsl_mc_bus *mc_bus; + struct fsl_mc_device *mc_adev; + int error = -EINVAL; + struct fsl_mc_resource *resource = NULL; + + *new_mc_adev = NULL; + if (WARN_ON(mc_dev->flags & FSL_MC_IS_DPRC)) + goto error; + + if (WARN_ON(mc_dev->dev.parent->bus != &fsl_mc_bus_type)) + goto error; + + if (WARN_ON(pool_type == FSL_MC_POOL_DPMCP)) + goto error; + + mc_bus_dev = to_fsl_mc_device(mc_dev->dev.parent); + mc_bus = to_fsl_mc_bus(mc_bus_dev); + error = fsl_mc_resource_allocate(mc_bus, pool_type, &resource); + if (error < 0) + goto error; + + mc_adev = resource->data; + if (WARN_ON(!mc_adev)) + goto error; + + *new_mc_adev = mc_adev; + return 0; +error: + if (resource) + fsl_mc_resource_free(resource); + + return error; +} +EXPORT_SYMBOL_GPL(fsl_mc_object_allocate); + +/** + * fsl_mc_object_free - Returns an allocatable MC object device to the + * corresponding resource pool of a given MC bus. + * + * @mc_adev: Pointer to the MC object device + */ +void fsl_mc_object_free(struct fsl_mc_device *mc_adev) +{ + struct fsl_mc_resource *resource; + + resource = mc_adev->resource; + if (WARN_ON(resource->type == FSL_MC_POOL_DPMCP)) + return; + if (WARN_ON(resource->data != mc_adev)) + return; + + fsl_mc_resource_free(resource); +} +EXPORT_SYMBOL_GPL(fsl_mc_object_free); + +/** + * fsl_mc_allocator_probe - callback invoked when an allocatable device is + * being added to the system + */ +static int fsl_mc_allocator_probe(struct fsl_mc_device *mc_dev) +{ + enum fsl_mc_pool_type pool_type; + struct fsl_mc_device *mc_bus_dev; + struct fsl_mc_bus *mc_bus; + int error = -EINVAL; + + if (WARN_ON(!FSL_MC_IS_ALLOCATABLE(mc_dev->obj_desc.type))) + goto error; + + mc_bus_dev = to_fsl_mc_device(mc_dev->dev.parent); + if (WARN_ON(mc_bus_dev->dev.bus != &fsl_mc_bus_type)) + goto error; + + mc_bus = to_fsl_mc_bus(mc_bus_dev); + error = object_type_to_pool_type(mc_dev->obj_desc.type, &pool_type); + if (error < 0) + goto error; + + error = fsl_mc_resource_pool_add_device(mc_bus, pool_type, mc_dev); + if (error < 0) + goto error; + + dev_info(&mc_dev->dev, + "Allocatable MC object device bound to fsl_mc_allocator driver"); + return 0; +error: + + return error; +} + +/** + * fsl_mc_allocator_remove - callback invoked when an allocatable device is + * being removed from the system + */ +static int fsl_mc_allocator_remove(struct fsl_mc_device *mc_dev) +{ + int error = -EINVAL; + + if (WARN_ON(!FSL_MC_IS_ALLOCATABLE(mc_dev->obj_desc.type))) + goto out; + + error = fsl_mc_resource_pool_remove_device(mc_dev); + if (error < 0) + goto out; + + dev_info(&mc_dev->dev, + "Allocatable MC object device unbound from fsl_mc_allocator driver"); + error = 0; +out: + return error; +} + +static const struct fsl_mc_device_match_id match_id_table[] = { + { + .vendor = FSL_MC_VENDOR_FREESCALE, + .obj_type = "dpbp", + .ver_major = DPBP_VER_MAJOR, + .ver_minor = DPBP_VER_MINOR + }, + { + .vendor = FSL_MC_VENDOR_FREESCALE, + .obj_type = "dpmcp", + .ver_major = DPMCP_VER_MAJOR, + .ver_minor = DPMCP_VER_MINOR + }, + { + .vendor = FSL_MC_VENDOR_FREESCALE, + .obj_type = "dpcon", + .ver_major = DPCON_VER_MAJOR, + .ver_minor = DPCON_VER_MINOR + }, + {.vendor = 0x0}, +}; + +static struct fsl_mc_driver fsl_mc_allocator_driver = { + .driver = { + .name = "fsl_mc_allocator", + .owner = THIS_MODULE, + .pm = NULL, + }, + .match_id_table = match_id_table, + .probe = fsl_mc_allocator_probe, + .remove = fsl_mc_allocator_remove, +}; + +module_fsl_mc_driver(fsl_mc_allocator_driver); + +MODULE_AUTHOR("Freescale Semiconductor Inc."); +MODULE_DESCRIPTION("Freescale's MC object device allocator"); +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/fsl-mc/bus/mc-bus.c b/drivers/staging/fsl-mc/bus/mc-bus.c index 72551e3c23b6..b4e90221a802 100644 --- a/drivers/staging/fsl-mc/bus/mc-bus.c +++ b/drivers/staging/fsl-mc/bus/mc-bus.c @@ -604,7 +604,7 @@ static int fsl_mc_bus_probe(struct platform_device *pdev) mc_portal_phys_addr = res.start; mc_portal_size = resource_size(&res); error = fsl_create_mc_io(&pdev->dev, mc_portal_phys_addr, - mc_portal_size, 0, &mc_io); + mc_portal_size, NULL, 0, &mc_io); if (error < 0) return error; diff --git a/drivers/staging/fsl-mc/bus/mc-sys.c b/drivers/staging/fsl-mc/bus/mc-sys.c index a07064a9bc9a..5737f599f0ef 100644 --- a/drivers/staging/fsl-mc/bus/mc-sys.c +++ b/drivers/staging/fsl-mc/bus/mc-sys.c @@ -60,6 +60,8 @@ * @dev: device to be associated with the MC I/O object * @mc_portal_phys_addr: physical address of the MC portal to use * @mc_portal_size: size in bytes of the MC portal + * @resource: Pointer to MC bus object allocator resource associated + * with this MC I/O object or NULL if none. * @flags: flags for the new MC I/O object * @new_mc_io: Area to return pointer to newly created MC I/O object * @@ -68,6 +70,7 @@ int __must_check fsl_create_mc_io(struct device *dev, phys_addr_t mc_portal_phys_addr, uint32_t mc_portal_size, + struct fsl_mc_resource *resource, uint32_t flags, struct fsl_mc_io **new_mc_io) { struct fsl_mc_io *mc_io; @@ -82,6 +85,7 @@ int __must_check fsl_create_mc_io(struct device *dev, mc_io->flags = flags; mc_io->portal_phys_addr = mc_portal_phys_addr; mc_io->portal_size = mc_portal_size; + mc_io->resource = resource; res = devm_request_mem_region(dev, mc_portal_phys_addr, mc_portal_size, diff --git a/drivers/staging/fsl-mc/include/dpbp-cmd.h b/drivers/staging/fsl-mc/include/dpbp-cmd.h new file mode 100644 index 000000000000..1fd70a215194 --- /dev/null +++ b/drivers/staging/fsl-mc/include/dpbp-cmd.h @@ -0,0 +1,60 @@ +/* Copyright 2013-2014 Freescale Semiconductor Inc. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of the above-listed copyright holders nor the +* names of any contributors may be used to endorse or promote products +* derived from this software without specific prior written permission. +* +* +* ALTERNATIVELY, this software may be distributed under the terms of the +* GNU General Public License ("GPL") as published by the Free Software +* Foundation, either version 2 of that License or (at your option) any +* later version. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ +#ifndef _FSL_DPBP_CMD_H +#define _FSL_DPBP_CMD_H + +/* DPBP Version */ +#define DPBP_VER_MAJOR 2 +#define DPBP_VER_MINOR 0 + +/* Command IDs */ +#define DPBP_CMDID_CLOSE 0x800 +#define DPBP_CMDID_OPEN 0x804 +#define DPBP_CMDID_CREATE 0x904 +#define DPBP_CMDID_DESTROY 0x900 + +#define DPBP_CMDID_ENABLE 0x002 +#define DPBP_CMDID_DISABLE 0x003 +#define DPBP_CMDID_GET_ATTR 0x004 +#define DPBP_CMDID_RESET 0x005 +#define DPBP_CMDID_IS_ENABLED 0x006 + +#define DPBP_CMDID_SET_IRQ 0x010 +#define DPBP_CMDID_GET_IRQ 0x011 +#define DPBP_CMDID_SET_IRQ_ENABLE 0x012 +#define DPBP_CMDID_GET_IRQ_ENABLE 0x013 +#define DPBP_CMDID_SET_IRQ_MASK 0x014 +#define DPBP_CMDID_GET_IRQ_MASK 0x015 +#define DPBP_CMDID_GET_IRQ_STATUS 0x016 +#define DPBP_CMDID_CLEAR_IRQ_STATUS 0x017 + +#endif /* _FSL_DPBP_CMD_H */ diff --git a/drivers/staging/fsl-mc/include/dpbp.h b/drivers/staging/fsl-mc/include/dpbp.h new file mode 100644 index 000000000000..5f3c8e74d2ad --- /dev/null +++ b/drivers/staging/fsl-mc/include/dpbp.h @@ -0,0 +1,330 @@ +/* Copyright 2013-2015 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the above-listed copyright holders nor the + * names of any contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef __FSL_DPBP_H +#define __FSL_DPBP_H + +/* Data Path Buffer Pool API + * Contains initialization APIs and runtime control APIs for DPBP + */ + +struct fsl_mc_io; + +/** + * dpbp_open() - Open a control session for the specified object. + * @mc_io: Pointer to MC portal's I/O object + * @dpbp_id: DPBP unique ID + * @token: Returned token; use in subsequent API calls + * + * This function can be used to open a control session for an + * already created object; an object may have been declared in + * the DPL or by calling the dpbp_create function. + * This function returns a unique authentication token, + * associated with the specific object ID and the specific MC + * portal; this token must be used in all subsequent commands for + * this specific object + * + * Return: '0' on Success; Error code otherwise. + */ +int dpbp_open(struct fsl_mc_io *mc_io, int dpbp_id, uint16_t *token); + +/** + * dpbp_close() - Close the control session of the object + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPBP object + * + * After this function is called, no further operations are + * allowed on the object without opening a new control session. + * + * Return: '0' on Success; Error code otherwise. + */ +int dpbp_close(struct fsl_mc_io *mc_io, uint16_t token); + +/** + * struct dpbp_cfg() - Structure representing DPBP configuration + * @options: place holder + */ +struct dpbp_cfg { + uint32_t options; +}; + +/** + * dpbp_create() - Create the DPBP object. + * @mc_io: Pointer to MC portal's I/O object + * @cfg: Configuration structure + * @token: Returned token; use in subsequent API calls + * + * Create the DPBP object, allocate required resources and + * perform required initialization. + * + * The object can be created either by declaring it in the + * DPL file, or by calling this function. + * This function returns a unique authentication token, + * associated with the specific object ID and the specific MC + * portal; this token must be used in all subsequent calls to + * this specific object. For objects that are created using the + * DPL file, call dpbp_open function to get an authentication + * token first. + * + * Return: '0' on Success; Error code otherwise. + */ +int dpbp_create(struct fsl_mc_io *mc_io, + const struct dpbp_cfg *cfg, + uint16_t *token); + +/** + * dpbp_destroy() - Destroy the DPBP object and release all its resources. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPBP object + * + * Return: '0' on Success; error code otherwise. + */ +int dpbp_destroy(struct fsl_mc_io *mc_io, uint16_t token); + +/** + * dpbp_enable() - Enable the DPBP. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPBP object + * + * Return: '0' on Success; Error code otherwise. + */ +int dpbp_enable(struct fsl_mc_io *mc_io, uint16_t token); + +/** + * dpbp_disable() - Disable the DPBP. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPBP object + * + * Return: '0' on Success; Error code otherwise. + */ +int dpbp_disable(struct fsl_mc_io *mc_io, uint16_t token); + +/** + * dpbp_is_enabled() - Check if the DPBP is enabled. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPBP object + * @en: Returns '1' if object is enabled; '0' otherwise + * + * Return: '0' on Success; Error code otherwise. + */ +int dpbp_is_enabled(struct fsl_mc_io *mc_io, uint16_t token, int *en); + +/** + * dpbp_reset() - Reset the DPBP, returns the object to initial state. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPBP object + * + * Return: '0' on Success; Error code otherwise. + */ +int dpbp_reset(struct fsl_mc_io *mc_io, uint16_t token); + +/** + * dpbp_set_irq() - Set IRQ information for the DPBP to trigger an interrupt. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPBP object + * @irq_index: Identifies the interrupt index to configure + * @irq_addr: Address that must be written to + * signal a message-based interrupt + * @irq_val: Value to write into irq_addr address + * @user_irq_id: A user defined number associated with this IRQ + * + * Return: '0' on Success; Error code otherwise. + */ +int dpbp_set_irq(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint64_t irq_addr, + uint32_t irq_val, + int user_irq_id); + +/** + * dpbp_get_irq() - Get IRQ information from the DPBP. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPBP object + * @irq_index: The interrupt index to configure + * @type: Interrupt type: 0 represents message interrupt + * type (both irq_addr and irq_val are valid) + * @irq_addr: Returned address that must be written to + * signal the message-based interrupt + * @irq_val: Value to write into irq_addr address + * @user_irq_id: A user defined number associated with this IRQ + * + * Return: '0' on Success; Error code otherwise. + */ +int dpbp_get_irq(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + int *type, + uint64_t *irq_addr, + uint32_t *irq_val, + int *user_irq_id); + +/** + * dpbp_set_irq_enable() - Set overall interrupt state. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPBP object + * @irq_index: The interrupt index to configure + * @en: Interrupt state - enable = 1, disable = 0 + * + * Allows GPP software to control when interrupts are generated. + * Each interrupt can have up to 32 causes. The enable/disable control's the + * overall interrupt state. if the interrupt is disabled no causes will cause + * an interrupt. + * + * Return: '0' on Success; Error code otherwise. + */ +int dpbp_set_irq_enable(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint8_t en); + +/** + * dpbp_get_irq_enable() - Get overall interrupt state + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPBP object + * @irq_index: The interrupt index to configure + * @en: Returned interrupt state - enable = 1, disable = 0 + * + * Return: '0' on Success; Error code otherwise. + */ +int dpbp_get_irq_enable(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint8_t *en); + +/** + * dpbp_set_irq_mask() - Set interrupt mask. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPBP object + * @irq_index: The interrupt index to configure + * @mask: Event mask to trigger interrupt; + * each bit: + * 0 = ignore event + * 1 = consider event for asserting IRQ + * + * Every interrupt can have up to 32 causes and the interrupt model supports + * masking/unmasking each cause independently + * + * Return: '0' on Success; Error code otherwise. + */ +int dpbp_set_irq_mask(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint32_t mask); + +/** + * dpbp_get_irq_mask() - Get interrupt mask. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPBP object + * @irq_index: The interrupt index to configure + * @mask: Returned event mask to trigger interrupt + * + * Every interrupt can have up to 32 causes and the interrupt model supports + * masking/unmasking each cause independently + * + * Return: '0' on Success; Error code otherwise. + */ +int dpbp_get_irq_mask(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint32_t *mask); + +/** + * dpbp_get_irq_status() - Get the current status of any pending interrupts. + * + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPBP object + * @irq_index: The interrupt index to configure + * @status: Returned interrupts status - one bit per cause: + * 0 = no interrupt pending + * 1 = interrupt pending + * + * Return: '0' on Success; Error code otherwise. + */ +int dpbp_get_irq_status(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint32_t *status); + +/** + * dpbp_clear_irq_status() - Clear a pending interrupt's status + * + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPBP object + * @irq_index: The interrupt index to configure + * @status: Bits to clear (W1C) - one bit per cause: + * 0 = don't change + * 1 = clear status bit + * + * Return: '0' on Success; Error code otherwise. + */ +int dpbp_clear_irq_status(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t irq_index, + uint32_t status); + +/** + * struct dpbp_attr - Structure representing DPBP attributes + * @id: DPBP object ID + * @version: DPBP version + * @bpid: Hardware buffer pool ID; should be used as an argument in + * acquire/release operations on buffers + */ +struct dpbp_attr { + int id; + /** + * struct version - Structure representing DPBP version + * @major: DPBP major version + * @minor: DPBP minor version + */ + struct { + uint16_t major; + uint16_t minor; + } version; + uint16_t bpid; +}; + +/** + * dpbp_get_attributes - Retrieve DPBP attributes. + * + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPBP object + * @attr: Returned object's attributes + * + * Return: '0' on Success; Error code otherwise. + */ +int dpbp_get_attributes(struct fsl_mc_io *mc_io, + uint16_t token, + struct dpbp_attr *attr); + +/** @} */ + +#endif /* __FSL_DPBP_H */ diff --git a/drivers/staging/fsl-mc/include/dpcon-cmd.h b/drivers/staging/fsl-mc/include/dpcon-cmd.h new file mode 100644 index 000000000000..c878d33bfd86 --- /dev/null +++ b/drivers/staging/fsl-mc/include/dpcon-cmd.h @@ -0,0 +1,62 @@ +/* Copyright 2013-2015 Freescale Semiconductor Inc. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of the above-listed copyright holders nor the +* names of any contributors may be used to endorse or promote products +* derived from this software without specific prior written permission. +* +* +* ALTERNATIVELY, this software may be distributed under the terms of the +* GNU General Public License ("GPL") as published by the Free Software +* Foundation, either version 2 of that License or (at your option) any +* later version. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ +#ifndef _FSL_DPCON_CMD_H +#define _FSL_DPCON_CMD_H + +/* DPCON Version */ +#define DPCON_VER_MAJOR 2 +#define DPCON_VER_MINOR 0 + +/* Command IDs */ +#define DPCON_CMDID_CLOSE 0x800 +#define DPCON_CMDID_OPEN 0x808 +#define DPCON_CMDID_CREATE 0x908 +#define DPCON_CMDID_DESTROY 0x900 + +#define DPCON_CMDID_ENABLE 0x002 +#define DPCON_CMDID_DISABLE 0x003 +#define DPCON_CMDID_GET_ATTR 0x004 +#define DPCON_CMDID_RESET 0x005 +#define DPCON_CMDID_IS_ENABLED 0x006 + +#define DPCON_CMDID_SET_IRQ 0x010 +#define DPCON_CMDID_GET_IRQ 0x011 +#define DPCON_CMDID_SET_IRQ_ENABLE 0x012 +#define DPCON_CMDID_GET_IRQ_ENABLE 0x013 +#define DPCON_CMDID_SET_IRQ_MASK 0x014 +#define DPCON_CMDID_GET_IRQ_MASK 0x015 +#define DPCON_CMDID_GET_IRQ_STATUS 0x016 +#define DPCON_CMDID_CLEAR_IRQ_STATUS 0x017 + +#define DPCON_CMDID_SET_NOTIFICATION 0x100 + +#endif /* _FSL_DPCON_CMD_H */ diff --git a/drivers/staging/fsl-mc/include/mc-private.h b/drivers/staging/fsl-mc/include/mc-private.h index 197544447404..8e67075f43b2 100644 --- a/drivers/staging/fsl-mc/include/mc-private.h +++ b/drivers/staging/fsl-mc/include/mc-private.h @@ -21,6 +21,11 @@ (strcmp((_mc_dev)->obj_desc.type, (_obj_desc)->type) == 0 && \ (_mc_dev)->obj_desc.id == (_obj_desc)->id) +#define FSL_MC_IS_ALLOCATABLE(_obj_type) \ + (strcmp(_obj_type, "dpbp") == 0 || \ + strcmp(_obj_type, "dpmcp") == 0 || \ + strcmp(_obj_type, "dpcon") == 0) + /** * struct fsl_mc - Private data of a "fsl,qoriq-mc" platform device * @root_mc_bus_dev: MC object device representing the root DPRC @@ -32,19 +37,6 @@ struct fsl_mc { struct fsl_mc_addr_translation_range *translation_ranges; }; -/** - * struct fsl_mc_bus - logical bus that corresponds to a physical DPRC - * @mc_dev: fsl-mc device for the bus device itself. - * @scan_mutex: Serializes bus scanning - */ -struct fsl_mc_bus { - struct fsl_mc_device mc_dev; - struct mutex scan_mutex; /* serializes bus scanning */ -}; - -#define to_fsl_mc_bus(_mc_dev) \ - container_of(_mc_dev, struct fsl_mc_bus, mc_dev) - /** * struct fsl_mc_addr_translation_range - bus to system address translation * range @@ -59,6 +51,42 @@ struct fsl_mc_addr_translation_range { phys_addr_t start_phys_addr; }; +/** + * struct fsl_mc_resource_pool - Pool of MC resources of a given + * type + * @type: type of resources in the pool + * @max_count: maximum number of resources in the pool + * @free_count: number of free resources in the pool + * @mutex: mutex to serialize access to the pool's free list + * @free_list: anchor node of list of free resources in the pool + * @mc_bus: pointer to the MC bus that owns this resource pool + */ +struct fsl_mc_resource_pool { + enum fsl_mc_pool_type type; + int16_t max_count; + int16_t free_count; + struct mutex mutex; /* serializes access to free_list */ + struct list_head free_list; + struct fsl_mc_bus *mc_bus; +}; + +/** + * struct fsl_mc_bus - logical bus that corresponds to a physical DPRC + * @mc_dev: fsl-mc device for the bus device itself. + * @resource_pools: array of resource pools (one pool per resource type) + * for this MC bus. These resources represent allocatable entities + * from the physical DPRC. + * @scan_mutex: Serializes bus scanning + */ +struct fsl_mc_bus { + struct fsl_mc_device mc_dev; + struct fsl_mc_resource_pool resource_pools[FSL_MC_NUM_POOL_TYPES]; + struct mutex scan_mutex; /* serializes bus scanning */ +}; + +#define to_fsl_mc_bus(_mc_dev) \ + container_of(_mc_dev, struct fsl_mc_bus, mc_dev) + int __must_check fsl_mc_device_add(struct dprc_obj_desc *obj_desc, struct fsl_mc_io *mc_io, struct device *parent_dev, @@ -74,4 +102,11 @@ int __init dprc_driver_init(void); void __exit dprc_driver_exit(void); +int __must_check fsl_mc_resource_allocate(struct fsl_mc_bus *mc_bus, + enum fsl_mc_pool_type pool_type, + struct fsl_mc_resource + **new_resource); + +void fsl_mc_resource_free(struct fsl_mc_resource *resource); + #endif /* _FSL_MC_PRIVATE_H_ */ diff --git a/drivers/staging/fsl-mc/include/mc-sys.h b/drivers/staging/fsl-mc/include/mc-sys.h index abfd6a233ada..cb3b5a296615 100644 --- a/drivers/staging/fsl-mc/include/mc-sys.h +++ b/drivers/staging/fsl-mc/include/mc-sys.h @@ -40,6 +40,7 @@ #include #include +struct fsl_mc_resource; struct mc_command; /** @@ -49,6 +50,9 @@ struct mc_command; * @portal_size: MC command portal size in bytes * @portal_phys_addr: MC command portal physical address * @portal_virt_addr: MC command portal virtual address + * @resource: generic resource associated with the MC portal if + * the MC portal came from a resource pool, or NULL if the MC portal + * is permanently bound to a device (e.g., a DPRC) */ struct fsl_mc_io { struct device *dev; @@ -56,11 +60,13 @@ struct fsl_mc_io { uint32_t portal_size; phys_addr_t portal_phys_addr; void __iomem *portal_virt_addr; + struct fsl_mc_resource *resource; }; int __must_check fsl_create_mc_io(struct device *dev, phys_addr_t mc_portal_phys_addr, uint32_t mc_portal_size, + struct fsl_mc_resource *resource, uint32_t flags, struct fsl_mc_io **new_mc_io); void fsl_destroy_mc_io(struct fsl_mc_io *mc_io); diff --git a/drivers/staging/fsl-mc/include/mc.h b/drivers/staging/fsl-mc/include/mc.h index 5cd237b31704..fa02ef0529e7 100644 --- a/drivers/staging/fsl-mc/include/mc.h +++ b/drivers/staging/fsl-mc/include/mc.h @@ -65,6 +65,44 @@ struct fsl_mc_device_match_id { uint32_t ver_minor; }; +/** + * enum fsl_mc_pool_type - Types of allocatable MC bus resources + * + * Entries in these enum are used as indices in the array of resource + * pools of an fsl_mc_bus object. + */ +enum fsl_mc_pool_type { + FSL_MC_POOL_DPMCP = 0x0, /* corresponds to "dpmcp" in the MC */ + FSL_MC_POOL_DPBP, /* corresponds to "dpbp" in the MC */ + FSL_MC_POOL_DPCON, /* corresponds to "dpcon" in the MC */ + + /* + * NOTE: New resource pool types must be added before this entry + */ + FSL_MC_NUM_POOL_TYPES +}; + +/** + * struct fsl_mc_resource - MC generic resource + * @type: type of resource + * @id: unique MC resource Id within the resources of the same type + * @data: pointer to resource-specific data if the resource is currently + * allocated, or NULL if the resource is not currently allocated. + * @parent_pool: pointer to the parent resource pool from which this + * resource is allocated from. + * @node: Node in the free list of the corresponding resource pool + * + * NOTE: This structure is to be embedded as a field of specific + * MC resource structures. + */ +struct fsl_mc_resource { + enum fsl_mc_pool_type type; + int32_t id; + void *data; + struct fsl_mc_resource_pool *parent_pool; + struct list_head node; +}; + /** * Bit masks for a MC object device (struct fsl_mc_device) flags */ @@ -86,6 +124,7 @@ struct fsl_mc_device_match_id { * NULL if none. * @obj_desc: MC description of the DPAA device * @regions: pointer to array of MMIO region entries + * @resource: generic resource associated with this MC object device, if any. * * Generic device object for MC object devices that are "attached" to a * MC bus. @@ -95,6 +134,17 @@ struct fsl_mc_device_match_id { * - The SMMU notifier callback gets invoked after device_add() has been * called for an MC object device, but before the device-specific probe * callback gets called. + * - DP_OBJ_DPRC objects are the only MC objects that have built-in MC + * portals. For all other MC objects, their device drivers are responsible for + * allocating MC portals for them by calling fsl_mc_portal_allocate(). + * - Some types of MC objects (e.g., DP_OBJ_DPBP, DP_OBJ_DPCON) are + * treated as resources that can be allocated/deallocated from the + * corresponding resource pool in the object's parent DPRC, using the + * fsl_mc_object_allocate()/fsl_mc_object_free() functions. These MC objects + * are known as "allocatable" objects. For them, the corresponding + * fsl_mc_device's 'resource' points to the associated resource object. + * For MC objects that are not allocatable (e.g., DP_OBJ_DPRC, DP_OBJ_DPNI), + * 'resource' is NULL. */ struct fsl_mc_device { struct device dev; @@ -105,6 +155,7 @@ struct fsl_mc_device { struct fsl_mc_io *mc_io; struct dprc_obj_desc obj_desc; struct resource *regions; + struct fsl_mc_resource *resource; }; #define to_fsl_mc_device(_dev) \ @@ -131,6 +182,20 @@ int __must_check __fsl_mc_driver_register(struct fsl_mc_driver *fsl_mc_driver, void fsl_mc_driver_unregister(struct fsl_mc_driver *driver); +int __must_check fsl_mc_portal_allocate(struct fsl_mc_device *mc_dev, + uint16_t mc_io_flags, + struct fsl_mc_io **new_mc_io); + +void fsl_mc_portal_free(struct fsl_mc_io *mc_io); + +int fsl_mc_portal_reset(struct fsl_mc_io *mc_io); + +int __must_check fsl_mc_object_allocate(struct fsl_mc_device *mc_dev, + enum fsl_mc_pool_type pool_type, + struct fsl_mc_device **new_mc_adev); + +void fsl_mc_object_free(struct fsl_mc_device *mc_adev); + extern struct bus_type fsl_mc_bus_type; #endif /* _FSL_MC_H_ */ -- GitLab From 045f32dda9477d3ddf31a4fa862c487d0f747e33 Mon Sep 17 00:00:00 2001 From: Baruch Siach Date: Mon, 16 Feb 2015 08:27:49 +0200 Subject: [PATCH 03235/11651] Revert "tty/serial: of_serial: add DT alias ID handling" This reverts commit 6d01bb9dc82a60580f749062a48cb47cd5caca07. The exact same code was added in commit 3239fd31d4 (serial: of-serial: fetch line number from DT) a few lined above. Doing this once should be enough. Cc: Rob Herring Signed-off-by: Baruch Siach Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/of_serial.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/of_serial.c index 7ff61e24a195..33fb94f78967 100644 --- a/drivers/tty/serial/of_serial.c +++ b/drivers/tty/serial/of_serial.c @@ -133,10 +133,6 @@ static int of_platform_serial_setup(struct platform_device *ofdev, if (of_find_property(np, "no-loopback-test", NULL)) port->flags |= UPF_SKIP_TEST; - ret = of_alias_get_id(np, "serial"); - if (ret >= 0) - port->line = ret; - port->dev = &ofdev->dev; switch (type) { -- GitLab From ca8bb4aefb932e3da105f28cbfba36d57a931081 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Sun, 15 Feb 2015 18:32:16 +0100 Subject: [PATCH 03236/11651] serial: 8250: Revert "tty: serial: 8250_core: read only RX if there is something in the FIFO" This reverts commit 0aa525d11859c1a4d5b78fdc704148e2ae03ae13. The conditional RX-FIFO read seems to cause spurious interrupts and we see just: |serial8250: too much work for irq29 The previous behaviour was "default" for decades and Marvell's 88f6282 SoC might not be the only that relies on it. Therefore the Omap fix is reverted for now. Fixes: 0aa525d11859 ("tty: serial: 8250_core: read only RX if there is something in the FIFO") Reported-By: Nicolas Schichan Debuged-By: Peter Hurley Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_core.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index e3b9570a1eff..deae122c9c4b 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -2138,8 +2138,8 @@ int serial8250_do_startup(struct uart_port *port) /* * Clear the interrupt registers. */ - if (serial_port_in(port, UART_LSR) & UART_LSR_DR) - serial_port_in(port, UART_RX); + serial_port_in(port, UART_LSR); + serial_port_in(port, UART_RX); serial_port_in(port, UART_IIR); serial_port_in(port, UART_MSR); @@ -2300,8 +2300,8 @@ dont_test_tx_en: * saved flags to avoid getting false values from polling * routines or the previous session. */ - if (serial_port_in(port, UART_LSR) & UART_LSR_DR) - serial_port_in(port, UART_RX); + serial_port_in(port, UART_LSR); + serial_port_in(port, UART_RX); serial_port_in(port, UART_IIR); serial_port_in(port, UART_MSR); up->lsr_saved_flags = 0; @@ -2394,8 +2394,7 @@ void serial8250_do_shutdown(struct uart_port *port) * Read data port to reset things, and then unlink from * the IRQ chain. */ - if (serial_port_in(port, UART_LSR) & UART_LSR_DR) - serial_port_in(port, UART_RX); + serial_port_in(port, UART_RX); serial8250_rpm_put(up); del_timer_sync(&up->timer); -- GitLab From f2e0ea861117bda073d1d7ffbd3120c07c0d5d34 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 6 Mar 2015 10:49:21 +0000 Subject: [PATCH 03237/11651] Change email address for 8250_pci I'm still receiving reports to my email address, so let's point this at the linux-serial mailing list instead. Cc: Signed-off-by: Russell King Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index daf2c82984e9..65dd3ad442ea 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -69,7 +69,7 @@ static void moan_device(const char *str, struct pci_dev *dev) "Please send the output of lspci -vv, this\n" "message (0x%04x,0x%04x,0x%04x,0x%04x), the\n" "manufacturer and name of serial board or\n" - "modem board to rmk+serial@arm.linux.org.uk.\n", + "modem board to .\n", pci_name(dev), str, dev->vendor, dev->device, dev->subsystem_vendor, dev->subsystem_device); } -- GitLab From 6262a3692b921a82075695c5c6d10f4a6bcc5fac Mon Sep 17 00:00:00 2001 From: Wang YanQing Date: Sat, 7 Mar 2015 01:13:03 +0800 Subject: [PATCH 03238/11651] serial:8250:8250_pci: fix redundant entry report for WCH_CH352_2S Commit 8b5c913f7ee6464849570bacb6bcd9ef0eaf7dce ("serial: 8250_pci: Add WCH CH352 quirk to avoid Xscale detection") trigger one redundant entry report message. This patch fix it. Reported-by: Russell King Signed-off-by: Wang YanQing Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_pci.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 65dd3ad442ea..285b875fd187 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -5415,10 +5415,6 @@ static struct pci_device_id serial_pci_tbl[] = { PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_b0_bt_2_115200 }, - { PCI_VENDOR_ID_WCH, PCI_DEVICE_ID_WCH_CH352_2S, - PCI_ANY_ID, PCI_ANY_ID, - 0, 0, pbn_b0_bt_2_115200 }, - { PCIE_VENDOR_ID_WCH, PCIE_DEVICE_ID_WCH_CH384_4S, PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_wch384_4 }, -- GitLab From 7cf91108d44dbef3d48766fd0e7f7347c2e48bda Mon Sep 17 00:00:00 2001 From: Wang YanQing Date: Sat, 7 Mar 2015 01:08:35 +0800 Subject: [PATCH 03239/11651] serial:8250:8250_pci: delete unneeded quirk entries These quirk entries have the same effect as default quirk entry, so we can just delete them. Signed-off-by: Wang YanQing Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_pci.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 285b875fd187..892eb32cdef4 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -1987,13 +1987,6 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { .subdevice = PCI_ANY_ID, .setup = byt_serial_setup, }, - { - .vendor = PCI_VENDOR_ID_INTEL, - .device = PCI_DEVICE_ID_INTEL_QRK_UART, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .setup = pci_default_setup, - }, { .vendor = PCI_VENDOR_ID_INTEL, .device = PCI_DEVICE_ID_INTEL_BSW_UART1, @@ -2199,13 +2192,6 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { /* * PLX */ - { - .vendor = PCI_VENDOR_ID_PLX, - .device = PCI_DEVICE_ID_PLX_9030, - .subvendor = PCI_SUBVENDOR_ID_PERLE, - .subdevice = PCI_ANY_ID, - .setup = pci_default_setup, - }, { .vendor = PCI_VENDOR_ID_PLX, .device = PCI_DEVICE_ID_PLX_9050, -- GitLab From dfd37668ea6d5029fb5d8a66ea5e202d0655fad7 Mon Sep 17 00:00:00 2001 From: Desmond Liu Date: Thu, 26 Feb 2015 16:35:57 -0800 Subject: [PATCH 03240/11651] serial: 8250_dw: Fix get_mctrl behaviour Fixed behaviour of get_mctrl() serial driver function as documented in: https://www.kernel.org/doc/Documentation/serial/driver Added device-tree properties 'dcd-override', 'dsr-override', 'cts-override', and 'ri-override' specific to the Synopsis 8250 DesignWare UART driver. Allows one to force Data Carrier Detect, Clear To Send, and Data Set Ready signals to permanently be reported as active. The Ring indicator can be forced to be reported as inactive. It is possible that if modem control signalling is enabled on a port that doesn't have these pins (e.g. - a simple two wire Tx/Rx port), the driver can hang indefinitely waiting for the state to change. The new DT properties allow the driver to ignore the state of these pins on serial ports that don't support them, as recommended in the kernel documentation. Reviewed-by: JD (Jiandong) Zheng Signed-off-by: Jonathan Richardson Signed-off-by: Greg Kroah-Hartman --- .../bindings/serial/snps-dw-apb-uart.txt | 16 ++++++++++ drivers/tty/serial/8250/8250_dw.c | 32 +++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.txt b/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.txt index 7f76214f728a..289c40ed7470 100644 --- a/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.txt +++ b/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.txt @@ -21,6 +21,18 @@ Optional properties: - reg-io-width : the size (in bytes) of the IO accesses that should be performed on the device. If this property is not present then single byte accesses are used. +- dcd-override : Override the DCD modem status signal. This signal will always + be reported as active instead of being obtained from the modem status + register. Define this if your serial port does not use this pin. +- dsr-override : Override the DTS modem status signal. This signal will always + be reported as active instead of being obtained from the modem status + register. Define this if your serial port does not use this pin. +- cts-override : Override the CTS modem status signal. This signal will always + be reported as active instead of being obtained from the modem status + register. Define this if your serial port does not use this pin. +- ri-override : Override the RI modem status signal. This signal will always be + reported as inactive instead of being obtained from the modem status register. + Define this if your serial port does not use this pin. Example: @@ -31,6 +43,10 @@ Example: interrupts = <10>; reg-shift = <2>; reg-io-width = <4>; + dcd-override; + dsr-override; + cts-override; + ri-override; }; Example with one clock: diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c index e60116235836..2ab229ddee38 100644 --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c @@ -59,6 +59,8 @@ struct dw8250_data { u8 usr_reg; int last_mcr; int line; + int msr_mask_on; + int msr_mask_off; struct clk *clk; struct clk *pclk; struct reset_control *rst; @@ -81,6 +83,12 @@ static inline int dw8250_modify_msr(struct uart_port *p, int offset, int value) value &= ~UART_MSR_DCTS; } + /* Override any modem control signals if needed */ + if (offset == UART_MSR) { + value |= d->msr_mask_on; + value &= ~d->msr_mask_off; + } + return value; } @@ -334,6 +342,30 @@ static int dw8250_probe_of(struct uart_port *p, if (id >= 0) p->line = id; + if (of_property_read_bool(np, "dcd-override")) { + /* Always report DCD as active */ + data->msr_mask_on |= UART_MSR_DCD; + data->msr_mask_off |= UART_MSR_DDCD; + } + + if (of_property_read_bool(np, "dsr-override")) { + /* Always report DSR as active */ + data->msr_mask_on |= UART_MSR_DSR; + data->msr_mask_off |= UART_MSR_DDSR; + } + + if (of_property_read_bool(np, "cts-override")) { + /* Always report DSR as active */ + data->msr_mask_on |= UART_MSR_DSR; + data->msr_mask_off |= UART_MSR_DDSR; + } + + if (of_property_read_bool(np, "ri-override")) { + /* Always report Ring indicator as inactive */ + data->msr_mask_off |= UART_MSR_RI; + data->msr_mask_off |= UART_MSR_TERI; + } + /* clock got configured through clk api, all done */ if (p->uartclk) return 0; -- GitLab From f0bf0bd07943bfde8f5ac39a32664810a379c7d3 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 27 Feb 2015 18:40:31 +0100 Subject: [PATCH 03241/11651] tty: fix up atime/mtime mess, take four This problem was taken care of three times already in * b0de59b5733d18b0d1974a060860a8b5c1b36a2e (TTY: do not update atime/mtime on read/write), * 37b7f3c76595e23257f61bd80b223de8658617ee (TTY: fix atime/mtime regression), and * b0b885657b6c8ef63a46bc9299b2a7715d19acde (tty: fix up atime/mtime mess, take three) But it still misses one point. As John Paul correctly points out, we do not care about setting date. If somebody ever changes wall time backwards (by mistake for example), tty timestamps are never updated until the original wall time passes. So check the absolute difference of times and if it large than "8 seconds or so", always update the time. That means we will update immediatelly when changing time. Ergo, CAP_SYS_TIME can foul the check, but it was always that way. Thanks John for serving me this so nicely debugged. Signed-off-by: Jiri Slaby Reported-by: John Paul Perry Cc: # all, as b0b885657 was backported Acked-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 51f066aa375e..2bb4dfc02873 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -1028,8 +1028,8 @@ EXPORT_SYMBOL(start_tty); /* We limit tty time update visibility to every 8 seconds or so. */ static void tty_update_time(struct timespec *time) { - unsigned long sec = get_seconds() & ~7; - if ((long)(sec - time->tv_sec) > 0) + unsigned long sec = get_seconds(); + if (abs(sec - time->tv_sec) & ~7) time->tv_sec = sec; } -- GitLab From 5dcb34bbc3f3274b37a71a71f1b60ac96782a5ed Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 25 Feb 2015 16:06:09 +0100 Subject: [PATCH 03242/11651] serial: pl010 is no longer broken As more ARM platforms are moving into ARCH_MULTIPLATFORM, we can now have integrator and versatile in the same kernel, and first one selects this driver, causing a Kconfig warning: warning: (ARCH_INTEGRATOR_AP) selects SERIAL_AMBA_PL010 which has unmet direct dependencies (TTY && HAS_IOMEM && ARM_AMBA && (BROKEN || !ARCH_VERSATILE)) It turns out that it has not been broken on versatile for a long time, so we can remove the statement here. Signed-off-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index d2501f01cd03..bbb12794cc8c 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -20,7 +20,7 @@ comment "Non-8250 serial port support" config SERIAL_AMBA_PL010 tristate "ARM AMBA PL010 serial port support" - depends on ARM_AMBA && (BROKEN || !ARCH_VERSATILE) + depends on ARM_AMBA select SERIAL_CORE help This selects the ARM(R) AMBA(R) PrimeCell PL010 UART. If you have -- GitLab From 97f9f707d26dfe34368a5b88f1996f2eaf973b42 Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Fri, 20 Feb 2015 19:12:57 +0100 Subject: [PATCH 03243/11651] serial: core: replace current->state by __set_current_state() Use helper functions to access current->state. Direct assignments are prone to races and therefore buggy. Thanks to Peter Zijlstra for the exact definition of the problem. Suggested-By: Peter Zijlstra Signed-off-by: Fabian Frederick Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/serial_core.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 6a1055ae3437..63d29473c703 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -1118,8 +1118,7 @@ uart_wait_modem_status(struct uart_state *state, unsigned long arg) cprev = cnow; } - - current->state = TASK_RUNNING; + __set_current_state(TASK_RUNNING); remove_wait_queue(&port->delta_msr_wait, &wait); return ret; -- GitLab From 213dce3c17a6536e6f28548085dc9de2dae77eca Mon Sep 17 00:00:00 2001 From: Kevin Hao Date: Sat, 31 Jan 2015 21:47:43 +0800 Subject: [PATCH 03244/11651] tty: kconfig: remove the superfluous dependency on PPC_OF In the current kernel, the CONFIG_PPC_OF is always 'y' for the ppc arch. So we don't need to check it with other ppc specific options. Signed-off-by: Kevin Hao Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index bbb12794cc8c..2b619e511b9e 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -835,7 +835,7 @@ config SERIAL_MCF_CONSOLE config SERIAL_PMACZILOG tristate "Mac or PowerMac z85c30 ESCC support" - depends on (M68K && MAC) || (PPC_OF && PPC_PMAC) + depends on (M68K && MAC) || PPC_PMAC select SERIAL_CORE help This driver supports the Zilog z85C30 serial ports found on @@ -1153,7 +1153,7 @@ config SERIAL_OMAP_CONSOLE config SERIAL_OF_PLATFORM_NWPSERIAL tristate "NWP serial port driver" - depends on PPC_OF && PPC_DCR + depends on PPC_DCR select SERIAL_OF_PLATFORM select SERIAL_CORE_CONSOLE select SERIAL_CORE -- GitLab From 61702c3e4f064250d11395fce7d3242a2cfcf9c1 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 2 Feb 2015 14:53:26 +0200 Subject: [PATCH 03245/11651] serial: 8250_pci: convert to dev_pm_ops Convert the legacy system PM callbacks to new ones. Meanwhile, remove the redudant calls to the PCI for changing a power state since it's done by bus code. Signed-off-by: Andy Shevchenko Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_pci.c | 31 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index daf2c82984e9..fbe919410e0f 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -4020,41 +4020,41 @@ static void pciserial_remove_one(struct pci_dev *dev) pci_disable_device(dev); } -#ifdef CONFIG_PM -static int pciserial_suspend_one(struct pci_dev *dev, pm_message_t state) +#ifdef CONFIG_PM_SLEEP +static int pciserial_suspend_one(struct device *dev) { - struct serial_private *priv = pci_get_drvdata(dev); + struct pci_dev *pdev = to_pci_dev(dev); + struct serial_private *priv = pci_get_drvdata(pdev); if (priv) pciserial_suspend_ports(priv); - pci_save_state(dev); - pci_set_power_state(dev, pci_choose_state(dev, state)); return 0; } -static int pciserial_resume_one(struct pci_dev *dev) +static int pciserial_resume_one(struct device *dev) { + struct pci_dev *pdev = to_pci_dev(dev); + struct serial_private *priv = pci_get_drvdata(pdev); int err; - struct serial_private *priv = pci_get_drvdata(dev); - - pci_set_power_state(dev, PCI_D0); - pci_restore_state(dev); if (priv) { /* * The device may have been disabled. Re-enable it. */ - err = pci_enable_device(dev); + err = pci_enable_device(pdev); /* FIXME: We cannot simply error out here */ if (err) - dev_err(&dev->dev, "Unable to re-enable ports, trying to continue.\n"); + dev_err(dev, "Unable to re-enable ports, trying to continue.\n"); pciserial_resume_ports(priv); } return 0; } #endif +static SIMPLE_DEV_PM_OPS(pciserial_pm_ops, pciserial_suspend_one, + pciserial_resume_one); + static struct pci_device_id serial_pci_tbl[] = { /* Advantech use PCI_DEVICE_ID_ADVANTECH_PCI3620 (0x3620) as 'PCI_SUBVENDOR_ID' */ { PCI_VENDOR_ID_ADVANTECH, PCI_DEVICE_ID_ADVANTECH_PCI3620, @@ -5528,10 +5528,9 @@ static struct pci_driver serial_pci_driver = { .name = "serial", .probe = pciserial_init_one, .remove = pciserial_remove_one, -#ifdef CONFIG_PM - .suspend = pciserial_suspend_one, - .resume = pciserial_resume_one, -#endif + .driver = { + .pm = &pciserial_pm_ops, + }, .id_table = serial_pci_tbl, .err_handler = &serial8250_err_handler, }; -- GitLab From 6ae4a16cf4b6d449778697701de1b2ea86726def Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 3 Feb 2015 11:01:47 +0100 Subject: [PATCH 03246/11651] tty: serial: 8250_core: Remove trailing whitespaces No functional changes. Signed-off-by: Michal Simek Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index e3b9570a1eff..463425721866 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -895,7 +895,7 @@ static int broken_efr(struct uart_8250_port *up) /* * Exar ST16C2550 "A2" devices incorrectly detect as * having an EFR, and report an ID of 0x0201. See - * http://linux.derkeiler.com/Mailing-Lists/Kernel/2004-11/4812.html + * http://linux.derkeiler.com/Mailing-Lists/Kernel/2004-11/4812.html */ if (autoconfig_read_divisor_id(up) == 0x0201 && size_fifo(up) == 16) return 1; @@ -1260,7 +1260,7 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) serial_out(up, UART_LCR, save_lcr); port->fifosize = uart_config[up->port.type].fifo_size; - old_capabilities = up->capabilities; + old_capabilities = up->capabilities; up->capabilities = uart_config[port->type].flags; up->tx_loadsz = uart_config[port->type].tx_loadsz; -- GitLab From ad3d4fdc8ee6d268d90d1a29bccd5318fa071cab Mon Sep 17 00:00:00 2001 From: Sanjeev Sharma Date: Tue, 3 Feb 2015 16:16:06 +0530 Subject: [PATCH 03247/11651] serial:imx make of_device_id array const Make of_device_id array const. Signed-off-by: Sanjeev Sharma Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/imx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 0eb29b1c47ac..412bfbf8730b 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -273,7 +273,7 @@ static struct platform_device_id imx_uart_devtype[] = { }; MODULE_DEVICE_TABLE(platform, imx_uart_devtype); -static struct of_device_id imx_uart_dt_ids[] = { +static const struct of_device_id imx_uart_dt_ids[] = { { .compatible = "fsl,imx6q-uart", .data = &imx_uart_devdata[IMX6Q_UART], }, { .compatible = "fsl,imx1-uart", .data = &imx_uart_devdata[IMX1_UART], }, { .compatible = "fsl,imx21-uart", .data = &imx_uart_devdata[IMX21_UART], }, -- GitLab From b51e3f5ad5b2618702d689942dfaf7b15ea5eba4 Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Tue, 3 Feb 2015 21:05:50 +0100 Subject: [PATCH 03248/11651] sprd_serial: compile sprd_suspend and sprd_resume conditionally MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Building sprd_serial.o when CONFIG_PM_SLEEP is not defined triggers these warnings: drivers/tty/serial/sprd_serial.c:755:12: warning: ‘sprd_suspend’ defined but not used [-Wunused-function] static int sprd_suspend(struct device *dev) ^ drivers/tty/serial/sprd_serial.c:764:12: warning: ‘sprd_resume’ defined but not used [-Wunused-function] static int sprd_resume(struct device *dev) ^ Let's compile these functions only when CONFIG_PM_SLEEP is defined. Signed-off-by: Paul Bolle Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sprd_serial.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/tty/serial/sprd_serial.c b/drivers/tty/serial/sprd_serial.c index 594b63331ef4..be3ed3f4ad60 100644 --- a/drivers/tty/serial/sprd_serial.c +++ b/drivers/tty/serial/sprd_serial.c @@ -752,6 +752,7 @@ static int sprd_probe(struct platform_device *pdev) return ret; } +#ifdef CONFIG_PM_SLEEP static int sprd_suspend(struct device *dev) { struct sprd_uart_port *sup = dev_get_drvdata(dev); @@ -769,6 +770,7 @@ static int sprd_resume(struct device *dev) return 0; } +#endif static SIMPLE_DEV_PM_OPS(sprd_pm_ops, sprd_suspend, sprd_resume); -- GitLab From f3ac3fc287818a63072618b091074267bfa5184d Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Wed, 4 Feb 2015 15:03:48 +0200 Subject: [PATCH 03249/11651] serial: 8250_dw: Add missing MODULE_ALIAS() for module autoloading support Without this the module does not load automatically whenever suitable platform device appears. Reported-by: Jerome Blin Signed-off-by: Mika Westerberg Reviewed-by: Andy Shevchenko Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_dw.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c index e60116235836..f426acc8c6b5 100644 --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c @@ -608,3 +608,4 @@ module_platform_driver(dw8250_platform_driver); MODULE_AUTHOR("Jamie Iles"); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Synopsys DesignWare 8250 serial port driver"); +MODULE_ALIAS("platform:dw-apb-uart"); -- GitLab From 16420ad05cdf82b27655a1e4554a8379a06c8075 Mon Sep 17 00:00:00 2001 From: "Lad, Prabhakar" Date: Wed, 4 Feb 2015 18:21:22 +0000 Subject: [PATCH 03250/11651] tty: serial/bcm63xx_uart: fix sparse warning this patch fixes following sparse warnings: bcm63xx_uart.c:857:43: warning: Using plain integer as NULL pointer bcm63xx_uart.c:871:35: warning: Using plain integer as NULL pointer Signed-off-by: Lad, Prabhakar Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/bcm63xx_uart.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/bcm63xx_uart.c b/drivers/tty/serial/bcm63xx_uart.c index 01d83df08e3d..681e0f3d5e0e 100644 --- a/drivers/tty/serial/bcm63xx_uart.c +++ b/drivers/tty/serial/bcm63xx_uart.c @@ -854,7 +854,7 @@ static int bcm_uart_probe(struct platform_device *pdev) ret = uart_add_one_port(&bcm_uart_driver, port); if (ret) { - ports[pdev->id].membase = 0; + ports[pdev->id].membase = NULL; return ret; } platform_set_drvdata(pdev, port); @@ -868,7 +868,7 @@ static int bcm_uart_remove(struct platform_device *pdev) port = platform_get_drvdata(pdev); uart_remove_one_port(&bcm_uart_driver, port); /* mark port as free */ - ports[pdev->id].membase = 0; + ports[pdev->id].membase = NULL; return 0; } -- GitLab From 4f86a95d75386b47178335599264a000601e01ed Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Sat, 7 Feb 2015 15:46:41 -0200 Subject: [PATCH 03251/11651] serial: imx: Do not store/restore the UBRC register UBRC is a read-only register, so we should not store and restore it inside imx_flush_buffer(). Reported-by: Fugang Duan Signed-off-by: Fabio Estevam Acked-by: Fugang Duan Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/imx.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 412bfbf8730b..ca00b3f1520f 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -1320,7 +1320,7 @@ static void imx_flush_buffer(struct uart_port *port) struct imx_port *sport = (struct imx_port *)port; struct scatterlist *sgl = &sport->tx_sgl[0]; unsigned long temp; - int i = 100, ubir, ubmr, ubrc, uts; + int i = 100, ubir, ubmr, uts; if (!sport->dma_chan_tx) return; @@ -1345,7 +1345,6 @@ static void imx_flush_buffer(struct uart_port *port) */ ubir = readl(sport->port.membase + UBIR); ubmr = readl(sport->port.membase + UBMR); - ubrc = readl(sport->port.membase + UBRC); uts = readl(sport->port.membase + IMX21_UTS); temp = readl(sport->port.membase + UCR2); @@ -1358,7 +1357,6 @@ static void imx_flush_buffer(struct uart_port *port) /* Restore the registers */ writel(ubir, sport->port.membase + UBIR); writel(ubmr, sport->port.membase + UBMR); - writel(ubrc, sport->port.membase + UBRC); writel(uts, sport->port.membase + IMX21_UTS); } -- GitLab From c89b73703ea3e61ab233560d2c6c4fc0963111dc Mon Sep 17 00:00:00 2001 From: Nicholas Mc Guire Date: Mon, 9 Feb 2015 09:41:49 -0500 Subject: [PATCH 03252/11651] tty: max3100: use msecs_to_jiffies for time conversion This is only an API consolidation and should make things more readable it replaces var * HZ / 1000 by msecs_to_jiffies(var). Signed-off-by: Nicholas Mc Guire Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/max3100.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/max3100.c b/drivers/tty/serial/max3100.c index 79f9a9eff545..077377259a2c 100644 --- a/drivers/tty/serial/max3100.c +++ b/drivers/tty/serial/max3100.c @@ -782,7 +782,7 @@ static int max3100_probe(struct spi_device *spi) pdata = dev_get_platdata(&spi->dev); max3100s[i]->crystal = pdata->crystal; max3100s[i]->loopback = pdata->loopback; - max3100s[i]->poll_time = pdata->poll_time * HZ / 1000; + max3100s[i]->poll_time = msecs_to_jiffies(pdata->poll_time); if (pdata->poll_time > 0 && max3100s[i]->poll_time == 0) max3100s[i]->poll_time = 1; max3100s[i]->max3100_hw_suspend = pdata->max3100_hw_suspend; -- GitLab From 722ccf416ac2804cdb9b5c84e81524fab775a577 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Thu, 12 Feb 2015 15:24:38 +0100 Subject: [PATCH 03253/11651] serial: atmel: fix error handling when mctrl_gpio_init fails MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mctrl_gpio_init at present doesn't return NULL. (It might be used in the future when no gpios are to be used indicating success.) Properly pass error returned and also make driver probing fail on error. Signed-off-by: Uwe Kleine-König Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/atmel_serial.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index 846552bff67d..4031dc367d3b 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -2542,8 +2542,8 @@ static int atmel_init_gpios(struct atmel_uart_port *p, struct device *dev) struct gpio_desc *gpiod; p->gpios = mctrl_gpio_init(dev, 0); - if (IS_ERR_OR_NULL(p->gpios)) - return -1; + if (IS_ERR(p->gpios)) + return PTR_ERR(p->gpios); for (i = 0; i < UART_GPIO_MAX; i++) { gpiod = mctrl_gpio_to_gpiod(p->gpios, i); @@ -2594,9 +2594,10 @@ static int atmel_serial_probe(struct platform_device *pdev) port->uart.line = ret; ret = atmel_init_gpios(port, &pdev->dev); - if (ret < 0) - dev_err(&pdev->dev, "%s", - "Failed to initialize GPIOs. The serial port may not work as expected"); + if (ret < 0) { + dev_err(&pdev->dev, "Failed to initialize GPIOs."); + goto err; + } ret = atmel_init_port(port, pdev); if (ret) -- GitLab From f059a455fc979e0e7f155d98bf628fccab1c5b88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Thu, 12 Feb 2015 15:24:39 +0100 Subject: [PATCH 03254/11651] serial: clps711x: fail if mctrl_gpio_init fails MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mctrl_gpio_init is fully aware of being optional. If it returns an error code this indicates a real error that must not be ignored. Signed-off-by: Uwe Kleine-König Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/clps711x.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/tty/serial/clps711x.c b/drivers/tty/serial/clps711x.c index 6e11c275f2ab..d5d2dd7c7917 100644 --- a/drivers/tty/serial/clps711x.c +++ b/drivers/tty/serial/clps711x.c @@ -501,6 +501,8 @@ static int uart_clps711x_probe(struct platform_device *pdev) platform_set_drvdata(pdev, s); s->gpios = mctrl_gpio_init(&pdev->dev, 0); + if (IS_ERR(s->gpios)) + return PTR_ERR(s->gpios); ret = uart_add_one_port(&clps711x_uart, &s->port); if (ret) -- GitLab From 343fda95481a7254fd81342370ba04ab255f95fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Thu, 12 Feb 2015 15:24:40 +0100 Subject: [PATCH 03255/11651] serial: mxs-auart: properly handle mctrl_gpio failing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If mctrl_gpio_init returns an error code this value should be forwarded and the driver must not simply ignore this failure. Signed-off-by: Uwe Kleine-König Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/mxs-auart.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c index d1298b6cc68e..9abdccf5bfb2 100644 --- a/drivers/tty/serial/mxs-auart.c +++ b/drivers/tty/serial/mxs-auart.c @@ -1155,14 +1155,14 @@ static int serial_mxs_probe_dt(struct mxs_auart_port *s, return 0; } -static bool mxs_auart_init_gpios(struct mxs_auart_port *s, struct device *dev) +static int mxs_auart_init_gpios(struct mxs_auart_port *s, struct device *dev) { enum mctrl_gpio_idx i; struct gpio_desc *gpiod; s->gpios = mctrl_gpio_init(dev, 0); - if (IS_ERR_OR_NULL(s->gpios)) - return false; + if (IS_ERR(s->gpios)) + return PTR_ERR(s->gpios); /* Block (enabled before) DMA option if RTS or CTS is GPIO line */ if (!RTS_AT_AUART() || !CTS_AT_AUART()) { @@ -1180,7 +1180,7 @@ static bool mxs_auart_init_gpios(struct mxs_auart_port *s, struct device *dev) s->gpio_irq[i] = -EINVAL; } - return true; + return 0; } static void mxs_auart_free_gpio_irq(struct mxs_auart_port *s) @@ -1276,9 +1276,11 @@ static int mxs_auart_probe(struct platform_device *pdev) platform_set_drvdata(pdev, s); - if (!mxs_auart_init_gpios(s, &pdev->dev)) - dev_err(&pdev->dev, - "Failed to initialize GPIOs. The serial port may not work as expected\n"); + ret = mxs_auart_init_gpios(s, &pdev->dev); + if (ret) { + dev_err(&pdev->dev, "Failed to initialize GPIOs.\n"); + got out_free_irq; + } /* * Get the GPIO lines IRQ -- GitLab From 9e9f079c56517568868788945dc4a080de6e150b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Thu, 12 Feb 2015 15:24:41 +0100 Subject: [PATCH 03256/11651] serial: mctrl-gpio: don't check for struct mctrl_gpios * to be invalid MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drivers using mctrl-gpio must not pass invalid values for struct mctrl_gpios *. All drivers were fixed in this regard and so some checks can go away or be simplified. Signed-off-by: Uwe Kleine-König Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/serial_mctrl_gpio.c | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/drivers/tty/serial/serial_mctrl_gpio.c b/drivers/tty/serial/serial_mctrl_gpio.c index a38596c5194e..c0381a09f12d 100644 --- a/drivers/tty/serial/serial_mctrl_gpio.c +++ b/drivers/tty/serial/serial_mctrl_gpio.c @@ -48,9 +48,6 @@ void mctrl_gpio_set(struct mctrl_gpios *gpios, unsigned int mctrl) int value_array[UART_GPIO_MAX]; unsigned int count = 0; - if (IS_ERR_OR_NULL(gpios)) - return; - for (i = 0; i < UART_GPIO_MAX; i++) if (!IS_ERR_OR_NULL(gpios->gpio[i]) && mctrl_gpios_desc[i].dir_out) { @@ -65,10 +62,7 @@ EXPORT_SYMBOL_GPL(mctrl_gpio_set); struct gpio_desc *mctrl_gpio_to_gpiod(struct mctrl_gpios *gpios, enum mctrl_gpio_idx gidx) { - if (!IS_ERR_OR_NULL(gpios) && !IS_ERR_OR_NULL(gpios->gpio[gidx])) - return gpios->gpio[gidx]; - else - return NULL; + return gpios->gpio[gidx]; } EXPORT_SYMBOL_GPL(mctrl_gpio_to_gpiod); @@ -76,15 +70,8 @@ unsigned int mctrl_gpio_get(struct mctrl_gpios *gpios, unsigned int *mctrl) { enum mctrl_gpio_idx i; - /* - * return it unchanged if the structure is not allocated - */ - if (IS_ERR_OR_NULL(gpios)) - return *mctrl; - for (i = 0; i < UART_GPIO_MAX; i++) { - if (!IS_ERR_OR_NULL(gpios->gpio[i]) && - !mctrl_gpios_desc[i].dir_out) { + if (gpios->gpio[i] && !mctrl_gpios_desc[i].dir_out) { if (gpiod_get_value(gpios->gpio[i])) *mctrl |= mctrl_gpios_desc[i].mctrl; else @@ -138,9 +125,6 @@ void mctrl_gpio_free(struct device *dev, struct mctrl_gpios *gpios) { enum mctrl_gpio_idx i; - if (IS_ERR_OR_NULL(gpios)) - return; - for (i = 0; i < UART_GPIO_MAX; i++) if (!IS_ERR_OR_NULL(gpios->gpio[i])) devm_gpiod_put(dev, gpios->gpio[i]); -- GitLab From 1d267ea6539f266352f4739c718e278dc62b1df7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Thu, 12 Feb 2015 15:24:42 +0100 Subject: [PATCH 03257/11651] serial: mctrl-gpio: simplify init routine MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of ignoring errors returned by devm_gpiod_get_index use devm_gpiod_get_index_optional which results in slightly more strict error handling which is good. Also use the fourth parameter to devm_gpiod_get_index_optional to be able to drop the explicit direction setting. Signed-off-by: Uwe Kleine-König Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/serial_mctrl_gpio.c | 29 ++++++++++---------------- 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/drivers/tty/serial/serial_mctrl_gpio.c b/drivers/tty/serial/serial_mctrl_gpio.c index c0381a09f12d..5027db7b5814 100644 --- a/drivers/tty/serial/serial_mctrl_gpio.c +++ b/drivers/tty/serial/serial_mctrl_gpio.c @@ -94,27 +94,20 @@ struct mctrl_gpios *mctrl_gpio_init(struct device *dev, unsigned int idx) return ERR_PTR(-ENOMEM); for (i = 0; i < UART_GPIO_MAX; i++) { - gpios->gpio[i] = devm_gpiod_get_index(dev, - mctrl_gpios_desc[i].name, - idx); - - /* - * The GPIOs are maybe not all filled, - * this is not an error. - */ - if (IS_ERR_OR_NULL(gpios->gpio[i])) - continue; + enum gpiod_flags flags; if (mctrl_gpios_desc[i].dir_out) - err = gpiod_direction_output(gpios->gpio[i], 0); + flags = GPIOD_OUT_LOW; else - err = gpiod_direction_input(gpios->gpio[i]); - if (err) { - dev_dbg(dev, "Unable to set direction for %s GPIO", - mctrl_gpios_desc[i].name); - devm_gpiod_put(dev, gpios->gpio[i]); - gpios->gpio[i] = NULL; - } + flags = GPIOD_IN; + + gpios->gpio[i] = + devm_gpiod_get_index_optional(dev, + mctrl_gpios_desc[i].name, + idx, flags); + + if (IS_ERR(gpios->gpio[i])) + return PTR_ERR(gpios->gpio[i]); } return gpios; -- GitLab From bb8478d7d676802211a9a5d77bd0f87899900e41 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 23 Feb 2015 11:34:30 +0800 Subject: [PATCH 03258/11651] serial: ar933x_uart: Fix off-by-one for checking valid alias id Current code uses the alias id as array subscript of ar933x_console_ports. So the valid id is 0 ... CONFIG_SERIAL_AR933X_NR_UARTS - 1. Signed-off-by: Axel Lin Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/ar933x_uart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/ar933x_uart.c b/drivers/tty/serial/ar933x_uart.c index 77fc9faa74a4..1519d2ca7705 100644 --- a/drivers/tty/serial/ar933x_uart.c +++ b/drivers/tty/serial/ar933x_uart.c @@ -649,7 +649,7 @@ static int ar933x_uart_probe(struct platform_device *pdev) id = 0; } - if (id > CONFIG_SERIAL_AR933X_NR_UARTS) + if (id >= CONFIG_SERIAL_AR933X_NR_UARTS) return -EINVAL; irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); -- GitLab From 84e0185efaf8de931e1aab0687d8f8acd186a1c0 Mon Sep 17 00:00:00 2001 From: Joseph Kogut Date: Sun, 22 Feb 2015 17:26:57 -0700 Subject: [PATCH 03259/11651] tty: serial: s/Medfile/Medfield Fixed misspelling of 'Medfield' Signed-off-by: Joseph Kogut Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 2b619e511b9e..60c368a5dbf1 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -489,7 +489,7 @@ config SERIAL_MFD_HSU select SERIAL_CORE config SERIAL_MFD_HSU_CONSOLE - bool "Medfile HSU serial console support" + bool "Medfield HSU serial console support" depends on SERIAL_MFD_HSU=y select SERIAL_CORE_CONSOLE -- GitLab From 2b49e0c56741fca538176f66ed3c8d16ce4fccd8 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 23 Feb 2015 16:24:42 +0200 Subject: [PATCH 03260/11651] dmaengine: append hsu DMA driver The HSU DMA is developed to support High Speed UART controllers found in particular on Intel MID platforms such as Intel Medfield. The existing implementation is tighten to the drivers/tty/serial/mfd.c driver and has a lot of disadvantages. Besides that we would like to get rid of the old HS UART driver in regarding to extending the 8250 which supports generic DMAEngine API. That's why the current driver has been developed. Signed-off-by: Andy Shevchenko Signed-off-by: Greg Kroah-Hartman --- drivers/dma/Kconfig | 2 + drivers/dma/Makefile | 1 + drivers/dma/hsu/Kconfig | 14 + drivers/dma/hsu/Makefile | 5 + drivers/dma/hsu/hsu.c | 504 ++++++++++++++++++++++++++ drivers/dma/hsu/hsu.h | 118 ++++++ drivers/dma/hsu/pci.c | 123 +++++++ include/linux/dma/hsu.h | 48 +++ include/linux/platform_data/dma-hsu.h | 25 ++ 9 files changed, 840 insertions(+) create mode 100644 drivers/dma/hsu/Kconfig create mode 100644 drivers/dma/hsu/Makefile create mode 100644 drivers/dma/hsu/hsu.c create mode 100644 drivers/dma/hsu/hsu.h create mode 100644 drivers/dma/hsu/pci.c create mode 100644 include/linux/dma/hsu.h create mode 100644 include/linux/platform_data/dma-hsu.h diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index a874b6ec6650..074ffad334a7 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -125,6 +125,8 @@ config FSL_DMA EloPlus is on mpc85xx and mpc86xx and Pxxx parts, and the Elo3 is on some Txxx and Bxxx parts. +source "drivers/dma/hsu/Kconfig" + config MPC512X_DMA tristate "Freescale MPC512x built-in DMA engine support" depends on PPC_MPC512x || PPC_MPC831x diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile index f915f61ec574..bf4485800c60 100644 --- a/drivers/dma/Makefile +++ b/drivers/dma/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_DMATEST) += dmatest.o obj-$(CONFIG_INTEL_IOATDMA) += ioat/ obj-$(CONFIG_INTEL_IOP_ADMA) += iop-adma.o obj-$(CONFIG_FSL_DMA) += fsldma.o +obj-$(CONFIG_HSU_DMA) += hsu/ obj-$(CONFIG_MPC512X_DMA) += mpc512x_dma.o obj-$(CONFIG_PPC_BESTCOMM) += bestcomm/ obj-$(CONFIG_MV_XOR) += mv_xor.o diff --git a/drivers/dma/hsu/Kconfig b/drivers/dma/hsu/Kconfig new file mode 100644 index 000000000000..7e98eff7440e --- /dev/null +++ b/drivers/dma/hsu/Kconfig @@ -0,0 +1,14 @@ +# DMA engine configuration for hsu +config HSU_DMA + tristate "High Speed UART DMA support" + select DMA_ENGINE + select DMA_VIRTUAL_CHANNELS + +config HSU_DMA_PCI + tristate "High Speed UART DMA PCI driver" + depends on PCI + select HSU_DMA + help + Support the High Speed UART DMA on the platfroms that + enumerate it as a PCI device. For example, Intel Medfield + has integrated this HSU DMA controller. diff --git a/drivers/dma/hsu/Makefile b/drivers/dma/hsu/Makefile new file mode 100644 index 000000000000..b8f9af032ef1 --- /dev/null +++ b/drivers/dma/hsu/Makefile @@ -0,0 +1,5 @@ +obj-$(CONFIG_HSU_DMA) += hsu_dma.o +hsu_dma-objs := hsu.o + +obj-$(CONFIG_HSU_DMA_PCI) += hsu_dma_pci.o +hsu_dma_pci-objs := pci.o diff --git a/drivers/dma/hsu/hsu.c b/drivers/dma/hsu/hsu.c new file mode 100644 index 000000000000..683ba9b62795 --- /dev/null +++ b/drivers/dma/hsu/hsu.c @@ -0,0 +1,504 @@ +/* + * Core driver for the High Speed UART DMA + * + * Copyright (C) 2015 Intel Corporation + * Author: Andy Shevchenko + * + * Partially based on the bits found in drivers/tty/serial/mfd.c. + * + * 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. + */ + +/* + * DMA channel allocation: + * 1. Even number chans are used for DMA Read (UART TX), odd chans for DMA + * Write (UART RX). + * 2. 0/1 channel are assigned to port 0, 2/3 chan to port 1, 4/5 chan to + * port 3, and so on. + */ + +#include +#include +#include +#include +#include +#include + +#include "hsu.h" + +#define HSU_DMA_BUSWIDTHS \ + BIT(DMA_SLAVE_BUSWIDTH_UNDEFINED) | \ + BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \ + BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \ + BIT(DMA_SLAVE_BUSWIDTH_3_BYTES) | \ + BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) | \ + BIT(DMA_SLAVE_BUSWIDTH_8_BYTES) | \ + BIT(DMA_SLAVE_BUSWIDTH_16_BYTES) + +static inline void hsu_chan_disable(struct hsu_dma_chan *hsuc) +{ + hsu_chan_writel(hsuc, HSU_CH_CR, 0); +} + +static inline void hsu_chan_enable(struct hsu_dma_chan *hsuc) +{ + u32 cr = HSU_CH_CR_CHA; + + if (hsuc->direction == DMA_MEM_TO_DEV) + cr &= ~HSU_CH_CR_CHD; + else if (hsuc->direction == DMA_DEV_TO_MEM) + cr |= HSU_CH_CR_CHD; + + hsu_chan_writel(hsuc, HSU_CH_CR, cr); +} + +static void hsu_dma_chan_start(struct hsu_dma_chan *hsuc) +{ + struct dma_slave_config *config = &hsuc->config; + struct hsu_dma_desc *desc = hsuc->desc; + u32 bsr, mtsr; + u32 dcr = HSU_CH_DCR_CHSOE | HSU_CH_DCR_CHEI; + unsigned int i, count; + + if (hsuc->direction == DMA_MEM_TO_DEV) { + bsr = config->dst_maxburst; + mtsr = config->dst_addr_width; + } else if (hsuc->direction == DMA_DEV_TO_MEM) { + bsr = config->src_maxburst; + mtsr = config->src_addr_width; + } else { + /* Not supported direction */ + return; + } + + hsu_chan_disable(hsuc); + + hsu_chan_writel(hsuc, HSU_CH_DCR, 0); + hsu_chan_writel(hsuc, HSU_CH_BSR, bsr); + hsu_chan_writel(hsuc, HSU_CH_MTSR, mtsr); + + /* Set descriptors */ + count = (desc->nents - desc->active) % HSU_DMA_CHAN_NR_DESC; + for (i = 0; i < count; i++) { + hsu_chan_writel(hsuc, HSU_CH_DxSAR(i), desc->sg[i].addr); + hsu_chan_writel(hsuc, HSU_CH_DxTSR(i), desc->sg[i].len); + + /* Prepare value for DCR */ + dcr |= HSU_CH_DCR_DESCA(i); + dcr |= HSU_CH_DCR_CHTOI(i); /* timeout bit, see HSU Errata 1 */ + + desc->active++; + } + /* Only for the last descriptor in the chain */ + dcr |= HSU_CH_DCR_CHSOD(count - 1); + dcr |= HSU_CH_DCR_CHDI(count - 1); + + hsu_chan_writel(hsuc, HSU_CH_DCR, dcr); + + hsu_chan_enable(hsuc); +} + +static void hsu_dma_stop_channel(struct hsu_dma_chan *hsuc) +{ + unsigned long flags; + + spin_lock_irqsave(&hsuc->lock, flags); + hsu_chan_disable(hsuc); + hsu_chan_writel(hsuc, HSU_CH_DCR, 0); + spin_unlock_irqrestore(&hsuc->lock, flags); +} + +static void hsu_dma_start_channel(struct hsu_dma_chan *hsuc) +{ + unsigned long flags; + + spin_lock_irqsave(&hsuc->lock, flags); + hsu_dma_chan_start(hsuc); + spin_unlock_irqrestore(&hsuc->lock, flags); +} + +static void hsu_dma_start_transfer(struct hsu_dma_chan *hsuc) +{ + struct virt_dma_desc *vdesc; + + /* Get the next descriptor */ + vdesc = vchan_next_desc(&hsuc->vchan); + if (!vdesc) { + hsuc->desc = NULL; + return; + } + + list_del(&vdesc->node); + hsuc->desc = to_hsu_dma_desc(vdesc); + + /* Start the channel with a new descriptor */ + hsu_dma_start_channel(hsuc); +} + +static u32 hsu_dma_chan_get_sr(struct hsu_dma_chan *hsuc) +{ + unsigned long flags; + u32 sr; + + spin_lock_irqsave(&hsuc->lock, flags); + sr = hsu_chan_readl(hsuc, HSU_CH_SR); + spin_unlock_irqrestore(&hsuc->lock, flags); + + return sr; +} + +irqreturn_t hsu_dma_irq(struct hsu_dma_chip *chip, unsigned short nr) +{ + struct hsu_dma_chan *hsuc; + struct hsu_dma_desc *desc; + unsigned long flags; + u32 sr; + + /* Sanity check */ + if (nr >= chip->pdata->nr_channels) + return IRQ_NONE; + + hsuc = &chip->hsu->chan[nr]; + + /* + * No matter what situation, need read clear the IRQ status + * There is a bug, see Errata 5, HSD 2900918 + */ + sr = hsu_dma_chan_get_sr(hsuc); + if (!sr) + return IRQ_NONE; + + /* Timeout IRQ, need wait some time, see Errata 2 */ + if (hsuc->direction == DMA_DEV_TO_MEM && (sr & HSU_CH_SR_DESCTO_ANY)) + udelay(2); + + sr &= ~HSU_CH_SR_DESCTO_ANY; + if (!sr) + return IRQ_HANDLED; + + spin_lock_irqsave(&hsuc->vchan.lock, flags); + desc = hsuc->desc; + if (desc) { + if (sr & HSU_CH_SR_CHE) { + desc->status = DMA_ERROR; + } else if (desc->active < desc->nents) { + hsu_dma_start_channel(hsuc); + } else { + vchan_cookie_complete(&desc->vdesc); + desc->status = DMA_COMPLETE; + hsu_dma_start_transfer(hsuc); + } + } + spin_unlock_irqrestore(&hsuc->vchan.lock, flags); + + return IRQ_HANDLED; +} +EXPORT_SYMBOL_GPL(hsu_dma_irq); + +static struct hsu_dma_desc *hsu_dma_alloc_desc(unsigned int nents) +{ + struct hsu_dma_desc *desc; + + desc = kzalloc(sizeof(*desc), GFP_ATOMIC); + if (!desc) + return NULL; + + desc->sg = kcalloc(nents, sizeof(*desc->sg), GFP_ATOMIC); + if (!desc->sg) { + kfree(desc); + return NULL; + } + + return desc; +} + +static void hsu_dma_desc_free(struct virt_dma_desc *vdesc) +{ + struct hsu_dma_desc *desc = to_hsu_dma_desc(vdesc); + + kfree(desc->sg); + kfree(desc); +} + +static struct dma_async_tx_descriptor *hsu_dma_prep_slave_sg( + struct dma_chan *chan, struct scatterlist *sgl, + unsigned int sg_len, enum dma_transfer_direction direction, + unsigned long flags, void *context) +{ + struct hsu_dma_chan *hsuc = to_hsu_dma_chan(chan); + struct hsu_dma_desc *desc; + struct scatterlist *sg; + unsigned int i; + + desc = hsu_dma_alloc_desc(sg_len); + if (!desc) + return NULL; + + for_each_sg(sgl, sg, sg_len, i) { + desc->sg[i].addr = sg_dma_address(sg); + desc->sg[i].len = sg_dma_len(sg); + } + + desc->nents = sg_len; + desc->direction = direction; + desc->active = 0; + desc->status = DMA_IN_PROGRESS; + + return vchan_tx_prep(&hsuc->vchan, &desc->vdesc, flags); +} + +static void hsu_dma_issue_pending(struct dma_chan *chan) +{ + struct hsu_dma_chan *hsuc = to_hsu_dma_chan(chan); + unsigned long flags; + + spin_lock_irqsave(&hsuc->vchan.lock, flags); + if (vchan_issue_pending(&hsuc->vchan) && !hsuc->desc) + hsu_dma_start_transfer(hsuc); + spin_unlock_irqrestore(&hsuc->vchan.lock, flags); +} + +static size_t hsu_dma_desc_size(struct hsu_dma_desc *desc) +{ + size_t bytes = 0; + unsigned int i; + + for (i = desc->active; i < desc->nents; i++) + bytes += desc->sg[i].len; + + return bytes; +} + +static size_t hsu_dma_active_desc_size(struct hsu_dma_chan *hsuc) +{ + struct hsu_dma_desc *desc = hsuc->desc; + size_t bytes = hsu_dma_desc_size(desc); + int i; + unsigned long flags; + + spin_lock_irqsave(&hsuc->lock, flags); + i = desc->active % HSU_DMA_CHAN_NR_DESC; + do { + bytes += hsu_chan_readl(hsuc, HSU_CH_DxTSR(i)); + } while (--i >= 0); + spin_unlock_irqrestore(&hsuc->lock, flags); + + return bytes; +} + +static enum dma_status hsu_dma_tx_status(struct dma_chan *chan, + dma_cookie_t cookie, struct dma_tx_state *state) +{ + struct hsu_dma_chan *hsuc = to_hsu_dma_chan(chan); + struct virt_dma_desc *vdesc; + enum dma_status status; + size_t bytes; + unsigned long flags; + + status = dma_cookie_status(chan, cookie, state); + if (status == DMA_COMPLETE) + return status; + + spin_lock_irqsave(&hsuc->vchan.lock, flags); + vdesc = vchan_find_desc(&hsuc->vchan, cookie); + if (hsuc->desc && cookie == hsuc->desc->vdesc.tx.cookie) { + bytes = hsu_dma_active_desc_size(hsuc); + dma_set_residue(state, bytes); + status = hsuc->desc->status; + } else if (vdesc) { + bytes = hsu_dma_desc_size(to_hsu_dma_desc(vdesc)); + dma_set_residue(state, bytes); + } + spin_unlock_irqrestore(&hsuc->vchan.lock, flags); + + return status; +} + +static int hsu_dma_slave_config(struct dma_chan *chan, + struct dma_slave_config *config) +{ + struct hsu_dma_chan *hsuc = to_hsu_dma_chan(chan); + + /* Check if chan will be configured for slave transfers */ + if (!is_slave_direction(config->direction)) + return -EINVAL; + + memcpy(&hsuc->config, config, sizeof(hsuc->config)); + + return 0; +} + +static void hsu_dma_chan_deactivate(struct hsu_dma_chan *hsuc) +{ + unsigned long flags; + + spin_lock_irqsave(&hsuc->lock, flags); + hsu_chan_disable(hsuc); + spin_unlock_irqrestore(&hsuc->lock, flags); +} + +static void hsu_dma_chan_activate(struct hsu_dma_chan *hsuc) +{ + unsigned long flags; + + spin_lock_irqsave(&hsuc->lock, flags); + hsu_chan_enable(hsuc); + spin_unlock_irqrestore(&hsuc->lock, flags); +} + +static int hsu_dma_pause(struct dma_chan *chan) +{ + struct hsu_dma_chan *hsuc = to_hsu_dma_chan(chan); + unsigned long flags; + + spin_lock_irqsave(&hsuc->vchan.lock, flags); + if (hsuc->desc && hsuc->desc->status == DMA_IN_PROGRESS) { + hsu_dma_chan_deactivate(hsuc); + hsuc->desc->status = DMA_PAUSED; + } + spin_unlock_irqrestore(&hsuc->vchan.lock, flags); + + return 0; +} + +static int hsu_dma_resume(struct dma_chan *chan) +{ + struct hsu_dma_chan *hsuc = to_hsu_dma_chan(chan); + unsigned long flags; + + spin_lock_irqsave(&hsuc->vchan.lock, flags); + if (hsuc->desc && hsuc->desc->status == DMA_PAUSED) { + hsuc->desc->status = DMA_IN_PROGRESS; + hsu_dma_chan_activate(hsuc); + } + spin_unlock_irqrestore(&hsuc->vchan.lock, flags); + + return 0; +} + +static int hsu_dma_terminate_all(struct dma_chan *chan) +{ + struct hsu_dma_chan *hsuc = to_hsu_dma_chan(chan); + unsigned long flags; + LIST_HEAD(head); + + spin_lock_irqsave(&hsuc->vchan.lock, flags); + + hsu_dma_stop_channel(hsuc); + hsuc->desc = NULL; + + vchan_get_all_descriptors(&hsuc->vchan, &head); + spin_unlock_irqrestore(&hsuc->vchan.lock, flags); + vchan_dma_desc_free_list(&hsuc->vchan, &head); + + return 0; +} + +static int hsu_dma_alloc_chan_resources(struct dma_chan *chan) +{ + return 0; +} + +static void hsu_dma_free_chan_resources(struct dma_chan *chan) +{ + vchan_free_chan_resources(to_virt_chan(chan)); +} + +int hsu_dma_probe(struct hsu_dma_chip *chip) +{ + struct hsu_dma *hsu; + struct hsu_dma_platform_data *pdata = chip->pdata; + void __iomem *addr = chip->regs + chip->offset; + unsigned short i; + int ret; + + hsu = devm_kzalloc(chip->dev, sizeof(*hsu), GFP_KERNEL); + if (!hsu) + return -ENOMEM; + + chip->hsu = hsu; + + if (!pdata) { + pdata = devm_kzalloc(chip->dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + chip->pdata = pdata; + + /* Guess nr_channels from the IO space length */ + pdata->nr_channels = (chip->length - chip->offset) / + HSU_DMA_CHAN_LENGTH; + } + + hsu->chan = devm_kcalloc(chip->dev, pdata->nr_channels, + sizeof(*hsu->chan), GFP_KERNEL); + if (!hsu->chan) + return -ENOMEM; + + INIT_LIST_HEAD(&hsu->dma.channels); + for (i = 0; i < pdata->nr_channels; i++) { + struct hsu_dma_chan *hsuc = &hsu->chan[i]; + + hsuc->vchan.desc_free = hsu_dma_desc_free; + vchan_init(&hsuc->vchan, &hsu->dma); + + hsuc->direction = (i & 0x1) ? DMA_DEV_TO_MEM : DMA_MEM_TO_DEV; + hsuc->reg = addr + i * HSU_DMA_CHAN_LENGTH; + + spin_lock_init(&hsuc->lock); + } + + dma_cap_set(DMA_SLAVE, hsu->dma.cap_mask); + dma_cap_set(DMA_PRIVATE, hsu->dma.cap_mask); + + hsu->dma.device_alloc_chan_resources = hsu_dma_alloc_chan_resources; + hsu->dma.device_free_chan_resources = hsu_dma_free_chan_resources; + + hsu->dma.device_prep_slave_sg = hsu_dma_prep_slave_sg; + + hsu->dma.device_issue_pending = hsu_dma_issue_pending; + hsu->dma.device_tx_status = hsu_dma_tx_status; + + hsu->dma.device_config = hsu_dma_slave_config; + hsu->dma.device_pause = hsu_dma_pause; + hsu->dma.device_resume = hsu_dma_resume; + hsu->dma.device_terminate_all = hsu_dma_terminate_all; + + hsu->dma.src_addr_widths = HSU_DMA_BUSWIDTHS; + hsu->dma.dst_addr_widths = HSU_DMA_BUSWIDTHS; + hsu->dma.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); + hsu->dma.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST; + + hsu->dma.dev = chip->dev; + + ret = dma_async_device_register(&hsu->dma); + if (ret) + return ret; + + dev_info(chip->dev, "Found HSU DMA, %d channels\n", pdata->nr_channels); + return 0; +} +EXPORT_SYMBOL_GPL(hsu_dma_probe); + +int hsu_dma_remove(struct hsu_dma_chip *chip) +{ + struct hsu_dma *hsu = chip->hsu; + unsigned short i; + + dma_async_device_unregister(&hsu->dma); + + for (i = 0; i < chip->pdata->nr_channels; i++) { + struct hsu_dma_chan *hsuc = &hsu->chan[i]; + + tasklet_kill(&hsuc->vchan.task); + } + + return 0; +} +EXPORT_SYMBOL_GPL(hsu_dma_remove); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("High Speed UART DMA core driver"); +MODULE_AUTHOR("Andy Shevchenko "); diff --git a/drivers/dma/hsu/hsu.h b/drivers/dma/hsu/hsu.h new file mode 100644 index 000000000000..0275233cf550 --- /dev/null +++ b/drivers/dma/hsu/hsu.h @@ -0,0 +1,118 @@ +/* + * Driver for the High Speed UART DMA + * + * Copyright (C) 2015 Intel Corporation + * + * Partially based on the bits found in drivers/tty/serial/mfd.c. + * + * 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. + */ + +#ifndef __DMA_HSU_H__ +#define __DMA_HSU_H__ + +#include +#include + +#include "../virt-dma.h" + +#define HSU_CH_SR 0x00 /* channel status */ +#define HSU_CH_CR 0x04 /* channel control */ +#define HSU_CH_DCR 0x08 /* descriptor control */ +#define HSU_CH_BSR 0x10 /* FIFO buffer size */ +#define HSU_CH_MTSR 0x14 /* minimum transfer size */ +#define HSU_CH_DxSAR(x) (0x20 + 8 * (x)) /* desc start addr */ +#define HSU_CH_DxTSR(x) (0x24 + 8 * (x)) /* desc transfer size */ +#define HSU_CH_D0SAR 0x20 /* desc 0 start addr */ +#define HSU_CH_D0TSR 0x24 /* desc 0 transfer size */ +#define HSU_CH_D1SAR 0x28 +#define HSU_CH_D1TSR 0x2c +#define HSU_CH_D2SAR 0x30 +#define HSU_CH_D2TSR 0x34 +#define HSU_CH_D3SAR 0x38 +#define HSU_CH_D3TSR 0x3c + +#define HSU_DMA_CHAN_NR_DESC 4 +#define HSU_DMA_CHAN_LENGTH 0x40 + +/* Bits in HSU_CH_SR */ +#define HSU_CH_SR_DESCTO(x) BIT(8 + (x)) +#define HSU_CH_SR_DESCTO_ANY (BIT(11) | BIT(10) | BIT(9) | BIT(8)) +#define HSU_CH_SR_CHE BIT(15) + +/* Bits in HSU_CH_CR */ +#define HSU_CH_CR_CHA BIT(0) +#define HSU_CH_CR_CHD BIT(1) + +/* Bits in HSU_CH_DCR */ +#define HSU_CH_DCR_DESCA(x) BIT(0 + (x)) +#define HSU_CH_DCR_CHSOD(x) BIT(8 + (x)) +#define HSU_CH_DCR_CHSOTO BIT(14) +#define HSU_CH_DCR_CHSOE BIT(15) +#define HSU_CH_DCR_CHDI(x) BIT(16 + (x)) +#define HSU_CH_DCR_CHEI BIT(23) +#define HSU_CH_DCR_CHTOI(x) BIT(24 + (x)) + +struct hsu_dma_sg { + dma_addr_t addr; + unsigned int len; +}; + +struct hsu_dma_desc { + struct virt_dma_desc vdesc; + enum dma_transfer_direction direction; + struct hsu_dma_sg *sg; + unsigned int nents; + unsigned int active; + enum dma_status status; +}; + +static inline struct hsu_dma_desc *to_hsu_dma_desc(struct virt_dma_desc *vdesc) +{ + return container_of(vdesc, struct hsu_dma_desc, vdesc); +} + +struct hsu_dma_chan { + struct virt_dma_chan vchan; + + void __iomem *reg; + spinlock_t lock; + + /* hardware configuration */ + enum dma_transfer_direction direction; + struct dma_slave_config config; + + struct hsu_dma_desc *desc; +}; + +static inline struct hsu_dma_chan *to_hsu_dma_chan(struct dma_chan *chan) +{ + return container_of(chan, struct hsu_dma_chan, vchan.chan); +} + +static inline u32 hsu_chan_readl(struct hsu_dma_chan *hsuc, int offset) +{ + return readl(hsuc->reg + offset); +} + +static inline void hsu_chan_writel(struct hsu_dma_chan *hsuc, int offset, + u32 value) +{ + writel(value, hsuc->reg + offset); +} + +struct hsu_dma { + struct dma_device dma; + + /* channels */ + struct hsu_dma_chan *chan; +}; + +static inline struct hsu_dma *to_hsu_dma(struct dma_device *ddev) +{ + return container_of(ddev, struct hsu_dma, dma); +} + +#endif /* __DMA_HSU_H__ */ diff --git a/drivers/dma/hsu/pci.c b/drivers/dma/hsu/pci.c new file mode 100644 index 000000000000..563b4685d766 --- /dev/null +++ b/drivers/dma/hsu/pci.c @@ -0,0 +1,123 @@ +/* + * PCI driver for the High Speed UART DMA + * + * Copyright (C) 2015 Intel Corporation + * Author: Andy Shevchenko + * + * Partially based on the bits found in drivers/tty/serial/mfd.c. + * + * 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 +#include +#include +#include + +#include "hsu.h" + +#define HSU_PCI_DMASR 0x00 +#define HSU_PCI_DMAISR 0x04 + +#define HSU_PCI_CHAN_OFFSET 0x100 + +static irqreturn_t hsu_pci_irq(int irq, void *dev) +{ + struct hsu_dma_chip *chip = dev; + u32 dmaisr; + unsigned short i; + irqreturn_t ret = IRQ_NONE; + + dmaisr = readl(chip->regs + HSU_PCI_DMAISR); + for (i = 0; i < chip->pdata->nr_channels; i++) { + if (dmaisr & 0x1) + ret |= hsu_dma_irq(chip, i); + dmaisr >>= 1; + } + + return ret; +} + +static int hsu_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) +{ + struct hsu_dma_chip *chip; + int ret; + + ret = pcim_enable_device(pdev); + if (ret) + return ret; + + ret = pcim_iomap_regions(pdev, BIT(0), pci_name(pdev)); + if (ret) { + dev_err(&pdev->dev, "I/O memory remapping failed\n"); + return ret; + } + + pci_set_master(pdev); + pci_try_set_mwi(pdev); + + ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); + if (ret) + return ret; + + ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); + if (ret) + return ret; + + chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL); + if (!chip) + return -ENOMEM; + + chip->dev = &pdev->dev; + chip->regs = pcim_iomap_table(pdev)[0]; + chip->length = pci_resource_len(pdev, 0); + chip->offset = HSU_PCI_CHAN_OFFSET; + chip->irq = pdev->irq; + + pci_enable_msi(pdev); + + ret = hsu_dma_probe(chip); + if (ret) + return ret; + + ret = request_irq(chip->irq, hsu_pci_irq, 0, "hsu_dma_pci", chip); + if (ret) + goto err_register_irq; + + pci_set_drvdata(pdev, chip); + + return 0; + +err_register_irq: + hsu_dma_remove(chip); + return ret; +} + +static void hsu_pci_remove(struct pci_dev *pdev) +{ + struct hsu_dma_chip *chip = pci_get_drvdata(pdev); + + free_irq(chip->irq, chip); + hsu_dma_remove(chip); +} + +static const struct pci_device_id hsu_pci_id_table[] = { + { PCI_VDEVICE(INTEL, 0x081e), 0 }, + { } +}; +MODULE_DEVICE_TABLE(pci, hsu_pci_id_table); + +static struct pci_driver hsu_pci_driver = { + .name = "hsu_dma_pci", + .id_table = hsu_pci_id_table, + .probe = hsu_pci_probe, + .remove = hsu_pci_remove, +}; + +module_pci_driver(hsu_pci_driver); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("High Speed UART DMA PCI driver"); +MODULE_AUTHOR("Andy Shevchenko "); diff --git a/include/linux/dma/hsu.h b/include/linux/dma/hsu.h new file mode 100644 index 000000000000..234393a6997b --- /dev/null +++ b/include/linux/dma/hsu.h @@ -0,0 +1,48 @@ +/* + * Driver for the High Speed UART DMA + * + * Copyright (C) 2015 Intel Corporation + * + * 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. + */ + +#ifndef _DMA_HSU_H +#define _DMA_HSU_H + +#include +#include + +#include + +struct hsu_dma; + +/** + * struct hsu_dma_chip - representation of HSU DMA hardware + * @dev: struct device of the DMA controller + * @irq: irq line + * @regs: memory mapped I/O space + * @length: I/O space length + * @offset: offset of the I/O space where registers are located + * @hsu: struct hsu_dma that is filed by ->probe() + * @pdata: platform data for the DMA controller if provided + */ +struct hsu_dma_chip { + struct device *dev; + int irq; + void __iomem *regs; + unsigned int length; + unsigned int offset; + struct hsu_dma *hsu; + struct hsu_dma_platform_data *pdata; +}; + +/* Export to the internal users */ +irqreturn_t hsu_dma_irq(struct hsu_dma_chip *chip, unsigned short nr); + +/* Export to the platform drivers */ +int hsu_dma_probe(struct hsu_dma_chip *chip); +int hsu_dma_remove(struct hsu_dma_chip *chip); + +#endif /* _DMA_HSU_H */ diff --git a/include/linux/platform_data/dma-hsu.h b/include/linux/platform_data/dma-hsu.h new file mode 100644 index 000000000000..8a1f6a4920b2 --- /dev/null +++ b/include/linux/platform_data/dma-hsu.h @@ -0,0 +1,25 @@ +/* + * Driver for the High Speed UART DMA + * + * Copyright (C) 2015 Intel Corporation + * + * 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. + */ + +#ifndef _PLATFORM_DATA_DMA_HSU_H +#define _PLATFORM_DATA_DMA_HSU_H + +#include + +struct hsu_dma_slave { + struct device *dma_dev; + int chan_id; +}; + +struct hsu_dma_platform_data { + unsigned short nr_channels; +}; + +#endif /* _PLATFORM_DATA_DMA_HSU_H */ -- GitLab From f549e94effa163ea170d2f0c12d307cb602431c6 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 23 Feb 2015 16:24:43 +0200 Subject: [PATCH 03261/11651] serial: 8250_pci: add Intel Penwell ports Intel Penwell supports 3 HSUART ports which are 8250 compatible. The patch adds necessary bits to the driver. The functions have intel_mid_* prefix due to more than one platform will use this code. Signed-off-by: Andy Shevchenko Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_pci.c | 183 +++++++++++++++++++++++++++++ 1 file changed, 183 insertions(+) diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index fbe919410e0f..c03199e122ed 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -27,6 +27,7 @@ #include #include +#include #include "8250.h" @@ -1525,6 +1526,148 @@ byt_serial_setup(struct serial_private *priv, return ret; } +#define INTEL_MID_UART_PS 0x30 +#define INTEL_MID_UART_MUL 0x34 + +static void intel_mid_set_termios_50M(struct uart_port *p, + struct ktermios *termios, + struct ktermios *old) +{ + unsigned int baud = tty_termios_baud_rate(termios); + u32 ps, mul; + + /* + * The uart clk is 50Mhz, and the baud rate come from: + * baud = 50M * MUL / (DIV * PS * DLAB) + * + * For those basic low baud rate we can get the direct + * scalar from 2746800, like 115200 = 2746800/24. For those + * higher baud rate, we handle them case by case, mainly by + * adjusting the MUL/PS registers, and DIV register is kept + * as default value 0x3d09 to make things simple. + */ + + ps = 0x10; + + switch (baud) { + case 500000: + case 1000000: + case 1500000: + case 3000000: + mul = 0x3a98; + p->uartclk = 48000000; + break; + case 2000000: + case 4000000: + mul = 0x2710; + ps = 0x08; + p->uartclk = 64000000; + break; + case 2500000: + mul = 0x30d4; + p->uartclk = 40000000; + break; + case 3500000: + mul = 0x3345; + ps = 0x0c; + p->uartclk = 56000000; + break; + default: + mul = 0x2400; + p->uartclk = 29491200; + } + + writel(ps, p->membase + INTEL_MID_UART_PS); /* set PS */ + writel(mul, p->membase + INTEL_MID_UART_MUL); /* set MUL */ + + serial8250_do_set_termios(p, termios, old); +} + +static bool intel_mid_dma_filter(struct dma_chan *chan, void *param) +{ + struct hsu_dma_slave *s = param; + + if (s->dma_dev != chan->device->dev || s->chan_id != chan->chan_id) + return false; + + chan->private = s; + return true; +} + +static int intel_mid_serial_setup(struct serial_private *priv, + const struct pciserial_board *board, + struct uart_8250_port *port, int idx, + int index, struct pci_dev *dma_dev) +{ + struct device *dev = port->port.dev; + struct uart_8250_dma *dma; + struct hsu_dma_slave *tx_param, *rx_param; + + dma = devm_kzalloc(dev, sizeof(*dma), GFP_KERNEL); + if (!dma) + return -ENOMEM; + + tx_param = devm_kzalloc(dev, sizeof(*tx_param), GFP_KERNEL); + if (!tx_param) + return -ENOMEM; + + rx_param = devm_kzalloc(dev, sizeof(*rx_param), GFP_KERNEL); + if (!rx_param) + return -ENOMEM; + + rx_param->chan_id = index * 2 + 1; + tx_param->chan_id = index * 2; + + dma->rxconf.src_maxburst = 64; + dma->txconf.dst_maxburst = 64; + + rx_param->dma_dev = &dma_dev->dev; + tx_param->dma_dev = &dma_dev->dev; + + dma->fn = intel_mid_dma_filter; + dma->rx_param = rx_param; + dma->tx_param = tx_param; + + port->port.type = PORT_16750; + port->port.flags |= UPF_FIXED_PORT | UPF_FIXED_TYPE; + port->dma = dma; + + return pci_default_setup(priv, board, port, idx); +} + +#define PCI_DEVICE_ID_INTEL_PNW_UART1 0x081b +#define PCI_DEVICE_ID_INTEL_PNW_UART2 0x081c +#define PCI_DEVICE_ID_INTEL_PNW_UART3 0x081d + +static int pnw_serial_setup(struct serial_private *priv, + const struct pciserial_board *board, + struct uart_8250_port *port, int idx) +{ + struct pci_dev *pdev = priv->dev; + struct pci_dev *dma_dev; + int index; + + switch (pdev->device) { + case PCI_DEVICE_ID_INTEL_PNW_UART1: + index = 0; + break; + case PCI_DEVICE_ID_INTEL_PNW_UART2: + index = 1; + break; + case PCI_DEVICE_ID_INTEL_PNW_UART3: + index = 2; + break; + default: + return -EINVAL; + } + + dma_dev = pci_get_slot(pdev->bus, PCI_DEVFN(PCI_SLOT(pdev->devfn), 3)); + + port->port.set_termios = intel_mid_set_termios_50M; + + return intel_mid_serial_setup(priv, board, port, idx, index, dma_dev); +} + static int pci_omegapci_setup(struct serial_private *priv, const struct pciserial_board *board, @@ -1987,6 +2130,27 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { .subdevice = PCI_ANY_ID, .setup = byt_serial_setup, }, + { + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_PNW_UART1, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .setup = pnw_serial_setup, + }, + { + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_PNW_UART2, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .setup = pnw_serial_setup, + }, + { + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_PNW_UART3, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .setup = pnw_serial_setup, + }, { .vendor = PCI_VENDOR_ID_INTEL, .device = PCI_DEVICE_ID_INTEL_QRK_UART, @@ -2878,6 +3042,7 @@ enum pci_board_num_t { pbn_ADDIDATA_PCIe_8_3906250, pbn_ce4100_1_115200, pbn_byt, + pbn_pnw, pbn_qrk, pbn_omegapci, pbn_NETMOS9900_2s_115200, @@ -3644,6 +3809,11 @@ static struct pciserial_board pci_boards[] = { .uart_offset = 0x80, .reg_shift = 2, }, + [pbn_pnw] = { + .flags = FL_BASE0, + .num_ports = 1, + .base_baud = 115200, + }, [pbn_qrk] = { .flags = FL_BASE0, .num_ports = 1, @@ -5376,6 +5546,19 @@ static struct pci_device_id serial_pci_tbl[] = { PCI_CLASS_COMMUNICATION_SERIAL << 8, 0xff0000, pbn_byt }, + /* + * Intel Penwell + */ + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PNW_UART1, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, + pbn_pnw}, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PNW_UART2, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, + pbn_pnw}, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PNW_UART3, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, + pbn_pnw}, + /* * Intel Quark x1000 */ -- GitLab From 1bd187de536494a27925902b9653e9ef0ace4774 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 23 Feb 2015 16:24:44 +0200 Subject: [PATCH 03262/11651] x86, intel-mid: remove Intel MID specific serial support Since we have a native 8250 driver carrying the Intel MID serial devices the specific support is not needed anymore. This patch removes it for Intel MID. Note that the console device name is changed from ttyMFDx to ttySx. Signed-off-by: Andy Shevchenko Acked-by: Ingo Molnar Signed-off-by: Greg Kroah-Hartman --- arch/x86/Kconfig.debug | 4 - arch/x86/include/asm/intel-mid.h | 3 - arch/x86/kernel/early_printk.c | 6 - arch/x86/platform/intel-mid/Makefile | 1 - .../intel-mid/early_printk_intel_mid.c | 112 -- drivers/tty/serial/Kconfig | 10 - drivers/tty/serial/Makefile | 1 - drivers/tty/serial/mfd.c | 1505 ----------------- include/linux/serial_mfd.h | 47 - include/uapi/linux/serial_reg.h | 19 - 10 files changed, 1708 deletions(-) delete mode 100644 arch/x86/platform/intel-mid/early_printk_intel_mid.c delete mode 100644 drivers/tty/serial/mfd.c delete mode 100644 include/linux/serial_mfd.h diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index 20028da8ae18..72484a645f05 100644 --- a/arch/x86/Kconfig.debug +++ b/arch/x86/Kconfig.debug @@ -43,10 +43,6 @@ config EARLY_PRINTK with klogd/syslogd or the X server. You should normally N here, unless you want to debug such a crash. -config EARLY_PRINTK_INTEL_MID - bool "Early printk for Intel MID platform support" - depends on EARLY_PRINTK && X86_INTEL_MID - config EARLY_PRINTK_DBGP bool "Early printk via EHCI debug port" depends on EARLY_PRINTK && PCI diff --git a/arch/x86/include/asm/intel-mid.h b/arch/x86/include/asm/intel-mid.h index 705d35708a50..7c5af123bdbd 100644 --- a/arch/x86/include/asm/intel-mid.h +++ b/arch/x86/include/asm/intel-mid.h @@ -136,9 +136,6 @@ extern enum intel_mid_timer_options intel_mid_timer_options; #define SFI_MTMR_MAX_NUM 8 #define SFI_MRTC_MAX 8 -extern struct console early_hsu_console; -extern void hsu_early_console_init(const char *); - extern void intel_scu_devices_create(void); extern void intel_scu_devices_destroy(void); diff --git a/arch/x86/kernel/early_printk.c b/arch/x86/kernel/early_printk.c index a62536a1be88..f85e3fb50f28 100644 --- a/arch/x86/kernel/early_printk.c +++ b/arch/x86/kernel/early_printk.c @@ -375,12 +375,6 @@ static int __init setup_early_printk(char *buf) if (!strncmp(buf, "xen", 3)) early_console_register(&xenboot_console, keep); #endif -#ifdef CONFIG_EARLY_PRINTK_INTEL_MID - if (!strncmp(buf, "hsu", 3)) { - hsu_early_console_init(buf + 3); - early_console_register(&early_hsu_console, keep); - } -#endif #ifdef CONFIG_EARLY_PRINTK_EFI if (!strncmp(buf, "efi", 3)) early_console_register(&early_efi_console, keep); diff --git a/arch/x86/platform/intel-mid/Makefile b/arch/x86/platform/intel-mid/Makefile index 0a8ee703b9fa..0ce1b1913673 100644 --- a/arch/x86/platform/intel-mid/Makefile +++ b/arch/x86/platform/intel-mid/Makefile @@ -1,5 +1,4 @@ obj-$(CONFIG_X86_INTEL_MID) += intel-mid.o intel_mid_vrtc.o mfld.o mrfl.o -obj-$(CONFIG_EARLY_PRINTK_INTEL_MID) += early_printk_intel_mid.o # SFI specific code ifdef CONFIG_X86_INTEL_MID diff --git a/arch/x86/platform/intel-mid/early_printk_intel_mid.c b/arch/x86/platform/intel-mid/early_printk_intel_mid.c deleted file mode 100644 index 4e720829ab90..000000000000 --- a/arch/x86/platform/intel-mid/early_printk_intel_mid.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * early_printk_intel_mid.c - early consoles for Intel MID platforms - * - * Copyright (c) 2008-2010, Intel Corporation - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; version 2 - * of the License. - */ - -/* - * This file implements early console named hsu. - * hsu is based on a High Speed UART device which only exists in the Medfield - * platform - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -/* - * Following is the early console based on Medfield HSU (High - * Speed UART) device. - */ -#define HSU_PORT_BASE 0xffa28080 - -static void __iomem *phsu; - -void hsu_early_console_init(const char *s) -{ - unsigned long paddr, port = 0; - u8 lcr; - - /* - * Select the early HSU console port if specified by user in the - * kernel command line. - */ - if (*s && !kstrtoul(s, 10, &port)) - port = clamp_val(port, 0, 2); - - paddr = HSU_PORT_BASE + port * 0x80; - phsu = (void __iomem *)set_fixmap_offset_nocache(FIX_EARLYCON_MEM_BASE, paddr); - - /* Disable FIFO */ - writeb(0x0, phsu + UART_FCR); - - /* Set to default 115200 bps, 8n1 */ - lcr = readb(phsu + UART_LCR); - writeb((0x80 | lcr), phsu + UART_LCR); - writeb(0x18, phsu + UART_DLL); - writeb(lcr, phsu + UART_LCR); - writel(0x3600, phsu + UART_MUL*4); - - writeb(0x8, phsu + UART_MCR); - writeb(0x7, phsu + UART_FCR); - writeb(0x3, phsu + UART_LCR); - - /* Clear IRQ status */ - readb(phsu + UART_LSR); - readb(phsu + UART_RX); - readb(phsu + UART_IIR); - readb(phsu + UART_MSR); - - /* Enable FIFO */ - writeb(0x7, phsu + UART_FCR); -} - -#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) - -static void early_hsu_putc(char ch) -{ - unsigned int timeout = 10000; /* 10ms */ - u8 status; - - while (--timeout) { - status = readb(phsu + UART_LSR); - if (status & BOTH_EMPTY) - break; - udelay(1); - } - - /* Only write the char when there was no timeout */ - if (timeout) - writeb(ch, phsu + UART_TX); -} - -static void early_hsu_write(struct console *con, const char *str, unsigned n) -{ - int i; - - for (i = 0; i < n && *str; i++) { - if (*str == '\n') - early_hsu_putc('\r'); - early_hsu_putc(*str); - str++; - } -} - -struct console early_hsu_console = { - .name = "earlyhsu", - .write = early_hsu_write, - .flags = CON_PRINTBUFFER, - .index = -1, -}; diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 60c368a5dbf1..c9dbc626038d 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -483,16 +483,6 @@ config SERIAL_SA1100_CONSOLE your boot loader (lilo or loadlin) about how to pass options to the kernel at boot time.) -config SERIAL_MFD_HSU - tristate "Medfield High Speed UART support" - depends on PCI - select SERIAL_CORE - -config SERIAL_MFD_HSU_CONSOLE - bool "Medfield HSU serial console support" - depends on SERIAL_MFD_HSU=y - select SERIAL_CORE_CONSOLE - config SERIAL_BFIN tristate "Blackfin serial port support" depends on BLACKFIN diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile index 599be4b05a26..f42b4f9845df 100644 --- a/drivers/tty/serial/Makefile +++ b/drivers/tty/serial/Makefile @@ -78,7 +78,6 @@ obj-$(CONFIG_SERIAL_TIMBERDALE) += timbuart.o obj-$(CONFIG_SERIAL_GRLIB_GAISLER_APBUART) += apbuart.o obj-$(CONFIG_SERIAL_ALTERA_JTAGUART) += altera_jtaguart.o obj-$(CONFIG_SERIAL_VT8500) += vt8500_serial.o -obj-$(CONFIG_SERIAL_MFD_HSU) += mfd.o obj-$(CONFIG_SERIAL_IFX6X60) += ifx6x60.o obj-$(CONFIG_SERIAL_PCH_UART) += pch_uart.o obj-$(CONFIG_SERIAL_MSM_SMD) += msm_smd_tty.o diff --git a/drivers/tty/serial/mfd.c b/drivers/tty/serial/mfd.c deleted file mode 100644 index 8fe4501d7565..000000000000 --- a/drivers/tty/serial/mfd.c +++ /dev/null @@ -1,1505 +0,0 @@ -/* - * mfd.c: driver for High Speed UART device of Intel Medfield platform - * - * Refer pxa.c, 8250.c and some other drivers in drivers/serial/ - * - * (C) Copyright 2010 Intel Corporation - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; version 2 - * of the License. - */ - -/* Notes: - * 1. DMA channel allocation: 0/1 channel are assigned to port 0, - * 2/3 chan to port 1, 4/5 chan to port 3. Even number chans - * are used for RX, odd chans for TX - * - * 2. The RI/DSR/DCD/DTR are not pinned out, DCD & DSR are always - * asserted, only when the HW is reset the DDCD and DDSR will - * be triggered - */ - -#if defined(CONFIG_SERIAL_MFD_HSU_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) -#define SUPPORT_SYSRQ -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define HSU_DMA_BUF_SIZE 2048 - -#define chan_readl(chan, offset) readl(chan->reg + offset) -#define chan_writel(chan, offset, val) writel(val, chan->reg + offset) - -#define mfd_readl(obj, offset) readl(obj->reg + offset) -#define mfd_writel(obj, offset, val) writel(val, obj->reg + offset) - -static int hsu_dma_enable; -module_param(hsu_dma_enable, int, 0); -MODULE_PARM_DESC(hsu_dma_enable, - "It is a bitmap to set working mode, if bit[x] is 1, then port[x] will work in DMA mode, otherwise in PIO mode."); - -struct hsu_dma_buffer { - u8 *buf; - dma_addr_t dma_addr; - u32 dma_size; - u32 ofs; -}; - -struct hsu_dma_chan { - u32 id; - enum dma_data_direction dirt; - struct uart_hsu_port *uport; - void __iomem *reg; -}; - -struct uart_hsu_port { - struct uart_port port; - unsigned char ier; - unsigned char lcr; - unsigned char mcr; - unsigned int lsr_break_flag; - char name[12]; - int index; - struct device *dev; - - struct hsu_dma_chan *txc; - struct hsu_dma_chan *rxc; - struct hsu_dma_buffer txbuf; - struct hsu_dma_buffer rxbuf; - int use_dma; /* flag for DMA/PIO */ - int running; - int dma_tx_on; -}; - -/* Top level data structure of HSU */ -struct hsu_port { - void __iomem *reg; - unsigned long paddr; - unsigned long iolen; - u32 irq; - - struct uart_hsu_port port[3]; - struct hsu_dma_chan chans[10]; - - struct dentry *debugfs; -}; - -static inline unsigned int serial_in(struct uart_hsu_port *up, int offset) -{ - unsigned int val; - - if (offset > UART_MSR) { - offset <<= 2; - val = readl(up->port.membase + offset); - } else - val = (unsigned int)readb(up->port.membase + offset); - - return val; -} - -static inline void serial_out(struct uart_hsu_port *up, int offset, int value) -{ - if (offset > UART_MSR) { - offset <<= 2; - writel(value, up->port.membase + offset); - } else { - unsigned char val = value & 0xff; - writeb(val, up->port.membase + offset); - } -} - -#ifdef CONFIG_DEBUG_FS - -#define HSU_REGS_BUFSIZE 1024 - - -static ssize_t port_show_regs(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct uart_hsu_port *up = file->private_data; - char *buf; - u32 len = 0; - ssize_t ret; - - buf = kzalloc(HSU_REGS_BUFSIZE, GFP_KERNEL); - if (!buf) - return 0; - - len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, - "MFD HSU port[%d] regs:\n", up->index); - - len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, - "=================================\n"); - len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, - "IER: \t\t0x%08x\n", serial_in(up, UART_IER)); - len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, - "IIR: \t\t0x%08x\n", serial_in(up, UART_IIR)); - len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, - "LCR: \t\t0x%08x\n", serial_in(up, UART_LCR)); - len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, - "MCR: \t\t0x%08x\n", serial_in(up, UART_MCR)); - len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, - "LSR: \t\t0x%08x\n", serial_in(up, UART_LSR)); - len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, - "MSR: \t\t0x%08x\n", serial_in(up, UART_MSR)); - len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, - "FOR: \t\t0x%08x\n", serial_in(up, UART_FOR)); - len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, - "PS: \t\t0x%08x\n", serial_in(up, UART_PS)); - len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, - "MUL: \t\t0x%08x\n", serial_in(up, UART_MUL)); - len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, - "DIV: \t\t0x%08x\n", serial_in(up, UART_DIV)); - - if (len > HSU_REGS_BUFSIZE) - len = HSU_REGS_BUFSIZE; - - ret = simple_read_from_buffer(user_buf, count, ppos, buf, len); - kfree(buf); - return ret; -} - -static ssize_t dma_show_regs(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct hsu_dma_chan *chan = file->private_data; - char *buf; - u32 len = 0; - ssize_t ret; - - buf = kzalloc(HSU_REGS_BUFSIZE, GFP_KERNEL); - if (!buf) - return 0; - - len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, - "MFD HSU DMA channel [%d] regs:\n", chan->id); - - len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, - "=================================\n"); - len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, - "CR: \t\t0x%08x\n", chan_readl(chan, HSU_CH_CR)); - len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, - "DCR: \t\t0x%08x\n", chan_readl(chan, HSU_CH_DCR)); - len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, - "BSR: \t\t0x%08x\n", chan_readl(chan, HSU_CH_BSR)); - len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, - "MOTSR: \t\t0x%08x\n", chan_readl(chan, HSU_CH_MOTSR)); - len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, - "D0SAR: \t\t0x%08x\n", chan_readl(chan, HSU_CH_D0SAR)); - len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, - "D0TSR: \t\t0x%08x\n", chan_readl(chan, HSU_CH_D0TSR)); - len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, - "D0SAR: \t\t0x%08x\n", chan_readl(chan, HSU_CH_D1SAR)); - len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, - "D0TSR: \t\t0x%08x\n", chan_readl(chan, HSU_CH_D1TSR)); - len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, - "D0SAR: \t\t0x%08x\n", chan_readl(chan, HSU_CH_D2SAR)); - len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, - "D0TSR: \t\t0x%08x\n", chan_readl(chan, HSU_CH_D2TSR)); - len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, - "D0SAR: \t\t0x%08x\n", chan_readl(chan, HSU_CH_D3SAR)); - len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, - "D0TSR: \t\t0x%08x\n", chan_readl(chan, HSU_CH_D3TSR)); - - if (len > HSU_REGS_BUFSIZE) - len = HSU_REGS_BUFSIZE; - - ret = simple_read_from_buffer(user_buf, count, ppos, buf, len); - kfree(buf); - return ret; -} - -static const struct file_operations port_regs_ops = { - .owner = THIS_MODULE, - .open = simple_open, - .read = port_show_regs, - .llseek = default_llseek, -}; - -static const struct file_operations dma_regs_ops = { - .owner = THIS_MODULE, - .open = simple_open, - .read = dma_show_regs, - .llseek = default_llseek, -}; - -static int hsu_debugfs_init(struct hsu_port *hsu) -{ - int i; - char name[32]; - - hsu->debugfs = debugfs_create_dir("hsu", NULL); - if (!hsu->debugfs) - return -ENOMEM; - - for (i = 0; i < 3; i++) { - snprintf(name, sizeof(name), "port_%d_regs", i); - debugfs_create_file(name, S_IFREG | S_IRUGO, - hsu->debugfs, (void *)(&hsu->port[i]), &port_regs_ops); - } - - for (i = 0; i < 6; i++) { - snprintf(name, sizeof(name), "dma_chan_%d_regs", i); - debugfs_create_file(name, S_IFREG | S_IRUGO, - hsu->debugfs, (void *)&hsu->chans[i], &dma_regs_ops); - } - - return 0; -} - -static void hsu_debugfs_remove(struct hsu_port *hsu) -{ - if (hsu->debugfs) - debugfs_remove_recursive(hsu->debugfs); -} - -#else -static inline int hsu_debugfs_init(struct hsu_port *hsu) -{ - return 0; -} - -static inline void hsu_debugfs_remove(struct hsu_port *hsu) -{ -} -#endif /* CONFIG_DEBUG_FS */ - -static void serial_hsu_enable_ms(struct uart_port *port) -{ - struct uart_hsu_port *up = - container_of(port, struct uart_hsu_port, port); - - up->ier |= UART_IER_MSI; - serial_out(up, UART_IER, up->ier); -} - -static void hsu_dma_tx(struct uart_hsu_port *up) -{ - struct circ_buf *xmit = &up->port.state->xmit; - struct hsu_dma_buffer *dbuf = &up->txbuf; - int count; - - /* test_and_set_bit may be better, but anyway it's in lock protected mode */ - if (up->dma_tx_on) - return; - - /* Update the circ buf info */ - xmit->tail += dbuf->ofs; - xmit->tail &= UART_XMIT_SIZE - 1; - - up->port.icount.tx += dbuf->ofs; - dbuf->ofs = 0; - - /* Disable the channel */ - chan_writel(up->txc, HSU_CH_CR, 0x0); - - if (!uart_circ_empty(xmit) && !uart_tx_stopped(&up->port)) { - dma_sync_single_for_device(up->port.dev, - dbuf->dma_addr, - dbuf->dma_size, - DMA_TO_DEVICE); - - count = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE); - dbuf->ofs = count; - - /* Reprogram the channel */ - chan_writel(up->txc, HSU_CH_D0SAR, dbuf->dma_addr + xmit->tail); - chan_writel(up->txc, HSU_CH_D0TSR, count); - - /* Reenable the channel */ - chan_writel(up->txc, HSU_CH_DCR, 0x1 - | (0x1 << 8) - | (0x1 << 16) - | (0x1 << 24)); - up->dma_tx_on = 1; - chan_writel(up->txc, HSU_CH_CR, 0x1); - } - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(&up->port); -} - -/* The buffer is already cache coherent */ -static void hsu_dma_start_rx_chan(struct hsu_dma_chan *rxc, - struct hsu_dma_buffer *dbuf) -{ - dbuf->ofs = 0; - - chan_writel(rxc, HSU_CH_BSR, 32); - chan_writel(rxc, HSU_CH_MOTSR, 4); - - chan_writel(rxc, HSU_CH_D0SAR, dbuf->dma_addr); - chan_writel(rxc, HSU_CH_D0TSR, dbuf->dma_size); - chan_writel(rxc, HSU_CH_DCR, 0x1 | (0x1 << 8) - | (0x1 << 16) - | (0x1 << 24) /* timeout bit, see HSU Errata 1 */ - ); - chan_writel(rxc, HSU_CH_CR, 0x3); -} - -/* Protected by spin_lock_irqsave(port->lock) */ -static void serial_hsu_start_tx(struct uart_port *port) -{ - struct uart_hsu_port *up = - container_of(port, struct uart_hsu_port, port); - - if (up->use_dma) { - hsu_dma_tx(up); - } else if (!(up->ier & UART_IER_THRI)) { - up->ier |= UART_IER_THRI; - serial_out(up, UART_IER, up->ier); - } -} - -static void serial_hsu_stop_tx(struct uart_port *port) -{ - struct uart_hsu_port *up = - container_of(port, struct uart_hsu_port, port); - struct hsu_dma_chan *txc = up->txc; - - if (up->use_dma) - chan_writel(txc, HSU_CH_CR, 0x0); - else if (up->ier & UART_IER_THRI) { - up->ier &= ~UART_IER_THRI; - serial_out(up, UART_IER, up->ier); - } -} - -/* This is always called in spinlock protected mode, so - * modify timeout timer is safe here */ -static void hsu_dma_rx(struct uart_hsu_port *up, u32 int_sts, - unsigned long *flags) -{ - struct hsu_dma_buffer *dbuf = &up->rxbuf; - struct hsu_dma_chan *chan = up->rxc; - struct uart_port *port = &up->port; - struct tty_port *tport = &port->state->port; - int count; - - /* - * First need to know how many is already transferred, - * then check if its a timeout DMA irq, and return - * the trail bytes out, push them up and reenable the - * channel - */ - - /* Timeout IRQ, need wait some time, see Errata 2 */ - if (int_sts & 0xf00) - udelay(2); - - /* Stop the channel */ - chan_writel(chan, HSU_CH_CR, 0x0); - - count = chan_readl(chan, HSU_CH_D0SAR) - dbuf->dma_addr; - if (!count) { - /* Restart the channel before we leave */ - chan_writel(chan, HSU_CH_CR, 0x3); - return; - } - - dma_sync_single_for_cpu(port->dev, dbuf->dma_addr, - dbuf->dma_size, DMA_FROM_DEVICE); - - /* - * Head will only wrap around when we recycle - * the DMA buffer, and when that happens, we - * explicitly set tail to 0. So head will - * always be greater than tail. - */ - tty_insert_flip_string(tport, dbuf->buf, count); - port->icount.rx += count; - - dma_sync_single_for_device(up->port.dev, dbuf->dma_addr, - dbuf->dma_size, DMA_FROM_DEVICE); - - /* Reprogram the channel */ - chan_writel(chan, HSU_CH_D0SAR, dbuf->dma_addr); - chan_writel(chan, HSU_CH_D0TSR, dbuf->dma_size); - chan_writel(chan, HSU_CH_DCR, 0x1 - | (0x1 << 8) - | (0x1 << 16) - | (0x1 << 24) /* timeout bit, see HSU Errata 1 */ - ); - spin_unlock_irqrestore(&up->port.lock, *flags); - tty_flip_buffer_push(tport); - spin_lock_irqsave(&up->port.lock, *flags); - - chan_writel(chan, HSU_CH_CR, 0x3); - -} - -static void serial_hsu_stop_rx(struct uart_port *port) -{ - struct uart_hsu_port *up = - container_of(port, struct uart_hsu_port, port); - struct hsu_dma_chan *chan = up->rxc; - - if (up->use_dma) - chan_writel(chan, HSU_CH_CR, 0x2); - else { - up->ier &= ~UART_IER_RLSI; - up->port.read_status_mask &= ~UART_LSR_DR; - serial_out(up, UART_IER, up->ier); - } -} - -static inline void receive_chars(struct uart_hsu_port *up, int *status, - unsigned long *flags) -{ - unsigned int ch, flag; - unsigned int max_count = 256; - - do { - ch = serial_in(up, UART_RX); - flag = TTY_NORMAL; - up->port.icount.rx++; - - if (unlikely(*status & (UART_LSR_BI | UART_LSR_PE | - UART_LSR_FE | UART_LSR_OE))) { - - dev_warn(up->dev, "We really rush into ERR/BI case" - "status = 0x%02x", *status); - /* For statistics only */ - if (*status & UART_LSR_BI) { - *status &= ~(UART_LSR_FE | UART_LSR_PE); - up->port.icount.brk++; - /* - * We do the SysRQ and SAK checking - * here because otherwise the break - * may get masked by ignore_status_mask - * or read_status_mask. - */ - if (uart_handle_break(&up->port)) - goto ignore_char; - } else if (*status & UART_LSR_PE) - up->port.icount.parity++; - else if (*status & UART_LSR_FE) - up->port.icount.frame++; - if (*status & UART_LSR_OE) - up->port.icount.overrun++; - - /* Mask off conditions which should be ignored. */ - *status &= up->port.read_status_mask; - -#ifdef CONFIG_SERIAL_MFD_HSU_CONSOLE - if (up->port.cons && - up->port.cons->index == up->port.line) { - /* Recover the break flag from console xmit */ - *status |= up->lsr_break_flag; - up->lsr_break_flag = 0; - } -#endif - if (*status & UART_LSR_BI) { - flag = TTY_BREAK; - } else if (*status & UART_LSR_PE) - flag = TTY_PARITY; - else if (*status & UART_LSR_FE) - flag = TTY_FRAME; - } - - if (uart_handle_sysrq_char(&up->port, ch)) - goto ignore_char; - - uart_insert_char(&up->port, *status, UART_LSR_OE, ch, flag); - ignore_char: - *status = serial_in(up, UART_LSR); - } while ((*status & UART_LSR_DR) && max_count--); - - spin_unlock_irqrestore(&up->port.lock, *flags); - tty_flip_buffer_push(&up->port.state->port); - spin_lock_irqsave(&up->port.lock, *flags); -} - -static void transmit_chars(struct uart_hsu_port *up) -{ - struct circ_buf *xmit = &up->port.state->xmit; - int count; - - if (up->port.x_char) { - serial_out(up, UART_TX, up->port.x_char); - up->port.icount.tx++; - up->port.x_char = 0; - return; - } - if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) { - serial_hsu_stop_tx(&up->port); - return; - } - - /* The IRQ is for TX FIFO half-empty */ - count = up->port.fifosize / 2; - - do { - serial_out(up, UART_TX, xmit->buf[xmit->tail]); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - - up->port.icount.tx++; - if (uart_circ_empty(xmit)) - break; - } while (--count > 0); - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(&up->port); - - if (uart_circ_empty(xmit)) - serial_hsu_stop_tx(&up->port); -} - -static inline void check_modem_status(struct uart_hsu_port *up) -{ - int status; - - status = serial_in(up, UART_MSR); - - if ((status & UART_MSR_ANY_DELTA) == 0) - return; - - if (status & UART_MSR_TERI) - up->port.icount.rng++; - if (status & UART_MSR_DDSR) - up->port.icount.dsr++; - /* We may only get DDCD when HW init and reset */ - if (status & UART_MSR_DDCD) - uart_handle_dcd_change(&up->port, status & UART_MSR_DCD); - /* Will start/stop_tx accordingly */ - if (status & UART_MSR_DCTS) - uart_handle_cts_change(&up->port, status & UART_MSR_CTS); - - wake_up_interruptible(&up->port.state->port.delta_msr_wait); -} - -/* - * This handles the interrupt from one port. - */ -static irqreturn_t port_irq(int irq, void *dev_id) -{ - struct uart_hsu_port *up = dev_id; - unsigned int iir, lsr; - unsigned long flags; - - if (unlikely(!up->running)) - return IRQ_NONE; - - spin_lock_irqsave(&up->port.lock, flags); - if (up->use_dma) { - lsr = serial_in(up, UART_LSR); - if (unlikely(lsr & (UART_LSR_BI | UART_LSR_PE | - UART_LSR_FE | UART_LSR_OE))) - dev_warn(up->dev, - "Got lsr irq while using DMA, lsr = 0x%2x\n", - lsr); - check_modem_status(up); - spin_unlock_irqrestore(&up->port.lock, flags); - return IRQ_HANDLED; - } - - iir = serial_in(up, UART_IIR); - if (iir & UART_IIR_NO_INT) { - spin_unlock_irqrestore(&up->port.lock, flags); - return IRQ_NONE; - } - - lsr = serial_in(up, UART_LSR); - if (lsr & UART_LSR_DR) - receive_chars(up, &lsr, &flags); - check_modem_status(up); - - /* lsr will be renewed during the receive_chars */ - if (lsr & UART_LSR_THRE) - transmit_chars(up); - - spin_unlock_irqrestore(&up->port.lock, flags); - return IRQ_HANDLED; -} - -static inline void dma_chan_irq(struct hsu_dma_chan *chan) -{ - struct uart_hsu_port *up = chan->uport; - unsigned long flags; - u32 int_sts; - - spin_lock_irqsave(&up->port.lock, flags); - - if (!up->use_dma || !up->running) - goto exit; - - /* - * No matter what situation, need read clear the IRQ status - * There is a bug, see Errata 5, HSD 2900918 - */ - int_sts = chan_readl(chan, HSU_CH_SR); - - /* Rx channel */ - if (chan->dirt == DMA_FROM_DEVICE) - hsu_dma_rx(up, int_sts, &flags); - - /* Tx channel */ - if (chan->dirt == DMA_TO_DEVICE) { - chan_writel(chan, HSU_CH_CR, 0x0); - up->dma_tx_on = 0; - hsu_dma_tx(up); - } - -exit: - spin_unlock_irqrestore(&up->port.lock, flags); - return; -} - -static irqreturn_t dma_irq(int irq, void *dev_id) -{ - struct hsu_port *hsu = dev_id; - u32 int_sts, i; - - int_sts = mfd_readl(hsu, HSU_GBL_DMAISR); - - /* Currently we only have 6 channels may be used */ - for (i = 0; i < 6; i++) { - if (int_sts & 0x1) - dma_chan_irq(&hsu->chans[i]); - int_sts >>= 1; - } - - return IRQ_HANDLED; -} - -static unsigned int serial_hsu_tx_empty(struct uart_port *port) -{ - struct uart_hsu_port *up = - container_of(port, struct uart_hsu_port, port); - unsigned long flags; - unsigned int ret; - - spin_lock_irqsave(&up->port.lock, flags); - ret = serial_in(up, UART_LSR) & UART_LSR_TEMT ? TIOCSER_TEMT : 0; - spin_unlock_irqrestore(&up->port.lock, flags); - - return ret; -} - -static unsigned int serial_hsu_get_mctrl(struct uart_port *port) -{ - struct uart_hsu_port *up = - container_of(port, struct uart_hsu_port, port); - unsigned char status; - unsigned int ret; - - status = serial_in(up, UART_MSR); - - ret = 0; - if (status & UART_MSR_DCD) - ret |= TIOCM_CAR; - if (status & UART_MSR_RI) - ret |= TIOCM_RNG; - if (status & UART_MSR_DSR) - ret |= TIOCM_DSR; - if (status & UART_MSR_CTS) - ret |= TIOCM_CTS; - return ret; -} - -static void serial_hsu_set_mctrl(struct uart_port *port, unsigned int mctrl) -{ - struct uart_hsu_port *up = - container_of(port, struct uart_hsu_port, port); - unsigned char mcr = 0; - - if (mctrl & TIOCM_RTS) - mcr |= UART_MCR_RTS; - if (mctrl & TIOCM_DTR) - mcr |= UART_MCR_DTR; - if (mctrl & TIOCM_OUT1) - mcr |= UART_MCR_OUT1; - if (mctrl & TIOCM_OUT2) - mcr |= UART_MCR_OUT2; - if (mctrl & TIOCM_LOOP) - mcr |= UART_MCR_LOOP; - - mcr |= up->mcr; - - serial_out(up, UART_MCR, mcr); -} - -static void serial_hsu_break_ctl(struct uart_port *port, int break_state) -{ - struct uart_hsu_port *up = - container_of(port, struct uart_hsu_port, port); - unsigned long flags; - - spin_lock_irqsave(&up->port.lock, flags); - if (break_state == -1) - up->lcr |= UART_LCR_SBC; - else - up->lcr &= ~UART_LCR_SBC; - serial_out(up, UART_LCR, up->lcr); - spin_unlock_irqrestore(&up->port.lock, flags); -} - -/* - * What special to do: - * 1. chose the 64B fifo mode - * 2. start dma or pio depends on configuration - * 3. we only allocate dma memory when needed - */ -static int serial_hsu_startup(struct uart_port *port) -{ - struct uart_hsu_port *up = - container_of(port, struct uart_hsu_port, port); - unsigned long flags; - - pm_runtime_get_sync(up->dev); - - /* - * Clear the FIFO buffers and disable them. - * (they will be reenabled in set_termios()) - */ - serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO); - serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | - UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); - serial_out(up, UART_FCR, 0); - - /* Clear the interrupt registers. */ - (void) serial_in(up, UART_LSR); - (void) serial_in(up, UART_RX); - (void) serial_in(up, UART_IIR); - (void) serial_in(up, UART_MSR); - - /* Now, initialize the UART, default is 8n1 */ - serial_out(up, UART_LCR, UART_LCR_WLEN8); - - spin_lock_irqsave(&up->port.lock, flags); - - up->port.mctrl |= TIOCM_OUT2; - serial_hsu_set_mctrl(&up->port, up->port.mctrl); - - /* - * Finally, enable interrupts. Note: Modem status interrupts - * are set via set_termios(), which will be occurring imminently - * anyway, so we don't enable them here. - */ - if (!up->use_dma) - up->ier = UART_IER_RLSI | UART_IER_RDI | UART_IER_RTOIE; - else - up->ier = 0; - serial_out(up, UART_IER, up->ier); - - spin_unlock_irqrestore(&up->port.lock, flags); - - /* DMA init */ - if (up->use_dma) { - struct hsu_dma_buffer *dbuf; - struct circ_buf *xmit = &port->state->xmit; - - up->dma_tx_on = 0; - - /* First allocate the RX buffer */ - dbuf = &up->rxbuf; - dbuf->buf = kzalloc(HSU_DMA_BUF_SIZE, GFP_KERNEL); - if (!dbuf->buf) { - up->use_dma = 0; - goto exit; - } - dbuf->dma_addr = dma_map_single(port->dev, - dbuf->buf, - HSU_DMA_BUF_SIZE, - DMA_FROM_DEVICE); - dbuf->dma_size = HSU_DMA_BUF_SIZE; - - /* Start the RX channel right now */ - hsu_dma_start_rx_chan(up->rxc, dbuf); - - /* Next init the TX DMA */ - dbuf = &up->txbuf; - dbuf->buf = xmit->buf; - dbuf->dma_addr = dma_map_single(port->dev, - dbuf->buf, - UART_XMIT_SIZE, - DMA_TO_DEVICE); - dbuf->dma_size = UART_XMIT_SIZE; - - /* This should not be changed all around */ - chan_writel(up->txc, HSU_CH_BSR, 32); - chan_writel(up->txc, HSU_CH_MOTSR, 4); - dbuf->ofs = 0; - } - -exit: - /* And clear the interrupt registers again for luck. */ - (void) serial_in(up, UART_LSR); - (void) serial_in(up, UART_RX); - (void) serial_in(up, UART_IIR); - (void) serial_in(up, UART_MSR); - - up->running = 1; - return 0; -} - -static void serial_hsu_shutdown(struct uart_port *port) -{ - struct uart_hsu_port *up = - container_of(port, struct uart_hsu_port, port); - unsigned long flags; - - /* Disable interrupts from this port */ - up->ier = 0; - serial_out(up, UART_IER, 0); - up->running = 0; - - spin_lock_irqsave(&up->port.lock, flags); - up->port.mctrl &= ~TIOCM_OUT2; - serial_hsu_set_mctrl(&up->port, up->port.mctrl); - spin_unlock_irqrestore(&up->port.lock, flags); - - /* Disable break condition and FIFOs */ - serial_out(up, UART_LCR, serial_in(up, UART_LCR) & ~UART_LCR_SBC); - serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | - UART_FCR_CLEAR_RCVR | - UART_FCR_CLEAR_XMIT); - serial_out(up, UART_FCR, 0); - - pm_runtime_put(up->dev); -} - -static void -serial_hsu_set_termios(struct uart_port *port, struct ktermios *termios, - struct ktermios *old) -{ - struct uart_hsu_port *up = - container_of(port, struct uart_hsu_port, port); - unsigned char cval, fcr = 0; - unsigned long flags; - unsigned int baud, quot; - u32 ps, mul; - - switch (termios->c_cflag & CSIZE) { - case CS5: - cval = UART_LCR_WLEN5; - break; - case CS6: - cval = UART_LCR_WLEN6; - break; - case CS7: - cval = UART_LCR_WLEN7; - break; - default: - case CS8: - cval = UART_LCR_WLEN8; - break; - } - - /* CMSPAR isn't supported by this driver */ - termios->c_cflag &= ~CMSPAR; - - if (termios->c_cflag & CSTOPB) - cval |= UART_LCR_STOP; - if (termios->c_cflag & PARENB) - cval |= UART_LCR_PARITY; - if (!(termios->c_cflag & PARODD)) - cval |= UART_LCR_EPAR; - - /* - * The base clk is 50Mhz, and the baud rate come from: - * baud = 50M * MUL / (DIV * PS * DLAB) - * - * For those basic low baud rate we can get the direct - * scalar from 2746800, like 115200 = 2746800/24. For those - * higher baud rate, we handle them case by case, mainly by - * adjusting the MUL/PS registers, and DIV register is kept - * as default value 0x3d09 to make things simple - */ - baud = uart_get_baud_rate(port, termios, old, 0, 4000000); - - quot = 1; - ps = 0x10; - mul = 0x3600; - switch (baud) { - case 3500000: - mul = 0x3345; - ps = 0xC; - break; - case 1843200: - mul = 0x2400; - break; - case 3000000: - case 2500000: - case 2000000: - case 1500000: - case 1000000: - case 500000: - /* mul/ps/quot = 0x9C4/0x10/0x1 will make a 500000 bps */ - mul = baud / 500000 * 0x9C4; - break; - default: - /* Use uart_get_divisor to get quot for other baud rates */ - quot = 0; - } - - if (!quot) - quot = uart_get_divisor(port, baud); - - if ((up->port.uartclk / quot) < (2400 * 16)) - fcr = UART_FCR_ENABLE_FIFO | UART_FCR_HSU_64_1B; - else if ((up->port.uartclk / quot) < (230400 * 16)) - fcr = UART_FCR_ENABLE_FIFO | UART_FCR_HSU_64_16B; - else - fcr = UART_FCR_ENABLE_FIFO | UART_FCR_HSU_64_32B; - - fcr |= UART_FCR_HSU_64B_FIFO; - - /* - * Ok, we're now changing the port state. Do it with - * interrupts disabled. - */ - spin_lock_irqsave(&up->port.lock, flags); - - /* Update the per-port timeout */ - uart_update_timeout(port, termios->c_cflag, baud); - - up->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; - if (termios->c_iflag & INPCK) - up->port.read_status_mask |= UART_LSR_FE | UART_LSR_PE; - if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK)) - up->port.read_status_mask |= UART_LSR_BI; - - /* Characters to ignore */ - up->port.ignore_status_mask = 0; - if (termios->c_iflag & IGNPAR) - up->port.ignore_status_mask |= UART_LSR_PE | UART_LSR_FE; - if (termios->c_iflag & IGNBRK) { - up->port.ignore_status_mask |= UART_LSR_BI; - /* - * If we're ignoring parity and break indicators, - * ignore overruns too (for real raw support). - */ - if (termios->c_iflag & IGNPAR) - up->port.ignore_status_mask |= UART_LSR_OE; - } - - /* Ignore all characters if CREAD is not set */ - if ((termios->c_cflag & CREAD) == 0) - up->port.ignore_status_mask |= UART_LSR_DR; - - /* - * CTS flow control flag and modem status interrupts, disable - * MSI by default - */ - up->ier &= ~UART_IER_MSI; - if (UART_ENABLE_MS(&up->port, termios->c_cflag)) - up->ier |= UART_IER_MSI; - - serial_out(up, UART_IER, up->ier); - - if (termios->c_cflag & CRTSCTS) - up->mcr |= UART_MCR_AFE | UART_MCR_RTS; - else - up->mcr &= ~UART_MCR_AFE; - - serial_out(up, UART_LCR, cval | UART_LCR_DLAB); /* set DLAB */ - serial_out(up, UART_DLL, quot & 0xff); /* LS of divisor */ - serial_out(up, UART_DLM, quot >> 8); /* MS of divisor */ - serial_out(up, UART_LCR, cval); /* reset DLAB */ - serial_out(up, UART_MUL, mul); /* set MUL */ - serial_out(up, UART_PS, ps); /* set PS */ - up->lcr = cval; /* Save LCR */ - serial_hsu_set_mctrl(&up->port, up->port.mctrl); - serial_out(up, UART_FCR, fcr); - spin_unlock_irqrestore(&up->port.lock, flags); -} - -static void -serial_hsu_pm(struct uart_port *port, unsigned int state, - unsigned int oldstate) -{ -} - -static void serial_hsu_release_port(struct uart_port *port) -{ -} - -static int serial_hsu_request_port(struct uart_port *port) -{ - return 0; -} - -static void serial_hsu_config_port(struct uart_port *port, int flags) -{ - struct uart_hsu_port *up = - container_of(port, struct uart_hsu_port, port); - up->port.type = PORT_MFD; -} - -static int -serial_hsu_verify_port(struct uart_port *port, struct serial_struct *ser) -{ - /* We don't want the core code to modify any port params */ - return -EINVAL; -} - -static const char * -serial_hsu_type(struct uart_port *port) -{ - struct uart_hsu_port *up = - container_of(port, struct uart_hsu_port, port); - return up->name; -} - -/* Mainly for uart console use */ -static struct uart_hsu_port *serial_hsu_ports[3]; -static struct uart_driver serial_hsu_reg; - -#ifdef CONFIG_SERIAL_MFD_HSU_CONSOLE - -#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) - -/* Wait for transmitter & holding register to empty */ -static inline void wait_for_xmitr(struct uart_hsu_port *up) -{ - unsigned int status, tmout = 1000; - - /* Wait up to 1ms for the character to be sent. */ - do { - status = serial_in(up, UART_LSR); - - if (status & UART_LSR_BI) - up->lsr_break_flag = UART_LSR_BI; - - if (--tmout == 0) - break; - udelay(1); - } while (!(status & BOTH_EMPTY)); - - /* Wait up to 1s for flow control if necessary */ - if (up->port.flags & UPF_CONS_FLOW) { - tmout = 1000000; - while (--tmout && - ((serial_in(up, UART_MSR) & UART_MSR_CTS) == 0)) - udelay(1); - } -} - -static void serial_hsu_console_putchar(struct uart_port *port, int ch) -{ - struct uart_hsu_port *up = - container_of(port, struct uart_hsu_port, port); - - wait_for_xmitr(up); - serial_out(up, UART_TX, ch); -} - -/* - * Print a string to the serial port trying not to disturb - * any possible real use of the port... - * - * The console_lock must be held when we get here. - */ -static void -serial_hsu_console_write(struct console *co, const char *s, unsigned int count) -{ - struct uart_hsu_port *up = serial_hsu_ports[co->index]; - unsigned long flags; - unsigned int ier; - int locked = 1; - - touch_nmi_watchdog(); - - local_irq_save(flags); - if (up->port.sysrq) - locked = 0; - else if (oops_in_progress) { - locked = spin_trylock(&up->port.lock); - } else - spin_lock(&up->port.lock); - - /* First save the IER then disable the interrupts */ - ier = serial_in(up, UART_IER); - serial_out(up, UART_IER, 0); - - uart_console_write(&up->port, s, count, serial_hsu_console_putchar); - - /* - * Finally, wait for transmitter to become empty - * and restore the IER - */ - wait_for_xmitr(up); - serial_out(up, UART_IER, ier); - - if (locked) - spin_unlock(&up->port.lock); - local_irq_restore(flags); -} - -static struct console serial_hsu_console; - -static int __init -serial_hsu_console_setup(struct console *co, char *options) -{ - struct uart_hsu_port *up; - int baud = 115200; - int bits = 8; - int parity = 'n'; - int flow = 'n'; - - if (co->index == -1 || co->index >= serial_hsu_reg.nr) - co->index = 0; - up = serial_hsu_ports[co->index]; - if (!up) - return -ENODEV; - - if (options) - uart_parse_options(options, &baud, &parity, &bits, &flow); - - return uart_set_options(&up->port, co, baud, parity, bits, flow); -} - -static struct console serial_hsu_console = { - .name = "ttyMFD", - .write = serial_hsu_console_write, - .device = uart_console_device, - .setup = serial_hsu_console_setup, - .flags = CON_PRINTBUFFER, - .index = -1, - .data = &serial_hsu_reg, -}; - -#define SERIAL_HSU_CONSOLE (&serial_hsu_console) -#else -#define SERIAL_HSU_CONSOLE NULL -#endif - -static struct uart_ops serial_hsu_pops = { - .tx_empty = serial_hsu_tx_empty, - .set_mctrl = serial_hsu_set_mctrl, - .get_mctrl = serial_hsu_get_mctrl, - .stop_tx = serial_hsu_stop_tx, - .start_tx = serial_hsu_start_tx, - .stop_rx = serial_hsu_stop_rx, - .enable_ms = serial_hsu_enable_ms, - .break_ctl = serial_hsu_break_ctl, - .startup = serial_hsu_startup, - .shutdown = serial_hsu_shutdown, - .set_termios = serial_hsu_set_termios, - .pm = serial_hsu_pm, - .type = serial_hsu_type, - .release_port = serial_hsu_release_port, - .request_port = serial_hsu_request_port, - .config_port = serial_hsu_config_port, - .verify_port = serial_hsu_verify_port, -}; - -static struct uart_driver serial_hsu_reg = { - .owner = THIS_MODULE, - .driver_name = "MFD serial", - .dev_name = "ttyMFD", - .major = TTY_MAJOR, - .minor = 128, - .nr = 3, - .cons = SERIAL_HSU_CONSOLE, -}; - -#ifdef CONFIG_PM -static int serial_hsu_suspend(struct pci_dev *pdev, pm_message_t state) -{ - void *priv = pci_get_drvdata(pdev); - struct uart_hsu_port *up; - - /* Make sure this is not the internal dma controller */ - if (priv && (pdev->device != 0x081E)) { - up = priv; - uart_suspend_port(&serial_hsu_reg, &up->port); - } - - pci_save_state(pdev); - pci_set_power_state(pdev, pci_choose_state(pdev, state)); - return 0; -} - -static int serial_hsu_resume(struct pci_dev *pdev) -{ - void *priv = pci_get_drvdata(pdev); - struct uart_hsu_port *up; - int ret; - - pci_set_power_state(pdev, PCI_D0); - pci_restore_state(pdev); - - ret = pci_enable_device(pdev); - if (ret) - dev_warn(&pdev->dev, - "HSU: can't re-enable device, try to continue\n"); - - if (priv && (pdev->device != 0x081E)) { - up = priv; - uart_resume_port(&serial_hsu_reg, &up->port); - } - return 0; -} - -static int serial_hsu_runtime_idle(struct device *dev) -{ - pm_schedule_suspend(dev, 500); - return -EBUSY; -} - -static int serial_hsu_runtime_suspend(struct device *dev) -{ - return 0; -} - -static int serial_hsu_runtime_resume(struct device *dev) -{ - return 0; -} -#else -#define serial_hsu_suspend NULL -#define serial_hsu_resume NULL -#define serial_hsu_runtime_idle NULL -#define serial_hsu_runtime_suspend NULL -#define serial_hsu_runtime_resume NULL -#endif - -static const struct dev_pm_ops serial_hsu_pm_ops = { - .runtime_suspend = serial_hsu_runtime_suspend, - .runtime_resume = serial_hsu_runtime_resume, - .runtime_idle = serial_hsu_runtime_idle, -}; - -/* temp global pointer before we settle down on using one or four PCI dev */ -static struct hsu_port *phsu; - -static int serial_hsu_probe(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - struct uart_hsu_port *uport; - int index, ret; - - printk(KERN_INFO "HSU: found PCI Serial controller(ID: %04x:%04x)\n", - pdev->vendor, pdev->device); - - switch (pdev->device) { - case 0x081B: - index = 0; - break; - case 0x081C: - index = 1; - break; - case 0x081D: - index = 2; - break; - case 0x081E: - /* internal DMA controller */ - index = 3; - break; - default: - dev_err(&pdev->dev, "HSU: out of index!"); - return -ENODEV; - } - - ret = pci_enable_device(pdev); - if (ret) - return ret; - - if (index == 3) { - /* DMA controller */ - ret = request_irq(pdev->irq, dma_irq, 0, "hsu_dma", phsu); - if (ret) { - dev_err(&pdev->dev, "can not get IRQ\n"); - goto err_disable; - } - pci_set_drvdata(pdev, phsu); - } else { - /* UART port 0~2 */ - uport = &phsu->port[index]; - uport->port.irq = pdev->irq; - uport->port.dev = &pdev->dev; - uport->dev = &pdev->dev; - - ret = request_irq(pdev->irq, port_irq, 0, uport->name, uport); - if (ret) { - dev_err(&pdev->dev, "can not get IRQ\n"); - goto err_disable; - } - uart_add_one_port(&serial_hsu_reg, &uport->port); - - pci_set_drvdata(pdev, uport); - } - - pm_runtime_put_noidle(&pdev->dev); - pm_runtime_allow(&pdev->dev); - - return 0; - -err_disable: - pci_disable_device(pdev); - return ret; -} - -static void hsu_global_init(void) -{ - struct hsu_port *hsu; - struct uart_hsu_port *uport; - struct hsu_dma_chan *dchan; - int i, ret; - - hsu = kzalloc(sizeof(struct hsu_port), GFP_KERNEL); - if (!hsu) - return; - - /* Get basic io resource and map it */ - hsu->paddr = 0xffa28000; - hsu->iolen = 0x1000; - - if (!(request_mem_region(hsu->paddr, hsu->iolen, "HSU global"))) - pr_warn("HSU: error in request mem region\n"); - - hsu->reg = ioremap_nocache((unsigned long)hsu->paddr, hsu->iolen); - if (!hsu->reg) { - pr_err("HSU: error in ioremap\n"); - ret = -ENOMEM; - goto err_free_region; - } - - /* Initialise the 3 UART ports */ - uport = hsu->port; - for (i = 0; i < 3; i++) { - uport->port.type = PORT_MFD; - uport->port.iotype = UPIO_MEM; - uport->port.mapbase = (resource_size_t)hsu->paddr - + HSU_PORT_REG_OFFSET - + i * HSU_PORT_REG_LENGTH; - uport->port.membase = hsu->reg + HSU_PORT_REG_OFFSET - + i * HSU_PORT_REG_LENGTH; - - sprintf(uport->name, "hsu_port%d", i); - uport->port.fifosize = 64; - uport->port.ops = &serial_hsu_pops; - uport->port.line = i; - uport->port.flags = UPF_IOREMAP; - /* set the scalable maxim support rate to 2746800 bps */ - uport->port.uartclk = 115200 * 24 * 16; - - uport->running = 0; - uport->txc = &hsu->chans[i * 2]; - uport->rxc = &hsu->chans[i * 2 + 1]; - - serial_hsu_ports[i] = uport; - uport->index = i; - - if (hsu_dma_enable & (1<use_dma = 1; - else - uport->use_dma = 0; - - uport++; - } - - /* Initialise 6 dma channels */ - dchan = hsu->chans; - for (i = 0; i < 6; i++) { - dchan->id = i; - dchan->dirt = (i & 0x1) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; - dchan->uport = &hsu->port[i/2]; - dchan->reg = hsu->reg + HSU_DMA_CHANS_REG_OFFSET + - i * HSU_DMA_CHANS_REG_LENGTH; - - dchan++; - } - - phsu = hsu; - hsu_debugfs_init(hsu); - return; - -err_free_region: - release_mem_region(hsu->paddr, hsu->iolen); - kfree(hsu); - return; -} - -static void serial_hsu_remove(struct pci_dev *pdev) -{ - void *priv = pci_get_drvdata(pdev); - struct uart_hsu_port *up; - - if (!priv) - return; - - pm_runtime_forbid(&pdev->dev); - pm_runtime_get_noresume(&pdev->dev); - - /* For port 0/1/2, priv is the address of uart_hsu_port */ - if (pdev->device != 0x081E) { - up = priv; - uart_remove_one_port(&serial_hsu_reg, &up->port); - } - - free_irq(pdev->irq, priv); - pci_disable_device(pdev); -} - -/* First 3 are UART ports, and the 4th is the DMA */ -static const struct pci_device_id pci_ids[] = { - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x081B) }, - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x081C) }, - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x081D) }, - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x081E) }, - {}, -}; - -static struct pci_driver hsu_pci_driver = { - .name = "HSU serial", - .id_table = pci_ids, - .probe = serial_hsu_probe, - .remove = serial_hsu_remove, - .suspend = serial_hsu_suspend, - .resume = serial_hsu_resume, - .driver = { - .pm = &serial_hsu_pm_ops, - }, -}; - -static int __init hsu_pci_init(void) -{ - int ret; - - hsu_global_init(); - - ret = uart_register_driver(&serial_hsu_reg); - if (ret) - return ret; - - return pci_register_driver(&hsu_pci_driver); -} - -static void __exit hsu_pci_exit(void) -{ - pci_unregister_driver(&hsu_pci_driver); - uart_unregister_driver(&serial_hsu_reg); - - hsu_debugfs_remove(phsu); - - kfree(phsu); -} - -module_init(hsu_pci_init); -module_exit(hsu_pci_exit); - -MODULE_LICENSE("GPL v2"); -MODULE_DEVICE_TABLE(pci, pci_ids); diff --git a/include/linux/serial_mfd.h b/include/linux/serial_mfd.h deleted file mode 100644 index 2b071e0b034d..000000000000 --- a/include/linux/serial_mfd.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef _SERIAL_MFD_H_ -#define _SERIAL_MFD_H_ - -/* HW register offset definition */ -#define UART_FOR 0x08 -#define UART_PS 0x0C -#define UART_MUL 0x0D -#define UART_DIV 0x0E - -#define HSU_GBL_IEN 0x0 -#define HSU_GBL_IST 0x4 - -#define HSU_GBL_INT_BIT_PORT0 0x0 -#define HSU_GBL_INT_BIT_PORT1 0x1 -#define HSU_GBL_INT_BIT_PORT2 0x2 -#define HSU_GBL_INT_BIT_IRI 0x3 -#define HSU_GBL_INT_BIT_HDLC 0x4 -#define HSU_GBL_INT_BIT_DMA 0x5 - -#define HSU_GBL_ISR 0x8 -#define HSU_GBL_DMASR 0x400 -#define HSU_GBL_DMAISR 0x404 - -#define HSU_PORT_REG_OFFSET 0x80 -#define HSU_PORT0_REG_OFFSET 0x80 -#define HSU_PORT1_REG_OFFSET 0x100 -#define HSU_PORT2_REG_OFFSET 0x180 -#define HSU_PORT_REG_LENGTH 0x80 - -#define HSU_DMA_CHANS_REG_OFFSET 0x500 -#define HSU_DMA_CHANS_REG_LENGTH 0x40 - -#define HSU_CH_SR 0x0 /* channel status reg */ -#define HSU_CH_CR 0x4 /* control reg */ -#define HSU_CH_DCR 0x8 /* descriptor control reg */ -#define HSU_CH_BSR 0x10 /* max fifo buffer size reg */ -#define HSU_CH_MOTSR 0x14 /* minimum ocp transfer size */ -#define HSU_CH_D0SAR 0x20 /* desc 0 start addr */ -#define HSU_CH_D0TSR 0x24 /* desc 0 transfer size */ -#define HSU_CH_D1SAR 0x28 -#define HSU_CH_D1TSR 0x2C -#define HSU_CH_D2SAR 0x30 -#define HSU_CH_D2TSR 0x34 -#define HSU_CH_D3SAR 0x38 -#define HSU_CH_D3TSR 0x3C - -#endif diff --git a/include/uapi/linux/serial_reg.h b/include/uapi/linux/serial_reg.h index 00adb01fa5f3..e9b4cb0cd7ed 100644 --- a/include/uapi/linux/serial_reg.h +++ b/include/uapi/linux/serial_reg.h @@ -241,25 +241,6 @@ #define UART_FCR_PXAR16 0x80 /* receive FIFO threshold = 16 */ #define UART_FCR_PXAR32 0xc0 /* receive FIFO threshold = 32 */ -/* - * Intel MID on-chip HSU (High Speed UART) defined bits - */ -#define UART_FCR_HSU_64_1B 0x00 /* receive FIFO treshold = 1 */ -#define UART_FCR_HSU_64_16B 0x40 /* receive FIFO treshold = 16 */ -#define UART_FCR_HSU_64_32B 0x80 /* receive FIFO treshold = 32 */ -#define UART_FCR_HSU_64_56B 0xc0 /* receive FIFO treshold = 56 */ - -#define UART_FCR_HSU_16_1B 0x00 /* receive FIFO treshold = 1 */ -#define UART_FCR_HSU_16_4B 0x40 /* receive FIFO treshold = 4 */ -#define UART_FCR_HSU_16_8B 0x80 /* receive FIFO treshold = 8 */ -#define UART_FCR_HSU_16_14B 0xc0 /* receive FIFO treshold = 14 */ - -#define UART_FCR_HSU_64B_FIFO 0x20 /* chose 64 bytes FIFO */ -#define UART_FCR_HSU_16B_FIFO 0x00 /* chose 16 bytes FIFO */ - -#define UART_FCR_HALF_EMPT_TXI 0x00 /* trigger TX_EMPT IRQ for half empty */ -#define UART_FCR_FULL_EMPT_TXI 0x08 /* trigger TX_EMPT IRQ for full empty */ - /* * These register definitions are for the 16C950 */ -- GitLab From 91555ce9012557b2d621d7b0b6ec694218a2a9bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Tue, 24 Feb 2015 11:17:05 +0100 Subject: [PATCH 03263/11651] serial: imx: Fix clearing of receiver overrun flag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The writeable bits in the USR2 register are all "write 1 to clear" so only write the bits that actually should be cleared. Fixes: f1f836e4209e ("serial: imx: Add Rx Fifo overrun error message") Signed-off-by: Uwe Kleine-König Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/imx.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index ca00b3f1520f..0f2afae25f6e 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -818,7 +818,7 @@ static irqreturn_t imx_int(int irq, void *dev_id) if (sts2 & USR2_ORE) { dev_err(sport->port.dev, "Rx FIFO overrun\n"); sport->port.icount.overrun++; - writel(sts2 | USR2_ORE, sport->port.membase + USR2); + writel(USR2_ORE, sport->port.membase + USR2); } return IRQ_HANDLED; @@ -1181,10 +1181,12 @@ static int imx_startup(struct uart_port *port) imx_uart_dma_init(sport); spin_lock_irqsave(&sport->port.lock, flags); + /* * Finally, clear and enable interrupts */ writel(USR1_RTSD, sport->port.membase + USR1); + writel(USR2_ORE, sport->port.membase + USR2); if (sport->dma_is_inited && !sport->dma_is_enabled) imx_enable_dma(sport); @@ -1199,10 +1201,6 @@ static int imx_startup(struct uart_port *port) writel(temp, sport->port.membase + UCR1); - /* Clear any pending ORE flag before enabling interrupt */ - temp = readl(sport->port.membase + USR2); - writel(temp | USR2_ORE, sport->port.membase + USR2); - temp = readl(sport->port.membase + UCR4); temp |= UCR4_OREN; writel(temp, sport->port.membase + UCR4); -- GitLab From 694e6729bf0e317e0b67c37cda1b74a5b04fbc07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Tue, 24 Feb 2015 11:17:06 +0100 Subject: [PATCH 03264/11651] serial: imx: remove long dead code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This if (0) exists since the driver was introduced in commit c49bde83eb6a ([ARM PATCH] 1956/2: Re: Motorola i.MX serial driver) back in 2004. Signed-off-by: Uwe Kleine-König Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/imx.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 0f2afae25f6e..9e3a8ffe97b4 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -1370,15 +1370,6 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios, unsigned long num, denom; uint64_t tdiv64; - /* - * If we don't support modem control lines, don't allow - * these to be set. - */ - if (0) { - termios->c_cflag &= ~(HUPCL | CRTSCTS | CMSPAR); - termios->c_cflag |= CLOCAL; - } - /* * We only support CS7 and CS8. */ -- GitLab From 842633bdcee64d5c1861eb67677e3500c5d208e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Tue, 24 Feb 2015 11:17:07 +0100 Subject: [PATCH 03265/11651] serial: imx: drop members from driver data that are only used during probe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is no benefit in keeping this information in RAM when it's not used any more, so better use function local variables instead. These members are unused since c0d1c6b0f0dc ("serial: imx: Fix the reporting of interrupts") Signed-off-by: Uwe Kleine-König Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/imx.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 9e3a8ffe97b4..65251984ba03 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -206,7 +206,6 @@ struct imx_port { struct uart_port port; struct timer_list timer; unsigned int old_status; - int txirq, rxirq, rtsirq; unsigned int have_rtscts:1; unsigned int dte_mode:1; unsigned int use_irda:1; @@ -1956,6 +1955,7 @@ static int serial_imx_probe(struct platform_device *pdev) void __iomem *base; int ret = 0; struct resource *res; + int txirq, rxirq, rtsirq; sport = devm_kzalloc(&pdev->dev, sizeof(*sport), GFP_KERNEL); if (!sport) @@ -1972,15 +1972,16 @@ static int serial_imx_probe(struct platform_device *pdev) if (IS_ERR(base)) return PTR_ERR(base); + rxirq = platform_get_irq(pdev, 0); + txirq = platform_get_irq(pdev, 1); + rtsirq = platform_get_irq(pdev, 2); + sport->port.dev = &pdev->dev; sport->port.mapbase = res->start; sport->port.membase = base; sport->port.type = PORT_IMX, sport->port.iotype = UPIO_MEM; - sport->port.irq = platform_get_irq(pdev, 0); - sport->rxirq = platform_get_irq(pdev, 0); - sport->txirq = platform_get_irq(pdev, 1); - sport->rtsirq = platform_get_irq(pdev, 2); + sport->port.irq = rxirq; sport->port.fifosize = 32; sport->port.ops = &imx_pops; sport->port.flags = UPF_BOOT_AUTOCONF; @@ -2008,27 +2009,27 @@ static int serial_imx_probe(struct platform_device *pdev) * Allocate the IRQ(s) i.MX1 has three interrupts whereas later * chips only have one interrupt. */ - if (sport->txirq > 0) { - ret = devm_request_irq(&pdev->dev, sport->rxirq, imx_rxint, 0, + if (txirq > 0) { + ret = devm_request_irq(&pdev->dev, rxirq, imx_rxint, 0, dev_name(&pdev->dev), sport); if (ret) return ret; - ret = devm_request_irq(&pdev->dev, sport->txirq, imx_txint, 0, + ret = devm_request_irq(&pdev->dev, txirq, imx_txint, 0, dev_name(&pdev->dev), sport); if (ret) return ret; /* do not use RTS IRQ on IrDA */ if (!USE_IRDA(sport)) { - ret = devm_request_irq(&pdev->dev, sport->rtsirq, + ret = devm_request_irq(&pdev->dev, rtsirq, imx_rtsint, 0, dev_name(&pdev->dev), sport); if (ret) return ret; } } else { - ret = devm_request_irq(&pdev->dev, sport->port.irq, imx_int, 0, + ret = devm_request_irq(&pdev->dev, rxirq, imx_int, 0, dev_name(&pdev->dev), sport); if (ret) return ret; -- GitLab From f890cef24bc0e17ea9a1f5c39d9105f3e8bc4f13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Tue, 24 Feb 2015 11:17:08 +0100 Subject: [PATCH 03266/11651] serial: imx: reformat and cleanup copyright header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix indention, remove old address of the FSF, remove in-file changelog, mention Freescale. Signed-off-by: Uwe Kleine-König Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/imx.c | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 65251984ba03..6ec35e1168eb 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -1,13 +1,13 @@ /* - * Driver for Motorola IMX serial ports + * Driver for Motorola/Freescale IMX serial ports * - * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. + * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. * - * Author: Sascha Hauer - * Copyright (C) 2004 Pengutronix + * Author: Sascha Hauer + * Copyright (C) 2004 Pengutronix * - * Copyright (C) 2009 emlix GmbH - * Author: Fabian Godehardt (added IrDA support for iMX) + * Author: Fabian Godehardt (added IrDA support for iMX) + * Copyright (C) 2009 emlix GmbH * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,13 +18,6 @@ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * [29-Mar-2005] Mike Lee - * Added hardware handshake */ #if defined(CONFIG_SERIAL_IMX_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) -- GitLab From f95661b2f2ae75c9b07b9b4e0a9a55c40e085e6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Tue, 24 Feb 2015 11:17:09 +0100 Subject: [PATCH 03267/11651] serial: imx: fix comment about which machines use the i.MX21 type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Uwe Kleine-König Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/imx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 6ec35e1168eb..cbbb47385877 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -182,7 +182,7 @@ #define UART_NR 8 -/* i.mx21 type uart runs on all i.mx except i.mx1 */ +/* i.MX21 type uart runs on all i.mx except i.MX1 and i.MX6q */ enum imx_uart_type { IMX1_UART, IMX21_UART, -- GitLab From afe9cbb1a6adf6da5fa6d4747d102b95b4bb52c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Tue, 24 Feb 2015 11:17:10 +0100 Subject: [PATCH 03268/11651] serial: imx: drop support for IRDA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Support for IRDA was added in 2009 in commit v2.6.31-rc1~399^2~2. There are no in-tree users. Signed-off-by: Uwe Kleine-König Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/imx.c | 157 ++--------------------- include/linux/platform_data/serial-imx.h | 5 - 2 files changed, 9 insertions(+), 153 deletions(-) diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index cbbb47385877..6dc1d2781b86 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -6,9 +6,6 @@ * Author: Sascha Hauer * Copyright (C) 2004 Pengutronix * - * Author: Fabian Godehardt (added IrDA support for iMX) - * Copyright (C) 2009 emlix GmbH - * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -201,7 +198,6 @@ struct imx_port { unsigned int old_status; unsigned int have_rtscts:1; unsigned int dte_mode:1; - unsigned int use_irda:1; unsigned int irda_inv_rx:1; unsigned int irda_inv_tx:1; unsigned short trcv_delay; /* transceiver delay */ @@ -228,12 +224,6 @@ struct imx_port_ucrs { unsigned int ucr3; }; -#ifdef CONFIG_IRDA -#define USE_IRDA(sport) ((sport)->use_irda) -#else -#define USE_IRDA(sport) (0) -#endif - static struct imx_uart_data imx_uart_devdata[] = { [IMX1_UART] = { .uts_reg = IMX1_UTS, @@ -368,48 +358,6 @@ static void imx_stop_tx(struct uart_port *port) struct imx_port *sport = (struct imx_port *)port; unsigned long temp; - if (USE_IRDA(sport)) { - /* half duplex - wait for end of transmission */ - int n = 256; - while ((--n > 0) && - !(readl(sport->port.membase + USR2) & USR2_TXDC)) { - udelay(5); - barrier(); - } - /* - * irda transceiver - wait a bit more to avoid - * cutoff, hardware dependent - */ - udelay(sport->trcv_delay); - - /* - * half duplex - reactivate receive mode, - * flush receive pipe echo crap - */ - if (readl(sport->port.membase + USR2) & USR2_TXDC) { - temp = readl(sport->port.membase + UCR1); - temp &= ~(UCR1_TXMPTYEN | UCR1_TRDYEN); - writel(temp, sport->port.membase + UCR1); - - temp = readl(sport->port.membase + UCR4); - temp &= ~(UCR4_TCEN); - writel(temp, sport->port.membase + UCR4); - - while (readl(sport->port.membase + URXD0) & - URXD_CHARRDY) - barrier(); - - temp = readl(sport->port.membase + UCR1); - temp |= UCR1_RRDYEN; - writel(temp, sport->port.membase + UCR1); - - temp = readl(sport->port.membase + UCR4); - temp |= UCR4_DREN; - writel(temp, sport->port.membase + UCR4); - } - return; - } - /* * We are maybe in the SMP context, so if the DMA TX thread is running * on other cpu, we have to wait for it to finish. @@ -612,32 +560,11 @@ static void imx_start_tx(struct uart_port *port) struct imx_port *sport = (struct imx_port *)port; unsigned long temp; - if (USE_IRDA(sport)) { - /* half duplex in IrDA mode; have to disable receive mode */ - temp = readl(sport->port.membase + UCR4); - temp &= ~(UCR4_DREN); - writel(temp, sport->port.membase + UCR4); - - temp = readl(sport->port.membase + UCR1); - temp &= ~(UCR1_RRDYEN); - writel(temp, sport->port.membase + UCR1); - } - if (!sport->dma_is_enabled) { temp = readl(sport->port.membase + UCR1); writel(temp | UCR1_TXMPTYEN, sport->port.membase + UCR1); } - if (USE_IRDA(sport)) { - temp = readl(sport->port.membase + UCR1); - temp |= UCR1_TRDYEN; - writel(temp, sport->port.membase + UCR1); - - temp = readl(sport->port.membase + UCR4); - temp |= UCR4_TCEN; - writel(temp, sport->port.membase + UCR4); - } - if (sport->dma_is_enabled) { if (sport->port.x_char) { /* We have X-char to send, so enable TX IRQ and @@ -1148,9 +1075,6 @@ static int imx_startup(struct uart_port *port) */ temp = readl(sport->port.membase + UCR4); - if (USE_IRDA(sport)) - temp |= UCR4_IRSC; - /* set the trigger level for CTS */ temp &= ~(UCR4_CTSTL_MASK << UCR4_CTSTL_SHF); temp |= CTSTL << UCR4_CTSTL_SHF; @@ -1186,11 +1110,6 @@ static int imx_startup(struct uart_port *port) temp = readl(sport->port.membase + UCR1); temp |= UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN; - if (USE_IRDA(sport)) { - temp |= UCR1_IREN; - temp &= ~(UCR1_RTSDEN); - } - writel(temp, sport->port.membase + UCR1); temp = readl(sport->port.membase + UCR4); @@ -1209,38 +1128,12 @@ static int imx_startup(struct uart_port *port) writel(temp, sport->port.membase + UCR3); } - if (USE_IRDA(sport)) { - temp = readl(sport->port.membase + UCR4); - if (sport->irda_inv_rx) - temp |= UCR4_INVR; - else - temp &= ~(UCR4_INVR); - writel(temp | UCR4_DREN, sport->port.membase + UCR4); - - temp = readl(sport->port.membase + UCR3); - if (sport->irda_inv_tx) - temp |= UCR3_INVT; - else - temp &= ~(UCR3_INVT); - writel(temp, sport->port.membase + UCR3); - } - /* * Enable modem status interrupts */ imx_enable_ms(&sport->port); spin_unlock_irqrestore(&sport->port.lock, flags); - if (USE_IRDA(sport)) { - struct imxuart_platform_data *pdata; - pdata = dev_get_platdata(sport->port.dev); - sport->irda_inv_rx = pdata->irda_inv_rx; - sport->irda_inv_tx = pdata->irda_inv_tx; - sport->trcv_delay = pdata->transceiver_delay; - if (pdata->irda_enable) - pdata->irda_enable(1); - } - return 0; } @@ -1276,13 +1169,6 @@ static void imx_shutdown(struct uart_port *port) writel(temp, sport->port.membase + UCR2); spin_unlock_irqrestore(&sport->port.lock, flags); - if (USE_IRDA(sport)) { - struct imxuart_platform_data *pdata; - pdata = dev_get_platdata(sport->port.dev); - if (pdata->irda_enable) - pdata->irda_enable(0); - } - /* * Stop our timer. */ @@ -1295,8 +1181,6 @@ static void imx_shutdown(struct uart_port *port) spin_lock_irqsave(&sport->port.lock, flags); temp = readl(sport->port.membase + UCR1); temp &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN); - if (USE_IRDA(sport)) - temp &= ~(UCR1_IREN); writel(temp, sport->port.membase + UCR1); spin_unlock_irqrestore(&sport->port.lock, flags); @@ -1450,24 +1334,16 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios, sport->port.membase + UCR2); old_txrxen &= (UCR2_TXEN | UCR2_RXEN); - if (USE_IRDA(sport)) { - /* - * use maximum available submodule frequency to - * avoid missing short pulses due to low sampling rate - */ + /* custom-baudrate handling */ + div = sport->port.uartclk / (baud * 16); + if (baud == 38400 && quot != div) + baud = sport->port.uartclk / (quot * 16); + + div = sport->port.uartclk / (baud * 16); + if (div > 7) + div = 7; + if (!div) div = 1; - } else { - /* custom-baudrate handling */ - div = sport->port.uartclk / (baud * 16); - if (baud == 38400 && quot != div) - baud = sport->port.uartclk / (quot * 16); - - div = sport->port.uartclk / (baud * 16); - if (div > 7) - div = 7; - if (!div) - div = 1; - } rational_best_approximation(16 * div * baud, sport->port.uartclk, 1 << 16, 1 << 16, &num, &denom); @@ -1906,9 +1782,6 @@ static int serial_imx_probe_dt(struct imx_port *sport, if (of_get_property(np, "fsl,uart-has-rtscts", NULL)) sport->have_rtscts = 1; - if (of_get_property(np, "fsl,irda-mode", NULL)) - sport->use_irda = 1; - if (of_get_property(np, "fsl,dte-mode", NULL)) sport->dte_mode = 1; @@ -1937,9 +1810,6 @@ static void serial_imx_probe_pdata(struct imx_port *sport, if (pdata->flags & IMXUART_HAVE_RTSCTS) sport->have_rtscts = 1; - - if (pdata->flags & IMXUART_IRDA) - sport->use_irda = 1; } static int serial_imx_probe(struct platform_device *pdev) @@ -2012,15 +1882,6 @@ static int serial_imx_probe(struct platform_device *pdev) dev_name(&pdev->dev), sport); if (ret) return ret; - - /* do not use RTS IRQ on IrDA */ - if (!USE_IRDA(sport)) { - ret = devm_request_irq(&pdev->dev, rtsirq, - imx_rtsint, 0, - dev_name(&pdev->dev), sport); - if (ret) - return ret; - } } else { ret = devm_request_irq(&pdev->dev, rxirq, imx_int, 0, dev_name(&pdev->dev), sport); diff --git a/include/linux/platform_data/serial-imx.h b/include/linux/platform_data/serial-imx.h index 3cc2e3c40914..a938eba2f18e 100644 --- a/include/linux/platform_data/serial-imx.h +++ b/include/linux/platform_data/serial-imx.h @@ -20,14 +20,9 @@ #define ASMARM_ARCH_UART_H #define IMXUART_HAVE_RTSCTS (1<<0) -#define IMXUART_IRDA (1<<1) struct imxuart_platform_data { unsigned int flags; - void (*irda_enable)(int enable); - unsigned int irda_inv_rx:1; - unsigned int irda_inv_tx:1; - unsigned short transceiver_delay; }; #endif -- GitLab From 17b8f2a3fdca29a9b296642fb3f6ad3c39ffc7d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Tue, 24 Feb 2015 11:17:11 +0100 Subject: [PATCH 03269/11651] serial: imx: add support for half duplex rs485 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The transmitter is expected to be controlled by the UART's RTS pin. Signed-off-by: Uwe Kleine-König Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/imx.c | 107 ++++++++++++++++++++++++++++++++++----- 1 file changed, 95 insertions(+), 12 deletions(-) diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 6dc1d2781b86..ddfb672d0152 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -365,8 +365,23 @@ static void imx_stop_tx(struct uart_port *port) if (sport->dma_is_enabled && sport->dma_is_txing) return; - temp = readl(sport->port.membase + UCR1); - writel(temp & ~UCR1_TXMPTYEN, sport->port.membase + UCR1); + temp = readl(port->membase + UCR1); + writel(temp & ~UCR1_TXMPTYEN, port->membase + UCR1); + + /* in rs485 mode disable transmitter if shifter is empty */ + if (port->rs485.flags & SER_RS485_ENABLED && + readl(port->membase + USR2) & USR2_TXDC) { + temp = readl(port->membase + UCR2); + if (port->rs485.flags & SER_RS485_RTS_AFTER_SEND) + temp &= ~UCR2_CTS; + else + temp |= UCR2_CTS; + writel(temp, port->membase + UCR2); + + temp = readl(port->membase + UCR4); + temp &= ~UCR4_TCEN; + writel(temp, port->membase + UCR4); + } } /* @@ -560,6 +575,20 @@ static void imx_start_tx(struct uart_port *port) struct imx_port *sport = (struct imx_port *)port; unsigned long temp; + if (port->rs485.flags & SER_RS485_ENABLED) { + /* enable transmitter and shifter empty irq */ + temp = readl(port->membase + UCR2); + if (port->rs485.flags & SER_RS485_RTS_ON_SEND) + temp &= ~UCR2_CTS; + else + temp |= UCR2_CTS; + writel(temp, port->membase + UCR2); + + temp = readl(port->membase + UCR4); + temp |= UCR4_TCEN; + writel(temp, port->membase + UCR4); + } + if (!sport->dma_is_enabled) { temp = readl(sport->port.membase + UCR1); writel(temp | UCR1_TXMPTYEN, sport->port.membase + UCR1); @@ -715,6 +744,7 @@ static irqreturn_t imx_int(int irq, void *dev_id) unsigned int sts2; sts = readl(sport->port.membase + USR1); + sts2 = readl(sport->port.membase + USR2); if (sts & USR1_RRDY) { if (sport->dma_is_enabled) @@ -723,8 +753,10 @@ static irqreturn_t imx_int(int irq, void *dev_id) imx_rxint(irq, dev_id); } - if (sts & USR1_TRDY && - readl(sport->port.membase + UCR1) & UCR1_TXMPTYEN) + if ((sts & USR1_TRDY && + readl(sport->port.membase + UCR1) & UCR1_TXMPTYEN) || + (sts2 & USR2_TXDC && + readl(sport->port.membase + UCR4) & UCR4_TCEN)) imx_txint(irq, dev_id); if (sts & USR1_RTSD) @@ -733,7 +765,6 @@ static irqreturn_t imx_int(int irq, void *dev_id) if (sts & USR1_AWAKE) writel(USR1_AWAKE, sport->port.membase + USR1); - sts2 = readl(sport->port.membase + USR2); if (sts2 & USR2_ORE) { dev_err(sport->port.dev, "Rx FIFO overrun\n"); sport->port.icount.overrun++; @@ -785,11 +816,13 @@ static void imx_set_mctrl(struct uart_port *port, unsigned int mctrl) struct imx_port *sport = (struct imx_port *)port; unsigned long temp; - temp = readl(sport->port.membase + UCR2) & ~(UCR2_CTS | UCR2_CTSC); - if (mctrl & TIOCM_RTS) - temp |= UCR2_CTS | UCR2_CTSC; - - writel(temp, sport->port.membase + UCR2); + if (!(port->rs485.flags & SER_RS485_ENABLED)) { + temp = readl(sport->port.membase + UCR2); + temp &= ~(UCR2_CTS | UCR2_CTSC); + if (mctrl & TIOCM_RTS) + temp |= UCR2_CTS | UCR2_CTSC; + writel(temp, sport->port.membase + UCR2); + } temp = readl(sport->port.membase + uts_reg(sport)) & ~UTS_LOOP; if (mctrl & TIOCM_LOOP) @@ -1264,11 +1297,26 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios, if (termios->c_cflag & CRTSCTS) { if (sport->have_rtscts) { ucr2 &= ~UCR2_IRTS; - ucr2 |= UCR2_CTSC; + + if (port->rs485.flags & SER_RS485_ENABLED) + /* + * RTS is mandatory for rs485 operation, so keep + * it under manual control and keep transmitter + * disabled. + */ + if (!(port->rs485.flags & + SER_RS485_RTS_AFTER_SEND)) + ucr2 |= UCR2_CTS; + else + ucr2 |= UCR2_CTSC; + } else { termios->c_cflag &= ~CRTSCTS; } - } + } else if (port->rs485.flags & SER_RS485_ENABLED) + /* disable transmitter */ + if (!(port->rs485.flags & SER_RS485_RTS_AFTER_SEND)) + ucr2 |= UCR2_CTS; if (termios->c_cflag & CSTOPB) ucr2 |= UCR2_STPB; @@ -1490,6 +1538,38 @@ static void imx_poll_put_char(struct uart_port *port, unsigned char c) } #endif +static int imx_rs485_config(struct uart_port *port, + struct serial_rs485 *rs485conf) +{ + struct imx_port *sport = (struct imx_port *)port; + + /* unimplemented */ + rs485conf->delay_rts_before_send = 0; + rs485conf->delay_rts_after_send = 0; + rs485conf->flags |= SER_RS485_RX_DURING_TX; + + /* RTS is required to control the transmitter */ + if (!sport->have_rtscts) + rs485conf->flags &= ~SER_RS485_ENABLED; + + if (rs485conf->flags & SER_RS485_ENABLED) { + unsigned long temp; + + /* disable transmitter */ + temp = readl(sport->port.membase + UCR2); + temp &= ~UCR2_CTSC; + if (rs485conf->flags & SER_RS485_RTS_AFTER_SEND) + temp &= ~UCR2_CTS; + else + temp |= UCR2_CTS; + writel(temp, sport->port.membase + UCR2); + } + + port->rs485 = *rs485conf; + + return 0; +} + static struct uart_ops imx_pops = { .tx_empty = imx_tx_empty, .set_mctrl = imx_set_mctrl, @@ -1847,6 +1927,9 @@ static int serial_imx_probe(struct platform_device *pdev) sport->port.irq = rxirq; sport->port.fifosize = 32; sport->port.ops = &imx_pops; + sport->port.rs485_config = imx_rs485_config; + sport->port.rs485.flags = + SER_RS485_RTS_ON_SEND | SER_RS485_RX_DURING_TX; sport->port.flags = UPF_BOOT_AUTOCONF; init_timer(&sport->timer); sport->timer.function = imx_timeout; -- GitLab From 7950dc586092d0c7a8b881188061cc3dc133d7e9 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Tue, 24 Feb 2015 12:06:34 -0500 Subject: [PATCH 03270/11651] serial: sprd: Fix iotype The Spreadtrum UART is accessed with mmio; declare the proper iotype. Also prevent userspace from assigning any other iotype via ioctl(TIOCSSERIAL). Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sprd_serial.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/sprd_serial.c b/drivers/tty/serial/sprd_serial.c index be3ed3f4ad60..2e6d63eabb2e 100644 --- a/drivers/tty/serial/sprd_serial.c +++ b/drivers/tty/serial/sprd_serial.c @@ -491,6 +491,8 @@ static int sprd_verify_port(struct uart_port *port, return -EINVAL; if (port->irq != ser->irq) return -EINVAL; + if (port->iotype != ser->io_type) + return -EINVAL; return 0; } @@ -705,7 +707,7 @@ static int sprd_probe(struct platform_device *pdev) up->dev = &pdev->dev; up->line = index; up->type = PORT_SPRD; - up->iotype = SERIAL_IO_PORT; + up->iotype = UPIO_MEM; up->uartclk = SPRD_DEF_RATE; up->fifosize = SPRD_FIFO_SIZE; up->ops = &serial_sprd_ops; -- GitLab From f6415491c5f33df1adb5983070618f30370bd346 Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Tue, 24 Feb 2015 15:13:57 -0800 Subject: [PATCH 03271/11651] tty: serial: xilinx_uartps: Use Macro for ttyPS0 All instances of "ttyPS" use this macro except for this one. Convert it. Signed-off-by: Peter Crosthwaite Acked-by: Michal Simek Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/xilinx_uartps.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c index cff531a51a78..8f9c5430f470 100644 --- a/drivers/tty/serial/xilinx_uartps.c +++ b/drivers/tty/serial/xilinx_uartps.c @@ -1154,7 +1154,8 @@ static int __init cdns_uart_console_setup(struct console *co, char *options) return -EINVAL; if (!port->mapbase) { - pr_debug("console on ttyPS%i not present\n", co->index); + pr_debug("console on " CDNS_UART_TTY_NAME "%i not present\n", + co->index); return -ENODEV; } -- GitLab From 30a22c215a0007603ffc08021f2e8b64018517dd Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sun, 1 Mar 2015 10:11:05 -0500 Subject: [PATCH 03272/11651] console: Fix console name size mismatch commit 6ae9200f2cab7 ("enlarge console.name") increased the storage for the console name to 16 bytes, but not the corresponding struct console_cmdline::name storage. Console names longer than 8 bytes cause read beyond end-of-string and failure to match console; I'm not sure if there are other unexpected consequences. Cc: # 2.6.22+ Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- kernel/printk/console_cmdline.h | 2 +- kernel/printk/printk.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/printk/console_cmdline.h b/kernel/printk/console_cmdline.h index cbd69d842341..2ca4a8b5fe57 100644 --- a/kernel/printk/console_cmdline.h +++ b/kernel/printk/console_cmdline.h @@ -3,7 +3,7 @@ struct console_cmdline { - char name[8]; /* Name of the driver */ + char name[16]; /* Name of the driver */ int index; /* Minor dev. to use */ char *options; /* Options for the driver */ #ifdef CONFIG_A11Y_BRAILLE_CONSOLE diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 01cfd69c54c6..bb0635bd74f2 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -2464,6 +2464,7 @@ void register_console(struct console *newcon) for (i = 0, c = console_cmdline; i < MAX_CMDLINECONSOLES && c->name[0]; i++, c++) { + BUILD_BUG_ON(sizeof(c->name) != sizeof(newcon->name)); if (strcmp(c->name, newcon->name) != 0) continue; if (newcon->index >= 0 && -- GitLab From c4e6dcfa00dab9b10e75bba835393b81f256310b Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 16 Feb 2015 22:39:04 +0800 Subject: [PATCH 03273/11651] serial: sprd: Fix missing spin_unlock in sprd_handle_irq() Fix return from sprd_handle_irq() with spin_lock held. Signed-off-by: Axel Lin Reviewed-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sprd_serial.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/sprd_serial.c b/drivers/tty/serial/sprd_serial.c index 594b63331ef4..bca975f5093b 100644 --- a/drivers/tty/serial/sprd_serial.c +++ b/drivers/tty/serial/sprd_serial.c @@ -293,8 +293,10 @@ static irqreturn_t sprd_handle_irq(int irq, void *dev_id) ims = serial_in(port, SPRD_IMSR); - if (!ims) + if (!ims) { + spin_unlock(&port->lock); return IRQ_NONE; + } serial_out(port, SPRD_ICLR, ~0); -- GitLab From 2bb785169e9709d41220e5c18b0270883a82f85c Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sun, 1 Mar 2015 10:18:16 -0500 Subject: [PATCH 03274/11651] serial: core: Fix iotype userspace breakage commit 3ffb1a8193bea ("serial: core: Add big-endian iotype") re-numbered userspace-dependent values; ioctl(TIOCSSERIAL) can assign the port iotype (which is expected to match the selected i/o accessors), so iotype values must not be changed. Cc: Kevin Cernekee Cc: # 3.19+ Signed-off-by: Peter Hurley Reviewed-by: Kevin Cernekee Signed-off-by: Greg Kroah-Hartman --- include/linux/serial_core.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index baf3e1d08416..1094f2d9cadb 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -147,9 +147,9 @@ struct uart_port { #define UPIO_HUB6 (1) /* Hub6 ISA card */ #define UPIO_MEM (2) /* 8b MMIO access */ #define UPIO_MEM32 (3) /* 32b little endian */ -#define UPIO_MEM32BE (4) /* 32b big endian */ -#define UPIO_AU (5) /* Au1x00 and RT288x type IO */ -#define UPIO_TSI (6) /* Tsi108/109 type IO */ +#define UPIO_AU (4) /* Au1x00 and RT288x type IO */ +#define UPIO_TSI (5) /* Tsi108/109 type IO */ +#define UPIO_MEM32BE (6) /* 32b big endian */ unsigned int read_status_mask; /* driver specific */ unsigned int ignore_status_mask; /* driver specific */ -- GitLab From 647f162b8e7e446c4bade031eb8a1a0a83d3de82 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sun, 1 Mar 2015 10:24:28 -0500 Subject: [PATCH 03275/11651] serial: uapi: Declare all userspace-visible io types ioctl(TIOCGSERIAL|TIOCSSERIAL) report and can change the port->iotype. UART drivers use the UPIO_* definitions, but the uapi header defines parallel values and userspace uses these parallel values for ioctls; thus the userspace values are definitive. Define UPIO_* iotypes in terms of the uapi defines, SERIAL_IO_*; extend the uapi defines to include all values in use by the serial core. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- include/linux/serial_core.h | 14 +++++++------- include/uapi/linux/serial.h | 4 ++++ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 1094f2d9cadb..d10965f0d8a4 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -143,13 +143,13 @@ struct uart_port { unsigned char iotype; /* io access style */ unsigned char unused1; -#define UPIO_PORT (0) /* 8b I/O port access */ -#define UPIO_HUB6 (1) /* Hub6 ISA card */ -#define UPIO_MEM (2) /* 8b MMIO access */ -#define UPIO_MEM32 (3) /* 32b little endian */ -#define UPIO_AU (4) /* Au1x00 and RT288x type IO */ -#define UPIO_TSI (5) /* Tsi108/109 type IO */ -#define UPIO_MEM32BE (6) /* 32b big endian */ +#define UPIO_PORT (SERIAL_IO_PORT) /* 8b I/O port access */ +#define UPIO_HUB6 (SERIAL_IO_HUB6) /* Hub6 ISA card */ +#define UPIO_MEM (SERIAL_IO_MEM) /* 8b MMIO access */ +#define UPIO_MEM32 (SERIAL_IO_MEM32) /* 32b little endian */ +#define UPIO_AU (SERIAL_IO_AU) /* Au1x00 and RT288x type IO */ +#define UPIO_TSI (SERIAL_IO_TSI) /* Tsi108/109 type IO */ +#define UPIO_MEM32BE (SERIAL_IO_MEM32BE) /* 32b big endian */ unsigned int read_status_mask; /* driver specific */ unsigned int ignore_status_mask; /* driver specific */ diff --git a/include/uapi/linux/serial.h b/include/uapi/linux/serial.h index 5e0d0ed61cf3..25331f9faa76 100644 --- a/include/uapi/linux/serial.h +++ b/include/uapi/linux/serial.h @@ -65,6 +65,10 @@ struct serial_struct { #define SERIAL_IO_PORT 0 #define SERIAL_IO_HUB6 1 #define SERIAL_IO_MEM 2 +#define SERIAL_IO_MEM32 3 +#define SERIAL_IO_AU 4 +#define SERIAL_IO_TSI 5 +#define SERIAL_IO_MEM32BE 6 #define UART_CLEAR_FIFO 0x01 #define UART_USE_FIFO 0x02 -- GitLab From 2c3fbe3cf28fbd7001545a92a83b4f8acfd9fa36 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 4 Mar 2015 10:39:03 +0100 Subject: [PATCH 03276/11651] net: irda: fix wait_until_sent poll timeout In case an infinite timeout (0) is requested, the irda wait_until_sent implementation would use a zero poll timeout rather than the default 200ms. Note that wait_until_sent is currently never called with a 0-timeout argument due to a bug in tty_wait_until_sent. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable # v2.6.12 Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- net/irda/ircomm/ircomm_tty.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c index 40695b9751c1..4efe486baee6 100644 --- a/net/irda/ircomm/ircomm_tty.c +++ b/net/irda/ircomm/ircomm_tty.c @@ -798,7 +798,9 @@ static void ircomm_tty_wait_until_sent(struct tty_struct *tty, int timeout) orig_jiffies = jiffies; /* Set poll time to 200 ms */ - poll_time = IRDA_MIN(timeout, msecs_to_jiffies(200)); + poll_time = msecs_to_jiffies(200); + if (timeout) + poll_time = min_t(unsigned long, timeout, poll_time); spin_lock_irqsave(&self->spinlock, flags); while (self->tx_skb && self->tx_skb->len) { -- GitLab From 6b270fd4db08fc13683d616a733d9cacdd3b4afa Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 4 Mar 2015 10:39:04 +0100 Subject: [PATCH 03277/11651] TTY: bfin_jtag_comm: remove incorrect wait_until_sent operation Remove incorrect and redundant wait_until_sent operation, which waits for the driver buffer rather than any hardware buffers to drain, something which is already taken care of by the tty layer (and chars_in_buffer). Signed-off-by: Johan Hovold Reviewed-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/bfin_jtag_comm.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/drivers/tty/bfin_jtag_comm.c b/drivers/tty/bfin_jtag_comm.c index d7b198c400c7..ce24182f8514 100644 --- a/drivers/tty/bfin_jtag_comm.c +++ b/drivers/tty/bfin_jtag_comm.c @@ -210,18 +210,6 @@ bfin_jc_chars_in_buffer(struct tty_struct *tty) return circ_cnt(&bfin_jc_write_buf); } -static void -bfin_jc_wait_until_sent(struct tty_struct *tty, int timeout) -{ - unsigned long expire = jiffies + timeout; - while (!circ_empty(&bfin_jc_write_buf)) { - if (signal_pending(current)) - break; - if (time_after(jiffies, expire)) - break; - } -} - static const struct tty_operations bfin_jc_ops = { .open = bfin_jc_open, .close = bfin_jc_close, @@ -230,7 +218,6 @@ static const struct tty_operations bfin_jc_ops = { .flush_chars = bfin_jc_flush_chars, .write_room = bfin_jc_write_room, .chars_in_buffer = bfin_jc_chars_in_buffer, - .wait_until_sent = bfin_jc_wait_until_sent, }; static int __init bfin_jc_init(void) -- GitLab From f528bf4f57e43d1af4b2a5c97f09e43e0338c105 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 4 Mar 2015 10:39:05 +0100 Subject: [PATCH 03278/11651] USB: serial: fix infinite wait_until_sent timeout Make sure to handle an infinite timeout (0). Note that wait_until_sent is currently never called with a 0-timeout argument due to a bug in tty_wait_until_sent. Fixes: dcf010503966 ("USB: serial: add generic wait_until_sent implementation") Cc: stable # v3.10 Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/generic.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index ccf1df7c4b80..54e170dd3dad 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -258,7 +258,8 @@ void usb_serial_generic_wait_until_sent(struct tty_struct *tty, long timeout) * character or at least one jiffy. */ period = max_t(unsigned long, (10 * HZ / bps), 1); - period = min_t(unsigned long, period, timeout); + if (timeout) + period = min_t(unsigned long, period, timeout); dev_dbg(&port->dev, "%s - timeout = %u ms, period = %u ms\n", __func__, jiffies_to_msecs(timeout), @@ -268,7 +269,7 @@ void usb_serial_generic_wait_until_sent(struct tty_struct *tty, long timeout) schedule_timeout_interruptible(period); if (signal_pending(current)) break; - if (time_after(jiffies, expire)) + if (timeout && time_after(jiffies, expire)) break; } } -- GitLab From 79fbf4a550ed6a22e1ae1516113e6c7fa5d56a53 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 4 Mar 2015 10:39:06 +0100 Subject: [PATCH 03279/11651] TTY: fix tty_wait_until_sent on 64-bit machines Fix overflow bug in tty_wait_until_sent on 64-bit machines, where an infinite timeout (0) would be passed to the underlying tty-driver's wait_until_sent-operation as a negative timeout (-1), causing it to return immediately. This manifests itself for example as tcdrain() returning immediately, drivers not honouring the drain flags when setting terminal attributes, or even dropped data on close as a requested infinite closing-wait timeout would be ignored. The first symptom was reported by Asier LLANO who noted that tcdrain() returned prematurely when using the ftdi_sio usb-serial driver. Fix this by passing 0 rather than MAX_SCHEDULE_TIMEOUT (LONG_MAX) to the underlying tty driver. Note that the serial-core wait_until_sent-implementation is not affected by this bug due to a lucky chance (comparison to an unsigned maximum timeout), and neither is the cyclades one that had an explicit check for negative timeouts, but all other tty drivers appear to be affected. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable # v2.6.12 Reported-by: ZIV-Asier Llano Palacios Signed-off-by: Johan Hovold Reviewed-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_ioctl.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c index a5cf253b2544..89ae23ac9ae6 100644 --- a/drivers/tty/tty_ioctl.c +++ b/drivers/tty/tty_ioctl.c @@ -217,11 +217,17 @@ void tty_wait_until_sent(struct tty_struct *tty, long timeout) #endif if (!timeout) timeout = MAX_SCHEDULE_TIMEOUT; + if (wait_event_interruptible_timeout(tty->write_wait, - !tty_chars_in_buffer(tty), timeout) >= 0) { - if (tty->ops->wait_until_sent) - tty->ops->wait_until_sent(tty, timeout); + !tty_chars_in_buffer(tty), timeout) < 0) { + return; } + + if (timeout == MAX_SCHEDULE_TIMEOUT) + timeout = 0; + + if (tty->ops->wait_until_sent) + tty->ops->wait_until_sent(tty, timeout); } EXPORT_SYMBOL(tty_wait_until_sent); -- GitLab From c37bc682e30b8027054356214eb8a3aafbda8e37 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 4 Mar 2015 10:39:07 +0100 Subject: [PATCH 03280/11651] TTY: fix tty_wait_until_sent maximum timeout Currently tty_wait_until_sent may take up to twice as long as the requested timeout while waiting for driver and hardware buffers to drain. Fix this by taking the remaining number of jiffies after waiting for driver buffers to drain into account so that the timeout actually becomes a maximum timeout as it is documented to be. Note that this specifically implies tighter timings when closing a port as a consequence of actually honouring the port closing-wait setting for drivers relying on tty_wait_until_sent_from_close (e.g. via tty_port_close_start). Signed-off-by: Johan Hovold Reviewed-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_ioctl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c index 89ae23ac9ae6..632fc8152061 100644 --- a/drivers/tty/tty_ioctl.c +++ b/drivers/tty/tty_ioctl.c @@ -218,10 +218,10 @@ void tty_wait_until_sent(struct tty_struct *tty, long timeout) if (!timeout) timeout = MAX_SCHEDULE_TIMEOUT; - if (wait_event_interruptible_timeout(tty->write_wait, - !tty_chars_in_buffer(tty), timeout) < 0) { + timeout = wait_event_interruptible_timeout(tty->write_wait, + !tty_chars_in_buffer(tty), timeout); + if (timeout <= 0) return; - } if (timeout == MAX_SCHEDULE_TIMEOUT) timeout = 0; -- GitLab From 734745caeb9f155ab58918834a8c70e83fa6afd3 Mon Sep 17 00:00:00 2001 From: Dave Martin Date: Wed, 4 Mar 2015 12:27:33 +0000 Subject: [PATCH 03281/11651] serial/amba-pl011: Activate TX IRQ passively The current PL011 driver transmits a dummy character when the UART is opened, to assert the TX IRQ for the first time (see pl011_startup()). The UART is put in loopback mode temporarily, so the receiver presumably shouldn't see anything. However... At least some platforms containing a PL011 send characters down the wire even when loopback mode is enabled. This means that a spurious NUL character may be seen at the receiver when the PL011 is opened through the TTY layer. The current code also temporarily sets the baud rate to maximum and the character width to the minimum, to that the dummy TX completes as quickly as possible. If this is seen by the receiver it will result in a framing error and can knock the receiver out of sync -- turning subsequent output into garbage until synchronisation is reestablished. (Particularly problematic during boot with systemd.) To avoid spurious transmissions, this patch removes assumptions about whether the TX IRQ will fire until at least one TX IRQ has been seen. Instead, the UART will unmask the TX IRQ and then slow-start via polling and timer-based soft IRQs initially. If the TTY layer writes enough data to fill the FIFO to the interrupt threshold in one go, the TX IRQ should assert, at which point the driver changes to fully interrupt-driven TX. In this way, the TX IRQ is activated as a side-effect instead of being done deliberately. This should also mean that the driver works on the SBSA Generic UART[1] (a cut-down PL011) without invasive changes. The Generic UART lacks some features needed for the dummy TX approach to work (FIFO disabling and loopback). [1] Server Base System Architecture (ARM-DEN-0029-v2.3) http://infocenter.arm.com/ (click-thru required :/) Signed-off-by: Dave Martin Tested-by: Andre Przywara Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/amba-pl011.c | 165 ++++++++++++++++++++++---------- 1 file changed, 115 insertions(+), 50 deletions(-) diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 8d94c194f090..69910f7e3991 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -58,6 +58,7 @@ #include #include #include +#include #define UART_NR 14 @@ -156,7 +157,9 @@ struct uart_amba_port { unsigned int lcrh_tx; /* vendor-specific */ unsigned int lcrh_rx; /* vendor-specific */ unsigned int old_cr; /* state during shutdown */ + struct delayed_work tx_softirq_work; bool autorts; + unsigned int tx_irq_seen; /* 0=none, 1=1, 2=2 or more */ char type[12]; #ifdef CONFIG_DMA_ENGINE /* DMA stuff */ @@ -440,8 +443,9 @@ static void pl011_dma_remove(struct uart_amba_port *uap) dma_release_channel(uap->dmarx.chan); } -/* Forward declare this for the refill routine */ +/* Forward declare these for the refill routine */ static int pl011_dma_tx_refill(struct uart_amba_port *uap); +static void pl011_start_tx_pio(struct uart_amba_port *uap); /* * The current DMA TX buffer has been sent. @@ -479,14 +483,13 @@ static void pl011_dma_tx_callback(void *data) return; } - if (pl011_dma_tx_refill(uap) <= 0) { + if (pl011_dma_tx_refill(uap) <= 0) /* * We didn't queue a DMA buffer for some reason, but we * have data pending to be sent. Re-enable the TX IRQ. */ - uap->im |= UART011_TXIM; - writew(uap->im, uap->port.membase + UART011_IMSC); - } + pl011_start_tx_pio(uap); + spin_unlock_irqrestore(&uap->port.lock, flags); } @@ -664,12 +667,10 @@ static inline bool pl011_dma_tx_start(struct uart_amba_port *uap) if (!uap->dmatx.queued) { if (pl011_dma_tx_refill(uap) > 0) { uap->im &= ~UART011_TXIM; - ret = true; - } else { - uap->im |= UART011_TXIM; + writew(uap->im, uap->port.membase + + UART011_IMSC); + } else ret = false; - } - writew(uap->im, uap->port.membase + UART011_IMSC); } else if (!(uap->dmacr & UART011_TXDMAE)) { uap->dmacr |= UART011_TXDMAE; writew(uap->dmacr, @@ -1208,15 +1209,24 @@ static void pl011_stop_tx(struct uart_port *port) pl011_dma_tx_stop(uap); } +static bool pl011_tx_chars(struct uart_amba_port *uap); + +/* Start TX with programmed I/O only (no DMA) */ +static void pl011_start_tx_pio(struct uart_amba_port *uap) +{ + uap->im |= UART011_TXIM; + writew(uap->im, uap->port.membase + UART011_IMSC); + if (!uap->tx_irq_seen) + pl011_tx_chars(uap); +} + static void pl011_start_tx(struct uart_port *port) { struct uart_amba_port *uap = container_of(port, struct uart_amba_port, port); - if (!pl011_dma_tx_start(uap)) { - uap->im |= UART011_TXIM; - writew(uap->im, uap->port.membase + UART011_IMSC); - } + if (!pl011_dma_tx_start(uap)) + pl011_start_tx_pio(uap); } static void pl011_stop_rx(struct uart_port *port) @@ -1274,40 +1284,87 @@ __acquires(&uap->port.lock) spin_lock(&uap->port.lock); } -static void pl011_tx_chars(struct uart_amba_port *uap) +/* + * Transmit a character + * There must be at least one free entry in the TX FIFO to accept the char. + * + * Returns true if the FIFO might have space in it afterwards; + * returns false if the FIFO definitely became full. + */ +static bool pl011_tx_char(struct uart_amba_port *uap, unsigned char c) +{ + writew(c, uap->port.membase + UART01x_DR); + uap->port.icount.tx++; + + if (likely(uap->tx_irq_seen > 1)) + return true; + + return !(readw(uap->port.membase + UART01x_FR) & UART01x_FR_TXFF); +} + +static bool pl011_tx_chars(struct uart_amba_port *uap) { struct circ_buf *xmit = &uap->port.state->xmit; int count; + if (unlikely(uap->tx_irq_seen < 2)) + /* + * Initial FIFO fill level unknown: we must check TXFF + * after each write, so just try to fill up the FIFO. + */ + count = uap->fifosize; + else /* tx_irq_seen >= 2 */ + /* + * FIFO initially at least half-empty, so we can simply + * write half the FIFO without polling TXFF. + + * Note: the *first* TX IRQ can still race with + * pl011_start_tx_pio(), which can result in the FIFO + * being fuller than expected in that case. + */ + count = uap->fifosize >> 1; + + /* + * If the FIFO is full we're guaranteed a TX IRQ at some later point, + * and can't transmit immediately in any case: + */ + if (unlikely(uap->tx_irq_seen < 2 && + readw(uap->port.membase + UART01x_FR) & UART01x_FR_TXFF)) + return false; + if (uap->port.x_char) { - writew(uap->port.x_char, uap->port.membase + UART01x_DR); - uap->port.icount.tx++; + pl011_tx_char(uap, uap->port.x_char); uap->port.x_char = 0; - return; + --count; } if (uart_circ_empty(xmit) || uart_tx_stopped(&uap->port)) { pl011_stop_tx(&uap->port); - return; + goto done; } /* If we are using DMA mode, try to send some characters. */ if (pl011_dma_tx_irq(uap)) - return; + goto done; - count = uap->fifosize >> 1; - do { - writew(xmit->buf[xmit->tail], uap->port.membase + UART01x_DR); + while (count-- > 0 && pl011_tx_char(uap, xmit->buf[xmit->tail])) { xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - uap->port.icount.tx++; if (uart_circ_empty(xmit)) break; - } while (--count > 0); + } if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(&uap->port); - if (uart_circ_empty(xmit)) + if (uart_circ_empty(xmit)) { pl011_stop_tx(&uap->port); + goto done; + } + + if (unlikely(!uap->tx_irq_seen)) + schedule_delayed_work(&uap->tx_softirq_work, uap->port.timeout); + +done: + return false; } static void pl011_modem_status(struct uart_amba_port *uap) @@ -1334,6 +1391,28 @@ static void pl011_modem_status(struct uart_amba_port *uap) wake_up_interruptible(&uap->port.state->port.delta_msr_wait); } +static void pl011_tx_softirq(struct work_struct *work) +{ + struct delayed_work *dwork = to_delayed_work(work); + struct uart_amba_port *uap = + container_of(dwork, struct uart_amba_port, tx_softirq_work); + + spin_lock(&uap->port.lock); + while (pl011_tx_chars(uap)) ; + spin_unlock(&uap->port.lock); +} + +static void pl011_tx_irq_seen(struct uart_amba_port *uap) +{ + if (likely(uap->tx_irq_seen > 1)) + return; + + uap->tx_irq_seen++; + if (uap->tx_irq_seen < 2) + /* first TX IRQ */ + cancel_delayed_work(&uap->tx_softirq_work); +} + static irqreturn_t pl011_int(int irq, void *dev_id) { struct uart_amba_port *uap = dev_id; @@ -1372,8 +1451,10 @@ static irqreturn_t pl011_int(int irq, void *dev_id) if (status & (UART011_DSRMIS|UART011_DCDMIS| UART011_CTSMIS|UART011_RIMIS)) pl011_modem_status(uap); - if (status & UART011_TXIS) + if (status & UART011_TXIS) { + pl011_tx_irq_seen(uap); pl011_tx_chars(uap); + } if (pass_counter-- == 0) break; @@ -1577,7 +1658,7 @@ static int pl011_startup(struct uart_port *port) { struct uart_amba_port *uap = container_of(port, struct uart_amba_port, port); - unsigned int cr, lcr_h, fbrd, ibrd; + unsigned int cr; int retval; retval = pl011_hwinit(port); @@ -1595,29 +1676,10 @@ static int pl011_startup(struct uart_port *port) writew(uap->vendor->ifls, uap->port.membase + UART011_IFLS); - /* - * Provoke TX FIFO interrupt into asserting. Taking care to preserve - * baud rate and data format specified by FBRD, IBRD and LCRH as the - * UART may already be in use as a console. - */ - spin_lock_irq(&uap->port.lock); - - fbrd = readw(uap->port.membase + UART011_FBRD); - ibrd = readw(uap->port.membase + UART011_IBRD); - lcr_h = readw(uap->port.membase + uap->lcrh_rx); - - cr = UART01x_CR_UARTEN | UART011_CR_TXE | UART011_CR_LBE; - writew(cr, uap->port.membase + UART011_CR); - writew(0, uap->port.membase + UART011_FBRD); - writew(1, uap->port.membase + UART011_IBRD); - pl011_write_lcr_h(uap, 0); - writew(0, uap->port.membase + UART01x_DR); - while (readw(uap->port.membase + UART01x_FR) & UART01x_FR_BUSY) - barrier(); + /* Assume that TX IRQ doesn't work until we see one: */ + uap->tx_irq_seen = 0; - writew(fbrd, uap->port.membase + UART011_FBRD); - writew(ibrd, uap->port.membase + UART011_IBRD); - pl011_write_lcr_h(uap, lcr_h); + spin_lock_irq(&uap->port.lock); /* restore RTS and DTR */ cr = uap->old_cr & (UART011_CR_RTS | UART011_CR_DTR); @@ -1672,6 +1734,8 @@ static void pl011_shutdown(struct uart_port *port) container_of(port, struct uart_amba_port, port); unsigned int cr; + cancel_delayed_work_sync(&uap->tx_softirq_work); + /* * disable all interrupts */ @@ -2218,6 +2282,7 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) uap->port.ops = &amba_pl011_pops; uap->port.flags = UPF_BOOT_AUTOCONF; uap->port.line = i; + INIT_DELAYED_WORK(&uap->tx_softirq_work, pl011_tx_softirq); pl011_dma_probe(&dev->dev, uap); /* Ensure interrupts from this UART are masked and cleared */ -- GitLab From f2ee6dfa0e8597eea8b98d240b0033994e20d215 Mon Sep 17 00:00:00 2001 From: Dave Martin Date: Wed, 4 Mar 2015 12:27:34 +0000 Subject: [PATCH 03282/11651] serial/amba-pl011: Leave the TX IRQ alone when the UART is not open Getting the TX IRQ re-asserted from scratch can be inefficient in some setups. This patch avoids clearing the TX IRQ across pl011_shutdown()... pl011_startup(), so that if the port is closed and reopened, the IRQ will still work afterwards without having to bootstrap it again. The TX IRQ continues to be masked in IMSC when the UART is not in use. Signed-off-by: Dave Martin Tested-by: Andre Przywara Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/amba-pl011.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 69910f7e3991..92783fc8a851 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -1676,9 +1676,6 @@ static int pl011_startup(struct uart_port *port) writew(uap->vendor->ifls, uap->port.membase + UART011_IFLS); - /* Assume that TX IRQ doesn't work until we see one: */ - uap->tx_irq_seen = 0; - spin_lock_irq(&uap->port.lock); /* restore RTS and DTR */ @@ -1742,7 +1739,7 @@ static void pl011_shutdown(struct uart_port *port) spin_lock_irq(&uap->port.lock); uap->im = 0; writew(uap->im, uap->port.membase + UART011_IMSC); - writew(0xffff, uap->port.membase + UART011_ICR); + writew(0xffff & ~UART011_TXIS, uap->port.membase + UART011_ICR); spin_unlock_irq(&uap->port.lock); pl011_dma_shutdown(uap); -- GitLab From c93682477bd861744589215515a63b81fdbd8948 Mon Sep 17 00:00:00 2001 From: Shani Michaeli Date: Thu, 5 Mar 2015 20:16:11 +0200 Subject: [PATCH 03283/11651] net/dcb: Add IEEE QCN attribute As specified in 802.1Qau spec. Add this optional attribute to the DCB netlink layer. To allow for application to use the new attribute, NIC drivers should implement and register the callbacks ieee_getqcn, ieee_setqcn and ieee_getqcnstats. The QCN attribute holds a set of parameters for management, and a set of statistics to provide informative data on Congestion-Control defined by this spec. Signed-off-by: Shani Michaeli Signed-off-by: Shachar Raindel Signed-off-by: Or Gerlitz Acked-by: John Fastabend Signed-off-by: David S. Miller --- include/net/dcbnl.h | 3 ++ include/uapi/linux/dcbnl.h | 66 ++++++++++++++++++++++++++++++++++++++ net/dcb/dcbnl.c | 44 +++++++++++++++++++++++-- 3 files changed, 110 insertions(+), 3 deletions(-) diff --git a/include/net/dcbnl.h b/include/net/dcbnl.h index 597b88a94332..207d9ba1f92c 100644 --- a/include/net/dcbnl.h +++ b/include/net/dcbnl.h @@ -49,6 +49,9 @@ struct dcbnl_rtnl_ops { int (*ieee_setets) (struct net_device *, struct ieee_ets *); int (*ieee_getmaxrate) (struct net_device *, struct ieee_maxrate *); int (*ieee_setmaxrate) (struct net_device *, struct ieee_maxrate *); + int (*ieee_getqcn) (struct net_device *, struct ieee_qcn *); + int (*ieee_setqcn) (struct net_device *, struct ieee_qcn *); + int (*ieee_getqcnstats) (struct net_device *, struct ieee_qcn_stats *); int (*ieee_getpfc) (struct net_device *, struct ieee_pfc *); int (*ieee_setpfc) (struct net_device *, struct ieee_pfc *); int (*ieee_getapp) (struct net_device *, struct dcb_app *); diff --git a/include/uapi/linux/dcbnl.h b/include/uapi/linux/dcbnl.h index e711f20dc522..6497d7933d5b 100644 --- a/include/uapi/linux/dcbnl.h +++ b/include/uapi/linux/dcbnl.h @@ -78,6 +78,70 @@ struct ieee_maxrate { __u64 tc_maxrate[IEEE_8021QAZ_MAX_TCS]; }; +enum dcbnl_cndd_states { + DCB_CNDD_RESET = 0, + DCB_CNDD_EDGE, + DCB_CNDD_INTERIOR, + DCB_CNDD_INTERIOR_READY, +}; + +/* This structure contains the IEEE 802.1Qau QCN managed object. + * + *@rpg_enable: enable QCN RP + *@rppp_max_rps: maximum number of RPs allowed for this CNPV on this port + *@rpg_time_reset: time between rate increases if no CNMs received. + * given in u-seconds + *@rpg_byte_reset: transmitted data between rate increases if no CNMs received. + * given in Bytes + *@rpg_threshold: The number of times rpByteStage or rpTimeStage can count + * before RP rate control state machine advances states + *@rpg_max_rate: the maxinun rate, in Mbits per second, + * at which an RP can transmit + *@rpg_ai_rate: The rate, in Mbits per second, + * used to increase rpTargetRate in the RPR_ACTIVE_INCREASE + *@rpg_hai_rate: The rate, in Mbits per second, + * used to increase rpTargetRate in the RPR_HYPER_INCREASE state + *@rpg_gd: Upon CNM receive, flow rate is limited to (Fb/Gd)*CurrentRate. + * rpgGd is given as log2(Gd), where Gd may only be powers of 2 + *@rpg_min_dec_fac: The minimum factor by which the current transmit rate + * can be changed by reception of a CNM. + * value is given as percentage (1-100) + *@rpg_min_rate: The minimum value, in bits per second, for rate to limit + *@cndd_state_machine: The state of the congestion notification domain + * defense state machine, as defined by IEEE 802.3Qau + * section 32.1.1. In the interior ready state, + * the QCN capable hardware may add CN-TAG TLV to the + * outgoing traffic, to specifically identify outgoing + * flows. + */ + +struct ieee_qcn { + __u8 rpg_enable[IEEE_8021QAZ_MAX_TCS]; + __u32 rppp_max_rps[IEEE_8021QAZ_MAX_TCS]; + __u32 rpg_time_reset[IEEE_8021QAZ_MAX_TCS]; + __u32 rpg_byte_reset[IEEE_8021QAZ_MAX_TCS]; + __u32 rpg_threshold[IEEE_8021QAZ_MAX_TCS]; + __u32 rpg_max_rate[IEEE_8021QAZ_MAX_TCS]; + __u32 rpg_ai_rate[IEEE_8021QAZ_MAX_TCS]; + __u32 rpg_hai_rate[IEEE_8021QAZ_MAX_TCS]; + __u32 rpg_gd[IEEE_8021QAZ_MAX_TCS]; + __u32 rpg_min_dec_fac[IEEE_8021QAZ_MAX_TCS]; + __u32 rpg_min_rate[IEEE_8021QAZ_MAX_TCS]; + __u32 cndd_state_machine[IEEE_8021QAZ_MAX_TCS]; +}; + +/* This structure contains the IEEE 802.1Qau QCN statistics. + * + *@rppp_rp_centiseconds: the number of RP-centiseconds accumulated + * by RPs at this priority level on this Port + *@rppp_created_rps: number of active RPs(flows) that react to CNMs + */ + +struct ieee_qcn_stats { + __u64 rppp_rp_centiseconds[IEEE_8021QAZ_MAX_TCS]; + __u32 rppp_created_rps[IEEE_8021QAZ_MAX_TCS]; +}; + /* This structure contains the IEEE 802.1Qaz PFC managed object * * @pfc_cap: Indicates the number of traffic classes on the local device @@ -334,6 +398,8 @@ enum ieee_attrs { DCB_ATTR_IEEE_PEER_PFC, DCB_ATTR_IEEE_PEER_APP, DCB_ATTR_IEEE_MAXRATE, + DCB_ATTR_IEEE_QCN, + DCB_ATTR_IEEE_QCN_STATS, __DCB_ATTR_IEEE_MAX }; #define DCB_ATTR_IEEE_MAX (__DCB_ATTR_IEEE_MAX - 1) diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c index 93ea80196f0e..5b21f6f88e97 100644 --- a/net/dcb/dcbnl.c +++ b/net/dcb/dcbnl.c @@ -177,6 +177,8 @@ static const struct nla_policy dcbnl_ieee_policy[DCB_ATTR_IEEE_MAX + 1] = { [DCB_ATTR_IEEE_PFC] = {.len = sizeof(struct ieee_pfc)}, [DCB_ATTR_IEEE_APP_TABLE] = {.type = NLA_NESTED}, [DCB_ATTR_IEEE_MAXRATE] = {.len = sizeof(struct ieee_maxrate)}, + [DCB_ATTR_IEEE_QCN] = {.len = sizeof(struct ieee_qcn)}, + [DCB_ATTR_IEEE_QCN_STATS] = {.len = sizeof(struct ieee_qcn_stats)}, }; static const struct nla_policy dcbnl_ieee_app[DCB_ATTR_IEEE_APP_MAX + 1] = { @@ -1030,7 +1032,7 @@ nla_put_failure: return err; } -/* Handle IEEE 802.1Qaz GET commands. */ +/* Handle IEEE 802.1Qaz/802.1Qau/802.1Qbb GET commands. */ static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev) { struct nlattr *ieee, *app; @@ -1067,6 +1069,32 @@ static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev) } } + if (ops->ieee_getqcn) { + struct ieee_qcn qcn; + + memset(&qcn, 0, sizeof(qcn)); + err = ops->ieee_getqcn(netdev, &qcn); + if (!err) { + err = nla_put(skb, DCB_ATTR_IEEE_QCN, + sizeof(qcn), &qcn); + if (err) + return -EMSGSIZE; + } + } + + if (ops->ieee_getqcnstats) { + struct ieee_qcn_stats qcn_stats; + + memset(&qcn_stats, 0, sizeof(qcn_stats)); + err = ops->ieee_getqcnstats(netdev, &qcn_stats); + if (!err) { + err = nla_put(skb, DCB_ATTR_IEEE_QCN_STATS, + sizeof(qcn_stats), &qcn_stats); + if (err) + return -EMSGSIZE; + } + } + if (ops->ieee_getpfc) { struct ieee_pfc pfc; memset(&pfc, 0, sizeof(pfc)); @@ -1379,8 +1407,9 @@ int dcbnl_cee_notify(struct net_device *dev, int event, int cmd, } EXPORT_SYMBOL(dcbnl_cee_notify); -/* Handle IEEE 802.1Qaz SET commands. If any requested operation can not - * be completed the entire msg is aborted and error value is returned. +/* Handle IEEE 802.1Qaz/802.1Qau/802.1Qbb SET commands. + * If any requested operation can not be completed + * the entire msg is aborted and error value is returned. * No attempt is made to reconcile the case where only part of the * cmd can be completed. */ @@ -1417,6 +1446,15 @@ static int dcbnl_ieee_set(struct net_device *netdev, struct nlmsghdr *nlh, goto err; } + if (ieee[DCB_ATTR_IEEE_QCN] && ops->ieee_setqcn) { + struct ieee_qcn *qcn = + nla_data(ieee[DCB_ATTR_IEEE_QCN]); + + err = ops->ieee_setqcn(netdev, qcn); + if (err) + goto err; + } + if (ieee[DCB_ATTR_IEEE_PFC] && ops->ieee_setpfc) { struct ieee_pfc *pfc = nla_data(ieee[DCB_ATTR_IEEE_PFC]); err = ops->ieee_setpfc(netdev, pfc); -- GitLab From d237baa1cbb3a2335357484c1d63a810a01947e2 Mon Sep 17 00:00:00 2001 From: Shani Michaeli Date: Thu, 5 Mar 2015 20:16:12 +0200 Subject: [PATCH 03284/11651] net/mlx4_core: Add basic elements for QCN Add device capability, firmware command opcode and etc prior elements needed for QCN suppprt. Disable SRIOV VF view/access for QCN is disabled. While here, remove a redundant offset definition into the QUERY_DEV_CAP mailbox. Signed-off-by: Shani Michaeli Signed-off-by: Or Gerlitz Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/cmd.c | 9 +++++++++ drivers/net/ethernet/mellanox/mlx4/fw.c | 13 +++++++++++-- include/linux/mlx4/cmd.h | 13 +++++++++++++ include/linux/mlx4/device.h | 3 ++- 4 files changed, 35 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c index a681d7c0bb9f..20b3c7b21e63 100644 --- a/drivers/net/ethernet/mellanox/mlx4/cmd.c +++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c @@ -1499,6 +1499,15 @@ static struct mlx4_cmd_info cmd_info[] = { .verify = NULL, .wrapper = mlx4_ACCESS_REG_wrapper, }, + { + .opcode = MLX4_CMD_CONGESTION_CTRL_OPCODE, + .has_inbox = false, + .has_outbox = false, + .out_is_imm = false, + .encode_slave_id = false, + .verify = NULL, + .wrapper = mlx4_CMD_EPERM_wrapper, + }, /* Native multicast commands are not available for guests */ { .opcode = MLX4_CMD_QP_ATTACH, diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c index 5a21e5dc94cb..242bcee5d774 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.c +++ b/drivers/net/ethernet/mellanox/mlx4/fw.c @@ -143,7 +143,8 @@ static void dump_dev_cap_flags2(struct mlx4_dev *dev, u64 flags) [18] = "More than 80 VFs support", [19] = "Performance optimized for limited rule configuration flow steering support", [20] = "Recoverable error events support", - [21] = "Port Remap support" + [21] = "Port Remap support", + [22] = "QCN support" }; int i; @@ -675,7 +676,7 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) #define QUERY_DEV_CAP_FLOW_STEERING_RANGE_EN_OFFSET 0x76 #define QUERY_DEV_CAP_FLOW_STEERING_MAX_QP_OFFSET 0x77 #define QUERY_DEV_CAP_CQ_EQ_CACHE_LINE_STRIDE 0x7a -#define QUERY_DEV_CAP_ETH_PROT_CTRL_OFFSET 0x7a +#define QUERY_DEV_CAP_ECN_QCN_VER_OFFSET 0x7b #define QUERY_DEV_CAP_RDMARC_ENTRY_SZ_OFFSET 0x80 #define QUERY_DEV_CAP_QPC_ENTRY_SZ_OFFSET 0x82 #define QUERY_DEV_CAP_AUX_ENTRY_SZ_OFFSET 0x84 @@ -777,6 +778,9 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_DMFS_IPOIB; MLX4_GET(field, outbox, QUERY_DEV_CAP_FLOW_STEERING_MAX_QP_OFFSET); dev_cap->fs_max_num_qp_per_entry = field; + MLX4_GET(field, outbox, QUERY_DEV_CAP_ECN_QCN_VER_OFFSET); + if (field & 0x1) + dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_QCN; MLX4_GET(stat_rate, outbox, QUERY_DEV_CAP_RATE_SUPPORT_OFFSET); dev_cap->stat_rate_support = stat_rate; MLX4_GET(field, outbox, QUERY_DEV_CAP_CQ_TS_SUPPORT_OFFSET); @@ -1149,6 +1153,11 @@ int mlx4_QUERY_DEV_CAP_wrapper(struct mlx4_dev *dev, int slave, DEV_CAP_EXT_2_FLAG_FSM); MLX4_PUT(outbox->buf, field32, QUERY_DEV_CAP_EXT_2_FLAGS_OFFSET); + /* turn off QCN for guests */ + MLX4_GET(field, outbox->buf, QUERY_DEV_CAP_ECN_QCN_VER_OFFSET); + field &= 0xfe; + MLX4_PUT(outbox->buf, field, QUERY_DEV_CAP_ECN_QCN_VER_OFFSET); + return 0; } diff --git a/include/linux/mlx4/cmd.h b/include/linux/mlx4/cmd.h index 7b6d4e9ff603..7299e9548906 100644 --- a/include/linux/mlx4/cmd.h +++ b/include/linux/mlx4/cmd.h @@ -163,6 +163,9 @@ enum { MLX4_QP_FLOW_STEERING_ATTACH = 0x65, MLX4_QP_FLOW_STEERING_DETACH = 0x66, MLX4_FLOW_STEERING_IB_UC_QP_RANGE = 0x64, + + /* Update and read QCN parameters */ + MLX4_CMD_CONGESTION_CTRL_OPCODE = 0x68, }; enum { @@ -233,6 +236,16 @@ struct mlx4_config_dev_params { u8 rx_csum_flags_port_2; }; +enum mlx4_en_congestion_control_algorithm { + MLX4_CTRL_ALGO_802_1_QAU_REACTION_POINT = 0, +}; + +enum mlx4_en_congestion_control_opmod { + MLX4_CONGESTION_CONTROL_GET_PARAMS, + MLX4_CONGESTION_CONTROL_GET_STATISTICS, + MLX4_CONGESTION_CONTROL_SET_PARAMS = 4, +}; + struct mlx4_dev; struct mlx4_cmd_mailbox { diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h index e4ebff7e9d02..1cc54822b931 100644 --- a/include/linux/mlx4/device.h +++ b/include/linux/mlx4/device.h @@ -203,7 +203,8 @@ enum { MLX4_DEV_CAP_FLAG2_80_VFS = 1LL << 18, MLX4_DEV_CAP_FLAG2_FS_A0 = 1LL << 19, MLX4_DEV_CAP_FLAG2_RECOVERABLE_ERROR_EVENT = 1LL << 20, - MLX4_DEV_CAP_FLAG2_PORT_REMAP = 1LL << 21 + MLX4_DEV_CAP_FLAG2_PORT_REMAP = 1LL << 21, + MLX4_DEV_CAP_FLAG2_QCN = 1LL << 22, }; enum { -- GitLab From 708b869bf56e58b0c41460ba7bf363bf50f330c2 Mon Sep 17 00:00:00 2001 From: Shani Michaeli Date: Thu, 5 Mar 2015 20:16:13 +0200 Subject: [PATCH 03285/11651] net/mlx4_en: Add QCN parameters and statistics handling Implement the IEEE DCB handlers for set/get QCN parameters and statistics reading per TC. Signed-off-by: Shani Michaeli Signed-off-by: Or Gerlitz Signed-off-by: David S. Miller --- .../net/ethernet/mellanox/mlx4/en_dcb_nl.c | 218 ++++++++++++++++++ drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 1 + 2 files changed, 219 insertions(+) diff --git a/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c b/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c index c95ca252187c..cde14fa2f742 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c @@ -36,6 +36,49 @@ #include "mlx4_en.h" +/* Definitions for QCN + */ + +struct mlx4_congestion_control_mb_prio_802_1_qau_params { + __be32 modify_enable_high; + __be32 modify_enable_low; + __be32 reserved1; + __be32 extended_enable; + __be32 rppp_max_rps; + __be32 rpg_time_reset; + __be32 rpg_byte_reset; + __be32 rpg_threshold; + __be32 rpg_max_rate; + __be32 rpg_ai_rate; + __be32 rpg_hai_rate; + __be32 rpg_gd; + __be32 rpg_min_dec_fac; + __be32 rpg_min_rate; + __be32 max_time_rise; + __be32 max_byte_rise; + __be32 max_qdelta; + __be32 min_qoffset; + __be32 gd_coefficient; + __be32 reserved2[5]; + __be32 cp_sample_base; + __be32 reserved3[39]; +}; + +struct mlx4_congestion_control_mb_prio_802_1_qau_statistics { + __be64 rppp_rp_centiseconds; + __be32 reserved1; + __be32 ignored_cnm; + __be32 rppp_created_rps; + __be32 estimated_total_rate; + __be32 max_active_rate_limiter_index; + __be32 dropped_cnms_busy_fw; + __be32 reserved2; + __be32 cnms_handled_successfully; + __be32 min_total_limiters_rate; + __be32 max_total_limiters_rate; + __be32 reserved3[4]; +}; + static int mlx4_en_dcbnl_ieee_getets(struct net_device *dev, struct ieee_ets *ets) { @@ -242,6 +285,178 @@ static int mlx4_en_dcbnl_ieee_setmaxrate(struct net_device *dev, return 0; } +#define RPG_ENABLE_BIT 31 +#define CN_TAG_BIT 30 + +static int mlx4_en_dcbnl_ieee_getqcn(struct net_device *dev, + struct ieee_qcn *qcn) +{ + struct mlx4_en_priv *priv = netdev_priv(dev); + struct mlx4_congestion_control_mb_prio_802_1_qau_params *hw_qcn; + struct mlx4_cmd_mailbox *mailbox_out = NULL; + u64 mailbox_in_dma = 0; + u32 inmod = 0; + int i, err; + + if (!(priv->mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_QCN)) + return -EOPNOTSUPP; + + mailbox_out = mlx4_alloc_cmd_mailbox(priv->mdev->dev); + if (IS_ERR(mailbox_out)) + return -ENOMEM; + hw_qcn = + (struct mlx4_congestion_control_mb_prio_802_1_qau_params *) + mailbox_out->buf; + + for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) { + inmod = priv->port | ((1 << i) << 8) | + (MLX4_CTRL_ALGO_802_1_QAU_REACTION_POINT << 16); + err = mlx4_cmd_box(priv->mdev->dev, mailbox_in_dma, + mailbox_out->dma, + inmod, MLX4_CONGESTION_CONTROL_GET_PARAMS, + MLX4_CMD_CONGESTION_CTRL_OPCODE, + MLX4_CMD_TIME_CLASS_C, + MLX4_CMD_NATIVE); + if (err) { + mlx4_free_cmd_mailbox(priv->mdev->dev, mailbox_out); + return err; + } + + qcn->rpg_enable[i] = + be32_to_cpu(hw_qcn->extended_enable) >> RPG_ENABLE_BIT; + qcn->rppp_max_rps[i] = + be32_to_cpu(hw_qcn->rppp_max_rps); + qcn->rpg_time_reset[i] = + be32_to_cpu(hw_qcn->rpg_time_reset); + qcn->rpg_byte_reset[i] = + be32_to_cpu(hw_qcn->rpg_byte_reset); + qcn->rpg_threshold[i] = + be32_to_cpu(hw_qcn->rpg_threshold); + qcn->rpg_max_rate[i] = + be32_to_cpu(hw_qcn->rpg_max_rate); + qcn->rpg_ai_rate[i] = + be32_to_cpu(hw_qcn->rpg_ai_rate); + qcn->rpg_hai_rate[i] = + be32_to_cpu(hw_qcn->rpg_hai_rate); + qcn->rpg_gd[i] = + be32_to_cpu(hw_qcn->rpg_gd); + qcn->rpg_min_dec_fac[i] = + be32_to_cpu(hw_qcn->rpg_min_dec_fac); + qcn->rpg_min_rate[i] = + be32_to_cpu(hw_qcn->rpg_min_rate); + qcn->cndd_state_machine[i] = + priv->cndd_state[i]; + } + mlx4_free_cmd_mailbox(priv->mdev->dev, mailbox_out); + return 0; +} + +static int mlx4_en_dcbnl_ieee_setqcn(struct net_device *dev, + struct ieee_qcn *qcn) +{ + struct mlx4_en_priv *priv = netdev_priv(dev); + struct mlx4_congestion_control_mb_prio_802_1_qau_params *hw_qcn; + struct mlx4_cmd_mailbox *mailbox_in = NULL; + u64 mailbox_in_dma = 0; + u32 inmod = 0; + int i, err; +#define MODIFY_ENABLE_HIGH_MASK 0xc0000000 +#define MODIFY_ENABLE_LOW_MASK 0xffc00000 + + if (!(priv->mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_QCN)) + return -EOPNOTSUPP; + + mailbox_in = mlx4_alloc_cmd_mailbox(priv->mdev->dev); + if (IS_ERR(mailbox_in)) + return -ENOMEM; + + mailbox_in_dma = mailbox_in->dma; + hw_qcn = + (struct mlx4_congestion_control_mb_prio_802_1_qau_params *)mailbox_in->buf; + for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) { + inmod = priv->port | ((1 << i) << 8) | + (MLX4_CTRL_ALGO_802_1_QAU_REACTION_POINT << 16); + + /* Before updating QCN parameter, + * need to set it's modify enable bit to 1 + */ + + hw_qcn->modify_enable_high = cpu_to_be32( + MODIFY_ENABLE_HIGH_MASK); + hw_qcn->modify_enable_low = cpu_to_be32(MODIFY_ENABLE_LOW_MASK); + + hw_qcn->extended_enable = cpu_to_be32(qcn->rpg_enable[i] << RPG_ENABLE_BIT); + hw_qcn->rppp_max_rps = cpu_to_be32(qcn->rppp_max_rps[i]); + hw_qcn->rpg_time_reset = cpu_to_be32(qcn->rpg_time_reset[i]); + hw_qcn->rpg_byte_reset = cpu_to_be32(qcn->rpg_byte_reset[i]); + hw_qcn->rpg_threshold = cpu_to_be32(qcn->rpg_threshold[i]); + hw_qcn->rpg_max_rate = cpu_to_be32(qcn->rpg_max_rate[i]); + hw_qcn->rpg_ai_rate = cpu_to_be32(qcn->rpg_ai_rate[i]); + hw_qcn->rpg_hai_rate = cpu_to_be32(qcn->rpg_hai_rate[i]); + hw_qcn->rpg_gd = cpu_to_be32(qcn->rpg_gd[i]); + hw_qcn->rpg_min_dec_fac = cpu_to_be32(qcn->rpg_min_dec_fac[i]); + hw_qcn->rpg_min_rate = cpu_to_be32(qcn->rpg_min_rate[i]); + priv->cndd_state[i] = qcn->cndd_state_machine[i]; + if (qcn->cndd_state_machine[i] == DCB_CNDD_INTERIOR_READY) + hw_qcn->extended_enable |= cpu_to_be32(1 << CN_TAG_BIT); + + err = mlx4_cmd(priv->mdev->dev, mailbox_in_dma, inmod, + MLX4_CONGESTION_CONTROL_SET_PARAMS, + MLX4_CMD_CONGESTION_CTRL_OPCODE, + MLX4_CMD_TIME_CLASS_C, + MLX4_CMD_NATIVE); + if (err) { + mlx4_free_cmd_mailbox(priv->mdev->dev, mailbox_in); + return err; + } + } + mlx4_free_cmd_mailbox(priv->mdev->dev, mailbox_in); + return 0; +} + +static int mlx4_en_dcbnl_ieee_getqcnstats(struct net_device *dev, + struct ieee_qcn_stats *qcn_stats) +{ + struct mlx4_en_priv *priv = netdev_priv(dev); + struct mlx4_congestion_control_mb_prio_802_1_qau_statistics *hw_qcn_stats; + struct mlx4_cmd_mailbox *mailbox_out = NULL; + u64 mailbox_in_dma = 0; + u32 inmod = 0; + int i, err; + + if (!(priv->mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_QCN)) + return -EOPNOTSUPP; + + mailbox_out = mlx4_alloc_cmd_mailbox(priv->mdev->dev); + if (IS_ERR(mailbox_out)) + return -ENOMEM; + + hw_qcn_stats = + (struct mlx4_congestion_control_mb_prio_802_1_qau_statistics *) + mailbox_out->buf; + + for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) { + inmod = priv->port | ((1 << i) << 8) | + (MLX4_CTRL_ALGO_802_1_QAU_REACTION_POINT << 16); + err = mlx4_cmd_box(priv->mdev->dev, mailbox_in_dma, + mailbox_out->dma, inmod, + MLX4_CONGESTION_CONTROL_GET_STATISTICS, + MLX4_CMD_CONGESTION_CTRL_OPCODE, + MLX4_CMD_TIME_CLASS_C, + MLX4_CMD_NATIVE); + if (err) { + mlx4_free_cmd_mailbox(priv->mdev->dev, mailbox_out); + return err; + } + qcn_stats->rppp_rp_centiseconds[i] = + be64_to_cpu(hw_qcn_stats->rppp_rp_centiseconds); + qcn_stats->rppp_created_rps[i] = + be32_to_cpu(hw_qcn_stats->rppp_created_rps); + } + mlx4_free_cmd_mailbox(priv->mdev->dev, mailbox_out); + return 0; +} + const struct dcbnl_rtnl_ops mlx4_en_dcbnl_ops = { .ieee_getets = mlx4_en_dcbnl_ieee_getets, .ieee_setets = mlx4_en_dcbnl_ieee_setets, @@ -252,6 +467,9 @@ const struct dcbnl_rtnl_ops mlx4_en_dcbnl_ops = { .getdcbx = mlx4_en_dcbnl_getdcbx, .setdcbx = mlx4_en_dcbnl_setdcbx, + .ieee_getqcn = mlx4_en_dcbnl_ieee_getqcn, + .ieee_setqcn = mlx4_en_dcbnl_ieee_setqcn, + .ieee_getqcnstats = mlx4_en_dcbnl_ieee_getqcnstats, }; const struct dcbnl_rtnl_ops mlx4_en_dcbnl_pfc_ops = { diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index 2a8268e6be15..94553b501c76 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h @@ -608,6 +608,7 @@ struct mlx4_en_priv { #ifdef CONFIG_MLX4_EN_DCB struct ieee_ets ets; u16 maxrate[IEEE_8021QAZ_MAX_TCS]; + enum dcbnl_cndd_states cndd_state[IEEE_8021QAZ_MAX_TCS]; #endif #ifdef CONFIG_RFS_ACCEL spinlock_t filters_lock; -- GitLab From 1c9be31015747b0a981804438b269cfb0f49aa8a Mon Sep 17 00:00:00 2001 From: Jorge Ramirez-Ortiz Date: Fri, 6 Mar 2015 13:05:40 -0500 Subject: [PATCH 03286/11651] drivers/tty: amba: defer DMA probe until the DMA channel is required. Fix a race condition that happens when device_initcall(pl011_dma_initicall) is executed before all the devices have been probed - this issue was observed on a hisi_6220 SoC (HiKey board from Linaro). The deferred driver probing framework relies on late_initcall to trigger deferred probes so it is just possible that, even with a valid DMA driver ready to be loaded, we fail to synchronize with it. The proposed implementation delays probing the DMA until dma_startup. As this is invoked on port startup and port resume - but DMA probing is only required once - we avoid calling multiple times using a new field in uart_amba_port to track this scenario. This commit allows for subsequent attempts to associate an external DMA if the DMA driver itself is not available (but present in the deferred probe pending list). Signed-off-by: Jorge Ramirez-Ortiz Reviewed-by: Rob Herring Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/amba-pl011.c | 71 ++++++++------------------------- 1 file changed, 17 insertions(+), 54 deletions(-) diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 92783fc8a851..7b428e7652c5 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -167,6 +167,7 @@ struct uart_amba_port { bool using_rx_dma; struct pl011_dmarx_data dmarx; struct pl011_dmatx_data dmatx; + bool dma_probed; #endif }; @@ -264,10 +265,11 @@ static void pl011_sgbuf_free(struct dma_chan *chan, struct pl011_sgbuf *sg, } } -static void pl011_dma_probe_initcall(struct device *dev, struct uart_amba_port *uap) +static void pl011_dma_probe(struct uart_amba_port *uap) { /* DMA is the sole user of the platform data right now */ struct amba_pl011_data *plat = dev_get_platdata(uap->port.dev); + struct device *dev = uap->port.dev; struct dma_slave_config tx_conf = { .dst_addr = uap->port.mapbase + UART01x_DR, .dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE, @@ -278,9 +280,15 @@ static void pl011_dma_probe_initcall(struct device *dev, struct uart_amba_port * struct dma_chan *chan; dma_cap_mask_t mask; - chan = dma_request_slave_channel(dev, "tx"); + uap->dma_probed = true; + chan = dma_request_slave_channel_reason(dev, "tx"); + if (IS_ERR(chan)) { + if (PTR_ERR(chan) == -EPROBE_DEFER) { + dev_info(uap->port.dev, "DMA driver not ready\n"); + uap->dma_probed = false; + return; + } - if (!chan) { /* We need platform data */ if (!plat || !plat->dma_filter) { dev_info(uap->port.dev, "no DMA platform data\n"); @@ -388,55 +396,8 @@ static void pl011_dma_probe_initcall(struct device *dev, struct uart_amba_port * } } -#ifndef MODULE -/* - * Stack up the UARTs and let the above initcall be done at device - * initcall time, because the serial driver is called as an arch - * initcall, and at this time the DMA subsystem is not yet registered. - * At this point the driver will switch over to using DMA where desired. - */ -struct dma_uap { - struct list_head node; - struct uart_amba_port *uap; - struct device *dev; -}; - -static LIST_HEAD(pl011_dma_uarts); - -static int __init pl011_dma_initcall(void) -{ - struct list_head *node, *tmp; - - list_for_each_safe(node, tmp, &pl011_dma_uarts) { - struct dma_uap *dmau = list_entry(node, struct dma_uap, node); - pl011_dma_probe_initcall(dmau->dev, dmau->uap); - list_del(node); - kfree(dmau); - } - return 0; -} - -device_initcall(pl011_dma_initcall); - -static void pl011_dma_probe(struct device *dev, struct uart_amba_port *uap) -{ - struct dma_uap *dmau = kzalloc(sizeof(struct dma_uap), GFP_KERNEL); - if (dmau) { - dmau->uap = uap; - dmau->dev = dev; - list_add_tail(&dmau->node, &pl011_dma_uarts); - } -} -#else -static void pl011_dma_probe(struct device *dev, struct uart_amba_port *uap) -{ - pl011_dma_probe_initcall(dev, uap); -} -#endif - static void pl011_dma_remove(struct uart_amba_port *uap) { - /* TODO: remove the initcall if it has not yet executed */ if (uap->dmatx.chan) dma_release_channel(uap->dmatx.chan); if (uap->dmarx.chan) @@ -1022,6 +983,9 @@ static void pl011_dma_startup(struct uart_amba_port *uap) { int ret; + if (!uap->dma_probed) + pl011_dma_probe(uap); + if (!uap->dmatx.chan) return; @@ -1143,7 +1107,7 @@ static inline bool pl011_dma_rx_running(struct uart_amba_port *uap) #else /* Blank functions if the DMA engine is not available */ -static inline void pl011_dma_probe(struct device *dev, struct uart_amba_port *uap) +static inline void pl011_dma_probe(struct uart_amba_port *uap) { } @@ -2280,7 +2244,6 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) uap->port.flags = UPF_BOOT_AUTOCONF; uap->port.line = i; INIT_DELAYED_WORK(&uap->tx_softirq_work, pl011_tx_softirq); - pl011_dma_probe(&dev->dev, uap); /* Ensure interrupts from this UART are masked and cleared */ writew(0, uap->port.membase + UART011_IMSC); @@ -2295,7 +2258,8 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) if (!amba_reg.state) { ret = uart_register_driver(&amba_reg); if (ret < 0) { - pr_err("Failed to register AMBA-PL011 driver\n"); + dev_err(&dev->dev, + "Failed to register AMBA-PL011 driver\n"); return ret; } } @@ -2304,7 +2268,6 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) if (ret) { amba_ports[i] = NULL; uart_unregister_driver(&amba_reg); - pl011_dma_remove(uap); } return ret; -- GitLab From feb27d155dfabcb8baabe10367f25fc2b1bcede1 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 5 Mar 2015 20:48:46 +0300 Subject: [PATCH 03287/11651] ax25: remove unneeded NULL test in ax_xmit() We get a static checker warning here on devel kernels: drivers/net/hamradio/mkiss.c:560 ax_xmit() warn: variable dereferenced before check 'skb' (see line 532) It turns out that the NULL check can be deleted. Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller --- drivers/net/hamradio/mkiss.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c index 17058c490b79..2ffbf13471d0 100644 --- a/drivers/net/hamradio/mkiss.c +++ b/drivers/net/hamradio/mkiss.c @@ -557,11 +557,9 @@ static netdev_tx_t ax_xmit(struct sk_buff *skb, struct net_device *dev) } /* We were not busy, so we are now... :-) */ - if (skb != NULL) { - netif_stop_queue(dev); - ax_encaps(dev, skb->data, skb->len); - kfree_skb(skb); - } + netif_stop_queue(dev); + ax_encaps(dev, skb->data, skb->len); + kfree_skb(skb); return NETDEV_TX_OK; } -- GitLab From 58025e46ea2d39f1840d5b1be5edea3297cfd23f Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 5 Mar 2015 13:47:48 -0800 Subject: [PATCH 03288/11651] net: gro: remove obsolete code from skb_gro_receive() Some drivers use copybreak to copy tiny frames into smaller skb, and this smaller skb might not have skb->head_frag set for various reasons. skb_gro_receive() currently doesn't allow to aggregate the smaller skb into the previous GRO packet if this GRO packet has at least 2 MSS in it. Following workload easily demonstrates the problem. netperf -t TCP_RR -H target -- -r 3000,3000 (tcpdump shows one GRO packet with 2 MSS, plus one additional packet of 104 bytes that should have been appended.) It turns out that we can remove code from skb_gro_receive(), because commit 8a29111c7ca6 ("net: gro: allow to build full sized skb") and its followups removed the assumption that a GRO packet with a frag_list had to have an empty head. Removing this code allows the aggregation of the last (incomplete) frame in some RPC workloads. Note that tcp_gro_receive() already takes care of forcing a flush if necessary, including this case. If we want to avoid using frag_list in the first place (in forwarding workloads for example, as the outgoing NIC is generally not able to cope with skbs having a frag_list), we need to address this separately. Signed-off-by: Eric Dumazet Cc: Herbert Xu Signed-off-by: David S. Miller --- net/core/skbuff.c | 45 +-------------------------------------------- 1 file changed, 1 insertion(+), 44 deletions(-) diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 913b94a77060..47c32413d5b9 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -3206,10 +3206,9 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb) struct skb_shared_info *pinfo, *skbinfo = skb_shinfo(skb); unsigned int offset = skb_gro_offset(skb); unsigned int headlen = skb_headlen(skb); - struct sk_buff *nskb, *lp, *p = *head; unsigned int len = skb_gro_len(skb); + struct sk_buff *lp, *p = *head; unsigned int delta_truesize; - unsigned int headroom; if (unlikely(p->len + len >= 65536)) return -E2BIG; @@ -3276,48 +3275,6 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb) NAPI_GRO_CB(skb)->free = NAPI_GRO_FREE_STOLEN_HEAD; goto done; } - /* switch back to head shinfo */ - pinfo = skb_shinfo(p); - - if (pinfo->frag_list) - goto merge; - if (skb_gro_len(p) != pinfo->gso_size) - return -E2BIG; - - headroom = skb_headroom(p); - nskb = alloc_skb(headroom + skb_gro_offset(p), GFP_ATOMIC); - if (unlikely(!nskb)) - return -ENOMEM; - - __copy_skb_header(nskb, p); - nskb->mac_len = p->mac_len; - - skb_reserve(nskb, headroom); - __skb_put(nskb, skb_gro_offset(p)); - - skb_set_mac_header(nskb, skb_mac_header(p) - p->data); - skb_set_network_header(nskb, skb_network_offset(p)); - skb_set_transport_header(nskb, skb_transport_offset(p)); - - __skb_pull(p, skb_gro_offset(p)); - memcpy(skb_mac_header(nskb), skb_mac_header(p), - p->data - skb_mac_header(p)); - - skb_shinfo(nskb)->frag_list = p; - skb_shinfo(nskb)->gso_size = pinfo->gso_size; - pinfo->gso_size = 0; - __skb_header_release(p); - NAPI_GRO_CB(nskb)->last = p; - - nskb->data_len += p->len; - nskb->truesize += p->truesize; - nskb->len += p->len; - - *head = nskb; - nskb->next = p->next; - p->next = NULL; - - p = nskb; merge: delta_truesize = skb->truesize; -- GitLab From 3ba67dabaa58e3223325f0a813a6e830fb5f5cc5 Mon Sep 17 00:00:00 2001 From: Daniel Borkmann Date: Thu, 5 Mar 2015 23:27:51 +0100 Subject: [PATCH 03289/11651] ebpf: bpf_map_*: fix linker error on avr32 and openrisc arch Fengguang reported, that on openrisc and avr32 architectures, we get the following linker errors on *_defconfig builds that have no bpf syscall support: net/built-in.o:(.rodata+0x1cd0): undefined reference to `bpf_map_lookup_elem_proto' net/built-in.o:(.rodata+0x1cd4): undefined reference to `bpf_map_update_elem_proto' net/built-in.o:(.rodata+0x1cd8): undefined reference to `bpf_map_delete_elem_proto' Fix it up by providing built-in weak definitions of the symbols, so they can be overridden when the syscall is enabled. I think the issue might be that gcc is not able to optimize all that away. This patch fixes the linker errors for me, tested with Fengguang's make.cross [1] script. [1] https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross Reported-by: Fengguang Wu Fixes: d4052c4aea0c ("ebpf: remove CONFIG_BPF_SYSCALL ifdefs in socket filter code") Signed-off-by: Daniel Borkmann Acked-by: Alexei Starovoitov Signed-off-by: David S. Miller --- kernel/bpf/core.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c index a64e7a207d2b..50603aec766a 100644 --- a/kernel/bpf/core.c +++ b/kernel/bpf/core.c @@ -656,6 +656,11 @@ void bpf_prog_free(struct bpf_prog *fp) } EXPORT_SYMBOL_GPL(bpf_prog_free); +/* Weak definitions of helper functions in case we don't have bpf syscall. */ +const struct bpf_func_proto bpf_map_lookup_elem_proto __weak; +const struct bpf_func_proto bpf_map_update_elem_proto __weak; +const struct bpf_func_proto bpf_map_delete_elem_proto __weak; + /* To execute LD_ABS/LD_IND instructions __bpf_prog_run() may call * skb_copy_bits(), so provide a weak definition of it for NET-less config. */ -- GitLab From 2c2770541040318fa6ac0ac4424d8af6dd0709bf Mon Sep 17 00:00:00 2001 From: Leilei Zhao Date: Fri, 27 Feb 2015 16:07:14 +0800 Subject: [PATCH 03290/11651] tty/serial: at91: correct check of buf used in DMA We only use buf of ring In DMA rx function while using buf of xmit in DMA tx function. So in DMA rx we need definitively to check the buf of ring which is corresponding to DMA rx function. And use macro PAGE_ALIGNED to simplify the expression. Signed-off-by: Leilei Zhao Acked-by: Nicolas Ferre Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/atmel_serial.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index 4031dc367d3b..1a1d255baab5 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -848,7 +848,7 @@ static int atmel_prepare_tx_dma(struct uart_port *port) spin_lock_init(&atmel_port->lock_tx); sg_init_table(&atmel_port->sg_tx, 1); /* UART circular tx buffer is an aligned page. */ - BUG_ON((int)port->state->xmit.buf & ~PAGE_MASK); + BUG_ON(!PAGE_ALIGNED(port->state->xmit.buf)); sg_set_page(&atmel_port->sg_tx, virt_to_page(port->state->xmit.buf), UART_XMIT_SIZE, @@ -1027,7 +1027,7 @@ static int atmel_prepare_rx_dma(struct uart_port *port) spin_lock_init(&atmel_port->lock_rx); sg_init_table(&atmel_port->sg_rx, 1); /* UART circular rx buffer is an aligned page. */ - BUG_ON((int)port->state->xmit.buf & ~PAGE_MASK); + BUG_ON(!PAGE_ALIGNED(ring->buf)); sg_set_page(&atmel_port->sg_rx, virt_to_page(ring->buf), ATMEL_SERIAL_RINGSIZE, -- GitLab From a510880f6ea00ee28f22ec61a3c53357bb1bbaa5 Mon Sep 17 00:00:00 2001 From: Leilei Zhao Date: Fri, 27 Feb 2015 16:07:15 +0800 Subject: [PATCH 03291/11651] tty/serial: at91: correct buffer size used in DMA The buffer size set in DMA is inconsistent with its allocation. So keep them consistent here. The structure atmel_uart_char is used in PIO mode with its meaning. But here in DMA, all of the buffer is treated as general char. Signed-off-by: Leilei Zhao Acked-by: Nicolas Ferre Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/atmel_serial.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index 1a1d255baab5..6b70ec6d1704 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -1030,7 +1030,7 @@ static int atmel_prepare_rx_dma(struct uart_port *port) BUG_ON(!PAGE_ALIGNED(ring->buf)); sg_set_page(&atmel_port->sg_rx, virt_to_page(ring->buf), - ATMEL_SERIAL_RINGSIZE, + sizeof(struct atmel_uart_char) * ATMEL_SERIAL_RINGSIZE, (int)ring->buf & ~PAGE_MASK); nent = dma_map_sg(port->dev, &atmel_port->sg_rx, -- GitLab From 4a1e8888675b81d8f118b11650084c5e242be4b7 Mon Sep 17 00:00:00 2001 From: Leilei Zhao Date: Fri, 27 Feb 2015 16:07:16 +0800 Subject: [PATCH 03292/11651] tty/serial: at91: revise the return type of atmel_init_property The function of atmel_init_property is to set the work manner of atmel serial ports according to the property in device trees. If DMA or PDC is not set or something goes wrong in getting property, the work manner will switch to general PIO mode, thus there will not be any failure case in this function. It's actually a procedure. So changing the return type from int to void. Signed-off-by: Leilei Zhao Acked-by: Nicolas Ferre Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/atmel_serial.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index 6b70ec6d1704..a9b268841bb8 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -1534,7 +1534,7 @@ static void atmel_tasklet_func(unsigned long data) spin_unlock(&port->lock); } -static int atmel_init_property(struct atmel_uart_port *atmel_port, +static void atmel_init_property(struct atmel_uart_port *atmel_port, struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; @@ -1575,7 +1575,6 @@ static int atmel_init_property(struct atmel_uart_port *atmel_port, atmel_port->use_dma_tx = false; } - return 0; } static void atmel_init_rs485(struct uart_port *port, @@ -2235,8 +2234,8 @@ static int atmel_init_port(struct atmel_uart_port *atmel_port, struct uart_port *port = &atmel_port->uart; struct atmel_uart_data *pdata = dev_get_platdata(&pdev->dev); - if (!atmel_init_property(atmel_port, pdev)) - atmel_set_ops(port); + atmel_init_property(atmel_port, pdev); + atmel_set_ops(port); atmel_init_rs485(port, pdev); -- GitLab From 4d9628a1486658b83e47ad4c7ff07ff1ff0d3d89 Mon Sep 17 00:00:00 2001 From: Leilei Zhao Date: Fri, 27 Feb 2015 16:07:17 +0800 Subject: [PATCH 03293/11651] tty/serial: at91: set ops in property init each time The property in device tree will be reading each time when tty is opened, so the ops of serial port should be set after that instead of setting once in probe. Otherwise, the ops of serial port is inconsistent with the state of serial work manner. For example, the atmel serial driver can't work when switching to PIO mode due to DMA channel is not available. Signed-off-by: Leilei Zhao Acked-by: Nicolas Ferre Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/atmel_serial.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index a9b268841bb8..8fac877bc3d4 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -1759,6 +1759,7 @@ static int atmel_startup(struct uart_port *port) * Initialize DMA (if necessary) */ atmel_init_property(atmel_port, pdev); + atmel_set_ops(port); if (atmel_port->prepare_rx) { retval = atmel_port->prepare_rx(port); -- GitLab From 1e1257860fd10487795b782f1dbb5b5f2c203474 Mon Sep 17 00:00:00 2001 From: Leilei Zhao Date: Fri, 27 Feb 2015 16:07:18 +0800 Subject: [PATCH 03294/11651] tty/serial: at91: correct the usage of tasklet The tasklet may be scheduled and executed after serial port was shutdown, for example, DMA rx callback will schedule the tasklet while serial port is shutting down, especially serial port is sending and receiving data in a higher baud rate and it's killed by external program. In this case, tasklet_kill can only clear the current scheduling out, so tasklet should be disabled to prevent being executed in later scheduling. Otherwise, the tasklet executed after serial port was shutdown can lead to kernel crash. Signed-off-by: Leilei Zhao Acked-by: Nicolas Ferre Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/atmel_serial.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index 8fac877bc3d4..b45a4809031e 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -1755,6 +1755,8 @@ static int atmel_startup(struct uart_port *port) if (retval) goto free_irq; + tasklet_enable(&atmel_port->tasklet); + /* * Initialize DMA (if necessary) */ @@ -1858,6 +1860,7 @@ static void atmel_shutdown(struct uart_port *port) * Clear out any scheduled tasklets before * we destroy the buffers */ + tasklet_disable(&atmel_port->tasklet); tasklet_kill(&atmel_port->tasklet); /* @@ -2251,6 +2254,7 @@ static int atmel_init_port(struct atmel_uart_port *atmel_port, tasklet_init(&atmel_port->tasklet, atmel_tasklet_func, (unsigned long)port); + tasklet_disable(&atmel_port->tasklet); memset(&atmel_port->rx_ring, 0, sizeof(atmel_port->rx_ring)); -- GitLab From 73abaf87f01be6fa6da3c0aa9c138a1b6b281068 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sun, 1 Mar 2015 11:05:46 -0500 Subject: [PATCH 03295/11651] serial: earlycon: Refactor parse_options into serial core Prepare to support console-defined matching; refactor the command line parameter string processing from parse_options() into a new core function, uart_parse_earlycon(), which decodes command line parameters of the form: earlycon=,io|mmio|mmio32,, console=,io|mmio|mmio32,, earlycon=,0x, console=,0x, Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/earlycon.c | 39 +++++++++------------------ drivers/tty/serial/serial_core.c | 46 ++++++++++++++++++++++++++++++++ include/linux/serial_core.h | 2 ++ 3 files changed, 61 insertions(+), 26 deletions(-) diff --git a/drivers/tty/serial/earlycon.c b/drivers/tty/serial/earlycon.c index 64fe25a4285c..58d6bcdaf31c 100644 --- a/drivers/tty/serial/earlycon.c +++ b/drivers/tty/serial/earlycon.c @@ -54,44 +54,31 @@ static void __iomem * __init earlycon_map(unsigned long paddr, size_t size) return base; } -static int __init parse_options(struct earlycon_device *device, - char *options) +static int __init parse_options(struct earlycon_device *device, char *options) { struct uart_port *port = &device->port; - int mmio, mmio32, length; + int length; unsigned long addr; - if (!options) - return -ENODEV; + if (uart_parse_earlycon(options, &port->iotype, &addr, &options)) + return -EINVAL; - mmio = !strncmp(options, "mmio,", 5); - mmio32 = !strncmp(options, "mmio32,", 7); - if (mmio || mmio32) { - port->iotype = (mmio ? UPIO_MEM : UPIO_MEM32); - options += mmio ? 5 : 7; - addr = simple_strtoul(options, NULL, 0); + switch (port->iotype) { + case UPIO_MEM32: + port->regshift = 2; /* fall-through */ + case UPIO_MEM: port->mapbase = addr; - if (mmio32) - port->regshift = 2; - } else if (!strncmp(options, "io,", 3)) { - port->iotype = UPIO_PORT; - options += 3; - addr = simple_strtoul(options, NULL, 0); + break; + case UPIO_PORT: port->iobase = addr; - mmio = 0; - } else if (!strncmp(options, "0x", 2)) { - port->iotype = UPIO_MEM; - addr = simple_strtoul(options, NULL, 0); - port->mapbase = addr; - } else { + break; + default: return -EINVAL; } port->uartclk = BASE_BAUD * 16; - options = strchr(options, ','); if (options) { - options++; device->baud = simple_strtoul(options, NULL, 0); length = min(strcspn(options, " ") + 1, (size_t)(sizeof(device->options))); @@ -100,7 +87,7 @@ static int __init parse_options(struct earlycon_device *device, if (port->iotype == UPIO_MEM || port->iotype == UPIO_MEM32) pr_info("Early serial console at MMIO%s 0x%llx (options '%s')\n", - mmio32 ? "32" : "", + (port->iotype == UPIO_MEM32) ? "32" : "", (unsigned long long)port->mapbase, device->options); else diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 63d29473c703..8379e3fa0162 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -1808,6 +1808,52 @@ uart_get_console(struct uart_port *ports, int nr, struct console *co) return ports + idx; } +/** + * uart_parse_earlycon - Parse earlycon options + * @p: ptr to 2nd field (ie., just beyond ',') + * @iotype: ptr for decoded iotype (out) + * @addr: ptr for decoded mapbase/iobase (out) + * @options: ptr for field; NULL if not present (out) + * + * Decodes earlycon kernel command line parameters of the form + * earlycon=,io|mmio|mmio32,, + * console=,io|mmio|mmio32,, + * + * The optional form + * earlycon=,0x, + * console=,0x, + * is also accepted; the returned @iotype will be UPIO_MEM. + * + * Returns 0 on success or -EINVAL on failure + */ +int uart_parse_earlycon(char *p, unsigned char *iotype, unsigned long *addr, + char **options) +{ + if (strncmp(p, "mmio,", 5) == 0) { + *iotype = UPIO_MEM; + p += 5; + } else if (strncmp(p, "mmio32,", 7) == 0) { + *iotype = UPIO_MEM32; + p += 7; + } else if (strncmp(p, "io,", 3) == 0) { + *iotype = UPIO_PORT; + p += 3; + } else if (strncmp(p, "0x", 2) == 0) { + *iotype = UPIO_MEM; + } else { + return -EINVAL; + } + + *addr = simple_strtoul(p, NULL, 0); + p = strchr(p, ','); + if (p) + p++; + + *options = p; + return 0; +} +EXPORT_SYMBOL_GPL(uart_parse_earlycon); + /** * uart_parse_options - Parse serial port baud/parity/bits/flow control. * @options: pointer to option string diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index baf3e1d08416..cc5c506f07dd 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -354,6 +354,8 @@ early_param("earlycon", name ## _setup_earlycon); struct uart_port *uart_get_console(struct uart_port *ports, int nr, struct console *c); +int uart_parse_earlycon(char *p, unsigned char *iotype, unsigned long *addr, + char **options); void uart_parse_options(char *options, int *baud, int *parity, int *bits, int *flow); int uart_set_options(struct uart_port *port, struct console *co, int baud, -- GitLab From f427c990e2d0fd30336b0c252aa7e38e4cffdea2 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sun, 1 Mar 2015 11:05:47 -0500 Subject: [PATCH 03296/11651] console: Preserve index after console setup() Before register_console() calls the setup() method of the matched console, the registering console index is already equal to the index from the console command line; ie. newcon->index == c->index. This change is also required to support extensible console matching; (the command line index may have no relation to the console index assigned by the console-defined match() function). Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- kernel/printk/printk.c | 1 - 1 file changed, 1 deletion(-) diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 01cfd69c54c6..d261a7e5f51a 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -2479,7 +2479,6 @@ void register_console(struct console *newcon) newcon->setup(newcon, console_cmdline[i].options) != 0) break; newcon->flags |= CON_ENABLED; - newcon->index = c->index; if (i == selected_console) { newcon->flags |= CON_CONSDEV; preferred_console = selected_console; -- GitLab From 833b1f7b5191e4ac15dfd86aa8137f2349f0fc30 Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Tue, 3 Mar 2015 18:11:14 +0300 Subject: [PATCH 03297/11651] serial/8250_dw: use platform_get_irq() instead of platform_get_resource() It is not recommened to use platform_get_resource(pdev, IORESOURCE_IRQ) for requesting IRQ's resources any more, as they can be not ready yet in case of DT-booting. platform_get_irq() instead is a recommended way for getting IRQ even if it was not retrieved earlier. It also makes code simpler because we're getting "int" value right away and no conversion from resource to int is required. Signed-off-by: Alexey Brodkin Cc: Vineet Gupta Cc: Alan Cox Cc: Greg Kroah-Hartman Cc: Andy Shevchenko Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_dw.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c index f426acc8c6b5..06933e8826a1 100644 --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c @@ -384,18 +384,24 @@ static int dw8250_probe(struct platform_device *pdev) { struct uart_8250_port uart = {}; struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); - struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + int irq = platform_get_irq(pdev, 0); struct dw8250_data *data; int err; - if (!regs || !irq) { - dev_err(&pdev->dev, "no registers/irq defined\n"); + if (!regs) { + dev_err(&pdev->dev, "no registers defined\n"); return -EINVAL; } + if (irq < 0) { + if (irq != -EPROBE_DEFER) + dev_err(&pdev->dev, "cannot get irq\n"); + return irq; + } + spin_lock_init(&uart.port.lock); uart.port.mapbase = regs->start; - uart.port.irq = irq->start; + uart.port.irq = irq; uart.port.handle_irq = dw8250_handle_irq; uart.port.pm = dw8250_do_pm; uart.port.type = PORT_8250; -- GitLab From 0f43deba6f79c8f2004008fe0c0afa23bc061b2f Mon Sep 17 00:00:00 2001 From: Scott Feldman Date: Fri, 6 Mar 2015 15:54:51 -0800 Subject: [PATCH 03298/11651] rocker: quiet sparce endianess warnings Signed-off-by: Scott Feldman Reviewed-by: Jonathan Toppins Signed-off-by: David S. Miller --- drivers/net/ethernet/rocker/rocker.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/rocker/rocker.c b/drivers/net/ethernet/rocker/rocker.c index cc1bbfddebfe..9629352fa5da 100644 --- a/drivers/net/ethernet/rocker/rocker.c +++ b/drivers/net/ethernet/rocker/rocker.c @@ -2737,7 +2737,8 @@ static struct rocker_neigh_tbl_entry * { struct rocker_neigh_tbl_entry *found; - hash_for_each_possible(rocker->neigh_tbl, found, entry, (u32)ip_addr) + hash_for_each_possible(rocker->neigh_tbl, found, + entry, be32_to_cpu(ip_addr)) if (found->ip_addr == ip_addr) return found; @@ -2749,7 +2750,8 @@ static void _rocker_neigh_add(struct rocker *rocker, { entry->index = rocker->neigh_tbl_next_index++; entry->ref_count++; - hash_add(rocker->neigh_tbl, &entry->entry, (u32)entry->ip_addr); + hash_add(rocker->neigh_tbl, &entry->entry, + be32_to_cpu(entry->ip_addr)); } static void _rocker_neigh_del(struct rocker *rocker, @@ -2868,7 +2870,7 @@ static int rocker_port_ipv4_resolve(struct rocker_port *rocker_port, __be32 ip_addr) { struct net_device *dev = rocker_port->dev; - struct neighbour *n = __ipv4_neigh_lookup(dev, (u32)ip_addr); + struct neighbour *n = __ipv4_neigh_lookup(dev, (__force u32)ip_addr); int err = 0; if (!n) -- GitLab From 1b5ef07e3dd3972d9111650fb6e0f5a566c741d8 Mon Sep 17 00:00:00 2001 From: Scott Feldman Date: Fri, 6 Mar 2015 15:54:52 -0800 Subject: [PATCH 03299/11651] rocker: sparse: fix dynamic allocation on stack warning Signed-off-by: Scott Feldman Signed-off-by: David S. Miller --- drivers/net/ethernet/rocker/rocker.c | 2 +- drivers/net/ethernet/rocker/rocker.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/rocker/rocker.c b/drivers/net/ethernet/rocker/rocker.c index 9629352fa5da..65e140315a58 100644 --- a/drivers/net/ethernet/rocker/rocker.c +++ b/drivers/net/ethernet/rocker/rocker.c @@ -2955,7 +2955,7 @@ static int rocker_port_vlan_flood_group(struct rocker_port *rocker_port, struct rocker_port *p; struct rocker *rocker = rocker_port->rocker; u32 group_id = ROCKER_GROUP_L2_FLOOD(vlan_id, 0); - u32 group_ids[rocker->port_count]; + u32 group_ids[ROCKER_FP_PORTS_MAX]; u8 group_count = 0; int err; int i; diff --git a/drivers/net/ethernet/rocker/rocker.h b/drivers/net/ethernet/rocker/rocker.h index 0a94b7c300be..51e430d25138 100644 --- a/drivers/net/ethernet/rocker/rocker.h +++ b/drivers/net/ethernet/rocker/rocker.h @@ -27,6 +27,8 @@ enum { ROCKER_ENOBUFS = 105, }; +#define ROCKER_FP_PORTS_MAX 62 + #define PCI_VENDOR_ID_REDHAT 0x1b36 #define PCI_DEVICE_ID_REDHAT_ROCKER 0x0006 -- GitLab From 4c0d9b17d1c0608bbbef6d00e68956de2c3b1f8e Mon Sep 17 00:00:00 2001 From: Nicholas Mc Guire Date: Mon, 9 Feb 2015 10:53:25 -0500 Subject: [PATCH 03300/11651] vt: vt_ioctl: use msecs_to_jiffies for time conversion Converting milliseconds to jiffies by "val * HZ / 1000" is technically OK but msecs_to_jiffies(val) is the cleaner solution and handles all corner cases correctly. This is a minor API consolidation only and should make things more readable. Signed-off-by: Nicholas Mc Guire Signed-off-by: Greg Kroah-Hartman --- drivers/tty/vt/vt_ioctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c index 2bd78e2ac8ec..97d5a74558a3 100644 --- a/drivers/tty/vt/vt_ioctl.c +++ b/drivers/tty/vt/vt_ioctl.c @@ -388,7 +388,7 @@ int vt_ioctl(struct tty_struct *tty, * Generate the tone for the appropriate number of ticks. * If the time is zero, turn off sound ourselves. */ - ticks = HZ * ((arg >> 16) & 0xffff) / 1000; + ticks = msecs_to_jiffies((arg >> 16) & 0xffff); count = ticks ? (arg & 0xffff) : 0; if (count) count = PIT_TICK_RATE / count; -- GitLab From 678afb9aa8cf2002160c1a56cef5c90df6dc285e Mon Sep 17 00:00:00 2001 From: "Lad, Prabhakar" Date: Wed, 4 Feb 2015 18:18:03 +0000 Subject: [PATCH 03301/11651] tty: vt/vt: fix sparse warning this patch fixes following sparse warning: vt.c:1240:12: warning: symbol 'rgb_from_256' was not declared. Should it be static? Signed-off-by: Lad, Prabhakar Signed-off-by: Greg Kroah-Hartman --- drivers/tty/vt/vt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 6e00572cbeb9..57ed647658be 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -1237,7 +1237,7 @@ static void default_attr(struct vc_data *vc) struct rgb { u8 r; u8 g; u8 b; }; -struct rgb rgb_from_256(int i) +static struct rgb rgb_from_256(int i) { struct rgb c; if (i < 8) { /* Standard colours. */ -- GitLab From 3372ec28622083ac87daf18918a222fbee06f6f9 Mon Sep 17 00:00:00 2001 From: Nicholas Mc Guire Date: Mon, 9 Feb 2015 10:54:10 -0500 Subject: [PATCH 03302/11651] vt: use msecs_to_jiffies for time conversion Converting milliseconds to jiffies by "val * HZ / 1000" is technically OK but msecs_to_jiffies(val) is the cleaner solution and handles all corner cases correctly. This is a minor API consolidation only and should make things more readable. Signed-off-by: Nicholas Mc Guire Reviewed-by: David Herrmann Signed-off-by: Greg Kroah-Hartman --- drivers/tty/vt/vt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 57ed647658be..edf17b4e385f 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -1573,7 +1573,7 @@ static void setterm_command(struct vc_data *vc) case 11: /* set bell duration in msec */ if (vc->vc_npar >= 1) vc->vc_bell_duration = (vc->vc_par[1] < 2000) ? - vc->vc_par[1] * HZ / 1000 : 0; + msecs_to_jiffies(vc->vc_par[1]) : 0; else vc->vc_bell_duration = DEFAULT_BELL_DURATION; break; -- GitLab From 6302ce4d80aa82b3fdb5c5cd68e7268037091b47 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Wed, 4 Mar 2015 16:18:33 -0800 Subject: [PATCH 03303/11651] libsas: Fix Kernel Crash in smp_execute_task This crash was reported: [ 366.947370] sd 3:0:1:0: [sdb] Spinning up disk.... [ 368.804046] BUG: unable to handle kernel NULL pointer dereference at (null) [ 368.804072] IP: [] __mutex_lock_common.isra.7+0x9c/0x15b [ 368.804098] PGD 0 [ 368.804114] Oops: 0002 [#1] SMP [ 368.804143] CPU 1 [ 368.804151] Modules linked in: sg netconsole s3g(PO) uinput joydev hid_multitouch usbhid hid snd_hda_codec_via cpufreq_userspace cpufreq_powersave cpufreq_stats uhci_hcd cpufreq_conservative snd_hda_intel snd_hda_codec snd_hwdep snd_pcm sdhci_pci snd_page_alloc sdhci snd_timer snd psmouse evdev serio_raw pcspkr soundcore xhci_hcd shpchp s3g_drm(O) mvsas mmc_core ahci libahci drm i2c_core acpi_cpufreq mperf video processor button thermal_sys dm_dmirror exfat_fs exfat_core dm_zcache dm_mod padlock_aes aes_generic padlock_sha iscsi_target_mod target_core_mod configfs sswipe libsas libata scsi_transport_sas picdev via_cputemp hwmon_vid fuse parport_pc ppdev lp parport autofs4 ext4 crc16 mbcache jbd2 sd_mod crc_t10dif usb_storage scsi_mod ehci_hcd usbcore usb_common [ 368.804749] [ 368.804764] Pid: 392, comm: kworker/u:3 Tainted: P W O 3.4.87-logicube-ng.22 #1 To be filled by O.E.M. To be filled by O.E.M./EPIA-M920 [ 368.804802] RIP: 0010:[] [] __mutex_lock_common.isra.7+0x9c/0x15b [ 368.804827] RSP: 0018:ffff880117001cc0 EFLAGS: 00010246 [ 368.804842] RAX: 0000000000000000 RBX: ffff8801185030d0 RCX: ffff88008edcb420 [ 368.804857] RDX: 0000000000000000 RSI: 0000000000000002 RDI: ffff8801185030d4 [ 368.804873] RBP: ffff8801181531c0 R08: 0000000000000020 R09: 00000000fffffffe [ 368.804885] R10: 0000000000000000 R11: 0000000000000000 R12: ffff8801185030d4 [ 368.804899] R13: 0000000000000002 R14: ffff880117001fd8 R15: ffff8801185030d8 [ 368.804916] FS: 0000000000000000(0000) GS:ffff88011fc80000(0000) knlGS:0000000000000000 [ 368.804931] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b [ 368.804946] CR2: 0000000000000000 CR3: 000000000160b000 CR4: 00000000000006e0 [ 368.804962] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 368.804978] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 [ 368.804995] Process kworker/u:3 (pid: 392, threadinfo ffff880117000000, task ffff8801181531c0) [ 368.805009] Stack: [ 368.805017] ffff8801185030d8 0000000000000000 ffffffff8161ddf0 ffffffff81056f7c [ 368.805062] 000000000000b503 ffff8801185030d0 ffff880118503000 0000000000000000 [ 368.805100] ffff8801185030d0 ffff8801188b8000 ffff88008edcb420 ffffffff813583ac [ 368.805135] Call Trace: [ 368.805153] [] ? up+0xb/0x33 [ 368.805168] [] ? mutex_lock+0x16/0x25 [ 368.805194] [] ? smp_execute_task+0x4e/0x222 [libsas] [ 368.805217] [] ? sas_find_bcast_dev+0x3c/0x15d [libsas] [ 368.805240] [] ? sas_find_bcast_dev+0x6f/0x15d [libsas] [ 368.805264] [] ? sas_ex_revalidate_domain+0x37/0x2ec [libsas] [ 368.805280] [] ? printk+0x43/0x48 [ 368.805296] [] ? _raw_spin_unlock_irqrestore+0xc/0xd [ 368.805318] [] ? sas_revalidate_domain+0x85/0xb6 [libsas] [ 368.805336] [] ? process_one_work+0x151/0x27c [ 368.805351] [] ? worker_thread+0xbb/0x152 [ 368.805366] [] ? manage_workers.isra.29+0x163/0x163 [ 368.805382] [] ? kthread+0x79/0x81 [ 368.805399] [] ? kernel_thread_helper+0x4/0x10 [ 368.805416] [] ? kthread_flush_work_fn+0x9/0x9 [ 368.805431] [] ? gs_change+0x13/0x13 [ 368.805442] Code: 83 7d 30 63 7e 04 f3 90 eb ab 4c 8d 63 04 4c 8d 7b 08 4c 89 e7 e8 fa 15 00 00 48 8b 43 10 4c 89 3c 24 48 89 63 10 48 89 44 24 08 <48> 89 20 83 c8 ff 48 89 6c 24 10 87 03 ff c8 74 35 4d 89 ee 41 [ 368.805851] RIP [] __mutex_lock_common.isra.7+0x9c/0x15b [ 368.805877] RSP [ 368.805886] CR2: 0000000000000000 [ 368.805899] ---[ end trace b720682065d8f4cc ]--- It's directly caused by 89d3cf6 [SCSI] libsas: add mutex for SMP task execution, but shows a deeper cause: expander functions expect to be able to cast to and treat domain devices as expanders. The correct fix is to only do expander discover when we know we've got an expander device to avoid wrongly casting a non-expander device. Reported-by: Praveen Murali Tested-by: Praveen Murali Cc: stable@vger.kernel.org Signed-off-by: James Bottomley --- drivers/scsi/libsas/sas_discover.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/libsas/sas_discover.c b/drivers/scsi/libsas/sas_discover.c index 62b58d38ce2e..60de66252fa2 100644 --- a/drivers/scsi/libsas/sas_discover.c +++ b/drivers/scsi/libsas/sas_discover.c @@ -500,6 +500,7 @@ static void sas_revalidate_domain(struct work_struct *work) struct sas_discovery_event *ev = to_sas_discovery_event(work); struct asd_sas_port *port = ev->port; struct sas_ha_struct *ha = port->ha; + struct domain_device *ddev = port->port_dev; /* prevent revalidation from finding sata links in recovery */ mutex_lock(&ha->disco_mutex); @@ -514,8 +515,9 @@ static void sas_revalidate_domain(struct work_struct *work) SAS_DPRINTK("REVALIDATING DOMAIN on port %d, pid:%d\n", port->id, task_pid_nr(current)); - if (port->port_dev) - res = sas_ex_revalidate_domain(port->port_dev); + if (ddev && (ddev->dev_type == SAS_FANOUT_EXPANDER_DEVICE || + ddev->dev_type == SAS_EDGE_EXPANDER_DEVICE)) + res = sas_ex_revalidate_domain(ddev); SAS_DPRINTK("done REVALIDATING DOMAIN on port %d, pid:%d, res 0x%x\n", port->id, task_pid_nr(current), res); -- GitLab From f8e471f9eb9068bf5ac8c6a04da74329a442f75a Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Fri, 6 Mar 2015 20:34:32 -0800 Subject: [PATCH 03304/11651] target: Add target_show_dynamic_sessions attribute helper This patch adds a new helper function that can be used by fabric driver TPG attributes for dumping the list of active sessions with a dynamically generated se_node_acl. (generate_node_acl=1). It prints one se_node_acl->initiatorname per line, up to PAGE_SIZE which is due to the current limitiation of single page attribute output within sysfs and configfs code. Note that if a session is referencing a explicit NodeACL, the InitiatorName will not appear within dynamic_sessions output. Reported-by: Andy Grover Signed-off-by: Nicholas Bellinger --- drivers/target/target_core_transport.c | 24 ++++++++++++++++++++ include/target/target_core_fabric.h | 1 + include/target/target_core_fabric_configfs.h | 5 ++++ 3 files changed, 30 insertions(+) diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 0adc0f650213..e06c136ff839 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -404,6 +404,30 @@ void target_put_session(struct se_session *se_sess) } EXPORT_SYMBOL(target_put_session); +ssize_t target_show_dynamic_sessions(struct se_portal_group *se_tpg, char *page) +{ + struct se_session *se_sess; + ssize_t len = 0; + + spin_lock_bh(&se_tpg->session_lock); + list_for_each_entry(se_sess, &se_tpg->tpg_sess_list, sess_list) { + if (!se_sess->se_node_acl) + continue; + if (!se_sess->se_node_acl->dynamic_node_acl) + continue; + if (strlen(se_sess->se_node_acl->initiatorname) + 1 + len > PAGE_SIZE) + break; + + len += snprintf(page + len, PAGE_SIZE - len, "%s\n", + se_sess->se_node_acl->initiatorname); + len += 1; /* Include NULL terminator */ + } + spin_unlock_bh(&se_tpg->session_lock); + + return len; +} +EXPORT_SYMBOL(target_show_dynamic_sessions); + static void target_complete_nacl(struct kref *kref) { struct se_node_acl *nacl = container_of(kref, diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h index 22a4e98eec80..2f4a2505db4c 100644 --- a/include/target/target_core_fabric.h +++ b/include/target/target_core_fabric.h @@ -95,6 +95,7 @@ void transport_register_session(struct se_portal_group *, struct se_node_acl *, struct se_session *, void *); void target_get_session(struct se_session *); void target_put_session(struct se_session *); +ssize_t target_show_dynamic_sessions(struct se_portal_group *, char *); void transport_free_session(struct se_session *); void target_put_nacl(struct se_node_acl *); void transport_deregister_session_configfs(struct se_session *); diff --git a/include/target/target_core_fabric_configfs.h b/include/target/target_core_fabric_configfs.h index b32a14905cfa..7a0649c09e79 100644 --- a/include/target/target_core_fabric_configfs.h +++ b/include/target/target_core_fabric_configfs.h @@ -90,6 +90,11 @@ static struct target_fabric_tpg_attribute _fabric##_tpg_##_name = \ _fabric##_tpg_store_##_name); +#define TF_TPG_BASE_ATTR_RO(_fabric, _name) \ +static struct target_fabric_tpg_attribute _fabric##_tpg_##_name = \ + __CONFIGFS_EATTR_RO(_name, \ + _fabric##_tpg_show_##_name); + CONFIGFS_EATTR_STRUCT(target_fabric_wwn, target_fabric_configfs); #define TF_WWN_ATTR(_fabric, _name, _mode) \ static struct target_fabric_wwn_attribute _fabric##_wwn_##_name = \ -- GitLab From d4ee46ff8c8404d63779772e4ddb3553eaca26ae Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Fri, 6 Mar 2015 20:40:57 -0800 Subject: [PATCH 03305/11651] iscsi-target: Expose per endpoint dynamic_sessions attribute This patch exposes a new ../iscsi/$IQN/$TPGT/dynamic_sessions attribute to dump the currently active sessions by iSCSI InitiatorName that have been created with dynamically generated se_node_acls. This information is useful so that user-space can optionally perform dynamic -> explicit NodeACL conversion based on $INITIATOR_WWPN. Signed-off-by: Nicholas Bellinger --- drivers/target/iscsi/iscsi_target_configfs.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c index 48384b675e62..95a67f604073 100644 --- a/drivers/target/iscsi/iscsi_target_configfs.c +++ b/drivers/target/iscsi/iscsi_target_configfs.c @@ -1410,8 +1410,18 @@ out: TF_TPG_BASE_ATTR(lio_target, enable, S_IRUGO | S_IWUSR); +static ssize_t lio_target_tpg_show_dynamic_sessions( + struct se_portal_group *se_tpg, + char *page) +{ + return target_show_dynamic_sessions(se_tpg, page); +} + +TF_TPG_BASE_ATTR_RO(lio_target, dynamic_sessions); + static struct configfs_attribute *lio_target_tpg_attrs[] = { &lio_target_tpg_enable.attr, + &lio_target_tpg_dynamic_sessions.attr, NULL, }; -- GitLab From d23dbaaaa454667ad6af6feb56f740a990d1295d Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Fri, 6 Mar 2015 20:43:34 -0800 Subject: [PATCH 03306/11651] tcm_qla2xxx: Expose per endpoint dynamic_sessions attribute This patch exposes a new ../qla2xxx*/$WWPN/$TPGT/dynamic_sessions attribute to dump the currently active sessions by FC initiator WWPN that have been created with dynamically generated se_node_acls. This information is useful so that user-space can optionally perform dynamic -> explicit NodeACL conversion based on $INITIATOR_WWPN. Signed-off-by: Nicholas Bellinger --- drivers/scsi/qla2xxx/tcm_qla2xxx.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c index 99f43b7fc9ab..c4f66f5745a8 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c @@ -1082,8 +1082,18 @@ static ssize_t tcm_qla2xxx_tpg_store_enable( TF_TPG_BASE_ATTR(tcm_qla2xxx, enable, S_IRUGO | S_IWUSR); +static ssize_t tcm_qla2xxx_tpg_show_dynamic_sessions( + struct se_portal_group *se_tpg, + char *page) +{ + return target_show_dynamic_sessions(se_tpg, page); +} + +TF_TPG_BASE_ATTR_RO(tcm_qla2xxx, dynamic_sessions); + static struct configfs_attribute *tcm_qla2xxx_tpg_attrs[] = { &tcm_qla2xxx_tpg_enable.attr, + &tcm_qla2xxx_tpg_dynamic_sessions.attr, NULL, }; -- GitLab From 4076b521cb50c411467c4ba65f82ef0079823357 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Wed, 18 Feb 2015 12:25:42 +0100 Subject: [PATCH 03307/11651] ARM: BCM5301X: Add DT for Netgear R8000 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Reported-by: Ian Kent Signed-off-by: Florian Fainelli --- arch/arm/boot/dts/Makefile | 3 +- arch/arm/boot/dts/bcm4709-netgear-r8000.dts | 77 +++++++++++++++++++++ 2 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 arch/arm/boot/dts/bcm4709-netgear-r8000.dts diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index 2604d7ca9333..c6e0a4c5080c 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -59,7 +59,8 @@ dtb-$(CONFIG_ARCH_BCM_5301X) += \ bcm4708-netgear-r6300-v2.dtb \ bcm47081-asus-rt-n18u.dtb \ bcm47081-buffalo-wzr-600dhp2.dtb \ - bcm47081-buffalo-wzr-900dhp.dtb + bcm47081-buffalo-wzr-900dhp.dtb \ + bcm4709-netgear-r8000.dtb dtb-$(CONFIG_ARCH_BCM_63XX) += \ bcm963138dvt.dtb dtb-$(CONFIG_ARCH_BCM_CYGNUS) += \ diff --git a/arch/arm/boot/dts/bcm4709-netgear-r8000.dts b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts new file mode 100644 index 000000000000..ea26dd3ec03a --- /dev/null +++ b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts @@ -0,0 +1,77 @@ +/* + * Broadcom BCM470X / BCM5301X ARM platform code. + * DTS for Netgear R8000 + * + * Copyright (C) 2015 Rafał Miłecki + * + * Licensed under the GNU/GPL. See COPYING for details. + */ + +/dts-v1/; + +#include "bcm4708.dtsi" + +/ { + compatible = "netgear,r8000", "brcm,bcm4709", "brcm,bcm4708"; + model = "Netgear R8000 (BCM4709)"; + + chosen { + bootargs = "console=ttyS0,115200"; + }; + + memory { + reg = <0x00000000 0x08000000>; + }; + + leds { + compatible = "gpio-leds"; + + power0 { + label = "bcm53xx:white:power"; + gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>; + linux,default-trigger = "default-on"; + }; + + power1 { + label = "bcm53xx:amber:power"; + gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>; + linux,default-trigger = "default-off"; + }; + + 5ghz-1 { + label = "bcm53xx:white:5ghz-1"; + gpios = <&chipcommon 12 GPIO_ACTIVE_LOW>; + linux,default-trigger = "default-off"; + }; + + 2ghz { + label = "bcm53xx:white:2ghz"; + gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>; + linux,default-trigger = "default-off"; + }; + }; + + gpio-keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + + rfkill { + label = "WiFi"; + linux,code = ; + gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>; + }; + + wps { + label = "WPS"; + linux,code = ; + gpios = <&chipcommon 5 GPIO_ACTIVE_LOW>; + }; + + restart { + label = "Reset"; + linux,code = ; + gpios = <&chipcommon 6 GPIO_ACTIVE_LOW>; + }; + }; +}; -- GitLab From 7875b470c9d80dff2d58ae9692adb3a2b5814a89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Fri, 20 Feb 2015 11:22:05 +0100 Subject: [PATCH 03308/11651] ARM: BCM5301X: Fix default state of power LEDs on Netgear R6250 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We want green LED to be enabled by default. Signed-off-by: Rafał Miłecki Signed-off-by: Florian Fainelli --- arch/arm/boot/dts/bcm4708-netgear-r6250.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/bcm4708-netgear-r6250.dts b/arch/arm/boot/dts/bcm4708-netgear-r6250.dts index f18c9d9b2f2c..2ed9e5794785 100644 --- a/arch/arm/boot/dts/bcm4708-netgear-r6250.dts +++ b/arch/arm/boot/dts/bcm4708-netgear-r6250.dts @@ -45,13 +45,13 @@ power0 { label = "bcm53xx:green:power"; gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-off"; + linux,default-trigger = "default-on"; }; power1 { label = "bcm53xx:amber:power"; gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-on"; + linux,default-trigger = "default-off"; }; usb { -- GitLab From b27559a433bb6080d95c2593d4a2b81401197911 Mon Sep 17 00:00:00 2001 From: Andy Lutomirski Date: Fri, 6 Mar 2015 17:50:18 -0800 Subject: [PATCH 03309/11651] x86/asm/entry: Delay loading sp0 slightly on task switch The change: 75182b1632a8 ("x86/asm/entry: Switch all C consumers of kernel_stack to this_cpu_sp0()") had the unintended side effect of changing the return value of current_thread_info() during part of the context switch process. Change it back. This has no effect as far as I can tell -- it's just for consistency. Signed-off-by: Andy Lutomirski Cc: Borislav Petkov Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Oleg Nesterov Cc: Thomas Gleixner Link: http://lkml.kernel.org/r/9fcaa47dd8487db59eed7a3911b6ae409476763e.1425692936.git.luto@amacapital.net Signed-off-by: Ingo Molnar --- arch/x86/kernel/process_32.c | 10 +++++----- arch/x86/kernel/process_64.c | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index d3460af3d27a..0405cab6634d 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c @@ -255,11 +255,6 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) fpu = switch_fpu_prepare(prev_p, next_p, cpu); - /* - * Reload esp0. - */ - load_sp0(tss, next); - /* * Save away %gs. No need to save %fs, as it was saved on the * stack on entry. No need to save %es and %ds, as those are @@ -310,6 +305,11 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) */ arch_end_context_switch(next_p); + /* + * Reload esp0. This changes current_thread_info(). + */ + load_sp0(tss, next); + this_cpu_write(kernel_stack, (unsigned long)task_stack_page(next_p) + THREAD_SIZE - KERNEL_STACK_OFFSET); diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 2cd562f96c1f..1e393d27d701 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -283,9 +283,6 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) fpu = switch_fpu_prepare(prev_p, next_p, cpu); - /* Reload esp0 and ss1. */ - load_sp0(tss, next); - /* We must save %fs and %gs before load_TLS() because * %fs and %gs may be cleared by load_TLS(). * @@ -413,6 +410,9 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) task_thread_info(prev_p)->saved_preempt_count = this_cpu_read(__preempt_count); this_cpu_write(__preempt_count, task_thread_info(next_p)->saved_preempt_count); + /* Reload esp0 and ss1. This changes current_thread_info(). */ + load_sp0(tss, next); + this_cpu_write(kernel_stack, (unsigned long)task_stack_page(next_p) + THREAD_SIZE - KERNEL_STACK_OFFSET); -- GitLab From a7fcf28d431ef70afaa91496e64e16dc51dccec4 Mon Sep 17 00:00:00 2001 From: Andy Lutomirski Date: Fri, 6 Mar 2015 17:50:19 -0800 Subject: [PATCH 03310/11651] x86/asm/entry: Replace this_cpu_sp0() with current_top_of_stack() and fix it on x86_32 I broke 32-bit kernels. The implementation of sp0 was correct as far as I can tell, but sp0 was much weirder on x86_32 than I realized. It has the following issues: - Init's sp0 is inconsistent with everything else's: non-init tasks are offset by 8 bytes. (I have no idea why, and the comment is unhelpful.) - vm86 does crazy things to sp0. Fix it up by replacing this_cpu_sp0() with current_top_of_stack() and using a new percpu variable to track the top of the stack on x86_32. Signed-off-by: Andy Lutomirski Cc: Borislav Petkov Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Oleg Nesterov Cc: Thomas Gleixner Fixes: 75182b1632a8 ("x86/asm/entry: Switch all C consumers of kernel_stack to this_cpu_sp0()") Link: http://lkml.kernel.org/r/d09dbe270883433776e0cbee3c7079433349e96d.1425692936.git.luto@amacapital.net Signed-off-by: Ingo Molnar --- arch/x86/include/asm/processor.h | 11 ++++++++++- arch/x86/include/asm/thread_info.h | 4 +--- arch/x86/kernel/cpu/common.c | 13 +++++++++++-- arch/x86/kernel/process_32.c | 11 +++++++---- arch/x86/kernel/smpboot.c | 2 ++ arch/x86/kernel/traps.c | 4 ++-- 6 files changed, 33 insertions(+), 12 deletions(-) diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index f5e3ec63767d..48a61c1c626e 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -284,6 +284,10 @@ struct tss_struct { DECLARE_PER_CPU_SHARED_ALIGNED(struct tss_struct, cpu_tss); +#ifdef CONFIG_X86_32 +DECLARE_PER_CPU(unsigned long, cpu_current_top_of_stack); +#endif + /* * Save the original ist values for checking stack pointers during debugging */ @@ -564,9 +568,14 @@ static inline void native_swapgs(void) #endif } -static inline unsigned long this_cpu_sp0(void) +static inline unsigned long current_top_of_stack(void) { +#ifdef CONFIG_X86_64 return this_cpu_read_stable(cpu_tss.x86_tss.sp0); +#else + /* sp0 on x86_32 is special in and around vm86 mode. */ + return this_cpu_read_stable(cpu_current_top_of_stack); +#endif } #ifdef CONFIG_PARAVIRT diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h index a2fa1899494e..7740edd56fed 100644 --- a/arch/x86/include/asm/thread_info.h +++ b/arch/x86/include/asm/thread_info.h @@ -158,9 +158,7 @@ DECLARE_PER_CPU(unsigned long, kernel_stack); static inline struct thread_info *current_thread_info(void) { - struct thread_info *ti; - ti = (void *)(this_cpu_sp0() - THREAD_SIZE); - return ti; + return (struct thread_info *)(current_top_of_stack() - THREAD_SIZE); } static inline unsigned long current_stack_pointer(void) diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 5d0f0cc7ea26..76348334b934 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -1130,8 +1130,8 @@ DEFINE_PER_CPU_FIRST(union irq_stack_union, irq_stack_union) __aligned(PAGE_SIZE) __visible; /* - * The following four percpu variables are hot. Align current_task to - * cacheline size such that all four fall in the same cacheline. + * The following percpu variables are hot. Align current_task to + * cacheline size such that they fall in the same cacheline. */ DEFINE_PER_CPU(struct task_struct *, current_task) ____cacheline_aligned = &init_task; @@ -1226,6 +1226,15 @@ DEFINE_PER_CPU(int, __preempt_count) = INIT_PREEMPT_COUNT; EXPORT_PER_CPU_SYMBOL(__preempt_count); DEFINE_PER_CPU(struct task_struct *, fpu_owner_task); +/* + * On x86_32, vm86 modifies tss.sp0, so sp0 isn't a reliable way to find + * the top of the kernel stack. Use an extra percpu variable to track the + * top of the kernel stack directly. + */ +DEFINE_PER_CPU(unsigned long, cpu_current_top_of_stack) = + (unsigned long)&init_thread_union + THREAD_SIZE; +EXPORT_PER_CPU_SYMBOL(cpu_current_top_of_stack); + #ifdef CONFIG_CC_STACKPROTECTOR DEFINE_PER_CPU_ALIGNED(struct stack_canary, stack_canary); #endif diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index 0405cab6634d..1b9963faf4eb 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c @@ -306,13 +306,16 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) arch_end_context_switch(next_p); /* - * Reload esp0. This changes current_thread_info(). + * Reload esp0, kernel_stack, and current_top_of_stack. This changes + * current_thread_info(). */ load_sp0(tss, next); - this_cpu_write(kernel_stack, - (unsigned long)task_stack_page(next_p) + - THREAD_SIZE - KERNEL_STACK_OFFSET); + (unsigned long)task_stack_page(next_p) + + THREAD_SIZE - KERNEL_STACK_OFFSET); + this_cpu_write(cpu_current_top_of_stack, + (unsigned long)task_stack_page(next_p) + + THREAD_SIZE); /* * Restore %gs if needed (which is common) diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index febc6aabc72e..759388c538cf 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -806,6 +806,8 @@ static int do_boot_cpu(int apicid, int cpu, struct task_struct *idle) #ifdef CONFIG_X86_32 /* Stack for startup_32 can be just as for start_secondary onwards */ irq_ctx_init(cpu); + per_cpu(cpu_current_top_of_stack, cpu) = + (unsigned long)task_stack_page(idle) + THREAD_SIZE; #else clear_tsk_thread_flag(idle, TIF_FORK); initial_gs = per_cpu_offset(cpu); diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index fa290586ed37..081252c44cde 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -174,8 +174,8 @@ void ist_begin_non_atomic(struct pt_regs *regs) * will catch asm bugs and any attempt to use ist_preempt_enable * from double_fault. */ - BUG_ON((unsigned long)(this_cpu_sp0() - current_stack_pointer()) >= - THREAD_SIZE); + BUG_ON((unsigned long)(current_top_of_stack() - + current_stack_pointer()) >= THREAD_SIZE); preempt_count_sub(HARDIRQ_OFFSET); } -- GitLab From 9198f6edfd9ced74fd90b238d5a354aeac89bdfa Mon Sep 17 00:00:00 2001 From: Jason Low Date: Fri, 6 Mar 2015 23:45:31 -0800 Subject: [PATCH 03311/11651] locking/rwsem: Fix lock optimistic spinning when owner is not running Ming reported soft lockups occurring when running xfstest due to the following tip:locking/core commit: b3fd4f03ca0b ("locking/rwsem: Avoid deceiving lock spinners") When doing optimistic spinning in rwsem, threads should stop spinning when the lock owner is not running. While a thread is spinning on owner, if the owner reschedules, owner->on_cpu returns false and we stop spinning. However, this commit essentially caused the check to get ignored because when we break out of the spin loop due to !on_cpu, we continue spinning if sem->owner != NULL. This patch fixes this by making sure we stop spinning if the owner is not running. Furthermore, just like with mutexes, refactor the code such that we don't have separate checks for owner_running(). This makes it more straightforward in terms of why we exit the spin on owner loop and we would also avoid needing to "guess" why we broke out of the loop to make this more readable. Reported-and-tested-by: Ming Lei Signed-off-by: Jason Low Acked-by: Davidlohr Bueso Cc: Andrew Morton Cc: Dave Jones Cc: Linus Torvalds Cc: Michel Lespinasse Cc: Oleg Nesterov Cc: Paul E. McKenney Cc: Peter Zijlstra Cc: Sasha Levin Cc: Thomas Gleixner Cc: Tim Chen Link: http://lkml.kernel.org/r/1425714331.2475.388.camel@j-VirtualBox Signed-off-by: Ingo Molnar --- kernel/locking/rwsem-xadd.c | 31 +++++++++++-------------------- 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/kernel/locking/rwsem-xadd.c b/kernel/locking/rwsem-xadd.c index 06e2214edf98..3417d0172a5d 100644 --- a/kernel/locking/rwsem-xadd.c +++ b/kernel/locking/rwsem-xadd.c @@ -324,32 +324,23 @@ done: return ret; } -static inline bool owner_running(struct rw_semaphore *sem, - struct task_struct *owner) -{ - if (sem->owner != owner) - return false; - - /* - * Ensure we emit the owner->on_cpu, dereference _after_ checking - * sem->owner still matches owner, if that fails, owner might - * point to free()d memory, if it still matches, the rcu_read_lock() - * ensures the memory stays valid. - */ - barrier(); - - return owner->on_cpu; -} - static noinline bool rwsem_spin_on_owner(struct rw_semaphore *sem, struct task_struct *owner) { long count; rcu_read_lock(); - while (owner_running(sem, owner)) { - /* abort spinning when need_resched */ - if (need_resched()) { + while (sem->owner == owner) { + /* + * Ensure we emit the owner->on_cpu, dereference _after_ + * checking sem->owner still matches owner, if that fails, + * owner might point to free()d memory, if it still matches, + * the rcu_read_lock() ensures the memory stays valid. + */ + barrier(); + + /* abort spinning when need_resched or owner is not running */ + if (!owner->on_cpu || need_resched()) { rcu_read_unlock(); return false; } -- GitLab From 3f1615340acea54e21f4b9d4d65921540dca84b2 Mon Sep 17 00:00:00 2001 From: Pontus Fuchs Date: Fri, 6 Mar 2015 16:18:41 +0100 Subject: [PATCH 03312/11651] brcmfmac: Perform bound checking on vendor command buffer A short or malformed vendor command buffer could cause reads outside the command buffer. Cc: stable@vger.kernel.org # v3.19 Signed-off-by: Pontus Fuchs [arend@broadcom.com: slightly modified debug trace output] Signed-off-by: Arend van Spriel Signed-off-by: Kalle Valo --- drivers/net/wireless/brcm80211/brcmfmac/vendor.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/brcm80211/brcmfmac/vendor.c b/drivers/net/wireless/brcm80211/brcmfmac/vendor.c index 50cdf7090198..8eff2753abad 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/vendor.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/vendor.c @@ -39,13 +39,22 @@ static int brcmf_cfg80211_vndr_cmds_dcmd_handler(struct wiphy *wiphy, void *dcmd_buf = NULL, *wr_pointer; u16 msglen, maxmsglen = PAGE_SIZE - 0x100; - brcmf_dbg(TRACE, "cmd %x set %d len %d\n", cmdhdr->cmd, cmdhdr->set, - cmdhdr->len); + if (len < sizeof(*cmdhdr)) { + brcmf_err("vendor command too short: %d\n", len); + return -EINVAL; + } vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev); ifp = vif->ifp; - len -= sizeof(struct brcmf_vndr_dcmd_hdr); + brcmf_dbg(TRACE, "ifidx=%d, cmd=%d\n", ifp->ifidx, cmdhdr->cmd); + + if (cmdhdr->offset > len) { + brcmf_err("bad buffer offset %d > %d\n", cmdhdr->offset, len); + return -EINVAL; + } + + len -= cmdhdr->offset; ret_len = cmdhdr->len; if (ret_len > 0 || len > 0) { if (len > BRCMF_DCMD_MAXLEN) { -- GitLab From 3e1aa7cb59aff4b245b45e326fcdba1bf7f105c6 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 6 Mar 2015 21:55:32 +0100 Subject: [PATCH 03313/11651] x86/asm: Optimize unnecessarily wide TEST instructions By the nature of the TEST operation, it is often possible to test a narrower part of the operand: "testl $3, mem" -> "testb $3, mem", "testq $3, %rcx" -> "testb $3, %cl" This results in shorter instructions, because the TEST instruction has no sign-entending byte-immediate forms unlike other ALU ops. Note that this change does not create any LCP (Length-Changing Prefix) stalls, which happen when adding a 0x66 prefix, which happens when 16-bit immediates are used, which changes such TEST instructions: [test_opcode] [modrm] [imm32] to: [0x66] [test_opcode] [modrm] [imm16] where [imm16] has a *different length* now: 2 bytes instead of 4. This confuses the decoder and slows down execution. REX prefixes were carefully designed to almost never hit this case: adding REX prefix does not change instruction length except MOVABS and MOV [addr],RAX instruction. This patch does not add instructions which would use a 0x66 prefix, code changes in assembly are: -48 f7 07 01 00 00 00 testq $0x1,(%rdi) +f6 07 01 testb $0x1,(%rdi) -48 f7 c1 01 00 00 00 test $0x1,%rcx +f6 c1 01 test $0x1,%cl -48 f7 c1 02 00 00 00 test $0x2,%rcx +f6 c1 02 test $0x2,%cl -41 f7 c2 01 00 00 00 test $0x1,%r10d +41 f6 c2 01 test $0x1,%r10b -48 f7 c1 04 00 00 00 test $0x4,%rcx +f6 c1 04 test $0x4,%cl -48 f7 c1 08 00 00 00 test $0x8,%rcx +f6 c1 08 test $0x8,%cl Linus further notes: "There are no stalls from using 8-bit instruction forms. Now, changing from 64-bit or 32-bit 'test' instructions to 8-bit ones *could* cause problems if it ends up having forwarding issues, so that instead of just forwarding the result, you end up having to wait for it to be stable in the L1 cache (or possibly the register file). The forwarding from the store buffer is simplest and most reliable if the read is done at the exact same address and the exact same size as the write that gets forwarded. But that's true only if: (a) the write was very recent and is still in the write queue. I'm not sure that's the case here anyway. (b) on at least most Intel microarchitectures, you have to test a different byte than the lowest one (so forwarding a 64-bit write to a 8-bit read ends up working fine, as long as the 8-bit read is of the low 8 bits of the written data). A very similar issue *might* show up for registers too, not just memory writes, if you use 'testb' with a high-byte register (where instead of forwarding the value from the original producer it needs to go through the register file and then shifted). But it's mainly a problem for store buffers. But afaik, the way Denys changed the test instructions, neither of the above issues should be true. The real problem for store buffer forwarding tends to be "write 8 bits, read 32 bits". That can be really surprisingly expensive, because the read ends up having to wait until the write has hit the cacheline, and we might talk tens of cycles of latency here. But "write 32 bits, read the low 8 bits" *should* be fast on pretty much all x86 chips, afaik." Signed-off-by: Denys Vlasenko Acked-by: Andy Lutomirski Acked-by: Linus Torvalds Cc: Borislav Petkov Cc: Frederic Weisbecker Cc: H. Peter Anvin Cc: H. Peter Anvin Cc: Kees Cook Cc: Oleg Nesterov Cc: Steven Rostedt Cc: Will Drewry Link: http://lkml.kernel.org/r/1425675332-31576-1-git-send-email-dvlasenk@redhat.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/head_64.S | 2 +- arch/x86/kernel/relocate_kernel_32.S | 8 ++++---- arch/x86/kernel/relocate_kernel_64.S | 8 ++++---- arch/x86/lib/checksum_32.S | 4 ++-- arch/x86/lib/csum-copy_64.S | 2 +- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S index 9a0919678f97..ae6588b301c2 100644 --- a/arch/x86/kernel/head_64.S +++ b/arch/x86/kernel/head_64.S @@ -146,7 +146,7 @@ startup_64: leaq level2_kernel_pgt(%rip), %rdi leaq 4096(%rdi), %r8 /* See if it is a valid page table entry */ -1: testq $1, 0(%rdi) +1: testb $1, 0(%rdi) jz 2f addq %rbp, 0(%rdi) /* Go to the next page */ diff --git a/arch/x86/kernel/relocate_kernel_32.S b/arch/x86/kernel/relocate_kernel_32.S index e13f8e7c22a6..77630d57e7bf 100644 --- a/arch/x86/kernel/relocate_kernel_32.S +++ b/arch/x86/kernel/relocate_kernel_32.S @@ -226,23 +226,23 @@ swap_pages: movl (%ebx), %ecx addl $4, %ebx 1: - testl $0x1, %ecx /* is it a destination page */ + testb $0x1, %cl /* is it a destination page */ jz 2f movl %ecx, %edi andl $0xfffff000, %edi jmp 0b 2: - testl $0x2, %ecx /* is it an indirection page */ + testb $0x2, %cl /* is it an indirection page */ jz 2f movl %ecx, %ebx andl $0xfffff000, %ebx jmp 0b 2: - testl $0x4, %ecx /* is it the done indicator */ + testb $0x4, %cl /* is it the done indicator */ jz 2f jmp 3f 2: - testl $0x8, %ecx /* is it the source indicator */ + testb $0x8, %cl /* is it the source indicator */ jz 0b /* Ignore it otherwise */ movl %ecx, %esi /* For every source page do a copy */ andl $0xfffff000, %esi diff --git a/arch/x86/kernel/relocate_kernel_64.S b/arch/x86/kernel/relocate_kernel_64.S index 3fd2c693e475..04cb1790a596 100644 --- a/arch/x86/kernel/relocate_kernel_64.S +++ b/arch/x86/kernel/relocate_kernel_64.S @@ -221,23 +221,23 @@ swap_pages: movq (%rbx), %rcx addq $8, %rbx 1: - testq $0x1, %rcx /* is it a destination page? */ + testb $0x1, %cl /* is it a destination page? */ jz 2f movq %rcx, %rdi andq $0xfffffffffffff000, %rdi jmp 0b 2: - testq $0x2, %rcx /* is it an indirection page? */ + testb $0x2, %cl /* is it an indirection page? */ jz 2f movq %rcx, %rbx andq $0xfffffffffffff000, %rbx jmp 0b 2: - testq $0x4, %rcx /* is it the done indicator? */ + testb $0x4, %cl /* is it the done indicator? */ jz 2f jmp 3f 2: - testq $0x8, %rcx /* is it the source indicator? */ + testb $0x8, %cl /* is it the source indicator? */ jz 0b /* Ignore it otherwise */ movq %rcx, %rsi /* For ever source page do a copy */ andq $0xfffffffffffff000, %rsi diff --git a/arch/x86/lib/checksum_32.S b/arch/x86/lib/checksum_32.S index c3b9953d3fa0..9bc944a91274 100644 --- a/arch/x86/lib/checksum_32.S +++ b/arch/x86/lib/checksum_32.S @@ -125,7 +125,7 @@ ENTRY(csum_partial) 6: addl %ecx,%eax adcl $0, %eax 7: - testl $1, 12(%esp) + testb $1, 12(%esp) jz 8f roll $8, %eax 8: @@ -245,7 +245,7 @@ ENTRY(csum_partial) addl %ebx,%eax adcl $0,%eax 80: - testl $1, 12(%esp) + testb $1, 12(%esp) jz 90f roll $8, %eax 90: diff --git a/arch/x86/lib/csum-copy_64.S b/arch/x86/lib/csum-copy_64.S index 2419d5fefae3..9734182966f3 100644 --- a/arch/x86/lib/csum-copy_64.S +++ b/arch/x86/lib/csum-copy_64.S @@ -196,7 +196,7 @@ ENTRY(csum_partial_copy_generic) /* handle last odd byte */ .Lhandle_1: - testl $1, %r10d + testb $1, %r10b jz .Lende xorl %ebx, %ebx source -- GitLab From 12cb89e37a0c25fae7a0f1d2e4985558db9d0b13 Mon Sep 17 00:00:00 2001 From: "Ivan T. Ivanov" Date: Fri, 6 Mar 2015 17:26:17 +0200 Subject: [PATCH 03314/11651] spi: qup: Fix cs-num DT property parsing num-cs is 32 bit property, don't read just upper 16 bits. Fixes: 4a8573abe965 (spi: qup: Remove chip select function) Signed-off-by: Ivan T. Ivanov Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- drivers/spi/spi-qup.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/spi/spi-qup.c b/drivers/spi/spi-qup.c index ff9cdbdb6672..2b2c359f5a50 100644 --- a/drivers/spi/spi-qup.c +++ b/drivers/spi/spi-qup.c @@ -498,7 +498,7 @@ static int spi_qup_probe(struct platform_device *pdev) struct resource *res; struct device *dev; void __iomem *base; - u32 max_freq, iomode; + u32 max_freq, iomode, num_cs; int ret, irq, size; dev = &pdev->dev; @@ -550,10 +550,11 @@ static int spi_qup_probe(struct platform_device *pdev) } /* use num-cs unless not present or out of range */ - if (of_property_read_u16(dev->of_node, "num-cs", - &master->num_chipselect) || - (master->num_chipselect > SPI_NUM_CHIPSELECTS)) + if (of_property_read_u32(dev->of_node, "num-cs", &num_cs) || + num_cs > SPI_NUM_CHIPSELECTS) master->num_chipselect = SPI_NUM_CHIPSELECTS; + else + master->num_chipselect = num_cs; master->bus_num = pdev->id; master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LOOP; -- GitLab From 612762e82ae6058d69b4ce734598491bf030afe7 Mon Sep 17 00:00:00 2001 From: Andy Gross Date: Wed, 4 Mar 2015 12:02:05 +0200 Subject: [PATCH 03315/11651] spi: qup: Add DMA capabilities This patch adds DMA capabilities to the spi-qup driver. If DMA channels are present, the QUP will use DMA instead of block mode for transfers to/from SPI peripherals for transactions larger than the length of a block. Signed-off-by: Andy Gross Signed-off-by: Stanimir Varbanov Reviewed-by: Ivan T. Ivanov --- .../devicetree/bindings/spi/qcom,spi-qup.txt | 8 + drivers/spi/spi-qup.c | 336 ++++++++++++++++-- 2 files changed, 312 insertions(+), 32 deletions(-) diff --git a/Documentation/devicetree/bindings/spi/qcom,spi-qup.txt b/Documentation/devicetree/bindings/spi/qcom,spi-qup.txt index e2c88df2cc15..5c090771c016 100644 --- a/Documentation/devicetree/bindings/spi/qcom,spi-qup.txt +++ b/Documentation/devicetree/bindings/spi/qcom,spi-qup.txt @@ -33,6 +33,11 @@ Optional properties: nodes. If unspecified, a single SPI device without a chip select can be used. +- dmas: Two DMA channel specifiers following the convention outlined + in bindings/dma/dma.txt +- dma-names: Names for the dma channels, if present. There must be at + least one channel named "tx" for transmit and named "rx" for + receive. SPI slave nodes must be children of the SPI master node and can contain properties described in Documentation/devicetree/bindings/spi/spi-bus.txt @@ -51,6 +56,9 @@ Example: clocks = <&gcc GCC_BLSP2_QUP2_SPI_APPS_CLK>, <&gcc GCC_BLSP2_AHB_CLK>; clock-names = "core", "iface"; + dmas = <&blsp1_bam 13>, <&blsp1_bam 12>; + dma-names = "rx", "tx"; + pinctrl-names = "default"; pinctrl-0 = <&spi8_default>; diff --git a/drivers/spi/spi-qup.c b/drivers/spi/spi-qup.c index ff9cdbdb6672..4b5fc4d67b6e 100644 --- a/drivers/spi/spi-qup.c +++ b/drivers/spi/spi-qup.c @@ -22,6 +22,8 @@ #include #include #include +#include +#include #define QUP_CONFIG 0x0000 #define QUP_STATE 0x0004 @@ -116,6 +118,8 @@ #define SPI_NUM_CHIPSELECTS 4 +#define SPI_MAX_DMA_XFER (SZ_64K - 64) + /* high speed mode is when bus rate is greater then 26MHz */ #define SPI_HS_MIN_RATE 26000000 #define SPI_MAX_RATE 50000000 @@ -140,9 +144,14 @@ struct spi_qup { struct completion done; int error; int w_size; /* bytes per SPI word */ + int n_words; int tx_bytes; int rx_bytes; int qup_v1; + + int use_dma; + struct dma_slave_config rx_conf; + struct dma_slave_config tx_conf; }; @@ -198,7 +207,6 @@ static int spi_qup_set_state(struct spi_qup *controller, u32 state) return 0; } - static void spi_qup_fifo_read(struct spi_qup *controller, struct spi_transfer *xfer) { @@ -266,6 +274,107 @@ static void spi_qup_fifo_write(struct spi_qup *controller, } } +static void spi_qup_dma_done(void *data) +{ + struct spi_qup *qup = data; + + complete(&qup->done); +} + +static int spi_qup_prep_sg(struct spi_master *master, struct spi_transfer *xfer, + enum dma_transfer_direction dir, + dma_async_tx_callback callback) +{ + struct spi_qup *qup = spi_master_get_devdata(master); + unsigned long flags = DMA_PREP_INTERRUPT | DMA_PREP_FENCE; + struct dma_async_tx_descriptor *desc; + struct scatterlist *sgl; + struct dma_chan *chan; + dma_cookie_t cookie; + unsigned int nents; + + if (dir == DMA_MEM_TO_DEV) { + chan = master->dma_tx; + nents = xfer->tx_sg.nents; + sgl = xfer->tx_sg.sgl; + } else { + chan = master->dma_rx; + nents = xfer->rx_sg.nents; + sgl = xfer->rx_sg.sgl; + } + + desc = dmaengine_prep_slave_sg(chan, sgl, nents, dir, flags); + if (!desc) + return -EINVAL; + + desc->callback = callback; + desc->callback_param = qup; + + cookie = dmaengine_submit(desc); + + return dma_submit_error(cookie); +} + +static void spi_qup_dma_terminate(struct spi_master *master, + struct spi_transfer *xfer) +{ + if (xfer->tx_buf) + dmaengine_terminate_all(master->dma_tx); + if (xfer->rx_buf) + dmaengine_terminate_all(master->dma_rx); +} + +static int spi_qup_do_dma(struct spi_master *master, struct spi_transfer *xfer) +{ + dma_async_tx_callback rx_done = NULL, tx_done = NULL; + int ret; + + if (xfer->rx_buf) + rx_done = spi_qup_dma_done; + else if (xfer->tx_buf) + tx_done = spi_qup_dma_done; + + if (xfer->rx_buf) { + ret = spi_qup_prep_sg(master, xfer, DMA_DEV_TO_MEM, rx_done); + if (ret) + return ret; + + dma_async_issue_pending(master->dma_rx); + } + + if (xfer->tx_buf) { + ret = spi_qup_prep_sg(master, xfer, DMA_MEM_TO_DEV, tx_done); + if (ret) + return ret; + + dma_async_issue_pending(master->dma_tx); + } + + return 0; +} + +static int spi_qup_do_pio(struct spi_master *master, struct spi_transfer *xfer) +{ + struct spi_qup *qup = spi_master_get_devdata(master); + int ret; + + ret = spi_qup_set_state(qup, QUP_STATE_RUN); + if (ret) { + dev_warn(qup->dev, "cannot set RUN state\n"); + return ret; + } + + ret = spi_qup_set_state(qup, QUP_STATE_PAUSE); + if (ret) { + dev_warn(qup->dev, "cannot set PAUSE state\n"); + return ret; + } + + spi_qup_fifo_write(qup, xfer); + + return 0; +} + static irqreturn_t spi_qup_qup_irq(int irq, void *dev_id) { struct spi_qup *controller = dev_id; @@ -315,11 +424,13 @@ static irqreturn_t spi_qup_qup_irq(int irq, void *dev_id) error = -EIO; } - if (opflags & QUP_OP_IN_SERVICE_FLAG) - spi_qup_fifo_read(controller, xfer); + if (!controller->use_dma) { + if (opflags & QUP_OP_IN_SERVICE_FLAG) + spi_qup_fifo_read(controller, xfer); - if (opflags & QUP_OP_OUT_SERVICE_FLAG) - spi_qup_fifo_write(controller, xfer); + if (opflags & QUP_OP_OUT_SERVICE_FLAG) + spi_qup_fifo_write(controller, xfer); + } spin_lock_irqsave(&controller->lock, flags); controller->error = error; @@ -332,13 +443,35 @@ static irqreturn_t spi_qup_qup_irq(int irq, void *dev_id) return IRQ_HANDLED; } +static u32 +spi_qup_get_mode(struct spi_master *master, struct spi_transfer *xfer) +{ + struct spi_qup *qup = spi_master_get_devdata(master); + u32 mode; + + qup->w_size = 4; + + if (xfer->bits_per_word <= 8) + qup->w_size = 1; + else if (xfer->bits_per_word <= 16) + qup->w_size = 2; + + qup->n_words = xfer->len / qup->w_size; + + if (qup->n_words <= (qup->in_fifo_sz / sizeof(u32))) + mode = QUP_IO_M_MODE_FIFO; + else + mode = QUP_IO_M_MODE_BLOCK; + + return mode; +} /* set clock freq ... bits per word */ static int spi_qup_io_config(struct spi_device *spi, struct spi_transfer *xfer) { struct spi_qup *controller = spi_master_get_devdata(spi->master); u32 config, iomode, mode, control; - int ret, n_words, w_size; + int ret, n_words; if (spi->mode & SPI_LOOP && xfer->len > controller->in_fifo_sz) { dev_err(controller->dev, "too big size for loopback %d > %d\n", @@ -358,35 +491,54 @@ static int spi_qup_io_config(struct spi_device *spi, struct spi_transfer *xfer) return -EIO; } - w_size = 4; - if (xfer->bits_per_word <= 8) - w_size = 1; - else if (xfer->bits_per_word <= 16) - w_size = 2; - - n_words = xfer->len / w_size; - controller->w_size = w_size; + mode = spi_qup_get_mode(spi->master, xfer); + n_words = controller->n_words; - if (n_words <= (controller->in_fifo_sz / sizeof(u32))) { - mode = QUP_IO_M_MODE_FIFO; + if (mode == QUP_IO_M_MODE_FIFO) { writel_relaxed(n_words, controller->base + QUP_MX_READ_CNT); writel_relaxed(n_words, controller->base + QUP_MX_WRITE_CNT); /* must be zero for FIFO */ writel_relaxed(0, controller->base + QUP_MX_INPUT_CNT); writel_relaxed(0, controller->base + QUP_MX_OUTPUT_CNT); - } else { - mode = QUP_IO_M_MODE_BLOCK; + } else if (!controller->use_dma) { writel_relaxed(n_words, controller->base + QUP_MX_INPUT_CNT); writel_relaxed(n_words, controller->base + QUP_MX_OUTPUT_CNT); /* must be zero for BLOCK and BAM */ writel_relaxed(0, controller->base + QUP_MX_READ_CNT); writel_relaxed(0, controller->base + QUP_MX_WRITE_CNT); + } else { + mode = QUP_IO_M_MODE_BAM; + writel_relaxed(0, controller->base + QUP_MX_READ_CNT); + writel_relaxed(0, controller->base + QUP_MX_WRITE_CNT); + + if (!controller->qup_v1) { + void __iomem *input_cnt; + + input_cnt = controller->base + QUP_MX_INPUT_CNT; + /* + * for DMA transfers, both QUP_MX_INPUT_CNT and + * QUP_MX_OUTPUT_CNT must be zero to all cases but one. + * That case is a non-balanced transfer when there is + * only a rx_buf. + */ + if (xfer->tx_buf) + writel_relaxed(0, input_cnt); + else + writel_relaxed(n_words, input_cnt); + + writel_relaxed(0, controller->base + QUP_MX_OUTPUT_CNT); + } } iomode = readl_relaxed(controller->base + QUP_IO_M_MODES); /* Set input and output transfer mode */ iomode &= ~(QUP_IO_M_INPUT_MODE_MASK | QUP_IO_M_OUTPUT_MODE_MASK); - iomode &= ~(QUP_IO_M_PACK_EN | QUP_IO_M_UNPACK_EN); + + if (!controller->use_dma) + iomode &= ~(QUP_IO_M_PACK_EN | QUP_IO_M_UNPACK_EN); + else + iomode |= QUP_IO_M_PACK_EN | QUP_IO_M_UNPACK_EN; + iomode |= (mode << QUP_IO_M_OUTPUT_MODE_MASK_SHIFT); iomode |= (mode << QUP_IO_M_INPUT_MODE_MASK_SHIFT); @@ -428,11 +580,31 @@ static int spi_qup_io_config(struct spi_device *spi, struct spi_transfer *xfer) config &= ~(QUP_CONFIG_NO_INPUT | QUP_CONFIG_NO_OUTPUT | QUP_CONFIG_N); config |= xfer->bits_per_word - 1; config |= QUP_CONFIG_SPI_MODE; + + if (controller->use_dma) { + if (!xfer->tx_buf) + config |= QUP_CONFIG_NO_OUTPUT; + if (!xfer->rx_buf) + config |= QUP_CONFIG_NO_INPUT; + } + writel_relaxed(config, controller->base + QUP_CONFIG); /* only write to OPERATIONAL_MASK when register is present */ - if (!controller->qup_v1) - writel_relaxed(0, controller->base + QUP_OPERATIONAL_MASK); + if (!controller->qup_v1) { + u32 mask = 0; + + /* + * mask INPUT and OUTPUT service flags to prevent IRQs on FIFO + * status change in BAM mode + */ + + if (mode == QUP_IO_M_MODE_BAM) + mask = QUP_OP_IN_SERVICE_FLAG | QUP_OP_OUT_SERVICE_FLAG; + + writel_relaxed(mask, controller->base + QUP_OPERATIONAL_MASK); + } + return 0; } @@ -461,17 +633,13 @@ static int spi_qup_transfer_one(struct spi_master *master, controller->tx_bytes = 0; spin_unlock_irqrestore(&controller->lock, flags); - if (spi_qup_set_state(controller, QUP_STATE_RUN)) { - dev_warn(controller->dev, "cannot set RUN state\n"); - goto exit; - } + if (controller->use_dma) + ret = spi_qup_do_dma(master, xfer); + else + ret = spi_qup_do_pio(master, xfer); - if (spi_qup_set_state(controller, QUP_STATE_PAUSE)) { - dev_warn(controller->dev, "cannot set PAUSE state\n"); + if (ret) goto exit; - } - - spi_qup_fifo_write(controller, xfer); if (spi_qup_set_state(controller, QUP_STATE_RUN)) { dev_warn(controller->dev, "cannot set EXECUTE state\n"); @@ -480,6 +648,7 @@ static int spi_qup_transfer_one(struct spi_master *master, if (!wait_for_completion_timeout(&controller->done, timeout)) ret = -ETIMEDOUT; + exit: spi_qup_set_state(controller, QUP_STATE_RESET); spin_lock_irqsave(&controller->lock, flags); @@ -487,6 +656,97 @@ exit: if (!ret) ret = controller->error; spin_unlock_irqrestore(&controller->lock, flags); + + if (ret && controller->use_dma) + spi_qup_dma_terminate(master, xfer); + + return ret; +} + +static bool spi_qup_can_dma(struct spi_master *master, struct spi_device *spi, + struct spi_transfer *xfer) +{ + struct spi_qup *qup = spi_master_get_devdata(master); + size_t dma_align = dma_get_cache_alignment(); + u32 mode; + + qup->use_dma = 0; + + if (xfer->rx_buf && (xfer->len % qup->in_blk_sz || + IS_ERR_OR_NULL(master->dma_rx) || + !IS_ALIGNED((size_t)xfer->rx_buf, dma_align))) + return false; + + if (xfer->tx_buf && (xfer->len % qup->out_blk_sz || + IS_ERR_OR_NULL(master->dma_tx) || + !IS_ALIGNED((size_t)xfer->tx_buf, dma_align))) + return false; + + mode = spi_qup_get_mode(master, xfer); + if (mode == QUP_IO_M_MODE_FIFO) + return false; + + qup->use_dma = 1; + + return true; +} + +static void spi_qup_release_dma(struct spi_master *master) +{ + if (!IS_ERR_OR_NULL(master->dma_rx)) + dma_release_channel(master->dma_rx); + if (!IS_ERR_OR_NULL(master->dma_tx)) + dma_release_channel(master->dma_tx); +} + +static int spi_qup_init_dma(struct spi_master *master, resource_size_t base) +{ + struct spi_qup *spi = spi_master_get_devdata(master); + struct dma_slave_config *rx_conf = &spi->rx_conf, + *tx_conf = &spi->tx_conf; + struct device *dev = spi->dev; + int ret; + + /* allocate dma resources, if available */ + master->dma_rx = dma_request_slave_channel_reason(dev, "rx"); + if (IS_ERR(master->dma_rx)) + return PTR_ERR(master->dma_rx); + + master->dma_tx = dma_request_slave_channel_reason(dev, "tx"); + if (IS_ERR(master->dma_tx)) { + ret = PTR_ERR(master->dma_tx); + goto err_tx; + } + + /* set DMA parameters */ + rx_conf->direction = DMA_DEV_TO_MEM; + rx_conf->device_fc = 1; + rx_conf->src_addr = base + QUP_INPUT_FIFO; + rx_conf->src_maxburst = spi->in_blk_sz; + + tx_conf->direction = DMA_MEM_TO_DEV; + tx_conf->device_fc = 1; + tx_conf->dst_addr = base + QUP_OUTPUT_FIFO; + tx_conf->dst_maxburst = spi->out_blk_sz; + + ret = dmaengine_slave_config(master->dma_rx, rx_conf); + if (ret) { + dev_err(dev, "failed to configure RX channel\n"); + goto err; + } + + ret = dmaengine_slave_config(master->dma_tx, tx_conf); + if (ret) { + dev_err(dev, "failed to configure TX channel\n"); + goto err; + } + + return 0; + +err: + dma_release_channel(master->dma_tx); +err_tx: + dma_release_channel(master->dma_rx); return ret; } @@ -562,6 +822,8 @@ static int spi_qup_probe(struct platform_device *pdev) master->transfer_one = spi_qup_transfer_one; master->dev.of_node = pdev->dev.of_node; master->auto_runtime_pm = true; + master->dma_alignment = dma_get_cache_alignment(); + master->max_dma_len = SPI_MAX_DMA_XFER; platform_set_drvdata(pdev, master); @@ -573,6 +835,12 @@ static int spi_qup_probe(struct platform_device *pdev) controller->cclk = cclk; controller->irq = irq; + ret = spi_qup_init_dma(master, res->start); + if (ret == -EPROBE_DEFER) + goto error; + else if (!ret) + master->can_dma = spi_qup_can_dma; + /* set v1 flag if device is version 1 */ if (of_device_is_compatible(dev->of_node, "qcom,spi-qup-v1.1.1")) controller->qup_v1 = 1; @@ -609,7 +877,7 @@ static int spi_qup_probe(struct platform_device *pdev) ret = spi_qup_set_state(controller, QUP_STATE_RESET); if (ret) { dev_err(dev, "cannot set RESET state\n"); - goto error; + goto error_dma; } writel_relaxed(0, base + QUP_OPERATIONAL); @@ -633,7 +901,7 @@ static int spi_qup_probe(struct platform_device *pdev) ret = devm_request_irq(dev, irq, spi_qup_qup_irq, IRQF_TRIGGER_HIGH, pdev->name, controller); if (ret) - goto error; + goto error_dma; pm_runtime_set_autosuspend_delay(dev, MSEC_PER_SEC); pm_runtime_use_autosuspend(dev); @@ -648,6 +916,8 @@ static int spi_qup_probe(struct platform_device *pdev) disable_pm: pm_runtime_disable(&pdev->dev); +error_dma: + spi_qup_release_dma(master); error: clk_disable_unprepare(cclk); clk_disable_unprepare(iclk); @@ -739,6 +1009,8 @@ static int spi_qup_remove(struct platform_device *pdev) if (ret) return ret; + spi_qup_release_dma(master); + clk_disable_unprepare(controller->cclk); clk_disable_unprepare(controller->iclk); -- GitLab From 854d2f241d71f6ca08ccde30e6c7c2e403363e52 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 6 Mar 2015 14:42:01 +0200 Subject: [PATCH 03316/11651] spi: dw-mid: clear BUSY flag fist and test other one The logic of DMA completion is broken now since test_and_clear_bit() never returns the other bit is set. It means condition are always false and we have spi_finalize_current_transfer() called per each DMA completion which is wrong. The patch fixes logic by clearing BUSY bit first and then check for the other one. Fixes: 30c8eb52cc4a (spi: dw-mid: split rx and tx callbacks when DMA) Signed-off-by: Andy Shevchenko Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- drivers/spi/spi-dw-mid.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi-dw-mid.c b/drivers/spi/spi-dw-mid.c index 3ce39d10fafb..4f8c798e0633 100644 --- a/drivers/spi/spi-dw-mid.c +++ b/drivers/spi/spi-dw-mid.c @@ -108,7 +108,8 @@ static void dw_spi_dma_tx_done(void *arg) { struct dw_spi *dws = arg; - if (test_and_clear_bit(TX_BUSY, &dws->dma_chan_busy) & BIT(RX_BUSY)) + clear_bit(TX_BUSY, &dws->dma_chan_busy); + if (test_bit(RX_BUSY, &dws->dma_chan_busy)) return; dw_spi_xfer_done(dws); } @@ -156,7 +157,8 @@ static void dw_spi_dma_rx_done(void *arg) { struct dw_spi *dws = arg; - if (test_and_clear_bit(RX_BUSY, &dws->dma_chan_busy) & BIT(TX_BUSY)) + clear_bit(RX_BUSY, &dws->dma_chan_busy); + if (test_bit(TX_BUSY, &dws->dma_chan_busy)) return; dw_spi_xfer_done(dws); } -- GitLab From 37a2973a058e08f8dcccb265d90176e6b6b55191 Mon Sep 17 00:00:00 2001 From: Shannon Nelson Date: Fri, 27 Feb 2015 09:15:19 +0000 Subject: [PATCH 03317/11651] i40e/i40evf: Refactor i40e_debug_aq and make some functions static A sparse complaint in i40e_debug_aq in a funky buffer write goes away by straightening out the code out to something less convoluted. Also fix some other sparse warnings while we are at it, making some functions static and using NULL instead of 0. Change-ID: I93907534fe1f1f675830774b3d14ecf1c6ffc9a0 Signed-off-by: Shannon Nelson Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_common.c | 50 +++++++++---------- drivers/net/ethernet/intel/i40e/i40e_main.c | 2 +- drivers/net/ethernet/intel/i40e/i40e_nvm.c | 8 +-- drivers/net/ethernet/intel/i40e/i40e_txrx.c | 2 +- .../net/ethernet/intel/i40evf/i40e_common.c | 44 ++++++++-------- drivers/net/ethernet/intel/i40evf/i40e_txrx.c | 2 +- 6 files changed, 54 insertions(+), 54 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c index 10f9451339ed..fc4817ab2bb3 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_common.c +++ b/drivers/net/ethernet/intel/i40e/i40e_common.c @@ -85,9 +85,8 @@ void i40e_debug_aq(struct i40e_hw *hw, enum i40e_debug_mask mask, void *desc, { struct i40e_aq_desc *aq_desc = (struct i40e_aq_desc *)desc; u16 len = le16_to_cpu(aq_desc->datalen); - u8 *aq_buffer = (u8 *)buffer; - u32 data[4]; - u32 i = 0; + u8 *buf = (u8 *)buffer; + u16 i = 0; if ((!(mask & hw->debug_mask)) || (desc == NULL)) return; @@ -109,29 +108,30 @@ void i40e_debug_aq(struct i40e_hw *hw, enum i40e_debug_mask mask, void *desc, le32_to_cpu(aq_desc->params.external.addr_low)); if ((buffer != NULL) && (aq_desc->datalen != 0)) { - memset(data, 0, sizeof(data)); i40e_debug(hw, mask, "AQ CMD Buffer:\n"); if (buf_len < len) len = buf_len; - for (i = 0; i < len; i++) { - data[((i % 16) / 4)] |= - ((u32)aq_buffer[i]) << (8 * (i % 4)); - if ((i % 16) == 15) { - i40e_debug(hw, mask, - "\t0x%04X %08X %08X %08X %08X\n", - i - 15, le32_to_cpu(data[0]), - le32_to_cpu(data[1]), - le32_to_cpu(data[2]), - le32_to_cpu(data[3])); - memset(data, 0, sizeof(data)); - } + /* write the full 16-byte chunks */ + for (i = 0; i < (len - 16); i += 16) + i40e_debug(hw, mask, + "\t0x%04X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", + i, buf[i], buf[i + 1], buf[i + 2], + buf[i + 3], buf[i + 4], buf[i + 5], + buf[i + 6], buf[i + 7], buf[i + 8], + buf[i + 9], buf[i + 10], buf[i + 11], + buf[i + 12], buf[i + 13], buf[i + 14], + buf[i + 15]); + /* write whatever's left over without overrunning the buffer */ + if (i < len) { + char d_buf[80]; + int j = 0; + + memset(d_buf, 0, sizeof(d_buf)); + j += sprintf(d_buf, "\t0x%04X ", i); + while (i < len) + j += sprintf(&d_buf[j], " %02X", buf[i++]); + i40e_debug(hw, mask, "%s\n", d_buf); } - if ((i % 16) != 0) - i40e_debug(hw, mask, "\t0x%04X %08X %08X %08X %08X\n", - i - (i % 16), le32_to_cpu(data[0]), - le32_to_cpu(data[1]), - le32_to_cpu(data[2]), - le32_to_cpu(data[3])); } } @@ -3409,9 +3409,9 @@ i40e_status i40e_aq_add_rem_control_packet_filter(struct i40e_hw *hw, * is not passed then only register at 'reg_addr0' is read. * **/ -i40e_status i40e_aq_alternate_read(struct i40e_hw *hw, - u32 reg_addr0, u32 *reg_val0, - u32 reg_addr1, u32 *reg_val1) +static i40e_status i40e_aq_alternate_read(struct i40e_hw *hw, + u32 reg_addr0, u32 *reg_val0, + u32 reg_addr1, u32 *reg_val1) { struct i40e_aq_desc desc; struct i40e_aqc_alternate_write *cmd_resp = diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 0937cf325e00..02672c31119f 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -7923,7 +7923,7 @@ static int i40e_ndo_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq, } #endif /* HAVE_BRIDGE_ATTRIBS */ -const struct net_device_ops i40e_netdev_ops = { +static const struct net_device_ops i40e_netdev_ops = { .ndo_open = i40e_open, .ndo_stop = i40e_close, .ndo_start_xmit = i40e_lan_xmit_frame, diff --git a/drivers/net/ethernet/intel/i40e/i40e_nvm.c b/drivers/net/ethernet/intel/i40e/i40e_nvm.c index 039018abad4a..89bd5b4d79cf 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_nvm.c +++ b/drivers/net/ethernet/intel/i40e/i40e_nvm.c @@ -171,8 +171,8 @@ static i40e_status i40e_poll_sr_srctl_done_bit(struct i40e_hw *hw) * * Reads one 16 bit word from the Shadow RAM using the GLNVM_SRCTL register. **/ -i40e_status i40e_read_nvm_word_srctl(struct i40e_hw *hw, u16 offset, - u16 *data) +static i40e_status i40e_read_nvm_word_srctl(struct i40e_hw *hw, u16 offset, + u16 *data) { i40e_status ret_code = I40E_ERR_TIMEOUT; u32 sr_reg; @@ -237,8 +237,8 @@ i40e_status i40e_read_nvm_word(struct i40e_hw *hw, u16 offset, * method. The buffer read is preceded by the NVM ownership take * and followed by the release. **/ -i40e_status i40e_read_nvm_buffer_srctl(struct i40e_hw *hw, u16 offset, - u16 *words, u16 *data) +static i40e_status i40e_read_nvm_buffer_srctl(struct i40e_hw *hw, u16 offset, + u16 *words, u16 *data) { i40e_status ret_code = 0; u16 index, word; diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index d4b4aa7c204e..7327952b292f 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -1044,7 +1044,7 @@ void i40e_clean_rx_ring(struct i40e_ring *rx_ring) for (i = 0; i < rx_ring->count; i++) { rx_bi = &rx_ring->rx_bi[i]; rx_bi->dma = 0; - rx_bi->hdr_buf = 0; + rx_bi->hdr_buf = NULL; } } } diff --git a/drivers/net/ethernet/intel/i40evf/i40e_common.c b/drivers/net/ethernet/intel/i40evf/i40e_common.c index 0335b3f08cc1..f07b9ff2b823 100644 --- a/drivers/net/ethernet/intel/i40evf/i40e_common.c +++ b/drivers/net/ethernet/intel/i40evf/i40e_common.c @@ -85,9 +85,8 @@ void i40evf_debug_aq(struct i40e_hw *hw, enum i40e_debug_mask mask, void *desc, { struct i40e_aq_desc *aq_desc = (struct i40e_aq_desc *)desc; u16 len = le16_to_cpu(aq_desc->datalen); - u8 *aq_buffer = (u8 *)buffer; - u32 data[4]; - u32 i = 0; + u8 *buf = (u8 *)buffer; + u16 i = 0; if ((!(mask & hw->debug_mask)) || (desc == NULL)) return; @@ -109,29 +108,30 @@ void i40evf_debug_aq(struct i40e_hw *hw, enum i40e_debug_mask mask, void *desc, le32_to_cpu(aq_desc->params.external.addr_low)); if ((buffer != NULL) && (aq_desc->datalen != 0)) { - memset(data, 0, sizeof(data)); i40e_debug(hw, mask, "AQ CMD Buffer:\n"); if (buf_len < len) len = buf_len; - for (i = 0; i < len; i++) { - data[((i % 16) / 4)] |= - ((u32)aq_buffer[i]) << (8 * (i % 4)); - if ((i % 16) == 15) { - i40e_debug(hw, mask, - "\t0x%04X %08X %08X %08X %08X\n", - i - 15, le32_to_cpu(data[0]), - le32_to_cpu(data[1]), - le32_to_cpu(data[2]), - le32_to_cpu(data[3])); - memset(data, 0, sizeof(data)); - } + /* write the full 16-byte chunks */ + for (i = 0; i < (len - 16); i += 16) + i40e_debug(hw, mask, + "\t0x%04X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", + i, buf[i], buf[i + 1], buf[i + 2], + buf[i + 3], buf[i + 4], buf[i + 5], + buf[i + 6], buf[i + 7], buf[i + 8], + buf[i + 9], buf[i + 10], buf[i + 11], + buf[i + 12], buf[i + 13], buf[i + 14], + buf[i + 15]); + /* write whatever's left over without overrunning the buffer */ + if (i < len) { + char d_buf[80]; + int j = 0; + + memset(d_buf, 0, sizeof(d_buf)); + j += sprintf(d_buf, "\t0x%04X ", i); + while (i < len) + j += sprintf(&d_buf[j], " %02X", buf[i++]); + i40e_debug(hw, mask, "%s\n", d_buf); } - if ((i % 16) != 0) - i40e_debug(hw, mask, "\t0x%04X %08X %08X %08X %08X\n", - i - (i % 16), le32_to_cpu(data[0]), - le32_to_cpu(data[1]), - le32_to_cpu(data[2]), - le32_to_cpu(data[3])); } } diff --git a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c index fe13ad2def46..021b0d4d8a35 100644 --- a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c @@ -542,7 +542,7 @@ void i40evf_clean_rx_ring(struct i40e_ring *rx_ring) for (i = 0; i < rx_ring->count; i++) { rx_bi = &rx_ring->rx_bi[i]; rx_bi->dma = 0; - rx_bi->hdr_buf = 0; + rx_bi->hdr_buf = NULL; } } } -- GitLab From d6d83c1b3e471124bde4ea57bb7bf278bb931553 Mon Sep 17 00:00:00 2001 From: Catherine Sullivan Date: Fri, 27 Feb 2015 09:15:20 +0000 Subject: [PATCH 03318/11651] i40e: Remove duplicate code This series of code was repeated twice, remove one of them. Signed-off-by: Catherine Sullivan Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_main.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 02672c31119f..0e4312f6e096 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -9238,14 +9238,6 @@ static int i40e_setup_pf_switch(struct i40e_pf *pf, bool reinit) i40e_aq_get_link_info(&pf->hw, true, NULL, NULL); i40e_link_event(pf); - /* Initialize user-specific link properties */ - pf->fc_autoneg_status = ((pf->hw.phy.link_info.an_info & - I40E_AQ_AN_COMPLETED) ? true : false); - - /* fill in link information and enable LSE reporting */ - i40e_aq_get_link_info(&pf->hw, true, NULL, NULL); - i40e_link_event(pf); - /* Initialize user-specific link properties */ pf->fc_autoneg_status = ((pf->hw.phy.link_info.an_info & I40E_AQ_AN_COMPLETED) ? true : false); -- GitLab From ef0620774f403c6f226ec22857f5df9217d603cd Mon Sep 17 00:00:00 2001 From: Kamil Krawczyk Date: Fri, 27 Feb 2015 09:15:21 +0000 Subject: [PATCH 03319/11651] i40e: Remove unneeded conversion Remove LE16 to CPU endianes conversion from i40e_read_nvm_word_srctl function, as it's already done by register read function. Change-ID: I739f0f20a9b8e18223e54c0ca5443e63d75da878 Signed-off-by: Kamil Krawczyk Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_nvm.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_nvm.c b/drivers/net/ethernet/intel/i40e/i40e_nvm.c index 89bd5b4d79cf..e49acd2accd3 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_nvm.c +++ b/drivers/net/ethernet/intel/i40e/i40e_nvm.c @@ -200,7 +200,6 @@ static i40e_status i40e_read_nvm_word_srctl(struct i40e_hw *hw, u16 offset, *data = (u16)((sr_reg & I40E_GLNVM_SRDATA_RDDATA_MASK) >> I40E_GLNVM_SRDATA_RDDATA_SHIFT); - *data = le16_to_cpu(*data); } } if (ret_code) -- GitLab From 71e6163a4ca274fcf63dd94bbe3c1efca497589f Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Fri, 27 Feb 2015 09:15:22 +0000 Subject: [PATCH 03320/11651] i40e: store msg_enable in the right size The kernel returns a u32 for netif_msg_init, and we were storing it in a u16. Fix the width of the datatype. Change-ID: I4b23326e5707c91cd59325c5a1ccb2ba7a3974fc Signed-off-by: Jesse Brandeburg Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h index ce3fbb87544e..4fb258ae83c6 100644 --- a/drivers/net/ethernet/intel/i40e/i40e.h +++ b/drivers/net/ethernet/intel/i40e/i40e.h @@ -276,7 +276,7 @@ struct i40e_pf { enum i40e_interrupt_policy int_policy; u16 rx_itr_default; u16 tx_itr_default; - u16 msg_enable; + u32 msg_enable; char int_name[I40E_INT_NAME_STR_LEN]; u16 adminq_work_limit; /* num of admin receive queue desc to process */ unsigned long service_timer_period; -- GitLab From 7b115dd06dd5e06a85324c2cdebb59c2cb17772f Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Fri, 27 Feb 2015 09:15:23 +0000 Subject: [PATCH 03321/11651] i40e: clean up debug_read_register There were some additional spaces and strange (double swapping) logic in this function that I started looking at because sparse was warning. This fixes the sparse warning and fixes up the other issues. Change-ID: I72a91a4197cd45921602649040e6bd25e5f17c0a Signed-off-by: Jesse Brandeburg Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_common.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c index fc4817ab2bb3..fb78bdd2eb95 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_common.c +++ b/drivers/net/ethernet/intel/i40e/i40e_common.c @@ -2126,7 +2126,7 @@ i40e_status i40e_aq_send_msg_to_vf(struct i40e_hw *hw, u16 vfid, * Read the register using the admin queue commands **/ i40e_status i40e_aq_debug_read_register(struct i40e_hw *hw, - u32 reg_addr, u64 *reg_val, + u32 reg_addr, u64 *reg_val, struct i40e_asq_cmd_details *cmd_details) { struct i40e_aq_desc desc; @@ -2137,17 +2137,15 @@ i40e_status i40e_aq_debug_read_register(struct i40e_hw *hw, if (reg_val == NULL) return I40E_ERR_PARAM; - i40e_fill_default_direct_cmd_desc(&desc, - i40e_aqc_opc_debug_read_reg); + i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_debug_read_reg); cmd_resp->address = cpu_to_le32(reg_addr); status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details); if (!status) { - *reg_val = ((u64)cmd_resp->value_high << 32) | - (u64)cmd_resp->value_low; - *reg_val = le64_to_cpu(*reg_val); + *reg_val = ((u64)le32_to_cpu(cmd_resp->value_high) << 32) | + (u64)le32_to_cpu(cmd_resp->value_low); } return status; -- GitLab From 1e200e4a5744b727f64880855689bdb1b2502d43 Mon Sep 17 00:00:00 2001 From: Shannon Nelson Date: Fri, 27 Feb 2015 09:15:24 +0000 Subject: [PATCH 03322/11651] i40e: rework vector reservation The initial problem solved here is that the vector allocation was trying too hard to save vectors for VMDq, to the point of not giving the PF enough when in a tight situation such as an NPAR partition. This change makes sure that the PF will get all the queues and vectors it wants to fill out its destiny. Essentially, nothing is specially reserved for VMDq, it simply gets whatever is left after the PF, FCoE, and FD sideband get what they want. Additionally, the calculations for the reservations were harder to follow than necessary, so I've made it more straight forward. Change-ID: I99b384f104535b686c690b8ef0a787559485c8d4 Signed-off-by: Shannon Nelson Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_main.c | 75 +++++++++++++++------ 1 file changed, 56 insertions(+), 19 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 0e4312f6e096..1ab5b5f3d107 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -1541,7 +1541,7 @@ static void i40e_vsi_setup_queue_map(struct i40e_vsi *vsi, vsi->tc_config.tc_info[i].qoffset = offset; vsi->tc_config.tc_info[i].qcount = qcount; - /* find the power-of-2 of the number of queue pairs */ + /* find the next higher power-of-2 of num queue pairs */ num_qps = qcount; pow = 0; while (num_qps && ((1 << pow) < qcount)) { @@ -6940,7 +6940,7 @@ static int i40e_reserve_msix_vectors(struct i40e_pf *pf, int vectors) static int i40e_init_msix(struct i40e_pf *pf) { struct i40e_hw *hw = &pf->hw; - int other_vecs = 0; + int vectors_left; int v_budget, i; int v_actual; @@ -6964,25 +6964,62 @@ static int i40e_init_msix(struct i40e_pf *pf) * If we can't get what we want, we'll simplify to nearly nothing * and try again. If that still fails, we punt. */ - pf->num_lan_msix = min_t(int, num_online_cpus(), - hw->func_caps.num_msix_vectors); - pf->num_vmdq_msix = pf->num_vmdq_qps; - other_vecs = 1; - other_vecs += (pf->num_vmdq_vsis * pf->num_vmdq_msix); - if (pf->flags & I40E_FLAG_FD_SB_ENABLED) - other_vecs++; - - /* Scale down if necessary, and the rings will share vectors */ - pf->num_lan_msix = min_t(int, pf->num_lan_msix, - (hw->func_caps.num_msix_vectors - other_vecs)); - v_budget = pf->num_lan_msix + other_vecs; + vectors_left = hw->func_caps.num_msix_vectors; + v_budget = 0; + + /* reserve one vector for miscellaneous handler */ + if (vectors_left) { + v_budget++; + vectors_left--; + } + + /* reserve vectors for the main PF traffic queues */ + pf->num_lan_msix = min_t(int, num_online_cpus(), vectors_left); + vectors_left -= pf->num_lan_msix; + v_budget += pf->num_lan_msix; + + /* reserve one vector for sideband flow director */ + if (pf->flags & I40E_FLAG_FD_SB_ENABLED) { + if (vectors_left) { + v_budget++; + vectors_left--; + } else { + pf->flags &= ~I40E_FLAG_FD_SB_ENABLED; + } + } #ifdef I40E_FCOE + /* can we reserve enough for FCoE? */ if (pf->flags & I40E_FLAG_FCOE_ENABLED) { - pf->num_fcoe_msix = pf->num_fcoe_qps; + if (!vectors_left) + pf->num_fcoe_msix = 0; + else if (vectors_left >= pf->num_fcoe_qps) + pf->num_fcoe_msix = pf->num_fcoe_qps; + else + pf->num_fcoe_msix = 1; v_budget += pf->num_fcoe_msix; + vectors_left -= pf->num_fcoe_msix; } + #endif + /* any vectors left over go for VMDq support */ + if (pf->flags & I40E_FLAG_VMDQ_ENABLED) { + int vmdq_vecs_wanted = pf->num_vmdq_vsis * pf->num_vmdq_qps; + int vmdq_vecs = min_t(int, vectors_left, vmdq_vecs_wanted); + + /* if we're short on vectors for what's desired, we limit + * the queues per vmdq. If this is still more than are + * available, the user will need to change the number of + * queues/vectors used by the PF later with the ethtool + * channels command + */ + if (vmdq_vecs < vmdq_vecs_wanted) + pf->num_vmdq_qps = 1; + pf->num_vmdq_msix = pf->num_vmdq_qps; + + v_budget += vmdq_vecs; + vectors_left -= vmdq_vecs; + } pf->msix_entries = kcalloc(v_budget, sizeof(struct msix_entry), GFP_KERNEL); @@ -7028,6 +7065,8 @@ static int i40e_init_msix(struct i40e_pf *pf) /* Scale vector usage down */ pf->num_vmdq_msix = 1; /* force VMDqs to only one vector */ pf->num_vmdq_vsis = 1; + pf->num_vmdq_qps = 1; + pf->flags &= ~I40E_FLAG_FD_SB_ENABLED; /* partition out the remaining vectors */ switch (vec) { @@ -7053,10 +7092,8 @@ static int i40e_init_msix(struct i40e_pf *pf) vec--; } #endif - pf->num_lan_msix = min_t(int, (vec / 2), - pf->num_lan_qps); - pf->num_vmdq_vsis = min_t(int, (vec - pf->num_lan_msix), - I40E_DEFAULT_NUM_VMDQ_VSI); + /* give the rest to the PF */ + pf->num_lan_msix = min_t(int, vec, pf->num_lan_qps); break; } } -- GitLab From 386a0afa709931e0037bb2e812df62230e8af370 Mon Sep 17 00:00:00 2001 From: Akeem G Abodunrin Date: Fri, 27 Feb 2015 09:15:25 +0000 Subject: [PATCH 03323/11651] i40e: Move code to enable/disable Loopback to the main file Since changes made to enable or disable loopback for all VSIs, not only SR-IOV or PCIOV, then it became necessary to move the associated functions to main file - so that other non-SRIOV supported driver can take advantage of the changes. Change-ID: I59a49fd23a6136acda5e16f8d1e5ac7fd9c5fc05 Signed-off-by: Akeem G Abodunrin Signed-off-by: Jesse Brandeburg Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_main.c | 68 +++++++++++++++++++ .../ethernet/intel/i40e/i40e_virtchnl_pf.c | 68 ------------------- .../ethernet/intel/i40e/i40e_virtchnl_pf.h | 2 - 3 files changed, 68 insertions(+), 70 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 1ab5b5f3d107..e765bb37ef8c 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -5912,6 +5912,74 @@ static void i40e_verify_eeprom(struct i40e_pf *pf) } } +/** + * i40e_enable_pf_switch_lb + * @pf: pointer to the pf structure + * + * enable switch loop back or die - no point in a return value + **/ +static void i40e_enable_pf_switch_lb(struct i40e_pf *pf) +{ + struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi]; + struct i40e_vsi_context ctxt; + int aq_ret; + + ctxt.seid = pf->main_vsi_seid; + ctxt.pf_num = pf->hw.pf_id; + ctxt.vf_num = 0; + aq_ret = i40e_aq_get_vsi_params(&pf->hw, &ctxt, NULL); + if (aq_ret) { + dev_info(&pf->pdev->dev, + "%s couldn't get pf vsi config, err %d, aq_err %d\n", + __func__, aq_ret, pf->hw.aq.asq_last_status); + return; + } + ctxt.flags = I40E_AQ_VSI_TYPE_PF; + ctxt.info.valid_sections = cpu_to_le16(I40E_AQ_VSI_PROP_SWITCH_VALID); + ctxt.info.switch_id |= cpu_to_le16(I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB); + + aq_ret = i40e_aq_update_vsi_params(&vsi->back->hw, &ctxt, NULL); + if (aq_ret) { + dev_info(&pf->pdev->dev, + "%s: update vsi switch failed, aq_err=%d\n", + __func__, vsi->back->hw.aq.asq_last_status); + } +} + +/** + * i40e_disable_pf_switch_lb + * @pf: pointer to the pf structure + * + * disable switch loop back or die - no point in a return value + **/ +static void i40e_disable_pf_switch_lb(struct i40e_pf *pf) +{ + struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi]; + struct i40e_vsi_context ctxt; + int aq_ret; + + ctxt.seid = pf->main_vsi_seid; + ctxt.pf_num = pf->hw.pf_id; + ctxt.vf_num = 0; + aq_ret = i40e_aq_get_vsi_params(&pf->hw, &ctxt, NULL); + if (aq_ret) { + dev_info(&pf->pdev->dev, + "%s couldn't get pf vsi config, err %d, aq_err %d\n", + __func__, aq_ret, pf->hw.aq.asq_last_status); + return; + } + ctxt.flags = I40E_AQ_VSI_TYPE_PF; + ctxt.info.valid_sections = cpu_to_le16(I40E_AQ_VSI_PROP_SWITCH_VALID); + ctxt.info.switch_id &= ~cpu_to_le16(I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB); + + aq_ret = i40e_aq_update_vsi_params(&vsi->back->hw, &ctxt, NULL); + if (aq_ret) { + dev_info(&pf->pdev->dev, + "%s: update vsi switch failed, aq_err=%d\n", + __func__, vsi->back->hw.aq.asq_last_status); + } +} + /** * i40e_config_bridge_mode - Configure the HW bridge mode * @veb: pointer to the bridge instance diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c index 1d8b94d80a87..7cc635e4c2e4 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c @@ -709,74 +709,6 @@ complete_reset: clear_bit(__I40E_VF_DISABLE, &pf->state); } -/** - * i40e_enable_pf_switch_lb - * @pf: pointer to the pf structure - * - * enable switch loop back or die - no point in a return value - **/ -void i40e_enable_pf_switch_lb(struct i40e_pf *pf) -{ - struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi]; - struct i40e_vsi_context ctxt; - int aq_ret; - - ctxt.seid = pf->main_vsi_seid; - ctxt.pf_num = pf->hw.pf_id; - ctxt.vf_num = 0; - aq_ret = i40e_aq_get_vsi_params(&pf->hw, &ctxt, NULL); - if (aq_ret) { - dev_info(&pf->pdev->dev, - "%s couldn't get pf vsi config, err %d, aq_err %d\n", - __func__, aq_ret, pf->hw.aq.asq_last_status); - return; - } - ctxt.flags = I40E_AQ_VSI_TYPE_PF; - ctxt.info.valid_sections = cpu_to_le16(I40E_AQ_VSI_PROP_SWITCH_VALID); - ctxt.info.switch_id |= cpu_to_le16(I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB); - - aq_ret = i40e_aq_update_vsi_params(&vsi->back->hw, &ctxt, NULL); - if (aq_ret) { - dev_info(&pf->pdev->dev, - "%s: update vsi switch failed, aq_err=%d\n", - __func__, vsi->back->hw.aq.asq_last_status); - } -} - -/** - * i40e_disable_pf_switch_lb - * @pf: pointer to the pf structure - * - * disable switch loop back or die - no point in a return value - **/ -void i40e_disable_pf_switch_lb(struct i40e_pf *pf) -{ - struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi]; - struct i40e_vsi_context ctxt; - int aq_ret; - - ctxt.seid = pf->main_vsi_seid; - ctxt.pf_num = pf->hw.pf_id; - ctxt.vf_num = 0; - aq_ret = i40e_aq_get_vsi_params(&pf->hw, &ctxt, NULL); - if (aq_ret) { - dev_info(&pf->pdev->dev, - "%s couldn't get pf vsi config, err %d, aq_err %d\n", - __func__, aq_ret, pf->hw.aq.asq_last_status); - return; - } - ctxt.flags = I40E_AQ_VSI_TYPE_PF; - ctxt.info.valid_sections = cpu_to_le16(I40E_AQ_VSI_PROP_SWITCH_VALID); - ctxt.info.switch_id &= ~cpu_to_le16(I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB); - - aq_ret = i40e_aq_update_vsi_params(&vsi->back->hw, &ctxt, NULL); - if (aq_ret) { - dev_info(&pf->pdev->dev, - "%s: update vsi switch failed, aq_err=%d\n", - __func__, vsi->back->hw.aq.asq_last_status); - } -} - /** * i40e_free_vfs * @pf: pointer to the pf structure diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h index ef777a62e393..21db113a64fa 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h +++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h @@ -126,7 +126,5 @@ int i40e_ndo_set_vf_spoofchk(struct net_device *netdev, int vf_id, bool enable); void i40e_vc_notify_link_state(struct i40e_pf *pf); void i40e_vc_notify_reset(struct i40e_pf *pf); -void i40e_enable_pf_switch_lb(struct i40e_pf *pf); -void i40e_disable_pf_switch_lb(struct i40e_pf *pf); #endif /* _I40E_VIRTCHNL_PF_H_ */ -- GitLab From 58ce51753faa5287106e87b942e9563156595a31 Mon Sep 17 00:00:00 2001 From: Shannon Nelson Date: Fri, 27 Feb 2015 09:15:26 +0000 Subject: [PATCH 03324/11651] i40e: print port stats only on partition 1 Only print the port and veb stats if this is the first partition of a multiplexed port. Change-ID: I7ce0c323cdee5cfd2e54d8bea5b0b9102987e671 Signed-off-by: Shannon Nelson Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c index e045de133251..01c811c99ff7 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c @@ -1224,7 +1224,7 @@ static int i40e_get_sset_count(struct net_device *netdev, int sset) case ETH_SS_TEST: return I40E_TEST_LEN; case ETH_SS_STATS: - if (vsi == pf->vsi[pf->lan_vsi]) { + if (vsi == pf->vsi[pf->lan_vsi] && pf->hw.partition_id == 1) { int len = I40E_PF_STATS_LEN(netdev); if (pf->lan_veb != I40E_NO_VEB) @@ -1297,7 +1297,7 @@ static void i40e_get_ethtool_stats(struct net_device *netdev, i += 2; } rcu_read_unlock(); - if (vsi != pf->vsi[pf->lan_vsi]) + if (vsi != pf->vsi[pf->lan_vsi] || pf->hw.partition_id != 1) return; if (pf->lan_veb != I40E_NO_VEB) { @@ -1370,7 +1370,7 @@ static void i40e_get_strings(struct net_device *netdev, u32 stringset, snprintf(p, ETH_GSTRING_LEN, "rx-%u.rx_bytes", i); p += ETH_GSTRING_LEN; } - if (vsi != pf->vsi[pf->lan_vsi]) + if (vsi != pf->vsi[pf->lan_vsi] || pf->hw.partition_id != 1) return; if (pf->lan_veb != I40E_NO_VEB) { -- GitLab From 4205d379b6ff61472a94efe55b9a103582257ab8 Mon Sep 17 00:00:00 2001 From: Anjali Singhai Jain Date: Fri, 27 Feb 2015 09:15:27 +0000 Subject: [PATCH 03325/11651] i40e: Avoid logs while adding/deleting FD-SB filters It is not necessary to print FD filter add/delete log with normal debug settings because ethtool -n ethx shows all the FD-SB filters on an interface. The log can still be turned on through higher debug levels and it will continue to print a log if there was an error in the add/delete process. Change-ID: I67db2baf49e2075d2f537de40f7895e5b02cd610 Signed-off-by: Anjali Singhai Jain Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_txrx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index 7327952b292f..64beea95bce6 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -228,7 +228,7 @@ static int i40e_add_del_fdir_udpv4(struct i40e_vsi *vsi, "PCTYPE:%d, Filter command send failed for fd_id:%d (ret = %d)\n", fd_data->pctype, fd_data->fd_id, ret); err = true; - } else { + } else if (I40E_DEBUG_FD & pf->hw.debug_mask) { if (add) dev_info(&pf->pdev->dev, "Filter OK for PCTYPE %d loc = %d\n", @@ -303,7 +303,7 @@ static int i40e_add_del_fdir_tcpv4(struct i40e_vsi *vsi, "PCTYPE:%d, Filter command send failed for fd_id:%d (ret = %d)\n", fd_data->pctype, fd_data->fd_id, ret); err = true; - } else { + } else if (I40E_DEBUG_FD & pf->hw.debug_mask) { if (add) dev_info(&pf->pdev->dev, "Filter OK for PCTYPE %d loc = %d)\n", fd_data->pctype, fd_data->fd_id); @@ -376,7 +376,7 @@ static int i40e_add_del_fdir_ipv4(struct i40e_vsi *vsi, "PCTYPE:%d, Filter command send failed for fd_id:%d (ret = %d)\n", fd_data->pctype, fd_data->fd_id, ret); err = true; - } else { + } else if (I40E_DEBUG_FD & pf->hw.debug_mask) { if (add) dev_info(&pf->pdev->dev, "Filter OK for PCTYPE %d loc = %d\n", -- GitLab From 04294e38a451b37288d61e52fa07ed087c5cdc02 Mon Sep 17 00:00:00 2001 From: Anjali Singhai Jain Date: Fri, 27 Feb 2015 09:15:28 +0000 Subject: [PATCH 03326/11651] i40e: FD filters flush policy changes Since GLQF_FDCNT_0 register now has the right offset, use it to simplify our FD flush flow. If the filter add error happens to be for SB we just auto disable SB. If filter error happens to be for ATR, auto disable ATR and mark the state to FD_FLUSH_REQUESTED. Which gets cleared when flush completes. If we are entering flush too quickly (< 30 seconds) and we have quite a few SB rules, its time to disable ATR for good. Since SB + ATR rules is most likely making the FD table unstable. ATR can be re-enabled by turning ntuple off (ethtool -K ntuple off) and will remain off after turning ntuple on till it gets unstable again. Change-ID: I2154a2e0a5d44851a2f0eb8731e2f1d4a4d1acbc Signed-off-by: Anjali Singhai Jain Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e.h | 8 +-- drivers/net/ethernet/intel/i40e/i40e_main.c | 59 +++++++++++++++------ drivers/net/ethernet/intel/i40e/i40e_txrx.c | 20 ++++++- 3 files changed, 67 insertions(+), 20 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h index 4fb258ae83c6..f01cdbf015c7 100644 --- a/drivers/net/ethernet/intel/i40e/i40e.h +++ b/drivers/net/ethernet/intel/i40e/i40e.h @@ -175,6 +175,7 @@ struct i40e_lump_tracking { #define I40E_FDIR_MAX_RAW_PACKET_SIZE 512 #define I40E_FDIR_BUFFER_FULL_MARGIN 10 #define I40E_FDIR_BUFFER_HEAD_ROOM 32 +#define I40E_FDIR_BUFFER_HEAD_ROOM_FOR_ATR (I40E_FDIR_BUFFER_HEAD_ROOM * 4) enum i40e_fd_stat_idx { I40E_FD_STAT_ATR, @@ -636,9 +637,10 @@ int i40e_program_fdir_filter(struct i40e_fdir_filter *fdir_data, u8 *raw_packet, int i40e_add_del_fdir(struct i40e_vsi *vsi, struct i40e_fdir_filter *input, bool add); void i40e_fdir_check_and_reenable(struct i40e_pf *pf); -int i40e_get_current_fd_count(struct i40e_pf *pf); -int i40e_get_cur_guaranteed_fd_count(struct i40e_pf *pf); -int i40e_get_current_atr_cnt(struct i40e_pf *pf); +u32 i40e_get_current_fd_count(struct i40e_pf *pf); +u32 i40e_get_cur_guaranteed_fd_count(struct i40e_pf *pf); +u32 i40e_get_current_atr_cnt(struct i40e_pf *pf); +u32 i40e_get_global_fd_count(struct i40e_pf *pf); bool i40e_set_ntuple(struct i40e_pf *pf, netdev_features_t features); void i40e_set_ethtool_ops(struct net_device *netdev); struct i40e_mac_filter *i40e_add_filter(struct i40e_vsi *vsi, diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index e765bb37ef8c..77099ed93bfb 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -5345,9 +5345,9 @@ static void i40e_service_event_complete(struct i40e_pf *pf) * i40e_get_cur_guaranteed_fd_count - Get the consumed guaranteed FD filters * @pf: board private structure **/ -int i40e_get_cur_guaranteed_fd_count(struct i40e_pf *pf) +u32 i40e_get_cur_guaranteed_fd_count(struct i40e_pf *pf) { - int val, fcnt_prog; + u32 val, fcnt_prog; val = rd32(&pf->hw, I40E_PFQF_FDSTAT); fcnt_prog = (val & I40E_PFQF_FDSTAT_GUARANT_CNT_MASK); @@ -5355,12 +5355,13 @@ int i40e_get_cur_guaranteed_fd_count(struct i40e_pf *pf) } /** - * i40e_get_current_fd_count - Get the count of total FD filters programmed + * i40e_get_current_fd_count - Get total FD filters programmed for this PF * @pf: board private structure **/ -int i40e_get_current_fd_count(struct i40e_pf *pf) +u32 i40e_get_current_fd_count(struct i40e_pf *pf) { - int val, fcnt_prog; + u32 val, fcnt_prog; + val = rd32(&pf->hw, I40E_PFQF_FDSTAT); fcnt_prog = (val & I40E_PFQF_FDSTAT_GUARANT_CNT_MASK) + ((val & I40E_PFQF_FDSTAT_BEST_CNT_MASK) >> @@ -5368,6 +5369,21 @@ int i40e_get_current_fd_count(struct i40e_pf *pf) return fcnt_prog; } +/** + * i40e_get_global_fd_count - Get total FD filters programmed on device + * @pf: board private structure + **/ +u32 i40e_get_global_fd_count(struct i40e_pf *pf) +{ + u32 val, fcnt_prog; + + val = rd32(&pf->hw, I40E_GLQF_FDCNT_0); + fcnt_prog = (val & I40E_GLQF_FDCNT_0_GUARANT_CNT_MASK) + + ((val & I40E_GLQF_FDCNT_0_BESTCNT_MASK) >> + I40E_GLQF_FDCNT_0_BESTCNT_SHIFT); + return fcnt_prog; +} + /** * i40e_fdir_check_and_reenable - Function to reenabe FD ATR or SB if disabled * @pf: board private structure @@ -5382,7 +5398,7 @@ void i40e_fdir_check_and_reenable(struct i40e_pf *pf) /* Check if, FD SB or ATR was auto disabled and if there is enough room * to re-enable */ - fcnt_prog = i40e_get_cur_guaranteed_fd_count(pf); + fcnt_prog = i40e_get_global_fd_count(pf); fcnt_avail = pf->fdir_pf_filter_count; if ((fcnt_prog < (fcnt_avail - I40E_FDIR_BUFFER_HEAD_ROOM)) || (pf->fd_add_err == 0) || @@ -5404,13 +5420,17 @@ void i40e_fdir_check_and_reenable(struct i40e_pf *pf) } #define I40E_MIN_FD_FLUSH_INTERVAL 10 +#define I40E_MIN_FD_FLUSH_SB_ATR_UNSTABLE 30 /** * i40e_fdir_flush_and_replay - Function to flush all FD filters and replay SB * @pf: board private structure **/ static void i40e_fdir_flush_and_replay(struct i40e_pf *pf) { + unsigned long min_flush_time; int flush_wait_retry = 50; + bool disable_atr = false; + int fd_room; int reg; if (!(pf->flags & (I40E_FLAG_FD_SB_ENABLED | I40E_FLAG_FD_ATR_ENABLED))) @@ -5418,9 +5438,20 @@ static void i40e_fdir_flush_and_replay(struct i40e_pf *pf) if (time_after(jiffies, pf->fd_flush_timestamp + (I40E_MIN_FD_FLUSH_INTERVAL * HZ))) { - set_bit(__I40E_FD_FLUSH_REQUESTED, &pf->state); + /* If the flush is happening too quick and we have mostly + * SB rules we should not re-enable ATR for some time. + */ + min_flush_time = pf->fd_flush_timestamp + + (I40E_MIN_FD_FLUSH_SB_ATR_UNSTABLE * HZ); + fd_room = pf->fdir_pf_filter_count - pf->fdir_pf_active_filters; + + if (!(time_after(jiffies, min_flush_time)) && + (fd_room < I40E_FDIR_BUFFER_HEAD_ROOM_FOR_ATR)) { + dev_info(&pf->pdev->dev, "ATR disabled, not enough FD filter space.\n"); + disable_atr = true; + } + pf->fd_flush_timestamp = jiffies; - pf->auto_disable_flags |= I40E_FLAG_FD_SB_ENABLED; pf->flags &= ~I40E_FLAG_FD_ATR_ENABLED; /* flush all filters */ wr32(&pf->hw, I40E_PFQF_CTL_1, @@ -5440,10 +5471,8 @@ static void i40e_fdir_flush_and_replay(struct i40e_pf *pf) } else { /* replay sideband filters */ i40e_fdir_filter_restore(pf->vsi[pf->lan_vsi]); - - pf->flags |= I40E_FLAG_FD_ATR_ENABLED; - pf->auto_disable_flags &= ~I40E_FLAG_FD_ATR_ENABLED; - pf->auto_disable_flags &= ~I40E_FLAG_FD_SB_ENABLED; + if (!disable_atr) + pf->flags |= I40E_FLAG_FD_ATR_ENABLED; clear_bit(__I40E_FD_FLUSH_REQUESTED, &pf->state); dev_info(&pf->pdev->dev, "FD Filter table flushed and FD-SB replayed.\n"); } @@ -5454,7 +5483,7 @@ static void i40e_fdir_flush_and_replay(struct i40e_pf *pf) * i40e_get_current_atr_count - Get the count of total FD ATR filters programmed * @pf: board private structure **/ -int i40e_get_current_atr_cnt(struct i40e_pf *pf) +u32 i40e_get_current_atr_cnt(struct i40e_pf *pf) { return i40e_get_current_fd_count(pf) - pf->fdir_pf_active_filters; } @@ -5480,9 +5509,7 @@ static void i40e_fdir_reinit_subtask(struct i40e_pf *pf) if (!(pf->flags & (I40E_FLAG_FD_SB_ENABLED | I40E_FLAG_FD_ATR_ENABLED))) return; - if ((pf->fd_add_err >= I40E_MAX_FD_PROGRAM_ERROR) && - (i40e_get_current_atr_cnt(pf) >= pf->fd_atr_cnt) && - (i40e_get_current_atr_cnt(pf) > pf->fdir_pf_filter_count)) + if (test_bit(__I40E_FD_FLUSH_REQUESTED, &pf->state)) i40e_fdir_flush_and_replay(pf); i40e_fdir_check_and_reenable(pf); diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index 64beea95bce6..cdd5cc13cbeb 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -471,12 +471,27 @@ static void i40e_fd_handle_status(struct i40e_ring *rx_ring, dev_warn(&pdev->dev, "ntuple filter loc = %d, could not be added\n", rx_desc->wb.qword0.hi_dword.fd_id); + /* Check if the programming error is for ATR. + * If so, auto disable ATR and set a state for + * flush in progress. Next time we come here if flush is in + * progress do nothing, once flush is complete the state will + * be cleared. + */ + if (test_bit(__I40E_FD_FLUSH_REQUESTED, &pf->state)) + return; + pf->fd_add_err++; /* store the current atr filter count */ pf->fd_atr_cnt = i40e_get_current_atr_cnt(pf); + if ((rx_desc->wb.qword0.hi_dword.fd_id == 0) && + (pf->auto_disable_flags & I40E_FLAG_FD_SB_ENABLED)) { + pf->auto_disable_flags |= I40E_FLAG_FD_ATR_ENABLED; + set_bit(__I40E_FD_FLUSH_REQUESTED, &pf->state); + } + /* filter programming failed most likely due to table full */ - fcnt_prog = i40e_get_cur_guaranteed_fd_count(pf); + fcnt_prog = i40e_get_global_fd_count(pf); fcnt_avail = pf->fdir_pf_filter_count; /* If ATR is running fcnt_prog can quickly change, * if we are very close to full, it makes sense to disable @@ -1926,6 +1941,9 @@ static void i40e_atr(struct i40e_ring *tx_ring, struct sk_buff *skb, if (!(pf->flags & I40E_FLAG_FD_ATR_ENABLED)) return; + if ((pf->auto_disable_flags & I40E_FLAG_FD_ATR_ENABLED)) + return; + /* if sampling is disabled do nothing */ if (!tx_ring->atr_sample_rate) return; -- GitLab From f68a8342b1082d9a4b084cb085396e562899bc62 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Sat, 7 Mar 2015 22:58:10 +0900 Subject: [PATCH 03327/11651] extcon: Rename extcon core driver This patch renames the extcon core driver from extcon-class.c to extcon.c because '-class' postfix is not necessary. Signed-off-by: Chanwoo Choi --- drivers/extcon/Makefile | 2 +- drivers/extcon/{extcon-class.c => extcon.c} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename drivers/extcon/{extcon-class.c => extcon.c} (100%) diff --git a/drivers/extcon/Makefile b/drivers/extcon/Makefile index e1eb2d50e72b..9204114791a3 100644 --- a/drivers/extcon/Makefile +++ b/drivers/extcon/Makefile @@ -2,7 +2,7 @@ # Makefile for external connector class (extcon) devices # -obj-$(CONFIG_EXTCON) += extcon-class.o +obj-$(CONFIG_EXTCON) += extcon.o obj-$(CONFIG_EXTCON_ADC_JACK) += extcon-adc-jack.o obj-$(CONFIG_EXTCON_ARIZONA) += extcon-arizona.o obj-$(CONFIG_EXTCON_GPIO) += extcon-gpio.o diff --git a/drivers/extcon/extcon-class.c b/drivers/extcon/extcon.c similarity index 100% rename from drivers/extcon/extcon-class.c rename to drivers/extcon/extcon.c -- GitLab From 34825e511971e193db16a96350faeb60eff0d842 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Sat, 7 Mar 2015 01:41:36 +0900 Subject: [PATCH 03328/11651] extcon: Fix the checkpatch warning This patch fixes the checkpatch warning about coding style. Signed-off-by: Chanwoo Choi --- drivers/extcon/extcon-max14577.c | 5 +---- drivers/extcon/extcon-max77693.c | 5 +---- drivers/extcon/extcon-max8997.c | 5 +---- drivers/extcon/extcon-rt8973a.c | 6 ++---- drivers/extcon/extcon-sm5502.c | 6 +++--- drivers/extcon/extcon-usb-gpio.c | 2 +- drivers/extcon/extcon.c | 1 + 7 files changed, 10 insertions(+), 20 deletions(-) diff --git a/drivers/extcon/extcon-max14577.c b/drivers/extcon/extcon-max14577.c index c1bf0cf747b0..3823aa4a3a80 100644 --- a/drivers/extcon/extcon-max14577.c +++ b/drivers/extcon/extcon-max14577.c @@ -539,8 +539,6 @@ static void max14577_muic_irq_work(struct work_struct *work) dev_err(info->dev, "failed to handle MUIC interrupt\n"); mutex_unlock(&info->mutex); - - return; } /* @@ -730,8 +728,7 @@ static int max14577_muic_probe(struct platform_device *pdev) muic_irq->name, info); if (ret) { dev_err(&pdev->dev, - "failed: irq request (IRQ: %d," - " error :%d)\n", + "failed: irq request (IRQ: %d, error :%d)\n", muic_irq->irq, ret); return ret; } diff --git a/drivers/extcon/extcon-max77693.c b/drivers/extcon/extcon-max77693.c index dfcc5cba25f0..a66bec8f6252 100644 --- a/drivers/extcon/extcon-max77693.c +++ b/drivers/extcon/extcon-max77693.c @@ -1019,8 +1019,6 @@ static void max77693_muic_irq_work(struct work_struct *work) dev_err(info->dev, "failed to handle MUIC interrupt\n"); mutex_unlock(&info->mutex); - - return; } static irqreturn_t max77693_muic_irq_handler(int irq, void *data) @@ -1171,8 +1169,7 @@ static int max77693_muic_probe(struct platform_device *pdev) muic_irq->name, info); if (ret) { dev_err(&pdev->dev, - "failed: irq request (IRQ: %d," - " error :%d)\n", + "failed: irq request (IRQ: %d, error :%d)\n", muic_irq->irq, ret); return ret; } diff --git a/drivers/extcon/extcon-max8997.c b/drivers/extcon/extcon-max8997.c index fc1678fa95c4..5774e56c6422 100644 --- a/drivers/extcon/extcon-max8997.c +++ b/drivers/extcon/extcon-max8997.c @@ -579,8 +579,6 @@ static void max8997_muic_irq_work(struct work_struct *work) dev_err(info->dev, "failed to handle MUIC interrupt\n"); mutex_unlock(&info->mutex); - - return; } static irqreturn_t max8997_muic_irq_handler(int irq, void *data) @@ -689,8 +687,7 @@ static int max8997_muic_probe(struct platform_device *pdev) muic_irq->name, info); if (ret) { dev_err(&pdev->dev, - "failed: irq request (IRQ: %d," - " error :%d)\n", + "failed: irq request (IRQ: %d, error :%d)\n", muic_irq->irq, ret); goto err_irq; } diff --git a/drivers/extcon/extcon-rt8973a.c b/drivers/extcon/extcon-rt8973a.c index a784b2d5ee72..9ccd5af89d1c 100644 --- a/drivers/extcon/extcon-rt8973a.c +++ b/drivers/extcon/extcon-rt8973a.c @@ -582,10 +582,8 @@ static int rt8973a_muic_i2c_probe(struct i2c_client *i2c, return -EINVAL; info = devm_kzalloc(&i2c->dev, sizeof(*info), GFP_KERNEL); - if (!info) { - dev_err(&i2c->dev, "failed to allocate memory\n"); + if (!info) return -ENOMEM; - } i2c_set_clientdata(i2c, info); info->dev = &i2c->dev; @@ -681,7 +679,7 @@ static int rt8973a_muic_i2c_remove(struct i2c_client *i2c) return 0; } -static struct of_device_id rt8973a_dt_match[] = { +static const struct of_device_id rt8973a_dt_match[] = { { .compatible = "richtek,rt8973a-muic" }, { }, }; diff --git a/drivers/extcon/extcon-sm5502.c b/drivers/extcon/extcon-sm5502.c index b0f7bd82af90..2f93cf307852 100644 --- a/drivers/extcon/extcon-sm5502.c +++ b/drivers/extcon/extcon-sm5502.c @@ -359,8 +359,8 @@ static unsigned int sm5502_muic_get_cable_type(struct sm5502_muic_info *info) break; default: dev_dbg(info->dev, - "cannot identify the cable type: adc(0x%x) " - "dev_type1(0x%x)\n", adc, dev_type1); + "cannot identify the cable type: adc(0x%x)\n", + adc); return -EINVAL; }; break; @@ -659,7 +659,7 @@ static int sm5502_muic_i2c_remove(struct i2c_client *i2c) return 0; } -static struct of_device_id sm5502_dt_match[] = { +static const struct of_device_id sm5502_dt_match[] = { { .compatible = "siliconmitus,sm5502-muic" }, { }, }; diff --git a/drivers/extcon/extcon-usb-gpio.c b/drivers/extcon/extcon-usb-gpio.c index 3f0bad3ce8aa..de67fce18984 100644 --- a/drivers/extcon/extcon-usb-gpio.c +++ b/drivers/extcon/extcon-usb-gpio.c @@ -214,7 +214,7 @@ static int usb_extcon_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(usb_extcon_pm_ops, usb_extcon_suspend, usb_extcon_resume); -static struct of_device_id usb_extcon_dt_match[] = { +static const struct of_device_id usb_extcon_dt_match[] = { { .compatible = "linux,extcon-usb-gpio", }, { /* sentinel */ } }; diff --git a/drivers/extcon/extcon.c b/drivers/extcon/extcon.c index 8319f25b7145..752ce1208428 100644 --- a/drivers/extcon/extcon.c +++ b/drivers/extcon/extcon.c @@ -158,6 +158,7 @@ static ssize_t name_show(struct device *dev, struct device_attribute *attr, /* Optional callback given by the user */ if (edev->print_name) { int ret = edev->print_name(edev, buf); + if (ret >= 0) return ret; } -- GitLab From 4599120466c784f8b2afef6fb2b7a452a73b400e Mon Sep 17 00:00:00 2001 From: Anjali Singhai Jain Date: Fri, 27 Feb 2015 09:15:29 +0000 Subject: [PATCH 03329/11651] i40e/i40evf: Simplify tunnel selection logic Use l4_tunnel type generically to keep code flow simple. Change-ID: Ic52287e3b1ca4204e6b6e13431890c1a6ae9c422 Signed-off-by: Anjali Singhai Jain Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_txrx.c | 12 ++++++++++-- drivers/net/ethernet/intel/i40evf/i40e_txrx.c | 12 ++++++++++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index cdd5cc13cbeb..a60b8405f046 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -2216,8 +2216,16 @@ static void i40e_tx_enable_csum(struct sk_buff *skb, u32 tx_flags, struct iphdr *this_ip_hdr; u32 network_hdr_len; u8 l4_hdr = 0; + u32 l4_tunnel = 0; if (skb->encapsulation) { + switch (ip_hdr(skb)->protocol) { + case IPPROTO_UDP: + l4_tunnel = I40E_TXD_CTX_UDP_TUNNELING; + break; + default: + return; + } network_hdr_len = skb_inner_network_header_len(skb); this_ip_hdr = inner_ip_hdr(skb); this_ipv6_hdr = inner_ipv6_hdr(skb); @@ -2240,8 +2248,8 @@ static void i40e_tx_enable_csum(struct sk_buff *skb, u32 tx_flags, /* Now set the ctx descriptor fields */ *cd_tunneling |= (skb_network_header_len(skb) >> 2) << - I40E_TXD_CTX_QW0_EXT_IPLEN_SHIFT | - I40E_TXD_CTX_UDP_TUNNELING | + I40E_TXD_CTX_QW0_EXT_IPLEN_SHIFT | + l4_tunnel | ((skb_inner_network_offset(skb) - skb_transport_offset(skb)) >> 1) << I40E_TXD_CTX_QW0_NATLEN_SHIFT; diff --git a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c index 021b0d4d8a35..1c2637b28728 100644 --- a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c @@ -1461,8 +1461,16 @@ static void i40e_tx_enable_csum(struct sk_buff *skb, u32 tx_flags, struct iphdr *this_ip_hdr; u32 network_hdr_len; u8 l4_hdr = 0; + u32 l4_tunnel = 0; if (skb->encapsulation) { + switch (ip_hdr(skb)->protocol) { + case IPPROTO_UDP: + l4_tunnel = I40E_TXD_CTX_UDP_TUNNELING; + break; + default: + return; + } network_hdr_len = skb_inner_network_header_len(skb); this_ip_hdr = inner_ip_hdr(skb); this_ipv6_hdr = inner_ipv6_hdr(skb); @@ -1485,8 +1493,8 @@ static void i40e_tx_enable_csum(struct sk_buff *skb, u32 tx_flags, /* Now set the ctx descriptor fields */ *cd_tunneling |= (skb_network_header_len(skb) >> 2) << - I40E_TXD_CTX_QW0_EXT_IPLEN_SHIFT | - I40E_TXD_CTX_UDP_TUNNELING | + I40E_TXD_CTX_QW0_EXT_IPLEN_SHIFT | + l4_tunnel | ((skb_inner_network_offset(skb) - skb_transport_offset(skb)) >> 1) << I40E_TXD_CTX_QW0_NATLEN_SHIFT; -- GitLab From d9e894ee8a06b0324b9d9f951c0276a7409b8518 Mon Sep 17 00:00:00 2001 From: Anjali Singhai Jain Date: Fri, 27 Feb 2015 09:15:30 +0000 Subject: [PATCH 03330/11651] i40e: Simplify code for rss_size_max config We initialize the pf->rss_size_max in sw_init now and hence this code can be simplified. Change-ID: I1a7abc837604a40bc65e6c6b21190b909ed6bb21 Signed-off-by: Anjali Singhai Jain Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_main.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 77099ed93bfb..f2f3d8957247 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -7398,13 +7398,10 @@ static int i40e_config_rss(struct i40e_pf *pf) /* Check capability and Set table size and register per hw expectation*/ reg_val = rd32(hw, I40E_PFQF_CTL_0); - if (hw->func_caps.rss_table_size == 512) { + if (pf->rss_table_size == 512) reg_val |= I40E_PFQF_CTL_0_HASHLUTSIZE_512; - pf->rss_table_size = 512; - } else { - pf->rss_table_size = 128; + else reg_val &= ~I40E_PFQF_CTL_0_HASHLUTSIZE_512; - } wr32(hw, I40E_PFQF_CTL_0, reg_val); /* Populate the LUT with max no. of queues in round robin fashion */ -- GitLab From 016890b99482745646de091d795384efd83f5d20 Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Fri, 27 Feb 2015 09:15:31 +0000 Subject: [PATCH 03331/11651] i40e/i40evf: enable prefetch of Tx descriptors during cleanup Performance can be improved a bit by imitating ixgbe and using prefetch to get us the next Tx descriptor. Change-ID: Ice7ffd4cd0ce87c35295059bdb7972a7f53723aa Signed-off-by: Jesse Brandeburg Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_txrx.c | 2 ++ drivers/net/ethernet/intel/i40evf/i40e_txrx.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index a60b8405f046..f5a50b9366cb 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -770,6 +770,8 @@ static bool i40e_clean_tx_irq(struct i40e_ring *tx_ring, int budget) tx_desc = I40E_TX_DESC(tx_ring, 0); } + prefetch(tx_desc); + /* update budget accounting */ budget--; } while (likely(budget)); diff --git a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c index 1c2637b28728..d9f3db542c5f 100644 --- a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c @@ -289,6 +289,8 @@ static bool i40e_clean_tx_irq(struct i40e_ring *tx_ring, int budget) tx_desc = I40E_TX_DESC(tx_ring, 0); } + prefetch(tx_desc); + /* update budget accounting */ budget--; } while (likely(budget)); -- GitLab From b85e911b7580d6a8ea7ebc9831c5ac566c595e4b Mon Sep 17 00:00:00 2001 From: Sravanthi Tangeda Date: Fri, 27 Feb 2015 09:15:33 +0000 Subject: [PATCH 03332/11651] i40e/i40evf: Bump version Bump i40e to 1.2.12 and i40evf to 1.2.6. Change-ID: I641871da3a9abd396b28eda5744a4d68493c1400 Signed-off-by: Sravanthi Tangeda Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_main.c | 2 +- drivers/net/ethernet/intel/i40evf/i40evf_main.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index f2f3d8957247..d689c456a9ac 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -39,7 +39,7 @@ static const char i40e_driver_string[] = #define DRV_VERSION_MAJOR 1 #define DRV_VERSION_MINOR 2 -#define DRV_VERSION_BUILD 11 +#define DRV_VERSION_BUILD 12 #define DRV_VERSION __stringify(DRV_VERSION_MAJOR) "." \ __stringify(DRV_VERSION_MINOR) "." \ __stringify(DRV_VERSION_BUILD) DRV_KERN diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c b/drivers/net/ethernet/intel/i40evf/i40evf_main.c index 3d53bb4c3208..8537416123a5 100644 --- a/drivers/net/ethernet/intel/i40evf/i40evf_main.c +++ b/drivers/net/ethernet/intel/i40evf/i40evf_main.c @@ -36,7 +36,7 @@ char i40evf_driver_name[] = "i40evf"; static const char i40evf_driver_string[] = "Intel(R) XL710/X710 Virtual Function Network Driver"; -#define DRV_VERSION "1.2.5" +#define DRV_VERSION "1.2.6" const char i40evf_driver_version[] = DRV_VERSION; static const char i40evf_copyright[] = "Copyright (c) 2013 - 2014 Intel Corporation."; -- GitLab From cd77f5e1fa17de2479d838a36fed0bc98b0a42c2 Mon Sep 17 00:00:00 2001 From: Greg Rose Date: Fri, 6 Mar 2015 01:41:07 +0000 Subject: [PATCH 03333/11651] i40e: Strip configfs code The use of configfs is not allowed in network drivers. Strip the code that uses it. Signed-off-by: Greg Rose Tested-by: Jim Young Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/Kconfig | 9 - drivers/net/ethernet/intel/i40e/Makefile | 1 - drivers/net/ethernet/intel/i40e/i40e.h | 4 - .../net/ethernet/intel/i40e/i40e_configfs.c | 354 ------------------ drivers/net/ethernet/intel/i40e/i40e_main.c | 6 - 5 files changed, 374 deletions(-) delete mode 100644 drivers/net/ethernet/intel/i40e/i40e_configfs.c diff --git a/drivers/net/ethernet/intel/Kconfig b/drivers/net/ethernet/intel/Kconfig index 7216a5370a1f..f4ff465584a0 100644 --- a/drivers/net/ethernet/intel/Kconfig +++ b/drivers/net/ethernet/intel/Kconfig @@ -303,15 +303,6 @@ config I40E_FCOE If unsure, say N. -config I40E_CONFIGFS_FS - bool "Config File System Support (configfs)" - default n - depends on I40E && CONFIGFS_FS && !(I40E=y && CONFIGFS_FS=m) - ---help--- - Provides support for the configfs file system for additional - driver configuration. Say Y here if you want to use the - configuration file system in the driver. - config I40EVF tristate "Intel(R) XL710 X710 Virtual Function Ethernet support" depends on PCI_MSI diff --git a/drivers/net/ethernet/intel/i40e/Makefile b/drivers/net/ethernet/intel/i40e/Makefile index 023e452aff8c..b4729ba57c9c 100644 --- a/drivers/net/ethernet/intel/i40e/Makefile +++ b/drivers/net/ethernet/intel/i40e/Makefile @@ -37,7 +37,6 @@ i40e-objs := i40e_main.o \ i40e_hmc.o \ i40e_lan_hmc.o \ i40e_nvm.o \ - i40e_configfs.o \ i40e_debugfs.o \ i40e_diag.o \ i40e_txrx.o \ diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h index f01cdbf015c7..7ce8e600c13c 100644 --- a/drivers/net/ethernet/intel/i40e/i40e.h +++ b/drivers/net/ethernet/intel/i40e/i40e.h @@ -749,10 +749,6 @@ int i40e_ptp_get_ts_config(struct i40e_pf *pf, struct ifreq *ifr); void i40e_ptp_init(struct i40e_pf *pf); void i40e_ptp_stop(struct i40e_pf *pf); int i40e_is_vsi_uplink_mode_veb(struct i40e_vsi *vsi); -#if IS_ENABLED(CONFIG_I40E_CONFIGFS_FS) -int i40e_configfs_init(void); -void i40e_configfs_exit(void); -#endif /* CONFIG_I40E_CONFIGFS_FS */ i40e_status i40e_get_npar_bw_setting(struct i40e_pf *pf); i40e_status i40e_set_npar_bw_setting(struct i40e_pf *pf); i40e_status i40e_commit_npar_bw_setting(struct i40e_pf *pf); diff --git a/drivers/net/ethernet/intel/i40e/i40e_configfs.c b/drivers/net/ethernet/intel/i40e/i40e_configfs.c deleted file mode 100644 index d3cdfc24d5bf..000000000000 --- a/drivers/net/ethernet/intel/i40e/i40e_configfs.c +++ /dev/null @@ -1,354 +0,0 @@ -/******************************************************************************* - * - * Intel Ethernet Controller XL710 Family Linux Driver - * Copyright(c) 2013 - 2015 Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope 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, see . - * - * The full GNU General Public License is included in this distribution in - * the file called "COPYING". - * - * Contact Information: - * e1000-devel Mailing List - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - ******************************************************************************/ - -#include -#include "i40e.h" - -#if IS_ENABLED(CONFIG_I40E_CONFIGFS_FS) - -/** - * configfs structure for i40e - * - * This file adds code for configfs support for the i40e driver. This sets - * up a filesystem under /sys/kernel/config in which configuration changes - * can be made for the driver's netdevs. - * - * The initialization in this code creates the "i40e" entry in the configfs - * system. After that, the user needs to use mkdir to create configurations - * for specific netdev ports; for example "mkdir eth3". This code will verify - * that such a netdev exists and that it is owned by i40e. - * - **/ - -struct i40e_cfgfs_vsi { - struct config_item item; - struct i40e_vsi *vsi; -}; - -static inline struct i40e_cfgfs_vsi *to_i40e_cfgfs_vsi(struct config_item *item) -{ - return item ? container_of(item, struct i40e_cfgfs_vsi, item) : NULL; -} - -static struct configfs_attribute i40e_cfgfs_vsi_attr_min_bw = { - .ca_owner = THIS_MODULE, - .ca_name = "min_bw", - .ca_mode = S_IRUGO | S_IWUSR, -}; - -static struct configfs_attribute i40e_cfgfs_vsi_attr_max_bw = { - .ca_owner = THIS_MODULE, - .ca_name = "max_bw", - .ca_mode = S_IRUGO | S_IWUSR, -}; - -static struct configfs_attribute i40e_cfgfs_vsi_attr_commit = { - .ca_owner = THIS_MODULE, - .ca_name = "commit", - .ca_mode = S_IRUGO | S_IWUSR, -}; - -static struct configfs_attribute i40e_cfgfs_vsi_attr_port_count = { - .ca_owner = THIS_MODULE, - .ca_name = "ports", - .ca_mode = S_IRUGO | S_IWUSR, -}; - -static struct configfs_attribute i40e_cfgfs_vsi_attr_part_count = { - .ca_owner = THIS_MODULE, - .ca_name = "partitions", - .ca_mode = S_IRUGO | S_IWUSR, -}; - -static struct configfs_attribute *i40e_cfgfs_vsi_attrs[] = { - &i40e_cfgfs_vsi_attr_min_bw, - &i40e_cfgfs_vsi_attr_max_bw, - &i40e_cfgfs_vsi_attr_commit, - &i40e_cfgfs_vsi_attr_port_count, - &i40e_cfgfs_vsi_attr_part_count, - NULL, -}; - -/** - * i40e_cfgfs_vsi_attr_show - Show a VSI's NPAR BW partition info - * @item: A pointer back to the configfs item created on driver load - * @attr: A pointer to this item's configuration attribute - * @page: A pointer to the output buffer - **/ -static ssize_t i40e_cfgfs_vsi_attr_show(struct config_item *item, - struct configfs_attribute *attr, - char *page) -{ - struct i40e_cfgfs_vsi *i40e_cfgfs_vsi = to_i40e_cfgfs_vsi(item); - struct i40e_pf *pf = i40e_cfgfs_vsi->vsi->back; - ssize_t count; - - if (i40e_cfgfs_vsi->vsi != pf->vsi[pf->lan_vsi]) - return 0; - - if (strncmp(attr->ca_name, "min_bw", 6) == 0) - count = sprintf(page, "%s %s %d%%\n", - i40e_cfgfs_vsi->vsi->netdev->name, - (pf->npar_min_bw & I40E_ALT_BW_RELATIVE_MASK) ? - "Relative Min BW" : "Absolute Min BW", - pf->npar_min_bw & I40E_ALT_BW_VALUE_MASK); - else if (strncmp(attr->ca_name, "max_bw", 6) == 0) - count = sprintf(page, "%s %s %d%%\n", - i40e_cfgfs_vsi->vsi->netdev->name, - (pf->npar_max_bw & I40E_ALT_BW_RELATIVE_MASK) ? - "Relative Max BW" : "Absolute Max BW", - pf->npar_max_bw & I40E_ALT_BW_VALUE_MASK); - else if (strncmp(attr->ca_name, "ports", 5) == 0) - count = sprintf(page, "%d\n", - pf->hw.num_ports); - else if (strncmp(attr->ca_name, "partitions", 10) == 0) - count = sprintf(page, "%d\n", - pf->hw.num_partitions); - else - return 0; - - return count; -} - -/** - * i40e_cfgfs_vsi_attr_store - Show a VSI's NPAR BW partition info - * @item: A pointer back to the configfs item created on driver load - * @attr: A pointer to this item's configuration attribute - * @page: A pointer to the user input buffer holding the user input values - **/ -static ssize_t i40e_cfgfs_vsi_attr_store(struct config_item *item, - struct configfs_attribute *attr, - const char *page, size_t count) -{ - struct i40e_cfgfs_vsi *i40e_cfgfs_vsi = to_i40e_cfgfs_vsi(item); - struct i40e_pf *pf = i40e_cfgfs_vsi->vsi->back; - char *p = (char *)page; - int rc; - unsigned long tmp; - - if (i40e_cfgfs_vsi->vsi != pf->vsi[pf->lan_vsi]) - return 0; - - if (!p || (*p && (*p == '\n'))) - return -EINVAL; - - rc = kstrtoul(p, 10, &tmp); - if (rc) - return rc; - if (tmp > 100) - return -ERANGE; - - if (strncmp(attr->ca_name, "min_bw", 6) == 0) { - if (tmp > (pf->npar_max_bw & I40E_ALT_BW_VALUE_MASK)) - return -ERANGE; - /* Preserve the valid and relative BW bits - the rest is - * don't care. - */ - pf->npar_min_bw &= (I40E_ALT_BW_RELATIVE_MASK | - I40E_ALT_BW_VALID_MASK); - pf->npar_min_bw |= (tmp & I40E_ALT_BW_VALUE_MASK); - i40e_set_npar_bw_setting(pf); - } else if (strncmp(attr->ca_name, "max_bw", 6) == 0) { - if (tmp < 1 || - tmp < (pf->npar_min_bw & I40E_ALT_BW_VALUE_MASK)) - return -ERANGE; - /* Preserve the valid and relative BW bits - the rest is - * don't care. - */ - pf->npar_max_bw &= (I40E_ALT_BW_RELATIVE_MASK | - I40E_ALT_BW_VALID_MASK); - pf->npar_max_bw |= (tmp & I40E_ALT_BW_VALUE_MASK); - i40e_set_npar_bw_setting(pf); - } else if (strncmp(attr->ca_name, "commit", 6) == 0 && tmp == 1) { - if (i40e_commit_npar_bw_setting(pf)) - return -EIO; - } - - return count; -} - -/** - * i40e_cfgfs_vsi_release - Free up the configuration item memory - * @item: A pointer back to the configfs item created on driver load - **/ -static void i40e_cfgfs_vsi_release(struct config_item *item) -{ - kfree(to_i40e_cfgfs_vsi(item)); -} - -static struct configfs_item_operations i40e_cfgfs_vsi_item_ops = { - .release = i40e_cfgfs_vsi_release, - .show_attribute = i40e_cfgfs_vsi_attr_show, - .store_attribute = i40e_cfgfs_vsi_attr_store, -}; - -static struct config_item_type i40e_cfgfs_vsi_type = { - .ct_item_ops = &i40e_cfgfs_vsi_item_ops, - .ct_attrs = i40e_cfgfs_vsi_attrs, - .ct_owner = THIS_MODULE, -}; - -struct i40e_cfgfs_group { - struct config_group group; -}; - -/** - * to_i40e_cfgfs_group - Get the group pointer from the config item - * @item: A pointer back to the configfs item created on driver load - **/ -static inline struct i40e_cfgfs_group * -to_i40e_cfgfs_group(struct config_item *item) -{ - return item ? container_of(to_config_group(item), - struct i40e_cfgfs_group, group) : NULL; -} - -/** - * i40e_cfgfs_group_make_item - Create the configfs item with group container - * @group: A pointer to our configfs group - * @name: A pointer to the nume of the device we're looking for - **/ -static struct config_item * -i40e_cfgfs_group_make_item(struct config_group *group, const char *name) -{ - struct i40e_cfgfs_vsi *i40e_cfgfs_vsi; - struct net_device *netdev; - struct i40e_netdev_priv *np; - - read_lock(&dev_base_lock); - netdev = first_net_device(&init_net); - while (netdev) { - if (strncmp(netdev->name, name, sizeof(netdev->name)) == 0) - break; - netdev = next_net_device(netdev); - } - read_unlock(&dev_base_lock); - - if (!netdev) - return ERR_PTR(-ENODEV); - - /* is this netdev owned by i40e? */ - if (netdev->netdev_ops->ndo_open != i40e_open) - return ERR_PTR(-EACCES); - - i40e_cfgfs_vsi = kzalloc(sizeof(*i40e_cfgfs_vsi), GFP_KERNEL); - if (!i40e_cfgfs_vsi) - return ERR_PTR(-ENOMEM); - - np = netdev_priv(netdev); - i40e_cfgfs_vsi->vsi = np->vsi; - config_item_init_type_name(&i40e_cfgfs_vsi->item, name, - &i40e_cfgfs_vsi_type); - - return &i40e_cfgfs_vsi->item; -} - -static struct configfs_attribute i40e_cfgfs_group_attr_description = { - .ca_owner = THIS_MODULE, - .ca_name = "description", - .ca_mode = S_IRUGO, -}; - -static struct configfs_attribute *i40e_cfgfs_group_attrs[] = { - &i40e_cfgfs_group_attr_description, - NULL, -}; - -static ssize_t i40e_cfgfs_group_attr_show(struct config_item *item, - struct configfs_attribute *attr, - char *page) -{ - return sprintf(page, -"i40e\n" -"\n" -"This subsystem allows the modification of network port configurations.\n" -"To start, use the name of the network port to be configured in a 'mkdir'\n" -"command, e.g. 'mkdir eth3'.\n"); -} - -static void i40e_cfgfs_group_release(struct config_item *item) -{ - kfree(to_i40e_cfgfs_group(item)); -} - -static struct configfs_item_operations i40e_cfgfs_group_item_ops = { - .release = i40e_cfgfs_group_release, - .show_attribute = i40e_cfgfs_group_attr_show, -}; - -/* Note that, since no extra work is required on ->drop_item(), - * no ->drop_item() is provided. - */ -static struct configfs_group_operations i40e_cfgfs_group_ops = { - .make_item = i40e_cfgfs_group_make_item, -}; - -static struct config_item_type i40e_cfgfs_group_type = { - .ct_item_ops = &i40e_cfgfs_group_item_ops, - .ct_group_ops = &i40e_cfgfs_group_ops, - .ct_attrs = i40e_cfgfs_group_attrs, - .ct_owner = THIS_MODULE, -}; - -static struct configfs_subsystem i40e_cfgfs_group_subsys = { - .su_group = { - .cg_item = { - .ci_namebuf = "i40e", - .ci_type = &i40e_cfgfs_group_type, - }, - }, -}; - -/** - * i40e_configfs_init - Initialize configfs support for our driver - **/ -int i40e_configfs_init(void) -{ - int ret; - struct configfs_subsystem *subsys; - - subsys = &i40e_cfgfs_group_subsys; - - config_group_init(&subsys->su_group); - mutex_init(&subsys->su_mutex); - ret = configfs_register_subsystem(subsys); - if (ret) { - pr_err("Error %d while registering configfs subsystem %s\n", - ret, subsys->su_group.cg_item.ci_namebuf); - return ret; - } - - return 0; -} - -/** - * i40e_configfs_init - Bail out - unregister configfs subsystem and release - **/ -void i40e_configfs_exit(void) -{ - configfs_unregister_subsystem(&i40e_cfgfs_group_subsys); -} -#endif /* IS_ENABLED(CONFIG_I40E_CONFIGFS_FS) */ diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index d689c456a9ac..4bed881e3cb6 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -10287,9 +10287,6 @@ static int __init i40e_init_module(void) i40e_driver_string, i40e_driver_version_str); pr_info("%s: %s\n", i40e_driver_name, i40e_copyright); -#if IS_ENABLED(CONFIG_I40E_CONFIGFS_FS) - i40e_configfs_init(); -#endif /* CONFIG_I40E_CONFIGFS_FS */ i40e_dbg_init(); return pci_register_driver(&i40e_driver); } @@ -10305,8 +10302,5 @@ static void __exit i40e_exit_module(void) { pci_unregister_driver(&i40e_driver); i40e_dbg_exit(); -#if IS_ENABLED(CONFIG_I40E_CONFIGFS_FS) - i40e_configfs_exit(); -#endif /* CONFIG_I40E_CONFIGFS_FS */ } module_exit(i40e_exit_module); -- GitLab From 0aed11244360c24c854a263eac0293acef2abd03 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 24 Feb 2015 00:54:16 +0000 Subject: [PATCH 03334/11651] dmaengine: export symbol of of_dma_request_slave_channel() Current DMAEngine implementation of DT bindings can't support DT subnode. This patch export symbols of of_dma_request_slave_channel() for subnode DMA DT bingings. ex) rcar_sound: rcar_sound@ec500000 { ... rcar_sound,dvc { dvc0: dvc@0 { dmas = <&audma0 0xbc>; dma-names = "tx"; }; dvc1: dvc@1 { dmas = <&audma0 0xbe>; dma-names = "tx"; }; }; ... }; Signed-off-by: Kuninori Morimoto Acked-by: Vinod Koul Signed-off-by: Mark Brown --- drivers/dma/of-dma.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/dma/of-dma.c b/drivers/dma/of-dma.c index ca31f1b45366..cbd4a8aff120 100644 --- a/drivers/dma/of-dma.c +++ b/drivers/dma/of-dma.c @@ -194,6 +194,7 @@ struct dma_chan *of_dma_request_slave_channel(struct device_node *np, return ERR_PTR(ret_no_channel); } +EXPORT_SYMBOL_GPL(of_dma_request_slave_channel); /** * of_dma_simple_xlate - Simple DMA engine translation function -- GitLab From c303cf0895ad927f5e9b8a5f8ed1c6b8c96a500f Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 20 Feb 2015 10:22:37 +0000 Subject: [PATCH 03335/11651] ASoC: rsnd: remove SH-DMA-BASE specific implementation Renesas R-Car sound had SH-DMA-BASE specific implementation before, but, now, it is no longer needed. Let's remove it. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/core.c | 1 - sound/soc/sh/rcar/rsnd.h | 1 - 2 files changed, 2 deletions(-) diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 1b53605f7154..0b14d3762cff 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -94,7 +94,6 @@ * */ #include -#include #include "rsnd.h" #define RSND_RATES SNDRV_PCM_RATE_8000_96000 diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index e7914bd610e2..5ffde9b8955d 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -171,7 +171,6 @@ u32 rsnd_get_adinr(struct rsnd_mod *mod); * R-Car DMA */ struct rsnd_dma { - struct sh_dmae_slave slave; struct dma_chan *chan; enum dma_transfer_direction dir; dma_addr_t addr; -- GitLab From 4715219ecef50cf79d7784545bf5bb4664bb800d Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 20 Feb 2015 10:23:08 +0000 Subject: [PATCH 03336/11651] ASoC: rsnd: remove un-needed parameter from rsnd_dma_init() It can get DMA direction via rsnd_dai_stream. Remove un-needed is_play from rsnd_dma_init(). Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/core.c | 6 ++++-- sound/soc/sh/rcar/rsnd.h | 16 +--------------- sound/soc/sh/rcar/src.c | 1 - sound/soc/sh/rcar/ssi.c | 1 - 4 files changed, 5 insertions(+), 19 deletions(-) diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 0b14d3762cff..1edf4dc41c70 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -311,13 +311,15 @@ static void rsnd_dma_of_path(struct rsnd_dma *dma, } } -int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, - int is_play, int id) +int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id) { struct device *dev = rsnd_priv_to_dev(priv); struct dma_slave_config cfg; + struct rsnd_mod *mod = rsnd_dma_to_mod(dma); struct rsnd_mod *mod_from; struct rsnd_mod *mod_to; + struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); + int is_play = rsnd_io_is_play(io); char dma_name[DMA_NAME_SIZE]; dma_cap_mask_t mask; int ret; diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 5ffde9b8955d..93a1a256f37c 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -179,8 +179,7 @@ struct rsnd_dma { void rsnd_dma_start(struct rsnd_dma *dma); void rsnd_dma_stop(struct rsnd_dma *dma); int rsnd_dma_available(struct rsnd_dma *dma); -int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, - int is_play, int id); +int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id); void rsnd_dma_quit(struct rsnd_priv *priv, struct rsnd_dma *dma); @@ -413,19 +412,6 @@ struct rsnd_priv { #define rsnd_lock(priv, flags) spin_lock_irqsave(&priv->lock, flags) #define rsnd_unlock(priv, flags) spin_unlock_irqrestore(&priv->lock, flags) -#define rsnd_info_is_playback(priv, type) \ -({ \ - struct rcar_snd_info *info = rsnd_priv_to_info(priv); \ - int i, is_play = 0; \ - for (i = 0; i < info->dai_info_nr; i++) { \ - if (info->dai_info[i].playback.type == (type)->info) { \ - is_play = 1; \ - break; \ - } \ - } \ - is_play; \ -}) - /* * rsnd_kctrl */ diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index 81c182b4bad5..7fb879871a8e 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c @@ -713,7 +713,6 @@ static int rsnd_src_probe_gen2(struct rsnd_mod *mod, ret = rsnd_dma_init(priv, rsnd_mod_to_dma(mod), - rsnd_info_is_playback(priv, src), src->info->dma_id); if (ret) goto rsnd_src_probe_gen2_fail; diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 9e7b627c08e2..57e737c7046b 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -478,7 +478,6 @@ static int rsnd_ssi_dma_probe(struct rsnd_mod *mod, ret = rsnd_dma_init( priv, rsnd_mod_to_dma(mod), - rsnd_info_is_playback(priv, ssi), dma_id); if (ret) goto rsnd_ssi_dma_probe_fail; -- GitLab From 9c706ab29f33b9562f570d1e99e21955d898dc85 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 20 Feb 2015 10:23:39 +0000 Subject: [PATCH 03337/11651] ASoC: rsnd: remove unused rsnd_dma_available() rsnd_dma_available() is not used. Let's remove it. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/core.c | 5 ----- sound/soc/sh/rcar/rsnd.h | 1 - sound/soc/sh/rcar/src.c | 2 -- sound/soc/sh/rcar/ssi.c | 2 -- 4 files changed, 10 deletions(-) diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 1edf4dc41c70..1da94bf730d2 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -222,11 +222,6 @@ void rsnd_dma_start(struct rsnd_dma *dma) dma_async_issue_pending(dma->chan); } -int rsnd_dma_available(struct rsnd_dma *dma) -{ - return !!dma->chan; -} - #define DMA_NAME_SIZE 16 #define MOD_MAX 4 /* MEM/SSI/SRC/DVC */ static int _rsnd_dma_of_name(char *dma_name, struct rsnd_mod *mod) diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 93a1a256f37c..cb12861a1f3c 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -178,7 +178,6 @@ struct rsnd_dma { void rsnd_dma_start(struct rsnd_dma *dma); void rsnd_dma_stop(struct rsnd_dma *dma); -int rsnd_dma_available(struct rsnd_dma *dma); int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id); void rsnd_dma_quit(struct rsnd_priv *priv, struct rsnd_dma *dma); diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index 7fb879871a8e..f12c8b3aa475 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c @@ -30,8 +30,6 @@ struct rsnd_src { #define rsnd_src_convert_rate(p) ((p)->info->convert_rate) #define rsnd_mod_to_src(_mod) \ container_of((_mod), struct rsnd_src, mod) -#define rsnd_src_dma_available(src) \ - rsnd_dma_available(rsnd_mod_to_dma(&(src)->mod)) #define for_each_rsnd_src(pos, priv, i) \ for ((i) = 0; \ diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 57e737c7046b..fcc77ea369b9 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -80,8 +80,6 @@ struct rsnd_ssi { #define rsnd_mod_to_ssi(_mod) container_of((_mod), struct rsnd_ssi, mod) #define rsnd_dma_to_ssi(dma) rsnd_mod_to_ssi(rsnd_dma_to_mod(dma)) #define rsnd_ssi_pio_available(ssi) ((ssi)->info->irq > 0) -#define rsnd_ssi_dma_available(ssi) \ - rsnd_dma_available(rsnd_mod_to_dma(&(ssi)->mod)) #define rsnd_ssi_clk_from_parent(ssi) ((ssi)->parent) #define rsnd_ssi_mode_flags(p) ((p)->info->flags) #define rsnd_ssi_dai_id(ssi) ((ssi)->info->dai_id) -- GitLab From 8a2ff4262ca611c38b31fec0af65be656d934f52 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 20 Feb 2015 10:24:06 +0000 Subject: [PATCH 03338/11651] ASoC: rsnd: remove un-needed parameter from rsnd_dma_quit() priv is not used on rsnd_dma_quit() Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/core.c | 5 ++--- sound/soc/sh/rcar/rsnd.h | 3 +-- sound/soc/sh/rcar/src.c | 2 +- sound/soc/sh/rcar/ssi.c | 2 +- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 1da94bf730d2..7db686d0cbd8 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -358,7 +358,7 @@ int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id) return 0; rsnd_dma_init_err: - rsnd_dma_quit(priv, dma); + rsnd_dma_quit(dma); rsnd_dma_channel_err: /* @@ -370,8 +370,7 @@ rsnd_dma_channel_err: return -EAGAIN; } -void rsnd_dma_quit(struct rsnd_priv *priv, - struct rsnd_dma *dma) +void rsnd_dma_quit(struct rsnd_dma *dma) { if (dma->chan) dma_release_channel(dma->chan); diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index cb12861a1f3c..6ee97e7f9948 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -179,8 +179,7 @@ struct rsnd_dma { void rsnd_dma_start(struct rsnd_dma *dma); void rsnd_dma_stop(struct rsnd_dma *dma); int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id); -void rsnd_dma_quit(struct rsnd_priv *priv, - struct rsnd_dma *dma); +void rsnd_dma_quit(struct rsnd_dma *dma); /* diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index f12c8b3aa475..e2792056ce24 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c @@ -730,7 +730,7 @@ rsnd_src_probe_gen2_fail: static int rsnd_src_remove_gen2(struct rsnd_mod *mod, struct rsnd_priv *priv) { - rsnd_dma_quit(priv, rsnd_mod_to_dma(mod)); + rsnd_dma_quit(rsnd_mod_to_dma(mod)); return 0; } diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index fcc77ea369b9..a0d902ad5985 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -499,7 +499,7 @@ static int rsnd_ssi_dma_remove(struct rsnd_mod *mod, struct device *dev = rsnd_priv_to_dev(priv); int irq = ssi->info->irq; - rsnd_dma_quit(priv, rsnd_mod_to_dma(mod)); + rsnd_dma_quit(rsnd_mod_to_dma(mod)); /* PIO will request IRQ again */ devm_free_irq(dev, irq, ssi); -- GitLab From 4ce3b17bd43b4f0136b1d0c7782d06fe9d3addfb Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 20 Feb 2015 10:24:27 +0000 Subject: [PATCH 03339/11651] ASoC: rsnd: tidyup rsnd_dma_to_mod() macro declaration position Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/rsnd.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 6ee97e7f9948..ec77c9f1a57c 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -182,6 +182,8 @@ int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id); void rsnd_dma_quit(struct rsnd_dma *dma); +#define rsnd_dma_to_mod(_dma) container_of((_dma), struct rsnd_mod, dma) + /* * R-Car sound mod */ @@ -253,7 +255,6 @@ struct rsnd_mod { #define rsnd_mod_to_priv(mod) (rsnd_io_to_priv(rsnd_mod_to_io(mod))) #define rsnd_mod_to_dma(mod) (&(mod)->dma) -#define rsnd_dma_to_mod(_dma) container_of((_dma), struct rsnd_mod, dma) #define rsnd_mod_to_io(mod) ((mod)->io) #define rsnd_mod_id(mod) ((mod)->id) #define rsnd_mod_hw_start(mod) clk_prepare_enable((mod)->clk) -- GitLab From 7277911c87ba85436600f5b7aab15de112416795 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 20 Feb 2015 10:24:52 +0000 Subject: [PATCH 03340/11651] ASoC: rsnd: enable to get resource by name rsnd driver needs to support Audio DMAC peri peri inside sound driver. getting resource by name is useful for it Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/gen.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c index de0685f2abae..d08bcd3dbfbf 100644 --- a/sound/soc/sh/rcar/gen.c +++ b/sound/soc/sh/rcar/gen.c @@ -118,11 +118,12 @@ void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, mask, data); } -#define rsnd_gen_regmap_init(priv, id_size, reg_id, conf) \ - _rsnd_gen_regmap_init(priv, id_size, reg_id, conf, ARRAY_SIZE(conf)) +#define rsnd_gen_regmap_init(priv, id_size, reg_id, name, conf) \ + _rsnd_gen_regmap_init(priv, id_size, reg_id, name, conf, ARRAY_SIZE(conf)) static int _rsnd_gen_regmap_init(struct rsnd_priv *priv, int id_size, int reg_id, + const char *name, struct rsnd_regmap_field_conf *conf, int conf_size) { @@ -142,7 +143,9 @@ static int _rsnd_gen_regmap_init(struct rsnd_priv *priv, regc.val_bits = 32; regc.reg_stride = 4; - res = platform_get_resource(pdev, IORESOURCE_MEM, reg_id); + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name); + if (!res) + res = platform_get_resource(pdev, IORESOURCE_MEM, reg_id); if (!res) return -ENODEV; @@ -368,10 +371,10 @@ static int rsnd_gen2_probe(struct platform_device *pdev, int ret_adg; int ret_ssi; - ret_ssiu = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_SSIU, conf_ssiu); - ret_scu = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_SCU, conf_scu); - ret_adg = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_ADG, conf_adg); - ret_ssi = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_SSI, conf_ssi); + ret_ssiu = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_SSIU, "ssiu", conf_ssiu); + ret_scu = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_SCU, "scu", conf_scu); + ret_adg = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_ADG, "adg", conf_adg); + ret_ssi = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_SSI, "ssi", conf_ssi); if (ret_ssiu < 0 || ret_scu < 0 || ret_adg < 0 || @@ -440,9 +443,9 @@ static int rsnd_gen1_probe(struct platform_device *pdev, int ret_adg; int ret_ssi; - ret_sru = rsnd_gen_regmap_init(priv, 9, RSND_GEN1_SRU, conf_sru); - ret_adg = rsnd_gen_regmap_init(priv, 9, RSND_GEN1_ADG, conf_adg); - ret_ssi = rsnd_gen_regmap_init(priv, 9, RSND_GEN1_SSI, conf_ssi); + ret_sru = rsnd_gen_regmap_init(priv, 9, RSND_GEN1_SRU, "sru", conf_sru); + ret_adg = rsnd_gen_regmap_init(priv, 9, RSND_GEN1_ADG, "adg", conf_adg); + ret_ssi = rsnd_gen_regmap_init(priv, 9, RSND_GEN1_SSI, "ssi", conf_ssi); if (ret_sru < 0 || ret_adg < 0 || ret_ssi < 0) -- GitLab From c5212b4556b6bd120b0f4e4ae7c4a1cb9f5efe07 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 20 Feb 2015 10:25:27 +0000 Subject: [PATCH 03341/11651] ASoC: rsnd: add rsnd_gen_get_phy_addr() to get physical address physical address is required from Audio DMAC peri peri. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/gen.c | 16 +++++++++++----- sound/soc/sh/rcar/rsnd.h | 1 + 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c index d08bcd3dbfbf..0da04ed3aabe 100644 --- a/sound/soc/sh/rcar/gen.c +++ b/sound/soc/sh/rcar/gen.c @@ -28,6 +28,7 @@ struct rsnd_gen { struct regmap *regmap[RSND_BASE_MAX]; struct regmap_field *regs[RSND_REG_MAX]; + phys_addr_t res[RSND_REG_MAX]; }; #define rsnd_priv_to_gen(p) ((struct rsnd_gen *)(p)->gen) @@ -118,6 +119,13 @@ void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, mask, data); } +phys_addr_t rsnd_gen_get_phy_addr(struct rsnd_priv *priv, int reg_id) +{ + struct rsnd_gen *gen = rsnd_priv_to_gen(priv); + + return gen->res[reg_id]; +} + #define rsnd_gen_regmap_init(priv, id_size, reg_id, name, conf) \ _rsnd_gen_regmap_init(priv, id_size, reg_id, name, conf, ARRAY_SIZE(conf)) static int _rsnd_gen_regmap_init(struct rsnd_priv *priv, @@ -159,6 +167,7 @@ static int _rsnd_gen_regmap_init(struct rsnd_priv *priv, gen->base[reg_id] = base; gen->regmap[reg_id] = regmap; + gen->res[reg_id] = res->start; for (i = 0; i < conf_size; i++) { @@ -216,13 +225,10 @@ rsnd_gen2_dma_addr(struct rsnd_priv *priv, struct rsnd_mod *mod, int is_play, int is_from) { - struct platform_device *pdev = rsnd_priv_to_pdev(priv); struct device *dev = rsnd_priv_to_dev(priv); struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); - dma_addr_t ssi_reg = platform_get_resource(pdev, - IORESOURCE_MEM, RSND_GEN2_SSI)->start; - dma_addr_t src_reg = platform_get_resource(pdev, - IORESOURCE_MEM, RSND_GEN2_SCU)->start; + phys_addr_t ssi_reg = rsnd_gen_get_phy_addr(priv, RSND_GEN2_SSI); + phys_addr_t src_reg = rsnd_gen_get_phy_addr(priv, RSND_GEN2_SCU); int is_ssi = !!(rsnd_io_to_mod_ssi(io) == mod); int use_src = !!rsnd_io_to_mod_src(io); int use_dvc = !!rsnd_io_to_mod_dvc(io); diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index ec77c9f1a57c..8a8a4d5d55ef 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -331,6 +331,7 @@ void __iomem *rsnd_gen_reg_get(struct rsnd_priv *priv, dma_addr_t rsnd_gen_dma_addr(struct rsnd_priv *priv, struct rsnd_mod *mod, int is_play, int is_from); +phys_addr_t rsnd_gen_get_phy_addr(struct rsnd_priv *priv, int reg_id); #define rsnd_is_gen1(s) (((s)->info->flags & RSND_GEN_MASK) == RSND_GEN1) #define rsnd_is_gen2(s) (((s)->info->flags & RSND_GEN_MASK) == RSND_GEN2) -- GitLab From bfe834be9525a82c8a40380c7df8ca3b149e9c93 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 20 Feb 2015 10:25:55 +0000 Subject: [PATCH 03342/11651] ASoC: rsnd: add dma.c for Audio DMAC / Audio DMAC peri peri Renesas sound driver had been assumed that Audio DMAC / Audio DMAC peri peri are implemented by DMAEngine. But, result of DMA ML discussion, it was concluded that it is not a general purpose DMAC. And it should be moved from current DMAEngine to rsnd driver. So, Audio DMAC peri peri become non DMAEngine. OTOH, ALSA SoC has soc-generic-dmaengine-pcm implementation. but it seems difficult to use this generic implementation on rsnd driver at this point, since it needs to fallback to PIO mode if DMA can't use. and additionally it needs 2 DMAC (= Audio DMAC / Audio DMAC peri peri). These are not "generic" feature. Of course I will try to use this generic dmaengine in the future somehow, but just use current style at this point until it can formally use 2 DMACs. This patch adds new dma.c and moves current dma code to dma.c from core.c. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/Makefile | 2 +- sound/soc/sh/rcar/core.c | 218 ---------------------------------- sound/soc/sh/rcar/dma.c | 231 +++++++++++++++++++++++++++++++++++++ 3 files changed, 232 insertions(+), 219 deletions(-) create mode 100644 sound/soc/sh/rcar/dma.c diff --git a/sound/soc/sh/rcar/Makefile b/sound/soc/sh/rcar/Makefile index 9ac536429800..7b204925b8c5 100644 --- a/sound/soc/sh/rcar/Makefile +++ b/sound/soc/sh/rcar/Makefile @@ -1,2 +1,2 @@ -snd-soc-rcar-objs := core.o gen.o src.o adg.o ssi.o dvc.o +snd-soc-rcar-objs := core.o gen.o dma.o src.o adg.o ssi.o dvc.o obj-$(CONFIG_SND_SOC_RCAR) += snd-soc-rcar.o \ No newline at end of file diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 7db686d0cbd8..9beea9ba338a 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -160,224 +160,6 @@ void rsnd_mod_init(struct rsnd_mod *mod, mod->clk = clk; } -/* - * rsnd_dma functions - */ -void rsnd_dma_stop(struct rsnd_dma *dma) -{ - dmaengine_terminate_all(dma->chan); -} - -static void rsnd_dma_complete(void *data) -{ - struct rsnd_dma *dma = (struct rsnd_dma *)data; - struct rsnd_mod *mod = rsnd_dma_to_mod(dma); - struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); - - /* - * Renesas sound Gen1 needs 1 DMAC, - * Gen2 needs 2 DMAC. - * In Gen2 case, it are Audio-DMAC, and Audio-DMAC-peri-peri. - * But, Audio-DMAC-peri-peri doesn't have interrupt, - * and this driver is assuming that here. - * - * If Audio-DMAC-peri-peri has interrpt, - * rsnd_dai_pointer_update() will be called twice, - * ant it will breaks io->byte_pos - */ - - rsnd_dai_pointer_update(io, io->byte_per_period); -} - -void rsnd_dma_start(struct rsnd_dma *dma) -{ - struct rsnd_mod *mod = rsnd_dma_to_mod(dma); - struct rsnd_priv *priv = rsnd_mod_to_priv(mod); - struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); - struct snd_pcm_substream *substream = io->substream; - struct device *dev = rsnd_priv_to_dev(priv); - struct dma_async_tx_descriptor *desc; - - desc = dmaengine_prep_dma_cyclic(dma->chan, - (dma->addr) ? dma->addr : - substream->runtime->dma_addr, - snd_pcm_lib_buffer_bytes(substream), - snd_pcm_lib_period_bytes(substream), - dma->dir, - DMA_PREP_INTERRUPT | DMA_CTRL_ACK); - - if (!desc) { - dev_err(dev, "dmaengine_prep_slave_sg() fail\n"); - return; - } - - desc->callback = rsnd_dma_complete; - desc->callback_param = dma; - - if (dmaengine_submit(desc) < 0) { - dev_err(dev, "dmaengine_submit() fail\n"); - return; - } - - dma_async_issue_pending(dma->chan); -} - -#define DMA_NAME_SIZE 16 -#define MOD_MAX 4 /* MEM/SSI/SRC/DVC */ -static int _rsnd_dma_of_name(char *dma_name, struct rsnd_mod *mod) -{ - if (mod) - return snprintf(dma_name, DMA_NAME_SIZE / 2, "%s%d", - rsnd_mod_dma_name(mod), rsnd_mod_id(mod)); - else - return snprintf(dma_name, DMA_NAME_SIZE / 2, "mem"); - -} - -static void rsnd_dma_of_name(struct rsnd_mod *mod_from, - struct rsnd_mod *mod_to, - char *dma_name) -{ - int index = 0; - - index = _rsnd_dma_of_name(dma_name + index, mod_from); - *(dma_name + index++) = '_'; - index = _rsnd_dma_of_name(dma_name + index, mod_to); -} - -static void rsnd_dma_of_path(struct rsnd_dma *dma, - int is_play, - struct rsnd_mod **mod_from, - struct rsnd_mod **mod_to) -{ - struct rsnd_mod *this = rsnd_dma_to_mod(dma); - struct rsnd_dai_stream *io = rsnd_mod_to_io(this); - struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io); - struct rsnd_mod *src = rsnd_io_to_mod_src(io); - struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io); - struct rsnd_mod *mod[MOD_MAX]; - int i, index; - - - for (i = 0; i < MOD_MAX; i++) - mod[i] = NULL; - - /* - * in play case... - * - * src -> dst - * - * mem -> SSI - * mem -> SRC -> SSI - * mem -> SRC -> DVC -> SSI - */ - mod[0] = NULL; /* for "mem" */ - index = 1; - for (i = 1; i < MOD_MAX; i++) { - if (!src) { - mod[i] = ssi; - } else if (!dvc) { - mod[i] = src; - src = NULL; - } else { - if ((!is_play) && (this == src)) - this = dvc; - - mod[i] = (is_play) ? src : dvc; - i++; - mod[i] = (is_play) ? dvc : src; - src = NULL; - dvc = NULL; - } - - if (mod[i] == this) - index = i; - - if (mod[i] == ssi) - break; - } - - if (is_play) { - *mod_from = mod[index - 1]; - *mod_to = mod[index]; - } else { - *mod_from = mod[index]; - *mod_to = mod[index - 1]; - } -} - -int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id) -{ - struct device *dev = rsnd_priv_to_dev(priv); - struct dma_slave_config cfg; - struct rsnd_mod *mod = rsnd_dma_to_mod(dma); - struct rsnd_mod *mod_from; - struct rsnd_mod *mod_to; - struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); - int is_play = rsnd_io_is_play(io); - char dma_name[DMA_NAME_SIZE]; - dma_cap_mask_t mask; - int ret; - - if (dma->chan) { - dev_err(dev, "it already has dma channel\n"); - return -EIO; - } - - dma_cap_zero(mask); - dma_cap_set(DMA_SLAVE, mask); - - rsnd_dma_of_path(dma, is_play, &mod_from, &mod_to); - rsnd_dma_of_name(mod_from, mod_to, dma_name); - - cfg.slave_id = id; - cfg.direction = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM; - cfg.src_addr = rsnd_gen_dma_addr(priv, mod_from, is_play, 1); - cfg.dst_addr = rsnd_gen_dma_addr(priv, mod_to, is_play, 0); - cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; - cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; - - dev_dbg(dev, "dma : %s %pad -> %pad\n", - dma_name, &cfg.src_addr, &cfg.dst_addr); - - dma->chan = dma_request_slave_channel_compat(mask, shdma_chan_filter, - (void *)id, dev, - dma_name); - if (!dma->chan) { - dev_err(dev, "can't get dma channel\n"); - goto rsnd_dma_channel_err; - } - - ret = dmaengine_slave_config(dma->chan, &cfg); - if (ret < 0) - goto rsnd_dma_init_err; - - dma->addr = is_play ? cfg.src_addr : cfg.dst_addr; - dma->dir = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM; - - return 0; - -rsnd_dma_init_err: - rsnd_dma_quit(dma); -rsnd_dma_channel_err: - - /* - * DMA failed. try to PIO mode - * see - * rsnd_ssi_fallback() - * rsnd_rdai_continuance_probe() - */ - return -EAGAIN; -} - -void rsnd_dma_quit(struct rsnd_dma *dma) -{ - if (dma->chan) - dma_release_channel(dma->chan); - - dma->chan = NULL; -} - /* * settting function */ diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c new file mode 100644 index 000000000000..37acd409e88c --- /dev/null +++ b/sound/soc/sh/rcar/dma.c @@ -0,0 +1,231 @@ +/* + * Renesas R-Car Audio DMAC support + * + * Copyright (C) 2015 Renesas Electronics Corp. + * Copyright (c) 2015 Kuninori Morimoto + * + * 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 "rsnd.h" + +static void rsnd_dma_complete(void *data) +{ + struct rsnd_dma *dma = (struct rsnd_dma *)data; + struct rsnd_mod *mod = rsnd_dma_to_mod(dma); + struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); + + /* + * Renesas sound Gen1 needs 1 DMAC, + * Gen2 needs 2 DMAC. + * In Gen2 case, it are Audio-DMAC, and Audio-DMAC-peri-peri. + * But, Audio-DMAC-peri-peri doesn't have interrupt, + * and this driver is assuming that here. + * + * If Audio-DMAC-peri-peri has interrpt, + * rsnd_dai_pointer_update() will be called twice, + * ant it will breaks io->byte_pos + */ + + rsnd_dai_pointer_update(io, io->byte_per_period); +} + +#define DMA_NAME_SIZE 16 +#define MOD_MAX 4 /* MEM/SSI/SRC/DVC */ +static int _rsnd_dma_of_name(char *dma_name, struct rsnd_mod *mod) +{ + if (mod) + return snprintf(dma_name, DMA_NAME_SIZE / 2, "%s%d", + rsnd_mod_dma_name(mod), rsnd_mod_id(mod)); + else + return snprintf(dma_name, DMA_NAME_SIZE / 2, "mem"); + +} + +static void rsnd_dma_of_name(struct rsnd_mod *mod_from, + struct rsnd_mod *mod_to, + char *dma_name) +{ + int index = 0; + + index = _rsnd_dma_of_name(dma_name + index, mod_from); + *(dma_name + index++) = '_'; + index = _rsnd_dma_of_name(dma_name + index, mod_to); +} + +void rsnd_dma_stop(struct rsnd_dma *dma) +{ + dmaengine_terminate_all(dma->chan); +} + +void rsnd_dma_start(struct rsnd_dma *dma) +{ + struct rsnd_mod *mod = rsnd_dma_to_mod(dma); + struct rsnd_priv *priv = rsnd_mod_to_priv(mod); + struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); + struct snd_pcm_substream *substream = io->substream; + struct device *dev = rsnd_priv_to_dev(priv); + struct dma_async_tx_descriptor *desc; + + desc = dmaengine_prep_dma_cyclic(dma->chan, + (dma->addr) ? dma->addr : + substream->runtime->dma_addr, + snd_pcm_lib_buffer_bytes(substream), + snd_pcm_lib_period_bytes(substream), + dma->dir, + DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + + if (!desc) { + dev_err(dev, "dmaengine_prep_slave_sg() fail\n"); + return; + } + + desc->callback = rsnd_dma_complete; + desc->callback_param = dma; + + if (dmaengine_submit(desc) < 0) { + dev_err(dev, "dmaengine_submit() fail\n"); + return; + } + + dma_async_issue_pending(dma->chan); +} + +static void rsnd_dma_of_path(struct rsnd_dma *dma, + int is_play, + struct rsnd_mod **mod_from, + struct rsnd_mod **mod_to); + +int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id) +{ + struct device *dev = rsnd_priv_to_dev(priv); + struct dma_slave_config cfg = {}; + struct rsnd_mod *mod = rsnd_dma_to_mod(dma); + struct rsnd_mod *mod_from; + struct rsnd_mod *mod_to; + struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); + int is_play = rsnd_io_is_play(io); + char dma_name[DMA_NAME_SIZE]; + dma_cap_mask_t mask; + int ret; + + if (dma->chan) { + dev_err(dev, "it already has dma channel\n"); + return -EIO; + } + + dma_cap_zero(mask); + dma_cap_set(DMA_SLAVE, mask); + + rsnd_dma_of_path(dma, is_play, &mod_from, &mod_to); + rsnd_dma_of_name(mod_from, mod_to, dma_name); + + cfg.direction = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM; + cfg.src_addr = rsnd_gen_dma_addr(priv, mod_from, is_play, 1); + cfg.dst_addr = rsnd_gen_dma_addr(priv, mod_to, is_play, 0); + cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + + dev_dbg(dev, "dma : %s %pad -> %pad\n", + dma_name, &cfg.src_addr, &cfg.dst_addr); + + dma->chan = dma_request_slave_channel_compat(mask, shdma_chan_filter, + (void *)id, dev, + dma_name); + if (!dma->chan) { + dev_err(dev, "can't get dma channel\n"); + goto rsnd_dma_channel_err; + } + + ret = dmaengine_slave_config(dma->chan, &cfg); + if (ret < 0) + goto rsnd_dma_init_err; + + dma->addr = is_play ? cfg.src_addr : cfg.dst_addr; + dma->dir = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM; + + return 0; + +rsnd_dma_init_err: + rsnd_dma_quit(dma); +rsnd_dma_channel_err: + + /* + * DMA failed. try to PIO mode + * see + * rsnd_ssi_fallback() + * rsnd_rdai_continuance_probe() + */ + return -EAGAIN; +} + +void rsnd_dma_quit(struct rsnd_dma *dma) +{ + if (dma->chan) + dma_release_channel(dma->chan); + + dma->chan = NULL; +} + +static void rsnd_dma_of_path(struct rsnd_dma *dma, + int is_play, + struct rsnd_mod **mod_from, + struct rsnd_mod **mod_to) +{ + struct rsnd_mod *this = rsnd_dma_to_mod(dma); + struct rsnd_dai_stream *io = rsnd_mod_to_io(this); + struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io); + struct rsnd_mod *src = rsnd_io_to_mod_src(io); + struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io); + struct rsnd_mod *mod[MOD_MAX]; + int i, index; + + + for (i = 0; i < MOD_MAX; i++) + mod[i] = NULL; + + /* + * in play case... + * + * src -> dst + * + * mem -> SSI + * mem -> SRC -> SSI + * mem -> SRC -> DVC -> SSI + */ + mod[0] = NULL; /* for "mem" */ + index = 1; + for (i = 1; i < MOD_MAX; i++) { + if (!src) { + mod[i] = ssi; + } else if (!dvc) { + mod[i] = src; + src = NULL; + } else { + if ((!is_play) && (this == src)) + this = dvc; + + mod[i] = (is_play) ? src : dvc; + i++; + mod[i] = (is_play) ? dvc : src; + src = NULL; + dvc = NULL; + } + + if (mod[i] == this) + index = i; + + if (mod[i] == ssi) + break; + } + + if (is_play) { + *mod_from = mod[index - 1]; + *mod_to = mod[index]; + } else { + *mod_from = mod[index]; + *mod_to = mod[index - 1]; + } +} + -- GitLab From 747c71b12ee8357e73a88eb25f569e2a20e80df3 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 20 Feb 2015 10:26:29 +0000 Subject: [PATCH 03343/11651] ASoC: rsnd: move rsnd_gen_dma_addr() from gen.c to dma.c Now, we have dma.c for Audio DMAC / Audio DMAC peri peri. rsnd_gen_dma_addr() should go there. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/dma.c | 120 ++++++++++++++++++++++++++++++++++++++- sound/soc/sh/rcar/gen.c | 110 ----------------------------------- sound/soc/sh/rcar/rsnd.h | 3 - 3 files changed, 117 insertions(+), 116 deletions(-) diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c index 37acd409e88c..188b4634939c 100644 --- a/sound/soc/sh/rcar/dma.c +++ b/sound/soc/sh/rcar/dma.c @@ -32,7 +32,6 @@ static void rsnd_dma_complete(void *data) } #define DMA_NAME_SIZE 16 -#define MOD_MAX 4 /* MEM/SSI/SRC/DVC */ static int _rsnd_dma_of_name(char *dma_name, struct rsnd_mod *mod) { if (mod) @@ -97,6 +96,10 @@ static void rsnd_dma_of_path(struct rsnd_dma *dma, struct rsnd_mod **mod_from, struct rsnd_mod **mod_to); +static dma_addr_t rsnd_dma_addr(struct rsnd_priv *priv, + struct rsnd_mod *mod, + int is_play, int is_from); + int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id) { struct device *dev = rsnd_priv_to_dev(priv); @@ -122,8 +125,8 @@ int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id) rsnd_dma_of_name(mod_from, mod_to, dma_name); cfg.direction = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM; - cfg.src_addr = rsnd_gen_dma_addr(priv, mod_from, is_play, 1); - cfg.dst_addr = rsnd_gen_dma_addr(priv, mod_to, is_play, 0); + cfg.src_addr = rsnd_dma_addr(priv, mod_from, is_play, 1); + cfg.dst_addr = rsnd_dma_addr(priv, mod_to, is_play, 0); cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; @@ -168,6 +171,117 @@ void rsnd_dma_quit(struct rsnd_dma *dma) dma->chan = NULL; } +/* + * DMA read/write register offset + * + * RSND_xxx_I_N for Audio DMAC input + * RSND_xxx_O_N for Audio DMAC output + * RSND_xxx_I_P for Audio DMAC peri peri input + * RSND_xxx_O_P for Audio DMAC peri peri output + * + * ex) R-Car H2 case + * mod / DMAC in / DMAC out / DMAC PP in / DMAC pp out + * SSI : 0xec541000 / 0xec241008 / 0xec24100c + * SSIU: 0xec541000 / 0xec100000 / 0xec100000 / 0xec400000 / 0xec400000 + * SCU : 0xec500000 / 0xec000000 / 0xec004000 / 0xec300000 / 0xec304000 + * CMD : 0xec500000 / / 0xec008000 0xec308000 + */ +#define RDMA_SSI_I_N(addr, i) (addr ##_reg - 0x00300000 + (0x40 * i) + 0x8) +#define RDMA_SSI_O_N(addr, i) (addr ##_reg - 0x00300000 + (0x40 * i) + 0xc) + +#define RDMA_SSIU_I_N(addr, i) (addr ##_reg - 0x00441000 + (0x1000 * i)) +#define RDMA_SSIU_O_N(addr, i) (addr ##_reg - 0x00441000 + (0x1000 * i)) + +#define RDMA_SSIU_I_P(addr, i) (addr ##_reg - 0x00141000 + (0x1000 * i)) +#define RDMA_SSIU_O_P(addr, i) (addr ##_reg - 0x00141000 + (0x1000 * i)) + +#define RDMA_SRC_I_N(addr, i) (addr ##_reg - 0x00500000 + (0x400 * i)) +#define RDMA_SRC_O_N(addr, i) (addr ##_reg - 0x004fc000 + (0x400 * i)) + +#define RDMA_SRC_I_P(addr, i) (addr ##_reg - 0x00200000 + (0x400 * i)) +#define RDMA_SRC_O_P(addr, i) (addr ##_reg - 0x001fc000 + (0x400 * i)) + +#define RDMA_CMD_O_N(addr, i) (addr ##_reg - 0x004f8000 + (0x400 * i)) +#define RDMA_CMD_O_P(addr, i) (addr ##_reg - 0x001f8000 + (0x400 * i)) + +static dma_addr_t +rsnd_gen2_dma_addr(struct rsnd_priv *priv, + struct rsnd_mod *mod, + int is_play, int is_from) +{ + struct device *dev = rsnd_priv_to_dev(priv); + struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); + phys_addr_t ssi_reg = rsnd_gen_get_phy_addr(priv, RSND_GEN2_SSI); + phys_addr_t src_reg = rsnd_gen_get_phy_addr(priv, RSND_GEN2_SCU); + int is_ssi = !!(rsnd_io_to_mod_ssi(io) == mod); + int use_src = !!rsnd_io_to_mod_src(io); + int use_dvc = !!rsnd_io_to_mod_dvc(io); + int id = rsnd_mod_id(mod); + struct dma_addr { + dma_addr_t out_addr; + dma_addr_t in_addr; + } dma_addrs[3][2][3] = { + /* SRC */ + {{{ 0, 0 }, + /* Capture */ + { RDMA_SRC_O_N(src, id), RDMA_SRC_I_P(src, id) }, + { RDMA_CMD_O_N(src, id), RDMA_SRC_I_P(src, id) } }, + /* Playback */ + {{ 0, 0, }, + { RDMA_SRC_O_P(src, id), RDMA_SRC_I_N(src, id) }, + { RDMA_CMD_O_P(src, id), RDMA_SRC_I_N(src, id) } } + }, + /* SSI */ + /* Capture */ + {{{ RDMA_SSI_O_N(ssi, id), 0 }, + { RDMA_SSIU_O_P(ssi, id), 0 }, + { RDMA_SSIU_O_P(ssi, id), 0 } }, + /* Playback */ + {{ 0, RDMA_SSI_I_N(ssi, id) }, + { 0, RDMA_SSIU_I_P(ssi, id) }, + { 0, RDMA_SSIU_I_P(ssi, id) } } + }, + /* SSIU */ + /* Capture */ + {{{ RDMA_SSIU_O_N(ssi, id), 0 }, + { RDMA_SSIU_O_P(ssi, id), 0 }, + { RDMA_SSIU_O_P(ssi, id), 0 } }, + /* Playback */ + {{ 0, RDMA_SSIU_I_N(ssi, id) }, + { 0, RDMA_SSIU_I_P(ssi, id) }, + { 0, RDMA_SSIU_I_P(ssi, id) } } }, + }; + + /* it shouldn't happen */ + if (use_dvc && !use_src) + dev_err(dev, "DVC is selected without SRC\n"); + + /* use SSIU or SSI ? */ + if (is_ssi && (0 == strcmp(rsnd_mod_dma_name(mod), "ssiu"))) + is_ssi++; + + return (is_from) ? + dma_addrs[is_ssi][is_play][use_src + use_dvc].out_addr : + dma_addrs[is_ssi][is_play][use_src + use_dvc].in_addr; +} + +static dma_addr_t rsnd_dma_addr(struct rsnd_priv *priv, + struct rsnd_mod *mod, + int is_play, int is_from) +{ + /* + * gen1 uses default DMA addr + */ + if (rsnd_is_gen1(priv)) + return 0; + + if (!mod) + return 0; + + return rsnd_gen2_dma_addr(priv, mod, is_play, is_from); +} + +#define MOD_MAX 4 /* MEM/SSI/SRC/DVC */ static void rsnd_dma_of_path(struct rsnd_dma *dma, int is_play, struct rsnd_mod **mod_from, diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c index 0da04ed3aabe..0273724a2668 100644 --- a/sound/soc/sh/rcar/gen.c +++ b/sound/soc/sh/rcar/gen.c @@ -187,116 +187,6 @@ static int _rsnd_gen_regmap_init(struct rsnd_priv *priv, return 0; } -/* - * DMA read/write register offset - * - * RSND_xxx_I_N for Audio DMAC input - * RSND_xxx_O_N for Audio DMAC output - * RSND_xxx_I_P for Audio DMAC peri peri input - * RSND_xxx_O_P for Audio DMAC peri peri output - * - * ex) R-Car H2 case - * mod / DMAC in / DMAC out / DMAC PP in / DMAC pp out - * SSI : 0xec541000 / 0xec241008 / 0xec24100c - * SSIU: 0xec541000 / 0xec100000 / 0xec100000 / 0xec400000 / 0xec400000 - * SCU : 0xec500000 / 0xec000000 / 0xec004000 / 0xec300000 / 0xec304000 - * CMD : 0xec500000 / / 0xec008000 0xec308000 - */ -#define RDMA_SSI_I_N(addr, i) (addr ##_reg - 0x00300000 + (0x40 * i) + 0x8) -#define RDMA_SSI_O_N(addr, i) (addr ##_reg - 0x00300000 + (0x40 * i) + 0xc) - -#define RDMA_SSIU_I_N(addr, i) (addr ##_reg - 0x00441000 + (0x1000 * i)) -#define RDMA_SSIU_O_N(addr, i) (addr ##_reg - 0x00441000 + (0x1000 * i)) - -#define RDMA_SSIU_I_P(addr, i) (addr ##_reg - 0x00141000 + (0x1000 * i)) -#define RDMA_SSIU_O_P(addr, i) (addr ##_reg - 0x00141000 + (0x1000 * i)) - -#define RDMA_SRC_I_N(addr, i) (addr ##_reg - 0x00500000 + (0x400 * i)) -#define RDMA_SRC_O_N(addr, i) (addr ##_reg - 0x004fc000 + (0x400 * i)) - -#define RDMA_SRC_I_P(addr, i) (addr ##_reg - 0x00200000 + (0x400 * i)) -#define RDMA_SRC_O_P(addr, i) (addr ##_reg - 0x001fc000 + (0x400 * i)) - -#define RDMA_CMD_O_N(addr, i) (addr ##_reg - 0x004f8000 + (0x400 * i)) -#define RDMA_CMD_O_P(addr, i) (addr ##_reg - 0x001f8000 + (0x400 * i)) - -static dma_addr_t -rsnd_gen2_dma_addr(struct rsnd_priv *priv, - struct rsnd_mod *mod, - int is_play, int is_from) -{ - struct device *dev = rsnd_priv_to_dev(priv); - struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); - phys_addr_t ssi_reg = rsnd_gen_get_phy_addr(priv, RSND_GEN2_SSI); - phys_addr_t src_reg = rsnd_gen_get_phy_addr(priv, RSND_GEN2_SCU); - int is_ssi = !!(rsnd_io_to_mod_ssi(io) == mod); - int use_src = !!rsnd_io_to_mod_src(io); - int use_dvc = !!rsnd_io_to_mod_dvc(io); - int id = rsnd_mod_id(mod); - struct dma_addr { - dma_addr_t out_addr; - dma_addr_t in_addr; - } dma_addrs[3][2][3] = { - /* SRC */ - {{{ 0, 0 }, - /* Capture */ - { RDMA_SRC_O_N(src, id), RDMA_SRC_I_P(src, id) }, - { RDMA_CMD_O_N(src, id), RDMA_SRC_I_P(src, id) } }, - /* Playback */ - {{ 0, 0, }, - { RDMA_SRC_O_P(src, id), RDMA_SRC_I_N(src, id) }, - { RDMA_CMD_O_P(src, id), RDMA_SRC_I_N(src, id) } } - }, - /* SSI */ - /* Capture */ - {{{ RDMA_SSI_O_N(ssi, id), 0 }, - { RDMA_SSIU_O_P(ssi, id), 0 }, - { RDMA_SSIU_O_P(ssi, id), 0 } }, - /* Playback */ - {{ 0, RDMA_SSI_I_N(ssi, id) }, - { 0, RDMA_SSIU_I_P(ssi, id) }, - { 0, RDMA_SSIU_I_P(ssi, id) } } - }, - /* SSIU */ - /* Capture */ - {{{ RDMA_SSIU_O_N(ssi, id), 0 }, - { RDMA_SSIU_O_P(ssi, id), 0 }, - { RDMA_SSIU_O_P(ssi, id), 0 } }, - /* Playback */ - {{ 0, RDMA_SSIU_I_N(ssi, id) }, - { 0, RDMA_SSIU_I_P(ssi, id) }, - { 0, RDMA_SSIU_I_P(ssi, id) } } }, - }; - - /* it shouldn't happen */ - if (use_dvc && !use_src) - dev_err(dev, "DVC is selected without SRC\n"); - - /* use SSIU or SSI ? */ - if (is_ssi && (0 == strcmp(rsnd_mod_dma_name(mod), "ssiu"))) - is_ssi++; - - return (is_from) ? - dma_addrs[is_ssi][is_play][use_src + use_dvc].out_addr : - dma_addrs[is_ssi][is_play][use_src + use_dvc].in_addr; -} - -dma_addr_t rsnd_gen_dma_addr(struct rsnd_priv *priv, - struct rsnd_mod *mod, - int is_play, int is_from) -{ - /* - * gen1 uses default DMA addr - */ - if (rsnd_is_gen1(priv)) - return 0; - - if (!mod) - return 0; - - return rsnd_gen2_dma_addr(priv, mod, is_play, is_from); -} - /* * Gen2 */ diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 8a8a4d5d55ef..a73e94c1d785 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -328,9 +328,6 @@ int rsnd_gen_probe(struct platform_device *pdev, void __iomem *rsnd_gen_reg_get(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg); -dma_addr_t rsnd_gen_dma_addr(struct rsnd_priv *priv, - struct rsnd_mod *mod, - int is_play, int is_from); phys_addr_t rsnd_gen_get_phy_addr(struct rsnd_priv *priv, int reg_id); #define rsnd_is_gen1(s) (((s)->info->flags & RSND_GEN_MASK) == RSND_GEN1) -- GitLab From 3c68565b6cb68b731b51eb21b59dce901002fc6e Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 20 Feb 2015 10:27:12 +0000 Subject: [PATCH 03344/11651] ASoC: rsnd: enable to care 1st / 2nd DMAC on rsnd_dma_xxx() rsnd driver needs to care about Audio DAMC (via DMAEngine), Audio DMAC peri peri (via local method) on rsnd driver. This patch adds new rsnd_dma_ops and care it. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/dma.c | 78 +++++++++++++++++++++++++++------------- sound/soc/sh/rcar/rsnd.h | 12 +++++++ 2 files changed, 65 insertions(+), 25 deletions(-) diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c index 188b4634939c..c911c079fdd0 100644 --- a/sound/soc/sh/rcar/dma.c +++ b/sound/soc/sh/rcar/dma.c @@ -10,7 +10,7 @@ */ #include "rsnd.h" -static void rsnd_dma_complete(void *data) +static void rsnd_dmaen_complete(void *data) { struct rsnd_dma *dma = (struct rsnd_dma *)data; struct rsnd_mod *mod = rsnd_dma_to_mod(dma); @@ -32,7 +32,7 @@ static void rsnd_dma_complete(void *data) } #define DMA_NAME_SIZE 16 -static int _rsnd_dma_of_name(char *dma_name, struct rsnd_mod *mod) +static int _rsnd_dmaen_of_name(char *dma_name, struct rsnd_mod *mod) { if (mod) return snprintf(dma_name, DMA_NAME_SIZE / 2, "%s%d", @@ -42,23 +42,23 @@ static int _rsnd_dma_of_name(char *dma_name, struct rsnd_mod *mod) } -static void rsnd_dma_of_name(struct rsnd_mod *mod_from, +static void rsnd_dmaen_of_name(struct rsnd_mod *mod_from, struct rsnd_mod *mod_to, char *dma_name) { int index = 0; - index = _rsnd_dma_of_name(dma_name + index, mod_from); + index = _rsnd_dmaen_of_name(dma_name + index, mod_from); *(dma_name + index++) = '_'; - index = _rsnd_dma_of_name(dma_name + index, mod_to); + index = _rsnd_dmaen_of_name(dma_name + index, mod_to); } -void rsnd_dma_stop(struct rsnd_dma *dma) +static void rsnd_dmaen_stop(struct rsnd_dma *dma) { dmaengine_terminate_all(dma->chan); } -void rsnd_dma_start(struct rsnd_dma *dma) +static void rsnd_dmaen_start(struct rsnd_dma *dma) { struct rsnd_mod *mod = rsnd_dma_to_mod(dma); struct rsnd_priv *priv = rsnd_mod_to_priv(mod); @@ -80,7 +80,7 @@ void rsnd_dma_start(struct rsnd_dma *dma) return; } - desc->callback = rsnd_dma_complete; + desc->callback = rsnd_dmaen_complete; desc->callback_param = dma; if (dmaengine_submit(desc) < 0) { @@ -91,22 +91,12 @@ void rsnd_dma_start(struct rsnd_dma *dma) dma_async_issue_pending(dma->chan); } -static void rsnd_dma_of_path(struct rsnd_dma *dma, - int is_play, - struct rsnd_mod **mod_from, - struct rsnd_mod **mod_to); - -static dma_addr_t rsnd_dma_addr(struct rsnd_priv *priv, - struct rsnd_mod *mod, - int is_play, int is_from); - -int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id) +static int rsnd_dmaen_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id, + struct rsnd_mod *mod_from, struct rsnd_mod *mod_to) { struct device *dev = rsnd_priv_to_dev(priv); struct dma_slave_config cfg = {}; struct rsnd_mod *mod = rsnd_dma_to_mod(dma); - struct rsnd_mod *mod_from; - struct rsnd_mod *mod_to; struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); int is_play = rsnd_io_is_play(io); char dma_name[DMA_NAME_SIZE]; @@ -121,12 +111,11 @@ int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id) dma_cap_zero(mask); dma_cap_set(DMA_SLAVE, mask); - rsnd_dma_of_path(dma, is_play, &mod_from, &mod_to); - rsnd_dma_of_name(mod_from, mod_to, dma_name); + rsnd_dmaen_of_name(mod_from, mod_to, dma_name); cfg.direction = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM; - cfg.src_addr = rsnd_dma_addr(priv, mod_from, is_play, 1); - cfg.dst_addr = rsnd_dma_addr(priv, mod_to, is_play, 0); + cfg.src_addr = dma->src_addr; + cfg.dst_addr = dma->dst_addr; cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; @@ -163,7 +152,7 @@ rsnd_dma_channel_err: return -EAGAIN; } -void rsnd_dma_quit(struct rsnd_dma *dma) +static void rsnd_dmaen_quit(struct rsnd_dma *dma) { if (dma->chan) dma_release_channel(dma->chan); @@ -171,6 +160,13 @@ void rsnd_dma_quit(struct rsnd_dma *dma) dma->chan = NULL; } +static struct rsnd_dma_ops rsnd_dmaen_ops = { + .start = rsnd_dmaen_start, + .stop = rsnd_dmaen_stop, + .init = rsnd_dmaen_init, + .quit = rsnd_dmaen_quit, +}; + /* * DMA read/write register offset * @@ -343,3 +339,35 @@ static void rsnd_dma_of_path(struct rsnd_dma *dma, } } +void rsnd_dma_stop(struct rsnd_dma *dma) +{ + dma->ops->stop(dma); +} + +void rsnd_dma_start(struct rsnd_dma *dma) +{ + dma->ops->start(dma); +} + +void rsnd_dma_quit(struct rsnd_dma *dma) +{ + dma->ops->quit(dma); +} + +int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id) +{ + struct rsnd_mod *mod = rsnd_dma_to_mod(dma); + struct rsnd_mod *mod_from; + struct rsnd_mod *mod_to; + struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); + int is_play = rsnd_io_is_play(io); + + rsnd_dma_of_path(dma, is_play, &mod_from, &mod_to); + + dma->src_addr = rsnd_dma_addr(priv, mod_from, is_play, 1); + dma->dst_addr = rsnd_dma_addr(priv, mod_to, is_play, 0); + + dma->ops = &rsnd_dmaen_ops; + + return dma->ops->init(priv, dma, id, mod_from, mod_to); +} diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index a73e94c1d785..c7299f74cf83 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -170,10 +170,22 @@ u32 rsnd_get_adinr(struct rsnd_mod *mod); /* * R-Car DMA */ +struct rsnd_dma; +struct rsnd_dma_ops { + void (*start)(struct rsnd_dma *dma); + void (*stop)(struct rsnd_dma *dma); + int (*init)(struct rsnd_priv *priv, struct rsnd_dma *dma, int id, + struct rsnd_mod *mod_from, struct rsnd_mod *mod_to); + void (*quit)(struct rsnd_dma *dma); +}; + struct rsnd_dma { struct dma_chan *chan; + struct rsnd_dma_ops *ops; enum dma_transfer_direction dir; dma_addr_t addr; + dma_addr_t src_addr; + dma_addr_t dst_addr; }; void rsnd_dma_start(struct rsnd_dma *dma); -- GitLab From 288f392e729dd4d3719c2319c7c3f8d4c820488b Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 20 Feb 2015 10:27:42 +0000 Subject: [PATCH 03345/11651] ASoC: rsnd: add Audio DMAC peri peri support rework Renesas R-Car sound (= rsnd) needs 2 DMAC which are called as Audio DMAC (= 1st DMAC) and Audio DMAC peri peri (2nd DMAC). And rsnd had assumed that 1st / 2nd DMACs are implemented as DMAEngine. But, in result of DMA ML discussion, 2nd DMAC was concluded that it is not a general purpose DMAC (2nd DMAC is for Device to Device inside sound system). Additionally, current DMAEngine can't support Device to Device, and we don't have correct DT bindings for it at this point. So the easiest solution for it is that move it from DMAEngine to rsnd driver. Audio DMAC peri peri is controlled from sound driver without DMAEngine by this patch. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/core.c | 1 + sound/soc/sh/rcar/dma.c | 211 ++++++++++++++++++++++++++++++++++++++- sound/soc/sh/rcar/rsnd.h | 11 +- 3 files changed, 221 insertions(+), 2 deletions(-) diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 9beea9ba338a..3b6e21948c71 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -974,6 +974,7 @@ static int rsnd_probe(struct platform_device *pdev) const struct rsnd_of_data *of_data, struct rsnd_priv *priv) = { rsnd_gen_probe, + rsnd_dma_probe, rsnd_ssi_probe, rsnd_src_probe, rsnd_dvc_probe, diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c index c911c079fdd0..a01bb8c6b068 100644 --- a/sound/soc/sh/rcar/dma.c +++ b/sound/soc/sh/rcar/dma.c @@ -8,8 +8,29 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ +#include #include "rsnd.h" +/* + * Audio DMAC peri peri register + */ +#define PDMASAR 0x00 +#define PDMADAR 0x04 +#define PDMACHCR 0x0c + +/* PDMACHCR */ +#define PDMACHCR_DE (1 << 0) + +struct rsnd_dma_ctrl { + void __iomem *base; + int dmapp_num; +}; + +#define rsnd_priv_to_dmac(p) ((struct rsnd_dma_ctrl *)(p)->dma) + +/* + * Audio DMAC + */ static void rsnd_dmaen_complete(void *data) { struct rsnd_dma *dma = (struct rsnd_dma *)data; @@ -108,6 +129,8 @@ static int rsnd_dmaen_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id, return -EIO; } + dev_dbg(dev, "Audio DMAC init\n"); + dma_cap_zero(mask); dma_cap_set(DMA_SLAVE, mask); @@ -167,6 +190,150 @@ static struct rsnd_dma_ops rsnd_dmaen_ops = { .quit = rsnd_dmaen_quit, }; +/* + * Audio DMAC peri peri + */ +static const u8 gen2_id_table_ssiu[] = { + 0x00, /* SSI00 */ + 0x04, /* SSI10 */ + 0x08, /* SSI20 */ + 0x0c, /* SSI3 */ + 0x0d, /* SSI4 */ + 0x0e, /* SSI5 */ + 0x0f, /* SSI6 */ + 0x10, /* SSI7 */ + 0x11, /* SSI8 */ + 0x12, /* SSI90 */ +}; +static const u8 gen2_id_table_scu[] = { + 0x2d, /* SCU_SRCI0 */ + 0x2e, /* SCU_SRCI1 */ + 0x2f, /* SCU_SRCI2 */ + 0x30, /* SCU_SRCI3 */ + 0x31, /* SCU_SRCI4 */ + 0x32, /* SCU_SRCI5 */ + 0x33, /* SCU_SRCI6 */ + 0x34, /* SCU_SRCI7 */ + 0x35, /* SCU_SRCI8 */ + 0x36, /* SCU_SRCI9 */ +}; +static const u8 gen2_id_table_cmd[] = { + 0x37, /* SCU_CMD0 */ + 0x38, /* SCU_CMD1 */ +}; + +static u32 rsnd_dmapp_get_id(struct rsnd_mod *mod) +{ + struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); + struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io); + struct rsnd_mod *src = rsnd_io_to_mod_src(io); + struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io); + const u8 *entry = NULL; + int id = rsnd_mod_id(mod); + int size = 0; + + if (mod == ssi) { + entry = gen2_id_table_ssiu; + size = ARRAY_SIZE(gen2_id_table_ssiu); + } else if (mod == src) { + entry = gen2_id_table_scu; + size = ARRAY_SIZE(gen2_id_table_scu); + } else if (mod == dvc) { + entry = gen2_id_table_cmd; + size = ARRAY_SIZE(gen2_id_table_cmd); + } + + if (!entry) + return 0xFF; + + if (size <= id) + return 0xFF; + + return entry[id]; +} + +static u32 rsnd_dmapp_get_chcr(struct rsnd_mod *mod_from, + struct rsnd_mod *mod_to) +{ + return (rsnd_dmapp_get_id(mod_from) << 24) + + (rsnd_dmapp_get_id(mod_to) << 16); +} + +#define rsnd_dmapp_addr(dmac, dma, reg) \ + (dmac->base + 0x20 + (0x10 * dma->dmapp_id) + reg) +static void rsnd_dmapp_write(struct rsnd_dma *dma, u32 data, u32 reg) +{ + struct rsnd_mod *mod = rsnd_dma_to_mod(dma); + struct rsnd_priv *priv = rsnd_mod_to_priv(mod); + struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv); + struct device *dev = rsnd_priv_to_dev(priv); + + dev_dbg(dev, "w %p : %08x\n", rsnd_dmapp_addr(dmac, dma, reg), data); + + iowrite32(data, rsnd_dmapp_addr(dmac, dma, reg)); +} + +static u32 rsnd_dmapp_read(struct rsnd_dma *dma, u32 reg) +{ + struct rsnd_mod *mod = rsnd_dma_to_mod(dma); + struct rsnd_priv *priv = rsnd_mod_to_priv(mod); + struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv); + + return ioread32(rsnd_dmapp_addr(dmac, dma, reg)); +} + +static void rsnd_dmapp_stop(struct rsnd_dma *dma) +{ + int i; + + rsnd_dmapp_write(dma, 0, PDMACHCR); + + for (i = 0; i < 1024; i++) { + if (0 == rsnd_dmapp_read(dma, PDMACHCR)) + return; + udelay(1); + } +} + +static void rsnd_dmapp_start(struct rsnd_dma *dma) +{ + rsnd_dmapp_write(dma, dma->src_addr, PDMASAR); + rsnd_dmapp_write(dma, dma->dst_addr, PDMADAR); + rsnd_dmapp_write(dma, dma->chcr, PDMACHCR); +} + +static int rsnd_dmapp_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id, + struct rsnd_mod *mod_from, struct rsnd_mod *mod_to) +{ + struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv); + struct device *dev = rsnd_priv_to_dev(priv); + + dev_dbg(dev, "Audio DMAC peri peri init\n"); + + dma->dmapp_id = dmac->dmapp_num; + dma->chcr = rsnd_dmapp_get_chcr(mod_from, mod_to) | PDMACHCR_DE; + + dmac->dmapp_num++; + + rsnd_dmapp_stop(dma); + + dev_dbg(dev, "id/src/dst/chcr = %d/%x/%x/%08x\n", + dma->dmapp_id, dma->src_addr, dma->dst_addr, dma->chcr); + + return 0; +} + +static struct rsnd_dma_ops rsnd_dmapp_ops = { + .start = rsnd_dmapp_start, + .stop = rsnd_dmapp_stop, + .init = rsnd_dmapp_init, + .quit = rsnd_dmapp_stop, +}; + +/* + * Common DMAC Interface + */ + /* * DMA read/write register offset * @@ -367,7 +534,49 @@ int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id) dma->src_addr = rsnd_dma_addr(priv, mod_from, is_play, 1); dma->dst_addr = rsnd_dma_addr(priv, mod_to, is_play, 0); - dma->ops = &rsnd_dmaen_ops; + /* for Gen2 */ + if (mod_from && mod_to) + dma->ops = &rsnd_dmapp_ops; + else + dma->ops = &rsnd_dmaen_ops; + + /* for Gen1, overwrite */ + if (rsnd_is_gen1(priv)) + dma->ops = &rsnd_dmaen_ops; return dma->ops->init(priv, dma, id, mod_from, mod_to); } + +int rsnd_dma_probe(struct platform_device *pdev, + const struct rsnd_of_data *of_data, + struct rsnd_priv *priv) +{ + struct device *dev = rsnd_priv_to_dev(priv); + struct rsnd_dma_ctrl *dmac; + struct resource *res; + + /* + * for Gen1 + */ + if (rsnd_is_gen1(priv)) + return 0; + + /* + * for Gen2 + */ + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "audmapp"); + dmac = devm_kzalloc(dev, sizeof(*dmac), GFP_KERNEL); + if (!dmac || !res) { + dev_err(dev, "dma allocate failed\n"); + return -ENOMEM; + } + + dmac->dmapp_num = 0; + dmac->base = devm_ioremap_resource(dev, res); + if (IS_ERR(dmac->base)) + return PTR_ERR(dmac->base); + + priv->dma = dmac; + + return 0; +} diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index c7299f74cf83..9e67142c82bd 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -184,6 +184,8 @@ struct rsnd_dma { struct rsnd_dma_ops *ops; enum dma_transfer_direction dir; dma_addr_t addr; + int dmapp_id; + u32 chcr; dma_addr_t src_addr; dma_addr_t dst_addr; }; @@ -192,7 +194,9 @@ void rsnd_dma_start(struct rsnd_dma *dma); void rsnd_dma_stop(struct rsnd_dma *dma); int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id); void rsnd_dma_quit(struct rsnd_dma *dma); - +int rsnd_dma_probe(struct platform_device *pdev, + const struct rsnd_of_data *of_data, + struct rsnd_priv *priv); #define rsnd_dma_to_mod(_dma) container_of((_dma), struct rsnd_mod, dma) @@ -395,6 +399,11 @@ struct rsnd_priv { */ void *adg; + /* + * below value will be filled on rsnd_dma_probe() + */ + void *dma; + /* * below value will be filled on rsnd_ssi_probe() */ -- GitLab From 56f2906ae2d0b48b64a67feef99e3be3b40c3617 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 20 Feb 2015 10:28:07 +0000 Subject: [PATCH 03346/11651] ASoC: rsnd: remove rsnd_dma::addr DMAEngine for Renesas R-Car driver is used only for Audio DMAC now. rsnd_dma::addr was added to support Audio DMAC peri peri, but it is no longer needed. Let's remove it Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/dma.c | 2 -- sound/soc/sh/rcar/rsnd.h | 1 - 2 files changed, 3 deletions(-) diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c index a01bb8c6b068..c407fd250d2a 100644 --- a/sound/soc/sh/rcar/dma.c +++ b/sound/soc/sh/rcar/dma.c @@ -89,7 +89,6 @@ static void rsnd_dmaen_start(struct rsnd_dma *dma) struct dma_async_tx_descriptor *desc; desc = dmaengine_prep_dma_cyclic(dma->chan, - (dma->addr) ? dma->addr : substream->runtime->dma_addr, snd_pcm_lib_buffer_bytes(substream), snd_pcm_lib_period_bytes(substream), @@ -157,7 +156,6 @@ static int rsnd_dmaen_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id, if (ret < 0) goto rsnd_dma_init_err; - dma->addr = is_play ? cfg.src_addr : cfg.dst_addr; dma->dir = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM; return 0; diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 9e67142c82bd..a2954917bfcb 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -183,7 +183,6 @@ struct rsnd_dma { struct dma_chan *chan; struct rsnd_dma_ops *ops; enum dma_transfer_direction dir; - dma_addr_t addr; int dmapp_id; u32 chcr; dma_addr_t src_addr; -- GitLab From aaf4fce019ecd55a2d93b6111525deeef300f751 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 20 Feb 2015 10:28:32 +0000 Subject: [PATCH 03347/11651] ASoC: rsnd: remove rsnd_dma::dir DMAEngine direction can be calculated from rsnd_dai_stream, So, rsnd_dma::dir does not make sense now. Let's remove it. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/dma.c | 5 ++--- sound/soc/sh/rcar/rsnd.h | 1 - 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c index c407fd250d2a..3f1ea58ee144 100644 --- a/sound/soc/sh/rcar/dma.c +++ b/sound/soc/sh/rcar/dma.c @@ -87,12 +87,13 @@ static void rsnd_dmaen_start(struct rsnd_dma *dma) struct snd_pcm_substream *substream = io->substream; struct device *dev = rsnd_priv_to_dev(priv); struct dma_async_tx_descriptor *desc; + int is_play = rsnd_io_is_play(io); desc = dmaengine_prep_dma_cyclic(dma->chan, substream->runtime->dma_addr, snd_pcm_lib_buffer_bytes(substream), snd_pcm_lib_period_bytes(substream), - dma->dir, + is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); if (!desc) { @@ -156,8 +157,6 @@ static int rsnd_dmaen_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id, if (ret < 0) goto rsnd_dma_init_err; - dma->dir = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM; - return 0; rsnd_dma_init_err: diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index a2954917bfcb..5d65a4b96743 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -182,7 +182,6 @@ struct rsnd_dma_ops { struct rsnd_dma { struct dma_chan *chan; struct rsnd_dma_ops *ops; - enum dma_transfer_direction dir; int dmapp_id; u32 chcr; dma_addr_t src_addr; -- GitLab From 0d00a52182be985bfae67d407ee81fefe448a0fd Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 20 Feb 2015 10:29:13 +0000 Subject: [PATCH 03348/11651] ASoC: rsnd: use union with rsnd_dmaen / rsnd_dmapp Renesas R-Car needs 2 DMACs.1st DMAC is DMAEngine, and 2nd DMAC is implemented as local code. These 2 DMACs are never shared. We can use union for these. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/dma.c | 40 +++++++++++++++++++++++++--------------- sound/soc/sh/rcar/rsnd.h | 16 ++++++++++++++-- 2 files changed, 39 insertions(+), 17 deletions(-) diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c index 3f1ea58ee144..b449763ebd43 100644 --- a/sound/soc/sh/rcar/dma.c +++ b/sound/soc/sh/rcar/dma.c @@ -76,11 +76,14 @@ static void rsnd_dmaen_of_name(struct rsnd_mod *mod_from, static void rsnd_dmaen_stop(struct rsnd_dma *dma) { - dmaengine_terminate_all(dma->chan); + struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma); + + dmaengine_terminate_all(dmaen->chan); } static void rsnd_dmaen_start(struct rsnd_dma *dma) { + struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma); struct rsnd_mod *mod = rsnd_dma_to_mod(dma); struct rsnd_priv *priv = rsnd_mod_to_priv(mod); struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); @@ -89,7 +92,7 @@ static void rsnd_dmaen_start(struct rsnd_dma *dma) struct dma_async_tx_descriptor *desc; int is_play = rsnd_io_is_play(io); - desc = dmaengine_prep_dma_cyclic(dma->chan, + desc = dmaengine_prep_dma_cyclic(dmaen->chan, substream->runtime->dma_addr, snd_pcm_lib_buffer_bytes(substream), snd_pcm_lib_period_bytes(substream), @@ -109,12 +112,13 @@ static void rsnd_dmaen_start(struct rsnd_dma *dma) return; } - dma_async_issue_pending(dma->chan); + dma_async_issue_pending(dmaen->chan); } static int rsnd_dmaen_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id, struct rsnd_mod *mod_from, struct rsnd_mod *mod_to) { + struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma); struct device *dev = rsnd_priv_to_dev(priv); struct dma_slave_config cfg = {}; struct rsnd_mod *mod = rsnd_dma_to_mod(dma); @@ -124,7 +128,7 @@ static int rsnd_dmaen_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id, dma_cap_mask_t mask; int ret; - if (dma->chan) { + if (dmaen->chan) { dev_err(dev, "it already has dma channel\n"); return -EIO; } @@ -145,15 +149,15 @@ static int rsnd_dmaen_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id, dev_dbg(dev, "dma : %s %pad -> %pad\n", dma_name, &cfg.src_addr, &cfg.dst_addr); - dma->chan = dma_request_slave_channel_compat(mask, shdma_chan_filter, + dmaen->chan = dma_request_slave_channel_compat(mask, shdma_chan_filter, (void *)id, dev, dma_name); - if (!dma->chan) { + if (!dmaen->chan) { dev_err(dev, "can't get dma channel\n"); goto rsnd_dma_channel_err; } - ret = dmaengine_slave_config(dma->chan, &cfg); + ret = dmaengine_slave_config(dmaen->chan, &cfg); if (ret < 0) goto rsnd_dma_init_err; @@ -174,10 +178,12 @@ rsnd_dma_channel_err: static void rsnd_dmaen_quit(struct rsnd_dma *dma) { - if (dma->chan) - dma_release_channel(dma->chan); + struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma); + + if (dmaen->chan) + dma_release_channel(dmaen->chan); - dma->chan = NULL; + dmaen->chan = NULL; } static struct rsnd_dma_ops rsnd_dmaen_ops = { @@ -257,7 +263,8 @@ static u32 rsnd_dmapp_get_chcr(struct rsnd_mod *mod_from, } #define rsnd_dmapp_addr(dmac, dma, reg) \ - (dmac->base + 0x20 + (0x10 * dma->dmapp_id) + reg) + (dmac->base + 0x20 + reg + \ + (0x10 * rsnd_dma_to_dmapp(dma)->dmapp_id)) static void rsnd_dmapp_write(struct rsnd_dma *dma, u32 data, u32 reg) { struct rsnd_mod *mod = rsnd_dma_to_mod(dma); @@ -294,28 +301,31 @@ static void rsnd_dmapp_stop(struct rsnd_dma *dma) static void rsnd_dmapp_start(struct rsnd_dma *dma) { + struct rsnd_dmapp *dmapp = rsnd_dma_to_dmapp(dma); + rsnd_dmapp_write(dma, dma->src_addr, PDMASAR); rsnd_dmapp_write(dma, dma->dst_addr, PDMADAR); - rsnd_dmapp_write(dma, dma->chcr, PDMACHCR); + rsnd_dmapp_write(dma, dmapp->chcr, PDMACHCR); } static int rsnd_dmapp_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id, struct rsnd_mod *mod_from, struct rsnd_mod *mod_to) { + struct rsnd_dmapp *dmapp = rsnd_dma_to_dmapp(dma); struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv); struct device *dev = rsnd_priv_to_dev(priv); dev_dbg(dev, "Audio DMAC peri peri init\n"); - dma->dmapp_id = dmac->dmapp_num; - dma->chcr = rsnd_dmapp_get_chcr(mod_from, mod_to) | PDMACHCR_DE; + dmapp->dmapp_id = dmac->dmapp_num; + dmapp->chcr = rsnd_dmapp_get_chcr(mod_from, mod_to) | PDMACHCR_DE; dmac->dmapp_num++; rsnd_dmapp_stop(dma); dev_dbg(dev, "id/src/dst/chcr = %d/%x/%x/%08x\n", - dma->dmapp_id, dma->src_addr, dma->dst_addr, dma->chcr); + dmapp->dmapp_id, dma->src_addr, dma->dst_addr, dmapp->chcr); return 0; } diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 5d65a4b96743..0d36e38ebbcf 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -179,14 +179,26 @@ struct rsnd_dma_ops { void (*quit)(struct rsnd_dma *dma); }; -struct rsnd_dma { +struct rsnd_dmaen { struct dma_chan *chan; - struct rsnd_dma_ops *ops; +}; + +struct rsnd_dmapp { int dmapp_id; u32 chcr; +}; + +struct rsnd_dma { + struct rsnd_dma_ops *ops; dma_addr_t src_addr; dma_addr_t dst_addr; + union { + struct rsnd_dmaen en; + struct rsnd_dmapp pp; + } dma; }; +#define rsnd_dma_to_dmaen(dma) (&(dma)->dma.en) +#define rsnd_dma_to_dmapp(dma) (&(dma)->dma.pp) void rsnd_dma_start(struct rsnd_dma *dma); void rsnd_dma_stop(struct rsnd_dma *dma); -- GitLab From e879a9ddf41c47ccc83039e99e04b0d5c56cd0c5 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 20 Feb 2015 10:29:41 +0000 Subject: [PATCH 03349/11651] ASoC: rsnd: enable rsnd_ssi_use_busif() for DMA Renesas R-Car sound driver uses SSI, but the DMA interfaces are SSI/SSIU. This interface is based on SSI/SRC/DVC connection. And DMA function needs to know which interface is used somehow. This patch enables rsnd_ssi_use_busif() for DMA. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/dma.c | 2 +- sound/soc/sh/rcar/rsnd.h | 1 + sound/soc/sh/rcar/ssi.c | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c index b449763ebd43..3f34461da1e0 100644 --- a/sound/soc/sh/rcar/dma.c +++ b/sound/soc/sh/rcar/dma.c @@ -427,7 +427,7 @@ rsnd_gen2_dma_addr(struct rsnd_priv *priv, dev_err(dev, "DVC is selected without SRC\n"); /* use SSIU or SSI ? */ - if (is_ssi && (0 == strcmp(rsnd_mod_dma_name(mod), "ssiu"))) + if (is_ssi && rsnd_ssi_use_busif(mod)) is_ssi++; return (is_from) ? diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 0d36e38ebbcf..68bc3f46d70b 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -514,6 +514,7 @@ int rsnd_ssi_probe(struct platform_device *pdev, struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id); int rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod); int rsnd_ssi_is_dma_mode(struct rsnd_mod *mod); +int rsnd_ssi_use_busif(struct rsnd_mod *mod); /* * R-Car DVC diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index a0d902ad5985..7e48d562dea8 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -84,7 +84,7 @@ struct rsnd_ssi { #define rsnd_ssi_mode_flags(p) ((p)->info->flags) #define rsnd_ssi_dai_id(ssi) ((ssi)->info->dai_id) -static int rsnd_ssi_use_busif(struct rsnd_mod *mod) +int rsnd_ssi_use_busif(struct rsnd_mod *mod) { struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); -- GitLab From 04e627baa68a8dc42f19b68e1b46d1c6aecebfd9 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 20 Feb 2015 10:30:02 +0000 Subject: [PATCH 03350/11651] ASoC: rsnd: ssi: add rsnd_ssi_of_node() This patch adds rsnd_ssi_of_node() to get SSI subnode from DT. This is prepare for new DT bindings for 1st DMAC Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/ssi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 7e48d562dea8..2133eb34ed06 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -83,6 +83,8 @@ struct rsnd_ssi { #define rsnd_ssi_clk_from_parent(ssi) ((ssi)->parent) #define rsnd_ssi_mode_flags(p) ((p)->info->flags) #define rsnd_ssi_dai_id(ssi) ((ssi)->info->dai_id) +#define rsnd_ssi_of_node(priv) \ + of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,ssi") int rsnd_ssi_use_busif(struct rsnd_mod *mod) { @@ -633,7 +635,7 @@ static void rsnd_of_parse_ssi(struct platform_device *pdev, if (!of_data) return; - node = of_get_child_by_name(dev->of_node, "rcar_sound,ssi"); + node = rsnd_ssi_of_node(priv); if (!node) return; -- GitLab From 82e76ed38edbdb338d64f5f2486fcd1482c8859a Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 20 Feb 2015 10:30:22 +0000 Subject: [PATCH 03351/11651] ASoC: rsnd: src: add rsnd_src_of_node() This patch adds rsnd_src_of_node() to get SRC subnode from DT. This is prepare for new DT bindings for 1st DMAC Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/src.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index e2792056ce24..5a601bed4154 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c @@ -28,6 +28,9 @@ struct rsnd_src { #define RSND_SRC_NAME_SIZE 16 #define rsnd_src_convert_rate(p) ((p)->info->convert_rate) +#define rsnd_src_of_node(priv) \ + of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,src") + #define rsnd_mod_to_src(_mod) \ container_of((_mod), struct rsnd_src, mod) @@ -807,7 +810,7 @@ static void rsnd_of_parse_src(struct platform_device *pdev, if (!of_data) return; - src_node = of_get_child_by_name(dev->of_node, "rcar_sound,src"); + src_node = rsnd_src_of_node(priv); if (!src_node) return; -- GitLab From 93b986e246248d0587acb4f073a621179a16b763 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 20 Feb 2015 10:30:41 +0000 Subject: [PATCH 03352/11651] ASoC: rsnd: dvc: add rsnd_dvc_of_node() This patch adds rsnd_dvc_of_node() to get DVC subnode from DT. This is prepare for new DT bindings for 1st DMAC Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/dvc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c index d7f9ed959c4e..e0990180e1ea 100644 --- a/sound/soc/sh/rcar/dvc.c +++ b/sound/soc/sh/rcar/dvc.c @@ -24,6 +24,9 @@ struct rsnd_dvc { struct rsnd_kctrl_cfg_s rdown; /* Ramp Rate Down */ }; +#define rsnd_dvc_of_node(priv) \ + of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,dvc") + #define rsnd_mod_to_dvc(_mod) \ container_of((_mod), struct rsnd_dvc, mod) -- GitLab From 72adc61f4637aa3596c1db1129f84d768475a885 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 20 Feb 2015 10:31:23 +0000 Subject: [PATCH 03353/11651] ASoC: rsnd: 1st DMAC dma-names cares subnode Renesas R-Car sound (= rsnd) needs 2 DMAC which are called as Audio DMAC (= 1st DMAC) and Audio DMAC peri peri (2nd DMAC). And rsnd had assumed that 1st / 2nd DMACs are implemented as DMAEngine. But, in result of DMA ML discussion, 2nd DMAC was concluded that it is not a general purpose DMAC (2nd DMAC is for Device to Device inside sound system). Additionally, current DMAEngine can't support Device to Device, and we don't have correct DT bindings for it at this point. So the easiest solution for it is that move it from DMAEngine to rsnd driver. dma-names on DT was implemented as no difference between 1st / 2nd DMAC's, since rsnd had assumed that both DMACs are implemented as DMAEngine. That style was "src_dst". But now, 2nd DMAC was implemented as non DMAEngine, and it doesn't need dma-names anymore. So, this dma-names rule is no longer needed. And additionally, dma-names was assumed that it has all (= SSI/SSIU/SRC/DVC) nodes under sound node. In upstream code, no SoC/platform is supporting DMA for rsnd driver yet. This means there is no compatible issue if this patch changes dma-names's rule of DT. This patch assumes dma-names for 1st DMAC are tx/rx base, and listed in each SSI/SRC/DVC subnode ex) rcar_sound,dvc { dvc0: dvc@0 { dmas = <&audma0 0xbc>; dma-names = "tx"; }; ... rcar_sound,src { src0: src@0 { ... dmas = <&audma0 0x85>, <&audma1 0x9a>; dma-names = "rx", "tx"; }; ... rcar_sound,ssi { ssi0: ssi@0 { ... dmas = <&audma0 0x01>, <&audma1 0x02>, <&audma0 0x15>, <&audma1 0x16>; dma-names = "rx", "tx", "rxu", "txu"; }; ... Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/core.c | 11 ++--- sound/soc/sh/rcar/dma.c | 88 +++++++++++++++++++++++----------------- sound/soc/sh/rcar/dvc.c | 9 ++++ sound/soc/sh/rcar/rsnd.h | 6 ++- sound/soc/sh/rcar/src.c | 13 ++++++ sound/soc/sh/rcar/ssi.c | 17 ++++++-- 6 files changed, 95 insertions(+), 49 deletions(-) diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 3b6e21948c71..7b995f025e22 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -137,15 +137,12 @@ char *rsnd_mod_name(struct rsnd_mod *mod) return mod->ops->name; } -char *rsnd_mod_dma_name(struct rsnd_mod *mod) +struct dma_chan *rsnd_mod_dma_req(struct rsnd_mod *mod) { - if (!mod || !mod->ops) - return "unknown"; - - if (!mod->ops->dma_name) - return mod->ops->name; + if (!mod || !mod->ops || !mod->ops->dma_req) + return NULL; - return mod->ops->dma_name(mod); + return mod->ops->dma_req(mod); } void rsnd_mod_init(struct rsnd_mod *mod, diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c index 3f34461da1e0..92fd55044ee6 100644 --- a/sound/soc/sh/rcar/dma.c +++ b/sound/soc/sh/rcar/dma.c @@ -9,6 +9,7 @@ * published by the Free Software Foundation. */ #include +#include #include "rsnd.h" /* @@ -52,28 +53,6 @@ static void rsnd_dmaen_complete(void *data) rsnd_dai_pointer_update(io, io->byte_per_period); } -#define DMA_NAME_SIZE 16 -static int _rsnd_dmaen_of_name(char *dma_name, struct rsnd_mod *mod) -{ - if (mod) - return snprintf(dma_name, DMA_NAME_SIZE / 2, "%s%d", - rsnd_mod_dma_name(mod), rsnd_mod_id(mod)); - else - return snprintf(dma_name, DMA_NAME_SIZE / 2, "mem"); - -} - -static void rsnd_dmaen_of_name(struct rsnd_mod *mod_from, - struct rsnd_mod *mod_to, - char *dma_name) -{ - int index = 0; - - index = _rsnd_dmaen_of_name(dma_name + index, mod_from); - *(dma_name + index++) = '_'; - index = _rsnd_dmaen_of_name(dma_name + index, mod_to); -} - static void rsnd_dmaen_stop(struct rsnd_dma *dma) { struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma); @@ -115,6 +94,40 @@ static void rsnd_dmaen_start(struct rsnd_dma *dma) dma_async_issue_pending(dmaen->chan); } +struct dma_chan *rsnd_dma_request_channel(struct device_node *of_node, + struct rsnd_mod *mod, char *name) +{ + struct dma_chan *chan; + struct device_node *np; + int i = 0; + + for_each_child_of_node(of_node, np) { + if (i == rsnd_mod_id(mod)) + break; + i++; + } + + chan = of_dma_request_slave_channel(np, name); + + of_node_put(np); + of_node_put(of_node); + + return chan; +} + +static struct dma_chan *rsnd_dmaen_request_channel(struct rsnd_mod *mod_from, + struct rsnd_mod *mod_to) +{ + if ((!mod_from && !mod_to) || + (mod_from && mod_to)) + return NULL; + + if (mod_from) + return rsnd_mod_dma_req(mod_from); + else + return rsnd_mod_dma_req(mod_to); +} + static int rsnd_dmaen_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id, struct rsnd_mod *mod_from, struct rsnd_mod *mod_to) { @@ -124,8 +137,6 @@ static int rsnd_dmaen_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id, struct rsnd_mod *mod = rsnd_dma_to_mod(dma); struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); int is_play = rsnd_io_is_play(io); - char dma_name[DMA_NAME_SIZE]; - dma_cap_mask_t mask; int ret; if (dmaen->chan) { @@ -135,10 +146,21 @@ static int rsnd_dmaen_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id, dev_dbg(dev, "Audio DMAC init\n"); - dma_cap_zero(mask); - dma_cap_set(DMA_SLAVE, mask); + if (dev->of_node) { + dmaen->chan = rsnd_dmaen_request_channel(mod_from, mod_to); + } else { + dma_cap_mask_t mask; + + dma_cap_zero(mask); + dma_cap_set(DMA_SLAVE, mask); - rsnd_dmaen_of_name(mod_from, mod_to, dma_name); + dmaen->chan = dma_request_channel(mask, shdma_chan_filter, + (void *)id); + } + if (IS_ERR_OR_NULL(dmaen->chan)) { + dev_err(dev, "can't get dma channel\n"); + goto rsnd_dma_channel_err; + } cfg.direction = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM; cfg.src_addr = dma->src_addr; @@ -146,16 +168,8 @@ static int rsnd_dmaen_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id, cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; - dev_dbg(dev, "dma : %s %pad -> %pad\n", - dma_name, &cfg.src_addr, &cfg.dst_addr); - - dmaen->chan = dma_request_slave_channel_compat(mask, shdma_chan_filter, - (void *)id, dev, - dma_name); - if (!dmaen->chan) { - dev_err(dev, "can't get dma channel\n"); - goto rsnd_dma_channel_err; - } + dev_dbg(dev, "dma : %pad -> %pad\n", + &cfg.src_addr, &cfg.dst_addr); ret = dmaengine_slave_config(dmaen->chan, &cfg); if (ret < 0) diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c index e0990180e1ea..aeeef1352eee 100644 --- a/sound/soc/sh/rcar/dvc.c +++ b/sound/soc/sh/rcar/dvc.c @@ -272,8 +272,17 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, return 0; } +static struct dma_chan *rsnd_dvc_dma_req(struct rsnd_mod *mod) +{ + struct rsnd_priv *priv = rsnd_mod_to_priv(mod); + + return rsnd_dma_request_channel(rsnd_dvc_of_node(priv), + mod, "tx"); +} + static struct rsnd_mod_ops rsnd_dvc_ops = { .name = DVC_NAME, + .dma_req = rsnd_dvc_dma_req, .probe = rsnd_dvc_probe_gen2, .remove = rsnd_dvc_remove_gen2, .init = rsnd_dvc_init, diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 68bc3f46d70b..52c401c9eeef 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -207,6 +207,8 @@ void rsnd_dma_quit(struct rsnd_dma *dma); int rsnd_dma_probe(struct platform_device *pdev, const struct rsnd_of_data *of_data, struct rsnd_priv *priv); +struct dma_chan *rsnd_dma_request_channel(struct device_node *of_node, + struct rsnd_mod *mod, char *name); #define rsnd_dma_to_mod(_dma) container_of((_dma), struct rsnd_mod, dma) @@ -222,7 +224,7 @@ enum rsnd_mod_type { struct rsnd_mod_ops { char *name; - char* (*dma_name)(struct rsnd_mod *mod); + struct dma_chan* (*dma_req)(struct rsnd_mod *mod); int (*probe)(struct rsnd_mod *mod, struct rsnd_priv *priv); int (*remove)(struct rsnd_mod *mod, @@ -292,7 +294,7 @@ void rsnd_mod_init(struct rsnd_mod *mod, enum rsnd_mod_type type, int id); char *rsnd_mod_name(struct rsnd_mod *mod); -char *rsnd_mod_dma_name(struct rsnd_mod *mod); +struct dma_chan *rsnd_mod_dma_req(struct rsnd_mod *mod); /* * R-Car sound DAI diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index 5a601bed4154..6ce8985757c1 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c @@ -114,6 +114,17 @@ struct rsnd_src { /* * Gen1/Gen2 common functions */ +static struct dma_chan *rsnd_src_dma_req(struct rsnd_mod *mod) +{ + struct rsnd_priv *priv = rsnd_mod_to_priv(mod); + struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); + int is_play = rsnd_io_is_play(io); + + return rsnd_dma_request_channel(rsnd_src_of_node(priv), + mod, + is_play ? "rx" : "tx"); +} + int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod, int use_busif) { @@ -506,6 +517,7 @@ static int rsnd_src_stop_gen1(struct rsnd_mod *mod, static struct rsnd_mod_ops rsnd_src_gen1_ops = { .name = SRC_NAME, + .dma_req = rsnd_src_dma_req, .probe = rsnd_src_probe_gen1, .init = rsnd_src_init_gen1, .quit = rsnd_src_quit, @@ -780,6 +792,7 @@ static int rsnd_src_stop_gen2(struct rsnd_mod *mod, static struct rsnd_mod_ops rsnd_src_gen2_ops = { .name = SRC_NAME, + .dma_req = rsnd_src_dma_req, .probe = rsnd_src_probe_gen2, .remove = rsnd_src_remove_gen2, .init = rsnd_src_init_gen2, diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 2133eb34ed06..fea4aa53918a 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -553,14 +553,25 @@ static int rsnd_ssi_dma_stop(struct rsnd_mod *mod, return 0; } -static char *rsnd_ssi_dma_name(struct rsnd_mod *mod) +static struct dma_chan *rsnd_ssi_dma_req(struct rsnd_mod *mod) { - return rsnd_ssi_use_busif(mod) ? "ssiu" : SSI_NAME; + struct rsnd_priv *priv = rsnd_mod_to_priv(mod); + struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); + int is_play = rsnd_io_is_play(io); + char *name; + + if (rsnd_ssi_use_busif(mod)) + name = is_play ? "rxu" : "txu"; + else + name = is_play ? "rx" : "tx"; + + return rsnd_dma_request_channel(rsnd_ssi_of_node(priv), + mod, name); } static struct rsnd_mod_ops rsnd_ssi_dma_ops = { .name = SSI_NAME, - .dma_name = rsnd_ssi_dma_name, + .dma_req = rsnd_ssi_dma_req, .probe = rsnd_ssi_dma_probe, .remove = rsnd_ssi_dma_remove, .init = rsnd_ssi_init, -- GitLab From 5cf4f68672856dcbca883b460aee4ee5bfbeafb0 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 20 Feb 2015 10:31:55 +0000 Subject: [PATCH 03354/11651] ASoC: rsnd: add sample code of rcar_sound,src irq cfcefe01265cbaf5ca7209226d043b07bfa8b587 (ASoC: rsnd: add recovery support for under/over flow error on SRC) added SRC recovery support which needs IRQ. This patch adds SRC irq sample code on DT bingdings text Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- .../bindings/sound/renesas,rsnd.txt | 40 ++++++++++++++----- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/Documentation/devicetree/bindings/sound/renesas,rsnd.txt b/Documentation/devicetree/bindings/sound/renesas,rsnd.txt index 2dd690bc19cc..87e0fc2ce399 100644 --- a/Documentation/devicetree/bindings/sound/renesas,rsnd.txt +++ b/Documentation/devicetree/bindings/sound/renesas,rsnd.txt @@ -53,16 +53,36 @@ rcar_sound: rcar_sound@ec500000 { }; rcar_sound,src { - src0: src@0 { }; - src1: src@1 { }; - src2: src@2 { }; - src3: src@3 { }; - src4: src@4 { }; - src5: src@5 { }; - src6: src@6 { }; - src7: src@7 { }; - src8: src@8 { }; - src9: src@9 { }; + src0: src@0 { + interrupts = <0 352 IRQ_TYPE_LEVEL_HIGH>; + }; + src1: src@1 { + interrupts = <0 353 IRQ_TYPE_LEVEL_HIGH>; + }; + src2: src@2 { + interrupts = <0 354 IRQ_TYPE_LEVEL_HIGH>; + }; + src3: src@3 { + interrupts = <0 355 IRQ_TYPE_LEVEL_HIGH>; + }; + src4: src@4 { + interrupts = <0 356 IRQ_TYPE_LEVEL_HIGH>; + }; + src5: src@5 { + interrupts = <0 357 IRQ_TYPE_LEVEL_HIGH>; + }; + src6: src@6 { + interrupts = <0 358 IRQ_TYPE_LEVEL_HIGH>; + }; + src7: src@7 { + interrupts = <0 359 IRQ_TYPE_LEVEL_HIGH>; + }; + src8: src@8 { + interrupts = <0 360 IRQ_TYPE_LEVEL_HIGH>; + }; + src9: src@9 { + interrupts = <0 361 IRQ_TYPE_LEVEL_HIGH>; + }; }; rcar_sound,ssi { -- GitLab From bb02714fe5f198c0f07a8039ebcc636c1bffbc03 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 20 Feb 2015 10:32:15 +0000 Subject: [PATCH 03355/11651] ASoC: rsnd: add sample code of missing clocks Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- .../bindings/sound/renesas,rsnd.txt | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/Documentation/devicetree/bindings/sound/renesas,rsnd.txt b/Documentation/devicetree/bindings/sound/renesas,rsnd.txt index 87e0fc2ce399..503967ba39db 100644 --- a/Documentation/devicetree/bindings/sound/renesas,rsnd.txt +++ b/Documentation/devicetree/bindings/sound/renesas,rsnd.txt @@ -47,6 +47,27 @@ rcar_sound: rcar_sound@ec500000 { <0 0xec540000 0 0x1000>, /* SSIU */ <0 0xec541000 0 0x1280>; /* SSI */ + clocks = <&mstp10_clks R8A7790_CLK_SSI_ALL>, + <&mstp10_clks R8A7790_CLK_SSI9>, <&mstp10_clks R8A7790_CLK_SSI8>, + <&mstp10_clks R8A7790_CLK_SSI7>, <&mstp10_clks R8A7790_CLK_SSI6>, + <&mstp10_clks R8A7790_CLK_SSI5>, <&mstp10_clks R8A7790_CLK_SSI4>, + <&mstp10_clks R8A7790_CLK_SSI3>, <&mstp10_clks R8A7790_CLK_SSI2>, + <&mstp10_clks R8A7790_CLK_SSI1>, <&mstp10_clks R8A7790_CLK_SSI0>, + <&mstp10_clks R8A7790_CLK_SCU_SRC9>, <&mstp10_clks R8A7790_CLK_SCU_SRC8>, + <&mstp10_clks R8A7790_CLK_SCU_SRC7>, <&mstp10_clks R8A7790_CLK_SCU_SRC6>, + <&mstp10_clks R8A7790_CLK_SCU_SRC5>, <&mstp10_clks R8A7790_CLK_SCU_SRC4>, + <&mstp10_clks R8A7790_CLK_SCU_SRC3>, <&mstp10_clks R8A7790_CLK_SCU_SRC2>, + <&mstp10_clks R8A7790_CLK_SCU_SRC1>, <&mstp10_clks R8A7790_CLK_SCU_SRC0>, + <&mstp10_clks R8A7790_CLK_SCU_DVC0>, <&mstp10_clks R8A7790_CLK_SCU_DVC1>, + <&audio_clk_a>, <&audio_clk_b>, <&audio_clk_c>, <&m2_clk>; + clock-names = "ssi-all", + "ssi.9", "ssi.8", "ssi.7", "ssi.6", "ssi.5", + "ssi.4", "ssi.3", "ssi.2", "ssi.1", "ssi.0", + "src.9", "src.8", "src.7", "src.6", "src.5", + "src.4", "src.3", "src.2", "src.1", "src.0", + "dvc.0", "dvc.1", + "clk_a", "clk_b", "clk_c", "clk_i"; + rcar_sound,dvc { dvc0: dvc@0 { }; dvc1: dvc@1 { }; -- GitLab From e80a2fb18bc7dca116ec623dc909f07c5e505349 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 20 Feb 2015 10:32:49 +0000 Subject: [PATCH 03356/11651] ASoC: rsnd: add sample code of dma entry rsnd driver supports Audio DMAC (via DMAEngine) / Audio DMAC peri peri (via rsnd driver) now. This patch adds DT binding sample code on DT binging text Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- .../bindings/sound/renesas,rsnd.txt | 60 ++++++++++++++++++- 1 file changed, 57 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/sound/renesas,rsnd.txt b/Documentation/devicetree/bindings/sound/renesas,rsnd.txt index 503967ba39db..6e660d4f3631 100644 --- a/Documentation/devicetree/bindings/sound/renesas,rsnd.txt +++ b/Documentation/devicetree/bindings/sound/renesas,rsnd.txt @@ -29,9 +29,17 @@ SSI subnode properties: - shared-pin : if shared clock pin - pio-transfer : use PIO transfer mode - no-busif : BUSIF is not ussed when [mem -> SSI] via DMA case +- dma : Should contain Audio DMAC entry +- dma-names : SSI case "rx" (=playback), "tx" (=capture) + SSIU case "rxu" (=playback), "txu" (=capture) SRC subnode properties: -no properties at this point +- dma : Should contain Audio DMAC entry +- dma-names : "rx" (=playback), "tx" (=capture) + +DVC subnode properties: +- dma : Should contain Audio DMAC entry +- dma-names : "tx" (=playback/capture) DAI subnode properties: - playback : list of playback modules @@ -69,73 +77,119 @@ rcar_sound: rcar_sound@ec500000 { "clk_a", "clk_b", "clk_c", "clk_i"; rcar_sound,dvc { - dvc0: dvc@0 { }; - dvc1: dvc@1 { }; + dvc0: dvc@0 { + dmas = <&audma0 0xbc>; + dma-names = "tx"; + }; + dvc1: dvc@1 { + dmas = <&audma0 0xbe>; + dma-names = "tx"; + }; }; rcar_sound,src { src0: src@0 { interrupts = <0 352 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x85>, <&audma1 0x9a>; + dma-names = "rx", "tx"; }; src1: src@1 { interrupts = <0 353 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x87>, <&audma1 0x9c>; + dma-names = "rx", "tx"; }; src2: src@2 { interrupts = <0 354 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x89>, <&audma1 0x9e>; + dma-names = "rx", "tx"; }; src3: src@3 { interrupts = <0 355 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x8b>, <&audma1 0xa0>; + dma-names = "rx", "tx"; }; src4: src@4 { interrupts = <0 356 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x8d>, <&audma1 0xb0>; + dma-names = "rx", "tx"; }; src5: src@5 { interrupts = <0 357 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x8f>, <&audma1 0xb2>; + dma-names = "rx", "tx"; }; src6: src@6 { interrupts = <0 358 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x91>, <&audma1 0xb4>; + dma-names = "rx", "tx"; }; src7: src@7 { interrupts = <0 359 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x93>, <&audma1 0xb6>; + dma-names = "rx", "tx"; }; src8: src@8 { interrupts = <0 360 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x95>, <&audma1 0xb8>; + dma-names = "rx", "tx"; }; src9: src@9 { interrupts = <0 361 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x97>, <&audma1 0xba>; + dma-names = "rx", "tx"; }; }; rcar_sound,ssi { ssi0: ssi@0 { interrupts = <0 370 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x01>, <&audma1 0x02>, <&audma0 0x15>, <&audma1 0x16>; + dma-names = "rx", "tx", "rxu", "txu"; }; ssi1: ssi@1 { interrupts = <0 371 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x03>, <&audma1 0x04>, <&audma0 0x49>, <&audma1 0x4a>; + dma-names = "rx", "tx", "rxu", "txu"; }; ssi2: ssi@2 { interrupts = <0 372 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x05>, <&audma1 0x06>, <&audma0 0x63>, <&audma1 0x64>; + dma-names = "rx", "tx", "rxu", "txu"; }; ssi3: ssi@3 { interrupts = <0 373 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x07>, <&audma1 0x08>, <&audma0 0x6f>, <&audma1 0x70>; + dma-names = "rx", "tx", "rxu", "txu"; }; ssi4: ssi@4 { interrupts = <0 374 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x09>, <&audma1 0x0a>, <&audma0 0x71>, <&audma1 0x72>; + dma-names = "rx", "tx", "rxu", "txu"; }; ssi5: ssi@5 { interrupts = <0 375 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x0b>, <&audma1 0x0c>, <&audma0 0x73>, <&audma1 0x74>; + dma-names = "rx", "tx", "rxu", "txu"; }; ssi6: ssi@6 { interrupts = <0 376 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x0d>, <&audma1 0x0e>, <&audma0 0x75>, <&audma1 0x76>; + dma-names = "rx", "tx", "rxu", "txu"; }; ssi7: ssi@7 { interrupts = <0 377 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x0f>, <&audma1 0x10>, <&audma0 0x79>, <&audma1 0x7a>; + dma-names = "rx", "tx", "rxu", "txu"; }; ssi8: ssi@8 { interrupts = <0 378 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x11>, <&audma1 0x12>, <&audma0 0x7b>, <&audma1 0x7c>; + dma-names = "rx", "tx", "rxu", "txu"; }; ssi9: ssi@9 { interrupts = <0 379 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x13>, <&audma1 0x14>, <&audma0 0x7d>, <&audma1 0x7e>; + dma-names = "rx", "tx", "rxu", "txu"; }; }; -- GitLab From d3b1c0badbc86c034af55704ea88c1e656b402fe Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 20 Feb 2015 10:33:09 +0000 Subject: [PATCH 03357/11651] ASoC: rsnd: add sample code of reg-names Current rsnd driver supports reg-names, and Audio DMAC peri peri. This patch adds sample code for it. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/renesas,rsnd.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/sound/renesas,rsnd.txt b/Documentation/devicetree/bindings/sound/renesas,rsnd.txt index 6e660d4f3631..f316ce1f214a 100644 --- a/Documentation/devicetree/bindings/sound/renesas,rsnd.txt +++ b/Documentation/devicetree/bindings/sound/renesas,rsnd.txt @@ -53,7 +53,9 @@ rcar_sound: rcar_sound@ec500000 { reg = <0 0xec500000 0 0x1000>, /* SCU */ <0 0xec5a0000 0 0x100>, /* ADG */ <0 0xec540000 0 0x1000>, /* SSIU */ - <0 0xec541000 0 0x1280>; /* SSI */ + <0 0xec541000 0 0x1280>, /* SSI */ + <0 0xec740000 0 0x200>; /* Audio DMAC peri peri*/ + reg-names = "scu", "adg", "ssiu", "ssi", "audmapp"; clocks = <&mstp10_clks R8A7790_CLK_SSI_ALL>, <&mstp10_clks R8A7790_CLK_SSI9>, <&mstp10_clks R8A7790_CLK_SSI8>, -- GitLab From 328f494d95aac8bd4896aea2328bc281053bcb71 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sat, 7 Mar 2015 17:10:01 +0100 Subject: [PATCH 03358/11651] regmap: regcache-rbtree: Fix present bitmap resize When inserting a new register into a block at the lower end the present bitmap is currently shifted into the wrong direction. The effect of this is that the bitmap becomes corrupted and registers which are present might be reported as not present and vice versa. Fix this by shifting left rather than right. Fixes: 472fdec7380c("regmap: rbtree: Reduce number of nodes, take 2") Reported-by: Daniel Baluta Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- drivers/base/regmap/regcache-rbtree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/base/regmap/regcache-rbtree.c b/drivers/base/regmap/regcache-rbtree.c index d453a2c98ad0..81751a49d8bf 100644 --- a/drivers/base/regmap/regcache-rbtree.c +++ b/drivers/base/regmap/regcache-rbtree.c @@ -307,7 +307,7 @@ static int regcache_rbtree_insert_to_block(struct regmap *map, if (pos == 0) { memmove(blk + offset * map->cache_word_size, blk, rbnode->blklen * map->cache_word_size); - bitmap_shift_right(present, present, offset, blklen); + bitmap_shift_left(present, present, offset, blklen); } /* update the rbnode block, its size and the base register */ -- GitLab From c8b263cc03eaaa324c9222474191e6d849cb6dda Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Sat, 7 Mar 2015 16:33:53 +0100 Subject: [PATCH 03359/11651] regulator: act8865: add input supply handling The act88600/act8846/act8865 regulators have a number of input supplies supplying the individual regulators. This may even be recursively like on most Rockchip boards using the act8846 where REG4 is most of the time connected to the inl1-supply. Therefore add the ability to specify the input supplies for the individual inputs. The input-names are taken from the datasheets of act8600, act8846 and act8865. On the act8600 some regulators do not have separate input supplies. Signed-off-by: Heiko Stuebner Signed-off-by: Mark Brown --- .../bindings/regulator/act8865-regulator.txt | 22 ++++++++ drivers/regulator/act8865-regulator.c | 55 ++++++++++--------- 2 files changed, 50 insertions(+), 27 deletions(-) diff --git a/Documentation/devicetree/bindings/regulator/act8865-regulator.txt b/Documentation/devicetree/bindings/regulator/act8865-regulator.txt index e170df2357df..e91485d11241 100644 --- a/Documentation/devicetree/bindings/regulator/act8865-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/act8865-regulator.txt @@ -9,6 +9,28 @@ Optional properties: - system-power-controller: Telling whether or not this pmic is controlling the system power. See Documentation/devicetree/bindings/power/power-controller.txt . +Optional input supply properties: +- for act8600: + - vp1-supply: The input supply for DCDC_REG1 + - vp2-supply: The input supply for DCDC_REG2 + - vp3-supply: The input supply for DCDC_REG3 + - inl-supply: The input supply for LDO_REG5, LDO_REG6, LDO_REG7 and LDO_REG8 + SUDCDC_REG4, LDO_REG9 and LDO_REG10 do not have separate supplies. +- for act8846: + - vp1-supply: The input supply for REG1 + - vp2-supply: The input supply for REG2 + - vp3-supply: The input supply for REG3 + - vp4-supply: The input supply for REG4 + - inl1-supply: The input supply for REG5, REG6 and REG7 + - inl2-supply: The input supply for REG8 and LDO_REG9 + - inl3-supply: The input supply for REG10, REG11 and REG12 +- for act8865: + - vp1-supply: The input supply for DCDC_REG1 + - vp2-supply: The input supply for DCDC_REG2 + - vp3-supply: The input supply for DCDC_REG3 + - inl45-supply: The input supply for LDO_REG1 and LDO_REG2 + - inl67-supply: The input supply for LDO_REG3 and LDO_REG4 + Any standard regulator properties can be used to configure the single regulator. The valid names for regulators are: diff --git a/drivers/regulator/act8865-regulator.c b/drivers/regulator/act8865-regulator.c index 3781f6e289d8..2ff73d72ca34 100644 --- a/drivers/regulator/act8865-regulator.c +++ b/drivers/regulator/act8865-regulator.c @@ -173,9 +173,10 @@ static struct regulator_ops act8865_ldo_ops = { .is_enabled = regulator_is_enabled_regmap, }; -#define ACT88xx_REG(_name, _family, _id, _vsel_reg) \ +#define ACT88xx_REG(_name, _family, _id, _vsel_reg, _supply) \ [_family##_ID_##_id] = { \ .name = _name, \ + .supply_name = _supply, \ .id = _family##_ID_##_id, \ .type = REGULATOR_VOLTAGE, \ .ops = &act8865_ops, \ @@ -190,9 +191,9 @@ static struct regulator_ops act8865_ldo_ops = { } static const struct regulator_desc act8600_regulators[] = { - ACT88xx_REG("DCDC1", ACT8600, DCDC1, VSET), - ACT88xx_REG("DCDC2", ACT8600, DCDC2, VSET), - ACT88xx_REG("DCDC3", ACT8600, DCDC3, VSET), + ACT88xx_REG("DCDC1", ACT8600, DCDC1, VSET, "vp1"), + ACT88xx_REG("DCDC2", ACT8600, DCDC2, VSET, "vp2"), + ACT88xx_REG("DCDC3", ACT8600, DCDC3, VSET, "vp3"), { .name = "SUDCDC_REG4", .id = ACT8600_ID_SUDCDC4, @@ -207,10 +208,10 @@ static const struct regulator_desc act8600_regulators[] = { .enable_mask = ACT8865_ENA, .owner = THIS_MODULE, }, - ACT88xx_REG("LDO5", ACT8600, LDO5, VSET), - ACT88xx_REG("LDO6", ACT8600, LDO6, VSET), - ACT88xx_REG("LDO7", ACT8600, LDO7, VSET), - ACT88xx_REG("LDO8", ACT8600, LDO8, VSET), + ACT88xx_REG("LDO5", ACT8600, LDO5, VSET, "inl"), + ACT88xx_REG("LDO6", ACT8600, LDO6, VSET, "inl"), + ACT88xx_REG("LDO7", ACT8600, LDO7, VSET, "inl"), + ACT88xx_REG("LDO8", ACT8600, LDO8, VSET, "inl"), { .name = "LDO_REG9", .id = ACT8600_ID_LDO9, @@ -236,28 +237,28 @@ static const struct regulator_desc act8600_regulators[] = { }; static const struct regulator_desc act8846_regulators[] = { - ACT88xx_REG("REG1", ACT8846, REG1, VSET), - ACT88xx_REG("REG2", ACT8846, REG2, VSET0), - ACT88xx_REG("REG3", ACT8846, REG3, VSET0), - ACT88xx_REG("REG4", ACT8846, REG4, VSET0), - ACT88xx_REG("REG5", ACT8846, REG5, VSET), - ACT88xx_REG("REG6", ACT8846, REG6, VSET), - ACT88xx_REG("REG7", ACT8846, REG7, VSET), - ACT88xx_REG("REG8", ACT8846, REG8, VSET), - ACT88xx_REG("REG9", ACT8846, REG9, VSET), - ACT88xx_REG("REG10", ACT8846, REG10, VSET), - ACT88xx_REG("REG11", ACT8846, REG11, VSET), - ACT88xx_REG("REG12", ACT8846, REG12, VSET), + ACT88xx_REG("REG1", ACT8846, REG1, VSET, "vp1"), + ACT88xx_REG("REG2", ACT8846, REG2, VSET0, "vp2"), + ACT88xx_REG("REG3", ACT8846, REG3, VSET0, "vp3"), + ACT88xx_REG("REG4", ACT8846, REG4, VSET0, "vp4"), + ACT88xx_REG("REG5", ACT8846, REG5, VSET, "inl1"), + ACT88xx_REG("REG6", ACT8846, REG6, VSET, "inl1"), + ACT88xx_REG("REG7", ACT8846, REG7, VSET, "inl1"), + ACT88xx_REG("REG8", ACT8846, REG8, VSET, "inl2"), + ACT88xx_REG("REG9", ACT8846, REG9, VSET, "inl2"), + ACT88xx_REG("REG10", ACT8846, REG10, VSET, "inl3"), + ACT88xx_REG("REG11", ACT8846, REG11, VSET, "inl3"), + ACT88xx_REG("REG12", ACT8846, REG12, VSET, "inl3"), }; static const struct regulator_desc act8865_regulators[] = { - ACT88xx_REG("DCDC_REG1", ACT8865, DCDC1, VSET1), - ACT88xx_REG("DCDC_REG2", ACT8865, DCDC2, VSET1), - ACT88xx_REG("DCDC_REG3", ACT8865, DCDC3, VSET1), - ACT88xx_REG("LDO_REG1", ACT8865, LDO1, VSET), - ACT88xx_REG("LDO_REG2", ACT8865, LDO2, VSET), - ACT88xx_REG("LDO_REG3", ACT8865, LDO3, VSET), - ACT88xx_REG("LDO_REG4", ACT8865, LDO4, VSET), + ACT88xx_REG("DCDC_REG1", ACT8865, DCDC1, VSET1, "vp1"), + ACT88xx_REG("DCDC_REG2", ACT8865, DCDC2, VSET1, "vp2"), + ACT88xx_REG("DCDC_REG3", ACT8865, DCDC3, VSET1, "vp3"), + ACT88xx_REG("LDO_REG1", ACT8865, LDO1, VSET, "inl45"), + ACT88xx_REG("LDO_REG2", ACT8865, LDO2, VSET, "inl45"), + ACT88xx_REG("LDO_REG3", ACT8865, LDO3, VSET, "inl67"), + ACT88xx_REG("LDO_REG4", ACT8865, LDO4, VSET, "inl67"), }; #ifdef CONFIG_OF -- GitLab From aa5e18320788728476e84e2140aa736bc5525c87 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sat, 7 Mar 2015 19:35:37 +0200 Subject: [PATCH 03360/11651] iwlwifi: mvm: fix compilation with IWLWIFI_DEBUGFS not set The commits below broke compilation when CONFIG_IWLWIFI_DEBUGFS is not set. FIx that. Fixes: ddf89ab10a93 ("iwlwifi: mvm: allow to force the Rx chains from debugfs") Fixes: 9d761fd8a583 ("iwlwifi: mvm: add trigger for firmware dump upon missed beacons") Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c | 1 - drivers/net/wireless/iwlwifi/mvm/mac80211.c | 2 ++ drivers/net/wireless/iwlwifi/mvm/mvm.h | 2 +- drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c | 2 ++ 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c b/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c index 7faad90386b8..5f37eab5008d 100644 --- a/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c +++ b/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c @@ -627,7 +627,6 @@ void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif) return; mvmvif->dbgfs_dir = debugfs_create_dir("iwlmvm", dbgfs_dir); - mvmvif->mvm = mvm; if (!mvmvif->dbgfs_dir) { IWL_ERR(mvm, "Failed to create debugfs directory under %s\n", diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 5a5d5c8544fc..204255423d99 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -1346,6 +1346,8 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); int ret; + mvmvif->mvm = mvm; + /* * make sure D0i3 exit is completed, otherwise a target access * during tx queue configuration could be done when still in diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index f4ecd1bde1cf..e10172d69eaa 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -356,6 +356,7 @@ struct iwl_mvm_vif_bf_data { * average signal of beacons retrieved from the firmware */ struct iwl_mvm_vif { + struct iwl_mvm *mvm; u16 id; u16 color; u8 ap_sta_id; @@ -418,7 +419,6 @@ struct iwl_mvm_vif { #endif #ifdef CONFIG_IWLWIFI_DEBUGFS - struct iwl_mvm *mvm; struct dentry *dbgfs_dir; struct dentry *dbgfs_slink; struct iwl_dbgfs_pm dbgfs_pm; diff --git a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c index 1bd10eda01f9..192b74bc8cf6 100644 --- a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c +++ b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c @@ -175,8 +175,10 @@ static void iwl_mvm_phy_ctxt_cmd_data(struct iwl_mvm *mvm, cmd->rxchain_info |= cpu_to_le32(idle_cnt << PHY_RX_CHAIN_CNT_POS); cmd->rxchain_info |= cpu_to_le32(active_cnt << PHY_RX_CHAIN_MIMO_CNT_POS); +#ifdef CONFIG_IWLWIFI_DEBUGFS if (unlikely(mvm->dbgfs_rx_phyinfo)) cmd->rxchain_info = cpu_to_le32(mvm->dbgfs_rx_phyinfo); +#endif cmd->txchain_info = cpu_to_le32(iwl_mvm_get_valid_tx_ant(mvm)); } -- GitLab From 42d0631bb6c9bd730437cca19e5b870ecd24215d Mon Sep 17 00:00:00 2001 From: Anda-Maria Nicolae Date: Thu, 5 Mar 2015 13:23:56 +0200 Subject: [PATCH 03361/11651] bq2415x_charger: Remove unnecessary else after return Fix coding style to comply with checkpatch.pl Signed-off-by: Anda-Maria Nicolae Signed-off-by: Sebastian Reichel --- drivers/power/bq2415x_charger.c | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/drivers/power/bq2415x_charger.c b/drivers/power/bq2415x_charger.c index 727740066754..4976c1b4bc82 100644 --- a/drivers/power/bq2415x_charger.c +++ b/drivers/power/bq2415x_charger.c @@ -346,8 +346,7 @@ static int bq2415x_exec_command(struct bq2415x_device *bq, BQ2415X_BIT_CE); if (ret < 0) return ret; - else - return ret > 0 ? 0 : 1; + return ret > 0 ? 0 : 1; case BQ2415X_CHARGER_ENABLE: return bq2415x_i2c_write_bit(bq, BQ2415X_REG_CONTROL, 0, BQ2415X_BIT_CE); @@ -420,20 +419,17 @@ static enum bq2415x_chip bq2415x_detect_chip(struct bq2415x_device *bq) case 0: if (bq->chip == BQ24151A) return bq->chip; - else - return BQ24151; + return BQ24151; case 1: if (bq->chip == BQ24150A || bq->chip == BQ24152 || bq->chip == BQ24155) return bq->chip; - else - return BQ24150; + return BQ24150; case 2: if (bq->chip == BQ24153A) return bq->chip; - else - return BQ24153; + return BQ24153; default: return BQUNKNOWN; } @@ -444,8 +440,7 @@ static enum bq2415x_chip bq2415x_detect_chip(struct bq2415x_device *bq) case 0: if (bq->chip == BQ24156A) return bq->chip; - else - return BQ24156; + return BQ24156; case 2: return BQ24158; default: @@ -474,8 +469,7 @@ static int bq2415x_detect_revision(struct bq2415x_device *bq) case BQ24152: if (ret >= 0 && ret <= 3) return ret; - else - return -1; + return -1; case BQ24153: case BQ24153A: case BQ24156: @@ -485,13 +479,11 @@ static int bq2415x_detect_revision(struct bq2415x_device *bq) return 0; else if (ret == 1) return 1; - else - return -1; + return -1; case BQ24155: if (ret == 3) return 3; - else - return -1; + return -1; case BQUNKNOWN: return -1; } -- GitLab From 0e1392d9df3dca4c1774a0c61fd85fce81cb88cd Mon Sep 17 00:00:00 2001 From: Anda-Maria Nicolae Date: Thu, 5 Mar 2015 13:23:57 +0200 Subject: [PATCH 03362/11651] bq2415x_charger: Add support for bq24157s This patch adds bq24157s charger in the list of supported chargers. bq24157s is similar to bq24158, except for Bit6 from Special Charger Voltage/Enable Pin Status register, but this register is currently not used by bq2415x_charger. Signed-off-by: Anda-Maria Nicolae Signed-off-by: Sebastian Reichel --- drivers/power/bq2415x_charger.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/power/bq2415x_charger.c b/drivers/power/bq2415x_charger.c index 4976c1b4bc82..2333d7f1182b 100644 --- a/drivers/power/bq2415x_charger.c +++ b/drivers/power/bq2415x_charger.c @@ -20,6 +20,8 @@ * http://www.ti.com/product/bq24153 * http://www.ti.com/product/bq24153a * http://www.ti.com/product/bq24155 + * http://www.ti.com/product/bq24157s + * http://www.ti.com/product/bq24158 */ #include @@ -141,6 +143,7 @@ enum bq2415x_chip { BQ24155, BQ24156, BQ24156A, + BQ24157S, BQ24158, }; @@ -156,6 +159,7 @@ static char *bq2415x_chip_name[] = { "bq24155", "bq24156", "bq24156a", + "bq24157s", "bq24158", }; @@ -442,6 +446,8 @@ static enum bq2415x_chip bq2415x_detect_chip(struct bq2415x_device *bq) return bq->chip; return BQ24156; case 2: + if (bq->chip == BQ24157S) + return bq->chip; return BQ24158; default: return BQUNKNOWN; @@ -474,6 +480,7 @@ static int bq2415x_detect_revision(struct bq2415x_device *bq) case BQ24153A: case BQ24156: case BQ24156A: + case BQ24157S: case BQ24158: if (ret == 3) return 0; @@ -1717,6 +1724,7 @@ static const struct i2c_device_id bq2415x_i2c_id_table[] = { { "bq24155", BQ24155 }, { "bq24156", BQ24156 }, { "bq24156a", BQ24156A }, + { "bq24157s", BQ24157S }, { "bq24158", BQ24158 }, {}, }; -- GitLab From 776920e16a74b0009765d84b6c267fe820966307 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Sat, 7 Mar 2015 15:14:59 +0100 Subject: [PATCH 03363/11651] ARM: dts: rockchip: add input supplies for the act8846 on Radxa Rock On the Radxa Rock board most supplies come from the static 5v vsys supply, but the inl1-supply comes from the REG4 of the act8846 itself. Model this dependency using the added supply-handling to make sure the supplying regulator gets handled correctly and not accidentially turned off. Signed-off-by: Heiko Stuebner --- arch/arm/boot/dts/rk3188-radxarock.dts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/arch/arm/boot/dts/rk3188-radxarock.dts b/arch/arm/boot/dts/rk3188-radxarock.dts index 9a09579b8309..bdf85701987d 100644 --- a/arch/arm/boot/dts/rk3188-radxarock.dts +++ b/arch/arm/boot/dts/rk3188-radxarock.dts @@ -103,6 +103,14 @@ regulator-always-on; regulator-boot-on; }; + + vsys: vsys-regulator { + compatible = "regulator-fixed"; + regulator-name = "vsys"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-boot-on; + }; }; &emac { @@ -148,6 +156,14 @@ pinctrl-names = "default"; pinctrl-0 = <&act8846_dvs0_ctl>; + vp1-supply = <&vsys>; + vp2-supply = <&vsys>; + vp3-supply = <&vsys>; + vp4-supply = <&vsys>; + inl1-supply = <&vcc_io>; + inl2-supply = <&vsys>; + inl3-supply = <&vsys>; + regulators { vcc_ddr: REG1 { regulator-name = "VCC_DDR"; -- GitLab From b571a77a0dec969728e102971dd126cf374c2cef Mon Sep 17 00:00:00 2001 From: Todd Brandt Date: Wed, 4 Feb 2015 16:24:36 -0800 Subject: [PATCH 03364/11651] mfd/axp20x: change battery cell name to fuel gauge Name changes to the battery cell structure to a more generic cell type: fuel gauge. Signed-off-by: Todd Brandt Acked-By: Sebastian Reichel Acked-by: Jacob Pan Signed-off-by: Sebastian Reichel --- drivers/mfd/axp20x.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c index b1b580a88654..0acbe52b2411 100644 --- a/drivers/mfd/axp20x.c +++ b/drivers/mfd/axp20x.c @@ -87,7 +87,7 @@ static struct resource axp20x_pek_resources[] = { }, }; -static struct resource axp288_battery_resources[] = { +static struct resource axp288_fuel_gauge_resources[] = { { .start = AXP288_IRQ_QWBTU, .end = AXP288_IRQ_QWBTU, @@ -350,9 +350,9 @@ static struct mfd_cell axp288_cells[] = { .resources = axp288_charger_resources, }, { - .name = "axp288_battery", - .num_resources = ARRAY_SIZE(axp288_battery_resources), - .resources = axp288_battery_resources, + .name = "axp288_fuel_gauge", + .num_resources = ARRAY_SIZE(axp288_fuel_gauge_resources), + .resources = axp288_fuel_gauge_resources, }, { .name = "axp288_pmic_acpi", -- GitLab From 5a5bf49088f4c92f36786a2e4c20e17f715f0827 Mon Sep 17 00:00:00 2001 From: Todd Brandt Date: Wed, 4 Feb 2015 16:24:38 -0800 Subject: [PATCH 03365/11651] X-Power AXP288 PMIC Fuel Gauge Driver New power_supply driver at driver/power which interfaces with the axp20x mfd driver as a cell. Provides battery info, monitors for changes, and generates alerts on temperature and capacity issues Signed-off-by: Todd Brandt Acked-by: Jacob Pan Signed-off-by: Sebastian Reichel --- drivers/power/Kconfig | 9 + drivers/power/Makefile | 1 + drivers/power/axp288_fuel_gauge.c | 1151 +++++++++++++++++++++++++++++ 3 files changed, 1161 insertions(+) create mode 100644 drivers/power/axp288_fuel_gauge.c diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index 640eb36f49c0..4091fb092d06 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -204,6 +204,15 @@ config CHARGER_DA9150 This driver can also be built as a module. If so, the module will be called da9150-charger. +config AXP288_FUEL_GAUGE + tristate "X-Powers AXP288 Fuel Gauge" + depends on MFD_AXP20X && IIO + help + Say yes here to have support for X-Power power management IC (PMIC) + Fuel Gauge. The device provides battery statistics and status + monitoring as well as alerts for battery over/under voltage and + over/under temperature. + config BATTERY_MAX17040 tristate "Maxim MAX17040 Fuel Gauge" depends on I2C diff --git a/drivers/power/Makefile b/drivers/power/Makefile index 7b604f4926fc..b7b0181c95e5 100644 --- a/drivers/power/Makefile +++ b/drivers/power/Makefile @@ -63,3 +63,4 @@ obj-$(CONFIG_POWER_AVS) += avs/ obj-$(CONFIG_CHARGER_SMB347) += smb347-charger.o obj-$(CONFIG_CHARGER_TPS65090) += tps65090-charger.o obj-$(CONFIG_POWER_RESET) += reset/ +obj-$(CONFIG_AXP288_FUEL_GAUGE) += axp288_fuel_gauge.o diff --git a/drivers/power/axp288_fuel_gauge.c b/drivers/power/axp288_fuel_gauge.c new file mode 100644 index 000000000000..c86e709c1880 --- /dev/null +++ b/drivers/power/axp288_fuel_gauge.c @@ -0,0 +1,1151 @@ +/* + * axp288_fuel_gauge.c - Xpower AXP288 PMIC Fuel Gauge Driver + * + * Copyright (C) 2014 Intel Corporation + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define CHRG_STAT_BAT_SAFE_MODE (1 << 3) +#define CHRG_STAT_BAT_VALID (1 << 4) +#define CHRG_STAT_BAT_PRESENT (1 << 5) +#define CHRG_STAT_CHARGING (1 << 6) +#define CHRG_STAT_PMIC_OTP (1 << 7) + +#define CHRG_CCCV_CC_MASK 0xf /* 4 bits */ +#define CHRG_CCCV_CC_BIT_POS 0 +#define CHRG_CCCV_CC_OFFSET 200 /* 200mA */ +#define CHRG_CCCV_CC_LSB_RES 200 /* 200mA */ +#define CHRG_CCCV_ITERM_20P (1 << 4) /* 20% of CC */ +#define CHRG_CCCV_CV_MASK 0x60 /* 2 bits */ +#define CHRG_CCCV_CV_BIT_POS 5 +#define CHRG_CCCV_CV_4100MV 0x0 /* 4.10V */ +#define CHRG_CCCV_CV_4150MV 0x1 /* 4.15V */ +#define CHRG_CCCV_CV_4200MV 0x2 /* 4.20V */ +#define CHRG_CCCV_CV_4350MV 0x3 /* 4.35V */ +#define CHRG_CCCV_CHG_EN (1 << 7) + +#define CV_4100 4100 /* 4100mV */ +#define CV_4150 4150 /* 4150mV */ +#define CV_4200 4200 /* 4200mV */ +#define CV_4350 4350 /* 4350mV */ + +#define TEMP_IRQ_CFG_QWBTU (1 << 0) +#define TEMP_IRQ_CFG_WBTU (1 << 1) +#define TEMP_IRQ_CFG_QWBTO (1 << 2) +#define TEMP_IRQ_CFG_WBTO (1 << 3) +#define TEMP_IRQ_CFG_MASK 0xf + +#define FG_IRQ_CFG_LOWBATT_WL2 (1 << 0) +#define FG_IRQ_CFG_LOWBATT_WL1 (1 << 1) +#define FG_IRQ_CFG_LOWBATT_MASK 0x3 +#define LOWBAT_IRQ_STAT_LOWBATT_WL2 (1 << 0) +#define LOWBAT_IRQ_STAT_LOWBATT_WL1 (1 << 1) + +#define FG_CNTL_OCV_ADJ_STAT (1 << 2) +#define FG_CNTL_OCV_ADJ_EN (1 << 3) +#define FG_CNTL_CAP_ADJ_STAT (1 << 4) +#define FG_CNTL_CAP_ADJ_EN (1 << 5) +#define FG_CNTL_CC_EN (1 << 6) +#define FG_CNTL_GAUGE_EN (1 << 7) + +#define FG_REP_CAP_VALID (1 << 7) +#define FG_REP_CAP_VAL_MASK 0x7F + +#define FG_DES_CAP1_VALID (1 << 7) +#define FG_DES_CAP1_VAL_MASK 0x7F +#define FG_DES_CAP0_VAL_MASK 0xFF +#define FG_DES_CAP_RES_LSB 1456 /* 1.456mAhr */ + +#define FG_CC_MTR1_VALID (1 << 7) +#define FG_CC_MTR1_VAL_MASK 0x7F +#define FG_CC_MTR0_VAL_MASK 0xFF +#define FG_DES_CC_RES_LSB 1456 /* 1.456mAhr */ + +#define FG_OCV_CAP_VALID (1 << 7) +#define FG_OCV_CAP_VAL_MASK 0x7F +#define FG_CC_CAP_VALID (1 << 7) +#define FG_CC_CAP_VAL_MASK 0x7F + +#define FG_LOW_CAP_THR1_MASK 0xf0 /* 5% tp 20% */ +#define FG_LOW_CAP_THR1_VAL 0xa0 /* 15 perc */ +#define FG_LOW_CAP_THR2_MASK 0x0f /* 0% to 15% */ +#define FG_LOW_CAP_WARN_THR 14 /* 14 perc */ +#define FG_LOW_CAP_CRIT_THR 4 /* 4 perc */ +#define FG_LOW_CAP_SHDN_THR 0 /* 0 perc */ + +#define STATUS_MON_DELAY_JIFFIES (HZ * 60) /*60 sec */ +#define NR_RETRY_CNT 3 +#define DEV_NAME "axp288_fuel_gauge" + +/* 1.1mV per LSB expressed in uV */ +#define VOLTAGE_FROM_ADC(a) ((a * 11) / 10) +/* properties converted to tenths of degrees, uV, uA, uW */ +#define PROP_TEMP(a) ((a) * 10) +#define UNPROP_TEMP(a) ((a) / 10) +#define PROP_VOLT(a) ((a) * 1000) +#define PROP_CURR(a) ((a) * 1000) + +#define AXP288_FG_INTR_NUM 6 +enum { + QWBTU_IRQ = 0, + WBTU_IRQ, + QWBTO_IRQ, + WBTO_IRQ, + WL2_IRQ, + WL1_IRQ, +}; + +struct axp288_fg_info { + struct platform_device *pdev; + struct axp20x_fg_pdata *pdata; + struct regmap *regmap; + struct regmap_irq_chip_data *regmap_irqc; + int irq[AXP288_FG_INTR_NUM]; + struct power_supply bat; + struct mutex lock; + int status; + struct delayed_work status_monitor; + struct dentry *debug_file; +}; + +static enum power_supply_property fuel_gauge_props[] = { + POWER_SUPPLY_PROP_STATUS, + POWER_SUPPLY_PROP_PRESENT, + POWER_SUPPLY_PROP_HEALTH, + POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, + POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, + POWER_SUPPLY_PROP_VOLTAGE_NOW, + POWER_SUPPLY_PROP_VOLTAGE_OCV, + POWER_SUPPLY_PROP_CURRENT_NOW, + POWER_SUPPLY_PROP_CAPACITY, + POWER_SUPPLY_PROP_CAPACITY_ALERT_MIN, + POWER_SUPPLY_PROP_TEMP, + POWER_SUPPLY_PROP_TEMP_MAX, + POWER_SUPPLY_PROP_TEMP_MIN, + POWER_SUPPLY_PROP_TEMP_ALERT_MIN, + POWER_SUPPLY_PROP_TEMP_ALERT_MAX, + POWER_SUPPLY_PROP_TECHNOLOGY, + POWER_SUPPLY_PROP_CHARGE_FULL, + POWER_SUPPLY_PROP_CHARGE_NOW, + POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, + POWER_SUPPLY_PROP_MODEL_NAME, +}; + +static int fuel_gauge_reg_readb(struct axp288_fg_info *info, int reg) +{ + int ret, i; + unsigned int val; + + for (i = 0; i < NR_RETRY_CNT; i++) { + ret = regmap_read(info->regmap, reg, &val); + if (ret == -EBUSY) + continue; + else + break; + } + + if (ret < 0) + dev_err(&info->pdev->dev, "axp288 reg read err:%d\n", ret); + + return val; +} + +static int fuel_gauge_reg_writeb(struct axp288_fg_info *info, int reg, u8 val) +{ + int ret; + + ret = regmap_write(info->regmap, reg, (unsigned int)val); + + if (ret < 0) + dev_err(&info->pdev->dev, "axp288 reg write err:%d\n", ret); + + return ret; +} + +static int pmic_read_adc_val(const char *name, int *raw_val, + struct axp288_fg_info *info) +{ + int ret, val = 0; + struct iio_channel *indio_chan; + + indio_chan = iio_channel_get(NULL, name); + if (IS_ERR_OR_NULL(indio_chan)) { + ret = PTR_ERR(indio_chan); + goto exit; + } + ret = iio_read_channel_raw(indio_chan, &val); + if (ret < 0) { + dev_err(&info->pdev->dev, + "IIO channel read error: %x, %x\n", ret, val); + goto err_exit; + } + + dev_dbg(&info->pdev->dev, "adc raw val=%x\n", val); + *raw_val = val; + +err_exit: + iio_channel_release(indio_chan); +exit: + return ret; +} + +#ifdef CONFIG_DEBUG_FS +static int fuel_gauge_debug_show(struct seq_file *s, void *data) +{ + struct axp288_fg_info *info = s->private; + int raw_val, ret; + + seq_printf(s, " PWR_STATUS[%02x] : %02x\n", + AXP20X_PWR_INPUT_STATUS, + fuel_gauge_reg_readb(info, AXP20X_PWR_INPUT_STATUS)); + seq_printf(s, "PWR_OP_MODE[%02x] : %02x\n", + AXP20X_PWR_OP_MODE, + fuel_gauge_reg_readb(info, AXP20X_PWR_OP_MODE)); + seq_printf(s, " CHRG_CTRL1[%02x] : %02x\n", + AXP20X_CHRG_CTRL1, + fuel_gauge_reg_readb(info, AXP20X_CHRG_CTRL1)); + seq_printf(s, " VLTF[%02x] : %02x\n", + AXP20X_V_LTF_DISCHRG, + fuel_gauge_reg_readb(info, AXP20X_V_LTF_DISCHRG)); + seq_printf(s, " VHTF[%02x] : %02x\n", + AXP20X_V_HTF_DISCHRG, + fuel_gauge_reg_readb(info, AXP20X_V_HTF_DISCHRG)); + seq_printf(s, " CC_CTRL[%02x] : %02x\n", + AXP20X_CC_CTRL, + fuel_gauge_reg_readb(info, AXP20X_CC_CTRL)); + seq_printf(s, "BATTERY CAP[%02x] : %02x\n", + AXP20X_FG_RES, + fuel_gauge_reg_readb(info, AXP20X_FG_RES)); + seq_printf(s, " FG_RDC1[%02x] : %02x\n", + AXP288_FG_RDC1_REG, + fuel_gauge_reg_readb(info, AXP288_FG_RDC1_REG)); + seq_printf(s, " FG_RDC0[%02x] : %02x\n", + AXP288_FG_RDC0_REG, + fuel_gauge_reg_readb(info, AXP288_FG_RDC0_REG)); + seq_printf(s, " FG_OCVH[%02x] : %02x\n", + AXP288_FG_OCVH_REG, + fuel_gauge_reg_readb(info, AXP288_FG_OCVH_REG)); + seq_printf(s, " FG_OCVL[%02x] : %02x\n", + AXP288_FG_OCVL_REG, + fuel_gauge_reg_readb(info, AXP288_FG_OCVL_REG)); + seq_printf(s, "FG_DES_CAP1[%02x] : %02x\n", + AXP288_FG_DES_CAP1_REG, + fuel_gauge_reg_readb(info, AXP288_FG_DES_CAP1_REG)); + seq_printf(s, "FG_DES_CAP0[%02x] : %02x\n", + AXP288_FG_DES_CAP0_REG, + fuel_gauge_reg_readb(info, AXP288_FG_DES_CAP0_REG)); + seq_printf(s, " FG_CC_MTR1[%02x] : %02x\n", + AXP288_FG_CC_MTR1_REG, + fuel_gauge_reg_readb(info, AXP288_FG_CC_MTR1_REG)); + seq_printf(s, " FG_CC_MTR0[%02x] : %02x\n", + AXP288_FG_CC_MTR0_REG, + fuel_gauge_reg_readb(info, AXP288_FG_CC_MTR0_REG)); + seq_printf(s, " FG_OCV_CAP[%02x] : %02x\n", + AXP288_FG_OCV_CAP_REG, + fuel_gauge_reg_readb(info, AXP288_FG_OCV_CAP_REG)); + seq_printf(s, " FG_CC_CAP[%02x] : %02x\n", + AXP288_FG_CC_CAP_REG, + fuel_gauge_reg_readb(info, AXP288_FG_CC_CAP_REG)); + seq_printf(s, " FG_LOW_CAP[%02x] : %02x\n", + AXP288_FG_LOW_CAP_REG, + fuel_gauge_reg_readb(info, AXP288_FG_LOW_CAP_REG)); + seq_printf(s, "TUNING_CTL0[%02x] : %02x\n", + AXP288_FG_TUNE0, + fuel_gauge_reg_readb(info, AXP288_FG_TUNE0)); + seq_printf(s, "TUNING_CTL1[%02x] : %02x\n", + AXP288_FG_TUNE1, + fuel_gauge_reg_readb(info, AXP288_FG_TUNE1)); + seq_printf(s, "TUNING_CTL2[%02x] : %02x\n", + AXP288_FG_TUNE2, + fuel_gauge_reg_readb(info, AXP288_FG_TUNE2)); + seq_printf(s, "TUNING_CTL3[%02x] : %02x\n", + AXP288_FG_TUNE3, + fuel_gauge_reg_readb(info, AXP288_FG_TUNE3)); + seq_printf(s, "TUNING_CTL4[%02x] : %02x\n", + AXP288_FG_TUNE4, + fuel_gauge_reg_readb(info, AXP288_FG_TUNE4)); + seq_printf(s, "TUNING_CTL5[%02x] : %02x\n", + AXP288_FG_TUNE5, + fuel_gauge_reg_readb(info, AXP288_FG_TUNE5)); + + ret = pmic_read_adc_val("axp288-batt-temp", &raw_val, info); + if (ret >= 0) + seq_printf(s, "axp288-batttemp : %d\n", raw_val); + ret = pmic_read_adc_val("axp288-pmic-temp", &raw_val, info); + if (ret >= 0) + seq_printf(s, "axp288-pmictemp : %d\n", raw_val); + ret = pmic_read_adc_val("axp288-system-temp", &raw_val, info); + if (ret >= 0) + seq_printf(s, "axp288-systtemp : %d\n", raw_val); + ret = pmic_read_adc_val("axp288-chrg-curr", &raw_val, info); + if (ret >= 0) + seq_printf(s, "axp288-chrgcurr : %d\n", raw_val); + ret = pmic_read_adc_val("axp288-chrg-d-curr", &raw_val, info); + if (ret >= 0) + seq_printf(s, "axp288-dchrgcur : %d\n", raw_val); + ret = pmic_read_adc_val("axp288-batt-volt", &raw_val, info); + if (ret >= 0) + seq_printf(s, "axp288-battvolt : %d\n", raw_val); + + return 0; +} + +static int debug_open(struct inode *inode, struct file *file) +{ + return single_open(file, fuel_gauge_debug_show, inode->i_private); +} + +static const struct file_operations fg_debug_fops = { + .open = debug_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static void fuel_gauge_create_debugfs(struct axp288_fg_info *info) +{ + info->debug_file = debugfs_create_file("fuelgauge", 0666, NULL, + info, &fg_debug_fops); +} + +static void fuel_gauge_remove_debugfs(struct axp288_fg_info *info) +{ + debugfs_remove(info->debug_file); +} +#else +static inline void fuel_gauge_create_debugfs(struct axp288_fg_info *info) +{ +} +static inline void fuel_gauge_remove_debugfs(struct axp288_fg_info *info) +{ +} +#endif + +static void fuel_gauge_get_status(struct axp288_fg_info *info) +{ + int pwr_stat, ret; + int charge, discharge; + + pwr_stat = fuel_gauge_reg_readb(info, AXP20X_PWR_INPUT_STATUS); + if (pwr_stat < 0) { + dev_err(&info->pdev->dev, + "PWR STAT read failed:%d\n", pwr_stat); + return; + } + ret = pmic_read_adc_val("axp288-chrg-curr", &charge, info); + if (ret < 0) { + dev_err(&info->pdev->dev, + "ADC charge current read failed:%d\n", ret); + return; + } + ret = pmic_read_adc_val("axp288-chrg-d-curr", &discharge, info); + if (ret < 0) { + dev_err(&info->pdev->dev, + "ADC discharge current read failed:%d\n", ret); + return; + } + + if (charge > 0) + info->status = POWER_SUPPLY_STATUS_CHARGING; + else if (discharge > 0) + info->status = POWER_SUPPLY_STATUS_DISCHARGING; + else { + if (pwr_stat & CHRG_STAT_BAT_PRESENT) + info->status = POWER_SUPPLY_STATUS_FULL; + else + info->status = POWER_SUPPLY_STATUS_NOT_CHARGING; + } +} + +static int fuel_gauge_get_vbatt(struct axp288_fg_info *info, int *vbatt) +{ + int ret = 0, raw_val; + + ret = pmic_read_adc_val("axp288-batt-volt", &raw_val, info); + if (ret < 0) + goto vbatt_read_fail; + + *vbatt = VOLTAGE_FROM_ADC(raw_val); +vbatt_read_fail: + return ret; +} + +static int fuel_gauge_get_current(struct axp288_fg_info *info, int *cur) +{ + int ret, value = 0; + int charge, discharge; + + ret = pmic_read_adc_val("axp288-chrg-curr", &charge, info); + if (ret < 0) + goto current_read_fail; + ret = pmic_read_adc_val("axp288-chrg-d-curr", &discharge, info); + if (ret < 0) + goto current_read_fail; + + if (charge > 0) + value = charge; + else if (discharge > 0) + value = -1 * discharge; + + *cur = value; +current_read_fail: + return ret; +} + +static int temp_to_adc(struct axp288_fg_info *info, int tval) +{ + int rntc = 0, i, ret, adc_val; + int rmin, rmax, tmin, tmax; + int tcsz = info->pdata->tcsz; + + /* get the Rntc resitance value for this temp */ + if (tval > info->pdata->thermistor_curve[0][1]) { + rntc = info->pdata->thermistor_curve[0][0]; + } else if (tval <= info->pdata->thermistor_curve[tcsz-1][1]) { + rntc = info->pdata->thermistor_curve[tcsz-1][0]; + } else { + for (i = 1; i < tcsz; i++) { + if (tval > info->pdata->thermistor_curve[i][1]) { + rmin = info->pdata->thermistor_curve[i-1][0]; + rmax = info->pdata->thermistor_curve[i][0]; + tmin = info->pdata->thermistor_curve[i-1][1]; + tmax = info->pdata->thermistor_curve[i][1]; + rntc = rmin + ((rmax - rmin) * + (tval - tmin) / (tmax - tmin)); + break; + } + } + } + + /* we need the current to calculate the proper adc voltage */ + ret = fuel_gauge_reg_readb(info, AXP20X_ADC_RATE); + if (ret < 0) { + dev_err(&info->pdev->dev, "%s:read err:%d\n", __func__, ret); + ret = 0x30; + } + + /* + * temperature is proportional to NTS thermistor resistance + * ADC_RATE[5-4] determines current, 00=20uA,01=40uA,10=60uA,11=80uA + * [12-bit ADC VAL] = R_NTC(Ω) * current / 800 + */ + adc_val = rntc * (20 + (20 * ((ret >> 4) & 0x3))) / 800; + + return adc_val; +} + +static int adc_to_temp(struct axp288_fg_info *info, int adc_val) +{ + int ret, r, i, tval = 0; + int rmin, rmax, tmin, tmax; + int tcsz = info->pdata->tcsz; + + ret = fuel_gauge_reg_readb(info, AXP20X_ADC_RATE); + if (ret < 0) { + dev_err(&info->pdev->dev, "%s:read err:%d\n", __func__, ret); + ret = 0x30; + } + + /* + * temperature is proportional to NTS thermistor resistance + * ADC_RATE[5-4] determines current, 00=20uA,01=40uA,10=60uA,11=80uA + * R_NTC(Ω) = [12-bit ADC VAL] * 800 / current + */ + r = adc_val * 800 / (20 + (20 * ((ret >> 4) & 0x3))); + + if (r < info->pdata->thermistor_curve[0][0]) { + tval = info->pdata->thermistor_curve[0][1]; + } else if (r >= info->pdata->thermistor_curve[tcsz-1][0]) { + tval = info->pdata->thermistor_curve[tcsz-1][1]; + } else { + for (i = 1; i < tcsz; i++) { + if (r < info->pdata->thermistor_curve[i][0]) { + rmin = info->pdata->thermistor_curve[i-1][0]; + rmax = info->pdata->thermistor_curve[i][0]; + tmin = info->pdata->thermistor_curve[i-1][1]; + tmax = info->pdata->thermistor_curve[i][1]; + tval = tmin + ((tmax - tmin) * + (r - rmin) / (rmax - rmin)); + break; + } + } + } + + return tval; +} + +static int fuel_gauge_get_btemp(struct axp288_fg_info *info, int *btemp) +{ + int ret, raw_val = 0; + + ret = pmic_read_adc_val("axp288-batt-temp", &raw_val, info); + if (ret < 0) + goto temp_read_fail; + + *btemp = adc_to_temp(info, raw_val); + +temp_read_fail: + return ret; +} + +static int fuel_gauge_get_vocv(struct axp288_fg_info *info, int *vocv) +{ + int ret, value; + + /* 12-bit data value, upper 8 in OCVH, lower 4 in OCVL */ + ret = fuel_gauge_reg_readb(info, AXP288_FG_OCVH_REG); + if (ret < 0) + goto vocv_read_fail; + value = ret << 4; + + ret = fuel_gauge_reg_readb(info, AXP288_FG_OCVL_REG); + if (ret < 0) + goto vocv_read_fail; + value |= (ret & 0xf); + + *vocv = VOLTAGE_FROM_ADC(value); +vocv_read_fail: + return ret; +} + +static int fuel_gauge_battery_health(struct axp288_fg_info *info) +{ + int temp, vocv; + int ret, health = POWER_SUPPLY_HEALTH_UNKNOWN; + + ret = fuel_gauge_get_btemp(info, &temp); + if (ret < 0) + goto health_read_fail; + + ret = fuel_gauge_get_vocv(info, &vocv); + if (ret < 0) + goto health_read_fail; + + if (vocv > info->pdata->max_volt) + health = POWER_SUPPLY_HEALTH_OVERVOLTAGE; + else if (temp > info->pdata->max_temp) + health = POWER_SUPPLY_HEALTH_OVERHEAT; + else if (temp < info->pdata->min_temp) + health = POWER_SUPPLY_HEALTH_COLD; + else if (vocv < info->pdata->min_volt) + health = POWER_SUPPLY_HEALTH_DEAD; + else + health = POWER_SUPPLY_HEALTH_GOOD; + +health_read_fail: + return health; +} + +static int fuel_gauge_set_high_btemp_alert(struct axp288_fg_info *info) +{ + int ret, adc_val; + + /* program temperature threshold as 1/16 ADC value */ + adc_val = temp_to_adc(info, info->pdata->max_temp); + ret = fuel_gauge_reg_writeb(info, AXP20X_V_HTF_DISCHRG, adc_val >> 4); + + return ret; +} + +static int fuel_gauge_set_low_btemp_alert(struct axp288_fg_info *info) +{ + int ret, adc_val; + + /* program temperature threshold as 1/16 ADC value */ + adc_val = temp_to_adc(info, info->pdata->min_temp); + ret = fuel_gauge_reg_writeb(info, AXP20X_V_LTF_DISCHRG, adc_val >> 4); + + return ret; +} + +static int fuel_gauge_get_property(struct power_supply *ps, + enum power_supply_property prop, + union power_supply_propval *val) +{ + struct axp288_fg_info *info = container_of(ps, + struct axp288_fg_info, bat); + int ret = 0, value; + + mutex_lock(&info->lock); + switch (prop) { + case POWER_SUPPLY_PROP_STATUS: + fuel_gauge_get_status(info); + val->intval = info->status; + break; + case POWER_SUPPLY_PROP_HEALTH: + val->intval = fuel_gauge_battery_health(info); + break; + case POWER_SUPPLY_PROP_VOLTAGE_NOW: + ret = fuel_gauge_get_vbatt(info, &value); + if (ret < 0) + goto fuel_gauge_read_err; + val->intval = PROP_VOLT(value); + break; + case POWER_SUPPLY_PROP_VOLTAGE_OCV: + ret = fuel_gauge_get_vocv(info, &value); + if (ret < 0) + goto fuel_gauge_read_err; + val->intval = PROP_VOLT(value); + break; + case POWER_SUPPLY_PROP_CURRENT_NOW: + ret = fuel_gauge_get_current(info, &value); + if (ret < 0) + goto fuel_gauge_read_err; + val->intval = PROP_CURR(value); + break; + case POWER_SUPPLY_PROP_PRESENT: + ret = fuel_gauge_reg_readb(info, AXP20X_PWR_OP_MODE); + if (ret < 0) + goto fuel_gauge_read_err; + + if (ret & CHRG_STAT_BAT_PRESENT) + val->intval = 1; + else + val->intval = 0; + break; + case POWER_SUPPLY_PROP_CAPACITY: + ret = fuel_gauge_reg_readb(info, AXP20X_FG_RES); + if (ret < 0) + goto fuel_gauge_read_err; + + if (!(ret & FG_REP_CAP_VALID)) + dev_err(&info->pdev->dev, + "capacity measurement not valid\n"); + val->intval = (ret & FG_REP_CAP_VAL_MASK); + break; + case POWER_SUPPLY_PROP_CAPACITY_ALERT_MIN: + ret = fuel_gauge_reg_readb(info, AXP288_FG_LOW_CAP_REG); + if (ret < 0) + goto fuel_gauge_read_err; + val->intval = (ret & 0x0f); + break; + case POWER_SUPPLY_PROP_TEMP: + ret = fuel_gauge_get_btemp(info, &value); + if (ret < 0) + goto fuel_gauge_read_err; + val->intval = PROP_TEMP(value); + break; + case POWER_SUPPLY_PROP_TEMP_MAX: + case POWER_SUPPLY_PROP_TEMP_ALERT_MAX: + val->intval = PROP_TEMP(info->pdata->max_temp); + break; + case POWER_SUPPLY_PROP_TEMP_MIN: + case POWER_SUPPLY_PROP_TEMP_ALERT_MIN: + val->intval = PROP_TEMP(info->pdata->min_temp); + break; + case POWER_SUPPLY_PROP_TECHNOLOGY: + val->intval = POWER_SUPPLY_TECHNOLOGY_LION; + break; + case POWER_SUPPLY_PROP_CHARGE_NOW: + ret = fuel_gauge_reg_readb(info, AXP288_FG_CC_MTR1_REG); + if (ret < 0) + goto fuel_gauge_read_err; + + value = (ret & FG_CC_MTR1_VAL_MASK) << 8; + ret = fuel_gauge_reg_readb(info, AXP288_FG_CC_MTR0_REG); + if (ret < 0) + goto fuel_gauge_read_err; + value |= (ret & FG_CC_MTR0_VAL_MASK); + val->intval = value * FG_DES_CAP_RES_LSB; + break; + case POWER_SUPPLY_PROP_CHARGE_FULL: + ret = fuel_gauge_reg_readb(info, AXP288_FG_DES_CAP1_REG); + if (ret < 0) + goto fuel_gauge_read_err; + + value = (ret & FG_DES_CAP1_VAL_MASK) << 8; + ret = fuel_gauge_reg_readb(info, AXP288_FG_DES_CAP0_REG); + if (ret < 0) + goto fuel_gauge_read_err; + value |= (ret & FG_DES_CAP0_VAL_MASK); + val->intval = value * FG_DES_CAP_RES_LSB; + break; + case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: + val->intval = PROP_CURR(info->pdata->design_cap); + break; + case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: + val->intval = PROP_VOLT(info->pdata->max_volt); + break; + case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: + val->intval = PROP_VOLT(info->pdata->min_volt); + break; + case POWER_SUPPLY_PROP_MODEL_NAME: + val->strval = info->pdata->battid; + break; + default: + mutex_unlock(&info->lock); + return -EINVAL; + } + + mutex_unlock(&info->lock); + return 0; + +fuel_gauge_read_err: + mutex_unlock(&info->lock); + return ret; +} + +static int fuel_gauge_set_property(struct power_supply *ps, + enum power_supply_property prop, + const union power_supply_propval *val) +{ + struct axp288_fg_info *info = container_of(ps, + struct axp288_fg_info, bat); + int ret = 0; + + mutex_lock(&info->lock); + switch (prop) { + case POWER_SUPPLY_PROP_STATUS: + info->status = val->intval; + break; + case POWER_SUPPLY_PROP_TEMP_MIN: + case POWER_SUPPLY_PROP_TEMP_ALERT_MIN: + if ((val->intval < PD_DEF_MIN_TEMP) || + (val->intval > PD_DEF_MAX_TEMP)) { + ret = -EINVAL; + break; + } + info->pdata->min_temp = UNPROP_TEMP(val->intval); + ret = fuel_gauge_set_low_btemp_alert(info); + if (ret < 0) + dev_err(&info->pdev->dev, + "temp alert min set fail:%d\n", ret); + break; + case POWER_SUPPLY_PROP_TEMP_MAX: + case POWER_SUPPLY_PROP_TEMP_ALERT_MAX: + if ((val->intval < PD_DEF_MIN_TEMP) || + (val->intval > PD_DEF_MAX_TEMP)) { + ret = -EINVAL; + break; + } + info->pdata->max_temp = UNPROP_TEMP(val->intval); + ret = fuel_gauge_set_high_btemp_alert(info); + if (ret < 0) + dev_err(&info->pdev->dev, + "temp alert max set fail:%d\n", ret); + break; + case POWER_SUPPLY_PROP_CAPACITY_ALERT_MIN: + if ((val->intval < 0) || (val->intval > 15)) { + ret = -EINVAL; + break; + } + ret = fuel_gauge_reg_readb(info, AXP288_FG_LOW_CAP_REG); + if (ret < 0) + break; + ret &= 0xf0; + ret |= (val->intval & 0xf); + ret = fuel_gauge_reg_writeb(info, AXP288_FG_LOW_CAP_REG, ret); + break; + default: + ret = -EINVAL; + break; + } + + mutex_unlock(&info->lock); + return ret; +} + +static int fuel_gauge_property_is_writeable(struct power_supply *psy, + enum power_supply_property psp) +{ + int ret; + + switch (psp) { + case POWER_SUPPLY_PROP_STATUS: + case POWER_SUPPLY_PROP_TEMP_MIN: + case POWER_SUPPLY_PROP_TEMP_ALERT_MIN: + case POWER_SUPPLY_PROP_TEMP_MAX: + case POWER_SUPPLY_PROP_TEMP_ALERT_MAX: + case POWER_SUPPLY_PROP_CAPACITY_ALERT_MIN: + ret = 1; + break; + default: + ret = 0; + } + + return ret; +} + +static void fuel_gauge_status_monitor(struct work_struct *work) +{ + struct axp288_fg_info *info = container_of(work, + struct axp288_fg_info, status_monitor.work); + + fuel_gauge_get_status(info); + power_supply_changed(&info->bat); + schedule_delayed_work(&info->status_monitor, STATUS_MON_DELAY_JIFFIES); +} + +static irqreturn_t fuel_gauge_thread_handler(int irq, void *dev) +{ + struct axp288_fg_info *info = dev; + int i; + + for (i = 0; i < AXP288_FG_INTR_NUM; i++) { + if (info->irq[i] == irq) + break; + } + + if (i >= AXP288_FG_INTR_NUM) { + dev_warn(&info->pdev->dev, "spurious interrupt!!\n"); + return IRQ_NONE; + } + + switch (i) { + case QWBTU_IRQ: + dev_info(&info->pdev->dev, + "Quit Battery under temperature in work mode IRQ (QWBTU)\n"); + break; + case WBTU_IRQ: + dev_info(&info->pdev->dev, + "Battery under temperature in work mode IRQ (WBTU)\n"); + break; + case QWBTO_IRQ: + dev_info(&info->pdev->dev, + "Quit Battery over temperature in work mode IRQ (QWBTO)\n"); + break; + case WBTO_IRQ: + dev_info(&info->pdev->dev, + "Battery over temperature in work mode IRQ (WBTO)\n"); + break; + case WL2_IRQ: + dev_info(&info->pdev->dev, "Low Batt Warning(2) INTR\n"); + break; + case WL1_IRQ: + dev_info(&info->pdev->dev, "Low Batt Warning(1) INTR\n"); + break; + default: + dev_warn(&info->pdev->dev, "Spurious Interrupt!!!\n"); + } + + power_supply_changed(&info->bat); + return IRQ_HANDLED; +} + +static void fuel_gauge_external_power_changed(struct power_supply *psy) +{ + struct axp288_fg_info *info = container_of(psy, + struct axp288_fg_info, bat); + + power_supply_changed(&info->bat); +} + +static int fuel_gauge_set_lowbatt_thresholds(struct axp288_fg_info *info) +{ + int ret; + u8 reg_val; + + ret = fuel_gauge_reg_readb(info, AXP20X_FG_RES); + if (ret < 0) { + dev_err(&info->pdev->dev, "%s:read err:%d\n", __func__, ret); + return ret; + } + ret = (ret & FG_REP_CAP_VAL_MASK); + + if (ret > FG_LOW_CAP_WARN_THR) + reg_val = FG_LOW_CAP_WARN_THR; + else if (ret > FG_LOW_CAP_CRIT_THR) + reg_val = FG_LOW_CAP_CRIT_THR; + else + reg_val = FG_LOW_CAP_SHDN_THR; + + reg_val |= FG_LOW_CAP_THR1_VAL; + ret = fuel_gauge_reg_writeb(info, AXP288_FG_LOW_CAP_REG, reg_val); + if (ret < 0) + dev_err(&info->pdev->dev, "%s:write err:%d\n", __func__, ret); + + return ret; +} + +static int fuel_gauge_program_vbatt_full(struct axp288_fg_info *info) +{ + int ret; + u8 val; + + ret = fuel_gauge_reg_readb(info, AXP20X_CHRG_CTRL1); + if (ret < 0) + goto fg_prog_ocv_fail; + else + val = (ret & ~CHRG_CCCV_CV_MASK); + + switch (info->pdata->max_volt) { + case CV_4100: + val |= (CHRG_CCCV_CV_4100MV << CHRG_CCCV_CV_BIT_POS); + break; + case CV_4150: + val |= (CHRG_CCCV_CV_4150MV << CHRG_CCCV_CV_BIT_POS); + break; + case CV_4200: + val |= (CHRG_CCCV_CV_4200MV << CHRG_CCCV_CV_BIT_POS); + break; + case CV_4350: + val |= (CHRG_CCCV_CV_4350MV << CHRG_CCCV_CV_BIT_POS); + break; + default: + val |= (CHRG_CCCV_CV_4200MV << CHRG_CCCV_CV_BIT_POS); + break; + } + + ret = fuel_gauge_reg_writeb(info, AXP20X_CHRG_CTRL1, val); +fg_prog_ocv_fail: + return ret; +} + +static int fuel_gauge_program_design_cap(struct axp288_fg_info *info) +{ + int ret; + + ret = fuel_gauge_reg_writeb(info, + AXP288_FG_DES_CAP1_REG, info->pdata->cap1); + if (ret < 0) + goto fg_prog_descap_fail; + + ret = fuel_gauge_reg_writeb(info, + AXP288_FG_DES_CAP0_REG, info->pdata->cap0); + +fg_prog_descap_fail: + return ret; +} + +static int fuel_gauge_program_ocv_curve(struct axp288_fg_info *info) +{ + int ret = 0, i; + + for (i = 0; i < OCV_CURVE_SIZE; i++) { + ret = fuel_gauge_reg_writeb(info, + AXP288_FG_OCV_CURVE_REG + i, info->pdata->ocv_curve[i]); + if (ret < 0) + goto fg_prog_ocv_fail; + } + +fg_prog_ocv_fail: + return ret; +} + +static int fuel_gauge_program_rdc_vals(struct axp288_fg_info *info) +{ + int ret; + + ret = fuel_gauge_reg_writeb(info, + AXP288_FG_RDC1_REG, info->pdata->rdc1); + if (ret < 0) + goto fg_prog_ocv_fail; + + ret = fuel_gauge_reg_writeb(info, + AXP288_FG_RDC0_REG, info->pdata->rdc0); + +fg_prog_ocv_fail: + return ret; +} + +static void fuel_gauge_init_config_regs(struct axp288_fg_info *info) +{ + int ret; + + /* + * check if the config data is already + * programmed and if so just return. + */ + + ret = fuel_gauge_reg_readb(info, AXP288_FG_DES_CAP1_REG); + if (ret < 0) { + dev_warn(&info->pdev->dev, "CAP1 reg read err!!\n"); + } else if (!(ret & FG_DES_CAP1_VALID)) { + dev_info(&info->pdev->dev, "FG data needs to be initialized\n"); + } else { + dev_info(&info->pdev->dev, "FG data is already initialized\n"); + return; + } + + ret = fuel_gauge_program_vbatt_full(info); + if (ret < 0) + dev_err(&info->pdev->dev, "set vbatt full fail:%d\n", ret); + + ret = fuel_gauge_program_design_cap(info); + if (ret < 0) + dev_err(&info->pdev->dev, "set design cap fail:%d\n", ret); + + ret = fuel_gauge_program_rdc_vals(info); + if (ret < 0) + dev_err(&info->pdev->dev, "set rdc fail:%d\n", ret); + + ret = fuel_gauge_program_ocv_curve(info); + if (ret < 0) + dev_err(&info->pdev->dev, "set ocv curve fail:%d\n", ret); + + ret = fuel_gauge_set_lowbatt_thresholds(info); + if (ret < 0) + dev_err(&info->pdev->dev, "lowbatt thr set fail:%d\n", ret); + + ret = fuel_gauge_reg_writeb(info, AXP20X_CC_CTRL, 0xef); + if (ret < 0) + dev_err(&info->pdev->dev, "gauge cntl set fail:%d\n", ret); +} + +static void fuel_gauge_init_irq(struct axp288_fg_info *info) +{ + int ret, i, pirq; + + for (i = 0; i < AXP288_FG_INTR_NUM; i++) { + pirq = platform_get_irq(info->pdev, i); + info->irq[i] = regmap_irq_get_virq(info->regmap_irqc, pirq); + if (info->irq[i] < 0) { + dev_warn(&info->pdev->dev, + "regmap_irq get virq failed for IRQ %d: %d\n", + pirq, info->irq[i]); + info->irq[i] = -1; + goto intr_failed; + } + ret = request_threaded_irq(info->irq[i], + NULL, fuel_gauge_thread_handler, + IRQF_ONESHOT, DEV_NAME, info); + if (ret) { + dev_warn(&info->pdev->dev, + "request irq failed for IRQ %d: %d\n", + pirq, info->irq[i]); + info->irq[i] = -1; + goto intr_failed; + } else { + dev_info(&info->pdev->dev, "HW IRQ %d -> VIRQ %d\n", + pirq, info->irq[i]); + } + } + return; + +intr_failed: + for (; i > 0; i--) { + free_irq(info->irq[i - 1], info); + info->irq[i - 1] = -1; + } +} + +static void fuel_gauge_init_hw_regs(struct axp288_fg_info *info) +{ + int ret; + unsigned int val; + + ret = fuel_gauge_set_high_btemp_alert(info); + if (ret < 0) + dev_err(&info->pdev->dev, "high batt temp set fail:%d\n", ret); + + ret = fuel_gauge_set_low_btemp_alert(info); + if (ret < 0) + dev_err(&info->pdev->dev, "low batt temp set fail:%d\n", ret); + + /* enable interrupts */ + val = fuel_gauge_reg_readb(info, AXP20X_IRQ3_EN); + val |= TEMP_IRQ_CFG_MASK; + fuel_gauge_reg_writeb(info, AXP20X_IRQ3_EN, val); + + val = fuel_gauge_reg_readb(info, AXP20X_IRQ4_EN); + val |= FG_IRQ_CFG_LOWBATT_MASK; + val = fuel_gauge_reg_writeb(info, AXP20X_IRQ4_EN, val); +} + +static int axp288_fuel_gauge_probe(struct platform_device *pdev) +{ + int ret; + struct axp288_fg_info *info; + struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent); + + info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); + if (!info) + return -ENOMEM; + + info->pdev = pdev; + info->regmap = axp20x->regmap; + info->regmap_irqc = axp20x->regmap_irqc; + info->status = POWER_SUPPLY_STATUS_UNKNOWN; + info->pdata = pdev->dev.platform_data; + if (!info->pdata) + return -ENODEV; + + platform_set_drvdata(pdev, info); + + mutex_init(&info->lock); + INIT_DELAYED_WORK(&info->status_monitor, fuel_gauge_status_monitor); + + info->bat.name = DEV_NAME; + info->bat.type = POWER_SUPPLY_TYPE_BATTERY; + info->bat.properties = fuel_gauge_props; + info->bat.num_properties = ARRAY_SIZE(fuel_gauge_props); + info->bat.get_property = fuel_gauge_get_property; + info->bat.set_property = fuel_gauge_set_property; + info->bat.property_is_writeable = fuel_gauge_property_is_writeable; + info->bat.external_power_changed = fuel_gauge_external_power_changed; + ret = power_supply_register(&pdev->dev, &info->bat); + if (ret) { + dev_err(&pdev->dev, "failed to register battery: %d\n", ret); + return ret; + } + + fuel_gauge_create_debugfs(info); + fuel_gauge_init_config_regs(info); + fuel_gauge_init_irq(info); + fuel_gauge_init_hw_regs(info); + schedule_delayed_work(&info->status_monitor, STATUS_MON_DELAY_JIFFIES); + + return ret; +} + +static struct platform_device_id axp288_fg_id_table[] = { + { .name = DEV_NAME }, + {}, +}; + +static int axp288_fuel_gauge_remove(struct platform_device *pdev) +{ + struct axp288_fg_info *info = platform_get_drvdata(pdev); + int i; + + cancel_delayed_work_sync(&info->status_monitor); + power_supply_unregister(&info->bat); + fuel_gauge_remove_debugfs(info); + + for (i = 0; i < AXP288_FG_INTR_NUM; i++) + if (info->irq[i] >= 0) + free_irq(info->irq[i], info); + + return 0; +} + +static struct platform_driver axp288_fuel_gauge_driver = { + .probe = axp288_fuel_gauge_probe, + .remove = axp288_fuel_gauge_remove, + .id_table = axp288_fg_id_table, + .driver = { + .name = DEV_NAME, + }, +}; + +module_platform_driver(axp288_fuel_gauge_driver); + +MODULE_AUTHOR("Todd Brandt "); +MODULE_DESCRIPTION("Xpower AXP288 Fuel Gauge Driver"); +MODULE_LICENSE("GPL"); -- GitLab From 70dddeee8945a0e62525a278ae7b91778f82f765 Mon Sep 17 00:00:00 2001 From: Octavian Purdila Date: Mon, 2 Mar 2015 21:03:05 +0200 Subject: [PATCH 03366/11651] iio: fix drivers that check buffer->scan_mask If the in-kernel push interface is used we may have a different masks on the device buffer and the kernel buffer and in this case the device should generate data for the reunion of the buffers, which is available at indio_dev->active_scan_mask. Compiled tested only except for bmc150-accel which was tested at runtime with the hardware. Signed-off-by: Octavian Purdila Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/accel/bma180.c | 2 +- drivers/iio/accel/bmc150-accel.c | 2 +- drivers/iio/accel/kxcjk-1013.c | 2 +- drivers/iio/adc/at91_adc.c | 5 ++--- drivers/iio/adc/ti_am335x_adc.c | 3 +-- drivers/iio/gyro/bmg160.c | 2 +- drivers/iio/imu/kmx61.c | 2 +- drivers/iio/proximity/sx9500.c | 2 +- 8 files changed, 9 insertions(+), 11 deletions(-) diff --git a/drivers/iio/accel/bma180.c b/drivers/iio/accel/bma180.c index 1096da327130..75c6d2103e07 100644 --- a/drivers/iio/accel/bma180.c +++ b/drivers/iio/accel/bma180.c @@ -659,7 +659,7 @@ static irqreturn_t bma180_trigger_handler(int irq, void *p) mutex_lock(&data->mutex); - for_each_set_bit(bit, indio_dev->buffer->scan_mask, + for_each_set_bit(bit, indio_dev->active_scan_mask, indio_dev->masklength) { ret = bma180_get_data_reg(data, bit); if (ret < 0) { diff --git a/drivers/iio/accel/bmc150-accel.c b/drivers/iio/accel/bmc150-accel.c index 066d0c04072c..7d1383de3e85 100644 --- a/drivers/iio/accel/bmc150-accel.c +++ b/drivers/iio/accel/bmc150-accel.c @@ -986,7 +986,7 @@ static irqreturn_t bmc150_accel_trigger_handler(int irq, void *p) int bit, ret, i = 0; mutex_lock(&data->mutex); - for_each_set_bit(bit, indio_dev->buffer->scan_mask, + for_each_set_bit(bit, indio_dev->active_scan_mask, indio_dev->masklength) { ret = i2c_smbus_read_word_data(data->client, BMC150_ACCEL_AXIS_TO_REG(bit)); diff --git a/drivers/iio/accel/kxcjk-1013.c b/drivers/iio/accel/kxcjk-1013.c index 567de269cc00..1a6379525fa4 100644 --- a/drivers/iio/accel/kxcjk-1013.c +++ b/drivers/iio/accel/kxcjk-1013.c @@ -956,7 +956,7 @@ static irqreturn_t kxcjk1013_trigger_handler(int irq, void *p) mutex_lock(&data->mutex); - for_each_set_bit(bit, indio_dev->buffer->scan_mask, + for_each_set_bit(bit, indio_dev->active_scan_mask, indio_dev->masklength) { ret = kxcjk1013_get_acc_reg(data, bit); if (ret < 0) { diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c index ff61ae55dd3f..8a0eb4a04fb5 100644 --- a/drivers/iio/adc/at91_adc.c +++ b/drivers/iio/adc/at91_adc.c @@ -544,7 +544,6 @@ static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state) { struct iio_dev *idev = iio_trigger_get_drvdata(trig); struct at91_adc_state *st = iio_priv(idev); - struct iio_buffer *buffer = idev->buffer; struct at91_adc_reg_desc *reg = st->registers; u32 status = at91_adc_readl(st, reg->trigger_register); int value; @@ -564,7 +563,7 @@ static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state) at91_adc_writel(st, reg->trigger_register, status | value); - for_each_set_bit(bit, buffer->scan_mask, + for_each_set_bit(bit, idev->active_scan_mask, st->num_channels) { struct iio_chan_spec const *chan = idev->channels + bit; at91_adc_writel(st, AT91_ADC_CHER, @@ -579,7 +578,7 @@ static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state) at91_adc_writel(st, reg->trigger_register, status & ~value); - for_each_set_bit(bit, buffer->scan_mask, + for_each_set_bit(bit, idev->active_scan_mask, st->num_channels) { struct iio_chan_spec const *chan = idev->channels + bit; at91_adc_writel(st, AT91_ADC_CHDR, diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c index 2e5cc4409f78..a0e7161f040c 100644 --- a/drivers/iio/adc/ti_am335x_adc.c +++ b/drivers/iio/adc/ti_am335x_adc.c @@ -188,12 +188,11 @@ static int tiadc_buffer_preenable(struct iio_dev *indio_dev) static int tiadc_buffer_postenable(struct iio_dev *indio_dev) { struct tiadc_device *adc_dev = iio_priv(indio_dev); - struct iio_buffer *buffer = indio_dev->buffer; unsigned int enb = 0; u8 bit; tiadc_step_config(indio_dev); - for_each_set_bit(bit, buffer->scan_mask, adc_dev->channels) + for_each_set_bit(bit, indio_dev->active_scan_mask, adc_dev->channels) enb |= (get_adc_step_bit(adc_dev, bit) << 1); adc_dev->buffer_en_ch_steps = enb; diff --git a/drivers/iio/gyro/bmg160.c b/drivers/iio/gyro/bmg160.c index 60451b328242..ccf3ea7e1afa 100644 --- a/drivers/iio/gyro/bmg160.c +++ b/drivers/iio/gyro/bmg160.c @@ -822,7 +822,7 @@ static irqreturn_t bmg160_trigger_handler(int irq, void *p) int bit, ret, i = 0; mutex_lock(&data->mutex); - for_each_set_bit(bit, indio_dev->buffer->scan_mask, + for_each_set_bit(bit, indio_dev->active_scan_mask, indio_dev->masklength) { ret = i2c_smbus_read_word_data(data->client, BMG160_AXIS_TO_REG(bit)); diff --git a/drivers/iio/imu/kmx61.c b/drivers/iio/imu/kmx61.c index 5cc3692acf37..b3a36376c719 100644 --- a/drivers/iio/imu/kmx61.c +++ b/drivers/iio/imu/kmx61.c @@ -1227,7 +1227,7 @@ static irqreturn_t kmx61_trigger_handler(int irq, void *p) base = KMX61_MAG_XOUT_L; mutex_lock(&data->lock); - for_each_set_bit(bit, indio_dev->buffer->scan_mask, + for_each_set_bit(bit, indio_dev->active_scan_mask, indio_dev->masklength) { ret = kmx61_read_measurement(data, base, bit); if (ret < 0) { diff --git a/drivers/iio/proximity/sx9500.c b/drivers/iio/proximity/sx9500.c index 74dff4e4a11a..89fca3a70750 100644 --- a/drivers/iio/proximity/sx9500.c +++ b/drivers/iio/proximity/sx9500.c @@ -494,7 +494,7 @@ static irqreturn_t sx9500_trigger_handler(int irq, void *private) mutex_lock(&data->mutex); - for_each_set_bit(bit, indio_dev->buffer->scan_mask, + for_each_set_bit(bit, indio_dev->active_scan_mask, indio_dev->masklength) { ret = sx9500_read_proximity(data, &indio_dev->channels[bit], &val); -- GitLab From 1672d933af196f69a69af8f1fe616750f7089592 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Wed, 4 Mar 2015 12:44:33 +0900 Subject: [PATCH 03367/11651] iio:adc: Fix typo in MODULE_DESCRIPTION in ad7793.c This patch fix spelling typo in MODULE_DESCRIPTION Signed-off-by: Masanari Iida Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ad7793.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/adc/ad7793.c b/drivers/iio/adc/ad7793.c index 4dddeabdfbb0..b84922a4b32e 100644 --- a/drivers/iio/adc/ad7793.c +++ b/drivers/iio/adc/ad7793.c @@ -861,5 +861,5 @@ static struct spi_driver ad7793_driver = { module_spi_driver(ad7793_driver); MODULE_AUTHOR("Michael Hennerich "); -MODULE_DESCRIPTION("Analog Devices AD7793 and simialr ADCs"); +MODULE_DESCRIPTION("Analog Devices AD7793 and similar ADCs"); MODULE_LICENSE("GPL v2"); -- GitLab From c5abbba932a4afd82cb35f3d6e691a2b4a0613be Mon Sep 17 00:00:00 2001 From: Tien Hock Loh Date: Tue, 24 Feb 2015 01:53:03 -0800 Subject: [PATCH 03368/11651] drivers/gpio: Altera soft IP GPIO driver Adds a new driver for Altera soft GPIO IP. The driver is able to do read/write and allows GPIO to be a interrupt controller. Tested on Altera GHRD on interrupt handling and IO. v10: - Updated conflicting device tree parameters - Removed unused headers - Used macro instead of magic numbers for ngpio - Code readability cleanup using ?: and temporal variables - Removed leftover garbage and unnecessary function calls - Checked bgpio_init but unusable because Altera GPIO may not be a multiple of 8 bits v9: - Removed duplicated initialization on set_type using temporals to improve code readability in calling generic_handle_irq - Using ?: ternary to reduce code size v8: - Using for_each_set_bit - Added const for struct definition - Removed naggy pr_err - Sort alpha header - Remove unused macros - Use fixed width data types instead of unsigned long - Whitespace issue fixes - Removed _relaxed function for better compatibility across different CPU - Changed irq_create_mapping to platform_get_irq updated implementation to use gpiochip_irqchip_add - Reserve interrupt-cells number 2 in device tree binding for future use - Remove confusing sections on devicetree bindings - Added tristate Kconfig help text v7: - Used dev_warn instead of pr_warn - Clean up unnecesarry if else indentation v6: - Added irq_startup and irq_shutdown - Changed bitwise clamping style - Cleanup bitwise operation to improve readability change naming of mapped irqs from virq to mapped_irq v5: - Dispose irq_domain mapping correctly - Update optional binding description in binding docs v4: - Added vendor prefix to devicetree binding for IP specific properties using MMIO GPIO helper library instead of manually map PIO to memory - altera_gpio_chip inline struct documentation to kerneldoc - Using dev_ print to print a better failure message v2, v3: - Do not reference NO_IRQ - Updated irq_set_type to only allow the hardware configured irq type Signed-off-by: Tien Hock Loh Signed-off-by: Linus Walleij --- MAINTAINERS | 6 + drivers/gpio/Kconfig | 10 + drivers/gpio/Makefile | 1 + drivers/gpio/gpio-altera.c | 374 +++++++++++++++++++++++++++++++++++++ 4 files changed, 391 insertions(+) create mode 100644 drivers/gpio/gpio-altera.c diff --git a/MAINTAINERS b/MAINTAINERS index ddc5a8cf9a8a..38fdfd134750 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -569,6 +569,12 @@ L: nios2-dev@lists.rocketboards.org (moderated for non-subscribers) S: Maintained F: drivers/mailbox/mailbox-altera.c +ALTERA PIO DRIVER +M: Tien Hock Loh +L: linux-gpio@vger.kernel.org +S: Maintained +F: drivers/gpio/gpio-altera.c + ALTERA TRIPLE SPEED ETHERNET DRIVER M: Vince Bridgers L: netdev@vger.kernel.org diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 249845a47624..e07b63d37b7b 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -156,6 +156,16 @@ config GPIO_DWAPB Say Y or M here to build support for the Synopsys DesignWare APB GPIO block. +config GPIO_ALTERA + tristate "Altera GPIO" + depends on OF_GPIO + select GPIO_GENERIC + select GPIOLIB_IRQCHIP + help + Say Y or M here to build support for the Altera PIO device. + + If driver is built as a module it will be called gpio-altera. + config GPIO_IT8761E tristate "IT8761E GPIO support" depends on X86 # unconditional access to IO space. diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index bdda6a94d2cd..a452b14130cc 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -17,6 +17,7 @@ obj-$(CONFIG_GPIO_74XX_MMIO) += gpio-74xx-mmio.o obj-$(CONFIG_GPIO_ADNP) += gpio-adnp.o obj-$(CONFIG_GPIO_ADP5520) += gpio-adp5520.o obj-$(CONFIG_GPIO_ADP5588) += gpio-adp5588.o +obj-$(CONFIG_GPIO_ALTERA) += gpio-altera.o obj-$(CONFIG_GPIO_AMD8111) += gpio-amd8111.o obj-$(CONFIG_GPIO_ARIZONA) += gpio-arizona.o obj-$(CONFIG_GPIO_BCM_KONA) += gpio-bcm-kona.o diff --git a/drivers/gpio/gpio-altera.c b/drivers/gpio/gpio-altera.c new file mode 100644 index 000000000000..4d41196b3f13 --- /dev/null +++ b/drivers/gpio/gpio-altera.c @@ -0,0 +1,374 @@ +/* + * Copyright (C) 2013 Altera Corporation + * Based on gpio-mpc8xxx.c + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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, see . + */ + +#include +#include +#include + +#define ALTERA_GPIO_MAX_NGPIO 32 +#define ALTERA_GPIO_DATA 0x0 +#define ALTERA_GPIO_DIR 0x4 +#define ALTERA_GPIO_IRQ_MASK 0x8 +#define ALTERA_GPIO_EDGE_CAP 0xc + +/** +* struct altera_gpio_chip +* @mmchip : memory mapped chip structure. +* @gpio_lock : synchronization lock so that new irq/set/get requests + will be blocked until the current one completes. +* @interrupt_trigger : specifies the hardware configured IRQ trigger type + (rising, falling, both, high) +* @mapped_irq : kernel mapped irq number. +*/ +struct altera_gpio_chip { + struct of_mm_gpio_chip mmchip; + spinlock_t gpio_lock; + int interrupt_trigger; + int mapped_irq; +}; + +static void altera_gpio_irq_unmask(struct irq_data *d) +{ + struct altera_gpio_chip *altera_gc; + struct of_mm_gpio_chip *mm_gc; + unsigned long flags; + u32 intmask; + + altera_gc = irq_data_get_irq_chip_data(d); + mm_gc = &altera_gc->mmchip; + + spin_lock_irqsave(&altera_gc->gpio_lock, flags); + intmask = readl(mm_gc->regs + ALTERA_GPIO_IRQ_MASK); + /* Set ALTERA_GPIO_IRQ_MASK bit to unmask */ + intmask |= BIT(irqd_to_hwirq(d)); + writel(intmask, mm_gc->regs + ALTERA_GPIO_IRQ_MASK); + spin_unlock_irqrestore(&altera_gc->gpio_lock, flags); +} + +static void altera_gpio_irq_mask(struct irq_data *d) +{ + struct altera_gpio_chip *altera_gc; + struct of_mm_gpio_chip *mm_gc; + unsigned long flags; + u32 intmask; + + altera_gc = irq_data_get_irq_chip_data(d); + mm_gc = &altera_gc->mmchip; + + spin_lock_irqsave(&altera_gc->gpio_lock, flags); + intmask = readl(mm_gc->regs + ALTERA_GPIO_IRQ_MASK); + /* Clear ALTERA_GPIO_IRQ_MASK bit to mask */ + intmask &= ~BIT(irqd_to_hwirq(d)); + writel(intmask, mm_gc->regs + ALTERA_GPIO_IRQ_MASK); + spin_unlock_irqrestore(&altera_gc->gpio_lock, flags); +} + +/** + * This controller's IRQ type is synthesized in hardware, so this function + * just checks if the requested set_type matches the synthesized IRQ type + */ +static int altera_gpio_irq_set_type(struct irq_data *d, + unsigned int type) +{ + struct altera_gpio_chip *altera_gc; + + altera_gc = irq_data_get_irq_chip_data(d); + + if (type == IRQ_TYPE_NONE) + return 0; + if (type == IRQ_TYPE_LEVEL_HIGH && + altera_gc->interrupt_trigger == IRQ_TYPE_LEVEL_HIGH) + return 0; + if (type == IRQ_TYPE_EDGE_RISING && + altera_gc->interrupt_trigger == IRQ_TYPE_EDGE_RISING) + return 0; + if (type == IRQ_TYPE_EDGE_FALLING && + altera_gc->interrupt_trigger == IRQ_TYPE_EDGE_FALLING) + return 0; + if (type == IRQ_TYPE_EDGE_BOTH && + altera_gc->interrupt_trigger == IRQ_TYPE_EDGE_BOTH) + return 0; + + return -EINVAL; +} + +static unsigned int altera_gpio_irq_startup(struct irq_data *d) { + altera_gpio_irq_unmask(d); + + return 0; +} + +static struct irq_chip altera_irq_chip = { + .name = "altera-gpio", + .irq_mask = altera_gpio_irq_mask, + .irq_unmask = altera_gpio_irq_unmask, + .irq_set_type = altera_gpio_irq_set_type, + .irq_startup = altera_gpio_irq_startup, + .irq_shutdown = altera_gpio_irq_mask, +}; + +static int altera_gpio_get(struct gpio_chip *gc, unsigned offset) +{ + struct of_mm_gpio_chip *mm_gc; + + mm_gc = to_of_mm_gpio_chip(gc); + + return !!(readl(mm_gc->regs + ALTERA_GPIO_DATA) & BIT(offset)); +} + +static void altera_gpio_set(struct gpio_chip *gc, unsigned offset, int value) +{ + struct of_mm_gpio_chip *mm_gc; + struct altera_gpio_chip *chip; + unsigned long flags; + unsigned int data_reg; + + mm_gc = to_of_mm_gpio_chip(gc); + chip = container_of(mm_gc, struct altera_gpio_chip, mmchip); + + spin_lock_irqsave(&chip->gpio_lock, flags); + data_reg = readl(mm_gc->regs + ALTERA_GPIO_DATA); + if (value) + data_reg |= BIT(offset); + else + data_reg &= ~BIT(offset); + writel(data_reg, mm_gc->regs + ALTERA_GPIO_DATA); + spin_unlock_irqrestore(&chip->gpio_lock, flags); +} + +static int altera_gpio_direction_input(struct gpio_chip *gc, unsigned offset) +{ + struct of_mm_gpio_chip *mm_gc; + struct altera_gpio_chip *chip; + unsigned long flags; + unsigned int gpio_ddr; + + mm_gc = to_of_mm_gpio_chip(gc); + chip = container_of(mm_gc, struct altera_gpio_chip, mmchip); + + spin_lock_irqsave(&chip->gpio_lock, flags); + /* Set pin as input, assumes software controlled IP */ + gpio_ddr = readl(mm_gc->regs + ALTERA_GPIO_DIR); + gpio_ddr &= ~BIT(offset); + writel(gpio_ddr, mm_gc->regs + ALTERA_GPIO_DIR); + spin_unlock_irqrestore(&chip->gpio_lock, flags); + + return 0; +} + +static int altera_gpio_direction_output(struct gpio_chip *gc, + unsigned offset, int value) +{ + struct of_mm_gpio_chip *mm_gc; + struct altera_gpio_chip *chip; + unsigned long flags; + unsigned int data_reg, gpio_ddr; + + mm_gc = to_of_mm_gpio_chip(gc); + chip = container_of(mm_gc, struct altera_gpio_chip, mmchip); + + spin_lock_irqsave(&chip->gpio_lock, flags); + /* Sets the GPIO value */ + data_reg = readl(mm_gc->regs + ALTERA_GPIO_DATA); + if (value) + data_reg |= BIT(offset); + else + data_reg &= ~BIT(offset); + writel(data_reg, mm_gc->regs + ALTERA_GPIO_DATA); + + /* Set pin as output, assumes software controlled IP */ + gpio_ddr = readl(mm_gc->regs + ALTERA_GPIO_DIR); + gpio_ddr |= BIT(offset); + writel(gpio_ddr, mm_gc->regs + ALTERA_GPIO_DIR); + spin_unlock_irqrestore(&chip->gpio_lock, flags); + + return 0; +} + +static void altera_gpio_irq_edge_handler(unsigned int irq, + struct irq_desc *desc) +{ + struct altera_gpio_chip *altera_gc; + struct irq_chip *chip; + struct of_mm_gpio_chip *mm_gc; + struct irq_domain *irqdomain; + unsigned long status; + int i; + + altera_gc = irq_desc_get_handler_data(desc); + chip = irq_desc_get_chip(desc); + mm_gc = &altera_gc->mmchip; + irqdomain = altera_gc->mmchip.gc.irqdomain; + + chained_irq_enter(chip, desc); + + while ((status = + (readl(mm_gc->regs + ALTERA_GPIO_EDGE_CAP) & + readl(mm_gc->regs + ALTERA_GPIO_IRQ_MASK)))) { + writel(status, mm_gc->regs + ALTERA_GPIO_EDGE_CAP); + for_each_set_bit(i, &status, mm_gc->gc.ngpio) { + generic_handle_irq(irq_find_mapping(irqdomain, i)); + } + } + + chained_irq_exit(chip, desc); +} + + +static void altera_gpio_irq_leveL_high_handler(unsigned int irq, + struct irq_desc *desc) +{ + struct altera_gpio_chip *altera_gc; + struct irq_chip *chip; + struct of_mm_gpio_chip *mm_gc; + struct irq_domain *irqdomain; + unsigned long status; + int i; + + altera_gc = irq_desc_get_handler_data(desc); + chip = irq_desc_get_chip(desc); + mm_gc = &altera_gc->mmchip; + irqdomain = altera_gc->mmchip.gc.irqdomain; + + chained_irq_enter(chip, desc); + + status = readl(mm_gc->regs + ALTERA_GPIO_DATA); + status &= readl(mm_gc->regs + ALTERA_GPIO_IRQ_MASK); + + for_each_set_bit(i, &status, mm_gc->gc.ngpio) { + generic_handle_irq(irq_find_mapping(irqdomain, i)); + } + chained_irq_exit(chip, desc); +} + +int altera_gpio_probe(struct platform_device *pdev) +{ + struct device_node *node = pdev->dev.of_node; + int reg, ret; + struct altera_gpio_chip *altera_gc; + + altera_gc = devm_kzalloc(&pdev->dev, sizeof(*altera_gc), GFP_KERNEL); + if (!altera_gc) + return -ENOMEM; + + spin_lock_init(&altera_gc->gpio_lock); + + if (of_property_read_u32(node, "altr,ngpio", ®)) + /* By default assume maximum ngpio */ + altera_gc->mmchip.gc.ngpio = ALTERA_GPIO_MAX_NGPIO; + else + altera_gc->mmchip.gc.ngpio = reg; + + if (altera_gc->mmchip.gc.ngpio > ALTERA_GPIO_MAX_NGPIO) { + dev_warn(&pdev->dev, + "ngpio is greater than %d, defaulting to %d\n", + ALTERA_GPIO_MAX_NGPIO, ALTERA_GPIO_MAX_NGPIO); + altera_gc->mmchip.gc.ngpio = ALTERA_GPIO_MAX_NGPIO; + } + + altera_gc->mmchip.gc.direction_input = altera_gpio_direction_input; + altera_gc->mmchip.gc.direction_output = altera_gpio_direction_output; + altera_gc->mmchip.gc.get = altera_gpio_get; + altera_gc->mmchip.gc.set = altera_gpio_set; + altera_gc->mmchip.gc.owner = THIS_MODULE; + altera_gc->mmchip.gc.dev = &pdev->dev; + + ret = of_mm_gpiochip_add(node, &altera_gc->mmchip); + if (ret) { + dev_err(&pdev->dev, "Failed adding memory mapped gpiochip\n"); + return ret; + } + + platform_set_drvdata(pdev, altera_gc); + + altera_gc->mapped_irq = platform_get_irq(pdev, 0); + + if (altera_gc->mapped_irq < 0) + goto skip_irq; + + if (of_property_read_u32(node, "altr,interrupt-type", ®)) { + ret = -EINVAL; + dev_err(&pdev->dev, + "altr,interrupt-type value not set in device tree\n"); + goto teardown; + } + altera_gc->interrupt_trigger = reg; + + ret = gpiochip_irqchip_add(&altera_gc->mmchip.gc, &altera_irq_chip, 0, + handle_simple_irq, IRQ_TYPE_NONE); + + if (ret) { + dev_info(&pdev->dev, "could not add irqchip\n"); + return ret; + } + + gpiochip_set_chained_irqchip(&altera_gc->mmchip.gc, + &altera_irq_chip, + altera_gc->mapped_irq, + altera_gc->interrupt_trigger == IRQ_TYPE_LEVEL_HIGH ? + altera_gpio_irq_leveL_high_handler : + altera_gpio_irq_edge_handler); + +skip_irq: + return 0; +teardown: + pr_err("%s: registration failed with status %d\n", + node->full_name, ret); + + return ret; +} + +static int altera_gpio_remove(struct platform_device *pdev) +{ + struct altera_gpio_chip *altera_gc = platform_get_drvdata(pdev); + + gpiochip_remove(&altera_gc->mmchip.gc); + + return -EIO; +} + +static const struct of_device_id altera_gpio_of_match[] = { + { .compatible = "altr,pio-1.0", }, + {}, +}; +MODULE_DEVICE_TABLE(of, altera_gpio_of_match); + +static struct platform_driver altera_gpio_driver = { + .driver = { + .name = "altera_gpio", + .of_match_table = of_match_ptr(altera_gpio_of_match), + }, + .probe = altera_gpio_probe, + .remove = altera_gpio_remove, +}; + +static int __init altera_gpio_init(void) +{ + return platform_driver_register(&altera_gpio_driver); +} +subsys_initcall(altera_gpio_init); + +static void __exit altera_gpio_exit(void) +{ + platform_driver_unregister(&altera_gpio_driver); +} +module_exit(altera_gpio_exit); + +MODULE_AUTHOR("Tien Hock Loh "); +MODULE_DESCRIPTION("Altera GPIO driver"); +MODULE_LICENSE("GPL"); -- GitLab From 02232be7a2bf6e2dd5e4a6c3a81470a09ecc7fdd Mon Sep 17 00:00:00 2001 From: Valentin Rothberg Date: Mon, 16 Feb 2015 17:32:48 +0100 Subject: [PATCH 03369/11651] ab8500_fg.c: only request threaded IRQs when necessary All 5 IRQ handlers of the driver are requested as threaded interrupt handlers. However, only 1 handler can block. The remaining 4 handlers defer the actual handling to a workqueue. Hence, 4 of 5 IRQ handlers have a considerable overhead, since they are executed in a kernel thread to schedule another kernel thread (workqueue). This change splits up the 5 interrupt handlers into top halves (_th) and bottom halves (_bh) and resolves the aforementioned overhead by only requesting threaded interrupts (i.e., bottom halves) when necessary. Signed-off-by: Valentin Rothberg Signed-off-by: Sebastian Reichel --- drivers/power/ab8500_fg.c | 46 ++++++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/drivers/power/ab8500_fg.c b/drivers/power/ab8500_fg.c index 40344e01df80..d30387bc4c21 100644 --- a/drivers/power/ab8500_fg.c +++ b/drivers/power/ab8500_fg.c @@ -3055,11 +3055,14 @@ static int ab8500_fg_remove(struct platform_device *pdev) } /* ab8500 fg driver interrupts and their respective isr */ -static struct ab8500_fg_interrupts ab8500_fg_irq[] = { +static struct ab8500_fg_interrupts ab8500_fg_irq_th[] = { {"NCONV_ACCU", ab8500_fg_cc_convend_handler}, {"BATT_OVV", ab8500_fg_batt_ovv_handler}, {"LOW_BAT_F", ab8500_fg_lowbatf_handler}, {"CC_INT_CALIB", ab8500_fg_cc_int_calib_handler}, +}; + +static struct ab8500_fg_interrupts ab8500_fg_irq_bh[] = { {"CCEOC", ab8500_fg_cc_data_end_handler}, }; @@ -3187,21 +3190,36 @@ static int ab8500_fg_probe(struct platform_device *pdev) init_completion(&di->ab8500_fg_started); init_completion(&di->ab8500_fg_complete); - /* Register interrupts */ - for (i = 0; i < ARRAY_SIZE(ab8500_fg_irq); i++) { - irq = platform_get_irq_byname(pdev, ab8500_fg_irq[i].name); - ret = request_threaded_irq(irq, NULL, ab8500_fg_irq[i].isr, - IRQF_SHARED | IRQF_NO_SUSPEND, - ab8500_fg_irq[i].name, di); + /* Register primary interrupt handlers */ + for (i = 0; i < ARRAY_SIZE(ab8500_fg_irq_th); i++) { + irq = platform_get_irq_byname(pdev, ab8500_fg_irq_th[i].name); + ret = request_irq(irq, ab8500_fg_irq_th[i].isr, + IRQF_SHARED | IRQF_NO_SUSPEND, + ab8500_fg_irq_th[i].name, di); if (ret != 0) { - dev_err(di->dev, "failed to request %s IRQ %d: %d\n" - , ab8500_fg_irq[i].name, irq, ret); + dev_err(di->dev, "failed to request %s IRQ %d: %d\n", + ab8500_fg_irq_th[i].name, irq, ret); goto free_irq; } dev_dbg(di->dev, "Requested %s IRQ %d: %d\n", - ab8500_fg_irq[i].name, irq, ret); + ab8500_fg_irq_th[i].name, irq, ret); } + + /* Register threaded interrupt handler */ + irq = platform_get_irq_byname(pdev, ab8500_fg_irq_bh[0].name); + ret = request_threaded_irq(irq, NULL, ab8500_fg_irq_bh[0].isr, + IRQF_SHARED | IRQF_NO_SUSPEND | IRQF_ONESHOT, + ab8500_fg_irq_bh[0].name, di); + + if (ret != 0) { + dev_err(di->dev, "failed to request %s IRQ %d: %d\n", + ab8500_fg_irq_bh[0].name, irq, ret); + goto free_irq; + } + dev_dbg(di->dev, "Requested %s IRQ %d: %d\n", + ab8500_fg_irq_bh[0].name, irq, ret); + di->irq = platform_get_irq_byname(pdev, "CCEOC"); disable_irq(di->irq); di->nbr_cceoc_irq_cnt = 0; @@ -3238,11 +3256,13 @@ static int ab8500_fg_probe(struct platform_device *pdev) free_irq: power_supply_unregister(&di->fg_psy); - /* We also have to free all successfully registered irqs */ - for (i = i - 1; i >= 0; i--) { - irq = platform_get_irq_byname(pdev, ab8500_fg_irq[i].name); + /* We also have to free all registered irqs */ + for (i = 0; i < ARRAY_SIZE(ab8500_fg_irq_th); i++) { + irq = platform_get_irq_byname(pdev, ab8500_fg_irq_th[i].name); free_irq(irq, di); } + irq = platform_get_irq_byname(pdev, ab8500_fg_irq_bh[0].name); + free_irq(irq, di); free_inst_curr_wq: destroy_workqueue(di->fg_wq); return ret; -- GitLab From 4fd9bbc6e0713a0106a7771b639a963f4b2411c6 Mon Sep 17 00:00:00 2001 From: Tien Hock Loh Date: Tue, 24 Feb 2015 01:53:02 -0800 Subject: [PATCH 03370/11651] drivers/gpio: Altera soft IP GPIO driver device tree binding Adds a new driver device tree binding for Altera soft GPIO IP Signed-off-by: Tien Hock Loh Signed-off-by: Linus Walleij --- .../devicetree/bindings/gpio/gpio-altera.txt | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 Documentation/devicetree/bindings/gpio/gpio-altera.txt diff --git a/Documentation/devicetree/bindings/gpio/gpio-altera.txt b/Documentation/devicetree/bindings/gpio/gpio-altera.txt new file mode 100644 index 000000000000..12f50149e1ed --- /dev/null +++ b/Documentation/devicetree/bindings/gpio/gpio-altera.txt @@ -0,0 +1,43 @@ +Altera GPIO controller bindings + +Required properties: +- compatible: + - "altr,pio-1.0" +- reg: Physical base address and length of the controller's registers. +- #gpio-cells : Should be 2 + - The first cell is the gpio offset number. + - The second cell is reserved and is currently unused. +- gpio-controller : Marks the device node as a GPIO controller. +- interrupt-controller: Mark the device node as an interrupt controller +- #interrupt-cells : Should be 1. The interrupt type is fixed in the hardware. + - The first cell is the GPIO offset number within the GPIO controller. +- interrupts: Specify the interrupt. +- altr,interrupt-trigger: Specifies the interrupt trigger type the GPIO + hardware is synthesized. This field is required if the Altera GPIO controller + used has IRQ enabled as the interrupt type is not software controlled, + but hardware synthesized. Required if GPIO is used as an interrupt + controller. The value is defined in + Only the following flags are supported: + IRQ_TYPE_EDGE_RISING + IRQ_TYPE_EDGE_FALLING + IRQ_TYPE_EDGE_BOTH + IRQ_TYPE_LEVEL_HIGH + +Optional properties: +- altr,ngpio: Width of the GPIO bank. This defines how many pins the + GPIO device has. Ranges between 1-32. Optional and defaults to 32 if not + specified. + +Example: + +gpio_altr: gpio@0xff200000 { + compatible = "altr,pio-1.0"; + reg = <0xff200000 0x10>; + interrupts = <0 45 4>; + altr,ngpio = <32>; + altr,interrupt-trigger = ; + #gpio-cells = <2>; + gpio-controller; + #interrupt-cells = <1>; + interrupt-controller; +}; -- GitLab From 0402d9f233ac5d66b39452037fef88333b06d51c Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sat, 7 Mar 2015 20:52:28 +0100 Subject: [PATCH 03371/11651] Bluetooth: fix sco_exit compile warning While compiling the following warning occurs: WARNING: net/built-in.o(.init.text+0x602c): Section mismatch in reference from the function bt_init() to the function .exit.text:sco_exit() The function __init bt_init() references a function __exit sco_exit(). This is often seen when error handling in the init function uses functionality in the exit path. The fix is often to remove the __exit annotation of sco_exit() so it may be used outside an exit section. Since commit 6d785aa345f525e1fdf098b7c590168f0b00f3f1 ("Bluetooth: Convert mgmt to use HCI chan registration API") the function "sco_exit" is used inside of function "bt_init". The suggested solution by remove the __exit annotation solved this issue. Signed-off-by: Alexander Aring Signed-off-by: Johan Hedberg --- net/bluetooth/sco.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 54279ac28120..4322c833e748 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -1231,7 +1231,7 @@ error: return err; } -void __exit sco_exit(void) +void sco_exit(void) { bt_procfs_cleanup(&init_net, "sco"); -- GitLab From 3e9845251926723319fb60c9e546fe42d3d11687 Mon Sep 17 00:00:00 2001 From: Mathias Gottschlag Date: Sat, 7 Mar 2015 13:26:31 -0800 Subject: [PATCH 03372/11651] Input: psmouse - remove hardcoded touchpad size from the focaltech driver The size has in most cases already been fetched from the touchpad, the hardcoded values should have been removed. Signed-off-by: Mathias Gottschlag Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/focaltech.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/input/mouse/focaltech.c b/drivers/input/mouse/focaltech.c index 757f78a94aec..e8fafe8785a7 100644 --- a/drivers/input/mouse/focaltech.c +++ b/drivers/input/mouse/focaltech.c @@ -67,9 +67,6 @@ static void focaltech_reset(struct psmouse *psmouse) #define FOC_MAX_FINGERS 5 -#define FOC_MAX_X 2431 -#define FOC_MAX_Y 1663 - /* * Current state of a single finger on the touchpad. */ @@ -131,7 +128,7 @@ static void focaltech_report_state(struct psmouse *psmouse) if (active) { input_report_abs(dev, ABS_MT_POSITION_X, finger->x); input_report_abs(dev, ABS_MT_POSITION_Y, - FOC_MAX_Y - finger->y); + priv->y_max - finger->y); } } input_mt_report_pointer_emulation(dev, true); -- GitLab From 679d83ea9390636ded518f533af0cefbade317c7 Mon Sep 17 00:00:00 2001 From: Mathias Gottschlag Date: Sat, 7 Mar 2015 13:27:08 -0800 Subject: [PATCH 03373/11651] Input: psmouse - ensure that focaltech reports consistent coordinates We don't know whether x_max or y_max really hold the maximum possible coordinates, and we don't know for sure whether we correctly interpret the coordinates sent by the touchpad, so we clamp the reported values to prevent confusion in userspace code. Signed-off-by: Mathias Gottschlag Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/focaltech.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/input/mouse/focaltech.c b/drivers/input/mouse/focaltech.c index e8fafe8785a7..c66e0e04bb7e 100644 --- a/drivers/input/mouse/focaltech.c +++ b/drivers/input/mouse/focaltech.c @@ -126,9 +126,17 @@ static void focaltech_report_state(struct psmouse *psmouse) input_mt_slot(dev, i); input_mt_report_slot_state(dev, MT_TOOL_FINGER, active); if (active) { - input_report_abs(dev, ABS_MT_POSITION_X, finger->x); + unsigned int clamped_x, clamped_y; + /* + * The touchpad might report invalid data, so we clamp + * the resulting values so that we do not confuse + * userspace. + */ + clamped_x = clamp(finger->x, 0U, priv->x_max); + clamped_y = clamp(finger->y, 0U, priv->y_max); + input_report_abs(dev, ABS_MT_POSITION_X, clamped_x); input_report_abs(dev, ABS_MT_POSITION_Y, - priv->y_max - finger->y); + priv->y_max - clamped_y); } } input_mt_report_pointer_emulation(dev, true); -- GitLab From 4ec212f003d2430b0b2748b8a3008255f39cfe13 Mon Sep 17 00:00:00 2001 From: Mathias Gottschlag Date: Sat, 7 Mar 2015 13:32:10 -0800 Subject: [PATCH 03374/11651] Input: psmouse - disable changing resolution/rate/scale for FocalTech These PS/2 commands make some touchpads stop responding, so this commit adds some dummy functions to replace the generic implementation. Because scale changes were not encapsulated in a method of struct psmouse yet, this commit adds a method set_scale to psmouse. Signed-off-by: Mathias Gottschlag Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/focaltech.c | 25 +++++++++++++++++++++++++ drivers/input/mouse/psmouse-base.c | 14 +++++++++++++- drivers/input/mouse/psmouse.h | 6 ++++++ 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/drivers/input/mouse/focaltech.c b/drivers/input/mouse/focaltech.c index c66e0e04bb7e..891a2716d6a0 100644 --- a/drivers/input/mouse/focaltech.c +++ b/drivers/input/mouse/focaltech.c @@ -386,6 +386,23 @@ static int focaltech_read_size(struct psmouse *psmouse) return 0; } + +void focaltech_set_resolution(struct psmouse *psmouse, unsigned int resolution) +{ + /* not supported yet */ +} + +static void focaltech_set_rate(struct psmouse *psmouse, unsigned int rate) +{ + /* not supported yet */ +} + +static void focaltech_set_scale(struct psmouse *psmouse, + enum psmouse_scale scale) +{ + /* not supported yet */ +} + int focaltech_init(struct psmouse *psmouse) { struct focaltech_data *priv; @@ -420,6 +437,14 @@ int focaltech_init(struct psmouse *psmouse) psmouse->cleanup = focaltech_reset; /* resync is not supported yet */ psmouse->resync_time = 0; + /* + * rate/resolution/scale changes are not supported yet, and + * the generic implementations of these functions seem to + * confuse some touchpads + */ + psmouse->set_resolution = focaltech_set_resolution; + psmouse->set_rate = focaltech_set_rate; + psmouse->set_scale = focaltech_set_scale; return 0; diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 4ccd01d7a48d..8bc61237bc1b 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c @@ -453,6 +453,17 @@ static void psmouse_set_rate(struct psmouse *psmouse, unsigned int rate) psmouse->rate = r; } +/* + * Here we set the mouse scaling. + */ + +static void psmouse_set_scale(struct psmouse *psmouse, enum psmouse_scale scale) +{ + ps2_command(&psmouse->ps2dev, NULL, + scale == PSMOUSE_SCALE21 ? PSMOUSE_CMD_SETSCALE21 : + PSMOUSE_CMD_SETSCALE11); +} + /* * psmouse_poll() - default poll handler. Everyone except for ALPS uses it. */ @@ -689,6 +700,7 @@ static void psmouse_apply_defaults(struct psmouse *psmouse) psmouse->set_rate = psmouse_set_rate; psmouse->set_resolution = psmouse_set_resolution; + psmouse->set_scale = psmouse_set_scale; psmouse->poll = psmouse_poll; psmouse->protocol_handler = psmouse_process_byte; psmouse->pktsize = 3; @@ -1160,7 +1172,7 @@ static void psmouse_initialize(struct psmouse *psmouse) if (psmouse_max_proto != PSMOUSE_PS2) { psmouse->set_rate(psmouse, psmouse->rate); psmouse->set_resolution(psmouse, psmouse->resolution); - ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSCALE11); + psmouse->set_scale(psmouse, PSMOUSE_SCALE11); } } diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h index c2ff137ecbdb..d02e1bdc9ae4 100644 --- a/drivers/input/mouse/psmouse.h +++ b/drivers/input/mouse/psmouse.h @@ -36,6 +36,11 @@ typedef enum { PSMOUSE_FULL_PACKET } psmouse_ret_t; +enum psmouse_scale { + PSMOUSE_SCALE11, + PSMOUSE_SCALE21 +}; + struct psmouse { void *private; struct input_dev *dev; @@ -67,6 +72,7 @@ struct psmouse { psmouse_ret_t (*protocol_handler)(struct psmouse *psmouse); void (*set_rate)(struct psmouse *psmouse, unsigned int rate); void (*set_resolution)(struct psmouse *psmouse, unsigned int resolution); + void (*set_scale)(struct psmouse *psmouse, enum psmouse_scale scale); int (*reconnect)(struct psmouse *psmouse); void (*disconnect)(struct psmouse *psmouse); -- GitLab From 4eb8d6e7e5aa14572bc389e554aad9869188cdcd Mon Sep 17 00:00:00 2001 From: Mathias Gottschlag Date: Sat, 7 Mar 2015 13:38:52 -0800 Subject: [PATCH 03375/11651] Input: psmouse - disable "palm detection" in the focaltech driver Apparently, the threshold for large contact area seems to be rather low on some devices, causing the touchpad to frequently freeze during normal usage. Because we do now know how we are supposed to use the value in question, this commit just drops the related code completely. Signed-off-by: Mathias Gottschlag Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/focaltech.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/drivers/input/mouse/focaltech.c b/drivers/input/mouse/focaltech.c index 891a2716d6a0..23d259416f2f 100644 --- a/drivers/input/mouse/focaltech.c +++ b/drivers/input/mouse/focaltech.c @@ -185,16 +185,6 @@ static void focaltech_process_abs_packet(struct psmouse *psmouse, state->pressed = (packet[0] >> 4) & 1; - /* - * packet[5] contains some kind of tool size in the most - * significant nibble. 0xff is a special value (latching) that - * signals a large contact area. - */ - if (packet[5] == 0xff) { - state->fingers[finger].valid = false; - return; - } - state->fingers[finger].x = ((packet[1] & 0xf) << 8) | packet[2]; state->fingers[finger].y = (packet[3] << 8) | packet[4]; state->fingers[finger].valid = true; -- GitLab From 9c348d45d829be10bea4cb8e675f14a1baf9bab1 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Sat, 7 Mar 2015 07:23:29 +0100 Subject: [PATCH 03376/11651] ARM: at91/dt: fix macb compatible strings Some at91 SoCs embed a 10/100 Mbit Ethernet IP, that is based on the at91sam9260 SoC. Fix at91 DTs accordingly. Signed-off-by: Boris Brezillon Reviewed-by: Alexandre Belloni Signed-off-by: David S. Miller --- arch/arm/boot/dts/at91sam9260.dtsi | 2 +- arch/arm/boot/dts/at91sam9263.dtsi | 2 +- arch/arm/boot/dts/at91sam9g45.dtsi | 2 +- arch/arm/boot/dts/at91sam9x5_macb0.dtsi | 2 +- arch/arm/boot/dts/at91sam9x5_macb1.dtsi | 2 +- arch/arm/boot/dts/sama5d3_emac.dtsi | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/arm/boot/dts/at91sam9260.dtsi b/arch/arm/boot/dts/at91sam9260.dtsi index fff0ee69aab4..9f7c7376f2cf 100644 --- a/arch/arm/boot/dts/at91sam9260.dtsi +++ b/arch/arm/boot/dts/at91sam9260.dtsi @@ -842,7 +842,7 @@ }; macb0: ethernet@fffc4000 { - compatible = "cdns,at32ap7000-macb", "cdns,macb"; + compatible = "cdns,at91sam9260-macb", "cdns,macb"; reg = <0xfffc4000 0x100>; interrupts = <21 IRQ_TYPE_LEVEL_HIGH 3>; pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/at91sam9263.dtsi b/arch/arm/boot/dts/at91sam9263.dtsi index 1f67bb4c144e..340179ef6ba0 100644 --- a/arch/arm/boot/dts/at91sam9263.dtsi +++ b/arch/arm/boot/dts/at91sam9263.dtsi @@ -845,7 +845,7 @@ }; macb0: ethernet@fffbc000 { - compatible = "cdns,at32ap7000-macb", "cdns,macb"; + compatible = "cdns,at91sam9260-macb", "cdns,macb"; reg = <0xfffbc000 0x100>; interrupts = <21 IRQ_TYPE_LEVEL_HIGH 3>; pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi index ee80aa9c0759..586eab7b653d 100644 --- a/arch/arm/boot/dts/at91sam9g45.dtsi +++ b/arch/arm/boot/dts/at91sam9g45.dtsi @@ -956,7 +956,7 @@ }; macb0: ethernet@fffbc000 { - compatible = "cdns,at32ap7000-macb", "cdns,macb"; + compatible = "cdns,at91sam9260-macb", "cdns,macb"; reg = <0xfffbc000 0x100>; interrupts = <25 IRQ_TYPE_LEVEL_HIGH 3>; pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/at91sam9x5_macb0.dtsi b/arch/arm/boot/dts/at91sam9x5_macb0.dtsi index 57e89d1d0325..73d7e30965ba 100644 --- a/arch/arm/boot/dts/at91sam9x5_macb0.dtsi +++ b/arch/arm/boot/dts/at91sam9x5_macb0.dtsi @@ -53,7 +53,7 @@ }; macb0: ethernet@f802c000 { - compatible = "cdns,at32ap7000-macb", "cdns,macb"; + compatible = "cdns,at91sam9260-macb", "cdns,macb"; reg = <0xf802c000 0x100>; interrupts = <24 IRQ_TYPE_LEVEL_HIGH 3>; pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/at91sam9x5_macb1.dtsi b/arch/arm/boot/dts/at91sam9x5_macb1.dtsi index 663676c02861..d81980c40c7d 100644 --- a/arch/arm/boot/dts/at91sam9x5_macb1.dtsi +++ b/arch/arm/boot/dts/at91sam9x5_macb1.dtsi @@ -41,7 +41,7 @@ }; macb1: ethernet@f8030000 { - compatible = "cdns,at32ap7000-macb", "cdns,macb"; + compatible = "cdns,at91sam9260-macb", "cdns,macb"; reg = <0xf8030000 0x100>; interrupts = <27 IRQ_TYPE_LEVEL_HIGH 3>; pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/sama5d3_emac.dtsi b/arch/arm/boot/dts/sama5d3_emac.dtsi index fe2af9276312..b4544cf11bad 100644 --- a/arch/arm/boot/dts/sama5d3_emac.dtsi +++ b/arch/arm/boot/dts/sama5d3_emac.dtsi @@ -41,7 +41,7 @@ }; macb1: ethernet@f802c000 { - compatible = "cdns,at32ap7000-macb", "cdns,macb"; + compatible = "cdns,at91sam9260-macb", "cdns,macb"; reg = <0xf802c000 0x100>; interrupts = <35 IRQ_TYPE_LEVEL_HIGH 3>; pinctrl-names = "default"; -- GitLab From a848748959d554666b34cffc08ef2d23f4bb2990 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Sat, 7 Mar 2015 07:23:30 +0100 Subject: [PATCH 03377/11651] net: macb: remove #if defined(CONFIG_ARCH_AT91) sections With multi platform support those sections could lead to unexpected behavior if both ARCH_AT91 and another ARM SoC using the MACB IP are selected. Add two new capabilities to encode the default MII mode and the presence of a CLKEN bit in USRIO register. Then define the appropriate config for IPs embedded in at91 SoCs. Signed-off-by: Boris Brezillon Reviewed-by: Alexandre Belloni Signed-off-by: David S. Miller --- drivers/net/ethernet/cadence/macb.c | 32 +++++++++++++++-------------- drivers/net/ethernet/cadence/macb.h | 2 ++ 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c index f6c8935a4f0b..ff649f0e9cb7 100644 --- a/drivers/net/ethernet/cadence/macb.c +++ b/drivers/net/ethernet/cadence/macb.c @@ -2131,6 +2131,10 @@ static const struct net_device_ops macb_netdev_ops = { }; #if defined(CONFIG_OF) +static struct macb_config at91sam9260_config = { + .caps = MACB_CAPS_USRIO_HAS_CLKEN | MACB_CAPS_USRIO_DEFAULT_IS_MII, +}; + static struct macb_config pc302gem_config = { .caps = MACB_CAPS_SG_DISABLED | MACB_CAPS_GIGABIT_MODE_AVAILABLE, .dma_burst_length = 16, @@ -2148,7 +2152,7 @@ static struct macb_config sama5d4_config = { static const struct of_device_id macb_dt_ids[] = { { .compatible = "cdns,at32ap7000-macb" }, - { .compatible = "cdns,at91sam9260-macb" }, + { .compatible = "cdns,at91sam9260-macb", .data = &at91sam9260_config }, { .compatible = "cdns,macb" }, { .compatible = "cdns,pc302-gem", .data = &pc302gem_config }, { .compatible = "cdns,gem", .data = &pc302gem_config }, @@ -2408,21 +2412,19 @@ static int macb_probe(struct platform_device *pdev) bp->phy_interface = err; } + config = 0; if (bp->phy_interface == PHY_INTERFACE_MODE_RGMII) - macb_or_gem_writel(bp, USRIO, GEM_BIT(RGMII)); - else if (bp->phy_interface == PHY_INTERFACE_MODE_RMII) -#if defined(CONFIG_ARCH_AT91) - macb_or_gem_writel(bp, USRIO, (MACB_BIT(RMII) | - MACB_BIT(CLKEN))); -#else - macb_or_gem_writel(bp, USRIO, 0); -#endif - else -#if defined(CONFIG_ARCH_AT91) - macb_or_gem_writel(bp, USRIO, MACB_BIT(CLKEN)); -#else - macb_or_gem_writel(bp, USRIO, MACB_BIT(MII)); -#endif + config = GEM_BIT(RGMII); + else if (bp->phy_interface == PHY_INTERFACE_MODE_RMII && + (bp->caps & MACB_CAPS_USRIO_DEFAULT_IS_MII)) + config = MACB_BIT(RMII); + else if (!(bp->caps & MACB_CAPS_USRIO_DEFAULT_IS_MII)) + config = MACB_BIT(MII); + + if (bp->caps & MACB_CAPS_USRIO_HAS_CLKEN) + config |= MACB_BIT(CLKEN); + + macb_or_gem_writel(bp, USRIO, config); err = register_netdev(dev); if (err) { diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h index 83241c8ec5dc..1797fb00124b 100644 --- a/drivers/net/ethernet/cadence/macb.h +++ b/drivers/net/ethernet/cadence/macb.h @@ -391,6 +391,8 @@ /* Capability mask bits */ #define MACB_CAPS_ISR_CLEAR_ON_WRITE 0x00000001 +#define MACB_CAPS_USRIO_HAS_CLKEN 0x00000002 +#define MACB_CAPS_USRIO_DEFAULT_IS_MII 0x00000004 #define MACB_CAPS_FIFO_MODE 0x10000000 #define MACB_CAPS_GIGABIT_MODE_AVAILABLE 0x20000000 #define MACB_CAPS_SG_DISABLED 0x40000000 -- GitLab From 93b31f48b3ba84cc5fc310c9765d11ebbeede7b5 Mon Sep 17 00:00:00 2001 From: Cyrille Pitchen Date: Sat, 7 Mar 2015 07:23:31 +0100 Subject: [PATCH 03378/11651] net/macb: unify clock management Most of the functions from the Common Clk Framework handle NULL pointer as input argument. Since the TX clock is optional, we now set tx_clk to NULL value instead of ERR_PTR(-ENOENT) when this clock is not available. This simplifies the clock management and avoid the need to test tx_clk value. Signed-off-by: Cyrille Pitchen Acked-by: Boris Brezillon Acked-by: Alexandre Belloni Signed-off-by: David S. Miller --- drivers/net/ethernet/cadence/macb.c | 31 +++++++++++++---------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c index ff649f0e9cb7..2bb3c1c06e60 100644 --- a/drivers/net/ethernet/cadence/macb.c +++ b/drivers/net/ethernet/cadence/macb.c @@ -213,6 +213,9 @@ static void macb_set_tx_clk(struct clk *clk, int speed, struct net_device *dev) { long ferr, rate, rate_rounded; + if (!clk) + return; + switch (speed) { case SPEED_10: rate = 2500000; @@ -292,8 +295,7 @@ static void macb_handle_link_change(struct net_device *dev) spin_unlock_irqrestore(&bp->lock, flags); - if (!IS_ERR(bp->tx_clk)) - macb_set_tx_clk(bp->tx_clk, phydev->speed, dev); + macb_set_tx_clk(bp->tx_clk, phydev->speed, dev); if (status_change) { if (phydev->link) { @@ -2264,6 +2266,8 @@ static int macb_probe(struct platform_device *pdev) } tx_clk = devm_clk_get(&pdev->dev, "tx_clk"); + if (IS_ERR(tx_clk)) + tx_clk = NULL; err = clk_prepare_enable(pclk); if (err) { @@ -2277,13 +2281,10 @@ static int macb_probe(struct platform_device *pdev) goto err_out_disable_pclk; } - if (!IS_ERR(tx_clk)) { - err = clk_prepare_enable(tx_clk); - if (err) { - dev_err(&pdev->dev, "failed to enable tx_clk (%u)\n", - err); - goto err_out_disable_hclk; - } + err = clk_prepare_enable(tx_clk); + if (err) { + dev_err(&pdev->dev, "failed to enable tx_clk (%u)\n", err); + goto err_out_disable_hclk; } err = -ENOMEM; @@ -2455,8 +2456,7 @@ err_out_unregister_netdev: err_out_free_netdev: free_netdev(dev); err_out_disable_clocks: - if (!IS_ERR(tx_clk)) - clk_disable_unprepare(tx_clk); + clk_disable_unprepare(tx_clk); err_out_disable_hclk: clk_disable_unprepare(hclk); err_out_disable_pclk: @@ -2480,8 +2480,7 @@ static int macb_remove(struct platform_device *pdev) kfree(bp->mii_bus->irq); mdiobus_free(bp->mii_bus); unregister_netdev(dev); - if (!IS_ERR(bp->tx_clk)) - clk_disable_unprepare(bp->tx_clk); + clk_disable_unprepare(bp->tx_clk); clk_disable_unprepare(bp->hclk); clk_disable_unprepare(bp->pclk); free_netdev(dev); @@ -2499,8 +2498,7 @@ static int __maybe_unused macb_suspend(struct device *dev) netif_carrier_off(netdev); netif_device_detach(netdev); - if (!IS_ERR(bp->tx_clk)) - clk_disable_unprepare(bp->tx_clk); + clk_disable_unprepare(bp->tx_clk); clk_disable_unprepare(bp->hclk); clk_disable_unprepare(bp->pclk); @@ -2515,8 +2513,7 @@ static int __maybe_unused macb_resume(struct device *dev) clk_prepare_enable(bp->pclk); clk_prepare_enable(bp->hclk); - if (!IS_ERR(bp->tx_clk)) - clk_prepare_enable(bp->tx_clk); + clk_prepare_enable(bp->tx_clk); netif_device_attach(netdev); -- GitLab From 421d9df0628be16e55705573ab49d8ddb6a1d68c Mon Sep 17 00:00:00 2001 From: Cyrille Pitchen Date: Sat, 7 Mar 2015 07:23:32 +0100 Subject: [PATCH 03379/11651] net/macb: merge at91_ether driver into macb driver macb and at91_ether drivers can be compiled as modules, but the at91_ether driver use some functions and variables defined in the macb one, thus creating a dependency on the macb driver. Since these drivers are sharing the same logic we can easily merge at91_ether into macb. In order to factorize common probing logic we've added an ->init() function to struct macb_config (the structure associated with the compatible string), and moved macb specific init code from macb_probe to macb_init. Signed-off-by: Cyrille Pitchen Signed-off-by: Boris Brezillon Tested-by: Alexandre Belloni Signed-off-by: David S. Miller --- drivers/net/ethernet/cadence/Kconfig | 8 - drivers/net/ethernet/cadence/Makefile | 1 - drivers/net/ethernet/cadence/at91_ether.c | 481 ---------------- drivers/net/ethernet/cadence/macb.c | 639 ++++++++++++++++------ drivers/net/ethernet/cadence/macb.h | 10 +- 5 files changed, 484 insertions(+), 655 deletions(-) delete mode 100644 drivers/net/ethernet/cadence/at91_ether.c diff --git a/drivers/net/ethernet/cadence/Kconfig b/drivers/net/ethernet/cadence/Kconfig index 739bb0048ebf..1ba3e3a67389 100644 --- a/drivers/net/ethernet/cadence/Kconfig +++ b/drivers/net/ethernet/cadence/Kconfig @@ -20,14 +20,6 @@ config NET_CADENCE if NET_CADENCE -config ARM_AT91_ETHER - tristate "AT91RM9200 Ethernet support" - depends on HAS_DMA && (ARCH_AT91 || COMPILE_TEST) - select MACB - ---help--- - If you wish to compile a kernel for the AT91RM9200 and enable - ethernet support, then you should always answer Y to this. - config MACB tristate "Cadence MACB/GEM support" depends on HAS_DMA diff --git a/drivers/net/ethernet/cadence/Makefile b/drivers/net/ethernet/cadence/Makefile index 9068b8331ed1..91f79b1f0505 100644 --- a/drivers/net/ethernet/cadence/Makefile +++ b/drivers/net/ethernet/cadence/Makefile @@ -2,5 +2,4 @@ # Makefile for the Atmel network device drivers. # -obj-$(CONFIG_ARM_AT91_ETHER) += at91_ether.o obj-$(CONFIG_MACB) += macb.o diff --git a/drivers/net/ethernet/cadence/at91_ether.c b/drivers/net/ethernet/cadence/at91_ether.c deleted file mode 100644 index 7ef55f5fa664..000000000000 --- a/drivers/net/ethernet/cadence/at91_ether.c +++ /dev/null @@ -1,481 +0,0 @@ -/* - * Ethernet driver for the Atmel AT91RM9200 (Thunder) - * - * Copyright (C) 2003 SAN People (Pty) Ltd - * - * Based on an earlier Atmel EMAC macrocell driver by Atmel and Lineo Inc. - * Initial version by Rick Bronson 01/11/2003 - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "macb.h" - -/* 1518 rounded up */ -#define MAX_RBUFF_SZ 0x600 -/* max number of receive buffers */ -#define MAX_RX_DESCR 9 - -/* Initialize and start the Receiver and Transmit subsystems */ -static int at91ether_start(struct net_device *dev) -{ - struct macb *lp = netdev_priv(dev); - dma_addr_t addr; - u32 ctl; - int i; - - lp->rx_ring = dma_alloc_coherent(&lp->pdev->dev, - (MAX_RX_DESCR * - sizeof(struct macb_dma_desc)), - &lp->rx_ring_dma, GFP_KERNEL); - if (!lp->rx_ring) - return -ENOMEM; - - lp->rx_buffers = dma_alloc_coherent(&lp->pdev->dev, - MAX_RX_DESCR * MAX_RBUFF_SZ, - &lp->rx_buffers_dma, GFP_KERNEL); - if (!lp->rx_buffers) { - dma_free_coherent(&lp->pdev->dev, - MAX_RX_DESCR * sizeof(struct macb_dma_desc), - lp->rx_ring, lp->rx_ring_dma); - lp->rx_ring = NULL; - return -ENOMEM; - } - - addr = lp->rx_buffers_dma; - for (i = 0; i < MAX_RX_DESCR; i++) { - lp->rx_ring[i].addr = addr; - lp->rx_ring[i].ctrl = 0; - addr += MAX_RBUFF_SZ; - } - - /* Set the Wrap bit on the last descriptor */ - lp->rx_ring[MAX_RX_DESCR - 1].addr |= MACB_BIT(RX_WRAP); - - /* Reset buffer index */ - lp->rx_tail = 0; - - /* Program address of descriptor list in Rx Buffer Queue register */ - macb_writel(lp, RBQP, lp->rx_ring_dma); - - /* Enable Receive and Transmit */ - ctl = macb_readl(lp, NCR); - macb_writel(lp, NCR, ctl | MACB_BIT(RE) | MACB_BIT(TE)); - - return 0; -} - -/* Open the ethernet interface */ -static int at91ether_open(struct net_device *dev) -{ - struct macb *lp = netdev_priv(dev); - u32 ctl; - int ret; - - /* Clear internal statistics */ - ctl = macb_readl(lp, NCR); - macb_writel(lp, NCR, ctl | MACB_BIT(CLRSTAT)); - - macb_set_hwaddr(lp); - - ret = at91ether_start(dev); - if (ret) - return ret; - - /* Enable MAC interrupts */ - macb_writel(lp, IER, MACB_BIT(RCOMP) | - MACB_BIT(RXUBR) | - MACB_BIT(ISR_TUND) | - MACB_BIT(ISR_RLE) | - MACB_BIT(TCOMP) | - MACB_BIT(ISR_ROVR) | - MACB_BIT(HRESP)); - - /* schedule a link state check */ - phy_start(lp->phy_dev); - - netif_start_queue(dev); - - return 0; -} - -/* Close the interface */ -static int at91ether_close(struct net_device *dev) -{ - struct macb *lp = netdev_priv(dev); - u32 ctl; - - /* Disable Receiver and Transmitter */ - ctl = macb_readl(lp, NCR); - macb_writel(lp, NCR, ctl & ~(MACB_BIT(TE) | MACB_BIT(RE))); - - /* Disable MAC interrupts */ - macb_writel(lp, IDR, MACB_BIT(RCOMP) | - MACB_BIT(RXUBR) | - MACB_BIT(ISR_TUND) | - MACB_BIT(ISR_RLE) | - MACB_BIT(TCOMP) | - MACB_BIT(ISR_ROVR) | - MACB_BIT(HRESP)); - - netif_stop_queue(dev); - - dma_free_coherent(&lp->pdev->dev, - MAX_RX_DESCR * sizeof(struct macb_dma_desc), - lp->rx_ring, lp->rx_ring_dma); - lp->rx_ring = NULL; - - dma_free_coherent(&lp->pdev->dev, - MAX_RX_DESCR * MAX_RBUFF_SZ, - lp->rx_buffers, lp->rx_buffers_dma); - lp->rx_buffers = NULL; - - return 0; -} - -/* Transmit packet */ -static int at91ether_start_xmit(struct sk_buff *skb, struct net_device *dev) -{ - struct macb *lp = netdev_priv(dev); - - if (macb_readl(lp, TSR) & MACB_BIT(RM9200_BNQ)) { - netif_stop_queue(dev); - - /* Store packet information (to free when Tx completed) */ - lp->skb = skb; - lp->skb_length = skb->len; - lp->skb_physaddr = dma_map_single(NULL, skb->data, skb->len, - DMA_TO_DEVICE); - - /* Set address of the data in the Transmit Address register */ - macb_writel(lp, TAR, lp->skb_physaddr); - /* Set length of the packet in the Transmit Control register */ - macb_writel(lp, TCR, skb->len); - - } else { - netdev_err(dev, "%s called, but device is busy!\n", __func__); - return NETDEV_TX_BUSY; - } - - return NETDEV_TX_OK; -} - -/* Extract received frame from buffer descriptors and sent to upper layers. - * (Called from interrupt context) - */ -static void at91ether_rx(struct net_device *dev) -{ - struct macb *lp = netdev_priv(dev); - unsigned char *p_recv; - struct sk_buff *skb; - unsigned int pktlen; - - while (lp->rx_ring[lp->rx_tail].addr & MACB_BIT(RX_USED)) { - p_recv = lp->rx_buffers + lp->rx_tail * MAX_RBUFF_SZ; - pktlen = MACB_BF(RX_FRMLEN, lp->rx_ring[lp->rx_tail].ctrl); - skb = netdev_alloc_skb(dev, pktlen + 2); - if (skb) { - skb_reserve(skb, 2); - memcpy(skb_put(skb, pktlen), p_recv, pktlen); - - skb->protocol = eth_type_trans(skb, dev); - lp->stats.rx_packets++; - lp->stats.rx_bytes += pktlen; - netif_rx(skb); - } else { - lp->stats.rx_dropped++; - } - - if (lp->rx_ring[lp->rx_tail].ctrl & MACB_BIT(RX_MHASH_MATCH)) - lp->stats.multicast++; - - /* reset ownership bit */ - lp->rx_ring[lp->rx_tail].addr &= ~MACB_BIT(RX_USED); - - /* wrap after last buffer */ - if (lp->rx_tail == MAX_RX_DESCR - 1) - lp->rx_tail = 0; - else - lp->rx_tail++; - } -} - -/* MAC interrupt handler */ -static irqreturn_t at91ether_interrupt(int irq, void *dev_id) -{ - struct net_device *dev = dev_id; - struct macb *lp = netdev_priv(dev); - u32 intstatus, ctl; - - /* MAC Interrupt Status register indicates what interrupts are pending. - * It is automatically cleared once read. - */ - intstatus = macb_readl(lp, ISR); - - /* Receive complete */ - if (intstatus & MACB_BIT(RCOMP)) - at91ether_rx(dev); - - /* Transmit complete */ - if (intstatus & MACB_BIT(TCOMP)) { - /* The TCOM bit is set even if the transmission failed */ - if (intstatus & (MACB_BIT(ISR_TUND) | MACB_BIT(ISR_RLE))) - lp->stats.tx_errors++; - - if (lp->skb) { - dev_kfree_skb_irq(lp->skb); - lp->skb = NULL; - dma_unmap_single(NULL, lp->skb_physaddr, lp->skb_length, DMA_TO_DEVICE); - lp->stats.tx_packets++; - lp->stats.tx_bytes += lp->skb_length; - } - netif_wake_queue(dev); - } - - /* Work-around for EMAC Errata section 41.3.1 */ - if (intstatus & MACB_BIT(RXUBR)) { - ctl = macb_readl(lp, NCR); - macb_writel(lp, NCR, ctl & ~MACB_BIT(RE)); - macb_writel(lp, NCR, ctl | MACB_BIT(RE)); - } - - if (intstatus & MACB_BIT(ISR_ROVR)) - netdev_err(dev, "ROVR error\n"); - - return IRQ_HANDLED; -} - -#ifdef CONFIG_NET_POLL_CONTROLLER -static void at91ether_poll_controller(struct net_device *dev) -{ - unsigned long flags; - - local_irq_save(flags); - at91ether_interrupt(dev->irq, dev); - local_irq_restore(flags); -} -#endif - -static const struct net_device_ops at91ether_netdev_ops = { - .ndo_open = at91ether_open, - .ndo_stop = at91ether_close, - .ndo_start_xmit = at91ether_start_xmit, - .ndo_get_stats = macb_get_stats, - .ndo_set_rx_mode = macb_set_rx_mode, - .ndo_set_mac_address = eth_mac_addr, - .ndo_do_ioctl = macb_ioctl, - .ndo_validate_addr = eth_validate_addr, - .ndo_change_mtu = eth_change_mtu, -#ifdef CONFIG_NET_POLL_CONTROLLER - .ndo_poll_controller = at91ether_poll_controller, -#endif -}; - -#if defined(CONFIG_OF) -static const struct of_device_id at91ether_dt_ids[] = { - { .compatible = "cdns,at91rm9200-emac" }, - { .compatible = "cdns,emac" }, - { /* sentinel */ } -}; -MODULE_DEVICE_TABLE(of, at91ether_dt_ids); -#endif - -/* Detect MAC & PHY and perform ethernet interface initialization */ -static int __init at91ether_probe(struct platform_device *pdev) -{ - struct macb_platform_data *board_data = dev_get_platdata(&pdev->dev); - struct resource *regs; - struct net_device *dev; - struct phy_device *phydev; - struct macb *lp; - int res; - u32 reg; - const char *mac; - - regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!regs) - return -ENOENT; - - dev = alloc_etherdev(sizeof(struct macb)); - if (!dev) - return -ENOMEM; - - lp = netdev_priv(dev); - lp->pdev = pdev; - lp->dev = dev; - spin_lock_init(&lp->lock); - - /* physical base address */ - dev->base_addr = regs->start; - lp->regs = devm_ioremap(&pdev->dev, regs->start, resource_size(regs)); - if (!lp->regs) { - res = -ENOMEM; - goto err_free_dev; - } - - /* Clock */ - lp->pclk = devm_clk_get(&pdev->dev, "ether_clk"); - if (IS_ERR(lp->pclk)) { - res = PTR_ERR(lp->pclk); - goto err_free_dev; - } - clk_prepare_enable(lp->pclk); - - lp->hclk = ERR_PTR(-ENOENT); - lp->tx_clk = ERR_PTR(-ENOENT); - - /* Install the interrupt handler */ - dev->irq = platform_get_irq(pdev, 0); - res = devm_request_irq(&pdev->dev, dev->irq, at91ether_interrupt, 0, dev->name, dev); - if (res) - goto err_disable_clock; - - dev->netdev_ops = &at91ether_netdev_ops; - dev->ethtool_ops = &macb_ethtool_ops; - platform_set_drvdata(pdev, dev); - SET_NETDEV_DEV(dev, &pdev->dev); - - mac = of_get_mac_address(pdev->dev.of_node); - if (mac) - memcpy(lp->dev->dev_addr, mac, ETH_ALEN); - else - macb_get_hwaddr(lp); - - res = of_get_phy_mode(pdev->dev.of_node); - if (res < 0) { - if (board_data && board_data->is_rmii) - lp->phy_interface = PHY_INTERFACE_MODE_RMII; - else - lp->phy_interface = PHY_INTERFACE_MODE_MII; - } else { - lp->phy_interface = res; - } - - macb_writel(lp, NCR, 0); - - reg = MACB_BF(CLK, MACB_CLK_DIV32) | MACB_BIT(BIG); - if (lp->phy_interface == PHY_INTERFACE_MODE_RMII) - reg |= MACB_BIT(RM9200_RMII); - - macb_writel(lp, NCFGR, reg); - - /* Register the network interface */ - res = register_netdev(dev); - if (res) - goto err_disable_clock; - - res = macb_mii_init(lp); - if (res) - goto err_out_unregister_netdev; - - /* will be enabled in open() */ - netif_carrier_off(dev); - - phydev = lp->phy_dev; - netdev_info(dev, "attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n", - phydev->drv->name, dev_name(&phydev->dev), - phydev->irq); - - /* Display ethernet banner */ - netdev_info(dev, "AT91 ethernet at 0x%08lx int=%d (%pM)\n", - dev->base_addr, dev->irq, dev->dev_addr); - - return 0; - -err_out_unregister_netdev: - unregister_netdev(dev); -err_disable_clock: - clk_disable_unprepare(lp->pclk); -err_free_dev: - free_netdev(dev); - return res; -} - -static int at91ether_remove(struct platform_device *pdev) -{ - struct net_device *dev = platform_get_drvdata(pdev); - struct macb *lp = netdev_priv(dev); - - if (lp->phy_dev) - phy_disconnect(lp->phy_dev); - - mdiobus_unregister(lp->mii_bus); - kfree(lp->mii_bus->irq); - mdiobus_free(lp->mii_bus); - unregister_netdev(dev); - clk_disable_unprepare(lp->pclk); - free_netdev(dev); - - return 0; -} - -#ifdef CONFIG_PM -static int at91ether_suspend(struct platform_device *pdev, pm_message_t mesg) -{ - struct net_device *net_dev = platform_get_drvdata(pdev); - struct macb *lp = netdev_priv(net_dev); - - if (netif_running(net_dev)) { - netif_stop_queue(net_dev); - netif_device_detach(net_dev); - - clk_disable_unprepare(lp->pclk); - } - return 0; -} - -static int at91ether_resume(struct platform_device *pdev) -{ - struct net_device *net_dev = platform_get_drvdata(pdev); - struct macb *lp = netdev_priv(net_dev); - - if (netif_running(net_dev)) { - clk_prepare_enable(lp->pclk); - - netif_device_attach(net_dev); - netif_start_queue(net_dev); - } - return 0; -} -#else -#define at91ether_suspend NULL -#define at91ether_resume NULL -#endif - -static struct platform_driver at91ether_driver = { - .remove = at91ether_remove, - .suspend = at91ether_suspend, - .resume = at91ether_resume, - .driver = { - .name = "at91_ether", - .of_match_table = of_match_ptr(at91ether_dt_ids), - }, -}; - -module_platform_driver_probe(at91ether_driver, at91ether_probe); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("AT91RM9200 EMAC Ethernet driver"); -MODULE_AUTHOR("Andrew Victor"); -MODULE_ALIAS("platform:at91_ether"); diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c index 2bb3c1c06e60..a4c5462c071a 100644 --- a/drivers/net/ethernet/cadence/macb.c +++ b/drivers/net/ethernet/cadence/macb.c @@ -102,7 +102,7 @@ static void *macb_rx_buffer(struct macb *bp, unsigned int index) return bp->rx_buffers + bp->rx_buffer_size * macb_rx_ring_wrap(index); } -void macb_set_hwaddr(struct macb *bp) +static void macb_set_hwaddr(struct macb *bp) { u32 bottom; u16 top; @@ -120,9 +120,8 @@ void macb_set_hwaddr(struct macb *bp) macb_or_gem_writel(bp, SA4B, 0); macb_or_gem_writel(bp, SA4T, 0); } -EXPORT_SYMBOL_GPL(macb_set_hwaddr); -void macb_get_hwaddr(struct macb *bp) +static void macb_get_hwaddr(struct macb *bp) { struct macb_platform_data *pdata; u32 bottom; @@ -162,7 +161,6 @@ void macb_get_hwaddr(struct macb *bp) netdev_info(bp->dev, "invalid hw address, using random\n"); eth_hw_addr_random(bp->dev); } -EXPORT_SYMBOL_GPL(macb_get_hwaddr); static int macb_mdio_read(struct mii_bus *bus, int mii_id, int regnum) { @@ -359,7 +357,7 @@ static int macb_mii_probe(struct net_device *dev) return 0; } -int macb_mii_init(struct macb *bp) +static int macb_mii_init(struct macb *bp) { struct macb_platform_data *pdata; struct device_node *np; @@ -440,7 +438,6 @@ err_out_free_mdiobus: err_out: return err; } -EXPORT_SYMBOL_GPL(macb_mii_init); static void macb_update_stats(struct macb *bp) { @@ -1743,7 +1740,7 @@ static void macb_sethashtable(struct net_device *dev) /* * Enable/Disable promiscuous and multicast modes. */ -void macb_set_rx_mode(struct net_device *dev) +static void macb_set_rx_mode(struct net_device *dev) { unsigned long cfg; struct macb *bp = netdev_priv(dev); @@ -1784,7 +1781,6 @@ void macb_set_rx_mode(struct net_device *dev) macb_writel(bp, NCFGR, cfg); } -EXPORT_SYMBOL_GPL(macb_set_rx_mode); static int macb_open(struct net_device *dev) { @@ -1937,7 +1933,7 @@ static void gem_get_ethtool_strings(struct net_device *dev, u32 sset, u8 *p) } } -struct net_device_stats *macb_get_stats(struct net_device *dev) +static struct net_device_stats *macb_get_stats(struct net_device *dev) { struct macb *bp = netdev_priv(dev); struct net_device_stats *nstat = &bp->stats; @@ -1983,7 +1979,6 @@ struct net_device_stats *macb_get_stats(struct net_device *dev) return nstat; } -EXPORT_SYMBOL_GPL(macb_get_stats); static int macb_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { @@ -2045,7 +2040,7 @@ static void macb_get_regs(struct net_device *dev, struct ethtool_regs *regs, } } -const struct ethtool_ops macb_ethtool_ops = { +static const struct ethtool_ops macb_ethtool_ops = { .get_settings = macb_get_settings, .set_settings = macb_set_settings, .get_regs_len = macb_get_regs_len, @@ -2053,7 +2048,6 @@ const struct ethtool_ops macb_ethtool_ops = { .get_link = ethtool_op_get_link, .get_ts_info = ethtool_op_get_ts_info, }; -EXPORT_SYMBOL_GPL(macb_ethtool_ops); static const struct ethtool_ops gem_ethtool_ops = { .get_settings = macb_get_settings, @@ -2067,7 +2061,7 @@ static const struct ethtool_ops gem_ethtool_ops = { .get_sset_count = gem_get_sset_count, }; -int macb_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +static int macb_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct macb *bp = netdev_priv(dev); struct phy_device *phydev = bp->phy_dev; @@ -2080,7 +2074,6 @@ int macb_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) return phy_mii_ioctl(phydev, rq, cmd); } -EXPORT_SYMBOL_GPL(macb_ioctl); static int macb_set_features(struct net_device *netdev, netdev_features_t features) @@ -2132,39 +2125,6 @@ static const struct net_device_ops macb_netdev_ops = { .ndo_set_features = macb_set_features, }; -#if defined(CONFIG_OF) -static struct macb_config at91sam9260_config = { - .caps = MACB_CAPS_USRIO_HAS_CLKEN | MACB_CAPS_USRIO_DEFAULT_IS_MII, -}; - -static struct macb_config pc302gem_config = { - .caps = MACB_CAPS_SG_DISABLED | MACB_CAPS_GIGABIT_MODE_AVAILABLE, - .dma_burst_length = 16, -}; - -static struct macb_config sama5d3_config = { - .caps = MACB_CAPS_SG_DISABLED | MACB_CAPS_GIGABIT_MODE_AVAILABLE, - .dma_burst_length = 16, -}; - -static struct macb_config sama5d4_config = { - .caps = 0, - .dma_burst_length = 4, -}; - -static const struct of_device_id macb_dt_ids[] = { - { .compatible = "cdns,at32ap7000-macb" }, - { .compatible = "cdns,at91sam9260-macb", .data = &at91sam9260_config }, - { .compatible = "cdns,macb" }, - { .compatible = "cdns,pc302-gem", .data = &pc302gem_config }, - { .compatible = "cdns,gem", .data = &pc302gem_config }, - { .compatible = "atmel,sama5d3-gem", .data = &sama5d3_config }, - { .compatible = "atmel,sama5d4-gem", .data = &sama5d4_config }, - { /* sentinel */ } -}; -MODULE_DEVICE_TABLE(of, macb_dt_ids); -#endif - /* * Configure peripheral capacities according to device tree * and integration options used @@ -2172,22 +2132,6 @@ MODULE_DEVICE_TABLE(of, macb_dt_ids); static void macb_configure_caps(struct macb *bp) { u32 dcfg; - const struct of_device_id *match; - const struct macb_config *config; - - if (bp->pdev->dev.of_node) { - match = of_match_node(macb_dt_ids, bp->pdev->dev.of_node); - if (match && match->data) { - config = (const struct macb_config *)match->data; - - bp->caps = config->caps; - /* - * As we have access to the matching node, configure - * DMA burst length as well - */ - bp->dma_burst_length = config->dma_burst_length; - } - } if (MACB_BFEXT(IDNUM, macb_readl(bp, MID)) == 0x2) bp->caps |= MACB_CAPS_MACB_IS_GEM; @@ -2230,92 +2174,57 @@ static void macb_probe_queues(void __iomem *mem, (*num_queues)++; } -static int macb_probe(struct platform_device *pdev) +static int macb_init(struct platform_device *pdev) { - struct macb_platform_data *pdata; - struct resource *regs; - struct net_device *dev; - struct macb *bp; - struct macb_queue *queue; - struct phy_device *phydev; - u32 config; - int err = -ENXIO; - const char *mac; - void __iomem *mem; + struct net_device *dev = platform_get_drvdata(pdev); unsigned int hw_q, queue_mask, q, num_queues; - struct clk *pclk, *hclk, *tx_clk; - - regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!regs) { - dev_err(&pdev->dev, "no mmio resource defined\n"); - goto err_out; - } + struct macb *bp = netdev_priv(dev); + struct macb_queue *queue; + int err; + u32 val; - pclk = devm_clk_get(&pdev->dev, "pclk"); - if (IS_ERR(pclk)) { - err = PTR_ERR(pclk); + bp->pclk = devm_clk_get(&pdev->dev, "pclk"); + if (IS_ERR(bp->pclk)) { + err = PTR_ERR(bp->pclk); dev_err(&pdev->dev, "failed to get macb_clk (%u)\n", err); - goto err_out; + return err; } - hclk = devm_clk_get(&pdev->dev, "hclk"); - if (IS_ERR(hclk)) { - err = PTR_ERR(hclk); + bp->hclk = devm_clk_get(&pdev->dev, "hclk"); + if (IS_ERR(bp->hclk)) { + err = PTR_ERR(bp->hclk); dev_err(&pdev->dev, "failed to get hclk (%u)\n", err); - goto err_out; + return err; } - tx_clk = devm_clk_get(&pdev->dev, "tx_clk"); - if (IS_ERR(tx_clk)) - tx_clk = NULL; + bp->tx_clk = devm_clk_get(&pdev->dev, "tx_clk"); + if (IS_ERR(bp->tx_clk)) + bp->tx_clk = NULL; - err = clk_prepare_enable(pclk); + err = clk_prepare_enable(bp->pclk); if (err) { dev_err(&pdev->dev, "failed to enable pclk (%u)\n", err); - goto err_out; + return err; } - err = clk_prepare_enable(hclk); + err = clk_prepare_enable(bp->hclk); if (err) { dev_err(&pdev->dev, "failed to enable hclk (%u)\n", err); - goto err_out_disable_pclk; + goto err_disable_pclk; } - err = clk_prepare_enable(tx_clk); + err = clk_prepare_enable(bp->tx_clk); if (err) { dev_err(&pdev->dev, "failed to enable tx_clk (%u)\n", err); - goto err_out_disable_hclk; + goto err_disable_hclk; } - err = -ENOMEM; - mem = devm_ioremap(&pdev->dev, regs->start, resource_size(regs)); - if (!mem) { - dev_err(&pdev->dev, "failed to map registers, aborting.\n"); - goto err_out_disable_clocks; - } - - macb_probe_queues(mem, &queue_mask, &num_queues); - dev = alloc_etherdev_mq(sizeof(*bp), num_queues); - if (!dev) - goto err_out_disable_clocks; - - SET_NETDEV_DEV(dev, &pdev->dev); - - bp = netdev_priv(dev); - bp->pdev = pdev; - bp->dev = dev; - bp->regs = mem; - bp->num_queues = num_queues; - bp->pclk = pclk; - bp->hclk = hclk; - bp->tx_clk = tx_clk; - - spin_lock_init(&bp->lock); - /* set the queue register mapping once for all: queue0 has a special * register mapping but we don't want to test the queue index then * compute the corresponding register offset at run time. */ + macb_probe_queues(bp->regs, &queue_mask, &num_queues); + for (hw_q = 0, q = 0; hw_q < MACB_MAX_QUEUES; ++hw_q) { if (!(queue_mask & (1 << hw_q))) continue; @@ -2349,22 +2258,16 @@ static int macb_probe(struct platform_device *pdev) dev_err(&pdev->dev, "Unable to request IRQ %d (error %d)\n", queue->irq, err); - goto err_out_free_netdev; + goto err_disable_tx_clk; } INIT_WORK(&queue->tx_error_task, macb_tx_error_task); q++; } - dev->irq = bp->queues[0].irq; dev->netdev_ops = &macb_netdev_ops; netif_napi_add(dev, &bp->napi, macb_poll, 64); - dev->base_addr = regs->start; - - /* setup capacities */ - macb_configure_caps(bp); - /* setup appropriated routines according to adapter type */ if (macb_is_gem(bp)) { bp->max_tx_length = GEM_MAX_TX_LEN; @@ -2391,18 +2294,439 @@ static int macb_probe(struct platform_device *pdev) dev->hw_features &= ~NETIF_F_SG; dev->features = dev->hw_features; + val = 0; + if (bp->phy_interface == PHY_INTERFACE_MODE_RGMII) + val = GEM_BIT(RGMII); + else if (bp->phy_interface == PHY_INTERFACE_MODE_RMII && + (bp->caps & MACB_CAPS_USRIO_DEFAULT_IS_MII)) + val = MACB_BIT(RMII); + else if (!(bp->caps & MACB_CAPS_USRIO_DEFAULT_IS_MII)) + val = MACB_BIT(MII); + + if (bp->caps & MACB_CAPS_USRIO_HAS_CLKEN) + val |= MACB_BIT(CLKEN); + + macb_or_gem_writel(bp, USRIO, val); + + /* setup capacities */ + macb_configure_caps(bp); + /* Set MII management clock divider */ - config = macb_mdc_clk_div(bp); - config |= macb_dbw(bp); - macb_writel(bp, NCFGR, config); + val = macb_mdc_clk_div(bp); + val |= macb_dbw(bp); + macb_writel(bp, NCFGR, val); + + return 0; + +err_disable_tx_clk: + clk_disable_unprepare(bp->tx_clk); + +err_disable_hclk: + clk_disable_unprepare(bp->hclk); + +err_disable_pclk: + clk_disable_unprepare(bp->pclk); + + return err; +} + +#if defined(CONFIG_OF) +/* 1518 rounded up */ +#define AT91ETHER_MAX_RBUFF_SZ 0x600 +/* max number of receive buffers */ +#define AT91ETHER_MAX_RX_DESCR 9 + +/* Initialize and start the Receiver and Transmit subsystems */ +static int at91ether_start(struct net_device *dev) +{ + struct macb *lp = netdev_priv(dev); + dma_addr_t addr; + u32 ctl; + int i; + + lp->rx_ring = dma_alloc_coherent(&lp->pdev->dev, + (AT91ETHER_MAX_RX_DESCR * + sizeof(struct macb_dma_desc)), + &lp->rx_ring_dma, GFP_KERNEL); + if (!lp->rx_ring) + return -ENOMEM; + + lp->rx_buffers = dma_alloc_coherent(&lp->pdev->dev, + AT91ETHER_MAX_RX_DESCR * + AT91ETHER_MAX_RBUFF_SZ, + &lp->rx_buffers_dma, GFP_KERNEL); + if (!lp->rx_buffers) { + dma_free_coherent(&lp->pdev->dev, + AT91ETHER_MAX_RX_DESCR * + sizeof(struct macb_dma_desc), + lp->rx_ring, lp->rx_ring_dma); + lp->rx_ring = NULL; + return -ENOMEM; + } + + addr = lp->rx_buffers_dma; + for (i = 0; i < AT91ETHER_MAX_RX_DESCR; i++) { + lp->rx_ring[i].addr = addr; + lp->rx_ring[i].ctrl = 0; + addr += AT91ETHER_MAX_RBUFF_SZ; + } + + /* Set the Wrap bit on the last descriptor */ + lp->rx_ring[AT91ETHER_MAX_RX_DESCR - 1].addr |= MACB_BIT(RX_WRAP); + + /* Reset buffer index */ + lp->rx_tail = 0; + + /* Program address of descriptor list in Rx Buffer Queue register */ + macb_writel(lp, RBQP, lp->rx_ring_dma); + + /* Enable Receive and Transmit */ + ctl = macb_readl(lp, NCR); + macb_writel(lp, NCR, ctl | MACB_BIT(RE) | MACB_BIT(TE)); + + return 0; +} + +/* Open the ethernet interface */ +static int at91ether_open(struct net_device *dev) +{ + struct macb *lp = netdev_priv(dev); + u32 ctl; + int ret; + + /* Clear internal statistics */ + ctl = macb_readl(lp, NCR); + macb_writel(lp, NCR, ctl | MACB_BIT(CLRSTAT)); + + macb_set_hwaddr(lp); + + ret = at91ether_start(dev); + if (ret) + return ret; + + /* Enable MAC interrupts */ + macb_writel(lp, IER, MACB_BIT(RCOMP) | + MACB_BIT(RXUBR) | + MACB_BIT(ISR_TUND) | + MACB_BIT(ISR_RLE) | + MACB_BIT(TCOMP) | + MACB_BIT(ISR_ROVR) | + MACB_BIT(HRESP)); + + /* schedule a link state check */ + phy_start(lp->phy_dev); + + netif_start_queue(dev); + + return 0; +} + +/* Close the interface */ +static int at91ether_close(struct net_device *dev) +{ + struct macb *lp = netdev_priv(dev); + u32 ctl; + + /* Disable Receiver and Transmitter */ + ctl = macb_readl(lp, NCR); + macb_writel(lp, NCR, ctl & ~(MACB_BIT(TE) | MACB_BIT(RE))); + + /* Disable MAC interrupts */ + macb_writel(lp, IDR, MACB_BIT(RCOMP) | + MACB_BIT(RXUBR) | + MACB_BIT(ISR_TUND) | + MACB_BIT(ISR_RLE) | + MACB_BIT(TCOMP) | + MACB_BIT(ISR_ROVR) | + MACB_BIT(HRESP)); + + netif_stop_queue(dev); + + dma_free_coherent(&lp->pdev->dev, + AT91ETHER_MAX_RX_DESCR * + sizeof(struct macb_dma_desc), + lp->rx_ring, lp->rx_ring_dma); + lp->rx_ring = NULL; + + dma_free_coherent(&lp->pdev->dev, + AT91ETHER_MAX_RX_DESCR * AT91ETHER_MAX_RBUFF_SZ, + lp->rx_buffers, lp->rx_buffers_dma); + lp->rx_buffers = NULL; + + return 0; +} + +/* Transmit packet */ +static int at91ether_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct macb *lp = netdev_priv(dev); + + if (macb_readl(lp, TSR) & MACB_BIT(RM9200_BNQ)) { + netif_stop_queue(dev); + + /* Store packet information (to free when Tx completed) */ + lp->skb = skb; + lp->skb_length = skb->len; + lp->skb_physaddr = dma_map_single(NULL, skb->data, skb->len, + DMA_TO_DEVICE); + + /* Set address of the data in the Transmit Address register */ + macb_writel(lp, TAR, lp->skb_physaddr); + /* Set length of the packet in the Transmit Control register */ + macb_writel(lp, TCR, skb->len); - mac = of_get_mac_address(pdev->dev.of_node); + } else { + netdev_err(dev, "%s called, but device is busy!\n", __func__); + return NETDEV_TX_BUSY; + } + + return NETDEV_TX_OK; +} + +/* Extract received frame from buffer descriptors and sent to upper layers. + * (Called from interrupt context) + */ +static void at91ether_rx(struct net_device *dev) +{ + struct macb *lp = netdev_priv(dev); + unsigned char *p_recv; + struct sk_buff *skb; + unsigned int pktlen; + + while (lp->rx_ring[lp->rx_tail].addr & MACB_BIT(RX_USED)) { + p_recv = lp->rx_buffers + lp->rx_tail * AT91ETHER_MAX_RBUFF_SZ; + pktlen = MACB_BF(RX_FRMLEN, lp->rx_ring[lp->rx_tail].ctrl); + skb = netdev_alloc_skb(dev, pktlen + 2); + if (skb) { + skb_reserve(skb, 2); + memcpy(skb_put(skb, pktlen), p_recv, pktlen); + + skb->protocol = eth_type_trans(skb, dev); + lp->stats.rx_packets++; + lp->stats.rx_bytes += pktlen; + netif_rx(skb); + } else { + lp->stats.rx_dropped++; + } + + if (lp->rx_ring[lp->rx_tail].ctrl & MACB_BIT(RX_MHASH_MATCH)) + lp->stats.multicast++; + + /* reset ownership bit */ + lp->rx_ring[lp->rx_tail].addr &= ~MACB_BIT(RX_USED); + + /* wrap after last buffer */ + if (lp->rx_tail == AT91ETHER_MAX_RX_DESCR - 1) + lp->rx_tail = 0; + else + lp->rx_tail++; + } +} + +/* MAC interrupt handler */ +static irqreturn_t at91ether_interrupt(int irq, void *dev_id) +{ + struct net_device *dev = dev_id; + struct macb *lp = netdev_priv(dev); + u32 intstatus, ctl; + + /* MAC Interrupt Status register indicates what interrupts are pending. + * It is automatically cleared once read. + */ + intstatus = macb_readl(lp, ISR); + + /* Receive complete */ + if (intstatus & MACB_BIT(RCOMP)) + at91ether_rx(dev); + + /* Transmit complete */ + if (intstatus & MACB_BIT(TCOMP)) { + /* The TCOM bit is set even if the transmission failed */ + if (intstatus & (MACB_BIT(ISR_TUND) | MACB_BIT(ISR_RLE))) + lp->stats.tx_errors++; + + if (lp->skb) { + dev_kfree_skb_irq(lp->skb); + lp->skb = NULL; + dma_unmap_single(NULL, lp->skb_physaddr, + lp->skb_length, DMA_TO_DEVICE); + lp->stats.tx_packets++; + lp->stats.tx_bytes += lp->skb_length; + } + netif_wake_queue(dev); + } + + /* Work-around for EMAC Errata section 41.3.1 */ + if (intstatus & MACB_BIT(RXUBR)) { + ctl = macb_readl(lp, NCR); + macb_writel(lp, NCR, ctl & ~MACB_BIT(RE)); + macb_writel(lp, NCR, ctl | MACB_BIT(RE)); + } + + if (intstatus & MACB_BIT(ISR_ROVR)) + netdev_err(dev, "ROVR error\n"); + + return IRQ_HANDLED; +} + +#ifdef CONFIG_NET_POLL_CONTROLLER +static void at91ether_poll_controller(struct net_device *dev) +{ + unsigned long flags; + + local_irq_save(flags); + at91ether_interrupt(dev->irq, dev); + local_irq_restore(flags); +} +#endif + +static const struct net_device_ops at91ether_netdev_ops = { + .ndo_open = at91ether_open, + .ndo_stop = at91ether_close, + .ndo_start_xmit = at91ether_start_xmit, + .ndo_get_stats = macb_get_stats, + .ndo_set_rx_mode = macb_set_rx_mode, + .ndo_set_mac_address = eth_mac_addr, + .ndo_do_ioctl = macb_ioctl, + .ndo_validate_addr = eth_validate_addr, + .ndo_change_mtu = eth_change_mtu, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = at91ether_poll_controller, +#endif +}; + +static int at91ether_init(struct platform_device *pdev) +{ + struct net_device *dev = platform_get_drvdata(pdev); + struct macb *bp = netdev_priv(dev); + int err; + u32 reg; + + bp->pclk = devm_clk_get(&pdev->dev, "ether_clk"); + if (IS_ERR(bp->pclk)) + return PTR_ERR(bp->pclk); + + err = clk_prepare_enable(bp->pclk); + if (err) { + dev_err(&pdev->dev, "failed to enable pclk (%u)\n", err); + return err; + } + + dev->netdev_ops = &at91ether_netdev_ops; + dev->ethtool_ops = &macb_ethtool_ops; + + err = devm_request_irq(&pdev->dev, dev->irq, at91ether_interrupt, + 0, dev->name, dev); + if (err) + goto err_disable_clk; + + macb_writel(bp, NCR, 0); + + reg = MACB_BF(CLK, MACB_CLK_DIV32) | MACB_BIT(BIG); + if (bp->phy_interface == PHY_INTERFACE_MODE_RMII) + reg |= MACB_BIT(RM9200_RMII); + + macb_writel(bp, NCFGR, reg); + + return 0; + +err_disable_clk: + clk_disable_unprepare(bp->pclk); + + return err; +} + +static struct macb_config at91sam9260_config = { + .caps = MACB_CAPS_USRIO_HAS_CLKEN | MACB_CAPS_USRIO_DEFAULT_IS_MII, + .init = macb_init, +}; + +static struct macb_config pc302gem_config = { + .caps = MACB_CAPS_SG_DISABLED | MACB_CAPS_GIGABIT_MODE_AVAILABLE, + .dma_burst_length = 16, + .init = macb_init, +}; + +static struct macb_config sama5d3_config = { + .caps = MACB_CAPS_SG_DISABLED | MACB_CAPS_GIGABIT_MODE_AVAILABLE, + .dma_burst_length = 16, + .init = macb_init, +}; + +static struct macb_config sama5d4_config = { + .caps = 0, + .dma_burst_length = 4, + .init = macb_init, +}; + +static struct macb_config emac_config = { + .init = at91ether_init, +}; + +static const struct of_device_id macb_dt_ids[] = { + { .compatible = "cdns,at32ap7000-macb" }, + { .compatible = "cdns,at91sam9260-macb", .data = &at91sam9260_config }, + { .compatible = "cdns,macb" }, + { .compatible = "cdns,pc302-gem", .data = &pc302gem_config }, + { .compatible = "cdns,gem", .data = &pc302gem_config }, + { .compatible = "atmel,sama5d3-gem", .data = &sama5d3_config }, + { .compatible = "atmel,sama5d4-gem", .data = &sama5d4_config }, + { .compatible = "cdns,at91rm9200-emac", .data = &emac_config }, + { .compatible = "cdns,emac", .data = &emac_config }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, macb_dt_ids); +#endif /* CONFIG_OF */ + +static int macb_probe(struct platform_device *pdev) +{ + int (*init)(struct platform_device *) = macb_init; + struct device_node *np = pdev->dev.of_node; + const struct macb_config *macb_config = NULL; + unsigned int queue_mask, num_queues; + struct macb_platform_data *pdata; + struct phy_device *phydev; + struct net_device *dev; + struct resource *regs; + void __iomem *mem; + const char *mac; + struct macb *bp; + int err; + + regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); + mem = devm_ioremap_resource(&pdev->dev, regs); + if (IS_ERR(mem)) + return PTR_ERR(mem); + + macb_probe_queues(mem, &queue_mask, &num_queues); + dev = alloc_etherdev_mq(sizeof(*bp), num_queues); + if (!dev) + return -ENOMEM; + + dev->base_addr = regs->start; + + SET_NETDEV_DEV(dev, &pdev->dev); + + bp = netdev_priv(dev); + bp->pdev = pdev; + bp->dev = dev; + bp->regs = mem; + bp->num_queues = num_queues; + spin_lock_init(&bp->lock); + + platform_set_drvdata(pdev, dev); + + dev->irq = platform_get_irq(pdev, 0); + if (dev->irq < 0) + return dev->irq; + + mac = of_get_mac_address(np); if (mac) memcpy(bp->dev->dev_addr, mac, ETH_ALEN); else macb_get_hwaddr(bp); - err = of_get_phy_mode(pdev->dev.of_node); + err = of_get_phy_mode(np); if (err < 0) { pdata = dev_get_platdata(&pdev->dev); if (pdata && pdata->is_rmii) @@ -2413,32 +2737,35 @@ static int macb_probe(struct platform_device *pdev) bp->phy_interface = err; } - config = 0; - if (bp->phy_interface == PHY_INTERFACE_MODE_RGMII) - config = GEM_BIT(RGMII); - else if (bp->phy_interface == PHY_INTERFACE_MODE_RMII && - (bp->caps & MACB_CAPS_USRIO_DEFAULT_IS_MII)) - config = MACB_BIT(RMII); - else if (!(bp->caps & MACB_CAPS_USRIO_DEFAULT_IS_MII)) - config = MACB_BIT(MII); + if (np) { + const struct of_device_id *match; - if (bp->caps & MACB_CAPS_USRIO_HAS_CLKEN) - config |= MACB_BIT(CLKEN); + match = of_match_node(macb_dt_ids, np); + if (match) + macb_config = match->data; + } + + if (macb_config) { + bp->caps = macb_config->caps; + bp->dma_burst_length = macb_config->dma_burst_length; + init = macb_config->init; + } - macb_or_gem_writel(bp, USRIO, config); + /* IP specific init */ + err = init(pdev); + if (err) + goto err_out_free_netdev; err = register_netdev(dev); if (err) { dev_err(&pdev->dev, "Cannot register net device, aborting.\n"); - goto err_out_free_netdev; + goto err_disable_clocks; } err = macb_mii_init(bp); if (err) goto err_out_unregister_netdev; - platform_set_drvdata(pdev, dev); - netif_carrier_off(dev); netdev_info(dev, "Cadence %s rev 0x%08x at 0x%08lx irq %d (%pM)\n", @@ -2453,15 +2780,15 @@ static int macb_probe(struct platform_device *pdev) err_out_unregister_netdev: unregister_netdev(dev); + +err_disable_clocks: + clk_disable_unprepare(bp->tx_clk); + clk_disable_unprepare(bp->hclk); + clk_disable_unprepare(bp->pclk); + err_out_free_netdev: free_netdev(dev); -err_out_disable_clocks: - clk_disable_unprepare(tx_clk); -err_out_disable_hclk: - clk_disable_unprepare(hclk); -err_out_disable_pclk: - clk_disable_unprepare(pclk); -err_out: + return err; } diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h index 1797fb00124b..21e4147d8b5c 100644 --- a/drivers/net/ethernet/cadence/macb.h +++ b/drivers/net/ethernet/cadence/macb.h @@ -754,6 +754,7 @@ struct macb_or_gem_ops { struct macb_config { u32 caps; unsigned int dma_burst_length; + int (*init)(struct platform_device *pdev); }; struct macb_queue { @@ -824,15 +825,6 @@ struct macb { u64 ethtool_stats[GEM_STATS_LEN]; }; -extern const struct ethtool_ops macb_ethtool_ops; - -int macb_mii_init(struct macb *bp); -int macb_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); -struct net_device_stats *macb_get_stats(struct net_device *dev); -void macb_set_rx_mode(struct net_device *dev); -void macb_set_hwaddr(struct macb *bp); -void macb_get_hwaddr(struct macb *bp); - static inline bool macb_is_gem(struct macb *bp) { return !!(bp->caps & MACB_CAPS_MACB_IS_GEM); -- GitLab From 6f5a272c99108d9f8450c454a4baede9e7cc643f Mon Sep 17 00:00:00 2001 From: Petri Gynther Date: Fri, 6 Mar 2015 13:45:00 -0800 Subject: [PATCH 03380/11651] net: bcmgenet: rework Rx queue init In preparation for supporting multiple Rx queues: 1. Move the initialization of priv->num_rx_bds, priv->rx_bds, and priv->rx_cbs from bcmgenet_init_rx_ring() to bcmgenet_init_dma() since they are not specific to a single Rx queue. Mimics the Tx init model where priv->num_tx_bds, priv->tx_bds, and priv->tx_cbs are initialized in bcmgenet_init_dma(). 2. Program DMA_MBUF_DONE_THRESH = 1 so that future Rx queues Q0-Q15 will get per-packet Rx interrupt. 3. Group DMA_START_ADDR, RDMA_READ_PTR, RDMA_WRITE_PTR, and DMA_END_ADDR initialization together. Mimics the Tx init model. 4. There is 1-to-1 mapping between RxCBs and RxBDs. Precalculate RxCB->bd_addr so that it can be used in the future. Signed-off-by: Petri Gynther Reviewed-by: Florian Fainelli Signed-off-by: David S. Miller --- .../net/ethernet/broadcom/genet/bcmgenet.c | 43 ++++++++++++------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index d90785caab59..83c0cb323e0c 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -1783,37 +1783,33 @@ static int bcmgenet_init_rx_ring(struct bcmgenet_priv *priv, u32 words_per_bd = WORDS_PER_BD(priv); int ret; - priv->num_rx_bds = TOTAL_DESC; - priv->rx_bds = priv->base + priv->hw_params->rdma_offset; priv->rx_bd_assign_ptr = priv->rx_bds; priv->rx_bd_assign_index = 0; priv->rx_c_index = 0; priv->rx_read_ptr = 0; - priv->rx_cbs = kcalloc(priv->num_rx_bds, sizeof(struct enet_cb), - GFP_KERNEL); - if (!priv->rx_cbs) - return -ENOMEM; ret = bcmgenet_alloc_rx_buffers(priv); if (ret) { - kfree(priv->rx_cbs); return ret; } - bcmgenet_rdma_ring_writel(priv, index, 0, RDMA_WRITE_PTR); bcmgenet_rdma_ring_writel(priv, index, 0, RDMA_PROD_INDEX); bcmgenet_rdma_ring_writel(priv, index, 0, RDMA_CONS_INDEX); + bcmgenet_rdma_ring_writel(priv, index, 1, DMA_MBUF_DONE_THRESH); bcmgenet_rdma_ring_writel(priv, index, ((size << DMA_RING_SIZE_SHIFT) | RX_BUF_LENGTH), DMA_RING_BUF_SIZE); - bcmgenet_rdma_ring_writel(priv, index, 0, DMA_START_ADDR); - bcmgenet_rdma_ring_writel(priv, index, - words_per_bd * size - 1, DMA_END_ADDR); bcmgenet_rdma_ring_writel(priv, index, (DMA_FC_THRESH_LO << DMA_XOFF_THRESHOLD_SHIFT) | DMA_FC_THRESH_HI, RDMA_XON_XOFF_THRESH); + + /* Set start and end address, read and write pointers */ + bcmgenet_rdma_ring_writel(priv, index, 0, DMA_START_ADDR); bcmgenet_rdma_ring_writel(priv, index, 0, RDMA_READ_PTR); + bcmgenet_rdma_ring_writel(priv, index, 0, RDMA_WRITE_PTR); + bcmgenet_rdma_ring_writel(priv, index, words_per_bd * size - 1, + DMA_END_ADDR); return ret; } @@ -1976,18 +1972,33 @@ static int bcmgenet_init_dma(struct bcmgenet_priv *priv) unsigned int i; struct enet_cb *cb; - netif_dbg(priv, hw, priv->dev, "bcmgenet: init_edma\n"); + netif_dbg(priv, hw, priv->dev, "%s\n", __func__); - /* by default, enable ring 16 (descriptor based) */ + /* Init rDma */ + bcmgenet_rdma_writel(priv, DMA_MAX_BURST_LENGTH, DMA_SCB_BURST_SIZE); + + /* Initialize common Rx ring structures */ + priv->rx_bds = priv->base + priv->hw_params->rdma_offset; + priv->num_rx_bds = TOTAL_DESC; + priv->rx_cbs = kcalloc(priv->num_rx_bds, sizeof(struct enet_cb), + GFP_KERNEL); + if (!priv->rx_cbs) + return -ENOMEM; + + for (i = 0; i < priv->num_rx_bds; i++) { + cb = priv->rx_cbs + i; + cb->bd_addr = priv->rx_bds + i * DMA_DESC_SIZE; + } + + /* Initialize Rx default queue 16 */ ret = bcmgenet_init_rx_ring(priv, DESC_INDEX, TOTAL_DESC); if (ret) { netdev_err(priv->dev, "failed to initialize RX ring\n"); + bcmgenet_free_rx_buffers(priv); + kfree(priv->rx_cbs); return ret; } - /* init rDma */ - bcmgenet_rdma_writel(priv, DMA_MAX_BURST_LENGTH, DMA_SCB_BURST_SIZE); - /* Init tDma */ bcmgenet_tdma_writel(priv, DMA_MAX_BURST_LENGTH, DMA_SCB_BURST_SIZE); -- GitLab From 11b3b45d69f1709aae6bb48b214064e22f0b5ef7 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Fri, 6 Mar 2015 22:23:51 -0800 Subject: [PATCH 03381/11651] net: dsa: mv88e6xxx: Add EEE support EEE configuration is similar for the various MV88E6xxx chips. Add generic support for it. Signed-off-by: Guenter Roeck Reviewed-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6xxx.c | 51 +++++++++++++++++++++++++++++++++++++ drivers/net/dsa/mv88e6xxx.h | 3 +++ 2 files changed, 54 insertions(+) diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c index a83ace0803e7..c18ffc98aacc 100644 --- a/drivers/net/dsa/mv88e6xxx.c +++ b/drivers/net/dsa/mv88e6xxx.c @@ -649,6 +649,57 @@ int mv88e6xxx_phy_write_indirect(struct dsa_switch *ds, int addr, int regnum, return mv88e6xxx_phy_wait(ds); } +int mv88e6xxx_get_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e) +{ + int reg; + + reg = mv88e6xxx_phy_read_indirect(ds, port, 16); + if (reg < 0) + return -EOPNOTSUPP; + + e->eee_enabled = !!(reg & 0x0200); + e->tx_lpi_enabled = !!(reg & 0x0100); + + reg = REG_READ(REG_PORT(port), 0); + e->eee_active = !!(reg & 0x0040); + + return 0; +} + +static int mv88e6xxx_eee_enable_set(struct dsa_switch *ds, int port, + bool eee_enabled, bool tx_lpi_enabled) +{ + int reg, nreg; + + reg = mv88e6xxx_phy_read_indirect(ds, port, 16); + if (reg < 0) + return reg; + + nreg = reg & ~0x0300; + if (eee_enabled) + nreg |= 0x0200; + if (tx_lpi_enabled) + nreg |= 0x0100; + + if (nreg != reg) + return mv88e6xxx_phy_write_indirect(ds, port, 16, nreg); + + return 0; +} + +int mv88e6xxx_set_eee(struct dsa_switch *ds, int port, + struct phy_device *phydev, struct ethtool_eee *e) +{ + int ret; + + ret = mv88e6xxx_eee_enable_set(ds, port, e->eee_enabled, + e->tx_lpi_enabled); + if (ret) + return -EOPNOTSUPP; + + return 0; +} + static int __init mv88e6xxx_init(void) { #if IS_ENABLED(CONFIG_NET_DSA_MV88E6131) diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h index 72942271bb67..5fd42ced9011 100644 --- a/drivers/net/dsa/mv88e6xxx.h +++ b/drivers/net/dsa/mv88e6xxx.h @@ -88,6 +88,9 @@ int mv88e6xxx_eeprom_busy_wait(struct dsa_switch *ds); int mv88e6xxx_phy_read_indirect(struct dsa_switch *ds, int addr, int regnum); int mv88e6xxx_phy_write_indirect(struct dsa_switch *ds, int addr, int regnum, u16 val); +int mv88e6xxx_get_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e); +int mv88e6xxx_set_eee(struct dsa_switch *ds, int port, + struct phy_device *phydev, struct ethtool_eee *e); extern struct dsa_switch_driver mv88e6131_switch_driver; extern struct dsa_switch_driver mv88e6123_61_65_switch_driver; -- GitLab From 04b0a80b57e9c45dd16c6dca7de892dac3812190 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Fri, 6 Mar 2015 22:23:52 -0800 Subject: [PATCH 03382/11651] net: dsa: mv88e6352: Add support for EEE Enable EEE support for MV88E6352. Signed-off-by: Guenter Roeck Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6352.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c index 1ebd8f96072a..7bc5998384c6 100644 --- a/drivers/net/dsa/mv88e6352.c +++ b/drivers/net/dsa/mv88e6352.c @@ -717,6 +717,8 @@ struct dsa_switch_driver mv88e6352_switch_driver = { .get_strings = mv88e6352_get_strings, .get_ethtool_stats = mv88e6352_get_ethtool_stats, .get_sset_count = mv88e6352_get_sset_count, + .set_eee = mv88e6xxx_set_eee, + .get_eee = mv88e6xxx_get_eee, #ifdef CONFIG_NET_DSA_HWMON .get_temp = mv88e6352_get_temp, .get_temp_limit = mv88e6352_get_temp_limit, -- GitLab From 5724be8464dceac047c1eaddaa3651cea0ec16ca Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Tue, 3 Mar 2015 11:27:23 +0100 Subject: [PATCH 03383/11651] irqchip: armada-370-xp: Fix chained per-cpu interrupts On the Cortex-A9-based Armada SoCs, the MPIC is not the primary interrupt controller. Yet, it still has to handle some per-cpu interrupt. To do so, it is chained with the GIC using a per-cpu interrupt. However, the current code only call irq_set_chained_handler, which is called and enable that interrupt only on the boot CPU, which means that the parent per-CPU interrupt is never unmasked on the secondary CPUs, preventing the per-CPU interrupt to actually work as expected. This was not seen until now since the only MPIC PPI users were the Marvell timers that were not working, but not used either since the system use the ARM TWD by default, and the ethernet controllers, that are faking there interrupts as SPI, and don't really expect to have interrupts on the secondary cores anyway. Add a CPU notifier that will enable the PPI on the secondary cores when they are brought up. Cc: # 3.15+ Signed-off-by: Maxime Ripard Acked-by: Gregory CLEMENT Link: https://lkml.kernel.org/r/1425378443-28822-1-git-send-email-maxime.ripard@free-electrons.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-armada-370-xp.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c index 463c235acbdc..4387dae14e45 100644 --- a/drivers/irqchip/irq-armada-370-xp.c +++ b/drivers/irqchip/irq-armada-370-xp.c @@ -69,6 +69,7 @@ static void __iomem *per_cpu_int_base; static void __iomem *main_int_base; static struct irq_domain *armada_370_xp_mpic_domain; static u32 doorbell_mask_reg; +static int parent_irq; #ifdef CONFIG_PCI_MSI static struct irq_domain *armada_370_xp_msi_domain; static DECLARE_BITMAP(msi_used, PCI_MSI_DOORBELL_NR); @@ -356,6 +357,7 @@ static int armada_xp_mpic_secondary_init(struct notifier_block *nfb, { if (action == CPU_STARTING || action == CPU_STARTING_FROZEN) armada_xp_mpic_smp_cpu_init(); + return NOTIFY_OK; } @@ -364,6 +366,20 @@ static struct notifier_block armada_370_xp_mpic_cpu_notifier = { .priority = 100, }; +static int mpic_cascaded_secondary_init(struct notifier_block *nfb, + unsigned long action, void *hcpu) +{ + if (action == CPU_STARTING || action == CPU_STARTING_FROZEN) + enable_percpu_irq(parent_irq, IRQ_TYPE_NONE); + + return NOTIFY_OK; +} + +static struct notifier_block mpic_cascaded_cpu_notifier = { + .notifier_call = mpic_cascaded_secondary_init, + .priority = 100, +}; + #endif /* CONFIG_SMP */ static struct irq_domain_ops armada_370_xp_mpic_irq_ops = { @@ -539,7 +555,7 @@ static int __init armada_370_xp_mpic_of_init(struct device_node *node, struct device_node *parent) { struct resource main_int_res, per_cpu_int_res; - int parent_irq, nr_irqs, i; + int nr_irqs, i; u32 control; BUG_ON(of_address_to_resource(node, 0, &main_int_res)); @@ -587,6 +603,9 @@ static int __init armada_370_xp_mpic_of_init(struct device_node *node, register_cpu_notifier(&armada_370_xp_mpic_cpu_notifier); #endif } else { +#ifdef CONFIG_SMP + register_cpu_notifier(&mpic_cascaded_cpu_notifier); +#endif irq_set_chained_handler(parent_irq, armada_370_xp_mpic_handle_cascade_irq); } -- GitLab From 0494e11aafc7855b1600fe19f04fadf682e52da9 Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Sun, 1 Mar 2015 23:41:27 +0100 Subject: [PATCH 03384/11651] irqchip: vf610-mscm-ir: Add support for Vybrid MSCM interrupt router This adds support for Vybrid's interrupt router. On VF6xx models, almost all peripherals can be used by either of the two CPU's, the Cortex-A5 or the Cortex-M4. The interrupt router routes the peripheral interrupts to the configured CPU. This IRQ chip driver configures the interrupt router to route the requested interrupt to the CPU the kernel is running on. The driver makes use of the irqdomain hierarchy support. The parent is given by the device tree. This should be one of the two possible parents either ARM GIC or the ARM NVIC interrupt controller. The latter is currently not yet supported. Note that there is no resource control mechnism implemented to avoid concurrent access of the same peripheral. The user needs to make sure to use device trees which assign the peripherals orthogonally. However, this driver warns the user in case the interrupt is already configured for the other CPU. This provides a poor man's resource controller. Acked-by: Marc Zyngier Signed-off-by: Stefan Agner Link: https://lkml.kernel.org/r/1425249689-32354-2-git-send-email-stefan@agner.ch Signed-off-by: Jason Cooper --- arch/arm/mach-imx/Kconfig | 1 + drivers/irqchip/Makefile | 1 + drivers/irqchip/irq-vf610-mscm-ir.c | 212 ++++++++++++++++++++++++++++ 3 files changed, 214 insertions(+) create mode 100644 drivers/irqchip/irq-vf610-mscm-ir.c diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index e8627e04e1e6..c8dffcee9736 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -631,6 +631,7 @@ config SOC_IMX6SX config SOC_VF610 bool "Vybrid Family VF610 support" + select IRQ_DOMAIN_HIERARCHY select ARM_GIC select PINCTRL_VF610 select PL310_ERRATA_769419 if CACHE_L2X0 diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index 42965d2476bb..9176c76eb164 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -37,6 +37,7 @@ obj-$(CONFIG_TB10X_IRQC) += irq-tb10x.o obj-$(CONFIG_XTENSA) += irq-xtensa-pic.o obj-$(CONFIG_XTENSA_MX) += irq-xtensa-mx.o obj-$(CONFIG_IRQ_CROSSBAR) += irq-crossbar.o +obj-$(CONFIG_SOC_VF610) += irq-vf610-mscm-ir.o obj-$(CONFIG_BCM7120_L2_IRQ) += irq-bcm7120-l2.o obj-$(CONFIG_BRCMSTB_L2_IRQ) += irq-brcmstb-l2.o obj-$(CONFIG_KEYSTONE_IRQ) += irq-keystone.o diff --git a/drivers/irqchip/irq-vf610-mscm-ir.c b/drivers/irqchip/irq-vf610-mscm-ir.c new file mode 100644 index 000000000000..9521057d4744 --- /dev/null +++ b/drivers/irqchip/irq-vf610-mscm-ir.c @@ -0,0 +1,212 @@ +/* + * Copyright (C) 2014-2015 Toradex AG + * Author: Stefan Agner + * + * 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. + * + * + * IRQ chip driver for MSCM interrupt router available on Vybrid SoC's. + * The interrupt router is between the CPU's interrupt controller and the + * peripheral. The router allows to route the peripheral interrupts to + * one of the two available CPU's on Vybrid VF6xx SoC's (Cortex-A5 or + * Cortex-M4). The router will be configured transparently on a IRQ + * request. + * + * o All peripheral interrupts of the Vybrid SoC can be routed to + * CPU 0, CPU 1 or both. The routing is useful for dual-core + * variants of Vybrid SoC such as VF6xx. This driver routes the + * requested interrupt to the CPU currently running on. + * + * o It is required to setup the interrupt router even on single-core + * variants of Vybrid. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "irqchip.h" + +#define MSCM_CPxNUM 0x4 + +#define MSCM_IRSPRC(n) (0x80 + 2 * (n)) +#define MSCM_IRSPRC_CPEN_MASK 0x3 + +#define MSCM_IRSPRC_NUM 112 + +struct vf610_mscm_ir_chip_data { + void __iomem *mscm_ir_base; + u16 cpu_mask; + u16 saved_irsprc[MSCM_IRSPRC_NUM]; +}; + +static struct vf610_mscm_ir_chip_data *mscm_ir_data; + +static inline void vf610_mscm_ir_save(struct vf610_mscm_ir_chip_data *data) +{ + int i; + + for (i = 0; i < MSCM_IRSPRC_NUM; i++) + data->saved_irsprc[i] = readw_relaxed(data->mscm_ir_base + MSCM_IRSPRC(i)); +} + +static inline void vf610_mscm_ir_restore(struct vf610_mscm_ir_chip_data *data) +{ + int i; + + for (i = 0; i < MSCM_IRSPRC_NUM; i++) + writew_relaxed(data->saved_irsprc[i], data->mscm_ir_base + MSCM_IRSPRC(i)); +} + +static int vf610_mscm_ir_notifier(struct notifier_block *self, + unsigned long cmd, void *v) +{ + switch (cmd) { + case CPU_CLUSTER_PM_ENTER: + vf610_mscm_ir_save(mscm_ir_data); + break; + case CPU_CLUSTER_PM_ENTER_FAILED: + case CPU_CLUSTER_PM_EXIT: + vf610_mscm_ir_restore(mscm_ir_data); + break; + } + + return NOTIFY_OK; +} + +static struct notifier_block mscm_ir_notifier_block = { + .notifier_call = vf610_mscm_ir_notifier, +}; + +static void vf610_mscm_ir_enable(struct irq_data *data) +{ + irq_hw_number_t hwirq = data->hwirq; + struct vf610_mscm_ir_chip_data *chip_data = data->chip_data; + u16 irsprc; + + irsprc = readw_relaxed(chip_data->mscm_ir_base + MSCM_IRSPRC(hwirq)); + irsprc &= MSCM_IRSPRC_CPEN_MASK; + + WARN_ON(irsprc & ~chip_data->cpu_mask); + + writew_relaxed(chip_data->cpu_mask, + chip_data->mscm_ir_base + MSCM_IRSPRC(hwirq)); + + irq_chip_unmask_parent(data); +} + +static void vf610_mscm_ir_disable(struct irq_data *data) +{ + irq_hw_number_t hwirq = data->hwirq; + struct vf610_mscm_ir_chip_data *chip_data = data->chip_data; + + writew_relaxed(0x0, chip_data->mscm_ir_base + MSCM_IRSPRC(hwirq)); + + irq_chip_mask_parent(data); +} + +static struct irq_chip vf610_mscm_ir_irq_chip = { + .name = "mscm-ir", + .irq_mask = irq_chip_mask_parent, + .irq_unmask = irq_chip_unmask_parent, + .irq_eoi = irq_chip_eoi_parent, + .irq_enable = vf610_mscm_ir_enable, + .irq_disable = vf610_mscm_ir_disable, + .irq_retrigger = irq_chip_retrigger_hierarchy, + .irq_set_affinity = irq_chip_set_affinity_parent, +}; + +static int vf610_mscm_ir_domain_alloc(struct irq_domain *domain, unsigned int virq, + unsigned int nr_irqs, void *arg) +{ + int i; + irq_hw_number_t hwirq; + struct of_phandle_args *irq_data = arg; + struct of_phandle_args gic_data; + + if (irq_data->args_count != 2) + return -EINVAL; + + hwirq = irq_data->args[0]; + for (i = 0; i < nr_irqs; i++) + irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i, + &vf610_mscm_ir_irq_chip, + domain->host_data); + + gic_data.np = domain->parent->of_node; + gic_data.args_count = 3; + gic_data.args[0] = GIC_SPI; + gic_data.args[1] = irq_data->args[0]; + gic_data.args[2] = irq_data->args[1]; + return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &gic_data); +} + +static const struct irq_domain_ops mscm_irq_domain_ops = { + .xlate = irq_domain_xlate_twocell, + .alloc = vf610_mscm_ir_domain_alloc, + .free = irq_domain_free_irqs_common, +}; + +static int __init vf610_mscm_ir_of_init(struct device_node *node, + struct device_node *parent) +{ + struct irq_domain *domain, *domain_parent; + struct regmap *mscm_cp_regmap; + int ret, cpuid; + + domain_parent = irq_find_host(parent); + if (!domain_parent) { + pr_err("vf610_mscm_ir: interrupt-parent not found\n"); + return -EINVAL; + } + + mscm_ir_data = kzalloc(sizeof(*mscm_ir_data), GFP_KERNEL); + if (!mscm_ir_data) + return -ENOMEM; + + mscm_ir_data->mscm_ir_base = of_io_request_and_map(node, 0, "mscm-ir"); + + if (!mscm_ir_data->mscm_ir_base) { + pr_err("vf610_mscm_ir: unable to map mscm register\n"); + ret = -ENOMEM; + goto out_free; + } + + mscm_cp_regmap = syscon_regmap_lookup_by_phandle(node, "fsl,cpucfg"); + if (IS_ERR(mscm_cp_regmap)) { + ret = PTR_ERR(mscm_cp_regmap); + pr_err("vf610_mscm_ir: regmap lookup for cpucfg failed\n"); + goto out_unmap; + } + + regmap_read(mscm_cp_regmap, MSCM_CPxNUM, &cpuid); + mscm_ir_data->cpu_mask = 0x1 << cpuid; + + domain = irq_domain_add_hierarchy(domain_parent, 0, + MSCM_IRSPRC_NUM, node, + &mscm_irq_domain_ops, mscm_ir_data); + if (!domain) { + ret = -ENOMEM; + goto out_unmap; + } + + cpu_pm_register_notifier(&mscm_ir_notifier_block); + + return 0; + +out_unmap: + iounmap(mscm_ir_data->mscm_ir_base); +out_free: + kfree(mscm_ir_data); + return ret; +} +IRQCHIP_DECLARE(vf610_mscm_ir, "fsl,vf610-mscm-ir", vf610_mscm_ir_of_init); -- GitLab From 4a073175392df3aa84fabca5a1bde47f36677d69 Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Sun, 1 Mar 2015 23:41:28 +0100 Subject: [PATCH 03385/11651] irqchip: vf610-mscm: Add Vybrid MSCM bindings Add binding documentation for CPU configuration and interrupt router submodule of the Miscellaneous System Control Module. The MSCM is used in all variants of Freescale Vybrid SoC's. Acked-by: Marc Zyngier Signed-off-by: Stefan Agner Link: https://lkml.kernel.org/r/1425249689-32354-3-git-send-email-stefan@agner.ch Signed-off-by: Jason Cooper --- .../arm/freescale/fsl,vf610-mscm-cpucfg.txt | 14 ++++++++ .../arm/freescale/fsl,vf610-mscm-ir.txt | 33 +++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 Documentation/devicetree/bindings/arm/freescale/fsl,vf610-mscm-cpucfg.txt create mode 100644 Documentation/devicetree/bindings/arm/freescale/fsl,vf610-mscm-ir.txt diff --git a/Documentation/devicetree/bindings/arm/freescale/fsl,vf610-mscm-cpucfg.txt b/Documentation/devicetree/bindings/arm/freescale/fsl,vf610-mscm-cpucfg.txt new file mode 100644 index 000000000000..44aa3c451ccf --- /dev/null +++ b/Documentation/devicetree/bindings/arm/freescale/fsl,vf610-mscm-cpucfg.txt @@ -0,0 +1,14 @@ +Freescale Vybrid Miscellaneous System Control - CPU Configuration + +The MSCM IP contains multiple sub modules, this binding describes the first +block of registers which contains CPU configuration information. + +Required properties: +- compatible: "fsl,vf610-mscm-cpucfg", "syscon" +- reg: the register range of the MSCM CPU configuration registers + +Example: + mscm_cpucfg: cpucfg@40001000 { + compatible = "fsl,vf610-mscm-cpucfg", "syscon"; + reg = <0x40001000 0x800>; + } diff --git a/Documentation/devicetree/bindings/arm/freescale/fsl,vf610-mscm-ir.txt b/Documentation/devicetree/bindings/arm/freescale/fsl,vf610-mscm-ir.txt new file mode 100644 index 000000000000..669808b2af49 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/freescale/fsl,vf610-mscm-ir.txt @@ -0,0 +1,33 @@ +Freescale Vybrid Miscellaneous System Control - Interrupt Router + +The MSCM IP contains multiple sub modules, this binding describes the second +block of registers which control the interrupt router. The interrupt router +allows to configure the recipient of each peripheral interrupt. Furthermore +it controls the directed processor interrupts. The module is available in all +Vybrid SoC's but is only really useful in dual core configurations (VF6xx +which comes with a Cortex-A5/Cortex-M4 combination). + +Required properties: +- compatible: "fsl,vf610-mscm-ir" +- reg: the register range of the MSCM Interrupt Router +- fsl,cpucfg: The handle to the MSCM CPU configuration node, required + to get the current CPU ID +- interrupt-controller: Identifies the node as an interrupt controller +- #interrupt-cells: Two cells, interrupt number and cells. + The hardware interrupt number according to interrupt + assignment of the interrupt router is required. + Flags get passed only when using GIC as parent. Flags + encoding as documented by the GIC bindings. +- interrupt-parent: Should be the phandle for the interrupt controller of + the CPU the device tree is intended to be used on. This + is either the node of the GIC or NVIC controller. + +Example: + mscm_ir: interrupt-controller@40001800 { + compatible = "fsl,vf610-mscm-ir"; + reg = <0x40001800 0x400>; + fsl,cpucfg = <&mscm_cpucfg>; + interrupt-controller; + #interrupt-cells = <2>; + interrupt-parent = <&intc>; + } -- GitLab From ceb5b6c8bee4841abac9e010c6069934d0f7c996 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 19 Feb 2015 16:22:31 -0800 Subject: [PATCH 03386/11651] Input: pwm-beeper - remove unneeded PWM_BEEPER_PM_OPS define The device->pm pointer is always present so there is no need to do tricks with conditionally defining the pointer. Signed-off-by: Dmitry Torokhov --- drivers/input/misc/pwm-beeper.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/input/misc/pwm-beeper.c b/drivers/input/misc/pwm-beeper.c index a28ee70ff158..a562071f6385 100644 --- a/drivers/input/misc/pwm-beeper.c +++ b/drivers/input/misc/pwm-beeper.c @@ -169,12 +169,6 @@ static int __maybe_unused pwm_beeper_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(pwm_beeper_pm_ops, pwm_beeper_suspend, pwm_beeper_resume); -#ifdef CONFIG_PM_SLEEP -#define PWM_BEEPER_PM_OPS (&pwm_beeper_pm_ops) -#else -#define PWM_BEEPER_PM_OPS NULL -#endif - #ifdef CONFIG_OF static const struct of_device_id pwm_beeper_match[] = { { .compatible = "pwm-beeper", }, @@ -187,7 +181,7 @@ static struct platform_driver pwm_beeper_driver = { .remove = pwm_beeper_remove, .driver = { .name = "pwm-beeper", - .pm = PWM_BEEPER_PM_OPS, + .pm = &pwm_beeper_pm_ops, .of_match_table = of_match_ptr(pwm_beeper_match), }, }; -- GitLab From b3beed7fe83b077291aa32d1f3006c8480f6344b Mon Sep 17 00:00:00 2001 From: Duson Lin Date: Sat, 7 Mar 2015 20:57:54 -0800 Subject: [PATCH 03387/11651] Input: elan_i2c - return error code when resume fails In order to better diagnose potential issues let's return error to the upper layers when resuming the device fails and also add a few diagnostic messages. Signed-off-by: Duson Lin Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/elan_i2c_core.c | 14 +++++++++----- drivers/input/mouse/elan_i2c_i2c.c | 10 +++++++++- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c index 7ce8bfe22d7e..b7535385fcdd 100644 --- a/drivers/input/mouse/elan_i2c_core.c +++ b/drivers/input/mouse/elan_i2c_core.c @@ -99,7 +99,7 @@ static int elan_enable_power(struct elan_tp_data *data) error = regulator_enable(data->vcc); if (error) { dev_err(&data->client->dev, - "Failed to enable regulator: %d\n", error); + "failed to enable regulator: %d\n", error); return error; } @@ -111,6 +111,7 @@ static int elan_enable_power(struct elan_tp_data *data) msleep(30); } while (--repeat > 0); + dev_err(&data->client->dev, "failed to enable power: %d\n", error); return error; } @@ -125,7 +126,7 @@ static int elan_disable_power(struct elan_tp_data *data) error = regulator_disable(data->vcc); if (error) { dev_err(&data->client->dev, - "Failed to disable regulator: %d\n", + "failed to disable regulator: %d\n", error); /* Attempt to power the chip back up */ data->ops->power_control(data->client, true); @@ -138,6 +139,7 @@ static int elan_disable_power(struct elan_tp_data *data) msleep(30); } while (--repeat > 0); + dev_err(&data->client->dev, "failed to disable power: %d\n", error); return error; } @@ -1084,16 +1086,18 @@ static int __maybe_unused elan_resume(struct device *dev) } error = elan_enable_power(data); - if (error) + if (error) { dev_err(dev, "power up when resuming failed: %d\n", error); + goto err; + } error = elan_initialize(data); if (error) dev_err(dev, "initialize when resuming failed: %d\n", error); +err: enable_irq(data->client->irq); - - return 0; + return error; } static SIMPLE_DEV_PM_OPS(elan_pm_ops, elan_suspend, elan_resume); diff --git a/drivers/input/mouse/elan_i2c_i2c.c b/drivers/input/mouse/elan_i2c_i2c.c index 029941f861af..6cf0def6d35e 100644 --- a/drivers/input/mouse/elan_i2c_i2c.c +++ b/drivers/input/mouse/elan_i2c_i2c.c @@ -117,7 +117,15 @@ static int elan_i2c_write_cmd(struct i2c_client *client, u16 reg, u16 cmd) int ret; ret = i2c_transfer(client->adapter, &msg, 1); - return ret == 1 ? 0 : (ret < 0 ? ret : -EIO); + if (ret != 1) { + if (ret >= 0) + ret = -EIO; + dev_err(&client->dev, "writing cmd (0x%04x) failed: %d\n", + reg, ret); + return ret; + } + + return 0; } static int elan_i2c_initialize(struct i2c_client *client) -- GitLab From 933a24b06b42617ef9fffece1857c5c4b23329aa Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Tue, 3 Mar 2015 11:43:14 +0100 Subject: [PATCH 03388/11651] irqchip: armada-370-xp: Initialize per cpu registers when CONFIG_SMP=N The irqchip driver called armada_xp_mpic_smp_cpu_init() when CONFIG_SMP=Y to initialize some per cpu registers. The function is called on each CPU by calling it explicitly on the boot CPU and then using a CPU notifier for the non boot CPUs. This commit removes the CONFIG_SMP constrain, so the per cpu registers are also initialized when CONFIG_SMP=N, which is the right thing to do. Signed-off-by: Ezequiel Garcia Signed-off-by: Maxime Ripard Acked-by: Gregory CLEMENT Link: https://lkml.kernel.org/r/1425379400-4346-2-git-send-email-maxime.ripard@free-electrons.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-armada-370-xp.c | 47 ++++++++++++++--------------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c index 4387dae14e45..b455c876974e 100644 --- a/drivers/irqchip/irq-armada-370-xp.c +++ b/drivers/irqchip/irq-armada-370-xp.c @@ -308,28 +308,6 @@ static int armada_370_xp_mpic_irq_map(struct irq_domain *h, return 0; } -#ifdef CONFIG_SMP -static void armada_mpic_send_doorbell(const struct cpumask *mask, - unsigned int irq) -{ - int cpu; - unsigned long map = 0; - - /* Convert our logical CPU mask into a physical one. */ - for_each_cpu(cpu, mask) - map |= 1 << cpu_logical_map(cpu); - - /* - * Ensure that stores to Normal memory are visible to the - * other CPUs before issuing the IPI. - */ - dsb(); - - /* submit softirq */ - writel((map << 8) | irq, main_int_base + - ARMADA_370_XP_SW_TRIG_INT_OFFS); -} - static void armada_xp_mpic_smp_cpu_init(void) { u32 control; @@ -352,6 +330,28 @@ static void armada_xp_mpic_smp_cpu_init(void) writel(0, per_cpu_int_base + ARMADA_370_XP_INT_CLEAR_MASK_OFFS); } +#ifdef CONFIG_SMP +static void armada_mpic_send_doorbell(const struct cpumask *mask, + unsigned int irq) +{ + int cpu; + unsigned long map = 0; + + /* Convert our logical CPU mask into a physical one. */ + for_each_cpu(cpu, mask) + map |= 1 << cpu_logical_map(cpu); + + /* + * Ensure that stores to Normal memory are visible to the + * other CPUs before issuing the IPI. + */ + dsb(); + + /* submit softirq */ + writel((map << 8) | irq, main_int_base + + ARMADA_370_XP_SW_TRIG_INT_OFFS); +} + static int armada_xp_mpic_secondary_init(struct notifier_block *nfb, unsigned long action, void *hcpu) { @@ -588,9 +588,8 @@ static int __init armada_370_xp_mpic_of_init(struct device_node *node, BUG_ON(!armada_370_xp_mpic_domain); -#ifdef CONFIG_SMP + /* Setup for the boot CPU */ armada_xp_mpic_smp_cpu_init(); -#endif armada_370_xp_msi_init(node, main_int_res.start); -- GitLab From 2c299de527ca2f39d231a257c00d09c498bb8447 Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Tue, 3 Mar 2015 11:43:15 +0100 Subject: [PATCH 03389/11651] irqchip: armada-370-xp: Introduce a is_percpu_irq() helper for readability This commit introduces a helper function is_percpu_irq(), to be used when interrupts are mapped to decide which ones are set as per CPU. This change will allow to extend the list of per cpu interrupts in a less intrusive fashion; also, it makes the code slightly more readable by keeping a list of the per CPU interrupts. Signed-off-by: Ezequiel Garcia Signed-off-by: Maxime Ripard Acked-by: Gregory CLEMENT Link: https://lkml.kernel.org/r/1425379400-4346-3-git-send-email-maxime.ripard@free-electrons.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-armada-370-xp.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c index b455c876974e..ea57fba263cf 100644 --- a/drivers/irqchip/irq-armada-370-xp.c +++ b/drivers/irqchip/irq-armada-370-xp.c @@ -77,6 +77,16 @@ static DEFINE_MUTEX(msi_used_lock); static phys_addr_t msi_doorbell_addr; #endif +static inline bool is_percpu_irq(irq_hw_number_t irq) +{ + switch (irq) { + case ARMADA_370_XP_TIMER0_PER_CPU_IRQ: + return true; + default: + return false; + } +} + /* * In SMP mode: * For shared global interrupts, mask/unmask global enable bit @@ -86,7 +96,7 @@ static void armada_370_xp_irq_mask(struct irq_data *d) { irq_hw_number_t hwirq = irqd_to_hwirq(d); - if (hwirq != ARMADA_370_XP_TIMER0_PER_CPU_IRQ) + if (!is_percpu_irq(hwirq)) writel(hwirq, main_int_base + ARMADA_370_XP_INT_CLEAR_ENABLE_OFFS); else @@ -98,7 +108,7 @@ static void armada_370_xp_irq_unmask(struct irq_data *d) { irq_hw_number_t hwirq = irqd_to_hwirq(d); - if (hwirq != ARMADA_370_XP_TIMER0_PER_CPU_IRQ) + if (!is_percpu_irq(hwirq)) writel(hwirq, main_int_base + ARMADA_370_XP_INT_SET_ENABLE_OFFS); else @@ -287,14 +297,14 @@ static int armada_370_xp_mpic_irq_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hw) { armada_370_xp_irq_mask(irq_get_irq_data(virq)); - if (hw != ARMADA_370_XP_TIMER0_PER_CPU_IRQ) + if (!is_percpu_irq(hw)) writel(hw, per_cpu_int_base + ARMADA_370_XP_INT_CLEAR_MASK_OFFS); else writel(hw, main_int_base + ARMADA_370_XP_INT_SET_ENABLE_OFFS); irq_set_status_flags(virq, IRQ_LEVEL); - if (hw == ARMADA_370_XP_TIMER0_PER_CPU_IRQ) { + if (is_percpu_irq(hw)) { irq_set_percpu_devid(virq); irq_set_chip_and_handler(virq, &armada_370_xp_irq_chip, handle_percpu_devid_irq); -- GitLab From 28da06dfd9e4b04577c517f9c4b52aaa73e3d1c7 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Tue, 3 Mar 2015 11:43:16 +0100 Subject: [PATCH 03390/11651] irqchip: armada-370-xp: Enable the PMU interrupts In order to let the Performance Monitoring Unit interrupts flowing in the MPIC, we need to unmask these interrupts in the Coherency Fabric Local Interrupt Mask Register. Since this register is a CPU-local register, unmasking this interrupt needs to be done on the boot CPU when the driver initializes, but also on the secondary CPU when they are brought up. Signed-off-by: Maxime Ripard Acked-by: Gregory CLEMENT Link: https://lkml.kernel.org/r/1425379400-4346-4-git-send-email-maxime.ripard@free-electrons.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-armada-370-xp.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c index ea57fba263cf..b36373c019ba 100644 --- a/drivers/irqchip/irq-armada-370-xp.c +++ b/drivers/irqchip/irq-armada-370-xp.c @@ -38,6 +38,8 @@ /* Interrupt Controller Registers Map */ #define ARMADA_370_XP_INT_SET_MASK_OFFS (0x48) #define ARMADA_370_XP_INT_CLEAR_MASK_OFFS (0x4C) +#define ARMADA_370_XP_INT_FABRIC_MASK_OFFS (0x54) +#define ARMADA_370_XP_INT_CAUSE_PERF(cpu) (1 << cpu) #define ARMADA_370_XP_INT_CONTROL (0x00) #define ARMADA_370_XP_INT_SET_ENABLE_OFFS (0x30) @@ -56,6 +58,7 @@ #define ARMADA_370_XP_MAX_PER_CPU_IRQS (28) #define ARMADA_370_XP_TIMER0_PER_CPU_IRQ (5) +#define ARMADA_370_XP_FABRIC_IRQ (3) #define IPI_DOORBELL_START (0) #define IPI_DOORBELL_END (8) @@ -81,6 +84,7 @@ static inline bool is_percpu_irq(irq_hw_number_t irq) { switch (irq) { case ARMADA_370_XP_TIMER0_PER_CPU_IRQ: + case ARMADA_370_XP_FABRIC_IRQ: return true; default: return false; @@ -340,6 +344,15 @@ static void armada_xp_mpic_smp_cpu_init(void) writel(0, per_cpu_int_base + ARMADA_370_XP_INT_CLEAR_MASK_OFFS); } +static void armada_xp_mpic_perf_init(void) +{ + unsigned long cpuid = cpu_logical_map(smp_processor_id()); + + /* Enable Performance Counter Overflow interrupts */ + writel(ARMADA_370_XP_INT_CAUSE_PERF(cpuid), + per_cpu_int_base + ARMADA_370_XP_INT_FABRIC_MASK_OFFS); +} + #ifdef CONFIG_SMP static void armada_mpic_send_doorbell(const struct cpumask *mask, unsigned int irq) @@ -365,8 +378,10 @@ static void armada_mpic_send_doorbell(const struct cpumask *mask, static int armada_xp_mpic_secondary_init(struct notifier_block *nfb, unsigned long action, void *hcpu) { - if (action == CPU_STARTING || action == CPU_STARTING_FROZEN) + if (action == CPU_STARTING || action == CPU_STARTING_FROZEN) { + armada_xp_mpic_perf_init(); armada_xp_mpic_smp_cpu_init(); + } return NOTIFY_OK; } @@ -379,8 +394,10 @@ static struct notifier_block armada_370_xp_mpic_cpu_notifier = { static int mpic_cascaded_secondary_init(struct notifier_block *nfb, unsigned long action, void *hcpu) { - if (action == CPU_STARTING || action == CPU_STARTING_FROZEN) + if (action == CPU_STARTING || action == CPU_STARTING_FROZEN) { + armada_xp_mpic_perf_init(); enable_percpu_irq(parent_irq, IRQ_TYPE_NONE); + } return NOTIFY_OK; } @@ -389,7 +406,6 @@ static struct notifier_block mpic_cascaded_cpu_notifier = { .notifier_call = mpic_cascaded_secondary_init, .priority = 100, }; - #endif /* CONFIG_SMP */ static struct irq_domain_ops armada_370_xp_mpic_irq_ops = { @@ -599,6 +615,7 @@ static int __init armada_370_xp_mpic_of_init(struct device_node *node, BUG_ON(!armada_370_xp_mpic_domain); /* Setup for the boot CPU */ + armada_xp_mpic_perf_init(); armada_xp_mpic_smp_cpu_init(); armada_370_xp_msi_init(node, main_int_res.start); -- GitLab From 16acae729564ee0c3918342d8556cc42eeb29942 Mon Sep 17 00:00:00 2001 From: Vladimir Murzin Date: Fri, 6 Mar 2015 16:37:40 +0000 Subject: [PATCH 03391/11651] irqchip: gicv3-its: Fix ITS CPU init We skip initialisation of ITS in case the device-tree has no corresponding description, but we are still accessing to ITS bits while setting CPU interface what leads to the kernel panic: ITS: No ITS available, not enabling LPIs CPU0: found redistributor 0 region 0:0x000000002f100000 Unable to handle kernel NULL pointer dereference at virtual address 00000000 pgd = ffffffc0007fb000 [00000000] *pgd=00000000fc407003, *pud=00000000fc407003, *pmd=00000000fc408003, *pte=006000002f000707 Internal error: Oops: 96000005 [#1] PREEMPT SMP Modules linked in: CPU: 0 PID: 0 Comm: swapper/0 Not tainted 3.19.0-rc2+ #318 Hardware name: FVP Base (DT) task: ffffffc00077edb0 ti: ffffffc00076c000 task.ti: ffffffc00076c000 PC is at its_cpu_init+0x2c/0x320 LR is at gic_cpu_init+0x168/0x1bc It happens in gic_rdists_supports_plpis() because gic_rdists is NULL. The gic_rdists is set to non-NULL only when ITS node is presented in the device-tree. Fix this by moving the call to gic_rdists_supports_plpis() inside the !list_empty(&its_nodes) block, because it is that list that guards the validity of the rest of the information in this driver. Acked-by: Marc Zyngier Signed-off-by: Vladimir Murzin Signed-off-by: Marc Zyngier Link: https://lkml.kernel.org/r/1425659870-11832-2-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-gic-v3-its.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index d8996bdf0f61..c217ebcf7a48 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -1382,12 +1382,11 @@ static bool gic_rdists_supports_plpis(void) int its_cpu_init(void) { - if (!gic_rdists_supports_plpis()) { - pr_info("CPU%d: LPIs not supported\n", smp_processor_id()); - return -ENXIO; - } - if (!list_empty(&its_nodes)) { + if (!gic_rdists_supports_plpis()) { + pr_info("CPU%d: LPIs not supported\n", smp_processor_id()); + return -ENXIO; + } its_cpu_init_lpis(); its_cpu_init_collection(); } -- GitLab From f54b97ed0b17d3da5f98ba8188cd5646415a922d Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Fri, 6 Mar 2015 16:37:41 +0000 Subject: [PATCH 03392/11651] irqchip: gicv3-its: Allocate enough memory for the full range of DeviceID The ITS table allocator is only allocating a single page per table. This works fine for most things, but leads to silent lack of interrupt delivery if we end-up with a device that has an ID that is out of the range defined by a single page of memory. Even worse, depending on the page size, behaviour changes, which is not a very good experience. A solution is actually to allocate memory for the full range of ID that the ITS supports. A massive waste memory wise, but at least a safe bet. Tested on a Phytium SoC. Tested-by: Chen Baozi Acked-by: Chen Baozi Signed-off-by: Marc Zyngier Link: https://lkml.kernel.org/r/1425659870-11832-3-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-gic-v3-its.c | 25 +++++++++++++++++++++---- include/linux/irqchip/arm-gic-v3.h | 2 ++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index c217ebcf7a48..733b32fda390 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -806,14 +806,31 @@ static int its_alloc_tables(struct its_node *its) u64 val = readq_relaxed(its->base + GITS_BASER + i * 8); u64 type = GITS_BASER_TYPE(val); u64 entry_size = GITS_BASER_ENTRY_SIZE(val); + int order = 0; + int alloc_size; u64 tmp; void *base; if (type == GITS_BASER_TYPE_NONE) continue; - /* We're lazy and only allocate a single page for now */ - base = (void *)get_zeroed_page(GFP_KERNEL); + /* + * Allocate as many entries as required to fit the + * range of device IDs that the ITS can grok... The ID + * space being incredibly sparse, this results in a + * massive waste of memory. + * + * For other tables, only allocate a single page. + */ + if (type == GITS_BASER_TYPE_DEVICE) { + u64 typer = readq_relaxed(its->base + GITS_TYPER); + u32 ids = GITS_TYPER_DEVBITS(typer); + + order = get_order((1UL << ids) * entry_size); + } + + alloc_size = (1 << order) * PAGE_SIZE; + base = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, order); if (!base) { err = -ENOMEM; goto out_free; @@ -841,7 +858,7 @@ retry_baser: break; } - val |= (PAGE_SIZE / psz) - 1; + val |= (alloc_size / psz) - 1; writeq_relaxed(val, its->base + GITS_BASER + i * 8); tmp = readq_relaxed(its->base + GITS_BASER + i * 8); @@ -882,7 +899,7 @@ retry_baser: } pr_info("ITS: allocated %d %s @%lx (psz %dK, shr %d)\n", - (int)(PAGE_SIZE / entry_size), + (int)(alloc_size / entry_size), its_base_type_string[type], (unsigned long)virt_to_phys(base), psz / SZ_1K, (int)shr >> GITS_BASER_SHAREABILITY_SHIFT); diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h index 800544bc7bfd..cbdd440d486d 100644 --- a/include/linux/irqchip/arm-gic-v3.h +++ b/include/linux/irqchip/arm-gic-v3.h @@ -166,6 +166,8 @@ #define GITS_TRANSLATER 0x10040 +#define GITS_TYPER_DEVBITS_SHIFT 13 +#define GITS_TYPER_DEVBITS(r) ((((r) >> GITS_TYPER_DEVBITS_SHIFT) & 0x1f) + 1) #define GITS_TYPER_PTA (1UL << 19) #define GITS_CBASER_VALID (1UL << 63) -- GitLab From e8137f4f5088d763ced1db82d3974336b76e1bd2 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Fri, 6 Mar 2015 16:37:42 +0000 Subject: [PATCH 03393/11651] irqchip: gicv3-its: Iterate over PCI aliases to generate ITS configuration The current PCI/MSI support in the GICv3 ITS doesn't really deal with systems where different PCI devices end-up using the same RequesterID (as it would be the case with non-transparent bridges, for example). It is likely that none of these devices would actually generate any interrupt, as the ITS is programmed with the device's own ID, and not that of the bridge. A solution to this is to iterate over the PCI hierarchy to discover what the device aliases too. We also use this to discover the upper bound of the number of MSIs that this sub-hierarchy can generate. With this in place, PCI aliases can be supported. Signed-off-by: Marc Zyngier Link: https://lkml.kernel.org/r/1425659870-11832-4-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-gic-v3-its.c | 54 +++++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 8 deletions(-) diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 733b32fda390..46b9441b36bd 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -1129,31 +1129,69 @@ static int its_alloc_device_irq(struct its_device *dev, irq_hw_number_t *hwirq) return 0; } +struct its_pci_alias { + struct pci_dev *pdev; + u32 dev_id; + u32 count; +}; + +static int its_pci_msi_vec_count(struct pci_dev *pdev) +{ + int msi, msix; + + msi = max(pci_msi_vec_count(pdev), 0); + msix = max(pci_msix_vec_count(pdev), 0); + + return max(msi, msix); +} + +static int its_get_pci_alias(struct pci_dev *pdev, u16 alias, void *data) +{ + struct its_pci_alias *dev_alias = data; + + dev_alias->dev_id = alias; + if (pdev != dev_alias->pdev) + dev_alias->count += its_pci_msi_vec_count(dev_alias->pdev); + + return 0; +} + static int its_msi_prepare(struct irq_domain *domain, struct device *dev, int nvec, msi_alloc_info_t *info) { struct pci_dev *pdev; struct its_node *its; - u32 dev_id; struct its_device *its_dev; + struct its_pci_alias dev_alias; if (!dev_is_pci(dev)) return -EINVAL; pdev = to_pci_dev(dev); - dev_id = PCI_DEVID(pdev->bus->number, pdev->devfn); + dev_alias.pdev = pdev; + dev_alias.count = nvec; + + pci_for_each_dma_alias(pdev, its_get_pci_alias, &dev_alias); its = domain->parent->host_data; - its_dev = its_find_device(its, dev_id); - if (WARN_ON(its_dev)) - return -EINVAL; + its_dev = its_find_device(its, dev_alias.dev_id); + if (its_dev) { + /* + * We already have seen this ID, probably through + * another alias (PCI bridge of some sort). No need to + * create the device. + */ + dev_dbg(dev, "Reusing ITT for devID %x\n", dev_alias.dev_id); + goto out; + } - its_dev = its_create_device(its, dev_id, nvec); + its_dev = its_create_device(its, dev_alias.dev_id, dev_alias.count); if (!its_dev) return -ENOMEM; - dev_dbg(&pdev->dev, "ITT %d entries, %d bits\n", nvec, ilog2(nvec)); - + dev_dbg(&pdev->dev, "ITT %d entries, %d bits\n", + dev_alias.count, ilog2(dev_alias.count)); +out: info->scratchpad[0].ptr = its_dev; info->scratchpad[1].ptr = dev; return 0; -- GitLab From 3e39e8f56c1c67cdd1e8f06da0d6b7c831818c76 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Fri, 6 Mar 2015 16:37:43 +0000 Subject: [PATCH 03394/11651] irqchip: gicv3-its: Fix unsafe locking reported by lockdep When compiled with CONFIG_LOCKDEP, the kernel shouts badly, saying that my locking is unsafe. I'm afraid the kernel is right: CPU0 CPU1 ---- ---- lock(&its->lock); local_irq_disable(); lock(&irq_desc_lock_class); lock(&its->lock); lock(&irq_desc_lock_class); *** DEADLOCK *** The fix is to always take its->lock with interrupts disabled. Reported-by: Will Deacon Signed-off-by: Marc Zyngier Link: https://lkml.kernel.org/r/1425659870-11832-5-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-gic-v3-its.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 46b9441b36bd..6850141d6524 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -416,13 +416,14 @@ static void its_send_single_command(struct its_node *its, { struct its_cmd_block *cmd, *sync_cmd, *next_cmd; struct its_collection *sync_col; + unsigned long flags; - raw_spin_lock(&its->lock); + raw_spin_lock_irqsave(&its->lock, flags); cmd = its_allocate_entry(its); if (!cmd) { /* We're soooooo screewed... */ pr_err_ratelimited("ITS can't allocate, dropping command\n"); - raw_spin_unlock(&its->lock); + raw_spin_unlock_irqrestore(&its->lock, flags); return; } sync_col = builder(cmd, desc); @@ -442,7 +443,7 @@ static void its_send_single_command(struct its_node *its, post: next_cmd = its_post_commands(its); - raw_spin_unlock(&its->lock); + raw_spin_unlock_irqrestore(&its->lock, flags); its_wait_for_range_completion(its, cmd, next_cmd); } @@ -1037,8 +1038,9 @@ static void its_cpu_init_collection(void) static struct its_device *its_find_device(struct its_node *its, u32 dev_id) { struct its_device *its_dev = NULL, *tmp; + unsigned long flags; - raw_spin_lock(&its->lock); + raw_spin_lock_irqsave(&its->lock, flags); list_for_each_entry(tmp, &its->its_device_list, entry) { if (tmp->device_id == dev_id) { @@ -1047,7 +1049,7 @@ static struct its_device *its_find_device(struct its_node *its, u32 dev_id) } } - raw_spin_unlock(&its->lock); + raw_spin_unlock_irqrestore(&its->lock, flags); return its_dev; } @@ -1057,6 +1059,7 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id, { struct its_device *dev; unsigned long *lpi_map; + unsigned long flags; void *itt; int lpi_base; int nr_lpis; @@ -1092,9 +1095,9 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id, dev->device_id = dev_id; INIT_LIST_HEAD(&dev->entry); - raw_spin_lock(&its->lock); + raw_spin_lock_irqsave(&its->lock, flags); list_add(&dev->entry, &its->its_device_list); - raw_spin_unlock(&its->lock); + raw_spin_unlock_irqrestore(&its->lock, flags); /* Bind the device to the first possible CPU */ cpu = cpumask_first(cpu_online_mask); @@ -1108,9 +1111,11 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id, static void its_free_device(struct its_device *its_dev) { - raw_spin_lock(&its_dev->its->lock); + unsigned long flags; + + raw_spin_lock_irqsave(&its_dev->its->lock, flags); list_del(&its_dev->entry); - raw_spin_unlock(&its_dev->its->lock); + raw_spin_unlock_irqrestore(&its_dev->its->lock, flags); kfree(its_dev->itt); kfree(its_dev); } -- GitLab From cf613871946230c5dd8178d07bcdc2984f4545cd Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Fri, 6 Mar 2015 16:37:44 +0000 Subject: [PATCH 03395/11651] irqchip: gic: Fix unsafe locking reported by lockdep When compiled with CONFIG_LOCKDEP, the kernel shouts badly, saying that the locking in the GIC code is unsafe. I'm afraid the kernel is right: CPU0 ---- lock(irq_controller_lock); lock(irq_controller_lock); *** DEADLOCK *** This can happen while enabling, disabling, setting the type or the affinity of an interrupt. The fix is to take the interrupt_controller_lock with interrupts disabled in these cases. Signed-off-by: Marc Zyngier Link: https://lkml.kernel.org/r/1425659870-11832-6-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-gic.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 4634cf7d0ec3..471e1cdc1933 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -154,23 +154,25 @@ static inline unsigned int gic_irq(struct irq_data *d) static void gic_mask_irq(struct irq_data *d) { u32 mask = 1 << (gic_irq(d) % 32); + unsigned long flags; - raw_spin_lock(&irq_controller_lock); + raw_spin_lock_irqsave(&irq_controller_lock, flags); writel_relaxed(mask, gic_dist_base(d) + GIC_DIST_ENABLE_CLEAR + (gic_irq(d) / 32) * 4); if (gic_arch_extn.irq_mask) gic_arch_extn.irq_mask(d); - raw_spin_unlock(&irq_controller_lock); + raw_spin_unlock_irqrestore(&irq_controller_lock, flags); } static void gic_unmask_irq(struct irq_data *d) { u32 mask = 1 << (gic_irq(d) % 32); + unsigned long flags; - raw_spin_lock(&irq_controller_lock); + raw_spin_lock_irqsave(&irq_controller_lock, flags); if (gic_arch_extn.irq_unmask) gic_arch_extn.irq_unmask(d); writel_relaxed(mask, gic_dist_base(d) + GIC_DIST_ENABLE_SET + (gic_irq(d) / 32) * 4); - raw_spin_unlock(&irq_controller_lock); + raw_spin_unlock_irqrestore(&irq_controller_lock, flags); } static void gic_eoi_irq(struct irq_data *d) @@ -188,6 +190,7 @@ static int gic_set_type(struct irq_data *d, unsigned int type) { void __iomem *base = gic_dist_base(d); unsigned int gicirq = gic_irq(d); + unsigned long flags; int ret; /* Interrupt configuration for SGIs can't be changed */ @@ -199,14 +202,14 @@ static int gic_set_type(struct irq_data *d, unsigned int type) type != IRQ_TYPE_EDGE_RISING) return -EINVAL; - raw_spin_lock(&irq_controller_lock); + raw_spin_lock_irqsave(&irq_controller_lock, flags); if (gic_arch_extn.irq_set_type) gic_arch_extn.irq_set_type(d, type); ret = gic_configure_irq(gicirq, type, base, NULL); - raw_spin_unlock(&irq_controller_lock); + raw_spin_unlock_irqrestore(&irq_controller_lock, flags); return ret; } @@ -227,6 +230,7 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val, void __iomem *reg = gic_dist_base(d) + GIC_DIST_TARGET + (gic_irq(d) & ~3); unsigned int cpu, shift = (gic_irq(d) % 4) * 8; u32 val, mask, bit; + unsigned long flags; if (!force) cpu = cpumask_any_and(mask_val, cpu_online_mask); @@ -236,12 +240,12 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val, if (cpu >= NR_GIC_CPU_IF || cpu >= nr_cpu_ids) return -EINVAL; - raw_spin_lock(&irq_controller_lock); + raw_spin_lock_irqsave(&irq_controller_lock, flags); mask = 0xff << shift; bit = gic_cpu_map[cpu] << shift; val = readl_relaxed(reg) & ~mask; writel_relaxed(val | bit, reg); - raw_spin_unlock(&irq_controller_lock); + raw_spin_unlock_irqrestore(&irq_controller_lock, flags); return IRQ_SET_MASK_OK; } -- GitLab From 614be385521b08b849da1098625da591984738c0 Mon Sep 17 00:00:00 2001 From: Vladimir Murzin Date: Fri, 6 Mar 2015 16:37:45 +0000 Subject: [PATCH 03396/11651] irqchip: gic-v3: Fix out of bounds access to cpu_logical_map While playing with KASan support for arm64/arm the following appeared on boot: ================================================================== BUG: AddressSanitizer: out of bounds access in __asan_load8+0x14/0x1c at addr ffffffc000ad0dc0 Read of size 8 by task swapper/0/1 page:ffffffbdc202b400 count:1 mapcount:0 mapping: (null) index:0x0 flags: 0x400(reserved) page dumped because: kasan: bad access detected Address belongs to variable __cpu_logical_map+0x200/0x220 CPU: 2 PID: 1 Comm: swapper/0 Not tainted 3.19.0-rc6-next-20150129+ #481 Hardware name: FVP Base (DT) Call trace: [] dump_backtrace+0x0/0x184 [] show_stack+0x10/0x1c [] dump_stack+0xa0/0xf8 [] kasan_report_error+0x23c/0x264 [] check_memory_region+0xc0/0xe4 [] __asan_load8+0x10/0x1c [] gic_raise_softirq+0xc4/0x1b4 [] smp_send_reschedule+0x30/0x3c [] try_to_wake_up+0x394/0x434 [] wake_up_process+0x2c/0x6c [] wake_up_worker+0x38/0x48 [] insert_work+0xac/0xec [] __queue_work+0x1a8/0x374 [] queue_work_on+0x5c/0x7c [] call_usermodehelper_exec+0x170/0x188 [] kobject_uevent_env+0x650/0x6bc [] kobject_uevent+0xc/0x18 [] kset_register+0xa8/0xc8 [] bus_register+0x134/0x2e8 [] subsys_virtual_register+0x2c/0x5c [] wq_sysfs_init+0x14/0x20 [] do_one_initcall+0xa8/0x1fc [] kernel_init_freeable+0x1ec/0x294 [] kernel_init+0xc/0xec Memory state around the buggy address: ffffff80003e0820: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ffffff80003e0830: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 >ffffff80003e0840: fa fa fa fa 00 00 00 00 00 00 00 00 00 00 00 00 ^ ffffff80003e0850: 00 00 fa fa fa fa fa fa 00 00 00 00 00 00 00 00 ================================================================== The reason for that cpumask_next() returns >= nr_cpu_ids if no further cpus set, but "==" condition is checked only, so we end up with out-of-bounds access to cpu_logical_map. Fix is by using the condition check for cpumask_next. Signed-off-by: Vladimir Murzin Signed-off-by: Marc Zyngier Link: https://lkml.kernel.org/r/1425659870-11832-7-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-gic-v3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index 1c6dea2fbc34..fd8850def1b8 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -466,7 +466,7 @@ static u16 gic_compute_target_list(int *base_cpu, const struct cpumask *mask, tlist |= 1 << (mpidr & 0xf); cpu = cpumask_next(cpu, mask); - if (cpu == nr_cpu_ids) + if (cpu >= nr_cpu_ids) goto out; mpidr = cpu_logical_map(cpu); -- GitLab From 6c834125ba460eb1eea63bcc053b45564ca93407 Mon Sep 17 00:00:00 2001 From: Yun Wu Date: Fri, 6 Mar 2015 16:37:46 +0000 Subject: [PATCH 03397/11651] irqchip: gicv3-its: Zero itt before handling to hardware Some kind of brain-dead implementations chooses to insert ITEes in rapid sequence of disabled ITEes, and an un-zeroed ITT will confuse ITS on judging whether an ITE is really enabled or not. Considering the implementations are still supported by the GICv3 architecture, in which ITT is not required to be zeroed before being handled to hardware, we do the favor in ITS driver. Acked-by: Marc Zyngier Signed-off-by: Yun Wu Signed-off-by: Marc Zyngier Link: https://lkml.kernel.org/r/1425659870-11832-8-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-gic-v3-its.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 6850141d6524..69eeea3e7fac 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -1076,7 +1076,7 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id, nr_ites = max(2UL, roundup_pow_of_two(nvecs)); sz = nr_ites * its->ite_size; sz = max(sz, ITS_ITT_ALIGN) + ITS_ITT_ALIGN - 1; - itt = kmalloc(sz, GFP_KERNEL); + itt = kzalloc(sz, GFP_KERNEL); lpi_map = its_lpi_alloc_chunks(nvecs, &lpi_base, &nr_lpis); if (!dev || !itt || !lpi_map) { -- GitLab From 790b57aed156d22d6c7101a37adc78a621be1167 Mon Sep 17 00:00:00 2001 From: Yun Wu Date: Fri, 6 Mar 2015 16:37:47 +0000 Subject: [PATCH 03398/11651] irqchip: gicv3-its: Use 64KB page as default granule The field of page size in register GITS_BASERn might be read-only if an implementation only supports a single, fixed page size. But currently the ITS driver will throw out an error when PAGE_SIZE is less than the minimum size supported by an ITS. So addressing this problem by using 64KB pages as default granule for all the ITS base tables. Acked-by: Marc Zyngier [maz: fixed bug breaking non Device Table allocations] Signed-off-by: Yun Wu Signed-off-by: Marc Zyngier Link: https://lkml.kernel.org/r/1425659870-11832-9-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-gic-v3-its.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 69eeea3e7fac..0fe25a97a5a9 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -800,14 +800,14 @@ static int its_alloc_tables(struct its_node *its) { int err; int i; - int psz = PAGE_SIZE; + int psz = SZ_64K; u64 shr = GITS_BASER_InnerShareable; for (i = 0; i < GITS_BASER_NR_REGS; i++) { u64 val = readq_relaxed(its->base + GITS_BASER + i * 8); u64 type = GITS_BASER_TYPE(val); u64 entry_size = GITS_BASER_ENTRY_SIZE(val); - int order = 0; + int order = get_order(psz); int alloc_size; u64 tmp; void *base; -- GitLab From 1d27704a26313b9ed7463d4bfc6eda29e2bb3180 Mon Sep 17 00:00:00 2001 From: Yun Wu Date: Fri, 6 Mar 2015 16:37:48 +0000 Subject: [PATCH 03399/11651] irqchip: gicv3-its: Add limitation to page order When required size of Device Table is out of the page allocator's capability, the whole ITS will fail in probing. This actually is not the hardware's problem and is mainly a limitation of the kernel page allocator. This patch will keep ITS going on to the next initializaion stage with an explicit warning. Acked-by: Marc Zyngier Signed-off-by: Yun Wu Signed-off-by: Marc Zyngier Link: https://lkml.kernel.org/r/1425659870-11832-10-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-gic-v3-its.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 0fe25a97a5a9..ec20d4a942e0 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -828,6 +828,11 @@ static int its_alloc_tables(struct its_node *its) u32 ids = GITS_TYPER_DEVBITS(typer); order = get_order((1UL << ids) * entry_size); + if (order >= MAX_ORDER) { + order = MAX_ORDER - 1; + pr_warn("%s: Device Table too large, reduce its page order to %u\n", + its->msi_chip.of_node->full_name, order); + } } alloc_size = (1 << order) * PAGE_SIZE; -- GitLab From 7cb991164a46992a499ecdc77b17f8ac94bdb75f Mon Sep 17 00:00:00 2001 From: Yun Wu Date: Fri, 6 Mar 2015 16:37:49 +0000 Subject: [PATCH 03400/11651] irqchip: gicv3-its: Define macros for GITS_CTLR fields Define macros for GITS_CTLR fields to avoid using magic numbers. Acked-by: Marc Zyngier Signed-off-by: Yun Wu Signed-off-by: Marc Zyngier Link: https://lkml.kernel.org/r/1425659870-11832-11-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-gic-v3-its.c | 2 +- include/linux/irqchip/arm-gic-v3.h | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index ec20d4a942e0..826da706be4b 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -1388,7 +1388,7 @@ static int its_probe(struct device_node *node, struct irq_domain *parent) writeq_relaxed(baser, its->base + GITS_CBASER); tmp = readq_relaxed(its->base + GITS_CBASER); writeq_relaxed(0, its->base + GITS_CWRITER); - writel_relaxed(1, its->base + GITS_CTLR); + writel_relaxed(GITS_CTLR_ENABLE, its->base + GITS_CTLR); if ((tmp ^ baser) & GITS_BASER_SHAREABILITY_MASK) { pr_info("ITS: using cache flushing for cmd queue\n"); diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h index cbdd440d486d..781974afff9f 100644 --- a/include/linux/irqchip/arm-gic-v3.h +++ b/include/linux/irqchip/arm-gic-v3.h @@ -166,6 +166,9 @@ #define GITS_TRANSLATER 0x10040 +#define GITS_CTLR_ENABLE (1U << 0) +#define GITS_CTLR_QUIESCENT (1U << 31) + #define GITS_TYPER_DEVBITS_SHIFT 13 #define GITS_TYPER_DEVBITS(r) ((((r) >> GITS_TYPER_DEVBITS_SHIFT) & 0x1f) + 1) #define GITS_TYPER_PTA (1UL << 19) -- GitLab From 4559fbb3a9b1bde46afc739fa6c300826acdc19c Mon Sep 17 00:00:00 2001 From: Yun Wu Date: Fri, 6 Mar 2015 16:37:50 +0000 Subject: [PATCH 03401/11651] irqchip: gicv3-its: Support safe initialization It's unsafe to change the configurations of an activated ITS directly since this will lead to unpredictable results. This patch guarantees the ITSes being initialized are quiescent. Acked-by: Marc Zyngier Signed-off-by: Yun Wu Signed-off-by: Marc Zyngier Link: https://lkml.kernel.org/r/1425659870-11832-12-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-gic-v3-its.c | 35 ++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 826da706be4b..596b0a9eee99 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -1320,6 +1320,34 @@ static const struct irq_domain_ops its_domain_ops = { .deactivate = its_irq_domain_deactivate, }; +static int its_force_quiescent(void __iomem *base) +{ + u32 count = 1000000; /* 1s */ + u32 val; + + val = readl_relaxed(base + GITS_CTLR); + if (val & GITS_CTLR_QUIESCENT) + return 0; + + /* Disable the generation of all interrupts to this ITS */ + val &= ~GITS_CTLR_ENABLE; + writel_relaxed(val, base + GITS_CTLR); + + /* Poll GITS_CTLR and wait until ITS becomes quiescent */ + while (1) { + val = readl_relaxed(base + GITS_CTLR); + if (val & GITS_CTLR_QUIESCENT) + return 0; + + count--; + if (!count) + return -EBUSY; + + cpu_relax(); + udelay(1); + } +} + static int its_probe(struct device_node *node, struct irq_domain *parent) { struct resource res; @@ -1348,6 +1376,13 @@ static int its_probe(struct device_node *node, struct irq_domain *parent) goto out_unmap; } + err = its_force_quiescent(its_base); + if (err) { + pr_warn("%s: failed to quiesce, giving up\n", + node->full_name); + goto out_unmap; + } + pr_info("ITS: %s\n", node->full_name); its = kzalloc(sizeof(*its), GFP_KERNEL); -- GitLab From b5c4437872de508073355e927b1fcdba4980cba7 Mon Sep 17 00:00:00 2001 From: Tolga Ceylan Date: Sat, 14 Feb 2015 20:32:43 -0800 Subject: [PATCH 03402/11651] Staging: iio: meter: ade7854-i2c: code style improvements Code reformatting based on checkpatch.pl with --strict: Alignment should match open paranthesis cases corrected Signed-off-by: Tolga Ceylan Signed-off-by: Jonathan Cameron --- drivers/staging/iio/meter/ade7854-i2c.c | 34 ++++++++++++------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/staging/iio/meter/ade7854-i2c.c b/drivers/staging/iio/meter/ade7854-i2c.c index 5d0671a198fe..5e6fbe4c976a 100644 --- a/drivers/staging/iio/meter/ade7854-i2c.c +++ b/drivers/staging/iio/meter/ade7854-i2c.c @@ -16,8 +16,8 @@ #include "ade7854.h" static int ade7854_i2c_write_reg_8(struct device *dev, - u16 reg_address, - u8 value) + u16 reg_address, + u8 value) { int ret; struct iio_dev *indio_dev = dev_to_iio_dev(dev); @@ -35,8 +35,8 @@ static int ade7854_i2c_write_reg_8(struct device *dev, } static int ade7854_i2c_write_reg_16(struct device *dev, - u16 reg_address, - u16 value) + u16 reg_address, + u16 value) { int ret; struct iio_dev *indio_dev = dev_to_iio_dev(dev); @@ -55,8 +55,8 @@ static int ade7854_i2c_write_reg_16(struct device *dev, } static int ade7854_i2c_write_reg_24(struct device *dev, - u16 reg_address, - u32 value) + u16 reg_address, + u32 value) { int ret; struct iio_dev *indio_dev = dev_to_iio_dev(dev); @@ -76,8 +76,8 @@ static int ade7854_i2c_write_reg_24(struct device *dev, } static int ade7854_i2c_write_reg_32(struct device *dev, - u16 reg_address, - u32 value) + u16 reg_address, + u32 value) { int ret; struct iio_dev *indio_dev = dev_to_iio_dev(dev); @@ -98,8 +98,8 @@ static int ade7854_i2c_write_reg_32(struct device *dev, } static int ade7854_i2c_read_reg_8(struct device *dev, - u16 reg_address, - u8 *val) + u16 reg_address, + u8 *val) { struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7854_state *st = iio_priv(indio_dev); @@ -124,8 +124,8 @@ out: } static int ade7854_i2c_read_reg_16(struct device *dev, - u16 reg_address, - u16 *val) + u16 reg_address, + u16 *val) { struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7854_state *st = iio_priv(indio_dev); @@ -150,8 +150,8 @@ out: } static int ade7854_i2c_read_reg_24(struct device *dev, - u16 reg_address, - u32 *val) + u16 reg_address, + u32 *val) { struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7854_state *st = iio_priv(indio_dev); @@ -176,8 +176,8 @@ out: } static int ade7854_i2c_read_reg_32(struct device *dev, - u16 reg_address, - u32 *val) + u16 reg_address, + u32 *val) { struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7854_state *st = iio_priv(indio_dev); @@ -203,7 +203,7 @@ out: } static int ade7854_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) + const struct i2c_device_id *id) { int ret; struct ade7854_state *st; -- GitLab From 21bd23ea128d083bf8a4fd570a66a128d58465b5 Mon Sep 17 00:00:00 2001 From: Tolga Ceylan Date: Sat, 14 Feb 2015 20:32:45 -0800 Subject: [PATCH 03403/11651] Staging: iio: meter: ade7854-i2c: code style improvements Code reformatting based on checkpatch.pl with --strict: Comparison to NULL rewritten as !indio_dev Signed-off-by: Tolga Ceylan Signed-off-by: Jonathan Cameron --- drivers/staging/iio/meter/ade7854-i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/iio/meter/ade7854-i2c.c b/drivers/staging/iio/meter/ade7854-i2c.c index 5e6fbe4c976a..4e7a3829ea55 100644 --- a/drivers/staging/iio/meter/ade7854-i2c.c +++ b/drivers/staging/iio/meter/ade7854-i2c.c @@ -210,7 +210,7 @@ static int ade7854_i2c_probe(struct i2c_client *client, struct iio_dev *indio_dev; indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*st)); - if (indio_dev == NULL) + if (!indio_dev) return -ENOMEM; st = iio_priv(indio_dev); i2c_set_clientdata(client, indio_dev); -- GitLab From 1ec28ce66aa4b0f7aaab0d496ee293ff2a52dd20 Mon Sep 17 00:00:00 2001 From: Kevin Tsai Date: Thu, 19 Feb 2015 15:02:51 -0800 Subject: [PATCH 03404/11651] iio: light: Added PM support for Capella CM3232 ambient light sensor driver. Added Power Management Support. Signed-off-by: Kevin Tsai Signed-off-by: Jonathan Cameron --- drivers/iio/light/cm3232.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/drivers/iio/light/cm3232.c b/drivers/iio/light/cm3232.c index 90e3519a91de..39c8d99cc48e 100644 --- a/drivers/iio/light/cm3232.c +++ b/drivers/iio/light/cm3232.c @@ -378,6 +378,39 @@ static const struct i2c_device_id cm3232_id[] = { {} }; +#ifdef CONFIG_PM_SLEEP +static int cm3232_suspend(struct device *dev) +{ + struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); + struct cm3232_chip *chip = iio_priv(indio_dev); + struct i2c_client *client = chip->client; + int ret; + + chip->regs_cmd |= CM3232_CMD_ALS_DISABLE; + ret = i2c_smbus_write_byte_data(client, CM3232_REG_ADDR_CMD, + chip->regs_cmd); + + return ret; +} + +static int cm3232_resume(struct device *dev) +{ + struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); + struct cm3232_chip *chip = iio_priv(indio_dev); + struct i2c_client *client = chip->client; + int ret; + + chip->regs_cmd &= ~CM3232_CMD_ALS_DISABLE; + ret = i2c_smbus_write_byte_data(client, CM3232_REG_ADDR_CMD, + chip->regs_cmd | CM3232_CMD_ALS_RESET); + + return ret; +} + +static const struct dev_pm_ops cm3232_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(cm3232_suspend, cm3232_resume)}; +#endif + MODULE_DEVICE_TABLE(i2c, cm3232_id); static const struct of_device_id cm3232_of_match[] = { @@ -390,6 +423,9 @@ static struct i2c_driver cm3232_driver = { .name = "cm3232", .owner = THIS_MODULE, .of_match_table = of_match_ptr(cm3232_of_match), +#ifdef CONFIG_PM_SLEEP + .pm = &cm3232_pm_ops, +#endif }, .id_table = cm3232_id, .probe = cm3232_probe, -- GitLab From d4461a602cf39c59f32817162539f4e723621865 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 3 Mar 2015 08:39:34 +0000 Subject: [PATCH 03405/11651] gadgetfs: get rid of flipping ->f_op in ep_config() Final methods start with get_ready_ep(), which will fail unless we have ->state == STATE_EP_ENABLED. So they'd be failing just fine until that first write() anyway. Let's do the following: * get_ready_ep() gets a new argument - true when called from ep_write_iter(), false otherwise. * make it quiet when it finds STATE_EP_READY (no printk, that is; the case won't be impossible after that change). * when that new argument is true, treat STATE_EP_READY the same way as STATE_EP_ENABLED (i.e. return zero and do not unlock). * in ep_write_iter(), after success of get_ready_ep() turn if (!usb_endpoint_dir_in(&epdata->desc)) { into if (epdata->state == STATE_EP_ENABLED && !usb_endpoint_dir_in(&epdata->desc)) { - that logics only applies after config. * have ep_config() take kernel-side buffer (i.e. use memcpy() instead of copy_from_user() in there) and in the "let's call ep_io or ep_aio" (again, in ep_write_iter()) add "... or ep_config() in case it's not configured yet" Signed-off-by: Al Viro --- drivers/usb/gadget/legacy/inode.c | 90 +++++++++++++------------------ 1 file changed, 37 insertions(+), 53 deletions(-) diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c index b825edcbf387..c0e25320a3c4 100644 --- a/drivers/usb/gadget/legacy/inode.c +++ b/drivers/usb/gadget/legacy/inode.c @@ -74,6 +74,8 @@ MODULE_DESCRIPTION (DRIVER_DESC); MODULE_AUTHOR ("David Brownell"); MODULE_LICENSE ("GPL"); +static int ep_open(struct inode *, struct file *); + /*----------------------------------------------------------------------*/ @@ -283,14 +285,15 @@ static void epio_complete (struct usb_ep *ep, struct usb_request *req) * still need dev->lock to use epdata->ep. */ static int -get_ready_ep (unsigned f_flags, struct ep_data *epdata) +get_ready_ep (unsigned f_flags, struct ep_data *epdata, bool is_write) { int val; if (f_flags & O_NONBLOCK) { if (!mutex_trylock(&epdata->lock)) goto nonblock; - if (epdata->state != STATE_EP_ENABLED) { + if (epdata->state != STATE_EP_ENABLED && + (!is_write || epdata->state != STATE_EP_READY)) { mutex_unlock(&epdata->lock); nonblock: val = -EAGAIN; @@ -305,18 +308,20 @@ nonblock: switch (epdata->state) { case STATE_EP_ENABLED: + return 0; + case STATE_EP_READY: /* not configured yet */ + if (is_write) + return 0; + // FALLTHRU + case STATE_EP_UNBOUND: /* clean disconnect */ break; // case STATE_EP_DISABLED: /* "can't happen" */ - // case STATE_EP_READY: /* "can't happen" */ default: /* error! */ pr_debug ("%s: ep %p not available, state %d\n", shortname, epdata, epdata->state); - // FALLTHROUGH - case STATE_EP_UNBOUND: /* clean disconnect */ - val = -ENODEV; - mutex_unlock(&epdata->lock); } - return val; + mutex_unlock(&epdata->lock); + return -ENODEV; } static ssize_t @@ -390,7 +395,7 @@ static long ep_ioctl(struct file *fd, unsigned code, unsigned long value) struct ep_data *data = fd->private_data; int status; - if ((status = get_ready_ep (fd->f_flags, data)) < 0) + if ((status = get_ready_ep (fd->f_flags, data, false)) < 0) return status; spin_lock_irq (&data->dev->lock); @@ -572,7 +577,7 @@ ep_read_iter(struct kiocb *iocb, struct iov_iter *to) ssize_t value; char *buf; - if ((value = get_ready_ep(file->f_flags, epdata)) < 0) + if ((value = get_ready_ep(file->f_flags, epdata, false)) < 0) return value; /* halt any endpoint by doing a "wrong direction" i/o call */ @@ -620,20 +625,25 @@ fail: return value; } +static ssize_t ep_config(struct ep_data *, const char *, size_t); + static ssize_t ep_write_iter(struct kiocb *iocb, struct iov_iter *from) { struct file *file = iocb->ki_filp; struct ep_data *epdata = file->private_data; size_t len = iov_iter_count(from); + bool configured; ssize_t value; char *buf; - if ((value = get_ready_ep(file->f_flags, epdata)) < 0) + if ((value = get_ready_ep(file->f_flags, epdata, true)) < 0) return value; + configured = epdata->state == STATE_EP_ENABLED; + /* halt any endpoint by doing a "wrong direction" i/o call */ - if (!usb_endpoint_dir_in(&epdata->desc)) { + if (configured && !usb_endpoint_dir_in(&epdata->desc)) { if (usb_endpoint_xfer_isoc(&epdata->desc) || !is_sync_kiocb(iocb)) { mutex_unlock(&epdata->lock); @@ -659,7 +669,9 @@ ep_write_iter(struct kiocb *iocb, struct iov_iter *from) goto out; } - if (is_sync_kiocb(iocb)) { + if (unlikely(!configured)) { + value = ep_config(epdata, buf, len); + } else if (is_sync_kiocb(iocb)) { value = ep_io(epdata, buf, len); } else { struct kiocb_priv *priv = kzalloc(sizeof *priv, GFP_KERNEL); @@ -681,13 +693,13 @@ out: /* used after endpoint configuration */ static const struct file_operations ep_io_operations = { .owner = THIS_MODULE, - .llseek = no_llseek, + .open = ep_open, + .release = ep_release, + .llseek = no_llseek, .read = new_sync_read, .write = new_sync_write, .unlocked_ioctl = ep_ioctl, - .release = ep_release, - .read_iter = ep_read_iter, .write_iter = ep_write_iter, }; @@ -706,17 +718,12 @@ static const struct file_operations ep_io_operations = { * speed descriptor, then optional high speed descriptor. */ static ssize_t -ep_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) +ep_config (struct ep_data *data, const char *buf, size_t len) { - struct ep_data *data = fd->private_data; struct usb_ep *ep; u32 tag; int value, length = len; - value = mutex_lock_interruptible(&data->lock); - if (value < 0) - return value; - if (data->state != STATE_EP_READY) { value = -EL2HLT; goto fail; @@ -727,9 +734,7 @@ ep_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) goto fail0; /* we might need to change message format someday */ - if (copy_from_user (&tag, buf, 4)) { - goto fail1; - } + memcpy(&tag, buf, 4); if (tag != 1) { DBG(data->dev, "config %s, bad tag %d\n", data->name, tag); goto fail0; @@ -742,19 +747,15 @@ ep_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) */ /* full/low speed descriptor, then high speed */ - if (copy_from_user (&data->desc, buf, USB_DT_ENDPOINT_SIZE)) { - goto fail1; - } + memcpy(&data->desc, buf, USB_DT_ENDPOINT_SIZE); if (data->desc.bLength != USB_DT_ENDPOINT_SIZE || data->desc.bDescriptorType != USB_DT_ENDPOINT) goto fail0; if (len != USB_DT_ENDPOINT_SIZE) { if (len != 2 * USB_DT_ENDPOINT_SIZE) goto fail0; - if (copy_from_user (&data->hs_desc, buf + USB_DT_ENDPOINT_SIZE, - USB_DT_ENDPOINT_SIZE)) { - goto fail1; - } + memcpy(&data->hs_desc, buf + USB_DT_ENDPOINT_SIZE, + USB_DT_ENDPOINT_SIZE); if (data->hs_desc.bLength != USB_DT_ENDPOINT_SIZE || data->hs_desc.bDescriptorType != USB_DT_ENDPOINT) { @@ -776,24 +777,20 @@ ep_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) case USB_SPEED_LOW: case USB_SPEED_FULL: ep->desc = &data->desc; - value = usb_ep_enable(ep); - if (value == 0) - data->state = STATE_EP_ENABLED; break; case USB_SPEED_HIGH: /* fails if caller didn't provide that descriptor... */ ep->desc = &data->hs_desc; - value = usb_ep_enable(ep); - if (value == 0) - data->state = STATE_EP_ENABLED; break; default: DBG(data->dev, "unconnected, %s init abandoned\n", data->name); value = -EINVAL; + goto gone; } + value = usb_ep_enable(ep); if (value == 0) { - fd->f_op = &ep_io_operations; + data->state = STATE_EP_ENABLED; value = length; } gone: @@ -803,14 +800,10 @@ fail: data->desc.bDescriptorType = 0; data->hs_desc.bDescriptorType = 0; } - mutex_unlock(&data->lock); return value; fail0: value = -EINVAL; goto fail; -fail1: - value = -EFAULT; - goto fail; } static int @@ -838,15 +831,6 @@ ep_open (struct inode *inode, struct file *fd) return value; } -/* used before endpoint configuration */ -static const struct file_operations ep_config_operations = { - .llseek = no_llseek, - - .open = ep_open, - .write = ep_config, - .release = ep_release, -}; - /*----------------------------------------------------------------------*/ /* EP0 IMPLEMENTATION can be partly in userspace. @@ -1586,7 +1570,7 @@ static int activate_ep_files (struct dev_data *dev) goto enomem1; data->dentry = gadgetfs_create_file (dev->sb, data->name, - data, &ep_config_operations); + data, &ep_io_operations); if (!data->dentry) goto enomem2; list_add_tail (&data->epfiles, &dev->epfiles); -- GitLab From 96b62a57193494010eed66ca0739c93eb4653162 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 4 Mar 2015 10:31:50 -0500 Subject: [PATCH 03406/11651] gadgetfs: really get rid of switching ->f_op ... for ep0 as well Signed-off-by: Alan Stern Signed-off-by: Al Viro --- drivers/usb/gadget/legacy/inode.c | 38 +++++++++++++++---------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c index c0e25320a3c4..200f9a584064 100644 --- a/drivers/usb/gadget/legacy/inode.c +++ b/drivers/usb/gadget/legacy/inode.c @@ -909,6 +909,10 @@ ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr) enum ep0_state state; spin_lock_irq (&dev->lock); + if (dev->state <= STATE_DEV_OPENED) { + retval = -EINVAL; + goto done; + } /* report fd mode change before acting on it */ if (dev->setup_abort) { @@ -1107,8 +1111,6 @@ ep0_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) struct dev_data *dev = fd->private_data; ssize_t retval = -ESRCH; - spin_lock_irq (&dev->lock); - /* report fd mode change before acting on it */ if (dev->setup_abort) { dev->setup_abort = 0; @@ -1154,7 +1156,6 @@ ep0_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) } else DBG (dev, "fail %s, state %d\n", __func__, dev->state); - spin_unlock_irq (&dev->lock); return retval; } @@ -1201,6 +1202,9 @@ ep0_poll (struct file *fd, poll_table *wait) struct dev_data *dev = fd->private_data; int mask = 0; + if (dev->state <= STATE_DEV_OPENED) + return DEFAULT_POLLMASK; + poll_wait(fd, &dev->wait, wait); spin_lock_irq (&dev->lock); @@ -1236,19 +1240,6 @@ static long dev_ioctl (struct file *fd, unsigned code, unsigned long value) return ret; } -/* used after device configuration */ -static const struct file_operations ep0_io_operations = { - .owner = THIS_MODULE, - .llseek = no_llseek, - - .read = ep0_read, - .write = ep0_write, - .fasync = ep0_fasync, - .poll = ep0_poll, - .unlocked_ioctl = dev_ioctl, - .release = dev_release, -}; - /*----------------------------------------------------------------------*/ /* The in-kernel gadget driver handles most ep0 issues, in particular @@ -1772,6 +1763,14 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) u32 tag; char *kbuf; + spin_lock_irq(&dev->lock); + if (dev->state > STATE_DEV_OPENED) { + value = ep0_write(fd, buf, len, ptr); + spin_unlock_irq(&dev->lock); + return value; + } + spin_unlock_irq(&dev->lock); + if (len < (USB_DT_CONFIG_SIZE + USB_DT_DEVICE_SIZE + 4)) return -EINVAL; @@ -1845,7 +1844,6 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) * on, they can work ... except in cleanup paths that * kick in after the ep0 descriptor is closed. */ - fd->f_op = &ep0_io_operations; value = len; } return value; @@ -1876,12 +1874,14 @@ dev_open (struct inode *inode, struct file *fd) return value; } -static const struct file_operations dev_init_operations = { +static const struct file_operations ep0_operations = { .llseek = no_llseek, .open = dev_open, + .read = ep0_read, .write = dev_config, .fasync = ep0_fasync, + .poll = ep0_poll, .unlocked_ioctl = dev_ioctl, .release = dev_release, }; @@ -1997,7 +1997,7 @@ gadgetfs_fill_super (struct super_block *sb, void *opts, int silent) goto Enomem; dev->sb = sb; - dev->dentry = gadgetfs_create_file(sb, CHIP, dev, &dev_init_operations); + dev->dentry = gadgetfs_create_file(sb, CHIP, dev, &ep0_operations); if (!dev->dentry) { put_dev(dev); goto Enomem; -- GitLab From 0548bf4f5ad6fc3bd93c4940fa48078b34609682 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Mon, 2 Mar 2015 21:40:39 +0100 Subject: [PATCH 03407/11651] regulator: Only enable disabled regulators on resume The _regulator_do_enable() call ought to be a no-op when called on an already-enabled regulator. However, as an optimization _regulator_enable() doesn't call _regulator_do_enable() on an already enabled regulator. That means we never test the case of calling _regulator_do_enable() during normal usage and there may be hidden bugs or warnings. We have seen warnings issued by the tps65090 driver and bugs when using the GPIO enable pin. Let's match the same optimization that _regulator_enable() in regulator_suspend_finish(). That may speed up suspend/resume and also avoids exposing hidden bugs. [Use much clearer commit message from Doug Anderson] Signed-off-by: Javier Martinez Canillas Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- drivers/regulator/core.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index b899947d839d..0e271e57504a 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -3807,9 +3807,11 @@ int regulator_suspend_finish(void) list_for_each_entry(rdev, ®ulator_list, list) { mutex_lock(&rdev->mutex); if (rdev->use_count > 0 || rdev->constraints->always_on) { - error = _regulator_do_enable(rdev); - if (error) - ret = error; + if (!_regulator_is_enabled(rdev)) { + error = _regulator_do_enable(rdev); + if (error) + ret = error; + } } else { if (!have_full_constraints()) goto unlock; -- GitLab From 29d62ec5f87fbeec8413e2215ddad12e7f972e4c Mon Sep 17 00:00:00 2001 From: Doug Anderson Date: Tue, 3 Mar 2015 15:20:47 -0800 Subject: [PATCH 03408/11651] regulator: core: Fix enable GPIO reference counting Normally _regulator_do_enable() isn't called on an already-enabled rdev. That's because the main caller, _regulator_enable() always calls _regulator_is_enabled() and only calls _regulator_do_enable() if the rdev was not already enabled. However, there is one caller of _regulator_do_enable() that doesn't check: regulator_suspend_finish(). While we might want to make regulator_suspend_finish() behave more like _regulator_enable(), it's probably also a good idea to make _regulator_do_enable() robust if it is called on an already enabled rdev. At the moment, _regulator_do_enable() is _not_ robust for already enabled rdevs if we're using an ena_pin. Each time _regulator_do_enable() is called for an rdev using an ena_pin the reference count of the ena_pin is incremented even if the rdev was already enabled. This is not as intended because the ena_pin is for something else: for keeping track of how many active rdevs there are sharing the same ena_pin. Here's how the reference counting works here: * Each time _regulator_enable() is called we increment rdev->use_count, so _regulator_enable() calls need to be balanced with _regulator_disable() calls. * There is no explicit reference counting in _regulator_do_enable() which is normally just a warapper around rdev->desc->ops->enable() with code for supporting delays. It's not expected that the "ops->enable()" call do reference counting. * Since regulator_ena_gpio_ctrl() does have reference counting (handling the sharing of the pin amongst multiple rdevs), we shouldn't call it if the current rdev is already enabled. Note that as part of this we cleanup (remove) the initting of ena_gpio_state in regulator_register(). In _regulator_do_enable(), _regulator_do_disable() and _regulator_is_enabled() is is clear that ena_gpio_state should be the state of whether this particular rdev has requested the GPIO be enabled. regulator_register() was initting it as the actual state of the pin. Fixes: 967cfb18c0e3 ("regulator: core: manage enable GPIO list") Signed-off-by: Doug Anderson Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- drivers/regulator/core.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 0e271e57504a..fafeb32427c1 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1839,10 +1839,12 @@ static int _regulator_do_enable(struct regulator_dev *rdev) } if (rdev->ena_pin) { - ret = regulator_ena_gpio_ctrl(rdev, true); - if (ret < 0) - return ret; - rdev->ena_gpio_state = 1; + if (!rdev->ena_gpio_state) { + ret = regulator_ena_gpio_ctrl(rdev, true); + if (ret < 0) + return ret; + rdev->ena_gpio_state = 1; + } } else if (rdev->desc->ops->enable) { ret = rdev->desc->ops->enable(rdev); if (ret < 0) @@ -1939,10 +1941,12 @@ static int _regulator_do_disable(struct regulator_dev *rdev) trace_regulator_disable(rdev_get_name(rdev)); if (rdev->ena_pin) { - ret = regulator_ena_gpio_ctrl(rdev, false); - if (ret < 0) - return ret; - rdev->ena_gpio_state = 0; + if (rdev->ena_gpio_state) { + ret = regulator_ena_gpio_ctrl(rdev, false); + if (ret < 0) + return ret; + rdev->ena_gpio_state = 0; + } } else if (rdev->desc->ops->disable) { ret = rdev->desc->ops->disable(rdev); @@ -3633,12 +3637,6 @@ regulator_register(const struct regulator_desc *regulator_desc, config->ena_gpio, ret); goto wash; } - - if (config->ena_gpio_flags & GPIOF_OUT_INIT_HIGH) - rdev->ena_gpio_state = 1; - - if (config->ena_gpio_invert) - rdev->ena_gpio_state = !rdev->ena_gpio_state; } /* set regulator constraints */ -- GitLab From 34e81ab4556f3b1371763861e74e3600818924b5 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sat, 7 Mar 2015 19:34:03 +0100 Subject: [PATCH 03409/11651] ASoC: Fix component lists locking Any access to the component_list, codec_list and platform_list needs to be properly locked by the client_mutex. Otherwise undefined behavior can occur if the list is modified in one thread and concurrently accessed from another thread. This patch adds the missing locking to the debugfs file handlers that display the registered components, as well as the various components unregister functions. Furthermore the client_lock is now held for the whole snd_soc_instantiate_card() sequence to make sure that component removal does not race against the card registration. Reported-by: Takashi Iwai Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 41 ++++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 30579ca5bacb..e5c990889dcc 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -347,6 +347,8 @@ static ssize_t codec_list_read_file(struct file *file, char __user *user_buf, if (!buf) return -ENOMEM; + mutex_lock(&client_mutex); + list_for_each_entry(codec, &codec_list, list) { len = snprintf(buf + ret, PAGE_SIZE - ret, "%s\n", codec->component.name); @@ -358,6 +360,8 @@ static ssize_t codec_list_read_file(struct file *file, char __user *user_buf, } } + mutex_unlock(&client_mutex); + if (ret >= 0) ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret); @@ -382,6 +386,8 @@ static ssize_t dai_list_read_file(struct file *file, char __user *user_buf, if (!buf) return -ENOMEM; + mutex_lock(&client_mutex); + list_for_each_entry(component, &component_list, list) { list_for_each_entry(dai, &component->dai_list, list) { len = snprintf(buf + ret, PAGE_SIZE - ret, "%s\n", @@ -395,6 +401,8 @@ static ssize_t dai_list_read_file(struct file *file, char __user *user_buf, } } + mutex_unlock(&client_mutex); + ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret); kfree(buf); @@ -418,6 +426,8 @@ static ssize_t platform_list_read_file(struct file *file, if (!buf) return -ENOMEM; + mutex_lock(&client_mutex); + list_for_each_entry(platform, &platform_list, list) { len = snprintf(buf + ret, PAGE_SIZE - ret, "%s\n", platform->component.name); @@ -429,6 +439,8 @@ static ssize_t platform_list_read_file(struct file *file, } } + mutex_unlock(&client_mutex); + ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret); kfree(buf); @@ -836,6 +848,8 @@ static struct snd_soc_component *soc_find_component( { struct snd_soc_component *component; + lockdep_assert_held(&client_mutex); + list_for_each_entry(component, &component_list, list) { if (of_node) { if (component->dev->of_node == of_node) @@ -854,6 +868,8 @@ static struct snd_soc_dai *snd_soc_find_dai( struct snd_soc_component *component; struct snd_soc_dai *dai; + lockdep_assert_held(&client_mutex); + /* Find CPU DAI from registered DAIs*/ list_for_each_entry(component, &component_list, list) { if (dlc->of_node && component->dev->of_node != dlc->of_node) @@ -1508,6 +1524,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) struct snd_soc_codec *codec; int ret, i, order; + mutex_lock(&client_mutex); mutex_lock_nested(&card->mutex, SND_SOC_CARD_CLASS_INIT); /* bind DAIs */ @@ -1662,6 +1679,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) card->instantiated = 1; snd_soc_dapm_sync(&card->dapm); mutex_unlock(&card->mutex); + mutex_unlock(&client_mutex); return 0; @@ -1680,6 +1698,7 @@ card_probe_error: base_error: mutex_unlock(&card->mutex); + mutex_unlock(&client_mutex); return ret; } @@ -2713,13 +2732,6 @@ static void snd_soc_component_del_unlocked(struct snd_soc_component *component) list_del(&component->list); } -static void snd_soc_component_del(struct snd_soc_component *component) -{ - mutex_lock(&client_mutex); - snd_soc_component_del_unlocked(component); - mutex_unlock(&client_mutex); -} - int snd_soc_register_component(struct device *dev, const struct snd_soc_component_driver *cmpnt_drv, struct snd_soc_dai_driver *dai_drv, @@ -2767,14 +2779,17 @@ void snd_soc_unregister_component(struct device *dev) { struct snd_soc_component *cmpnt; + mutex_lock(&client_mutex); list_for_each_entry(cmpnt, &component_list, list) { if (dev == cmpnt->dev && cmpnt->registered_as_component) goto found; } + mutex_unlock(&client_mutex); return; found: - snd_soc_component_del(cmpnt); + snd_soc_component_del_unlocked(cmpnt); + mutex_unlock(&client_mutex); snd_soc_component_cleanup(cmpnt); kfree(cmpnt); } @@ -2882,10 +2897,14 @@ struct snd_soc_platform *snd_soc_lookup_platform(struct device *dev) { struct snd_soc_platform *platform; + mutex_lock(&client_mutex); list_for_each_entry(platform, &platform_list, list) { - if (dev == platform->dev) + if (dev == platform->dev) { + mutex_unlock(&client_mutex); return platform; + } } + mutex_unlock(&client_mutex); return NULL; } @@ -3090,15 +3109,15 @@ void snd_soc_unregister_codec(struct device *dev) { struct snd_soc_codec *codec; + mutex_lock(&client_mutex); list_for_each_entry(codec, &codec_list, list) { if (dev == codec->dev) goto found; } + mutex_unlock(&client_mutex); return; found: - - mutex_lock(&client_mutex); list_del(&codec->list); snd_soc_component_del_unlocked(&codec->component); mutex_unlock(&client_mutex); -- GitLab From 778952598e53f09251bebe1655177b355cd9e836 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sat, 7 Mar 2015 19:35:08 +0100 Subject: [PATCH 03410/11651] ASoC: Remove unnecessary device_remove_file() Since commit d29697dc3b92 ("ASoC: Add sysfs entries via static attribute groups") the sysfs attributes of the rtd are manged by the device core and there is no need to manually call device_remove_file() anymore. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 30579ca5bacb..acf99f1250e5 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1410,7 +1410,6 @@ static void soc_remove_aux_dev(struct snd_soc_card *card, int num) /* unregister the rtd device */ if (rtd->dev_registered) { - device_remove_file(rtd->dev, &dev_attr_codec_reg); device_unregister(rtd->dev); rtd->dev_registered = 0; } -- GitLab From 1711fd9addf214823b993468567cab1f8254fc51 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 7 Mar 2015 21:08:46 +0000 Subject: [PATCH 03411/11651] sunrpc: fix braino in ->poll() POLL_OUT isn't what callers of ->poll() are expecting to see; it's actually __SI_POLL | 2 and it's a siginfo code, not a poll bitmap bit... Signed-off-by: Al Viro Cc: stable@vger.kernel.org Cc: Bruce Fields Signed-off-by: Linus Torvalds --- net/sunrpc/cache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c index 33fb105d4352..5199bb1a017e 100644 --- a/net/sunrpc/cache.c +++ b/net/sunrpc/cache.c @@ -921,7 +921,7 @@ static unsigned int cache_poll(struct file *filp, poll_table *wait, poll_wait(filp, &queue_wait, wait); /* alway allow write */ - mask = POLL_OUT | POLLWRNORM; + mask = POLLOUT | POLLWRNORM; if (!rp) return mask; -- GitLab From 47875e81476bda8a9bd4875eb281b46e33027d42 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 8 Mar 2015 14:56:37 +0100 Subject: [PATCH 03412/11651] spi: Use PM ops instead of legacy suspend/resume New drivers should use PM ops instead of the legacy suspend/resume callbacks. Update the SPI device driver guide to reflect this. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- Documentation/spi/spi-summary | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Documentation/spi/spi-summary b/Documentation/spi/spi-summary index d29734bff28c..d1824b399b2d 100644 --- a/Documentation/spi/spi-summary +++ b/Documentation/spi/spi-summary @@ -342,12 +342,11 @@ SPI protocol drivers somewhat resemble platform device drivers: .driver = { .name = "CHIP", .owner = THIS_MODULE, + .pm = &CHIP_pm_ops, }, .probe = CHIP_probe, .remove = CHIP_remove, - .suspend = CHIP_suspend, - .resume = CHIP_resume, }; The driver core will automatically attempt to bind this driver to any SPI -- GitLab From ea022bbb0090975a21c581d8405fbe90043a6eda Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 8 Mar 2015 14:56:38 +0100 Subject: [PATCH 03413/11651] spi: Remove support for legacy PM All SPI drivers have been converted from legacy suspend/resume callbacks to dev_pm_ops. So we can finally remove support for legacy PM from the SPI core. Since there aren't any special bus specific things to do during suspend/resume and since the PM core will automatically fallback directly to using the device's PM ops if no bus PM ops are specified there is no need to have any special SPI bus PM ops. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- drivers/spi/spi.c | 114 ---------------------------------------- include/linux/spi/spi.h | 4 -- 2 files changed, 118 deletions(-) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index c64a3e59fce3..7a2b7a7cb650 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -129,125 +129,11 @@ static int spi_uevent(struct device *dev, struct kobj_uevent_env *env) return 0; } -#ifdef CONFIG_PM_SLEEP -static int spi_legacy_suspend(struct device *dev, pm_message_t message) -{ - int value = 0; - struct spi_driver *drv = to_spi_driver(dev->driver); - - /* suspend will stop irqs and dma; no more i/o */ - if (drv) { - if (drv->suspend) - value = drv->suspend(to_spi_device(dev), message); - else - dev_dbg(dev, "... can't suspend\n"); - } - return value; -} - -static int spi_legacy_resume(struct device *dev) -{ - int value = 0; - struct spi_driver *drv = to_spi_driver(dev->driver); - - /* resume may restart the i/o queue */ - if (drv) { - if (drv->resume) - value = drv->resume(to_spi_device(dev)); - else - dev_dbg(dev, "... can't resume\n"); - } - return value; -} - -static int spi_pm_suspend(struct device *dev) -{ - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; - - if (pm) - return pm_generic_suspend(dev); - else - return spi_legacy_suspend(dev, PMSG_SUSPEND); -} - -static int spi_pm_resume(struct device *dev) -{ - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; - - if (pm) - return pm_generic_resume(dev); - else - return spi_legacy_resume(dev); -} - -static int spi_pm_freeze(struct device *dev) -{ - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; - - if (pm) - return pm_generic_freeze(dev); - else - return spi_legacy_suspend(dev, PMSG_FREEZE); -} - -static int spi_pm_thaw(struct device *dev) -{ - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; - - if (pm) - return pm_generic_thaw(dev); - else - return spi_legacy_resume(dev); -} - -static int spi_pm_poweroff(struct device *dev) -{ - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; - - if (pm) - return pm_generic_poweroff(dev); - else - return spi_legacy_suspend(dev, PMSG_HIBERNATE); -} - -static int spi_pm_restore(struct device *dev) -{ - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; - - if (pm) - return pm_generic_restore(dev); - else - return spi_legacy_resume(dev); -} -#else -#define spi_pm_suspend NULL -#define spi_pm_resume NULL -#define spi_pm_freeze NULL -#define spi_pm_thaw NULL -#define spi_pm_poweroff NULL -#define spi_pm_restore NULL -#endif - -static const struct dev_pm_ops spi_pm = { - .suspend = spi_pm_suspend, - .resume = spi_pm_resume, - .freeze = spi_pm_freeze, - .thaw = spi_pm_thaw, - .poweroff = spi_pm_poweroff, - .restore = spi_pm_restore, - SET_RUNTIME_PM_OPS( - pm_generic_runtime_suspend, - pm_generic_runtime_resume, - NULL - ) -}; - struct bus_type spi_bus_type = { .name = "spi", .dev_groups = spi_dev_groups, .match = spi_match_device, .uevent = spi_uevent, - .pm = &spi_pm, }; EXPORT_SYMBOL_GPL(spi_bus_type); diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index ed9489d893a4..9f6b481e8672 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -162,8 +162,6 @@ struct spi_transfer; * @remove: Unbinds this driver from the spi device * @shutdown: Standard shutdown callback used during system state * transitions such as powerdown/halt and kexec - * @suspend: Standard suspend callback used during system state transitions - * @resume: Standard resume callback used during system state transitions * @driver: SPI device drivers should initialize the name and owner * field of this structure. * @@ -184,8 +182,6 @@ struct spi_driver { int (*probe)(struct spi_device *spi); int (*remove)(struct spi_device *spi); void (*shutdown)(struct spi_device *spi); - int (*suspend)(struct spi_device *spi, pm_message_t mesg); - int (*resume)(struct spi_device *spi); struct device_driver driver; }; -- GitLab From 973877477e2f1eecdf8ae4305cd6e030c7cf08db Mon Sep 17 00:00:00 2001 From: Duson Lin Date: Sun, 8 Mar 2015 14:08:19 -0700 Subject: [PATCH 03414/11651] Input: elan_i2c - remove duplicate repeat code Remove duplicate "repeat--" from function elan_initialize. Signed-off-by: Duson Lin Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/elan_i2c_core.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c index b7535385fcdd..375d98f47483 100644 --- a/drivers/input/mouse/elan_i2c_core.c +++ b/drivers/input/mouse/elan_i2c_core.c @@ -198,7 +198,6 @@ static int elan_initialize(struct elan_tp_data *data) if (!error) return 0; - repeat--; msleep(30); } while (--repeat > 0); -- GitLab From 91c68a7c1d92b48287f2f3111a9b09b26a263d3f Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 8 Mar 2015 14:12:41 -0700 Subject: [PATCH 03415/11651] Input: sun4i-ts - A10 (sun4i) has a different temperature curve Testing has revealed that the temperature in the rtp controller of the A10 (sun4i) SoC has a different curve then on the A13 (sun5i) and later models. Add a new sun5i-a13-ts compatible to differentiate the newer models and set the curve based on the compatible string. The new curve is still not ideal on all A10-s, that seems to have to do with there being a large spread between different A10-s out there, the new curve us based on callibration results on 4 completely different models: raw min raw max temp min temp max stepsize offset Tong Zhang's hackberry 2402 2680 45.0 80.0 0.125 -255.3 Hansg's Cubieboard 2207 2300 36.0 45.0 0.096 -175.8 Olliver's lime 1 (*): 2258 2537 48.3 87.1 0.139 -265.7 Olliver's lime 2 (*): 2222 2486 46.7 91.7 0.170 -331.0 *) from: http://linux-sunxi.org/Temperature_Calibration Average all 4: 0.133 -257.0 Average without outliers (middle 2): 0.132 -261.0 Since it is better to slightly overreport the temperature this patch uses the average of all 4 as curve. This fixes the temperature reported on the A10 being much higher then expected. Reported-by: Tong Zhang Signed-off-by: Hans de Goede Signed-off-by: Dmitry Torokhov --- .../bindings/input/touchscreen/sun4i.txt | 3 ++- drivers/input/touchscreen/sun4i-ts.c | 16 +++++++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/input/touchscreen/sun4i.txt b/Documentation/devicetree/bindings/input/touchscreen/sun4i.txt index 433332d3b2ba..d59d25281e9f 100644 --- a/Documentation/devicetree/bindings/input/touchscreen/sun4i.txt +++ b/Documentation/devicetree/bindings/input/touchscreen/sun4i.txt @@ -2,7 +2,8 @@ sun4i resistive touchscreen controller -------------------------------------- Required properties: - - compatible: "allwinner,sun4i-a10-ts" or "allwinner,sun6i-a31-ts" + - compatible: "allwinner,sun4i-a10-ts", "allwinner,sun5i-a13-ts" or + "allwinner,sun6i-a31-ts" - reg: mmio address range of the chip - interrupts: interrupt to which the chip is connected - #thermal-sensor-cells: shall be 0 diff --git a/drivers/input/touchscreen/sun4i-ts.c b/drivers/input/touchscreen/sun4i-ts.c index b93a28b955fd..66ccd5af537d 100644 --- a/drivers/input/touchscreen/sun4i-ts.c +++ b/drivers/input/touchscreen/sun4i-ts.c @@ -258,6 +258,15 @@ static int sun4i_ts_probe(struct platform_device *pdev) /* Allwinner SDK has temperature = -271 + (value / 6) (C) */ ts->temp_offset = 1626; ts->temp_step = 167; + } else if (of_device_is_compatible(np, "allwinner,sun4i-a10-ts")) { + /* + * The A10 temperature sensor has quite a wide spread, these + * parameters are based on the averaging of the calibration + * results of 4 completely different boards, with a spread of + * temp_step from 96 - 170 and temp_offset from 1758 - 3310. + */ + ts->temp_offset = 2570; + ts->temp_step = 133; } else { /* * The user manuals do not contain the formula for calculating @@ -330,10 +339,10 @@ static int sun4i_ts_probe(struct platform_device *pdev) * finally enable tp mode. */ reg = STYLUS_UP_DEBOUN(5) | STYLUS_UP_DEBOUN_EN(1); - if (of_device_is_compatible(np, "allwinner,sun4i-a10-ts")) - reg |= TP_MODE_EN(1); - else + if (of_device_is_compatible(np, "allwinner,sun6i-a31-ts")) reg |= SUN6I_TP_MODE_EN(1); + else + reg |= TP_MODE_EN(1); writel(reg, ts->base + TP_CTRL1); /* @@ -383,6 +392,7 @@ static int sun4i_ts_remove(struct platform_device *pdev) static const struct of_device_id sun4i_ts_of_match[] = { { .compatible = "allwinner,sun4i-a10-ts", }, + { .compatible = "allwinner,sun5i-a13-ts", }, { .compatible = "allwinner,sun6i-a31-ts", }, { /* sentinel */ } }; -- GitLab From 9eccca0843205f87c00404b663188b88eb248051 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 8 Mar 2015 16:09:09 -0700 Subject: [PATCH 03416/11651] Linux 4.0-rc3 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index e6a9b1b94656..1100ff3c77e3 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 4 PATCHLEVEL = 0 SUBLEVEL = 0 -EXTRAVERSION = -rc2 +EXTRAVERSION = -rc3 NAME = Hurr durr I'ma sheep # *DOCUMENTATION* -- GitLab From 008a5b07f1b4beab1004ac799f449b59a45af8e9 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Sun, 8 Mar 2015 11:48:49 -0700 Subject: [PATCH 03417/11651] neterion: remove reference to ifconfig Remove reference to obsolete ifconfig command. MTU can be changed with ip command instead. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- Documentation/networking/s2io.txt | 2 +- Documentation/networking/vxge.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/networking/s2io.txt b/Documentation/networking/s2io.txt index d2a9f43b5546..0362a42f7cf4 100644 --- a/Documentation/networking/s2io.txt +++ b/Documentation/networking/s2io.txt @@ -38,7 +38,7 @@ The corresponding adapter's LED will blink multiple times. 3. Features supported: a. Jumbo frames. Xframe I/II supports MTU up to 9600 bytes, -modifiable using ifconfig command. +modifiable using ip command. b. Offloads. Supports checksum offload(TCP/UDP/IP) on transmit and receive, TSO. diff --git a/Documentation/networking/vxge.txt b/Documentation/networking/vxge.txt index bb76c667a476..abfec245f97c 100644 --- a/Documentation/networking/vxge.txt +++ b/Documentation/networking/vxge.txt @@ -39,7 +39,7 @@ iii) PCI-SIG's I/O Virtualization iv) Jumbo frames X3100 Series supports MTU up to 9600 bytes, modifiable using - ifconfig command. + ip command. v) Offloads supported: (Enabled by default) Checksum offload (TCP/UDP/IP) on transmit and receive paths -- GitLab From d865616e1889d0b6528b5d9b620e13b1607003a5 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Sat, 7 Mar 2015 16:19:41 -0600 Subject: [PATCH 03418/11651] mpls: Fix the kzalloc argument order in mpls_rt_alloc *Blink* I got the argument order wrong to kzalloc and the code was working properly when tested. *Blink* Fix that. Signed-off-by: "Eric W. Biederman" Signed-off-by: David S. Miller --- net/mpls/af_mpls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c index 4f265c677eca..59cc32564d50 100644 --- a/net/mpls/af_mpls.c +++ b/net/mpls/af_mpls.c @@ -239,7 +239,7 @@ static struct mpls_route *mpls_rt_alloc(size_t alen) { struct mpls_route *rt; - rt = kzalloc(GFP_KERNEL, sizeof(*rt) + alen); + rt = kzalloc(sizeof(*rt) + alen, GFP_KERNEL); if (rt) rt->rt_via_alen = alen; return rt; -- GitLab From 19d0c341d9d5cd186661fef58e7264a9701ef71d Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Sat, 7 Mar 2015 16:21:56 -0600 Subject: [PATCH 03419/11651] mpls: Cleanup the rcu usage in the code. Sparse was generating a lot of warnings mostly from missing annotations in the code. Add missing annotations and in a few cases tweak the code for performance by moving work before loops. This also fixes a problematic ommision of rcu_assign_pointer and rcu_dereference. Hopefully with complete rcu annotations any new rcu errors will stick out like a sore thumb. Signed-off-by: "Eric W. Biederman" Signed-off-by: David S. Miller --- net/mpls/af_mpls.c | 73 +++++++++++++++++++++++++++++----------------- 1 file changed, 47 insertions(+), 26 deletions(-) diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c index 59cc32564d50..0f2833e1b233 100644 --- a/net/mpls/af_mpls.c +++ b/net/mpls/af_mpls.c @@ -24,7 +24,7 @@ #define MAX_VIA_ALEN (ALIGN(MAX_ADDR_LEN, sizeof(unsigned long))) struct mpls_route { /* next hop label forwarding entry */ - struct net_device *rt_dev; + struct net_device __rcu *rt_dev; struct rcu_head rt_rcu; u32 rt_label[MAX_NEW_LABELS]; u8 rt_protocol; /* routing protocol that set this entry */ @@ -152,7 +152,7 @@ static int mpls_forward(struct sk_buff *skb, struct net_device *dev, goto drop; /* Find the output device */ - out_dev = rt->rt_dev; + out_dev = rcu_dereference(rt->rt_dev); if (!mpls_output_possible(out_dev)) goto drop; @@ -269,13 +269,15 @@ static void mpls_route_update(struct net *net, unsigned index, struct net_device *dev, struct mpls_route *new, const struct nl_info *info) { + struct mpls_route __rcu **platform_label; struct mpls_route *rt, *old = NULL; ASSERT_RTNL(); - rt = net->mpls.platform_label[index]; - if (!dev || (rt && (rt->rt_dev == dev))) { - rcu_assign_pointer(net->mpls.platform_label[index], new); + platform_label = rtnl_dereference(net->mpls.platform_label); + rt = rtnl_dereference(platform_label[index]); + if (!dev || (rt && (rtnl_dereference(rt->rt_dev) == dev))) { + rcu_assign_pointer(platform_label[index], new); old = rt; } @@ -287,9 +289,14 @@ static void mpls_route_update(struct net *net, unsigned index, static unsigned find_free_label(struct net *net) { + struct mpls_route __rcu **platform_label; + size_t platform_labels; unsigned index; - for (index = 16; index < net->mpls.platform_labels; index++) { - if (!net->mpls.platform_label[index]) + + platform_label = rtnl_dereference(net->mpls.platform_label); + platform_labels = net->mpls.platform_labels; + for (index = 16; index < platform_labels; index++) { + if (!rtnl_dereference(platform_label[index])) return index; } return LABEL_NOT_SPECIFIED; @@ -297,6 +304,7 @@ static unsigned find_free_label(struct net *net) static int mpls_route_add(struct mpls_route_config *cfg) { + struct mpls_route __rcu **platform_label; struct net *net = cfg->rc_nlinfo.nl_net; struct net_device *dev = NULL; struct mpls_route *rt, *old; @@ -345,7 +353,8 @@ static int mpls_route_add(struct mpls_route_config *cfg) goto errout; err = -EEXIST; - old = net->mpls.platform_label[index]; + platform_label = rtnl_dereference(net->mpls.platform_label); + old = rtnl_dereference(platform_label[index]); if ((cfg->rc_nlflags & NLM_F_EXCL) && old) goto errout; @@ -366,7 +375,7 @@ static int mpls_route_add(struct mpls_route_config *cfg) for (i = 0; i < rt->rt_labels; i++) rt->rt_label[i] = cfg->rc_output_label[i]; rt->rt_protocol = cfg->rc_protocol; - rt->rt_dev = dev; + RCU_INIT_POINTER(rt->rt_dev, dev); rt->rt_via_family = cfg->rc_via_family; memcpy(rt->rt_via, cfg->rc_via, cfg->rc_via_alen); @@ -406,14 +415,16 @@ errout: static void mpls_ifdown(struct net_device *dev) { + struct mpls_route __rcu **platform_label; struct net *net = dev_net(dev); unsigned index; + platform_label = rtnl_dereference(net->mpls.platform_label); for (index = 0; index < net->mpls.platform_labels; index++) { - struct mpls_route *rt = net->mpls.platform_label[index]; + struct mpls_route *rt = rtnl_dereference(platform_label[index]); if (!rt) continue; - if (rt->rt_dev != dev) + if (rtnl_dereference(rt->rt_dev) != dev) continue; rt->rt_dev = NULL; } @@ -653,6 +664,7 @@ static int mpls_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh) static int mpls_dump_route(struct sk_buff *skb, u32 portid, u32 seq, int event, u32 label, struct mpls_route *rt, int flags) { + struct net_device *dev; struct nlmsghdr *nlh; struct rtmsg *rtm; @@ -676,7 +688,8 @@ static int mpls_dump_route(struct sk_buff *skb, u32 portid, u32 seq, int event, goto nla_put_failure; if (nla_put_via(skb, rt->rt_via_family, rt->rt_via, rt->rt_via_alen)) goto nla_put_failure; - if (rt->rt_dev && nla_put_u32(skb, RTA_OIF, rt->rt_dev->ifindex)) + dev = rtnl_dereference(rt->rt_dev); + if (dev && nla_put_u32(skb, RTA_OIF, dev->ifindex)) goto nla_put_failure; if (nla_put_labels(skb, RTA_DST, 1, &label)) goto nla_put_failure; @@ -692,6 +705,8 @@ nla_put_failure: static int mpls_dump_routes(struct sk_buff *skb, struct netlink_callback *cb) { struct net *net = sock_net(skb->sk); + struct mpls_route __rcu **platform_label; + size_t platform_labels; unsigned int index; ASSERT_RTNL(); @@ -700,9 +715,11 @@ static int mpls_dump_routes(struct sk_buff *skb, struct netlink_callback *cb) if (index < 16) index = 16; - for (; index < net->mpls.platform_labels; index++) { + platform_label = rtnl_dereference(net->mpls.platform_label); + platform_labels = net->mpls.platform_labels; + for (; index < platform_labels; index++) { struct mpls_route *rt; - rt = net->mpls.platform_label[index]; + rt = rtnl_dereference(platform_label[index]); if (!rt) continue; @@ -780,7 +797,7 @@ static int resize_platform_label_table(struct net *net, size_t limit) rt0 = mpls_rt_alloc(lo->addr_len); if (!rt0) goto nort0; - rt0->rt_dev = lo; + RCU_INIT_POINTER(rt0->rt_dev, lo); rt0->rt_protocol = RTPROT_KERNEL; rt0->rt_via_family = AF_PACKET; memcpy(rt0->rt_via, lo->dev_addr, lo->addr_len); @@ -790,7 +807,7 @@ static int resize_platform_label_table(struct net *net, size_t limit) rt2 = mpls_rt_alloc(lo->addr_len); if (!rt2) goto nort2; - rt2->rt_dev = lo; + RCU_INIT_POINTER(rt2->rt_dev, lo); rt2->rt_protocol = RTPROT_KERNEL; rt2->rt_via_family = AF_PACKET; memcpy(rt2->rt_via, lo->dev_addr, lo->addr_len); @@ -798,7 +815,7 @@ static int resize_platform_label_table(struct net *net, size_t limit) rtnl_lock(); /* Remember the original table */ - old = net->mpls.platform_label; + old = rtnl_dereference(net->mpls.platform_label); old_limit = net->mpls.platform_labels; /* Free any labels beyond the new table */ @@ -815,19 +832,19 @@ static int resize_platform_label_table(struct net *net, size_t limit) /* If needed set the predefined labels */ if ((old_limit <= LABEL_IPV6_EXPLICIT_NULL) && (limit > LABEL_IPV6_EXPLICIT_NULL)) { - labels[LABEL_IPV6_EXPLICIT_NULL] = rt2; + RCU_INIT_POINTER(labels[LABEL_IPV6_EXPLICIT_NULL], rt2); rt2 = NULL; } if ((old_limit <= LABEL_IPV4_EXPLICIT_NULL) && (limit > LABEL_IPV4_EXPLICIT_NULL)) { - labels[LABEL_IPV4_EXPLICIT_NULL] = rt0; + RCU_INIT_POINTER(labels[LABEL_IPV4_EXPLICIT_NULL], rt0); rt0 = NULL; } /* Update the global pointers */ net->mpls.platform_labels = limit; - net->mpls.platform_label = labels; + rcu_assign_pointer(net->mpls.platform_label, labels); rtnl_unlock(); @@ -903,6 +920,8 @@ static int mpls_net_init(struct net *net) static void mpls_net_exit(struct net *net) { + struct mpls_route __rcu **platform_label; + size_t platform_labels; struct ctl_table *table; unsigned int index; @@ -910,8 +929,8 @@ static void mpls_net_exit(struct net *net) unregister_net_sysctl_table(net->mpls.ctl); kfree(table); - /* An rcu grace period haselapsed since there was a device in - * the network namespace (and thus the last in fqlight packet) + /* An rcu grace period has passed since there was a device in + * the network namespace (and thus the last in flight packet) * left this network namespace. This is because * unregister_netdevice_many and netdev_run_todo has completed * for each network device that was in this network namespace. @@ -920,14 +939,16 @@ static void mpls_net_exit(struct net *net) * freeing the platform_label table. */ rtnl_lock(); - for (index = 0; index < net->mpls.platform_labels; index++) { - struct mpls_route *rt = net->mpls.platform_label[index]; - rcu_assign_pointer(net->mpls.platform_label[index], NULL); + platform_label = rtnl_dereference(net->mpls.platform_label); + platform_labels = net->mpls.platform_labels; + for (index = 0; index < platform_labels; index++) { + struct mpls_route *rt = rtnl_dereference(platform_label[index]); + RCU_INIT_POINTER(platform_label[index], NULL); mpls_rt_free(rt); } rtnl_unlock(); - kvfree(net->mpls.platform_label); + kvfree(platform_label); } static struct pernet_operations mpls_net_ops = { -- GitLab From 0f7bbd5805e3d32e3ee58d1a802a8404a724f2fc Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Sat, 7 Mar 2015 16:22:40 -0600 Subject: [PATCH 03420/11651] mpls: Better error code for unsupported option. Signed-off-by: "Eric W. Biederman" Signed-off-by: David S. Miller --- net/mpls/af_mpls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c index 0f2833e1b233..5c99e3fc1b72 100644 --- a/net/mpls/af_mpls.c +++ b/net/mpls/af_mpls.c @@ -348,7 +348,7 @@ static int mpls_route_add(struct mpls_route_config *cfg) goto errout; /* Append makes no sense with mpls */ - err = -EINVAL; + err = -EOPNOTSUPP; if (cfg->rc_nlflags & NLM_F_APPEND) goto errout; -- GitLab From aa7da9375677d31dd53ed6253f55cb19e3075811 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Sat, 7 Mar 2015 16:23:23 -0600 Subject: [PATCH 03421/11651] mpls: Correct the ttl decrement. According to RFC3032 section 2.4.2 packets with an outgoing ttl of 0 MUST NOT be forwarded. According to section 2.4.1 an outgoing TTL of 0 comes from an incomming TTL <= 1. Therefore any packets that is received with a ttl <= 1 should not have it's ttl decremented and forwarded. Signed-off-by: "Eric W. Biederman" Signed-off-by: David S. Miller --- net/mpls/af_mpls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c index 5c99e3fc1b72..e120074157de 100644 --- a/net/mpls/af_mpls.c +++ b/net/mpls/af_mpls.c @@ -162,7 +162,7 @@ static int mpls_forward(struct sk_buff *skb, struct net_device *dev, skb_forward_csum(skb); /* Verify ttl is valid */ - if (dec.ttl <= 2) + if (dec.ttl <= 1) goto drop; dec.ttl -= 1; -- GitLab From 7d5f41f276b376d567e919530f8b5fd70be25426 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Sat, 7 Mar 2015 16:24:23 -0600 Subject: [PATCH 03422/11651] mpls: Fix the openvswitch select of NET_MPLS_GSO Fix the OPENVSWITCH Kconfig option and old Kconfigs by having OPENVSWITCH select both NET_MPLS_GSO and MPLSO. A Kbuild test robot reported that when NET_MPLS_GSO is selected by OPENVSWITCH the generated .config is broken because MPLS is not selected. Cc: Simon Horman Fixes: cec9166ca4e mpls: Refactor how the mpls module is built Reported-by: kbuild test robot Signed-off-by: "Eric W. Biederman" Reviewed-by: Simon Horman Signed-off-by: David S. Miller --- net/openvswitch/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/net/openvswitch/Kconfig b/net/openvswitch/Kconfig index b7d818c59423..ed6b0f8dd1bb 100644 --- a/net/openvswitch/Kconfig +++ b/net/openvswitch/Kconfig @@ -6,6 +6,7 @@ config OPENVSWITCH tristate "Open vSwitch" depends on INET select LIBCRC32C + select MPLS select NET_MPLS_GSO ---help--- Open vSwitch is a multilayer Ethernet switch targeted at virtualized -- GitLab From b79bda3d38ae67940f1740f7e015f284eb551680 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Sat, 7 Mar 2015 16:25:56 -0600 Subject: [PATCH 03423/11651] neigh: Use neigh table index for neigh_packet_xmit Remove a little bit of unnecessary work when transmitting a packet with neigh_packet_xmit. Use the neighbour table index not the address family as a parameter. Signed-off-by: "Eric W. Biederman" Signed-off-by: David S. Miller --- include/net/neighbour.h | 1 + net/core/neighbour.c | 22 +++++++++++----------- net/mpls/af_mpls.c | 35 ++++++++++++++++++++++------------- 3 files changed, 34 insertions(+), 24 deletions(-) diff --git a/include/net/neighbour.h b/include/net/neighbour.h index afb8237b0a8c..d48b8ec8b5f4 100644 --- a/include/net/neighbour.h +++ b/include/net/neighbour.h @@ -226,6 +226,7 @@ enum { NEIGH_ND_TABLE = 1, NEIGH_DN_TABLE = 2, NEIGH_NR_TABLES, + NEIGH_LINK_TABLE = NEIGH_NR_TABLES /* Pseudo table for neigh_xmit */ }; static inline int neigh_parms_family(struct neigh_parms *p) diff --git a/net/core/neighbour.c b/net/core/neighbour.c index cffaf00561e7..ad07990e943d 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -2391,22 +2391,15 @@ void __neigh_for_each_release(struct neigh_table *tbl, } EXPORT_SYMBOL(__neigh_for_each_release); -int neigh_xmit(int family, struct net_device *dev, +int neigh_xmit(int index, struct net_device *dev, const void *addr, struct sk_buff *skb) { - int err; - if (family == AF_PACKET) { - err = dev_hard_header(skb, dev, ntohs(skb->protocol), - addr, NULL, skb->len); - if (err < 0) - goto out_kfree_skb; - err = dev_queue_xmit(skb); - } else { + int err = -EAFNOSUPPORT; + if (likely(index < NEIGH_NR_TABLES)) { struct neigh_table *tbl; struct neighbour *neigh; - err = -ENETDOWN; - tbl = neigh_find_table(family); + tbl = neigh_tables[index]; if (!tbl) goto out; neigh = __neigh_lookup_noref(tbl, addr, dev); @@ -2417,6 +2410,13 @@ int neigh_xmit(int family, struct net_device *dev, goto out_kfree_skb; err = neigh->output(neigh, skb); } + else if (index == NEIGH_LINK_TABLE) { + err = dev_hard_header(skb, dev, ntohs(skb->protocol), + addr, NULL, skb->len); + if (err < 0) + goto out_kfree_skb; + err = dev_queue_xmit(skb); + } out: return err; out_kfree_skb: diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c index e120074157de..0ad8f7141be2 100644 --- a/net/mpls/af_mpls.c +++ b/net/mpls/af_mpls.c @@ -28,9 +28,9 @@ struct mpls_route { /* next hop label forwarding entry */ struct rcu_head rt_rcu; u32 rt_label[MAX_NEW_LABELS]; u8 rt_protocol; /* routing protocol that set this entry */ - u8 rt_labels:2, - rt_via_alen:6; - unsigned short rt_via_family; + u8 rt_labels; + u8 rt_via_alen; + u8 rt_via_table; u8 rt_via[0]; }; @@ -201,7 +201,7 @@ static int mpls_forward(struct sk_buff *skb, struct net_device *dev, } } - err = neigh_xmit(rt->rt_via_family, out_dev, rt->rt_via, skb); + err = neigh_xmit(rt->rt_via_table, out_dev, rt->rt_via, skb); if (err) net_dbg_ratelimited("%s: packet transmission failed: %d\n", __func__, err); @@ -225,7 +225,7 @@ static const struct nla_policy rtm_mpls_policy[RTA_MAX+1] = { struct mpls_route_config { u32 rc_protocol; u32 rc_ifindex; - u16 rc_via_family; + u16 rc_via_table; u16 rc_via_alen; u8 rc_via[MAX_VIA_ALEN]; u32 rc_label; @@ -343,7 +343,7 @@ static int mpls_route_add(struct mpls_route_config *cfg) goto errout; err = -EINVAL; - if ((cfg->rc_via_family == AF_PACKET) && + if ((cfg->rc_via_table == NEIGH_LINK_TABLE) && (dev->addr_len != cfg->rc_via_alen)) goto errout; @@ -376,7 +376,7 @@ static int mpls_route_add(struct mpls_route_config *cfg) rt->rt_label[i] = cfg->rc_output_label[i]; rt->rt_protocol = cfg->rc_protocol; RCU_INIT_POINTER(rt->rt_dev, dev); - rt->rt_via_family = cfg->rc_via_family; + rt->rt_via_table = cfg->rc_via_table; memcpy(rt->rt_via, cfg->rc_via, cfg->rc_via_alen); mpls_route_update(net, index, NULL, rt, &cfg->rc_nlinfo); @@ -448,15 +448,22 @@ static struct notifier_block mpls_dev_notifier = { }; static int nla_put_via(struct sk_buff *skb, - u16 family, const void *addr, int alen) + u8 table, const void *addr, int alen) { + static const int table_to_family[NEIGH_NR_TABLES + 1] = { + AF_INET, AF_INET6, AF_DECnet, AF_PACKET, + }; struct nlattr *nla; struct rtvia *via; + int family = AF_UNSPEC; nla = nla_reserve(skb, RTA_VIA, alen + 2); if (!nla) return -EMSGSIZE; + if (table <= NEIGH_NR_TABLES) + family = table_to_family[table]; + via = nla_data(nla); via->rtvia_family = family; memcpy(via->rtvia_addr, addr, alen); @@ -599,21 +606,23 @@ static int rtm_to_route_config(struct sk_buff *skb, struct nlmsghdr *nlh, struct rtvia *via = nla_data(nla); if (nla_len(nla) < offsetof(struct rtvia, rtvia_addr)) goto errout; - cfg->rc_via_family = via->rtvia_family; cfg->rc_via_alen = nla_len(nla) - offsetof(struct rtvia, rtvia_addr); if (cfg->rc_via_alen > MAX_VIA_ALEN) goto errout; /* Validate the address family */ - switch(cfg->rc_via_family) { + switch(via->rtvia_family) { case AF_PACKET: + cfg->rc_via_table = NEIGH_LINK_TABLE; break; case AF_INET: + cfg->rc_via_table = NEIGH_ARP_TABLE; if (cfg->rc_via_alen != 4) goto errout; break; case AF_INET6: + cfg->rc_via_table = NEIGH_ND_TABLE; if (cfg->rc_via_alen != 16) goto errout; break; @@ -686,7 +695,7 @@ static int mpls_dump_route(struct sk_buff *skb, u32 portid, u32 seq, int event, if (rt->rt_labels && nla_put_labels(skb, RTA_NEWDST, rt->rt_labels, rt->rt_label)) goto nla_put_failure; - if (nla_put_via(skb, rt->rt_via_family, rt->rt_via, rt->rt_via_alen)) + if (nla_put_via(skb, rt->rt_via_table, rt->rt_via, rt->rt_via_alen)) goto nla_put_failure; dev = rtnl_dereference(rt->rt_dev); if (dev && nla_put_u32(skb, RTA_OIF, dev->ifindex)) @@ -799,7 +808,7 @@ static int resize_platform_label_table(struct net *net, size_t limit) goto nort0; RCU_INIT_POINTER(rt0->rt_dev, lo); rt0->rt_protocol = RTPROT_KERNEL; - rt0->rt_via_family = AF_PACKET; + rt0->rt_via_table = NEIGH_LINK_TABLE; memcpy(rt0->rt_via, lo->dev_addr, lo->addr_len); } if (limit > LABEL_IPV6_EXPLICIT_NULL) { @@ -809,7 +818,7 @@ static int resize_platform_label_table(struct net *net, size_t limit) goto nort2; RCU_INIT_POINTER(rt2->rt_dev, lo); rt2->rt_protocol = RTPROT_KERNEL; - rt2->rt_via_family = AF_PACKET; + rt2->rt_via_table = NEIGH_LINK_TABLE; memcpy(rt2->rt_via, lo->dev_addr, lo->addr_len); } -- GitLab From 0595439a0a8740f776a0ae367a4c7f243add24ec Mon Sep 17 00:00:00 2001 From: Nicolas Saenz Julienne Date: Sun, 8 Mar 2015 19:21:20 +0000 Subject: [PATCH 03424/11651] power: generic-adc-battery: Fix power_supply_property returned value The POWER_SUPPLY_PROP_STATUS case in gab_get_property() wasn't providing any value. Signed-off-by: Nicolas Saenz Julienne Signed-off-by: Sebastian Reichel --- drivers/power/generic-adc-battery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/power/generic-adc-battery.c b/drivers/power/generic-adc-battery.c index d72733e4f93a..0a566ac3eefd 100644 --- a/drivers/power/generic-adc-battery.c +++ b/drivers/power/generic-adc-battery.c @@ -159,7 +159,7 @@ static int gab_get_property(struct power_supply *psy, switch (psp) { case POWER_SUPPLY_PROP_STATUS: - gab_get_status(adc_bat); + val->intval = gab_get_status(adc_bat); break; case POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN: val->intval = 0; -- GitLab From cbe21d92e4d501e4895ef668b43fd8998c9b3b02 Mon Sep 17 00:00:00 2001 From: Dinh Nguyen Date: Fri, 6 Mar 2015 17:48:28 -0600 Subject: [PATCH 03425/11651] net: stmmac: make reset control an optional requirement Not having a reset control line to the ethernet controller should not be a hard failure. Instead, add support for deferred probing and just print out a debug statement. Signed-off-by: Dinh Nguyen Cc: Vince Bridgers CC: David S. Miller Signed-off-by: David S. Miller --- drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c index e97074cd5800..5a36bd2c7837 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c @@ -91,7 +91,9 @@ static int socfpga_dwmac_parse_data(struct socfpga_dwmac *dwmac, struct device * STMMAC_RESOURCE_NAME); if (IS_ERR(dwmac->stmmac_rst)) { dev_info(dev, "Could not get reset control!\n"); - return -EINVAL; + if (PTR_ERR(dwmac->stmmac_rst) == -EPROBE_DEFER) + return -EPROBE_DEFER; + dwmac->stmmac_rst = NULL; } dwmac->interface = of_get_phy_mode(np); -- GitLab From dbedd44e982d61c156337b1a3fb252b24085f8e3 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Fri, 6 Mar 2015 20:49:12 -0800 Subject: [PATCH 03426/11651] ethernet: codespell comment spelling fixes To test a checkpatch spelling patch, I ran codespell against drivers/net/ethernet/. $ git ls-files drivers/net/ethernet/ | \ while read file ; do \ codespell -w $file; \ done I removed a false positive in e1000_hw.h Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/ethernet/allwinner/sun4i-emac.c | 2 +- drivers/net/ethernet/amd/amd8111e.c | 4 ++-- drivers/net/ethernet/amd/amd8111e.h | 2 +- drivers/net/ethernet/amd/xgbe/xgbe.h | 2 +- drivers/net/ethernet/apple/mace.c | 2 +- drivers/net/ethernet/apple/macmace.c | 2 +- drivers/net/ethernet/atheros/atl1c/atl1c_hw.c | 4 ++-- .../net/ethernet/atheros/atl1c/atl1c_main.c | 2 +- .../net/ethernet/broadcom/bnx2x/bnx2x_init.h | 2 +- .../net/ethernet/broadcom/bnx2x/bnx2x_link.c | 12 +++++------ .../net/ethernet/broadcom/bnx2x/bnx2x_reg.h | 2 +- .../net/ethernet/broadcom/bnx2x/bnx2x_stats.c | 2 +- .../net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c | 4 ++-- .../net/ethernet/brocade/bna/bfa_defs_cna.h | 2 +- drivers/net/ethernet/brocade/bna/bfa_ioc.c | 2 +- drivers/net/ethernet/brocade/bna/bfa_ioc_ct.c | 2 +- drivers/net/ethernet/brocade/bna/bfi.h | 4 ++-- .../net/ethernet/brocade/bna/bna_hw_defs.h | 2 +- drivers/net/ethernet/calxeda/xgmac.c | 20 +++++++++---------- drivers/net/ethernet/chelsio/cxgb3/t3_hw.c | 2 +- .../net/ethernet/chelsio/cxgb4/cxgb4_main.c | 2 +- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 6 +++--- drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h | 2 +- drivers/net/ethernet/chelsio/cxgb4vf/sge.c | 2 +- .../net/ethernet/chelsio/cxgb4vf/t4vf_hw.c | 2 +- drivers/net/ethernet/cirrus/cs89x0.c | 2 +- drivers/net/ethernet/dec/tulip/dmfe.c | 2 +- drivers/net/ethernet/dec/tulip/uli526x.c | 2 +- drivers/net/ethernet/emulex/benet/be_cmds.c | 2 +- drivers/net/ethernet/freescale/fec_ptp.c | 2 +- drivers/net/ethernet/intel/e100.c | 2 +- drivers/net/ethernet/intel/e1000/e1000_main.c | 2 +- .../net/ethernet/intel/i40evf/i40evf_main.c | 4 ++-- drivers/net/ethernet/intel/igb/igb_ptp.c | 2 +- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 2 +- drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c | 2 +- .../net/ethernet/intel/ixgbe/ixgbe_sriov.c | 2 +- drivers/net/ethernet/intel/ixgbe/ixgbe_type.h | 2 +- drivers/net/ethernet/intel/ixgbevf/vf.c | 2 +- drivers/net/ethernet/marvell/mvpp2.c | 4 ++-- drivers/net/ethernet/mellanox/mlx4/mlx4.h | 2 +- .../ethernet/mellanox/mlx4/resource_tracker.c | 2 +- drivers/net/ethernet/moxa/moxart_ether.c | 2 +- drivers/net/ethernet/neterion/s2io.c | 2 +- .../oki-semi/pch_gbe/pch_gbe_ethtool.c | 2 +- drivers/net/ethernet/packetengines/hamachi.c | 2 +- .../ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h | 2 +- .../ethernet/qlogic/qlcnic/qlcnic_83xx_init.c | 4 ++-- drivers/net/ethernet/qualcomm/qca_spi.c | 2 +- .../net/ethernet/samsung/sxgbe/sxgbe_main.c | 12 +++++------ drivers/net/ethernet/sfc/efx.c | 2 +- drivers/net/ethernet/sfc/farch.c | 4 ++-- drivers/net/ethernet/sfc/mcdi_pcol.h | 2 +- drivers/net/ethernet/sfc/siena_sriov.c | 2 +- drivers/net/ethernet/sfc/vfdi.h | 4 ++-- .../net/ethernet/stmicro/stmmac/stmmac_main.c | 2 +- drivers/net/ethernet/sun/sungem.c | 4 ++-- drivers/net/ethernet/ti/cpsw.c | 2 +- drivers/net/ethernet/toshiba/ps3_gelic_net.c | 2 +- drivers/net/ethernet/wiznet/w5100.c | 2 +- drivers/net/ethernet/wiznet/w5300.c | 2 +- 61 files changed, 92 insertions(+), 92 deletions(-) diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c b/drivers/net/ethernet/allwinner/sun4i-emac.c index f3470d96837a..bab01c849165 100644 --- a/drivers/net/ethernet/allwinner/sun4i-emac.c +++ b/drivers/net/ethernet/allwinner/sun4i-emac.c @@ -757,7 +757,7 @@ static void emac_shutdown(struct net_device *dev) /* Disable all interrupt */ writel(0, db->membase + EMAC_INT_CTL_REG); - /* clear interupt status */ + /* clear interrupt status */ reg_val = readl(db->membase + EMAC_INT_STA_REG); writel(reg_val, db->membase + EMAC_INT_STA_REG); diff --git a/drivers/net/ethernet/amd/amd8111e.c b/drivers/net/ethernet/amd/amd8111e.c index 4c2ae2221780..94960055fa1f 100644 --- a/drivers/net/ethernet/amd/amd8111e.c +++ b/drivers/net/ethernet/amd/amd8111e.c @@ -723,13 +723,13 @@ static int amd8111e_rx_poll(struct napi_struct *napi, int budget) * the last correctly noting the error. */ if(status & ERR_BIT) { - /* reseting flags */ + /* resetting flags */ lp->rx_ring[rx_index].rx_flags &= RESET_RX_FLAGS; goto err_next_pkt; } /* check for STP and ENP */ if(!((status & STP_BIT) && (status & ENP_BIT))){ - /* reseting flags */ + /* resetting flags */ lp->rx_ring[rx_index].rx_flags &= RESET_RX_FLAGS; goto err_next_pkt; } diff --git a/drivers/net/ethernet/amd/amd8111e.h b/drivers/net/ethernet/amd/amd8111e.h index a75092d584cc..7cdb18512407 100644 --- a/drivers/net/ethernet/amd/amd8111e.h +++ b/drivers/net/ethernet/amd/amd8111e.h @@ -614,7 +614,7 @@ typedef enum { /* Assume contoller gets data 10 times the maximum processing time */ #define REPEAT_CNT 10 -/* amd8111e decriptor flag definitions */ +/* amd8111e descriptor flag definitions */ typedef enum { OWN_BIT = (1 << 15), diff --git a/drivers/net/ethernet/amd/xgbe/xgbe.h b/drivers/net/ethernet/amd/xgbe/xgbe.h index 13e8f95c077c..1eea3e5a5d08 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe.h +++ b/drivers/net/ethernet/amd/xgbe/xgbe.h @@ -620,7 +620,7 @@ struct xgbe_hw_features { unsigned int mgk; /* PMT magic packet */ unsigned int mmc; /* RMON module */ unsigned int aoe; /* ARP Offload */ - unsigned int ts; /* IEEE 1588-2008 Adavanced Timestamp */ + unsigned int ts; /* IEEE 1588-2008 Advanced Timestamp */ unsigned int eee; /* Energy Efficient Ethernet */ unsigned int tx_coe; /* Tx Checksum Offload */ unsigned int rx_coe; /* Rx Checksum Offload */ diff --git a/drivers/net/ethernet/apple/mace.c b/drivers/net/ethernet/apple/mace.c index 842fe7684904..7fcaf0da42a8 100644 --- a/drivers/net/ethernet/apple/mace.c +++ b/drivers/net/ethernet/apple/mace.c @@ -720,7 +720,7 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id) mace_reset(dev); /* * XXX mace likes to hang the machine after a xmtfs error. - * This is hard to reproduce, reseting *may* help + * This is hard to reproduce, resetting *may* help */ } cp = mp->tx_cmds + NCMDS_TX * i; diff --git a/drivers/net/ethernet/apple/macmace.c b/drivers/net/ethernet/apple/macmace.c index 6e66127e6abf..89914ca17a49 100644 --- a/drivers/net/ethernet/apple/macmace.c +++ b/drivers/net/ethernet/apple/macmace.c @@ -575,7 +575,7 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id) mace_reset(dev); /* * XXX mace likes to hang the machine after a xmtfs error. - * This is hard to reproduce, reseting *may* help + * This is hard to reproduce, resetting *may* help */ } /* dma should have finished */ diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c b/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c index 52fdfe225978..a8b80c56ac25 100644 --- a/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c +++ b/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c @@ -307,7 +307,7 @@ void atl1c_start_phy_polling(struct atl1c_hw *hw, u16 clk_sel) /* * atl1c_read_phy_core - * core funtion to read register in PHY via MDIO control regsiter. + * core function to read register in PHY via MDIO control regsiter. * ext: extension register (see IEEE 802.3) * dev: device address (see IEEE 802.3 DEVAD, PRTAD is fixed to 0) * reg: reg to read @@ -356,7 +356,7 @@ int atl1c_read_phy_core(struct atl1c_hw *hw, bool ext, u8 dev, /* * atl1c_write_phy_core - * core funtion to write to register in PHY via MDIO control regsiter. + * core function to write to register in PHY via MDIO control register. * ext: extension register (see IEEE 802.3) * dev: device address (see IEEE 802.3 DEVAD, PRTAD is fixed to 0) * reg: reg to write diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c index 587f63e87588..932bd1862f7a 100644 --- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c +++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c @@ -752,7 +752,7 @@ static void atl1c_patch_assign(struct atl1c_hw *hw) if (hw->device_id == PCI_DEVICE_ID_ATHEROS_L2C_B2 && hw->revision_id == L2CB_V21) { - /* config acess mode */ + /* config access mode */ pci_write_config_dword(pdev, REG_PCIE_IND_ACC_ADDR, REG_PCIE_DEV_MISC_CTRL); pci_read_config_dword(pdev, REG_PCIE_IND_ACC_DATA, &misc_ctrl); diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h index bd90e50bd8e6..d6e1975b7b69 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h @@ -278,7 +278,7 @@ static inline void bnx2x_dcb_config_qm(struct bnx2x *bp, enum cos_mode mode, } -/* congestion managment port init api description +/* congestion management port init api description * the api works as follows: * the driver should pass the cmng_init_input struct, the port_init function * will prepare the required internal ram structure which will be passed back diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index 778e4cd32571..b7c77b26a8a4 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c @@ -563,7 +563,7 @@ static void bnx2x_ets_e3b0_set_credit_upper_bound_nig( * Will return the NIG ETS registers to init values.Except * credit_upper_bound. * That isn't used in this configuration (No WFQ is enabled) and will be -* configured acording to spec +* configured according to spec *. ******************************************************************************/ static void bnx2x_ets_e3b0_nig_disabled(const struct link_params *params, @@ -680,7 +680,7 @@ static void bnx2x_ets_e3b0_set_credit_upper_bound_pbf( * Will return the PBF ETS registers to init values.Except * credit_upper_bound. * That isn't used in this configuration (No WFQ is enabled) and will be -* configured acording to spec +* configured according to spec *. ******************************************************************************/ static void bnx2x_ets_e3b0_pbf_disabled(const struct link_params *params) @@ -738,7 +738,7 @@ static void bnx2x_ets_e3b0_pbf_disabled(const struct link_params *params) } /****************************************************************************** * Description: -* E3B0 disable will return basicly the values to init values. +* E3B0 disable will return basically the values to init values. *. ******************************************************************************/ static int bnx2x_ets_e3b0_disabled(const struct link_params *params, @@ -761,7 +761,7 @@ static int bnx2x_ets_e3b0_disabled(const struct link_params *params, /****************************************************************************** * Description: -* Disable will return basicly the values to init values. +* Disable will return basically the values to init values. * ******************************************************************************/ int bnx2x_ets_disabled(struct link_params *params, @@ -2938,7 +2938,7 @@ static int bnx2x_eee_initial_config(struct link_params *params, { vars->eee_status |= ((u32) mode) << SHMEM_EEE_SUPPORTED_SHIFT; - /* Propogate params' bits --> vars (for migration exposure) */ + /* Propagate params' bits --> vars (for migration exposure) */ if (params->eee_mode & EEE_MODE_ENABLE_LPI) vars->eee_status |= SHMEM_EEE_LPI_REQUESTED_BIT; else @@ -13308,7 +13308,7 @@ static void bnx2x_check_over_curr(struct link_params *params, vars->phy_flags &= ~PHY_OVER_CURRENT_FLAG; } -/* Returns 0 if no change occured since last check; 1 otherwise. */ +/* Returns 0 if no change occurred since last check; 1 otherwise. */ static u8 bnx2x_analyze_link_error(struct link_params *params, struct link_vars *vars, u32 status, u32 phy_flag, u32 link_flag, u8 notify) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h index 6fe547c93e74..0770e4bff89b 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h @@ -29,7 +29,7 @@ #define ATC_ATC_INT_STS_REG_ATC_TCPL_TO_NOT_PEND (0x1<<1) /* [RW 1] Initiate the ATC array - reset all the valid bits */ #define ATC_REG_ATC_INIT_ARRAY 0x1100b8 -/* [R 1] ATC initalization done */ +/* [R 1] ATC initialization done */ #define ATC_REG_ATC_INIT_DONE 0x1100bc /* [RC 6] Interrupt register #0 read clear */ #define ATC_REG_ATC_INT_STS_CLR 0x1101c0 diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c index d1608297c773..612cafb5df53 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c @@ -1620,7 +1620,7 @@ void bnx2x_memset_stats(struct bnx2x *bp) if (bp->port.pmf && bp->port.port_stx) bnx2x_port_stats_base_init(bp); - /* mark the end of statistics initializiation */ + /* mark the end of statistics initialization */ bp->stats_init = false; } diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c index be40eabc5304..15b2d1647560 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c @@ -800,7 +800,7 @@ int bnx2x_vfpf_config_rss(struct bnx2x *bp, req->rss_key_size = T_ETH_RSS_KEY; req->rss_result_mask = params->rss_result_mask; - /* flags handled individually for backward/forward compatability */ + /* flags handled individually for backward/forward compatibility */ if (params->rss_flags & (1 << BNX2X_RSS_MODE_DISABLED)) req->rss_flags |= VFPF_RSS_MODE_DISABLED; if (params->rss_flags & (1 << BNX2X_RSS_MODE_REGULAR)) @@ -1869,7 +1869,7 @@ static void bnx2x_vf_mbx_update_rss(struct bnx2x *bp, struct bnx2x_virtf *vf, rss.rss_obj = &vf->rss_conf_obj; rss.rss_result_mask = rss_tlv->rss_result_mask; - /* flags handled individually for backward/forward compatability */ + /* flags handled individually for backward/forward compatibility */ rss.rss_flags = 0; rss.ramrod_flags = 0; diff --git a/drivers/net/ethernet/brocade/bna/bfa_defs_cna.h b/drivers/net/ethernet/brocade/bna/bfa_defs_cna.h index 63e300f5ba41..a37326d44fbb 100644 --- a/drivers/net/ethernet/brocade/bna/bfa_defs_cna.h +++ b/drivers/net/ethernet/brocade/bna/bfa_defs_cna.h @@ -135,7 +135,7 @@ struct bfa_cee_lldp_str { u8 value[BFA_CEE_LLDP_MAX_STRING_LEN]; }; -/* LLDP paramters */ +/* LLDP parameters */ struct bfa_cee_lldp_cfg { struct bfa_cee_lldp_str chassis_id; struct bfa_cee_lldp_str port_id; diff --git a/drivers/net/ethernet/brocade/bna/bfa_ioc.c b/drivers/net/ethernet/brocade/bna/bfa_ioc.c index f2d13238b02e..594a2ab36d31 100644 --- a/drivers/net/ethernet/brocade/bna/bfa_ioc.c +++ b/drivers/net/ethernet/brocade/bna/bfa_ioc.c @@ -1340,7 +1340,7 @@ bfa_ioc_fwver_md5_check(struct bfi_ioc_image_hdr *fwhdr_1, return true; } -/* Returns TRUE if major minor and maintainence are same. +/* Returns TRUE if major minor and maintenance are same. * If patch version are same, check for MD5 Checksum to be same. */ static bool diff --git a/drivers/net/ethernet/brocade/bna/bfa_ioc_ct.c b/drivers/net/ethernet/brocade/bna/bfa_ioc_ct.c index 66c8507d7717..2e72445dbb4f 100644 --- a/drivers/net/ethernet/brocade/bna/bfa_ioc_ct.c +++ b/drivers/net/ethernet/brocade/bna/bfa_ioc_ct.c @@ -699,7 +699,7 @@ bfa_ioc_ct2_sclk_init(void __iomem *rb) /* * Ignore mode and program for the max clock (which is FC16) - * Firmware/NFC will do the PLL init appropiately + * Firmware/NFC will do the PLL init appropriately */ r32 = readl((rb + CT2_APP_PLL_SCLK_CTL_REG)); r32 &= ~(__APP_PLL_SCLK_REFCLK_SEL | __APP_PLL_SCLK_CLK_DIV2); diff --git a/drivers/net/ethernet/brocade/bna/bfi.h b/drivers/net/ethernet/brocade/bna/bfi.h index f1e1129e6241..2bcde4042268 100644 --- a/drivers/net/ethernet/brocade/bna/bfi.h +++ b/drivers/net/ethernet/brocade/bna/bfi.h @@ -159,8 +159,8 @@ enum bfi_asic_gen { }; enum bfi_asic_mode { - BFI_ASIC_MODE_FC = 1, /* FC upto 8G speed */ - BFI_ASIC_MODE_FC16 = 2, /* FC upto 16G speed */ + BFI_ASIC_MODE_FC = 1, /* FC up to 8G speed */ + BFI_ASIC_MODE_FC16 = 2, /* FC up to 16G speed */ BFI_ASIC_MODE_ETH = 3, /* Ethernet ports */ BFI_ASIC_MODE_COMBO = 4, /* FC 16G and Ethernet 10G port */ }; diff --git a/drivers/net/ethernet/brocade/bna/bna_hw_defs.h b/drivers/net/ethernet/brocade/bna/bna_hw_defs.h index c5feab130d6d..174af0e9d056 100644 --- a/drivers/net/ethernet/brocade/bna/bna_hw_defs.h +++ b/drivers/net/ethernet/brocade/bna/bna_hw_defs.h @@ -363,7 +363,7 @@ struct bna_txq_wi_vector { /* TxQ Entry Structure * - * BEWARE: Load values into this structure with correct endianess. + * BEWARE: Load values into this structure with correct endianness. */ struct bna_txq_entry { union { diff --git a/drivers/net/ethernet/calxeda/xgmac.c b/drivers/net/ethernet/calxeda/xgmac.c index 47bfea24b9e1..63efa0dc45ba 100644 --- a/drivers/net/ethernet/calxeda/xgmac.c +++ b/drivers/net/ethernet/calxeda/xgmac.c @@ -47,9 +47,9 @@ #define XGMAC_REMOTE_WAKE 0x00000700 /* Remote Wake-Up Frm Filter */ #define XGMAC_PMT 0x00000704 /* PMT Control and Status */ #define XGMAC_MMC_CTRL 0x00000800 /* XGMAC MMC Control */ -#define XGMAC_MMC_INTR_RX 0x00000804 /* Recieve Interrupt */ +#define XGMAC_MMC_INTR_RX 0x00000804 /* Receive Interrupt */ #define XGMAC_MMC_INTR_TX 0x00000808 /* Transmit Interrupt */ -#define XGMAC_MMC_INTR_MASK_RX 0x0000080c /* Recieve Interrupt Mask */ +#define XGMAC_MMC_INTR_MASK_RX 0x0000080c /* Receive Interrupt Mask */ #define XGMAC_MMC_INTR_MASK_TX 0x00000810 /* Transmit Interrupt Mask */ /* Hardware TX Statistics Counters */ @@ -153,7 +153,7 @@ #define XGMAC_FLOW_CTRL_PT_MASK 0xffff0000 /* Pause Time Mask */ #define XGMAC_FLOW_CTRL_PT_SHIFT 16 #define XGMAC_FLOW_CTRL_DZQP 0x00000080 /* Disable Zero-Quanta Phase */ -#define XGMAC_FLOW_CTRL_PLT 0x00000020 /* Pause Low Threshhold */ +#define XGMAC_FLOW_CTRL_PLT 0x00000020 /* Pause Low Threshold */ #define XGMAC_FLOW_CTRL_PLT_MASK 0x00000030 /* PLT MASK */ #define XGMAC_FLOW_CTRL_UP 0x00000008 /* Unicast Pause Frame Detect */ #define XGMAC_FLOW_CTRL_RFE 0x00000004 /* Rx Flow Control Enable */ @@ -254,18 +254,18 @@ /* XGMAC Operation Mode Register */ #define XGMAC_OMR_TSF 0x00200000 /* TX FIFO Store and Forward */ #define XGMAC_OMR_FTF 0x00100000 /* Flush Transmit FIFO */ -#define XGMAC_OMR_TTC 0x00020000 /* Transmit Threshhold Ctrl */ +#define XGMAC_OMR_TTC 0x00020000 /* Transmit Threshold Ctrl */ #define XGMAC_OMR_TTC_MASK 0x00030000 -#define XGMAC_OMR_RFD 0x00006000 /* FC Deactivation Threshhold */ -#define XGMAC_OMR_RFD_MASK 0x00007000 /* FC Deact Threshhold MASK */ -#define XGMAC_OMR_RFA 0x00000600 /* FC Activation Threshhold */ -#define XGMAC_OMR_RFA_MASK 0x00000E00 /* FC Act Threshhold MASK */ +#define XGMAC_OMR_RFD 0x00006000 /* FC Deactivation Threshold */ +#define XGMAC_OMR_RFD_MASK 0x00007000 /* FC Deact Threshold MASK */ +#define XGMAC_OMR_RFA 0x00000600 /* FC Activation Threshold */ +#define XGMAC_OMR_RFA_MASK 0x00000E00 /* FC Act Threshold MASK */ #define XGMAC_OMR_EFC 0x00000100 /* Enable Hardware FC */ #define XGMAC_OMR_FEF 0x00000080 /* Forward Error Frames */ #define XGMAC_OMR_DT 0x00000040 /* Drop TCP/IP csum Errors */ #define XGMAC_OMR_RSF 0x00000020 /* RX FIFO Store and Forward */ -#define XGMAC_OMR_RTC_256 0x00000018 /* RX Threshhold Ctrl */ -#define XGMAC_OMR_RTC_MASK 0x00000018 /* RX Threshhold Ctrl MASK */ +#define XGMAC_OMR_RTC_256 0x00000018 /* RX Threshold Ctrl */ +#define XGMAC_OMR_RTC_MASK 0x00000018 /* RX Threshold Ctrl MASK */ /* XGMAC HW Features Register */ #define DMA_HW_FEAT_TXCOESEL 0x00010000 /* TX Checksum offload */ diff --git a/drivers/net/ethernet/chelsio/cxgb3/t3_hw.c b/drivers/net/ethernet/chelsio/cxgb3/t3_hw.c index 184a8d545ac4..a22768c94200 100644 --- a/drivers/net/ethernet/chelsio/cxgb3/t3_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb3/t3_hw.c @@ -840,7 +840,7 @@ static int flash_wait_op(struct adapter *adapter, int attempts, int delay) * Read the specified number of 32-bit words from the serial flash. * If @byte_oriented is set the read data is stored as a byte array * (i.e., big-endian), otherwise as 32-bit words in the platform's - * natural endianess. + * natural endianness. */ static int t3_read_flash(struct adapter *adapter, unsigned int addr, unsigned int nwords, u32 *data, int byte_oriented) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index e344bdcd40b3..4af8a9fd75ae 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -5366,7 +5366,7 @@ static int adap_init0(struct adapter *adap) adap->tids.stid_base = val[1]; adap->tids.nstids = val[2] - val[1] + 1; /* - * Setup server filter region. Divide the availble filter + * Setup server filter region. Divide the available filter * region into two parts. Regular filters get 1/3rd and server * filters get 2/3rd part. This is only enabled if workarond * path is enabled. diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index 853c38997c82..1498d078c319 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -867,7 +867,7 @@ static int flash_wait_op(struct adapter *adapter, int attempts, int delay) * Read the specified number of 32-bit words from the serial flash. * If @byte_oriented is set the read data is stored as a byte array * (i.e., big-endian), otherwise as 32-bit words in the platform's - * natural endianess. + * natural endianness. */ int t4_read_flash(struct adapter *adapter, unsigned int addr, unsigned int nwords, u32 *data, int byte_oriented) @@ -3558,7 +3558,7 @@ int t4_fixup_host_params(struct adapter *adap, unsigned int page_size, * For the single-MTU buffers in unpacked mode we need to include * space for the SGE Control Packet Shift, 14 byte Ethernet header, * possible 4 byte VLAN tag, all rounded up to the next Ingress Packet - * Padding boundry. All of these are accommodated in the Factory + * Padding boundary. All of these are accommodated in the Factory * Default Firmware Configuration File but we need to adjust it for * this host's cache line size. */ @@ -4529,7 +4529,7 @@ int t4_init_tp_params(struct adapter *adap) PROTOCOL_F); /* If TP_INGRESS_CONFIG.VNID == 0, then TP_VLAN_PRI_MAP.VNIC_ID - * represents the presense of an Outer VLAN instead of a VNIC ID. + * represents the presence of an Outer VLAN instead of a VNIC ID. */ if ((adap->params.tp.ingress_config & VNIC_F) == 0) adap->params.tp.vnic_shift = -1; diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h index 9b353a88cbda..d136ca6a0c8a 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h @@ -36,7 +36,7 @@ #define _T4FW_INTERFACE_H_ enum fw_retval { - FW_SUCCESS = 0, /* completed sucessfully */ + FW_SUCCESS = 0, /* completed successfully */ FW_EPERM = 1, /* operation not permitted */ FW_ENOENT = 2, /* no such file or directory */ FW_EIO = 5, /* input/output error; hw bad */ diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c index 0545f0de1c52..5ba14b32c370 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c @@ -875,7 +875,7 @@ static inline unsigned int calc_tx_flits(const struct sk_buff *skb) * Write Header (incorporated as part of the cpl_tx_pkt_lso and * cpl_tx_pkt structures), followed by either a TX Packet Write CPL * message or, if we're doing a Large Send Offload, an LSO CPL message - * with an embeded TX Packet Write CPL message. + * with an embedded TX Packet Write CPL message. */ flits = sgl_len(skb_shinfo(skb)->nr_frags + 1); if (skb_shinfo(skb)->gso_size) diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c index 1b5506df35b1..c21e2e954ad8 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c @@ -339,7 +339,7 @@ int t4vf_port_init(struct adapter *adapter, int pidx) * @adapter: the adapter * * Issues a reset command to FW. For a Physical Function this would - * result in the Firmware reseting all of its state. For a Virtual + * result in the Firmware resetting all of its state. For a Virtual * Function this just resets the state associated with the VF. */ int t4vf_fw_reset(struct adapter *adapter) diff --git a/drivers/net/ethernet/cirrus/cs89x0.c b/drivers/net/ethernet/cirrus/cs89x0.c index d1c025fd9726..60383040d6c6 100644 --- a/drivers/net/ethernet/cirrus/cs89x0.c +++ b/drivers/net/ethernet/cirrus/cs89x0.c @@ -1578,7 +1578,7 @@ out1: #ifndef CONFIG_CS89x0_PLATFORM /* - * This function converts the I/O port addres used by the cs89x0_probe() and + * This function converts the I/O port address used by the cs89x0_probe() and * init_module() functions to the I/O memory address used by the * cs89x0_probe1() function. */ diff --git a/drivers/net/ethernet/dec/tulip/dmfe.c b/drivers/net/ethernet/dec/tulip/dmfe.c index 50a00777228e..afd8e78e024e 100644 --- a/drivers/net/ethernet/dec/tulip/dmfe.c +++ b/drivers/net/ethernet/dec/tulip/dmfe.c @@ -653,7 +653,7 @@ static void dmfe_init_dm910x(struct DEVICE *dev) if ( !(db->media_mode & DMFE_AUTO) ) db->op_mode = db->media_mode; /* Force Mode */ - /* Initialize Transmit/Receive decriptor and CR3/4 */ + /* Initialize Transmit/Receive descriptor and CR3/4 */ dmfe_descriptor_init(dev); /* Init CR6 to program DM910x operation */ diff --git a/drivers/net/ethernet/dec/tulip/uli526x.c b/drivers/net/ethernet/dec/tulip/uli526x.c index 1c5916b13778..2c30c0c83f98 100644 --- a/drivers/net/ethernet/dec/tulip/uli526x.c +++ b/drivers/net/ethernet/dec/tulip/uli526x.c @@ -564,7 +564,7 @@ static void uli526x_init(struct net_device *dev) if ( !(db->media_mode & ULI526X_AUTO) ) db->op_mode = db->media_mode; /* Force Mode */ - /* Initialize Transmit/Receive decriptor and CR3/4 */ + /* Initialize Transmit/Receive descriptor and CR3/4 */ uli526x_descriptor_init(dev, ioaddr); /* Init CR6 to program M526X operation */ diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c index 75cb4610423b..dc278391a391 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/drivers/net/ethernet/emulex/benet/be_cmds.c @@ -3021,7 +3021,7 @@ int be_cmd_get_mac_from_list(struct be_adapter *adapter, u8 *mac, mac_count = resp->true_mac_count + resp->pseudo_mac_count; /* Mac list returned could contain one or more active mac_ids - * or one or more true or pseudo permanant mac addresses. + * or one or more true or pseudo permanent mac addresses. * If an active mac_id is present, return first active mac_id * found. */ diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c index 1f9cf2345266..4585895ddc9a 100644 --- a/drivers/net/ethernet/freescale/fec_ptp.c +++ b/drivers/net/ethernet/freescale/fec_ptp.c @@ -136,7 +136,7 @@ static int fec_ptp_enable_pps(struct fec_enet_private *fep, uint enable) */ writel(FEC_T_TF_MASK, fep->hwp + FEC_TCSR(fep->pps_channel)); - /* It is recommended to doulbe check the TMODE field in the + /* It is recommended to double check the TMODE field in the * TCSR register to be cleared before the first compare counter * is written into TCCR register. Just add a double check. */ diff --git a/drivers/net/ethernet/intel/e100.c b/drivers/net/ethernet/intel/e100.c index e9c3a87e5b11..05f88394f9a5 100644 --- a/drivers/net/ethernet/intel/e100.c +++ b/drivers/net/ethernet/intel/e100.c @@ -414,7 +414,7 @@ enum cb_status { /** * cb_command - Command Block flags - * @cb_tx_nc: 0: controler does CRC (normal), 1: CRC from skb memory + * @cb_tx_nc: 0: controller does CRC (normal), 1: CRC from skb memory */ enum cb_command { cb_nop = 0x0000, diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c index 73c98d34fa1f..b548ef0cf56b 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_main.c +++ b/drivers/net/ethernet/intel/e1000/e1000_main.c @@ -1116,7 +1116,7 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (e1000_read_mac_addr(hw)) e_err(probe, "EEPROM Read Error\n"); } - /* don't block initalization here due to bad MAC address */ + /* don't block initialization here due to bad MAC address */ memcpy(netdev->dev_addr, hw->mac_addr, netdev->addr_len); if (!is_valid_ether_addr(netdev->dev_addr)) diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c b/drivers/net/ethernet/intel/i40evf/i40evf_main.c index 8537416123a5..f44911df286a 100644 --- a/drivers/net/ethernet/intel/i40evf/i40evf_main.c +++ b/drivers/net/ethernet/intel/i40evf/i40evf_main.c @@ -2009,7 +2009,7 @@ static int i40evf_check_reset_complete(struct i40e_hw *hw) * * This task completes the work that was begun in probe. Due to the nature * of VF-PF communications, we may need to wait tens of milliseconds to get - * reponses back from the PF. Rather than busy-wait in probe and bog down the + * responses back from the PF. Rather than busy-wait in probe and bog down the * whole system, we'll do it in a task so we can sleep. * This task only runs during driver init. Once we've established * communications with the PF driver and set up our netdev, the watchdog @@ -2400,7 +2400,7 @@ static int i40evf_suspend(struct pci_dev *pdev, pm_message_t state) } /** - * i40evf_resume - Power managment resume routine + * i40evf_resume - Power management resume routine * @pdev: PCI device information struct * * Called when the system (VM) is resumed from sleep/suspend. diff --git a/drivers/net/ethernet/intel/igb/igb_ptp.c b/drivers/net/ethernet/intel/igb/igb_ptp.c index d6be4c69172d..52d01b8b01ed 100644 --- a/drivers/net/ethernet/intel/igb/igb_ptp.c +++ b/drivers/net/ethernet/intel/igb/igb_ptp.c @@ -30,7 +30,7 @@ * * Neither the 82576 nor the 82580 offer registers wide enough to hold * nanoseconds time values for very long. For the 82580, SYSTIM always - * counts nanoseconds, but the upper 24 bits are not availible. The + * counts nanoseconds, but the upper 24 bits are not available. The * frequency is adjusted by changing the 32 bit fractional nanoseconds * register, TIMINCA. * diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 903664ff6904..21aea7e7f03f 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -2609,7 +2609,7 @@ static irqreturn_t ixgbe_msix_other(int irq, void *data) eicr = IXGBE_READ_REG(hw, IXGBE_EICS); /* The lower 16bits of the EICR register are for the queue interrupts - * which should be masked here in order to not accidently clear them if + * which should be masked here in order to not accidentally clear them if * the bits are high when ixgbe_msix_other is called. There is a race * condition otherwise which results in possible performance loss * especially if the ixgbe_msix_other interrupt is triggering diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c index 79c00f57d3e7..bd46f5d1c943 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c @@ -488,7 +488,7 @@ static void ixgbe_ptp_tx_hwtstamp(struct ixgbe_adapter *adapter) * @work: pointer to the work struct * * This work item polls TSYNCTXCTL valid bit to determine when a Tx hardware - * timestamp has been taken for the current skb. It is necesary, because the + * timestamp has been taken for the current skb. It is necessary, because the * descriptor's "done" bit does not correlate with the timestamp event. */ static void ixgbe_ptp_tx_hwtstamp_work(struct work_struct *work) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c index 7f37fe7269a7..09a291bb7c34 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c @@ -141,7 +141,7 @@ void ixgbe_enable_sriov(struct ixgbe_adapter *adapter) * The 82599 supports up to 64 VFs per physical function * but this implementation limits allocation to 63 so that * basic networking resources are still available to the - * physical function. If the user requests greater thn + * physical function. If the user requests greater than * 63 VFs then it is an error - reset to default of zero. */ adapter->num_vfs = min_t(unsigned int, adapter->num_vfs, IXGBE_MAX_VFS_DRV_LIMIT); diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h index fc5ecee56ca8..8451f9a7cbd8 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h @@ -1690,7 +1690,7 @@ enum { #define IXGBE_MACC_FS 0x00040000 #define IXGBE_MAC_RX2TX_LPBK 0x00000002 -/* Veto Bit definiton */ +/* Veto Bit definition */ #define IXGBE_MMNGC_MNG_VETO 0x00000001 /* LINKS Bit Masks */ diff --git a/drivers/net/ethernet/intel/ixgbevf/vf.c b/drivers/net/ethernet/intel/ixgbevf/vf.c index cdb53be7d995..f510a5822f90 100644 --- a/drivers/net/ethernet/intel/ixgbevf/vf.c +++ b/drivers/net/ethernet/intel/ixgbevf/vf.c @@ -65,7 +65,7 @@ static s32 ixgbevf_init_hw_vf(struct ixgbe_hw *hw) * ixgbevf_reset_hw_vf - Performs hardware reset * @hw: pointer to hardware structure * - * Resets the hardware by reseting the transmit and receive units, masks and + * Resets the hardware by resetting the transmit and receive units, masks and * clears all interrupts. **/ static s32 ixgbevf_reset_hw_vf(struct ixgbe_hw *hw) diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c index fdf3e382e464..3e8b1bfb1f2e 100644 --- a/drivers/net/ethernet/marvell/mvpp2.c +++ b/drivers/net/ethernet/marvell/mvpp2.c @@ -1423,7 +1423,7 @@ static void mvpp2_prs_mac_promisc_set(struct mvpp2 *priv, int port, bool add) { struct mvpp2_prs_entry pe; - /* Promiscous mode - Accept unknown packets */ + /* Promiscuous mode - Accept unknown packets */ if (priv->prs_shadow[MVPP2_PE_MAC_PROMISCUOUS].valid) { /* Entry exist - update port only */ @@ -3402,7 +3402,7 @@ static void mvpp2_bm_bufs_free(struct mvpp2 *priv, struct mvpp2_bm_pool *bm_pool for (i = 0; i < bm_pool->buf_num; i++) { u32 vaddr; - /* Get buffer virtual adress (indirect access) */ + /* Get buffer virtual address (indirect access) */ mvpp2_read(priv, MVPP2_BM_PHY_ALLOC_REG(bm_pool->id)); vaddr = mvpp2_read(priv, MVPP2_BM_VIRT_ALLOC_REG); if (!vaddr) diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h index 1409d0cd6143..0b16db015745 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h @@ -175,7 +175,7 @@ enum mlx4_res_tracker_free_type { /* *Virtual HCR structures. - * mlx4_vhcr is the sw representation, in machine endianess + * mlx4_vhcr is the sw representation, in machine endianness * * mlx4_vhcr_cmd is the formalized structure, the one that is passed * to FW to go through communication channel. diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index d97ca88c55b5..d43e25914d19 100644 --- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c @@ -3027,7 +3027,7 @@ int mlx4_WRITE_MTT_wrapper(struct mlx4_dev *dev, int slave, /* Call the SW implementation of write_mtt: * - Prepare a dummy mtt struct - * - Translate inbox contents to simple addresses in host endianess */ + * - Translate inbox contents to simple addresses in host endianness */ mtt.offset = 0; /* TBD this is broken but I don't handle it since we don't really use it */ mtt.order = 0; diff --git a/drivers/net/ethernet/moxa/moxart_ether.c b/drivers/net/ethernet/moxa/moxart_ether.c index 6c72e74fef3e..81d0f1c86d6d 100644 --- a/drivers/net/ethernet/moxa/moxart_ether.c +++ b/drivers/net/ethernet/moxa/moxart_ether.c @@ -150,7 +150,7 @@ static void moxart_mac_setup_desc_ring(struct net_device *ndev) priv->rx_head = 0; - /* reset the MAC controler TX/RX desciptor base address */ + /* reset the MAC controller TX/RX desciptor base address */ writel(priv->tx_base, priv->base + REG_TXR_BASE_ADDRESS); writel(priv->rx_base, priv->base + REG_RXR_BASE_ADDRESS); } diff --git a/drivers/net/ethernet/neterion/s2io.c b/drivers/net/ethernet/neterion/s2io.c index a4cdf2f8041a..092dcae0d4a9 100644 --- a/drivers/net/ethernet/neterion/s2io.c +++ b/drivers/net/ethernet/neterion/s2io.c @@ -1343,7 +1343,7 @@ static int init_nic(struct s2io_nic *nic) TX_PA_CFG_IGNORE_L2_ERR; writeq(val64, &bar0->tx_pa_cfg); - /* Rx DMA intialization. */ + /* Rx DMA initialization. */ val64 = 0; for (i = 0; i < config->rx_ring_num; i++) { struct rx_ring_config *rx_cfg = &config->rx_cfg[i]; diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_ethtool.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_ethtool.c index 4fe8ea96bd25..f6fcf7450352 100644 --- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_ethtool.c +++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_ethtool.c @@ -394,7 +394,7 @@ static void pch_gbe_get_pauseparam(struct net_device *netdev, } /** - * pch_gbe_set_pauseparam - Set pause paramters + * pch_gbe_set_pauseparam - Set pause parameters * @netdev: Network interface device structure * @pause: Pause parameters structure * Returns: diff --git a/drivers/net/ethernet/packetengines/hamachi.c b/drivers/net/ethernet/packetengines/hamachi.c index 319d9d40f922..13d88a6025c8 100644 --- a/drivers/net/ethernet/packetengines/hamachi.c +++ b/drivers/net/ethernet/packetengines/hamachi.c @@ -350,7 +350,7 @@ V. Recent Changes incorrectly defined and corrected (as per Michel Mueller). 02/23/1999 EPK Corrected the Tx full check to check that at least 4 slots - were available before reseting the tbusy and tx_full flags + were available before resetting the tbusy and tx_full flags (as per Michel Mueller). 03/11/1999 EPK Added Pete Wyckoff's hardware checksumming support. diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h index f3346a3779d3..69f828eb42cf 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h @@ -205,7 +205,7 @@ struct qlcnic_add_rings_mbx_out { * @phys_addr_{low|high}: DMA address of the transmit buffer * @cnsmr_index_{low|high}: host consumer index * @size: legth of transmit buffer ring - * @intr_id: interrput id + * @intr_id: interrupt id * @src: src of interrupt */ struct qlcnic_tx_mbx { diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c index 2bb48d57e7a5..33669c29b341 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c @@ -269,7 +269,7 @@ static int qlcnic_83xx_idc_clear_registers(struct qlcnic_adapter *adapter, } QLCWRX(adapter->ahw, QLC_83XX_IDC_DRV_ACK, 0); - /* Clear gracefull reset bit */ + /* Clear graceful reset bit */ val = QLCRDX(adapter->ahw, QLC_83XX_IDC_CTRL); val &= ~QLC_83XX_IDC_GRACEFULL_RESET; QLCWRX(adapter->ahw, QLC_83XX_IDC_CTRL, val); @@ -889,7 +889,7 @@ static int qlcnic_83xx_idc_ready_state(struct qlcnic_adapter *adapter) * @adapter: adapter structure * * Device will remain in this state until: - * Reset request ACK's are recieved from all the functions + * Reset request ACK's are received from all the functions * Wait time exceeds max time limit * * Returns: Error code or Success(0) diff --git a/drivers/net/ethernet/qualcomm/qca_spi.c b/drivers/net/ethernet/qualcomm/qca_spi.c index 2c811f66d5ac..4a42e960d331 100644 --- a/drivers/net/ethernet/qualcomm/qca_spi.c +++ b/drivers/net/ethernet/qualcomm/qca_spi.c @@ -571,7 +571,7 @@ qcaspi_spi_thread(void *data) } /* can only handle other interrupts - * if sync has occured + * if sync has occurred */ if (qca->sync == QCASPI_SYNC_READY) { if (intr_cause & SPI_INT_PKT_AVLBL) diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c index c8a01ee4d25e..413ea14ab91f 100644 --- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c +++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c @@ -422,11 +422,11 @@ static int init_tx_ring(struct device *dev, u8 queue_no, /* assign queue number */ tx_ring->queue_no = queue_no; - /* initalise counters */ + /* initialise counters */ tx_ring->dirty_tx = 0; tx_ring->cur_tx = 0; - /* initalise TX queue lock */ + /* initialise TX queue lock */ spin_lock_init(&tx_ring->tx_lock); return 0; @@ -515,7 +515,7 @@ static int init_rx_ring(struct net_device *dev, u8 queue_no, goto err_free_rx_buffers; } - /* initalise counters */ + /* initialise counters */ rx_ring->cur_rx = 0; rx_ring->dirty_rx = (unsigned int)(desc_index - rx_rsize); priv->dma_buf_sz = bfsize; @@ -837,7 +837,7 @@ static void sxgbe_restart_tx_queue(struct sxgbe_priv_data *priv, int queue_num) /* free the skbuffs of the ring */ tx_free_ring_skbufs(tx_ring); - /* initalise counters */ + /* initialise counters */ tx_ring->cur_tx = 0; tx_ring->dirty_tx = 0; @@ -1176,7 +1176,7 @@ static int sxgbe_open(struct net_device *dev) if (priv->phydev) phy_start(priv->phydev); - /* initalise TX coalesce parameters */ + /* initialise TX coalesce parameters */ sxgbe_tx_init_coalesce(priv); if ((priv->use_riwt) && (priv->hw->dma->rx_watchdog)) { @@ -1721,7 +1721,7 @@ static inline u64 sxgbe_get_stat64(void __iomem *ioaddr, int reg_lo, int reg_hi) * Description: * This function is a driver entry point whenever ifconfig command gets * executed to see device statistics. Statistics are number of - * bytes sent or received, errors occured etc. + * bytes sent or received, errors occurred etc. * Return value: * This function returns various statistical information of device. */ diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index 238482495e81..33d2f9aa1b53 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -3215,7 +3215,7 @@ static pci_ers_result_t efx_io_error_detected(struct pci_dev *pdev, return status; } -/* Fake a successfull reset, which will be performed later in efx_io_resume. */ +/* Fake a successful reset, which will be performed later in efx_io_resume. */ static pci_ers_result_t efx_io_slot_reset(struct pci_dev *pdev) { struct efx_nic *efx = pci_get_drvdata(pdev); diff --git a/drivers/net/ethernet/sfc/farch.c b/drivers/net/ethernet/sfc/farch.c index 75975328e020..bb89e96a125e 100644 --- a/drivers/net/ethernet/sfc/farch.c +++ b/drivers/net/ethernet/sfc/farch.c @@ -645,7 +645,7 @@ static bool efx_check_tx_flush_complete(struct efx_nic *efx) } /* Flush all the transmit queues, and continue flushing receive queues until - * they're all flushed. Wait for the DRAIN events to be recieved so that there + * they're all flushed. Wait for the DRAIN events to be received so that there * are no more RX and TX events left on any channel. */ static int efx_farch_do_flush(struct efx_nic *efx) { @@ -1108,7 +1108,7 @@ efx_farch_handle_tx_flush_done(struct efx_nic *efx, efx_qword_t *event) } /* If this flush done event corresponds to a &struct efx_rx_queue: If the flush - * was succesful then send an %EFX_CHANNEL_MAGIC_RX_DRAIN, otherwise add + * was successful then send an %EFX_CHANNEL_MAGIC_RX_DRAIN, otherwise add * the RX queue back to the mask of RX queues in need of flushing. */ static void diff --git a/drivers/net/ethernet/sfc/mcdi_pcol.h b/drivers/net/ethernet/sfc/mcdi_pcol.h index a707fb5ef14c..e028de10e1b7 100644 --- a/drivers/net/ethernet/sfc/mcdi_pcol.h +++ b/drivers/net/ethernet/sfc/mcdi_pcol.h @@ -6497,7 +6497,7 @@ #define MC_CMD_DUMP_BUFTBL_ENTRIES_OUT_LENMIN 12 #define MC_CMD_DUMP_BUFTBL_ENTRIES_OUT_LENMAX 252 #define MC_CMD_DUMP_BUFTBL_ENTRIES_OUT_LEN(num) (0+12*(num)) -/* Raw buffer table entries, layed out as BUFTBL_ENTRY. */ +/* Raw buffer table entries, laid out as BUFTBL_ENTRY. */ #define MC_CMD_DUMP_BUFTBL_ENTRIES_OUT_ENTRY_OFST 0 #define MC_CMD_DUMP_BUFTBL_ENTRIES_OUT_ENTRY_LEN 12 #define MC_CMD_DUMP_BUFTBL_ENTRIES_OUT_ENTRY_MINNUM 1 diff --git a/drivers/net/ethernet/sfc/siena_sriov.c b/drivers/net/ethernet/sfc/siena_sriov.c index a8bbbad68a88..fe83430796fd 100644 --- a/drivers/net/ethernet/sfc/siena_sriov.c +++ b/drivers/net/ethernet/sfc/siena_sriov.c @@ -1067,7 +1067,7 @@ void efx_siena_sriov_probe(struct efx_nic *efx) } /* Copy the list of individual addresses into the vfdi_status.peers - * array and auxillary pages, protected by %local_lock. Drop that lock + * array and auxiliary pages, protected by %local_lock. Drop that lock * and then broadcast the address list to every VF. */ static void efx_siena_sriov_peer_work(struct work_struct *data) diff --git a/drivers/net/ethernet/sfc/vfdi.h b/drivers/net/ethernet/sfc/vfdi.h index ae044f44936a..f62901d4cae0 100644 --- a/drivers/net/ethernet/sfc/vfdi.h +++ b/drivers/net/ethernet/sfc/vfdi.h @@ -98,7 +98,7 @@ struct vfdi_endpoint { * @VFDI_OP_INIT_TXQ: Initialize SRAM entries and initialize a TXQ. * @VFDI_OP_FINI_ALL_QUEUES: Flush all queues, finalize all queues, then * finalize the SRAM entries. - * @VFDI_OP_INSERT_FILTER: Insert a MAC filter targetting the given RXQ. + * @VFDI_OP_INSERT_FILTER: Insert a MAC filter targeting the given RXQ. * @VFDI_OP_REMOVE_ALL_FILTERS: Remove all filters. * @VFDI_OP_SET_STATUS_PAGE: Set the DMA page(s) used for status updates * from PF and write the initial status. @@ -148,7 +148,7 @@ enum vfdi_op { * @u.init_txq.flags: Checksum offload flags. * @u.init_txq.addr: Array of length %u.init_txq.buf_count containing DMA * address of each page backing the transmit queue. - * @u.mac_filter.rxq: Insert MAC filter at VF local address/VLAN targetting + * @u.mac_filter.rxq: Insert MAC filter at VF local address/VLAN targeting * all traffic at this receive queue. * @u.mac_filter.flags: MAC filter flags. * @u.set_status_page.dma_addr: Base address for the &struct vfdi_status. diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index a0ea84fe6519..5336594abed1 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -609,7 +609,7 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr) * where, freq_div_ratio = clk_ptp_ref_i/50MHz * hence, addend = ((2^32) * 50MHz)/clk_ptp_ref_i; * NOTE: clk_ptp_ref_i should be >= 50MHz to - * achive 20ns accuracy. + * achieve 20ns accuracy. * * 2^x * y == (y << x), hence * 2^32 * 50000000 ==> (50000000 << 32) diff --git a/drivers/net/ethernet/sun/sungem.c b/drivers/net/ethernet/sun/sungem.c index fef5dec2cffe..74e9b148378c 100644 --- a/drivers/net/ethernet/sun/sungem.c +++ b/drivers/net/ethernet/sun/sungem.c @@ -2175,7 +2175,7 @@ static int gem_do_start(struct net_device *dev) } /* Mark us as attached again if we come from resume(), this has - * no effect if we weren't detatched and needs to be done now. + * no effect if we weren't detached and needs to be done now. */ netif_device_attach(dev); @@ -2794,7 +2794,7 @@ static void gem_remove_one(struct pci_dev *pdev) unregister_netdev(dev); - /* Ensure reset task is truely gone */ + /* Ensure reset task is truly gone */ cancel_work_sync(&gp->reset_task); /* Free resources */ diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index a1bbaf6352ba..b536b4c82752 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -726,7 +726,7 @@ static void cpsw_rx_handler(void *token, int len, int status) if (ndev_status && (status >= 0)) { /* The packet received is for the interface which * is already down and the other interface is up - * and running, intead of freeing which results + * and running, instead of freeing which results * in reducing of the number of rx descriptor in * DMA engine, requeue skb back to cpdma. */ diff --git a/drivers/net/ethernet/toshiba/ps3_gelic_net.c b/drivers/net/ethernet/toshiba/ps3_gelic_net.c index bb7992804664..ac62a5e248b0 100644 --- a/drivers/net/ethernet/toshiba/ps3_gelic_net.c +++ b/drivers/net/ethernet/toshiba/ps3_gelic_net.c @@ -1065,7 +1065,7 @@ refill: /* * this call can fail, but for now, just leave this - * decriptor without skb + * descriptor without skb */ gelic_descr_prepare_rx(card, descr); diff --git a/drivers/net/ethernet/wiznet/w5100.c b/drivers/net/ethernet/wiznet/w5100.c index a495931a66a1..f5498c26b3c7 100644 --- a/drivers/net/ethernet/wiznet/w5100.c +++ b/drivers/net/ethernet/wiznet/w5100.c @@ -56,7 +56,7 @@ MODULE_LICENSE("GPL"); #define W5100_S0_REGS 0x0400 #define W5100_S0_MR 0x0400 /* S0 Mode Register */ -#define S0_MR_MACRAW 0x04 /* MAC RAW mode (promiscous) */ +#define S0_MR_MACRAW 0x04 /* MAC RAW mode (promiscuous) */ #define S0_MR_MACRAW_MF 0x44 /* MAC RAW mode (filtered) */ #define W5100_S0_CR 0x0401 /* S0 Command Register */ #define S0_CR_OPEN 0x01 /* OPEN command */ diff --git a/drivers/net/ethernet/wiznet/w5300.c b/drivers/net/ethernet/wiznet/w5300.c index 09322d9db578..ca0c631ed628 100644 --- a/drivers/net/ethernet/wiznet/w5300.c +++ b/drivers/net/ethernet/wiznet/w5300.c @@ -63,7 +63,7 @@ MODULE_LICENSE("GPL"); #define IDR_W5300 0x5300 /* =0x5300 for WIZnet W5300 */ #define W5300_S0_MR 0x0200 /* S0 Mode Register */ #define S0_MR_CLOSED 0x0000 /* Close mode */ -#define S0_MR_MACRAW 0x0004 /* MAC RAW mode (promiscous) */ +#define S0_MR_MACRAW 0x0004 /* MAC RAW mode (promiscuous) */ #define S0_MR_MACRAW_MF 0x0044 /* MAC RAW mode (filtered) */ #define W5300_S0_CR 0x0202 /* S0 Command Register */ #define S0_CR_OPEN 0x0001 /* OPEN command */ -- GitLab From 8edfe3b6fad28da191c8fa15e4e0d8f7335a0091 Mon Sep 17 00:00:00 2001 From: Peter Senna Tschudin Date: Sat, 7 Mar 2015 12:10:26 +0100 Subject: [PATCH 03427/11651] bgmac: Clean warning messages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On my test environment the throughput of a file transfer drops from 4.4MBps to 116KBps due the number of repeated warning messages. This patch removes the warning messages as DMA works correctly with addresses using 0xC0000000 bits. Signed-off-by: Peter Senna Tschudin Acked-by: Rafał Miłecki Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bgmac.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c index 676ffe093180..0469f72c6e7e 100644 --- a/drivers/net/ethernet/broadcom/bgmac.c +++ b/drivers/net/ethernet/broadcom/bgmac.c @@ -302,9 +302,6 @@ static int bgmac_dma_rx_skb_for_slot(struct bgmac *bgmac, slot->skb = skb; slot->dma_addr = dma_addr; - if (slot->dma_addr & 0xC0000000) - bgmac_warn(bgmac, "DMA address using 0xC0000000 bit(s), it may need translation trick\n"); - return 0; } @@ -505,8 +502,6 @@ static int bgmac_dma_alloc(struct bgmac *bgmac) ring->mmio_base); goto err_dma_free; } - if (ring->dma_base & 0xC0000000) - bgmac_warn(bgmac, "DMA address using 0xC0000000 bit(s), it may need translation trick\n"); ring->unaligned = bgmac_dma_unaligned(bgmac, ring, BGMAC_DMA_RING_TX); @@ -536,8 +531,6 @@ static int bgmac_dma_alloc(struct bgmac *bgmac) err = -ENOMEM; goto err_dma_free; } - if (ring->dma_base & 0xC0000000) - bgmac_warn(bgmac, "DMA address using 0xC0000000 bit(s), it may need translation trick\n"); ring->unaligned = bgmac_dma_unaligned(bgmac, ring, BGMAC_DMA_RING_RX); -- GitLab From fc6c6c2b8a2e1fbaa9e864af62c873dae15420ea Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Sat, 7 Mar 2015 07:37:06 +0100 Subject: [PATCH 03428/11651] net/macb: Update DT bindings documentation Add missing "cdns,at91sam9260-macb", "atmel,sama5d3-gem" and "atmel,sama5d4-gem" compatible strings. Signed-off-by: Boris Brezillon Reviewed-by: Alexandre Belloni Acked-by: Nicolas Ferre Signed-off-by: David S. Miller --- Documentation/devicetree/bindings/net/macb.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/net/macb.txt b/Documentation/devicetree/bindings/net/macb.txt index aaa696414f57..ba19d671e808 100644 --- a/Documentation/devicetree/bindings/net/macb.txt +++ b/Documentation/devicetree/bindings/net/macb.txt @@ -2,10 +2,13 @@ Required properties: - compatible: Should be "cdns,[-]{macb|gem}" - Use "cdns,at91sam9260-macb" Atmel at91sam9260 and at91sam9263 SoCs. + Use "cdns,at91sam9260-macb" for Atmel at91sam9 SoCs or the 10/100Mbit IP + available on sama5d3 SoCs. Use "cdns,at32ap7000-macb" for other 10/100 usage or use the generic form: "cdns,macb". Use "cdns,pc302-gem" for Picochip picoXcell pc302 and later devices based on the Cadence GEM, or the generic form: "cdns,gem". + Use "cdns,sama5d3-gem" for the Gigabit IP available on Atmel sama5d3 SoCs. + Use "cdns,sama5d4-gem" for the Gigabit IP available on Atmel sama5d4 SoCs. - reg: Address and length of the register set for the device - interrupts: Should contain macb interrupt - phy-mode: See ethernet.txt file in the same directory. -- GitLab From c247f0534cc5a5a547a343903f42295a471844e2 Mon Sep 17 00:00:00 2001 From: Willem de Bruijn Date: Sat, 7 Mar 2015 20:33:22 -0500 Subject: [PATCH 03429/11651] ip: fix error queue empty skb handling When reading from the error queue, msg_name and msg_control are only populated for some errors. A new exception for empty timestamp skbs added a false positive on icmp errors without payload. `traceroute -M udpconn` only displayed gateways that return payload with the icmp error: the embedded network headers are pulled before sock_queue_err_skb, leaving an skb with skb->len == 0 otherwise. Fix this regression by refining when msg_name and msg_control branches are taken. The solutions for the two fields are independent. msg_name only makes sense for errors that configure serr->port and serr->addr_offset. Test the first instead of skb->len. This also fixes another issue. saddr could hold the wrong data, as serr->addr_offset is not initialized in some code paths, pointing to the start of the network header. It is only valid when serr->port is set (non-zero). msg_control support differs between IPv4 and IPv6. IPv4 only honors requests for ICMP and timestamps with SOF_TIMESTAMPING_OPT_CMSG. The skb->len test can simply be removed, because skb->dev is also tested and never true for empty skbs. IPv6 honors requests for all errors aside from local errors and timestamps on empty skbs. In both cases, make the policy more explicit by moving this logic to a new function that decides whether to process msg_control and that optionally prepares the necessary fields in skb->cb[]. After this change, the IPv4 and IPv6 paths are more similar. The last case is rxrpc. Here, simply refine to only match timestamps. Fixes: 49ca0d8bfaf3 ("net-timestamp: no-payload option") Reported-by: Jan Niehusmann Signed-off-by: Willem de Bruijn ---- Changes v1->v2 - fix local origin test inversion in ip6_datagram_support_cmsg - make v4 and v6 code paths more similar by introducing analogous ipv4_datagram_support_cmsg - fix compile bug in rxrpc Signed-off-by: David S. Miller --- net/ipv4/ip_sockglue.c | 33 +++++++++++++++++++++++---------- net/ipv6/datagram.c | 39 ++++++++++++++++++++++++++++----------- net/rxrpc/ar-error.c | 4 ++-- 3 files changed, 53 insertions(+), 23 deletions(-) diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index 31d8c71986b4..5cd99271d3a6 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c @@ -432,17 +432,32 @@ void ip_local_error(struct sock *sk, int err, __be32 daddr, __be16 port, u32 inf kfree_skb(skb); } -static bool ipv4_pktinfo_prepare_errqueue(const struct sock *sk, - const struct sk_buff *skb, - int ee_origin) +/* IPv4 supports cmsg on all imcp errors and some timestamps + * + * Timestamp code paths do not initialize the fields expected by cmsg: + * the PKTINFO fields in skb->cb[]. Fill those in here. + */ +static bool ipv4_datagram_support_cmsg(const struct sock *sk, + struct sk_buff *skb, + int ee_origin) { - struct in_pktinfo *info = PKTINFO_SKB_CB(skb); + struct in_pktinfo *info; + + if (ee_origin == SO_EE_ORIGIN_ICMP) + return true; - if ((ee_origin != SO_EE_ORIGIN_TIMESTAMPING) || - (!(sk->sk_tsflags & SOF_TIMESTAMPING_OPT_CMSG)) || + if (ee_origin == SO_EE_ORIGIN_LOCAL) + return false; + + /* Support IP_PKTINFO on tstamp packets if requested, to correlate + * timestamp with egress dev. Not possible for packets without dev + * or without payload (SOF_TIMESTAMPING_OPT_TSONLY). + */ + if ((!(sk->sk_tsflags & SOF_TIMESTAMPING_OPT_CMSG)) || (!skb->dev)) return false; + info = PKTINFO_SKB_CB(skb); info->ipi_spec_dst.s_addr = ip_hdr(skb)->saddr; info->ipi_ifindex = skb->dev->ifindex; return true; @@ -483,7 +498,7 @@ int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len) serr = SKB_EXT_ERR(skb); - if (sin && skb->len) { + if (sin && serr->port) { sin->sin_family = AF_INET; sin->sin_addr.s_addr = *(__be32 *)(skb_network_header(skb) + serr->addr_offset); @@ -496,9 +511,7 @@ int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len) sin = &errhdr.offender; memset(sin, 0, sizeof(*sin)); - if (skb->len && - (serr->ee.ee_origin == SO_EE_ORIGIN_ICMP || - ipv4_pktinfo_prepare_errqueue(sk, skb, serr->ee.ee_origin))) { + if (ipv4_datagram_support_cmsg(sk, skb, serr->ee.ee_origin)) { sin->sin_family = AF_INET; sin->sin_addr.s_addr = ip_hdr(skb)->saddr; if (inet_sk(sk)->cmsg_flags) diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index c215be70cac0..ace8daca5c83 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c @@ -325,14 +325,34 @@ void ipv6_local_rxpmtu(struct sock *sk, struct flowi6 *fl6, u32 mtu) kfree_skb(skb); } -static void ip6_datagram_prepare_pktinfo_errqueue(struct sk_buff *skb) +/* IPv6 supports cmsg on all origins aside from SO_EE_ORIGIN_LOCAL. + * + * At one point, excluding local errors was a quick test to identify icmp/icmp6 + * errors. This is no longer true, but the test remained, so the v6 stack, + * unlike v4, also honors cmsg requests on all wifi and timestamp errors. + * + * Timestamp code paths do not initialize the fields expected by cmsg: + * the PKTINFO fields in skb->cb[]. Fill those in here. + */ +static bool ip6_datagram_support_cmsg(struct sk_buff *skb, + struct sock_exterr_skb *serr) { - int ifindex = skb->dev ? skb->dev->ifindex : -1; + if (serr->ee.ee_origin == SO_EE_ORIGIN_ICMP || + serr->ee.ee_origin == SO_EE_ORIGIN_ICMP6) + return true; + + if (serr->ee.ee_origin == SO_EE_ORIGIN_LOCAL) + return false; + + if (!skb->dev) + return false; if (skb->protocol == htons(ETH_P_IPV6)) - IP6CB(skb)->iif = ifindex; + IP6CB(skb)->iif = skb->dev->ifindex; else - PKTINFO_SKB_CB(skb)->ipi_ifindex = ifindex; + PKTINFO_SKB_CB(skb)->ipi_ifindex = skb->dev->ifindex; + + return true; } /* @@ -369,7 +389,7 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len) serr = SKB_EXT_ERR(skb); - if (sin && skb->len) { + if (sin && serr->port) { const unsigned char *nh = skb_network_header(skb); sin->sin6_family = AF_INET6; sin->sin6_flowinfo = 0; @@ -394,14 +414,11 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len) memcpy(&errhdr.ee, &serr->ee, sizeof(struct sock_extended_err)); sin = &errhdr.offender; memset(sin, 0, sizeof(*sin)); - if (serr->ee.ee_origin != SO_EE_ORIGIN_LOCAL && skb->len) { + + if (ip6_datagram_support_cmsg(skb, serr)) { sin->sin6_family = AF_INET6; - if (np->rxopt.all) { - if (serr->ee.ee_origin != SO_EE_ORIGIN_ICMP && - serr->ee.ee_origin != SO_EE_ORIGIN_ICMP6) - ip6_datagram_prepare_pktinfo_errqueue(skb); + if (np->rxopt.all) ip6_datagram_recv_common_ctl(sk, msg, skb); - } if (skb->protocol == htons(ETH_P_IPV6)) { sin->sin6_addr = ipv6_hdr(skb)->saddr; if (np->rxopt.all) diff --git a/net/rxrpc/ar-error.c b/net/rxrpc/ar-error.c index 5394b6be46ec..0610efa83d72 100644 --- a/net/rxrpc/ar-error.c +++ b/net/rxrpc/ar-error.c @@ -42,7 +42,8 @@ void rxrpc_UDP_error_report(struct sock *sk) _leave("UDP socket errqueue empty"); return; } - if (!skb->len) { + serr = SKB_EXT_ERR(skb); + if (!skb->len && serr->ee.ee_origin == SO_EE_ORIGIN_TIMESTAMPING) { _leave("UDP empty message"); kfree_skb(skb); return; @@ -50,7 +51,6 @@ void rxrpc_UDP_error_report(struct sock *sk) rxrpc_new_skb(skb); - serr = SKB_EXT_ERR(skb); addr = *(__be32 *)(skb_network_header(skb) + serr->addr_offset); port = serr->port; -- GitLab From 8b04baba10b007f8b6c245a50be73cf09cc3a414 Mon Sep 17 00:00:00 2001 From: Daniel Martin Date: Sun, 8 Mar 2015 22:27:37 -0700 Subject: [PATCH 03430/11651] Input: synaptics - split synaptics_resolution(), query first Split the function synaptics_resolution() into synaptics_resolution() and synaptics_quirks(). synaptics_resolution() will be called before synaptics_quirks() to query dimensions and resolutions before overwriting them with quirks. Cc: stable@vger.kernel.org Signed-off-by: Daniel Martin Acked-by: Hans de Goede Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/synaptics.c | 35 ++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 23e26e0768b5..b501dda75dcb 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -343,7 +343,6 @@ static int synaptics_resolution(struct psmouse *psmouse) { struct synaptics_data *priv = psmouse->private; unsigned char resp[3]; - int i; if (SYN_ID_MAJOR(priv->identity) < 4) return 0; @@ -355,17 +354,6 @@ static int synaptics_resolution(struct psmouse *psmouse) } } - for (i = 0; min_max_pnpid_table[i].pnp_ids; i++) { - if (psmouse_matches_pnp_id(psmouse, - min_max_pnpid_table[i].pnp_ids)) { - priv->x_min = min_max_pnpid_table[i].x_min; - priv->x_max = min_max_pnpid_table[i].x_max; - priv->y_min = min_max_pnpid_table[i].y_min; - priv->y_max = min_max_pnpid_table[i].y_max; - return 0; - } - } - if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 5 && SYN_CAP_MAX_DIMENSIONS(priv->ext_cap_0c)) { if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_MAX_COORDS, resp)) { @@ -391,6 +379,27 @@ static int synaptics_resolution(struct psmouse *psmouse) return 0; } +/* + * Apply quirk(s) if the hardware matches + */ + +static void synaptics_apply_quirks(struct psmouse *psmouse) +{ + struct synaptics_data *priv = psmouse->private; + int i; + + for (i = 0; min_max_pnpid_table[i].pnp_ids; i++) { + if (psmouse_matches_pnp_id(psmouse, + min_max_pnpid_table[i].pnp_ids)) { + priv->x_min = min_max_pnpid_table[i].x_min; + priv->x_max = min_max_pnpid_table[i].x_max; + priv->y_min = min_max_pnpid_table[i].y_min; + priv->y_max = min_max_pnpid_table[i].y_max; + break; + } + } +} + static int synaptics_query_hardware(struct psmouse *psmouse) { if (synaptics_identify(psmouse)) @@ -406,6 +415,8 @@ static int synaptics_query_hardware(struct psmouse *psmouse) if (synaptics_resolution(psmouse)) return -1; + synaptics_apply_quirks(psmouse); + return 0; } -- GitLab From 9aff65982d0f58a78a27769fba7e97bc937b2593 Mon Sep 17 00:00:00 2001 From: Daniel Martin Date: Sun, 8 Mar 2015 22:28:29 -0700 Subject: [PATCH 03431/11651] Input: synaptics - log queried and quirked dimension values Logging the dimension values we queried and the values we use from a quirk to overwrite can be helpful for debugging. This partly relates to bug: https://bugzilla.kernel.org/show_bug.cgi?id=91541 Cc: stable@vger.kernel.org Signed-off-by: Daniel Martin Acked-by: Hans de Goede Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/synaptics.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index b501dda75dcb..47c5dca20a60 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -362,6 +362,9 @@ static int synaptics_resolution(struct psmouse *psmouse) } else { priv->x_max = (resp[0] << 5) | ((resp[1] & 0x0f) << 1); priv->y_max = (resp[2] << 5) | ((resp[1] & 0xf0) >> 3); + psmouse_info(psmouse, + "queried max coordinates: x [..%d], y [..%d]\n", + priv->x_max, priv->y_max); } } @@ -373,6 +376,9 @@ static int synaptics_resolution(struct psmouse *psmouse) } else { priv->x_min = (resp[0] << 5) | ((resp[1] & 0x0f) << 1); priv->y_min = (resp[2] << 5) | ((resp[1] & 0xf0) >> 3); + psmouse_info(psmouse, + "queried min coordinates: x [%d..], y [%d..]\n", + priv->x_min, priv->y_min); } } @@ -395,6 +401,10 @@ static void synaptics_apply_quirks(struct psmouse *psmouse) priv->x_max = min_max_pnpid_table[i].x_max; priv->y_min = min_max_pnpid_table[i].y_min; priv->y_max = min_max_pnpid_table[i].y_max; + psmouse_info(psmouse, + "quirked min/max coordinates: x [%d..%d], y [%d..%d]\n", + priv->x_min, priv->x_max, + priv->y_min, priv->y_max); break; } } -- GitLab From ac097930f0730a9b777737de2b51e0fc49d2be7a Mon Sep 17 00:00:00 2001 From: Daniel Martin Date: Sun, 8 Mar 2015 22:28:40 -0700 Subject: [PATCH 03432/11651] Input: synaptics - query min dimensions for fw v8.1 Query the min dimensions even if the check SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 7 fails, but we know that the firmware version 8.1 is safe. With that we don't need quirks for post-2013 models anymore as they expose correct min and max dimensions. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=91541 Cc: stable@vger.kernel.org Signed-off-by: Daniel Martin re-order the tests to check SYN_CAP_MIN_DIMENSIONS even on FW 8.1 Signed-off-by: Benjamin Tissoires Acked-by: Hans de Goede Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/synaptics.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 47c5dca20a60..87c37f745b92 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -368,8 +368,14 @@ static int synaptics_resolution(struct psmouse *psmouse) } } - if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 7 && - SYN_CAP_MIN_DIMENSIONS(priv->ext_cap_0c)) { + if (SYN_CAP_MIN_DIMENSIONS(priv->ext_cap_0c) && + (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 7 || + /* + * Firmware v8.1 does not report proper number of extended + * capabilities, but has been proven to report correct min + * coordinates. + */ + SYN_ID_FULL(priv->identity) == 0x801)) { if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_MIN_COORDS, resp)) { psmouse_warn(psmouse, "device claims to have min coordinates query, but I'm not able to read it.\n"); -- GitLab From b05f4d1c332a22f98c037fa64f249aa30877adaf Mon Sep 17 00:00:00 2001 From: Daniel Martin Date: Sun, 8 Mar 2015 22:29:07 -0700 Subject: [PATCH 03433/11651] Input: synaptics - remove obsolete min/max quirk for X240 The firmware of the X240 (LEN0035, 2013/12) exposes the same values x [1232..5710], y [1156..4696] as the quirk applies. Cc: stable@vger.kernel.org Signed-off-by: Daniel Martin Acked-by: Hans de Goede Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/synaptics.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 87c37f745b92..af686a82b02b 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -131,7 +131,7 @@ static const struct min_max_quirk min_max_pnpid_table[] = { 1024, 5052, 2258, 4832 }, { - (const char * const []){"LEN0035", "LEN0042", NULL}, + (const char * const []){"LEN0042", NULL}, 1232, 5710, 1156, 4696 }, { -- GitLab From 5b3089ddb540401c1ad2e385a03d7e89ff954585 Mon Sep 17 00:00:00 2001 From: Daniel Martin Date: Sun, 8 Mar 2015 22:29:15 -0700 Subject: [PATCH 03434/11651] Input: synaptics - support min/max board id in min_max_pnpid_table Add a min/max range for board ids to the min/max coordinates quirk. This makes it possible to restrict quirks to specific models based upon their board id. The define ANY_BOARD_ID (0) serves as a wild card. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=91541 Cc: stable@vger.kernel.org Signed-off-by: Daniel Martin Acked-by: Hans de Goede Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/synaptics.c | 42 +++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index af686a82b02b..a900a385e5c3 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -120,32 +120,41 @@ void synaptics_reset(struct psmouse *psmouse) static bool cr48_profile_sensor; +#define ANY_BOARD_ID 0 struct min_max_quirk { const char * const *pnp_ids; + struct { + unsigned long int min, max; + } board_id; int x_min, x_max, y_min, y_max; }; static const struct min_max_quirk min_max_pnpid_table[] = { { (const char * const []){"LEN0033", NULL}, + {ANY_BOARD_ID, ANY_BOARD_ID}, 1024, 5052, 2258, 4832 }, { (const char * const []){"LEN0042", NULL}, + {ANY_BOARD_ID, ANY_BOARD_ID}, 1232, 5710, 1156, 4696 }, { (const char * const []){"LEN0034", "LEN0036", "LEN0037", "LEN0039", "LEN2002", "LEN2004", NULL}, + {ANY_BOARD_ID, ANY_BOARD_ID}, 1024, 5112, 2024, 4832 }, { (const char * const []){"LEN2001", NULL}, + {ANY_BOARD_ID, ANY_BOARD_ID}, 1024, 5022, 2508, 4832 }, { (const char * const []){"LEN2006", NULL}, + {ANY_BOARD_ID, ANY_BOARD_ID}, 1264, 5675, 1171, 4688 }, { } @@ -401,18 +410,27 @@ static void synaptics_apply_quirks(struct psmouse *psmouse) int i; for (i = 0; min_max_pnpid_table[i].pnp_ids; i++) { - if (psmouse_matches_pnp_id(psmouse, - min_max_pnpid_table[i].pnp_ids)) { - priv->x_min = min_max_pnpid_table[i].x_min; - priv->x_max = min_max_pnpid_table[i].x_max; - priv->y_min = min_max_pnpid_table[i].y_min; - priv->y_max = min_max_pnpid_table[i].y_max; - psmouse_info(psmouse, - "quirked min/max coordinates: x [%d..%d], y [%d..%d]\n", - priv->x_min, priv->x_max, - priv->y_min, priv->y_max); - break; - } + if (!psmouse_matches_pnp_id(psmouse, + min_max_pnpid_table[i].pnp_ids)) + continue; + + if (min_max_pnpid_table[i].board_id.min != ANY_BOARD_ID && + priv->board_id < min_max_pnpid_table[i].board_id.min) + continue; + + if (min_max_pnpid_table[i].board_id.max != ANY_BOARD_ID && + priv->board_id > min_max_pnpid_table[i].board_id.max) + continue; + + priv->x_min = min_max_pnpid_table[i].x_min; + priv->x_max = min_max_pnpid_table[i].x_max; + priv->y_min = min_max_pnpid_table[i].y_min; + priv->y_max = min_max_pnpid_table[i].y_max; + psmouse_info(psmouse, + "quirked min/max coordinates: x [%d..%d], y [%d..%d]\n", + priv->x_min, priv->x_max, + priv->y_min, priv->y_max); + break; } } -- GitLab From 02e07492cdfae9c86e3bd21c0beec88dbcc1e9e8 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Sun, 8 Mar 2015 22:29:25 -0700 Subject: [PATCH 03435/11651] Input: synaptics - skip quirks when post-2013 dimensions Post-2013 Lenovo laptops provide correct min/max dimensions, which are different with the ones currently quirked. According to https://bugzilla.kernel.org/show_bug.cgi?id=91541 the following board ids are assigned in the post-2013 touchpads: t440p/t440s: LEN0036 -> 2964/2962 t540p: LEN0034 -> 2964 Using 2961 as the common minimum makes these 3 laptops OK. We may need to update those values later if other pnp_ids has a lower board_id. Cc: stable@vger.kernel.org Signed-off-by: Benjamin Tissoires Acked-by: Hans de Goede Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/synaptics.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index a900a385e5c3..9567a708aa64 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -144,7 +144,7 @@ static const struct min_max_quirk min_max_pnpid_table[] = { (const char * const []){"LEN0034", "LEN0036", "LEN0037", "LEN0039", "LEN2002", "LEN2004", NULL}, - {ANY_BOARD_ID, ANY_BOARD_ID}, + {ANY_BOARD_ID, 2961}, 1024, 5112, 2024, 4832 }, { -- GitLab From dc5465dc8a6d5cae8a0e1d8826bdcb2e4cb261ab Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sun, 8 Mar 2015 22:30:43 -0700 Subject: [PATCH 03436/11651] Input: synaptics - fix middle button on Lenovo 2015 products On the X1 Carbon 3rd gen (with a 2015 broadwell cpu), the physical middle button of the trackstick (attached to the touchpad serio device, of course) seems to get lost. Actually, the touchpads reports 3 extra buttons, which falls in the switch below to the '2' case. Let's handle the case of odd numbers also, so that the middle button finds its way back. Cc: stable@vger.kernel.org Signed-off-by: Benjamin Tissoires Acked-by: Hans de Goede Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/synaptics.c | 44 ++++++++++++++++----------------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 9567a708aa64..e78cc5578527 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -658,6 +658,18 @@ static void synaptics_parse_agm(const unsigned char buf[], priv->agm_pending = true; } +static void synaptics_parse_ext_buttons(const unsigned char buf[], + struct synaptics_data *priv, + struct synaptics_hw_state *hw) +{ + unsigned int ext_bits = + (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) + 1) >> 1; + unsigned int ext_mask = GENMASK(ext_bits - 1, 0); + + hw->ext_buttons = buf[4] & ext_mask; + hw->ext_buttons |= (buf[5] & ext_mask) << ext_bits; +} + static bool is_forcepad; static int synaptics_parse_hw_state(const unsigned char buf[], @@ -744,28 +756,9 @@ static int synaptics_parse_hw_state(const unsigned char buf[], hw->down = ((buf[0] ^ buf[3]) & 0x02) ? 1 : 0; } - if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) && + if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) > 0 && ((buf[0] ^ buf[3]) & 0x02)) { - switch (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) & ~0x01) { - default: - /* - * if nExtBtn is greater than 8 it should be - * considered invalid and treated as 0 - */ - break; - case 8: - hw->ext_buttons |= ((buf[5] & 0x08)) ? 0x80 : 0; - hw->ext_buttons |= ((buf[4] & 0x08)) ? 0x40 : 0; - case 6: - hw->ext_buttons |= ((buf[5] & 0x04)) ? 0x20 : 0; - hw->ext_buttons |= ((buf[4] & 0x04)) ? 0x10 : 0; - case 4: - hw->ext_buttons |= ((buf[5] & 0x02)) ? 0x08 : 0; - hw->ext_buttons |= ((buf[4] & 0x02)) ? 0x04 : 0; - case 2: - hw->ext_buttons |= ((buf[5] & 0x01)) ? 0x02 : 0; - hw->ext_buttons |= ((buf[4] & 0x01)) ? 0x01 : 0; - } + synaptics_parse_ext_buttons(buf, priv, hw); } } else { hw->x = (((buf[1] & 0x1f) << 8) | buf[2]); @@ -832,6 +825,7 @@ static void synaptics_report_buttons(struct psmouse *psmouse, { struct input_dev *dev = psmouse->dev; struct synaptics_data *priv = psmouse->private; + int ext_bits = (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) + 1) >> 1; int i; input_report_key(dev, BTN_LEFT, hw->left); @@ -845,8 +839,12 @@ static void synaptics_report_buttons(struct psmouse *psmouse, input_report_key(dev, BTN_BACK, hw->down); } - for (i = 0; i < SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap); i++) - input_report_key(dev, BTN_0 + i, hw->ext_buttons & (1 << i)); + for (i = 0; i < ext_bits; i++) { + input_report_key(dev, BTN_0 + 2 * i, + hw->ext_buttons & (1 << i)); + input_report_key(dev, BTN_1 + 2 * i, + hw->ext_buttons & (1 << (i + ext_bits))); + } } static void synaptics_report_slot(struct input_dev *dev, int slot, -- GitLab From ebc80840b850db72f7ae84fbcf77630ae5409629 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Sun, 8 Mar 2015 22:32:43 -0700 Subject: [PATCH 03437/11651] Input: synaptics - handle spurious release of trackstick buttons The Fimware 8.1 has a bug in which the extra buttons are only sent when the ExtBit is 1. This should be fixed in a future FW update which should have a bump of the minor version. Cc: stable@vger.kernel.org Signed-off-by: Benjamin Tissoires Acked-by: Hans de Goede Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/synaptics.c | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index e78cc5578527..2f42a712f3e0 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -820,14 +820,36 @@ static void synaptics_report_semi_mt_data(struct input_dev *dev, } } -static void synaptics_report_buttons(struct psmouse *psmouse, - const struct synaptics_hw_state *hw) +static void synaptics_report_ext_buttons(struct psmouse *psmouse, + const struct synaptics_hw_state *hw) { struct input_dev *dev = psmouse->dev; struct synaptics_data *priv = psmouse->private; int ext_bits = (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) + 1) >> 1; int i; + if (!SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap)) + return; + + /* Bug in FW 8.1, buttons are reported only when ExtBit is 1 */ + if (SYN_ID_FULL(priv->identity) == 0x801 && + !((psmouse->packet[0] ^ psmouse->packet[3]) & 0x02)) + return; + + for (i = 0; i < ext_bits; i++) { + input_report_key(dev, BTN_0 + 2 * i, + hw->ext_buttons & (1 << i)); + input_report_key(dev, BTN_1 + 2 * i, + hw->ext_buttons & (1 << (i + ext_bits))); + } +} + +static void synaptics_report_buttons(struct psmouse *psmouse, + const struct synaptics_hw_state *hw) +{ + struct input_dev *dev = psmouse->dev; + struct synaptics_data *priv = psmouse->private; + input_report_key(dev, BTN_LEFT, hw->left); input_report_key(dev, BTN_RIGHT, hw->right); @@ -839,12 +861,7 @@ static void synaptics_report_buttons(struct psmouse *psmouse, input_report_key(dev, BTN_BACK, hw->down); } - for (i = 0; i < ext_bits; i++) { - input_report_key(dev, BTN_0 + 2 * i, - hw->ext_buttons & (1 << i)); - input_report_key(dev, BTN_1 + 2 * i, - hw->ext_buttons & (1 << (i + ext_bits))); - } + synaptics_report_ext_buttons(psmouse, hw); } static void synaptics_report_slot(struct input_dev *dev, int slot, -- GitLab From b57a7128be24062b5b5b26032b7cd58f1651547e Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Sun, 8 Mar 2015 22:33:36 -0700 Subject: [PATCH 03438/11651] Input: synaptics - do not retrieve the board id on old firmwares The board id capability has been added in firmware 7.5. Cc: stable@vger.kernel.org Signed-off-by: Benjamin Tissoires Acked-by: Hans de Goede Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/synaptics.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 2f42a712f3e0..2176874a41b1 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -250,6 +250,10 @@ static int synaptics_board_id(struct psmouse *psmouse) struct synaptics_data *priv = psmouse->private; unsigned char bid[3]; + /* firmwares prior 7.5 have no board_id encoded */ + if (SYN_ID_FULL(priv->identity) < 0x705) + return 0; + if (synaptics_send_cmd(psmouse, SYN_QUE_MODES, bid)) return -1; priv->board_id = ((bid[0] & 0xfc) << 6) | bid[1]; -- GitLab From 06aa374bc70468b517dd36b95c48c8f391c08a27 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Sun, 8 Mar 2015 22:34:03 -0700 Subject: [PATCH 03439/11651] Input: synaptics - retrieve the extended capabilities in query $10 Newer Synaptics touchpads need to get information from the query $10. Retrieve it if available. Signed-off-by: Benjamin Tissoires Acked-by: Hans de Goede Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/synaptics.c | 23 ++++++++++++++++++++--- drivers/input/mouse/synaptics.h | 23 +++++++++++++++++++++++ 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 2176874a41b1..8f6a153677b9 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -241,11 +241,24 @@ static int synaptics_model_id(struct psmouse *psmouse) return 0; } +static int synaptics_more_extended_queries(struct psmouse *psmouse) +{ + struct synaptics_data *priv = psmouse->private; + unsigned char buf[3]; + + if (synaptics_send_cmd(psmouse, SYN_QUE_MEXT_CAPAB_10, buf)) + return -1; + + priv->ext_cap_10 = (buf[0]<<16) | (buf[1]<<8) | buf[2]; + + return 0; +} + /* - * Read the board id from the touchpad + * Read the board id and the "More Extended Queries" from the touchpad * The board id is encoded in the "QUERY MODES" response */ -static int synaptics_board_id(struct psmouse *psmouse) +static int synaptics_query_modes(struct psmouse *psmouse) { struct synaptics_data *priv = psmouse->private; unsigned char bid[3]; @@ -257,6 +270,10 @@ static int synaptics_board_id(struct psmouse *psmouse) if (synaptics_send_cmd(psmouse, SYN_QUE_MODES, bid)) return -1; priv->board_id = ((bid[0] & 0xfc) << 6) | bid[1]; + + if (SYN_MEXT_CAP_BIT(bid[0])) + return synaptics_more_extended_queries(psmouse); + return 0; } @@ -446,7 +463,7 @@ static int synaptics_query_hardware(struct psmouse *psmouse) return -1; if (synaptics_firmware_id(psmouse)) return -1; - if (synaptics_board_id(psmouse)) + if (synaptics_query_modes(psmouse)) return -1; if (synaptics_capability(psmouse)) return -1; diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h index 1bd01f21783b..8d3761ce8f54 100644 --- a/drivers/input/mouse/synaptics.h +++ b/drivers/input/mouse/synaptics.h @@ -22,6 +22,7 @@ #define SYN_QUE_EXT_CAPAB_0C 0x0c #define SYN_QUE_EXT_MAX_COORDS 0x0d #define SYN_QUE_EXT_MIN_COORDS 0x0f +#define SYN_QUE_MEXT_CAPAB_10 0x10 /* synatics modes */ #define SYN_BIT_ABSOLUTE_MODE (1 << 7) @@ -53,6 +54,7 @@ #define SYN_EXT_CAP_REQUESTS(c) (((c) & 0x700000) >> 20) #define SYN_CAP_MULTI_BUTTON_NO(ec) (((ec) & 0x00f000) >> 12) #define SYN_CAP_PRODUCT_ID(ec) (((ec) & 0xff0000) >> 16) +#define SYN_MEXT_CAP_BIT(m) ((m) & (1 << 1)) /* * The following describes response for the 0x0c query. @@ -89,6 +91,26 @@ #define SYN_CAP_REDUCED_FILTERING(ex0c) ((ex0c) & 0x000400) #define SYN_CAP_IMAGE_SENSOR(ex0c) ((ex0c) & 0x000800) +/* + * The following descibes response for the 0x10 query. + * + * byte mask name meaning + * ---- ---- ------- ------------ + * 1 0x01 ext buttons are stick buttons exported in the extended + * capability are actually meant to be used + * by the tracktick (pass-through). + * 1 0x02 SecurePad the touchpad is a SecurePad, so it + * contains a built-in fingerprint reader. + * 1 0xe0 more ext count how many more extented queries are + * available after this one. + * 2 0xff SecurePad width the width of the SecurePad fingerprint + * reader. + * 3 0xff SecurePad height the height of the SecurePad fingerprint + * reader. + */ +#define SYN_CAP_EXT_BUTTONS_STICK(ex10) ((ex10) & 0x010000) +#define SYN_CAP_SECUREPAD(ex10) ((ex10) & 0x020000) + /* synaptics modes query bits */ #define SYN_MODE_ABSOLUTE(m) ((m) & (1 << 7)) #define SYN_MODE_RATE(m) ((m) & (1 << 6)) @@ -156,6 +178,7 @@ struct synaptics_data { unsigned long int capabilities; /* Capabilities */ unsigned long int ext_cap; /* Extended Capabilities */ unsigned long int ext_cap_0c; /* Ext Caps from 0x0c query */ + unsigned long int ext_cap_10; /* Ext Caps from 0x10 query */ unsigned long int identity; /* Identification */ unsigned int x_res, y_res; /* X/Y resolution in units/mm */ unsigned int x_max, y_max; /* Max coordinates (from FW) */ -- GitLab From 3adde1f59195df2965f632e22b31f97fb371612f Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Sun, 8 Mar 2015 22:34:50 -0700 Subject: [PATCH 03440/11651] Input: synaptics - remove TOPBUTTONPAD property for Lenovos 2015 The 2015 series of the Lenovo thinkpads added back the hardware buttons on top of the touchpad for the trackstick. Unfortunately, Lenovo used the PNPIDs that are supposed to be "5 buttons" touchpads, so the new laptops also have the INPUT_PROP_TOPBUTTONPAD. Yay! Instead of manually removing each of the new ones, or hoping that we know all the current ones, we can consider that the PNPIDs list that were given contains touchpads that have the trackstick buttons, either physically wired to them, or emulated with the top software button property. Thanks to the extra buttons capability in query $10, we can reliably detect the physical buttons from the software ones, and so we can remove the TOPBUTTONPAD property even if it was declared as such. Signed-off-by: Benjamin Tissoires Acked-by: Hans de Goede Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/synaptics.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 8f6a153677b9..9d599eb79f17 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -1570,7 +1570,8 @@ static void set_input_params(struct psmouse *psmouse, if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) { __set_bit(INPUT_PROP_BUTTONPAD, dev->propbit); - if (psmouse_matches_pnp_id(psmouse, topbuttonpad_pnp_ids)) + if (psmouse_matches_pnp_id(psmouse, topbuttonpad_pnp_ids) && + !SYN_CAP_EXT_BUTTONS_STICK(priv->ext_cap_10)) __set_bit(INPUT_PROP_TOPBUTTONPAD, dev->propbit); /* Clickpads report only left button */ __clear_bit(BTN_RIGHT, dev->keybit); -- GitLab From cdd9dc195916ef5644cfac079094c3c1d1616e4c Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Sun, 8 Mar 2015 22:35:41 -0700 Subject: [PATCH 03441/11651] Input: synaptics - re-route tracksticks buttons on the Lenovo 2015 series The 2015 series of the Lenovo thinkpads added back the hardware buttons on top of the touchpad for the trackstick. Unfortunately, they are wired to the touchpad, and not the trackstick. Thus, they are seen as extra buttons from the kernel point of view. This leads to a problem in user space because extra buttons on synaptics devices used to be used as scroll up/down buttons. So in the end, the experience for the user is scroll events for buttons left and right when using the trackstick. Yay! Fortunately, the firmware advertises such behavior in the extended capability $10, and so we can re-route the buttons through the pass-through interface. Hallelujah-expressed-by: Peter Hutterer Signed-off-by: Benjamin Tissoires Acked-by: Hans de Goede Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/synaptics.c | 47 +++++++++++++++++++++++++-------- drivers/input/mouse/synaptics.h | 5 ++++ 2 files changed, 41 insertions(+), 11 deletions(-) diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 9d599eb79f17..ecc7811cbd46 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -579,18 +579,22 @@ static int synaptics_is_pt_packet(unsigned char *buf) return (buf[0] & 0xFC) == 0x84 && (buf[3] & 0xCC) == 0xC4; } -static void synaptics_pass_pt_packet(struct serio *ptport, unsigned char *packet) +static void synaptics_pass_pt_packet(struct psmouse *psmouse, + struct serio *ptport, + unsigned char *packet) { + struct synaptics_data *priv = psmouse->private; struct psmouse *child = serio_get_drvdata(ptport); if (child && child->state == PSMOUSE_ACTIVATED) { - serio_interrupt(ptport, packet[1], 0); + serio_interrupt(ptport, packet[1] | priv->pt_buttons, 0); serio_interrupt(ptport, packet[4], 0); serio_interrupt(ptport, packet[5], 0); if (child->pktsize == 4) serio_interrupt(ptport, packet[2], 0); - } else + } else { serio_interrupt(ptport, packet[1], 0); + } } static void synaptics_pt_activate(struct psmouse *psmouse) @@ -847,6 +851,7 @@ static void synaptics_report_ext_buttons(struct psmouse *psmouse, struct input_dev *dev = psmouse->dev; struct synaptics_data *priv = psmouse->private; int ext_bits = (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) + 1) >> 1; + char buf[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; int i; if (!SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap)) @@ -857,12 +862,30 @@ static void synaptics_report_ext_buttons(struct psmouse *psmouse, !((psmouse->packet[0] ^ psmouse->packet[3]) & 0x02)) return; - for (i = 0; i < ext_bits; i++) { - input_report_key(dev, BTN_0 + 2 * i, - hw->ext_buttons & (1 << i)); - input_report_key(dev, BTN_1 + 2 * i, - hw->ext_buttons & (1 << (i + ext_bits))); + if (!SYN_CAP_EXT_BUTTONS_STICK(priv->ext_cap_10)) { + for (i = 0; i < ext_bits; i++) { + input_report_key(dev, BTN_0 + 2 * i, + hw->ext_buttons & (1 << i)); + input_report_key(dev, BTN_1 + 2 * i, + hw->ext_buttons & (1 << (i + ext_bits))); + } + return; } + + /* + * This generation of touchpads has the trackstick buttons + * physically wired to the touchpad. Re-route them through + * the pass-through interface. + */ + if (!priv->pt_port) + return; + + /* The trackstick expects at most 3 buttons */ + priv->pt_buttons = SYN_CAP_EXT_BUTTON_STICK_L(hw->ext_buttons) | + SYN_CAP_EXT_BUTTON_STICK_R(hw->ext_buttons) << 1 | + SYN_CAP_EXT_BUTTON_STICK_M(hw->ext_buttons) << 2; + + synaptics_pass_pt_packet(psmouse, priv->pt_port, buf); } static void synaptics_report_buttons(struct psmouse *psmouse, @@ -1459,7 +1482,8 @@ static psmouse_ret_t synaptics_process_byte(struct psmouse *psmouse) if (SYN_CAP_PASS_THROUGH(priv->capabilities) && synaptics_is_pt_packet(psmouse->packet)) { if (priv->pt_port) - synaptics_pass_pt_packet(priv->pt_port, psmouse->packet); + synaptics_pass_pt_packet(psmouse, priv->pt_port, + psmouse->packet); } else synaptics_process_packet(psmouse); @@ -1561,8 +1585,9 @@ static void set_input_params(struct psmouse *psmouse, __set_bit(BTN_BACK, dev->keybit); } - for (i = 0; i < SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap); i++) - __set_bit(BTN_0 + i, dev->keybit); + if (!SYN_CAP_EXT_BUTTONS_STICK(priv->ext_cap_10)) + for (i = 0; i < SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap); i++) + __set_bit(BTN_0 + i, dev->keybit); __clear_bit(EV_REL, dev->evbit); __clear_bit(REL_X, dev->relbit); diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h index 8d3761ce8f54..f39539c70219 100644 --- a/drivers/input/mouse/synaptics.h +++ b/drivers/input/mouse/synaptics.h @@ -111,6 +111,10 @@ #define SYN_CAP_EXT_BUTTONS_STICK(ex10) ((ex10) & 0x010000) #define SYN_CAP_SECUREPAD(ex10) ((ex10) & 0x020000) +#define SYN_CAP_EXT_BUTTON_STICK_L(eb) (!!((eb) & 0x01)) +#define SYN_CAP_EXT_BUTTON_STICK_M(eb) (!!((eb) & 0x02)) +#define SYN_CAP_EXT_BUTTON_STICK_R(eb) (!!((eb) & 0x04)) + /* synaptics modes query bits */ #define SYN_MODE_ABSOLUTE(m) ((m) & (1 << 7)) #define SYN_MODE_RATE(m) ((m) & (1 << 6)) @@ -192,6 +196,7 @@ struct synaptics_data { bool disable_gesture; /* disable gestures */ struct serio *pt_port; /* Pass-through serio port */ + unsigned char pt_buttons; /* Pass-through buttons */ struct synaptics_mt_state mt_state; /* Current mt finger state */ bool mt_state_lost; /* mt_state may be incorrect */ -- GitLab From 860e6f7fcbe5653ec4e394f9ee335f2032398beb Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Sun, 8 Mar 2015 22:38:55 -0700 Subject: [PATCH 03442/11651] Input: synaptics - remove X1 Carbon 3rd gen from the topbuttonpad list Lenovo decided to switch back to physical buttons for the trackstick on their latest series. The PNPId list was provided before they reverted back to physical buttons, so it contains the new models too. We can know from the touchpad capabilities that the touchpad has physical buttons, so removing the ids from the list is not mandatory. It is still nicer to remove the wrong ids, so start by removing the X1 Carbon 3rd gen, with the PNPId of LEN0048. Signed-off-by: Benjamin Tissoires Acked-by: Hans de Goede Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/synaptics.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index ecc7811cbd46..160def02cde2 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -183,7 +183,6 @@ static const char * const topbuttonpad_pnp_ids[] = { "LEN0045", "LEN0046", "LEN0047", - "LEN0048", "LEN0049", "LEN2000", "LEN2001", /* Edge E431 */ -- GitLab From 8f004f3f4daf5dc98dc78f8e62497ad834053855 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Sun, 8 Mar 2015 22:39:17 -0700 Subject: [PATCH 03443/11651] Input: synaptics - remove X250 from the topbuttonpad list Lenovo X250 has a PnpID of LEN0046, but it does not have the top software button requirement. For the record, Lenovo T450s and W541 have a PnpID of LEN200f and LEN004a, so they are not on the top software button list. Signed-off-by: Benjamin Tissoires Reviewed-by: Daniel Martin Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/synaptics.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 160def02cde2..ca7ca8d4eb33 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -181,7 +181,6 @@ static const char * const topbuttonpad_pnp_ids[] = { "LEN0041", "LEN0042", /* Yoga */ "LEN0045", - "LEN0046", "LEN0047", "LEN0049", "LEN2000", -- GitLab From c312530589ed9524fc7cc921105dc9b67ea32d6a Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Mon, 9 Feb 2015 19:11:33 +0000 Subject: [PATCH 03444/11651] staging: vt6655: vnt_tx_packet fix dma_idx selection. There is still a problem that dma_idx is causing packets to go onto the wrong tx path. Protect dma_idx fully with the present first lock and use pTDInfo->byFlags TD_FLAGS_NETIF_SKB to set MACvTransmit. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device_main.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 4324282afe49..f5c5872b587e 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -1187,12 +1187,14 @@ static int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; PSTxDesc head_td; - u32 dma_idx = TYPE_AC0DMA; + u32 dma_idx; unsigned long flags; spin_lock_irqsave(&priv->lock, flags); - if (!ieee80211_is_data(hdr->frame_control)) + if (ieee80211_is_data(hdr->frame_control)) + dma_idx = TYPE_AC0DMA; + else dma_idx = TYPE_TXDMA0; if (AVAIL_TD(priv, dma_idx) < 1) { @@ -1206,6 +1208,9 @@ static int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb) head_td->pTDInfo->skb = skb; + if (dma_idx == TYPE_AC0DMA) + head_td->pTDInfo->byFlags = TD_FLAGS_NETIF_SKB; + priv->iTDUsed[dma_idx]++; /* Take ownership */ @@ -1234,13 +1239,10 @@ static int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb) head_td->buff_addr = cpu_to_le32(head_td->pTDInfo->skb_dma); - if (dma_idx == TYPE_AC0DMA) { - head_td->pTDInfo->byFlags = TD_FLAGS_NETIF_SKB; - + if (head_td->pTDInfo->byFlags & TD_FLAGS_NETIF_SKB) MACvTransmitAC0(priv->PortOffset); - } else { + else MACvTransmit0(priv->PortOffset); - } spin_unlock_irqrestore(&priv->lock, flags); -- GitLab From a1f3f1ca66bd12c339b17a0c2ef93a093f90a277 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Sun, 8 Mar 2015 18:29:50 +0100 Subject: [PATCH 03445/11651] ALSA: hda - Fix regression of HD-audio controller fallback modes The commit [63e51fd708f5: ALSA: hda - Don't take unresponsive D3 transition too serious] introduced a conditional fallback behavior to the HD-audio controller depending on the flag set. However, it introduced a silly bug, too, that the flag was evaluated in a reverse way. This resulted in a regression of HD-audio controller driver where it can't go to the fallback mode at communication errors. Unfortunately (or fortunately?) this didn't come up until recently because the affected code path is an error handling that happens only on an unstable hardware chip. Most of recent chips work stably, thus they didn't hit this problem. Now, we've got a regression report with a VIA chip, and this seems indeed requiring the fallback to the polling mode, and finally the bug was revealed. The fix is a oneliner to remove the wrong logical NOT in the check. (Lesson learned - be careful about double negation.) The bug should be backported to stable, but the patch won't be applicable to 3.13 or earlier because of the code splits. The stable fix patches for earlier kernels will be posted later manually. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=94021 Fixes: 63e51fd708f5 ('ALSA: hda - Don't take unresponsive D3 transition too serious') Cc: # v3.14+ Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_controller.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c index a2ce773bdc62..17c2637d842c 100644 --- a/sound/pci/hda/hda_controller.c +++ b/sound/pci/hda/hda_controller.c @@ -1164,7 +1164,7 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus, } } - if (!bus->no_response_fallback) + if (bus->no_response_fallback) return -1; if (!chip->polling_mode && chip->poll_count < 2) { -- GitLab From 0d55ba46bfbee64fd2b492b87bfe2ec172e7b056 Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Wed, 4 Mar 2015 12:00:16 +0000 Subject: [PATCH 03446/11651] x86/cacheinfo: Move cacheinfo sysfs code to generic infrastructure This patch removes the redundant sysfs cacheinfo code by reusing the newly introduced generic cacheinfo infrastructure through the commit 246246cbde5e ("drivers: base: support cpu cache information interface to userspace via sysfs") The private pointer provided by the cacheinfo is used to implement the AMD L3 cache-specific attributes. Note that with v4.0-rc1, commit 513e3d2d11c9 ("cpumask: always use nr_cpu_ids in formatting and parsing functions") in particular changes from long format to shorter one for all cpumasks sysfs entries. As the consequence of the same, even the shared_cpu_map in the cacheinfo sysfs was also changed. This patch neither alters any existing sysfs entries nor their formating, however since the generic cacheinfo has switched to use the device attributes instead of the traditional raw kobjects, a directory named "power" along with its standard attributes are added similar to any other device. Signed-off-by: Sudeep Holla Cc: Thomas Gleixner Cc: Ingo Molnar Cc: "H. Peter Anvin" Cc: Andre Przywara Link: http://lkml.kernel.org/r/1425470416-20691-1-git-send-email-sudeep.holla@arm.com [ Add a check for uninitialized this_cpu_ci for the cpu_has_topoext case too in __cache_amd_cpumap_setup() ] Signed-off-by: Borislav Petkov --- arch/x86/kernel/cpu/intel_cacheinfo.c | 715 +++++++------------------- 1 file changed, 198 insertions(+), 517 deletions(-) diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c index 659643376dbf..8008bc2dd2d0 100644 --- a/arch/x86/kernel/cpu/intel_cacheinfo.c +++ b/arch/x86/kernel/cpu/intel_cacheinfo.c @@ -7,16 +7,14 @@ * Andi Kleen / Andreas Herrmann : CPUID4 emulation on AMD. */ -#include #include -#include -#include +#include #include #include +#include #include #include -#include #include #include @@ -116,10 +114,10 @@ static const struct _cache_table cache_table[] = enum _cache_type { - CACHE_TYPE_NULL = 0, - CACHE_TYPE_DATA = 1, - CACHE_TYPE_INST = 2, - CACHE_TYPE_UNIFIED = 3 + CTYPE_NULL = 0, + CTYPE_DATA = 1, + CTYPE_INST = 2, + CTYPE_UNIFIED = 3 }; union _cpuid4_leaf_eax { @@ -159,11 +157,6 @@ struct _cpuid4_info_regs { struct amd_northbridge *nb; }; -struct _cpuid4_info { - struct _cpuid4_info_regs base; - DECLARE_BITMAP(shared_cpu_map, NR_CPUS); -}; - unsigned short num_cache_leaves; /* AMD doesn't have CPUID4. Emulate it here to report the same @@ -220,6 +213,13 @@ static const unsigned short assocs[] = { static const unsigned char levels[] = { 1, 1, 2, 3 }; static const unsigned char types[] = { 1, 2, 3, 3 }; +static const enum cache_type cache_type_map[] = { + [CTYPE_NULL] = CACHE_TYPE_NOCACHE, + [CTYPE_DATA] = CACHE_TYPE_DATA, + [CTYPE_INST] = CACHE_TYPE_INST, + [CTYPE_UNIFIED] = CACHE_TYPE_UNIFIED, +}; + static void amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax, union _cpuid4_leaf_ebx *ebx, @@ -291,14 +291,8 @@ amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax, (ebx->split.ways_of_associativity + 1) - 1; } -struct _cache_attr { - struct attribute attr; - ssize_t (*show)(struct _cpuid4_info *, char *, unsigned int); - ssize_t (*store)(struct _cpuid4_info *, const char *, size_t count, - unsigned int); -}; - #if defined(CONFIG_AMD_NB) && defined(CONFIG_SYSFS) + /* * L3 cache descriptors */ @@ -325,20 +319,6 @@ static void amd_calc_l3_indices(struct amd_northbridge *nb) l3->indices = (max(max3(sc0, sc1, sc2), sc3) << 10) - 1; } -static void amd_init_l3_cache(struct _cpuid4_info_regs *this_leaf, int index) -{ - int node; - - /* only for L3, and not in virtualized environments */ - if (index < 3) - return; - - node = amd_get_nb_id(smp_processor_id()); - this_leaf->nb = node_to_amd_nb(node); - if (this_leaf->nb && !this_leaf->nb->l3_cache.indices) - amd_calc_l3_indices(this_leaf->nb); -} - /* * check whether a slot used for disabling an L3 index is occupied. * @l3: L3 cache descriptor @@ -359,15 +339,13 @@ int amd_get_l3_disable_slot(struct amd_northbridge *nb, unsigned slot) return -1; } -static ssize_t show_cache_disable(struct _cpuid4_info *this_leaf, char *buf, +static ssize_t show_cache_disable(struct cacheinfo *this_leaf, char *buf, unsigned int slot) { int index; + struct amd_northbridge *nb = this_leaf->priv; - if (!this_leaf->base.nb || !amd_nb_has_feature(AMD_NB_L3_INDEX_DISABLE)) - return -EINVAL; - - index = amd_get_l3_disable_slot(this_leaf->base.nb, slot); + index = amd_get_l3_disable_slot(nb, slot); if (index >= 0) return sprintf(buf, "%d\n", index); @@ -376,9 +354,10 @@ static ssize_t show_cache_disable(struct _cpuid4_info *this_leaf, char *buf, #define SHOW_CACHE_DISABLE(slot) \ static ssize_t \ -show_cache_disable_##slot(struct _cpuid4_info *this_leaf, char *buf, \ - unsigned int cpu) \ +cache_disable_##slot##_show(struct device *dev, \ + struct device_attribute *attr, char *buf) \ { \ + struct cacheinfo *this_leaf = dev_get_drvdata(dev); \ return show_cache_disable(this_leaf, buf, slot); \ } SHOW_CACHE_DISABLE(0) @@ -446,25 +425,23 @@ int amd_set_l3_disable_slot(struct amd_northbridge *nb, int cpu, unsigned slot, return 0; } -static ssize_t store_cache_disable(struct _cpuid4_info *this_leaf, - const char *buf, size_t count, - unsigned int slot) +static ssize_t store_cache_disable(struct cacheinfo *this_leaf, + const char *buf, size_t count, + unsigned int slot) { unsigned long val = 0; int cpu, err = 0; + struct amd_northbridge *nb = this_leaf->priv; if (!capable(CAP_SYS_ADMIN)) return -EPERM; - if (!this_leaf->base.nb || !amd_nb_has_feature(AMD_NB_L3_INDEX_DISABLE)) - return -EINVAL; - - cpu = cpumask_first(to_cpumask(this_leaf->shared_cpu_map)); + cpu = cpumask_first(&this_leaf->shared_cpu_map); if (kstrtoul(buf, 10, &val) < 0) return -EINVAL; - err = amd_set_l3_disable_slot(this_leaf->base.nb, cpu, slot, val); + err = amd_set_l3_disable_slot(nb, cpu, slot, val); if (err) { if (err == -EEXIST) pr_warning("L3 slot %d in use/index already disabled!\n", @@ -476,41 +453,36 @@ static ssize_t store_cache_disable(struct _cpuid4_info *this_leaf, #define STORE_CACHE_DISABLE(slot) \ static ssize_t \ -store_cache_disable_##slot(struct _cpuid4_info *this_leaf, \ - const char *buf, size_t count, \ - unsigned int cpu) \ +cache_disable_##slot##_store(struct device *dev, \ + struct device_attribute *attr, \ + const char *buf, size_t count) \ { \ + struct cacheinfo *this_leaf = dev_get_drvdata(dev); \ return store_cache_disable(this_leaf, buf, count, slot); \ } STORE_CACHE_DISABLE(0) STORE_CACHE_DISABLE(1) -static struct _cache_attr cache_disable_0 = __ATTR(cache_disable_0, 0644, - show_cache_disable_0, store_cache_disable_0); -static struct _cache_attr cache_disable_1 = __ATTR(cache_disable_1, 0644, - show_cache_disable_1, store_cache_disable_1); - -static ssize_t -show_subcaches(struct _cpuid4_info *this_leaf, char *buf, unsigned int cpu) +static ssize_t subcaches_show(struct device *dev, + struct device_attribute *attr, char *buf) { - if (!this_leaf->base.nb || !amd_nb_has_feature(AMD_NB_L3_PARTITIONING)) - return -EINVAL; + struct cacheinfo *this_leaf = dev_get_drvdata(dev); + int cpu = cpumask_first(&this_leaf->shared_cpu_map); return sprintf(buf, "%x\n", amd_get_subcaches(cpu)); } -static ssize_t -store_subcaches(struct _cpuid4_info *this_leaf, const char *buf, size_t count, - unsigned int cpu) +static ssize_t subcaches_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) { + struct cacheinfo *this_leaf = dev_get_drvdata(dev); + int cpu = cpumask_first(&this_leaf->shared_cpu_map); unsigned long val; if (!capable(CAP_SYS_ADMIN)) return -EPERM; - if (!this_leaf->base.nb || !amd_nb_has_feature(AMD_NB_L3_PARTITIONING)) - return -EINVAL; - if (kstrtoul(buf, 16, &val) < 0) return -EINVAL; @@ -520,9 +492,92 @@ store_subcaches(struct _cpuid4_info *this_leaf, const char *buf, size_t count, return count; } -static struct _cache_attr subcaches = - __ATTR(subcaches, 0644, show_subcaches, store_subcaches); +static DEVICE_ATTR_RW(cache_disable_0); +static DEVICE_ATTR_RW(cache_disable_1); +static DEVICE_ATTR_RW(subcaches); + +static umode_t +cache_private_attrs_is_visible(struct kobject *kobj, + struct attribute *attr, int unused) +{ + struct device *dev = kobj_to_dev(kobj); + struct cacheinfo *this_leaf = dev_get_drvdata(dev); + umode_t mode = attr->mode; + + if (!this_leaf->priv) + return 0; + + if ((attr == &dev_attr_subcaches.attr) && + amd_nb_has_feature(AMD_NB_L3_PARTITIONING)) + return mode; + + if ((attr == &dev_attr_cache_disable_0.attr || + attr == &dev_attr_cache_disable_1.attr) && + amd_nb_has_feature(AMD_NB_L3_INDEX_DISABLE)) + return mode; + + return 0; +} + +static struct attribute_group cache_private_group = { + .is_visible = cache_private_attrs_is_visible, +}; + +static void init_amd_l3_attrs(void) +{ + int n = 1; + static struct attribute **amd_l3_attrs; + + if (amd_l3_attrs) /* already initialized */ + return; + + if (amd_nb_has_feature(AMD_NB_L3_INDEX_DISABLE)) + n += 2; + if (amd_nb_has_feature(AMD_NB_L3_PARTITIONING)) + n += 1; + + amd_l3_attrs = kcalloc(n, sizeof(*amd_l3_attrs), GFP_KERNEL); + if (!amd_l3_attrs) + return; + + n = 0; + if (amd_nb_has_feature(AMD_NB_L3_INDEX_DISABLE)) { + amd_l3_attrs[n++] = &dev_attr_cache_disable_0.attr; + amd_l3_attrs[n++] = &dev_attr_cache_disable_1.attr; + } + if (amd_nb_has_feature(AMD_NB_L3_PARTITIONING)) + amd_l3_attrs[n++] = &dev_attr_subcaches.attr; + cache_private_group.attrs = amd_l3_attrs; +} + +const struct attribute_group * +cache_get_priv_group(struct cacheinfo *this_leaf) +{ + struct amd_northbridge *nb = this_leaf->priv; + + if (this_leaf->level < 3) + return NULL; + + if (nb && nb->l3_cache.indices) + init_amd_l3_attrs(); + + return &cache_private_group; +} + +static void amd_init_l3_cache(struct _cpuid4_info_regs *this_leaf, int index) +{ + int node; + + /* only for L3, and not in virtualized environments */ + if (index < 3) + return; + + node = amd_get_nb_id(smp_processor_id()); + this_leaf->nb = node_to_amd_nb(node); + if (this_leaf->nb && !this_leaf->nb->l3_cache.indices) + amd_calc_l3_indices(this_leaf->nb); +} #else #define amd_init_l3_cache(x, y) #endif /* CONFIG_AMD_NB && CONFIG_SYSFS */ @@ -546,7 +601,7 @@ cpuid4_cache_lookup_regs(int index, struct _cpuid4_info_regs *this_leaf) cpuid_count(4, index, &eax.full, &ebx.full, &ecx.full, &edx); } - if (eax.split.type == CACHE_TYPE_NULL) + if (eax.split.type == CTYPE_NULL) return -EIO; /* better error ? */ this_leaf->eax = eax; @@ -575,7 +630,7 @@ static int find_num_cache_leaves(struct cpuinfo_x86 *c) /* Do cpuid(op) loop to find out num_cache_leaves */ cpuid_count(op, i, &eax, &ebx, &ecx, &edx); cache_eax.full = eax; - } while (cache_eax.split.type != CACHE_TYPE_NULL); + } while (cache_eax.split.type != CTYPE_NULL); return i; } @@ -626,9 +681,9 @@ unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c) switch (this_leaf.eax.split.level) { case 1: - if (this_leaf.eax.split.type == CACHE_TYPE_DATA) + if (this_leaf.eax.split.type == CTYPE_DATA) new_l1d = this_leaf.size/1024; - else if (this_leaf.eax.split.type == CACHE_TYPE_INST) + else if (this_leaf.eax.split.type == CTYPE_INST) new_l1i = this_leaf.size/1024; break; case 2: @@ -747,55 +802,52 @@ unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c) return l2; } -#ifdef CONFIG_SYSFS - -/* pointer to _cpuid4_info array (for each cache leaf) */ -static DEFINE_PER_CPU(struct _cpuid4_info *, ici_cpuid4_info); -#define CPUID4_INFO_IDX(x, y) (&((per_cpu(ici_cpuid4_info, x))[y])) - -#ifdef CONFIG_SMP - -static int cache_shared_amd_cpu_map_setup(unsigned int cpu, int index) +static int __cache_amd_cpumap_setup(unsigned int cpu, int index, + struct _cpuid4_info_regs *base) { - struct _cpuid4_info *this_leaf; + struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); + struct cacheinfo *this_leaf; int i, sibling; if (cpu_has_topoext) { unsigned int apicid, nshared, first, last; - if (!per_cpu(ici_cpuid4_info, cpu)) - return 0; - - this_leaf = CPUID4_INFO_IDX(cpu, index); - nshared = this_leaf->base.eax.split.num_threads_sharing + 1; + this_leaf = this_cpu_ci->info_list + index; + nshared = base->eax.split.num_threads_sharing + 1; apicid = cpu_data(cpu).apicid; first = apicid - (apicid % nshared); last = first + nshared - 1; for_each_online_cpu(i) { + this_cpu_ci = get_cpu_cacheinfo(i); + if (!this_cpu_ci->info_list) + continue; + apicid = cpu_data(i).apicid; if ((apicid < first) || (apicid > last)) continue; - if (!per_cpu(ici_cpuid4_info, i)) - continue; - this_leaf = CPUID4_INFO_IDX(i, index); + + this_leaf = this_cpu_ci->info_list + index; for_each_online_cpu(sibling) { apicid = cpu_data(sibling).apicid; if ((apicid < first) || (apicid > last)) continue; - set_bit(sibling, this_leaf->shared_cpu_map); + cpumask_set_cpu(sibling, + &this_leaf->shared_cpu_map); } } } else if (index == 3) { for_each_cpu(i, cpu_llc_shared_mask(cpu)) { - if (!per_cpu(ici_cpuid4_info, i)) + this_cpu_ci = get_cpu_cacheinfo(i); + if (!this_cpu_ci->info_list) continue; - this_leaf = CPUID4_INFO_IDX(i, index); + this_leaf = this_cpu_ci->info_list + index; for_each_cpu(sibling, cpu_llc_shared_mask(cpu)) { if (!cpu_online(sibling)) continue; - set_bit(sibling, this_leaf->shared_cpu_map); + cpumask_set_cpu(sibling, + &this_leaf->shared_cpu_map); } } } else @@ -804,457 +856,86 @@ static int cache_shared_amd_cpu_map_setup(unsigned int cpu, int index) return 1; } -static void cache_shared_cpu_map_setup(unsigned int cpu, int index) +static void __cache_cpumap_setup(unsigned int cpu, int index, + struct _cpuid4_info_regs *base) { - struct _cpuid4_info *this_leaf, *sibling_leaf; + struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); + struct cacheinfo *this_leaf, *sibling_leaf; unsigned long num_threads_sharing; int index_msb, i; struct cpuinfo_x86 *c = &cpu_data(cpu); if (c->x86_vendor == X86_VENDOR_AMD) { - if (cache_shared_amd_cpu_map_setup(cpu, index)) + if (__cache_amd_cpumap_setup(cpu, index, base)) return; } - this_leaf = CPUID4_INFO_IDX(cpu, index); - num_threads_sharing = 1 + this_leaf->base.eax.split.num_threads_sharing; + this_leaf = this_cpu_ci->info_list + index; + num_threads_sharing = 1 + base->eax.split.num_threads_sharing; + cpumask_set_cpu(cpu, &this_leaf->shared_cpu_map); if (num_threads_sharing == 1) - cpumask_set_cpu(cpu, to_cpumask(this_leaf->shared_cpu_map)); - else { - index_msb = get_count_order(num_threads_sharing); - - for_each_online_cpu(i) { - if (cpu_data(i).apicid >> index_msb == - c->apicid >> index_msb) { - cpumask_set_cpu(i, - to_cpumask(this_leaf->shared_cpu_map)); - if (i != cpu && per_cpu(ici_cpuid4_info, i)) { - sibling_leaf = - CPUID4_INFO_IDX(i, index); - cpumask_set_cpu(cpu, to_cpumask( - sibling_leaf->shared_cpu_map)); - } - } - } - } -} -static void cache_remove_shared_cpu_map(unsigned int cpu, int index) -{ - struct _cpuid4_info *this_leaf, *sibling_leaf; - int sibling; - - this_leaf = CPUID4_INFO_IDX(cpu, index); - for_each_cpu(sibling, to_cpumask(this_leaf->shared_cpu_map)) { - sibling_leaf = CPUID4_INFO_IDX(sibling, index); - cpumask_clear_cpu(cpu, - to_cpumask(sibling_leaf->shared_cpu_map)); - } -} -#else -static void cache_shared_cpu_map_setup(unsigned int cpu, int index) -{ -} - -static void cache_remove_shared_cpu_map(unsigned int cpu, int index) -{ -} -#endif - -static void free_cache_attributes(unsigned int cpu) -{ - int i; - - for (i = 0; i < num_cache_leaves; i++) - cache_remove_shared_cpu_map(cpu, i); - - kfree(per_cpu(ici_cpuid4_info, cpu)); - per_cpu(ici_cpuid4_info, cpu) = NULL; -} - -static void get_cpu_leaves(void *_retval) -{ - int j, *retval = _retval, cpu = smp_processor_id(); + return; - /* Do cpuid and store the results */ - for (j = 0; j < num_cache_leaves; j++) { - struct _cpuid4_info *this_leaf = CPUID4_INFO_IDX(cpu, j); + index_msb = get_count_order(num_threads_sharing); - *retval = cpuid4_cache_lookup_regs(j, &this_leaf->base); - if (unlikely(*retval < 0)) { - int i; + for_each_online_cpu(i) + if (cpu_data(i).apicid >> index_msb == c->apicid >> index_msb) { + struct cpu_cacheinfo *sib_cpu_ci = get_cpu_cacheinfo(i); - for (i = 0; i < j; i++) - cache_remove_shared_cpu_map(cpu, i); - break; + if (i == cpu || !sib_cpu_ci->info_list) + continue;/* skip if itself or no cacheinfo */ + sibling_leaf = sib_cpu_ci->info_list + index; + cpumask_set_cpu(i, &this_leaf->shared_cpu_map); + cpumask_set_cpu(cpu, &sibling_leaf->shared_cpu_map); } - cache_shared_cpu_map_setup(cpu, j); - } } -static int detect_cache_attributes(unsigned int cpu) +static void ci_leaf_init(struct cacheinfo *this_leaf, + struct _cpuid4_info_regs *base) { - int retval; - - if (num_cache_leaves == 0) - return -ENOENT; - - per_cpu(ici_cpuid4_info, cpu) = kzalloc( - sizeof(struct _cpuid4_info) * num_cache_leaves, GFP_KERNEL); - if (per_cpu(ici_cpuid4_info, cpu) == NULL) - return -ENOMEM; - - smp_call_function_single(cpu, get_cpu_leaves, &retval, true); - if (retval) { - kfree(per_cpu(ici_cpuid4_info, cpu)); - per_cpu(ici_cpuid4_info, cpu) = NULL; - } - - return retval; + this_leaf->level = base->eax.split.level; + this_leaf->type = cache_type_map[base->eax.split.type]; + this_leaf->coherency_line_size = + base->ebx.split.coherency_line_size + 1; + this_leaf->ways_of_associativity = + base->ebx.split.ways_of_associativity + 1; + this_leaf->size = base->size; + this_leaf->number_of_sets = base->ecx.split.number_of_sets + 1; + this_leaf->physical_line_partition = + base->ebx.split.physical_line_partition + 1; + this_leaf->priv = base->nb; } -#include -#include -#include - -/* pointer to kobject for cpuX/cache */ -static DEFINE_PER_CPU(struct kobject *, ici_cache_kobject); - -struct _index_kobject { - struct kobject kobj; - unsigned int cpu; - unsigned short index; -}; - -/* pointer to array of kobjects for cpuX/cache/indexY */ -static DEFINE_PER_CPU(struct _index_kobject *, ici_index_kobject); -#define INDEX_KOBJECT_PTR(x, y) (&((per_cpu(ici_index_kobject, x))[y])) - -#define show_one_plus(file_name, object, val) \ -static ssize_t show_##file_name(struct _cpuid4_info *this_leaf, char *buf, \ - unsigned int cpu) \ -{ \ - return sprintf(buf, "%lu\n", (unsigned long)this_leaf->object + val); \ -} - -show_one_plus(level, base.eax.split.level, 0); -show_one_plus(coherency_line_size, base.ebx.split.coherency_line_size, 1); -show_one_plus(physical_line_partition, base.ebx.split.physical_line_partition, 1); -show_one_plus(ways_of_associativity, base.ebx.split.ways_of_associativity, 1); -show_one_plus(number_of_sets, base.ecx.split.number_of_sets, 1); - -static ssize_t show_size(struct _cpuid4_info *this_leaf, char *buf, - unsigned int cpu) -{ - return sprintf(buf, "%luK\n", this_leaf->base.size / 1024); -} - -static ssize_t show_shared_cpu_map_func(struct _cpuid4_info *this_leaf, - int type, char *buf) -{ - const struct cpumask *mask = to_cpumask(this_leaf->shared_cpu_map); - int ret; - - if (type) - ret = scnprintf(buf, PAGE_SIZE - 1, "%*pbl", - cpumask_pr_args(mask)); - else - ret = scnprintf(buf, PAGE_SIZE - 1, "%*pb", - cpumask_pr_args(mask)); - buf[ret++] = '\n'; - buf[ret] = '\0'; - return ret; -} - -static inline ssize_t show_shared_cpu_map(struct _cpuid4_info *leaf, char *buf, - unsigned int cpu) +static int __init_cache_level(unsigned int cpu) { - return show_shared_cpu_map_func(leaf, 0, buf); -} - -static inline ssize_t show_shared_cpu_list(struct _cpuid4_info *leaf, char *buf, - unsigned int cpu) -{ - return show_shared_cpu_map_func(leaf, 1, buf); -} + struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); -static ssize_t show_type(struct _cpuid4_info *this_leaf, char *buf, - unsigned int cpu) -{ - switch (this_leaf->base.eax.split.type) { - case CACHE_TYPE_DATA: - return sprintf(buf, "Data\n"); - case CACHE_TYPE_INST: - return sprintf(buf, "Instruction\n"); - case CACHE_TYPE_UNIFIED: - return sprintf(buf, "Unified\n"); - default: - return sprintf(buf, "Unknown\n"); - } -} - -#define to_object(k) container_of(k, struct _index_kobject, kobj) -#define to_attr(a) container_of(a, struct _cache_attr, attr) - -#define define_one_ro(_name) \ -static struct _cache_attr _name = \ - __ATTR(_name, 0444, show_##_name, NULL) - -define_one_ro(level); -define_one_ro(type); -define_one_ro(coherency_line_size); -define_one_ro(physical_line_partition); -define_one_ro(ways_of_associativity); -define_one_ro(number_of_sets); -define_one_ro(size); -define_one_ro(shared_cpu_map); -define_one_ro(shared_cpu_list); - -static struct attribute *default_attrs[] = { - &type.attr, - &level.attr, - &coherency_line_size.attr, - &physical_line_partition.attr, - &ways_of_associativity.attr, - &number_of_sets.attr, - &size.attr, - &shared_cpu_map.attr, - &shared_cpu_list.attr, - NULL -}; - -#ifdef CONFIG_AMD_NB -static struct attribute **amd_l3_attrs(void) -{ - static struct attribute **attrs; - int n; - - if (attrs) - return attrs; - - n = ARRAY_SIZE(default_attrs); - - if (amd_nb_has_feature(AMD_NB_L3_INDEX_DISABLE)) - n += 2; - - if (amd_nb_has_feature(AMD_NB_L3_PARTITIONING)) - n += 1; - - attrs = kzalloc(n * sizeof (struct attribute *), GFP_KERNEL); - if (attrs == NULL) - return attrs = default_attrs; - - for (n = 0; default_attrs[n]; n++) - attrs[n] = default_attrs[n]; - - if (amd_nb_has_feature(AMD_NB_L3_INDEX_DISABLE)) { - attrs[n++] = &cache_disable_0.attr; - attrs[n++] = &cache_disable_1.attr; - } - - if (amd_nb_has_feature(AMD_NB_L3_PARTITIONING)) - attrs[n++] = &subcaches.attr; - - return attrs; -} -#endif - -static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf) -{ - struct _cache_attr *fattr = to_attr(attr); - struct _index_kobject *this_leaf = to_object(kobj); - ssize_t ret; - - ret = fattr->show ? - fattr->show(CPUID4_INFO_IDX(this_leaf->cpu, this_leaf->index), - buf, this_leaf->cpu) : - 0; - return ret; -} - -static ssize_t store(struct kobject *kobj, struct attribute *attr, - const char *buf, size_t count) -{ - struct _cache_attr *fattr = to_attr(attr); - struct _index_kobject *this_leaf = to_object(kobj); - ssize_t ret; - - ret = fattr->store ? - fattr->store(CPUID4_INFO_IDX(this_leaf->cpu, this_leaf->index), - buf, count, this_leaf->cpu) : - 0; - return ret; -} - -static const struct sysfs_ops sysfs_ops = { - .show = show, - .store = store, -}; - -static struct kobj_type ktype_cache = { - .sysfs_ops = &sysfs_ops, - .default_attrs = default_attrs, -}; - -static struct kobj_type ktype_percpu_entry = { - .sysfs_ops = &sysfs_ops, -}; - -static void cpuid4_cache_sysfs_exit(unsigned int cpu) -{ - kfree(per_cpu(ici_cache_kobject, cpu)); - kfree(per_cpu(ici_index_kobject, cpu)); - per_cpu(ici_cache_kobject, cpu) = NULL; - per_cpu(ici_index_kobject, cpu) = NULL; - free_cache_attributes(cpu); -} - -static int cpuid4_cache_sysfs_init(unsigned int cpu) -{ - int err; - - if (num_cache_leaves == 0) + if (!num_cache_leaves) return -ENOENT; - - err = detect_cache_attributes(cpu); - if (err) - return err; - - /* Allocate all required memory */ - per_cpu(ici_cache_kobject, cpu) = - kzalloc(sizeof(struct kobject), GFP_KERNEL); - if (unlikely(per_cpu(ici_cache_kobject, cpu) == NULL)) - goto err_out; - - per_cpu(ici_index_kobject, cpu) = kzalloc( - sizeof(struct _index_kobject) * num_cache_leaves, GFP_KERNEL); - if (unlikely(per_cpu(ici_index_kobject, cpu) == NULL)) - goto err_out; - + if (!this_cpu_ci) + return -EINVAL; + this_cpu_ci->num_levels = 3; + this_cpu_ci->num_leaves = num_cache_leaves; return 0; - -err_out: - cpuid4_cache_sysfs_exit(cpu); - return -ENOMEM; } -static DECLARE_BITMAP(cache_dev_map, NR_CPUS); - -/* Add/Remove cache interface for CPU device */ -static int cache_add_dev(struct device *dev) +static int __populate_cache_leaves(unsigned int cpu) { - unsigned int cpu = dev->id; - unsigned long i, j; - struct _index_kobject *this_object; - struct _cpuid4_info *this_leaf; - int retval; - - retval = cpuid4_cache_sysfs_init(cpu); - if (unlikely(retval < 0)) - return retval; - - retval = kobject_init_and_add(per_cpu(ici_cache_kobject, cpu), - &ktype_percpu_entry, - &dev->kobj, "%s", "cache"); - if (retval < 0) { - cpuid4_cache_sysfs_exit(cpu); - return retval; - } + unsigned int idx, ret; + struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); + struct cacheinfo *this_leaf = this_cpu_ci->info_list; + struct _cpuid4_info_regs id4_regs = {}; - for (i = 0; i < num_cache_leaves; i++) { - this_object = INDEX_KOBJECT_PTR(cpu, i); - this_object->cpu = cpu; - this_object->index = i; - - this_leaf = CPUID4_INFO_IDX(cpu, i); - - ktype_cache.default_attrs = default_attrs; -#ifdef CONFIG_AMD_NB - if (this_leaf->base.nb) - ktype_cache.default_attrs = amd_l3_attrs(); -#endif - retval = kobject_init_and_add(&(this_object->kobj), - &ktype_cache, - per_cpu(ici_cache_kobject, cpu), - "index%1lu", i); - if (unlikely(retval)) { - for (j = 0; j < i; j++) - kobject_put(&(INDEX_KOBJECT_PTR(cpu, j)->kobj)); - kobject_put(per_cpu(ici_cache_kobject, cpu)); - cpuid4_cache_sysfs_exit(cpu); - return retval; - } - kobject_uevent(&(this_object->kobj), KOBJ_ADD); + for (idx = 0; idx < this_cpu_ci->num_leaves; idx++) { + ret = cpuid4_cache_lookup_regs(idx, &id4_regs); + if (ret) + return ret; + ci_leaf_init(this_leaf++, &id4_regs); + __cache_cpumap_setup(cpu, idx, &id4_regs); } - cpumask_set_cpu(cpu, to_cpumask(cache_dev_map)); - - kobject_uevent(per_cpu(ici_cache_kobject, cpu), KOBJ_ADD); return 0; } -static void cache_remove_dev(struct device *dev) -{ - unsigned int cpu = dev->id; - unsigned long i; - - if (per_cpu(ici_cpuid4_info, cpu) == NULL) - return; - if (!cpumask_test_cpu(cpu, to_cpumask(cache_dev_map))) - return; - cpumask_clear_cpu(cpu, to_cpumask(cache_dev_map)); - - for (i = 0; i < num_cache_leaves; i++) - kobject_put(&(INDEX_KOBJECT_PTR(cpu, i)->kobj)); - kobject_put(per_cpu(ici_cache_kobject, cpu)); - cpuid4_cache_sysfs_exit(cpu); -} - -static int cacheinfo_cpu_callback(struct notifier_block *nfb, - unsigned long action, void *hcpu) -{ - unsigned int cpu = (unsigned long)hcpu; - struct device *dev; - - dev = get_cpu_device(cpu); - switch (action) { - case CPU_ONLINE: - case CPU_ONLINE_FROZEN: - cache_add_dev(dev); - break; - case CPU_DEAD: - case CPU_DEAD_FROZEN: - cache_remove_dev(dev); - break; - } - return NOTIFY_OK; -} - -static struct notifier_block cacheinfo_cpu_notifier = { - .notifier_call = cacheinfo_cpu_callback, -}; - -static int __init cache_sysfs_init(void) -{ - int i, err = 0; - - if (num_cache_leaves == 0) - return 0; - - cpu_notifier_register_begin(); - for_each_online_cpu(i) { - struct device *dev = get_cpu_device(i); - - err = cache_add_dev(dev); - if (err) - goto out; - } - __register_hotcpu_notifier(&cacheinfo_cpu_notifier); - -out: - cpu_notifier_register_done(); - return err; -} - -device_initcall(cache_sysfs_init); - -#endif +DEFINE_SMP_CALL_CACHE_FUNCTION(init_cache_level) +DEFINE_SMP_CALL_CACHE_FUNCTION(populate_cache_leaves) -- GitLab From 969439016d2cf61fef53a973d7e6d2061c3793b1 Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Mon, 23 Feb 2015 20:37:54 +0100 Subject: [PATCH 03447/11651] can: add missing initialisations in CAN related skbuffs When accessing CAN network interfaces with AF_PACKET sockets e.g. by dhclient this can lead to a skb_under_panic due to missing skb initialisations. Add the missing initialisations at the CAN skbuff creation times on driver level (rx path) and in the network layer (tx path). Reported-by: Austin Schuh Reported-by: Daniel Steer Signed-off-by: Oliver Hartkopp Cc: linux-stable Signed-off-by: Marc Kleine-Budde --- drivers/net/can/dev.c | 8 ++++++++ net/can/af_can.c | 3 +++ 2 files changed, 11 insertions(+) diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index 3c82e02e3dae..b0f69248cb71 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c @@ -579,6 +579,10 @@ struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf) skb->pkt_type = PACKET_BROADCAST; skb->ip_summed = CHECKSUM_UNNECESSARY; + skb_reset_mac_header(skb); + skb_reset_network_header(skb); + skb_reset_transport_header(skb); + can_skb_reserve(skb); can_skb_prv(skb)->ifindex = dev->ifindex; @@ -603,6 +607,10 @@ struct sk_buff *alloc_canfd_skb(struct net_device *dev, skb->pkt_type = PACKET_BROADCAST; skb->ip_summed = CHECKSUM_UNNECESSARY; + skb_reset_mac_header(skb); + skb_reset_network_header(skb); + skb_reset_transport_header(skb); + can_skb_reserve(skb); can_skb_prv(skb)->ifindex = dev->ifindex; diff --git a/net/can/af_can.c b/net/can/af_can.c index 66e08040ced7..32d710eaf1fc 100644 --- a/net/can/af_can.c +++ b/net/can/af_can.c @@ -259,6 +259,9 @@ int can_send(struct sk_buff *skb, int loop) goto inval_skb; } + skb->ip_summed = CHECKSUM_UNNECESSARY; + + skb_reset_mac_header(skb); skb_reset_network_header(skb); skb_reset_transport_header(skb); -- GitLab From b0d4724b8e4ce2a60ee4e097ec50c3759ec2090a Mon Sep 17 00:00:00 2001 From: Stephane Grosjean Date: Mon, 2 Mar 2015 11:54:38 +0100 Subject: [PATCH 03448/11651] can: peak_usb: fix missing ctrlmode_ init for every dev Fixes a missing initialization of ctrlmode and ctrlmode_supported fields, for all other CAN devices than the first one. This fix only concerns the PCAN-USB Pro FD dual-channels CAN-FD device made by PEAK-System. Signed-off-by: Stephane Grosjean Signed-off-by: Marc Kleine-Budde --- drivers/net/can/usb/peak_usb/pcan_usb_fd.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c index 962c3f027383..0bac0f14edc3 100644 --- a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c +++ b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c @@ -879,6 +879,10 @@ static int pcan_usb_fd_init(struct peak_usb_device *dev) pdev->usb_if = ppdev->usb_if; pdev->cmd_buffer_addr = ppdev->cmd_buffer_addr; + + /* do a copy of the ctrlmode[_supported] too */ + dev->can.ctrlmode = ppdev->dev.can.ctrlmode; + dev->can.ctrlmode_supported = ppdev->dev.can.ctrlmode_supported; } pdev->usb_if->dev[dev->ctrl_idx] = dev; -- GitLab From deb2701cf704a2fd03a8b598bf73df3edb08818d Mon Sep 17 00:00:00 2001 From: "Ahmed S. Darwish" Date: Thu, 26 Feb 2015 10:20:11 -0500 Subject: [PATCH 03449/11651] can: kvaser_usb: Avoid double free on URB submission failures Upon a URB submission failure, the driver calls usb_free_urb() but then manually frees the URB buffer by itself. Meanwhile usb_free_urb() has alredy freed out that transfer buffer since we're the only code path holding a reference to this URB. Remove two of such invalid manual free(). Signed-off-by: Ahmed S. Darwish Cc: linux-stable Signed-off-by: Marc Kleine-Budde --- drivers/net/can/usb/kvaser_usb.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/drivers/net/can/usb/kvaser_usb.c b/drivers/net/can/usb/kvaser_usb.c index 2928f7003041..d986fe83c40d 100644 --- a/drivers/net/can/usb/kvaser_usb.c +++ b/drivers/net/can/usb/kvaser_usb.c @@ -787,7 +787,6 @@ static int kvaser_usb_simple_msg_async(struct kvaser_usb_net_priv *priv, netdev_err(netdev, "Error transmitting URB\n"); usb_unanchor_urb(urb); usb_free_urb(urb); - kfree(buf); return err; } @@ -1615,8 +1614,7 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb, struct urb *urb; void *buf; struct kvaser_msg *msg; - int i, err; - int ret = NETDEV_TX_OK; + int i, err, ret = NETDEV_TX_OK; u8 *msg_tx_can_flags = NULL; /* GCC */ if (can_dropped_invalid_skb(netdev, skb)) @@ -1634,7 +1632,7 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb, if (!buf) { stats->tx_dropped++; dev_kfree_skb(skb); - goto nobufmem; + goto freeurb; } msg = buf; @@ -1681,8 +1679,10 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb, /* This should never happen; it implies a flow control bug */ if (!context) { netdev_warn(netdev, "cannot find free context\n"); + + kfree(buf); ret = NETDEV_TX_BUSY; - goto releasebuf; + goto freeurb; } context->priv = priv; @@ -1719,16 +1719,12 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb, else netdev_warn(netdev, "Failed tx_urb %d\n", err); - goto releasebuf; + goto freeurb; } - usb_free_urb(urb); - - return NETDEV_TX_OK; + ret = NETDEV_TX_OK; -releasebuf: - kfree(buf); -nobufmem: +freeurb: usb_free_urb(urb); return ret; } -- GitLab From 2fec5104f9c61de4cf2205aa355101e19a81f490 Mon Sep 17 00:00:00 2001 From: "Ahmed S. Darwish" Date: Thu, 26 Feb 2015 10:22:02 -0500 Subject: [PATCH 03450/11651] can: kvaser_usb: Read all messages in a bulk-in URB buffer The Kvaser firmware can only read and write messages that are not crossing the USB endpoint's wMaxPacketSize boundary. While receiving commands from the CAN device, if the next command in the same URB buffer crossed that max packet size boundary, the firmware puts a zero-length placeholder command in its place then moves the real command to the next boundary mark. The driver did not recognize such behavior, leading to missing a good number of rx events during a heavy rx load session. Moreover, a tx URB context only gets freed upon receiving its respective tx ACK event. Over time, the free tx URB contexts pool gets depleted due to the missing ACK events. Consequently, the netif transmission queue gets __permanently__ stopped; no frames could be sent again except after restarting the CAN newtwork interface. Signed-off-by: Ahmed S. Darwish Cc: linux-stable Signed-off-by: Marc Kleine-Budde --- drivers/net/can/usb/kvaser_usb.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/drivers/net/can/usb/kvaser_usb.c b/drivers/net/can/usb/kvaser_usb.c index d986fe83c40d..a316fa4b91ab 100644 --- a/drivers/net/can/usb/kvaser_usb.c +++ b/drivers/net/can/usb/kvaser_usb.c @@ -14,6 +14,7 @@ * Copyright (C) 2015 Valeo S.A. */ +#include #include #include #include @@ -584,8 +585,15 @@ static int kvaser_usb_wait_msg(const struct kvaser_usb *dev, u8 id, while (pos <= actual_len - MSG_HEADER_LEN) { tmp = buf + pos; - if (!tmp->len) - break; + /* Handle messages crossing the USB endpoint max packet + * size boundary. Check kvaser_usb_read_bulk_callback() + * for further details. + */ + if (tmp->len == 0) { + pos = round_up(pos, + dev->bulk_in->wMaxPacketSize); + continue; + } if (pos + tmp->len > actual_len) { dev_err(dev->udev->dev.parent, @@ -1316,8 +1324,19 @@ static void kvaser_usb_read_bulk_callback(struct urb *urb) while (pos <= urb->actual_length - MSG_HEADER_LEN) { msg = urb->transfer_buffer + pos; - if (!msg->len) - break; + /* The Kvaser firmware can only read and write messages that + * does not cross the USB's endpoint wMaxPacketSize boundary. + * If a follow-up command crosses such boundary, firmware puts + * a placeholder zero-length command in its place then aligns + * the real command to the next max packet size. + * + * Handle such cases or we're going to miss a significant + * number of events in case of a heavy rx load on the bus. + */ + if (msg->len == 0) { + pos = round_up(pos, dev->bulk_in->wMaxPacketSize); + continue; + } if (pos + msg->len > urb->actual_length) { dev_err(dev->udev->dev.parent, "Format error\n"); @@ -1325,7 +1344,6 @@ static void kvaser_usb_read_bulk_callback(struct urb *urb) } kvaser_usb_handle_message(dev, msg); - pos += msg->len; } -- GitLab From 84b0d715d805a2af5b12a51ce85f66cec87111d0 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Fri, 6 Mar 2015 08:58:33 +0100 Subject: [PATCH 03451/11651] MAINTAINERS: linux-can moved to github As gitorious will shut down at the end of May 2015, the linux-can website moved to github. This patch reflects this change. Signed-off-by: Marc Kleine-Budde --- MAINTAINERS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 42f686f2e4b2..ce4380d7ab1a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2370,7 +2370,7 @@ F: arch/x86/include/asm/tce.h CAN NETWORK LAYER M: Oliver Hartkopp L: linux-can@vger.kernel.org -W: http://gitorious.org/linux-can +W: https://github.com/linux-can T: git git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can.git T: git git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next.git S: Maintained @@ -2386,7 +2386,7 @@ CAN NETWORK DRIVERS M: Wolfgang Grandegger M: Marc Kleine-Budde L: linux-can@vger.kernel.org -W: http://gitorious.org/linux-can +W: https://github.com/linux-can T: git git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can.git T: git git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next.git S: Maintained -- GitLab From f7214cf29ca6c977ad2c428f2b832e9c66f2ee1b Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Fri, 6 Mar 2015 09:00:38 +0100 Subject: [PATCH 03452/11651] MAINTAINERS: add Marc Kleine-Budde as co maintainer for CAN networking layer This patch adds Marc Kleine-Budde as a co maintainer for the CAN networking layer. Acked-by: Oliver Hartkopp Signed-off-by: Marc Kleine-Budde --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index ce4380d7ab1a..ba57e5d3ed5c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2369,6 +2369,7 @@ F: arch/x86/include/asm/tce.h CAN NETWORK LAYER M: Oliver Hartkopp +M: Marc Kleine-Budde L: linux-can@vger.kernel.org W: https://github.com/linux-can T: git git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can.git -- GitLab From 9cbbf3dc994797f49cd30607a16182ca6c87863f Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Fri, 13 Feb 2015 15:52:21 +0200 Subject: [PATCH 03453/11651] i2c: i801: Don't break user-visible strings It makes more difficult to grep these error prints from sources if they are split to multiple source lines. Signed-off-by: Jarkko Nikula Reviewed-by: Jean Delvare Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-i801.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 8fafb254e42a..7d1f4a478c54 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -1192,8 +1192,8 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id) /* Determine the address of the SMBus area */ priv->smba = pci_resource_start(dev, SMBBAR); if (!priv->smba) { - dev_err(&dev->dev, "SMBus base address uninitialized, " - "upgrade BIOS\n"); + dev_err(&dev->dev, + "SMBus base address uninitialized, upgrade BIOS\n"); err = -ENODEV; goto exit; } @@ -1206,8 +1206,9 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id) err = pci_request_region(dev, SMBBAR, i801_driver.name); if (err) { - dev_err(&dev->dev, "Failed to request SMBus region " - "0x%lx-0x%Lx\n", priv->smba, + dev_err(&dev->dev, + "Failed to request SMBus region 0x%lx-0x%Lx\n", + priv->smba, (unsigned long long)pci_resource_end(dev, SMBBAR)); goto exit; } -- GitLab From 256493c58625530a958296724b92b344f3271b2f Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Fri, 13 Feb 2015 15:52:22 +0200 Subject: [PATCH 03454/11651] i2c: i801: Remove i801_driver forward declaration struct pci_driver i801_driver forward declaration is needed only for accessing the name field. Remove it and use dev_driver_string() instead. Signed-off-by: Jarkko Nikula Reviewed-by: Jean Delvare Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-i801.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 7d1f4a478c54..5f827dfc671a 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -223,8 +223,6 @@ struct i801_priv { #endif }; -static struct pci_driver i801_driver; - #define FEATURE_SMBUS_PEC (1 << 0) #define FEATURE_BLOCK_BUFFER (1 << 1) #define FEATURE_BLOCK_PROC (1 << 2) @@ -1204,7 +1202,7 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id) goto exit; } - err = pci_request_region(dev, SMBBAR, i801_driver.name); + err = pci_request_region(dev, SMBBAR, dev_driver_string(&dev->dev)); if (err) { dev_err(&dev->dev, "Failed to request SMBus region 0x%lx-0x%Lx\n", @@ -1256,7 +1254,7 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id) init_waitqueue_head(&priv->waitq); err = request_irq(dev->irq, i801_isr, IRQF_SHARED, - i801_driver.name, priv); + dev_driver_string(&dev->dev), priv); if (err) { dev_err(&dev->dev, "Failed to allocate irq %d: %d\n", dev->irq, err); -- GitLab From 1621c59d94d13380015fb5131acc6c14ecd1c797 Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Fri, 13 Feb 2015 15:52:23 +0200 Subject: [PATCH 03455/11651] i2c: i801: Use managed devm_* memory and irq allocation This simplifies the error and remove paths. Signed-off-by: Jarkko Nikula Reviewed-by: Jean Delvare Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-i801.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 5f827dfc671a..b1d725d758bb 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -1138,7 +1138,7 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id) int err, i; struct i801_priv *priv; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = devm_kzalloc(&dev->dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; @@ -1253,8 +1253,9 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id) if (priv->features & FEATURE_IRQ) { init_waitqueue_head(&priv->waitq); - err = request_irq(dev->irq, i801_isr, IRQF_SHARED, - dev_driver_string(&dev->dev), priv); + err = devm_request_irq(&dev->dev, dev->irq, i801_isr, + IRQF_SHARED, + dev_driver_string(&dev->dev), priv); if (err) { dev_err(&dev->dev, "Failed to allocate irq %d: %d\n", dev->irq, err); @@ -1275,7 +1276,7 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id) err = i2c_add_adapter(&priv->adapter); if (err) { dev_err(&dev->dev, "Failed to add SMBus adapter\n"); - goto exit_free_irq; + goto exit_release; } i801_probe_optional_slaves(priv); @@ -1286,12 +1287,9 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id) return 0; -exit_free_irq: - if (priv->features & FEATURE_IRQ) - free_irq(dev->irq, priv); +exit_release: pci_release_region(dev, SMBBAR); exit: - kfree(priv); return err; } @@ -1303,11 +1301,8 @@ static void i801_remove(struct pci_dev *dev) i2c_del_adapter(&priv->adapter); pci_write_config_byte(dev, SMBHSTCFG, priv->original_hstcfg); - if (priv->features & FEATURE_IRQ) - free_irq(dev->irq, priv); pci_release_region(dev, SMBBAR); - kfree(priv); /* * do not call pci_disable_device(dev) since it can cause hard hangs on * some systems during power-off (eg. Fujitsu-Siemens Lifebook E8010) -- GitLab From f85da3f5de6f354bc26eb84c013b41a8b8558c5e Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Fri, 13 Feb 2015 15:52:24 +0200 Subject: [PATCH 03456/11651] i2c: i801: Remove pci_enable_device() call from i801_resume() Since pci_disable_device() is not called from i801_suspend() and power state is set already it means that subsequent pci_enable_device() calls do practically nothing but monotonically increase struct pci_dev enable_cnt. Signed-off-by: Jarkko Nikula Reviewed-by: Jean Delvare Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-i801.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index b1d725d758bb..5fb35464f693 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -1324,7 +1324,7 @@ static int i801_resume(struct pci_dev *dev) { pci_set_power_state(dev, PCI_D0); pci_restore_state(dev); - return pci_enable_device(dev); + return 0; } #else #define i801_suspend NULL -- GitLab From fef220da43d8537ed7d11da4db17b958cd779887 Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Fri, 13 Feb 2015 15:52:25 +0200 Subject: [PATCH 03457/11651] i2c: i801: Use managed pcim_* PCI device initialization and reservation Simplifies the code a bit and makes easier to disable PCI device on driver detach by removing the pcim_pin_device() call in the future if needed. Reason why i2c-i801.c doesn't ever call pci_disable_device() was because it made some systems to hang during power-off. See commit d6fcb3b9cf77 ("[PATCH] i2c-i801.c: don't pci_disable_device() after it was just enabled") and http://marc.info/?l=linux-kernel&m=115160053309535&w=2 Signed-off-by: Jarkko Nikula Reviewed-by: Jean Delvare Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-i801.c | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 5fb35464f693..5ecbb3fdc27e 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -1180,35 +1180,35 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id) } priv->features &= ~disable_features; - err = pci_enable_device(dev); + err = pcim_enable_device(dev); if (err) { dev_err(&dev->dev, "Failed to enable SMBus PCI device (%d)\n", err); - goto exit; + return err; } + pcim_pin_device(dev); /* Determine the address of the SMBus area */ priv->smba = pci_resource_start(dev, SMBBAR); if (!priv->smba) { dev_err(&dev->dev, "SMBus base address uninitialized, upgrade BIOS\n"); - err = -ENODEV; - goto exit; + return -ENODEV; } err = acpi_check_resource_conflict(&dev->resource[SMBBAR]); if (err) { - err = -ENODEV; - goto exit; + return -ENODEV; } - err = pci_request_region(dev, SMBBAR, dev_driver_string(&dev->dev)); + err = pcim_iomap_regions(dev, 1 << SMBBAR, + dev_driver_string(&dev->dev)); if (err) { dev_err(&dev->dev, "Failed to request SMBus region 0x%lx-0x%Lx\n", priv->smba, (unsigned long long)pci_resource_end(dev, SMBBAR)); - goto exit; + return err; } pci_read_config_byte(priv->pci_dev, SMBHSTCFG, &temp); @@ -1276,7 +1276,7 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id) err = i2c_add_adapter(&priv->adapter); if (err) { dev_err(&dev->dev, "Failed to add SMBus adapter\n"); - goto exit_release; + return err; } i801_probe_optional_slaves(priv); @@ -1286,11 +1286,6 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id) pci_set_drvdata(dev, priv); return 0; - -exit_release: - pci_release_region(dev, SMBBAR); -exit: - return err; } static void i801_remove(struct pci_dev *dev) @@ -1301,8 +1296,6 @@ static void i801_remove(struct pci_dev *dev) i2c_del_adapter(&priv->adapter); pci_write_config_byte(dev, SMBHSTCFG, priv->original_hstcfg); - pci_release_region(dev, SMBBAR); - /* * do not call pci_disable_device(dev) since it can cause hard hangs on * some systems during power-off (eg. Fujitsu-Siemens Lifebook E8010) -- GitLab From 58b59e0f2462780ae3978611519f6a5e477e31df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Tue, 17 Feb 2015 10:12:08 +0100 Subject: [PATCH 03458/11651] i2c: pca954x: improve usage of gpiod API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since 39b2bbe3d715 (gpio: add flags argument to gpiod_get*() functions) which appeared in v3.17-rc1, the gpiod_get* functions take an additional parameter that allows to specify direction and initial value for outputs. Also there is an *_optional variant that serves well here. The sematics is slightly changed here by using it. Now if a reset gpio is specified and getting hold on it fails, pca954x_probe fails, too. Signed-off-by: Uwe Kleine-König Acked-by: Laurent Pinchart Signed-off-by: Wolfram Sang --- drivers/i2c/muxes/i2c-mux-pca954x.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/muxes/i2c-mux-pca954x.c b/drivers/i2c/muxes/i2c-mux-pca954x.c index 3d8f4fe2e47e..bea0d2de2993 100644 --- a/drivers/i2c/muxes/i2c-mux-pca954x.c +++ b/drivers/i2c/muxes/i2c-mux-pca954x.c @@ -204,9 +204,9 @@ static int pca954x_probe(struct i2c_client *client, i2c_set_clientdata(client, data); /* Get the mux out of reset if a reset GPIO is specified. */ - gpio = devm_gpiod_get(&client->dev, "reset"); - if (!IS_ERR(gpio)) - gpiod_direction_output(gpio, 0); + gpio = devm_gpiod_get_optional(&client->dev, "reset", GPIOD_OUT_LOW); + if (IS_ERR(gpio)) + return PTR_ERR(gpio); /* Write the mux register at addr to verify * that the mux is in fact present. This also -- GitLab From 060e234e959a1c42f40f355963064c3e24981c7f Mon Sep 17 00:00:00 2001 From: Yanjiang Jin Date: Fri, 6 Mar 2015 10:34:41 +0800 Subject: [PATCH 03459/11651] crypto: caam - fix uninitialized edesc->sec4_sg_bytes field sec4_sg_bytes not being properly initialized causes ahash_done to try to free unallocated DMA memory: caam_jr ffe301000.jr: DMA-API: device driver tries to free DMA memory it has not allocated [device address=0xdeadbeefdeadbeef] [size=3735928559 bytes] ------------[ cut here ]------------ WARNING: at lib/dma-debug.c:1093 Modules linked in: CPU: 1 PID: 0 Comm: swapper/1 Not tainted 4.0.0-rc1+ #6 task: e9598c00 ti: effca000 task.ti: e95a2000 NIP: c04ef24c LR: c04ef24c CTR: c0549730 REGS: effcbd40 TRAP: 0700 Not tainted (4.0.0-rc1+) MSR: 00029002 CR: 22008084 XER: 20000000 GPR00: c04ef24c effcbdf0 e9598c00 00000096 c08f7424 c00ab2b0 00000000 00000001 GPR08: c0fe7510 effca000 00000000 000001c3 22008082 00000000 c1048e77 c1050000 GPR16: c0c36700 493c0040 0000002c e690e4a0 c1054fb4 c18bac40 00029002 c18b0788 GPR24: 00000014 e690e480 effcbe48 00000000 c0fde128 e6ffac10 deadbeef deadbeef NIP [c04ef24c] check_unmap+0x93c/0xb40 LR [c04ef24c] check_unmap+0x93c/0xb40 Call Trace: [effcbdf0] [c04ef24c] check_unmap+0x93c/0xb40 (unreliable) [effcbe40] [c04ef4f4] debug_dma_unmap_page+0xa4/0xc0 [effcbec0] [c070cda8] ahash_done+0x128/0x1a0 [effcbef0] [c0700070] caam_jr_dequeue+0x1d0/0x290 [effcbf40] [c0045f40] tasklet_action+0x110/0x1f0 [effcbf80] [c0044bc8] __do_softirq+0x188/0x700 [effcbfe0] [c00455d8] irq_exit+0x108/0x120 [effcbff0] [c000f520] call_do_irq+0x24/0x3c [e95a3e20] [c00059b8] do_IRQ+0xc8/0x170 [e95a3e50] [c0011bc8] ret_from_except+0x0/0x18 Signed-off-by: Yanjiang Jin Acked-by: Kim Phillips Signed-off-by: Herbert Xu --- drivers/crypto/caam/caamhash.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/crypto/caam/caamhash.c b/drivers/crypto/caam/caamhash.c index f347ab7eea95..ba0532efd3ae 100644 --- a/drivers/crypto/caam/caamhash.c +++ b/drivers/crypto/caam/caamhash.c @@ -1172,6 +1172,7 @@ static int ahash_final_no_ctx(struct ahash_request *req) return -ENOMEM; } + edesc->sec4_sg_bytes = 0; sh_len = desc_len(sh_desc); desc = edesc->hw_desc; init_job_desc_shared(desc, ptr, sh_len, HDR_SHARE_DEFER | HDR_REVERSE); -- GitLab From 4842234f83bfce83c93f84f5972a956ef2c87805 Mon Sep 17 00:00:00 2001 From: Yanjiang Jin Date: Fri, 6 Mar 2015 10:34:42 +0800 Subject: [PATCH 03460/11651] hwrng: caam - fix rng_unmap_ctx's DMA_UNMAP size problem Fix rng_unmap_ctx's DMA_UNMAP size problem for caam_rng, else system would report the below calltrace during cleanup caam_rng. Since rng_create_sh_desc() creates a fixed descriptor of exactly 4 command-lengths now, also update DESC_RNG_LEN to (4 * CAAM_CMD_SZ). caam_jr ffe301000.jr: DMA-API: device driver frees DMA memory with different size [device address=0x000000007f080010] [map size=16 bytes] [unmap size=40 bytes] ------------[ cut here ]------------ WARNING: at lib/dma-debug.c:887 Modules linked in: task: c0000000f7cdaa80 ti: c0000000e5340000 task.ti: c0000000e5340000 NIP: c0000000004f5bc8 LR: c0000000004f5bc4 CTR: c0000000005f69b0 REGS: c0000000e53433c0 TRAP: 0700 Not tainted MSR: 0000000080029000 CR: 24088482 XER: 00000000 SOFTE: 0 GPR00: c0000000004f5bc4 c0000000e5343640 c0000000012af360 000000000000009f GPR04: 0000000000000000 00000000000000a0 c000000000d02070 c000000015980660 GPR08: c000000000cff360 0000000000000000 0000000000000000 c0000000012da018 GPR12: 00000000000001e3 c000000001fff780 00000000100f0000 0000000000000001 GPR16: 0000000000000002 0000000000000000 0000000000000000 0000000000000000 GPR20: 0000000000000000 0000000000000000 ffffffffffffffff 0000000000000001 GPR24: 0000000000000001 0000000000000001 0000000000000000 0000000000000001 GPR28: c000000001556b90 c000000001565b80 c0000000e5343750 c0000000f9427480 NIP [c0000000004f5bc8] .check_unmap+0x538/0x9c0 LR [c0000000004f5bc4] .check_unmap+0x534/0x9c0 Call Trace: [c0000000e5343640] [c0000000004f5bc4] .check_unmap+0x534/0x9c0 (unreliable) [c0000000e53436e0] [c0000000004f60d4] .debug_dma_unmap_page+0x84/0xb0 [c0000000e5343810] [c00000000082f9d4] .caam_cleanup+0x1d4/0x240 [c0000000e53438a0] [c00000000056cc88] .hwrng_unregister+0xd8/0x1c0 Instruction dump: 7c641b78 41de0410 e8a90050 2fa50000 419e0484 e8de0028 e8ff0030 3c62ff90 e91e0030 38638388 48546ed9 60000000 <0fe00000> 3c62ff8f 38637fc8 48546ec5 ---[ end trace e43fd1734d6600df ]--- Signed-off-by: Yanjiang Jin Acked-by: Kim Phillips Signed-off-by: Herbert Xu --- drivers/crypto/caam/caamrng.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/crypto/caam/caamrng.c b/drivers/crypto/caam/caamrng.c index ae31e555793c..26a544b505f1 100644 --- a/drivers/crypto/caam/caamrng.c +++ b/drivers/crypto/caam/caamrng.c @@ -52,7 +52,7 @@ /* length of descriptors */ #define DESC_JOB_O_LEN (CAAM_CMD_SZ * 2 + CAAM_PTR_SZ * 2) -#define DESC_RNG_LEN (10 * CAAM_CMD_SZ) +#define DESC_RNG_LEN (4 * CAAM_CMD_SZ) /* Buffer, its dma address and lock */ struct buf_data { @@ -90,8 +90,8 @@ static inline void rng_unmap_ctx(struct caam_rng_ctx *ctx) struct device *jrdev = ctx->jrdev; if (ctx->sh_desc_dma) - dma_unmap_single(jrdev, ctx->sh_desc_dma, DESC_RNG_LEN, - DMA_TO_DEVICE); + dma_unmap_single(jrdev, ctx->sh_desc_dma, + desc_bytes(ctx->sh_desc), DMA_TO_DEVICE); rng_unmap_buf(jrdev, &ctx->bufs[0]); rng_unmap_buf(jrdev, &ctx->bufs[1]); } -- GitLab From cde001e4c3c3625c60b68a83eb1f1c2572dee07a Mon Sep 17 00:00:00 2001 From: Stephan Mueller Date: Fri, 6 Mar 2015 08:26:31 +0100 Subject: [PATCH 03461/11651] crypto: rng - RNGs must return 0 in success case Change the RNGs to always return 0 in success case. This patch ensures that seqiv.c works with RNGs other than krng. seqiv expects that any return code other than 0 is an error. Without the patch, rfc4106(gcm(aes)) will not work when using a DRBG or an ANSI X9.31 RNG. Signed-off-by: Stephan Mueller Signed-off-by: Herbert Xu --- crypto/ansi_cprng.c | 6 +++++- crypto/drbg.c | 7 ++++++- include/crypto/rng.h | 3 +-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/crypto/ansi_cprng.c b/crypto/ansi_cprng.c index 6f5bebc9bf01..765fe7609348 100644 --- a/crypto/ansi_cprng.c +++ b/crypto/ansi_cprng.c @@ -210,7 +210,11 @@ static int get_prng_bytes(char *buf, size_t nbytes, struct prng_context *ctx, byte_count = DEFAULT_BLK_SZ; } - err = byte_count; + /* + * Return 0 in case of success as mandated by the kernel + * crypto API interface definition. + */ + err = 0; dbgprint(KERN_CRIT "getting %d random bytes for context %p\n", byte_count, ctx); diff --git a/crypto/drbg.c b/crypto/drbg.c index 56c1d7ec3d9e..b69409cb7e6a 100644 --- a/crypto/drbg.c +++ b/crypto/drbg.c @@ -1280,7 +1280,7 @@ static void drbg_restore_shadow(struct drbg_state *drbg, * as defined in SP800-90A. The additional input is mixed into * the state in addition to the pulled entropy. * - * return: generated number of bytes + * return: 0 when all bytes are generated; < 0 in case of an error */ static int drbg_generate(struct drbg_state *drbg, unsigned char *buf, unsigned int buflen, @@ -1419,6 +1419,11 @@ static int drbg_generate(struct drbg_state *drbg, } #endif + /* + * All operations were successful, return 0 as mandated by + * the kernel crypto API interface. + */ + len = 0; err: shadow->d_ops->crypto_fini(shadow); drbg_restore_shadow(drbg, &shadow); diff --git a/include/crypto/rng.h b/include/crypto/rng.h index a16fb10142bf..6e28ea5be9f1 100644 --- a/include/crypto/rng.h +++ b/include/crypto/rng.h @@ -103,8 +103,7 @@ static inline void crypto_free_rng(struct crypto_rng *tfm) * This function fills the caller-allocated buffer with random numbers using the * random number generator referenced by the cipher handle. * - * Return: > 0 function was successful and returns the number of generated - * bytes; < 0 if an error occurred + * Return: 0 function was successful; < 0 if an error occurred */ static inline int crypto_rng_get_bytes(struct crypto_rng *tfm, u8 *rdata, unsigned int dlen) -- GitLab From dbe5fe7e1b3b3632bef2c09964a5f5505de4d744 Mon Sep 17 00:00:00 2001 From: Stephan Mueller Date: Fri, 6 Mar 2015 21:34:22 +0100 Subject: [PATCH 03462/11651] crypto: doc - AEAD / RNG AF_ALG interface The patch moves the information provided in Documentation/crypto/crypto-API-userspace.txt into a separate chapter in the kernel crypto API DocBook. Some corrections are applied (such as removing a reference to Netlink when the AF_ALG socket is referred to). In addition, the AEAD and RNG interface description is now added. Also, a brief description of the zero-copy interface with an example code snippet is provided. Signed-off-by: Stephan Mueller Signed-off-by: Herbert Xu --- Documentation/DocBook/crypto-API.tmpl | 596 ++++++++++++++++++ Documentation/crypto/crypto-API-userspace.txt | 205 ------ 2 files changed, 596 insertions(+), 205 deletions(-) delete mode 100644 Documentation/crypto/crypto-API-userspace.txt diff --git a/Documentation/DocBook/crypto-API.tmpl b/Documentation/DocBook/crypto-API.tmpl index 33f63cfc00ca..efc8d90a9a3f 100644 --- a/Documentation/DocBook/crypto-API.tmpl +++ b/Documentation/DocBook/crypto-API.tmpl @@ -1072,6 +1072,602 @@ kernel crypto API | Caller + User Space Interface + Introduction + + The concepts of the kernel crypto API visible to kernel space is fully + applicable to the user space interface as well. Therefore, the kernel + crypto API high level discussion for the in-kernel use cases applies + here as well. + + + + The major difference, however, is that user space can only act as a + consumer and never as a provider of a transformation or cipher algorithm. + + + + The following covers the user space interface exported by the kernel + crypto API. A working example of this description is libkcapi that + can be obtained from [1]. That library can be used by user space + applications that require cryptographic services from the kernel. + + + + Some details of the in-kernel kernel crypto API aspects do not + apply to user space, however. This includes the difference between + synchronous and asynchronous invocations. The user space API call + is fully synchronous. + + + + [1] http://www.chronox.de/libkcapi.html + + + + + User Space API General Remarks + + The kernel crypto API is accessible from user space. Currently, + the following ciphers are accessible: + + + + + Message digest including keyed message digest (HMAC, CMAC) + + + + Symmetric ciphers + + + + AEAD ciphers + + + + Random Number Generators + + + + + The interface is provided via socket type using the type AF_ALG. + In addition, the setsockopt option type is SOL_ALG. In case the + user space header files do not export these flags yet, use the + following macros: + + + +#ifndef AF_ALG +#define AF_ALG 38 +#endif +#ifndef SOL_ALG +#define SOL_ALG 279 +#endif + + + + A cipher is accessed with the same name as done for the in-kernel + API calls. This includes the generic vs. unique naming schema for + ciphers as well as the enforcement of priorities for generic names. + + + + To interact with the kernel crypto API, a socket must be + created by the user space application. User space invokes the cipher + operation with the send()/write() system call family. The result of the + cipher operation is obtained with the read()/recv() system call family. + + + + The following API calls assume that the socket descriptor + is already opened by the user space application and discusses only + the kernel crypto API specific invocations. + + + + To initialize the socket interface, the following sequence has to + be performed by the consumer: + + + + + + Create a socket of type AF_ALG with the struct sockaddr_alg + parameter specified below for the different cipher types. + + + + + + Invoke bind with the socket descriptor + + + + + + Invoke accept with the socket descriptor. The accept system call + returns a new file descriptor that is to be used to interact with + the particular cipher instance. When invoking send/write or recv/read + system calls to send data to the kernel or obtain data from the + kernel, the file descriptor returned by accept must be used. + + + + + + In-place Cipher operation + + Just like the in-kernel operation of the kernel crypto API, the user + space interface allows the cipher operation in-place. That means that + the input buffer used for the send/write system call and the output + buffer used by the read/recv system call may be one and the same. + This is of particular interest for symmetric cipher operations where a + copying of the output data to its final destination can be avoided. + + + + If a consumer on the other hand wants to maintain the plaintext and + the ciphertext in different memory locations, all a consumer needs + to do is to provide different memory pointers for the encryption and + decryption operation. + + + + Message Digest API + + The message digest type to be used for the cipher operation is + selected when invoking the bind syscall. bind requires the caller + to provide a filled struct sockaddr data structure. This data + structure must be filled as follows: + + + +struct sockaddr_alg sa = { + .salg_family = AF_ALG, + .salg_type = "hash", /* this selects the hash logic in the kernel */ + .salg_name = "sha1" /* this is the cipher name */ +}; + + + + The salg_type value "hash" applies to message digests and keyed + message digests. Though, a keyed message digest is referenced by + the appropriate salg_name. Please see below for the setsockopt + interface that explains how the key can be set for a keyed message + digest. + + + + Using the send() system call, the application provides the data that + should be processed with the message digest. The send system call + allows the following flags to be specified: + + + + + + MSG_MORE: If this flag is set, the send system call acts like a + message digest update function where the final hash is not + yet calculated. If the flag is not set, the send system call + calculates the final message digest immediately. + + + + + + With the recv() system call, the application can read the message + digest from the kernel crypto API. If the buffer is too small for the + message digest, the flag MSG_TRUNC is set by the kernel. + + + + In order to set a message digest key, the calling application must use + the setsockopt() option of ALG_SET_KEY. If the key is not set the HMAC + operation is performed without the initial HMAC state change caused by + the key. + + + + Symmetric Cipher API + + The operation is very similar to the message digest discussion. + During initialization, the struct sockaddr data structure must be + filled as follows: + + + +struct sockaddr_alg sa = { + .salg_family = AF_ALG, + .salg_type = "skcipher", /* this selects the symmetric cipher */ + .salg_name = "cbc(aes)" /* this is the cipher name */ +}; + + + + Before data can be sent to the kernel using the write/send system + call family, the consumer must set the key. The key setting is + described with the setsockopt invocation below. + + + + Using the sendmsg() system call, the application provides the data that should be processed for encryption or decryption. In addition, the IV is + specified with the data structure provided by the sendmsg() system call. + + + + The sendmsg system call parameter of struct msghdr is embedded into the + struct cmsghdr data structure. See recv(2) and cmsg(3) for more + information on how the cmsghdr data structure is used together with the + send/recv system call family. That cmsghdr data structure holds the + following information specified with a separate header instances: + + + + + + specification of the cipher operation type with one of these flags: + + + + ALG_OP_ENCRYPT - encryption of data + + + ALG_OP_DECRYPT - decryption of data + + + + + + + specification of the IV information marked with the flag ALG_SET_IV + + + + + + The send system call family allows the following flag to be specified: + + + + + + MSG_MORE: If this flag is set, the send system call acts like a + cipher update function where more input data is expected + with a subsequent invocation of the send system call. + + + + + + Note: The kernel reports -EINVAL for any unexpected data. The caller + must make sure that all data matches the constraints given in + /proc/crypto for the selected cipher. + + + + With the recv() system call, the application can read the result of + the cipher operation from the kernel crypto API. The output buffer + must be at least as large as to hold all blocks of the encrypted or + decrypted data. If the output data size is smaller, only as many + blocks are returned that fit into that output buffer size. + + + + AEAD Cipher API + + The operation is very similar to the symmetric cipher discussion. + During initialization, the struct sockaddr data structure must be + filled as follows: + + + +struct sockaddr_alg sa = { + .salg_family = AF_ALG, + .salg_type = "aead", /* this selects the symmetric cipher */ + .salg_name = "gcm(aes)" /* this is the cipher name */ +}; + + + + Before data can be sent to the kernel using the write/send system + call family, the consumer must set the key. The key setting is + described with the setsockopt invocation below. + + + + In addition, before data can be sent to the kernel using the + write/send system call family, the consumer must set the authentication + tag size. To set the authentication tag size, the caller must use the + setsockopt invocation described below. + + + + Using the sendmsg() system call, the application provides the data that should be processed for encryption or decryption. In addition, the IV is + specified with the data structure provided by the sendmsg() system call. + + + + The sendmsg system call parameter of struct msghdr is embedded into the + struct cmsghdr data structure. See recv(2) and cmsg(3) for more + information on how the cmsghdr data structure is used together with the + send/recv system call family. That cmsghdr data structure holds the + following information specified with a separate header instances: + + + + + + specification of the cipher operation type with one of these flags: + + + + ALG_OP_ENCRYPT - encryption of data + + + ALG_OP_DECRYPT - decryption of data + + + + + + + specification of the IV information marked with the flag ALG_SET_IV + + + + + + specification of the associated authentication data (AAD) with the + flag ALG_SET_AEAD_ASSOCLEN. The AAD is sent to the kernel together + with the plaintext / ciphertext. See below for the memory structure. + + + + + + The send system call family allows the following flag to be specified: + + + + + + MSG_MORE: If this flag is set, the send system call acts like a + cipher update function where more input data is expected + with a subsequent invocation of the send system call. + + + + + + Note: The kernel reports -EINVAL for any unexpected data. The caller + must make sure that all data matches the constraints given in + /proc/crypto for the selected cipher. + + + + With the recv() system call, the application can read the result of + the cipher operation from the kernel crypto API. The output buffer + must be at least as large as defined with the memory structure below. + If the output data size is smaller, the cipher operation is not performed. + + + + The authenticated decryption operation may indicate an integrity error. + Such breach in integrity is marked with the -EBADMSG error code. + + + AEAD Memory Structure + + The AEAD cipher operates with the following information that + is communicated between user and kernel space as one data stream: + + + + + plaintext or ciphertext + + + + associated authentication data (AAD) + + + + authentication tag + + + + + The sizes of the AAD and the authentication tag are provided with + the sendmsg and setsockopt calls (see there). As the kernel knows + the size of the entire data stream, the kernel is now able to + calculate the right offsets of the data components in the data + stream. + + + + The user space caller must arrange the aforementioned information + in the following order: + + + + + + AEAD encryption input: AAD || plaintext + + + + + + AEAD decryption input: AAD || ciphertext || authentication tag + + + + + + The output buffer the user space caller provides must be at least as + large to hold the following data: + + + + + + AEAD encryption output: ciphertext || authentication tag + + + + + + AEAD decryption output: plaintext + + + + + + + Random Number Generator API + + Again, the operation is very similar to the other APIs. + During initialization, the struct sockaddr data structure must be + filled as follows: + + + +struct sockaddr_alg sa = { + .salg_family = AF_ALG, + .salg_type = "rng", /* this selects the symmetric cipher */ + .salg_name = "drbg_nopr_sha256" /* this is the cipher name */ +}; + + + + Depending on the RNG type, the RNG must be seeded. The seed is provided + using the setsockopt interface to set the key. For example, the + ansi_cprng requires a seed. The DRBGs do not require a seed, but + may be seeded. + + + + Using the read()/recvmsg() system calls, random numbers can be obtained. + The kernel generates at most 128 bytes in one call. If user space + requires more data, multiple calls to read()/recvmsg() must be made. + + + + WARNING: The user space caller may invoke the initially mentioned + accept system call multiple times. In this case, the returned file + descriptors have the same state. + + + + + Zero-Copy Interface + + In addition to the send/write/read/recv system call familty, the AF_ALG + interface can be accessed with the zero-copy interface of splice/vmsplice. + As the name indicates, the kernel tries to avoid a copy operation into + kernel space. + + + + The zero-copy operation requires data to be aligned at the page boundary. + Non-aligned data can be used as well, but may require more operations of + the kernel which would defeat the speed gains obtained from the zero-copy + interface. + + + + The system-interent limit for the size of one zero-copy operation is + 16 pages. If more data is to be sent to AF_ALG, user space must slice + the input into segments with a maximum size of 16 pages. + + + + Zero-copy can be used with the following code example (a complete working + example is provided with libkcapi): + + + +int pipes[2]; + +pipe(pipes); +/* input data in iov */ +vmsplice(pipes[1], iov, iovlen, SPLICE_F_GIFT); +/* opfd is the file descriptor returned from accept() system call */ +splice(pipes[0], NULL, opfd, NULL, ret, 0); +read(opfd, out, outlen); + + + + + Setsockopt Interface + + In addition to the read/recv and send/write system call handling + to send and retrieve data subject to the cipher operation, a consumer + also needs to set the additional information for the cipher operation. + This additional information is set using the setsockopt system call + that must be invoked with the file descriptor of the open cipher + (i.e. the file descriptor returned by the accept system call). + + + + Each setsockopt invocation must use the level SOL_ALG. + + + + The setsockopt interface allows setting the following data using + the mentioned optname: + + + + + + ALG_SET_KEY -- Setting the key. Key setting is applicable to: + + + + the skcipher cipher type (symmetric ciphers) + + + the hash cipher type (keyed message digests) + + + the AEAD cipher type + + + the RNG cipher type to provide the seed + + + + + + + ALG_SET_AEAD_AUTHSIZE -- Setting the authentication tag size + for AEAD ciphers. For a encryption operation, the authentication + tag of the given size will be generated. For a decryption operation, + the provided ciphertext is assumed to contain an authentication tag + of the given size (see section about AEAD memory layout below). + + + + + + + User space API example + + Please see [1] for libkcapi which provides an easy-to-use wrapper + around the aforementioned Netlink kernel interface. [1] also contains + a test application that invokes all libkcapi API calls. + + + + [1] http://www.chronox.de/libkcapi.html + + + + + + Programming Interface Block Cipher Context Data Structures !Pinclude/linux/crypto.h Block Cipher Context Data Structures diff --git a/Documentation/crypto/crypto-API-userspace.txt b/Documentation/crypto/crypto-API-userspace.txt deleted file mode 100644 index ac619cd90300..000000000000 --- a/Documentation/crypto/crypto-API-userspace.txt +++ /dev/null @@ -1,205 +0,0 @@ -Introduction -============ - -The concepts of the kernel crypto API visible to kernel space is fully -applicable to the user space interface as well. Therefore, the kernel crypto API -high level discussion for the in-kernel use cases applies here as well. - -The major difference, however, is that user space can only act as a consumer -and never as a provider of a transformation or cipher algorithm. - -The following covers the user space interface exported by the kernel crypto -API. A working example of this description is libkcapi that can be obtained from -[1]. That library can be used by user space applications that require -cryptographic services from the kernel. - -Some details of the in-kernel kernel crypto API aspects do not -apply to user space, however. This includes the difference between synchronous -and asynchronous invocations. The user space API call is fully synchronous. -In addition, only a subset of all cipher types are available as documented -below. - - -User space API general remarks -============================== - -The kernel crypto API is accessible from user space. Currently, the following -ciphers are accessible: - - * Message digest including keyed message digest (HMAC, CMAC) - - * Symmetric ciphers - -Note, AEAD ciphers are currently not supported via the symmetric cipher -interface. - -The interface is provided via Netlink using the type AF_ALG. In addition, the -setsockopt option type is SOL_ALG. In case the user space header files do not -export these flags yet, use the following macros: - -#ifndef AF_ALG -#define AF_ALG 38 -#endif -#ifndef SOL_ALG -#define SOL_ALG 279 -#endif - -A cipher is accessed with the same name as done for the in-kernel API calls. -This includes the generic vs. unique naming schema for ciphers as well as the -enforcement of priorities for generic names. - -To interact with the kernel crypto API, a Netlink socket must be created by -the user space application. User space invokes the cipher operation with the -send/write system call family. The result of the cipher operation is obtained -with the read/recv system call family. - -The following API calls assume that the Netlink socket descriptor is already -opened by the user space application and discusses only the kernel crypto API -specific invocations. - -To initialize a Netlink interface, the following sequence has to be performed -by the consumer: - - 1. Create a socket of type AF_ALG with the struct sockaddr_alg parameter - specified below for the different cipher types. - - 2. Invoke bind with the socket descriptor - - 3. Invoke accept with the socket descriptor. The accept system call - returns a new file descriptor that is to be used to interact with - the particular cipher instance. When invoking send/write or recv/read - system calls to send data to the kernel or obtain data from the - kernel, the file descriptor returned by accept must be used. - -In-place cipher operation -========================= - -Just like the in-kernel operation of the kernel crypto API, the user space -interface allows the cipher operation in-place. That means that the input buffer -used for the send/write system call and the output buffer used by the read/recv -system call may be one and the same. This is of particular interest for -symmetric cipher operations where a copying of the output data to its final -destination can be avoided. - -If a consumer on the other hand wants to maintain the plaintext and the -ciphertext in different memory locations, all a consumer needs to do is to -provide different memory pointers for the encryption and decryption operation. - -Message digest API -================== - -The message digest type to be used for the cipher operation is selected when -invoking the bind syscall. bind requires the caller to provide a filled -struct sockaddr data structure. This data structure must be filled as follows: - -struct sockaddr_alg sa = { - .salg_family = AF_ALG, - .salg_type = "hash", /* this selects the hash logic in the kernel */ - .salg_name = "sha1" /* this is the cipher name */ -}; - -The salg_type value "hash" applies to message digests and keyed message digests. -Though, a keyed message digest is referenced by the appropriate salg_name. -Please see below for the setsockopt interface that explains how the key can be -set for a keyed message digest. - -Using the send() system call, the application provides the data that should be -processed with the message digest. The send system call allows the following -flags to be specified: - - * MSG_MORE: If this flag is set, the send system call acts like a - message digest update function where the final hash is not - yet calculated. If the flag is not set, the send system call - calculates the final message digest immediately. - -With the recv() system call, the application can read the message digest from -the kernel crypto API. If the buffer is too small for the message digest, the -flag MSG_TRUNC is set by the kernel. - -In order to set a message digest key, the calling application must use the -setsockopt() option of ALG_SET_KEY. If the key is not set the HMAC operation is -performed without the initial HMAC state change caused by the key. - - -Symmetric cipher API -==================== - -The operation is very similar to the message digest discussion. During -initialization, the struct sockaddr data structure must be filled as follows: - -struct sockaddr_alg sa = { - .salg_family = AF_ALG, - .salg_type = "skcipher", /* this selects the symmetric cipher */ - .salg_name = "cbc(aes)" /* this is the cipher name */ -}; - -Before data can be sent to the kernel using the write/send system call family, -the consumer must set the key. The key setting is described with the setsockopt -invocation below. - -Using the sendmsg() system call, the application provides the data that should -be processed for encryption or decryption. In addition, the IV is specified -with the data structure provided by the sendmsg() system call. - -The sendmsg system call parameter of struct msghdr is embedded into the -struct cmsghdr data structure. See recv(2) and cmsg(3) for more information -on how the cmsghdr data structure is used together with the send/recv system -call family. That cmsghdr data structure holds the following information -specified with a separate header instances: - - * specification of the cipher operation type with one of these flags: - ALG_OP_ENCRYPT - encryption of data - ALG_OP_DECRYPT - decryption of data - - * specification of the IV information marked with the flag ALG_SET_IV - -The send system call family allows the following flag to be specified: - - * MSG_MORE: If this flag is set, the send system call acts like a - cipher update function where more input data is expected - with a subsequent invocation of the send system call. - -Note: The kernel reports -EINVAL for any unexpected data. The caller must -make sure that all data matches the constraints given in /proc/crypto for the -selected cipher. - -With the recv() system call, the application can read the result of the -cipher operation from the kernel crypto API. The output buffer must be at least -as large as to hold all blocks of the encrypted or decrypted data. If the output -data size is smaller, only as many blocks are returned that fit into that -output buffer size. - -Setsockopt interface -==================== - -In addition to the read/recv and send/write system call handling to send and -retrieve data subject to the cipher operation, a consumer also needs to set -the additional information for the cipher operation. This additional information -is set using the setsockopt system call that must be invoked with the file -descriptor of the open cipher (i.e. the file descriptor returned by the -accept system call). - -Each setsockopt invocation must use the level SOL_ALG. - -The setsockopt interface allows setting the following data using the mentioned -optname: - - * ALG_SET_KEY -- Setting the key. Key setting is applicable to: - - - the skcipher cipher type (symmetric ciphers) - - - the hash cipher type (keyed message digests) - -User space API example -====================== - -Please see [1] for libkcapi which provides an easy-to-use wrapper around the -aforementioned Netlink kernel interface. [1] also contains a test application -that invokes all libkcapi API calls. - -[1] http://www.chronox.de/libkcapi.html - -Author -====== - -Stephan Mueller -- GitLab From 2ca87a17045194638c69be87e2430842f743b00b Mon Sep 17 00:00:00 2001 From: Stephan Mueller Date: Fri, 6 Mar 2015 21:36:21 +0100 Subject: [PATCH 03463/11651] MAINTAINERS: add crypto-API.tmpl The file Documentation/DocBook/crypto-API.tmpl documents the kernel crypto API and is maintained. Signed-off-by: Stephan Mueller Signed-off-by: Herbert Xu --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index ddc5a8cf9a8a..c10814e53858 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2805,6 +2805,7 @@ L: linux-crypto@vger.kernel.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6.git S: Maintained F: Documentation/crypto/ +F: Documentation/DocBook/crypto-API.tmpl F: arch/*/crypto/ F: crypto/ F: drivers/crypto/ -- GitLab From a508412b169d5398dc5f800147097b255c2941be Mon Sep 17 00:00:00 2001 From: Feng Kan Date: Fri, 6 Mar 2015 14:53:15 -0800 Subject: [PATCH 03464/11651] hwrng: xgene - add ACPI support for APM X-Gene RNG unit This adds ACPI support for APM X-Gene RNG unit. Signed-off-by: Feng Kan Signed-off-by: Herbert Xu --- drivers/char/hw_random/xgene-rng.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/char/hw_random/xgene-rng.c b/drivers/char/hw_random/xgene-rng.c index 23caa05380a8..c37cf754a985 100644 --- a/drivers/char/hw_random/xgene-rng.c +++ b/drivers/char/hw_random/xgene-rng.c @@ -21,6 +21,7 @@ * */ +#include #include #include #include @@ -310,6 +311,14 @@ static int xgene_rng_init(struct hwrng *rng) return 0; } +#ifdef CONFIG_ACPI +static const struct acpi_device_id xgene_rng_acpi_match[] = { + { "APMC0D18", }, + { } +}; +MODULE_DEVICE_TABLE(acpi, xgene_rng_acpi_match); +#endif + static struct hwrng xgene_rng_func = { .name = "xgene-rng", .init = xgene_rng_init, @@ -415,6 +424,7 @@ static struct platform_driver xgene_rng_driver = { .driver = { .name = "xgene-rng", .of_match_table = xgene_rng_of_match, + .acpi_match_table = ACPI_PTR(xgene_rng_acpi_match), }, }; -- GitLab From 3265c4babe93832167cb148083a0544548c23e6a Mon Sep 17 00:00:00 2001 From: Kim Phillips Date: Fri, 6 Mar 2015 18:46:21 -0600 Subject: [PATCH 03465/11651] crypto: powerpc - move files to fix build error The current cryptodev-2.6 tree commits: d9850fc529ef ("crypto: powerpc/sha1 - kernel config") 50ba29aaa7b0 ("crypto: powerpc/sha1 - glue") failed to properly place files under arch/powerpc/crypto, which leads to build errors: make[1]: *** No rule to make target 'arch/powerpc/crypto/sha1-spe-asm.o', needed by 'arch/powerpc/crypto/sha1-ppc-spe.o'. Stop. make[1]: *** No rule to make target 'arch/powerpc/crypto/sha1_spe_glue.o', needed by 'arch/powerpc/crypto/sha1-ppc-spe.o'. Stop. Makefile:947: recipe for target 'arch/powerpc/crypto' failed Move the two sha1 spe files under crypto/, and whilst there, rename other powerpc crypto files with underscores to use dashes for consistency. Cc: Markus Stockhausen Signed-off-by: Kim Phillips Signed-off-by: Herbert Xu --- arch/powerpc/crypto/Makefile | 8 ++++---- arch/powerpc/crypto/{aes_spe_glue.c => aes-spe-glue.c} | 0 arch/powerpc/crypto/{md5_glue.c => md5-glue.c} | 0 arch/powerpc/{ => crypto}/sha1-spe-asm.S | 0 arch/powerpc/{sha1_spe_glue.c => crypto/sha1-spe-glue.c} | 0 .../crypto/{sha256_spe_glue.c => sha256-spe-glue.c} | 0 6 files changed, 4 insertions(+), 4 deletions(-) rename arch/powerpc/crypto/{aes_spe_glue.c => aes-spe-glue.c} (100%) rename arch/powerpc/crypto/{md5_glue.c => md5-glue.c} (100%) rename arch/powerpc/{ => crypto}/sha1-spe-asm.S (100%) rename arch/powerpc/{sha1_spe_glue.c => crypto/sha1-spe-glue.c} (100%) rename arch/powerpc/crypto/{sha256_spe_glue.c => sha256-spe-glue.c} (100%) diff --git a/arch/powerpc/crypto/Makefile b/arch/powerpc/crypto/Makefile index c6b25cba3a0c..9c221b69c181 100644 --- a/arch/powerpc/crypto/Makefile +++ b/arch/powerpc/crypto/Makefile @@ -10,8 +10,8 @@ obj-$(CONFIG_CRYPTO_SHA1_PPC) += sha1-powerpc.o obj-$(CONFIG_CRYPTO_SHA1_PPC_SPE) += sha1-ppc-spe.o obj-$(CONFIG_CRYPTO_SHA256_PPC_SPE) += sha256-ppc-spe.o -aes-ppc-spe-y := aes-spe-core.o aes-spe-keys.o aes-tab-4k.o aes-spe-modes.o aes_spe_glue.o -md5-ppc-y := md5-asm.o md5_glue.o +aes-ppc-spe-y := aes-spe-core.o aes-spe-keys.o aes-tab-4k.o aes-spe-modes.o aes-spe-glue.o +md5-ppc-y := md5-asm.o md5-glue.o sha1-powerpc-y := sha1-powerpc-asm.o sha1.o -sha1-ppc-spe-y := sha1-spe-asm.o sha1_spe_glue.o -sha256-ppc-spe-y := sha256-spe-asm.o sha256_spe_glue.o +sha1-ppc-spe-y := sha1-spe-asm.o sha1-spe-glue.o +sha256-ppc-spe-y := sha256-spe-asm.o sha256-spe-glue.o diff --git a/arch/powerpc/crypto/aes_spe_glue.c b/arch/powerpc/crypto/aes-spe-glue.c similarity index 100% rename from arch/powerpc/crypto/aes_spe_glue.c rename to arch/powerpc/crypto/aes-spe-glue.c diff --git a/arch/powerpc/crypto/md5_glue.c b/arch/powerpc/crypto/md5-glue.c similarity index 100% rename from arch/powerpc/crypto/md5_glue.c rename to arch/powerpc/crypto/md5-glue.c diff --git a/arch/powerpc/sha1-spe-asm.S b/arch/powerpc/crypto/sha1-spe-asm.S similarity index 100% rename from arch/powerpc/sha1-spe-asm.S rename to arch/powerpc/crypto/sha1-spe-asm.S diff --git a/arch/powerpc/sha1_spe_glue.c b/arch/powerpc/crypto/sha1-spe-glue.c similarity index 100% rename from arch/powerpc/sha1_spe_glue.c rename to arch/powerpc/crypto/sha1-spe-glue.c diff --git a/arch/powerpc/crypto/sha256_spe_glue.c b/arch/powerpc/crypto/sha256-spe-glue.c similarity index 100% rename from arch/powerpc/crypto/sha256_spe_glue.c rename to arch/powerpc/crypto/sha256-spe-glue.c -- GitLab From 163fe301b9f78b6de57d0014eafe504fd20c0cd4 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sat, 7 Mar 2015 16:36:37 +0000 Subject: [PATCH 03466/11651] staging: vt6656: vnt_rf_setpower: fix missing rate RATE_12M When the driver sets this rate a power of zero value is set causing data flow stoppage until another rate is tried. Signed-off-by: Malcolm Priestley Cc: # v3.17+ Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/rf.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/vt6656/rf.c b/drivers/staging/vt6656/rf.c index c42cde59f598..c4286ccac320 100644 --- a/drivers/staging/vt6656/rf.c +++ b/drivers/staging/vt6656/rf.c @@ -640,6 +640,7 @@ int vnt_rf_setpower(struct vnt_private *priv, u32 rate, u32 channel) break; case RATE_6M: case RATE_9M: + case RATE_12M: case RATE_18M: case RATE_24M: case RATE_36M: -- GitLab From 40c8790bcb7ac74f3038153cd09310e220c6a1df Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sat, 7 Mar 2015 17:04:54 +0000 Subject: [PATCH 03467/11651] vt6655: RFbSetPower fix missing rate RATE_12M When the driver sets this rate a power of zero value is set causing data flow stoppage until another rate is tried. Signed-off-by: Malcolm Priestley Cc: Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/rf.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/vt6655/rf.c b/drivers/staging/vt6655/rf.c index 941b2adca95a..7626f635f160 100644 --- a/drivers/staging/vt6655/rf.c +++ b/drivers/staging/vt6655/rf.c @@ -794,6 +794,7 @@ bool RFbSetPower( break; case RATE_6M: case RATE_9M: + case RATE_12M: case RATE_18M: byPwr = priv->abyOFDMPwrTbl[uCH]; if (priv->byRFType == RF_UW2452) -- GitLab From 1f51d5801859e0b382dcc8f06875811d63ec8953 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sat, 7 Mar 2015 17:04:55 +0000 Subject: [PATCH 03468/11651] vt6655: Fix late setting of byRFType. byRFType is not set prior to registration of mac80211 causing unpredictable operation after channel scans. With byRFType unset all channels are enabled this causes tx power to be set to values not present its eeprom. Move setting of this variable to vt6655_probe. byRFType must have a mask set. byRevId not used by driver and is removed. Signed-off-by: Malcolm Priestley Cc: # v3.19+ Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device_main.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index f5c5872b587e..03b2a90b9ac0 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -330,16 +330,6 @@ static void device_init_registers(struct vnt_private *pDevice) /* zonetype initial */ pDevice->byOriginalZonetype = pDevice->abyEEPROM[EEP_OFS_ZONETYPE]; - /* Get RFType */ - pDevice->byRFType = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_RFTYPE); - - /* force change RevID for VT3253 emu */ - if ((pDevice->byRFType & RF_EMU) != 0) - pDevice->byRevId = 0x80; - - pDevice->byRFType &= RF_MASK; - pr_debug("pDevice->byRFType = %x\n", pDevice->byRFType); - if (!pDevice->bZoneRegExist) pDevice->byZoneType = pDevice->abyEEPROM[EEP_OFS_ZONETYPE]; @@ -1780,6 +1770,12 @@ vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent) MACvInitialize(priv->PortOffset); MACvReadEtherAddress(priv->PortOffset, priv->abyCurrentNetAddr); + /* Get RFType */ + priv->byRFType = SROMbyReadEmbedded(priv->PortOffset, EEP_OFS_RFTYPE); + priv->byRFType &= RF_MASK; + + dev_dbg(&pcid->dev, "RF Type = %x\n", priv->byRFType); + device_get_options(priv); device_set_options(priv); /* Mask out the options cannot be set to the chip */ -- GitLab From b90f8f22ed86f4f1a38dd2178c4be558c0c70fb9 Mon Sep 17 00:00:00 2001 From: Kefeng Wang Date: Mon, 2 Mar 2015 15:23:54 +0800 Subject: [PATCH 03469/11651] gpio: dwapb: re-enable GPIO_DWAPB for arm64 Hisilicon arm64 soc uses designWare gpio, re-enable it after commit 1972c97db5b(gpio: dwapb: fix compile errors). Signed-off-by: Kefeng Wang Signed-off-by: Linus Walleij --- drivers/gpio/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index e07b63d37b7b..f563c883b887 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -148,7 +148,7 @@ config GPIO_GENERIC_PLATFORM config GPIO_DWAPB tristate "Synopsys DesignWare APB GPIO driver" - depends on ARM + depends on ARM || ARM64 depends on OF_GPIO select GPIO_GENERIC select GENERIC_IRQ_CHIP -- GitLab From d24fc643b5cfb4fdb0d1bd569e1a2e128c0bf311 Mon Sep 17 00:00:00 2001 From: Angelo Compagnucci Date: Sun, 8 Mar 2015 14:36:58 +0100 Subject: [PATCH 03470/11651] iio: ti-adc128s052: Add DT binding documentation Adding binding documentation for Texas Instruments' ADC128S052 ADC chip. Signed-off-by: Angelo Compagnucci Signed-off-by: Jonathan Cameron --- .../bindings/iio/adc/ti-adc128s052.txt | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/adc/ti-adc128s052.txt diff --git a/Documentation/devicetree/bindings/iio/adc/ti-adc128s052.txt b/Documentation/devicetree/bindings/iio/adc/ti-adc128s052.txt new file mode 100644 index 000000000000..42ca7deec97d --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/ti-adc128s052.txt @@ -0,0 +1,18 @@ +* Texas Instruments' ADC128S052 ADC chip + +Required properties: + - compatible: Should be "ti,adc128s052" + - reg: spi chip select number for the device + - vref-supply: The regulator supply for ADC reference voltage + +Recommended properties: + - spi-max-frequency: Definition as per + Documentation/devicetree/bindings/spi/spi-bus.txt + +Example: +adc@0 { + compatible = "ti,adc128s052"; + reg = <0>; + vref-supply = <&vdd_supply>; + spi-max-frequency = <1000000>; +}; -- GitLab From 4a428bf3d92385f27cbb15bef90754027ba4f2d9 Mon Sep 17 00:00:00 2001 From: Angelo Compagnucci Date: Sun, 8 Mar 2015 14:37:23 +0100 Subject: [PATCH 03471/11651] iio: mcp3422: Add DT binding documentation Adding binding documentation for ADC MCP3422. Signed-off-by: Angelo Compagnucci Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/adc/mcp3422.txt | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/adc/mcp3422.txt diff --git a/Documentation/devicetree/bindings/iio/adc/mcp3422.txt b/Documentation/devicetree/bindings/iio/adc/mcp3422.txt new file mode 100644 index 000000000000..333139cc0bfb --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/mcp3422.txt @@ -0,0 +1,17 @@ +* Microchip mcp3422/3/4/6/7/8 chip family (ADC) + +Required properties: + - compatible: Should be + "microchip,mcp3422" or + "microchip,mcp3423" or + "microchip,mcp3424" or + "microchip,mcp3426" or + "microchip,mcp3427" or + "microchip,mcp3428" + - reg: I2C address for the device + +Example: +adc@0 { + compatible = "microchip,mcp3424"; + reg = <0x68>; +}; -- GitLab From 700d98551ff16a59e164bf884aefbdc5d798ff75 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Thu, 29 Jan 2015 17:54:46 +1100 Subject: [PATCH 03472/11651] ncr5380: Drop owner assignment from platform_drivers This platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang Signed-off-by: Finn Thain Signed-off-by: James Bottomley --- drivers/scsi/atari_scsi.c | 1 - drivers/scsi/mac_scsi.c | 1 - drivers/scsi/sun3_scsi.c | 1 - 3 files changed, 3 deletions(-) diff --git a/drivers/scsi/atari_scsi.c b/drivers/scsi/atari_scsi.c index d1c37a386947..5ede3daa93dc 100644 --- a/drivers/scsi/atari_scsi.c +++ b/drivers/scsi/atari_scsi.c @@ -1014,7 +1014,6 @@ static struct platform_driver atari_scsi_driver = { .remove = __exit_p(atari_scsi_remove), .driver = { .name = DRV_MODULE_NAME, - .owner = THIS_MODULE, }, }; diff --git a/drivers/scsi/mac_scsi.c b/drivers/scsi/mac_scsi.c index 1e85c07e3b62..d64a769b8155 100644 --- a/drivers/scsi/mac_scsi.c +++ b/drivers/scsi/mac_scsi.c @@ -483,7 +483,6 @@ static struct platform_driver mac_scsi_driver = { .remove = __exit_p(mac_scsi_remove), .driver = { .name = DRV_MODULE_NAME, - .owner = THIS_MODULE, }, }; diff --git a/drivers/scsi/sun3_scsi.c b/drivers/scsi/sun3_scsi.c index 2a906d1d34ba..22a42836d193 100644 --- a/drivers/scsi/sun3_scsi.c +++ b/drivers/scsi/sun3_scsi.c @@ -676,7 +676,6 @@ static struct platform_driver sun3_scsi_driver = { .remove = __exit_p(sun3_scsi_remove), .driver = { .name = DRV_MODULE_NAME, - .owner = THIS_MODULE, }, }; -- GitLab From 05d6a0884729f808b881e88affe1700fe45aab56 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Wed, 3 Dec 2014 12:32:03 +0100 Subject: [PATCH 03473/11651] ARM: at91/dt: at91sam9261: fix clocks and clock-names in udc definition Peripheral clock is named pclk and system clock is named hclk (those are the names expected by the at91_udc driver). Drop the deprecated usb_clk (formerly used to configure the usb clock rate which is now directly configurable through hclk). Signed-off-by: Boris Brezillon Signed-off-by: Nicolas Ferre --- arch/arm/boot/dts/at91sam9261.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/at91sam9261.dtsi b/arch/arm/boot/dts/at91sam9261.dtsi index e247b0b5fdab..115b332b456b 100644 --- a/arch/arm/boot/dts/at91sam9261.dtsi +++ b/arch/arm/boot/dts/at91sam9261.dtsi @@ -127,8 +127,8 @@ compatible = "atmel,at91rm9200-udc"; reg = <0xfffa4000 0x4000>; interrupts = <10 IRQ_TYPE_LEVEL_HIGH 2>; - clocks = <&usb>, <&udc_clk>, <&udpck>; - clock-names = "usb_clk", "udc_clk", "udpck"; + clocks = <&udc_clk>, <&udpck>; + clock-names = "pclk", "hclk"; status = "disabled"; }; -- GitLab From b026e8ed55e05a81018ba4ce73ca0cf2c9300950 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sat, 3 Jan 2015 23:00:16 +0100 Subject: [PATCH 03474/11651] g_NCR5380: Kill compiler warning if builtin If CONFIG_SCSI_GENERIC_NCR5380=y: drivers/scsi/g_NCR5380.c:727: warning: 'id_table' defined but not used In the non-modular case, MODULE_DEVICE_TABLE() expands to nothing, and id_table is not referenced. Correct the existing #ifdef to fix this. Signed-off-by: Geert Uytterhoeven Signed-off-by: Finn Thain Signed-off-by: James Bottomley --- drivers/scsi/g_NCR5380.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c index f35792f7051c..74ec2f5669ab 100644 --- a/drivers/scsi/g_NCR5380.c +++ b/drivers/scsi/g_NCR5380.c @@ -723,7 +723,7 @@ module_param(ncr_53c400a, int, 0); module_param(dtc_3181e, int, 0); MODULE_LICENSE("GPL"); -#ifndef SCSI_G_NCR5380_MEM +#if !defined(SCSI_G_NCR5380_MEM) && defined(MODULE) static struct isapnp_device_id id_table[] = { { ISAPNP_ANY_ID, ISAPNP_ANY_ID, -- GitLab From 8582e267e9a29ccfd2151c5d74bc2b1440dfb827 Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Delgado Date: Wed, 11 Feb 2015 13:53:14 +0100 Subject: [PATCH 03475/11651] asm/dma-mapping-common: Clarify output of dma_map_sg_attrs Although dma_map_sg_attrs returns 0 on error and it cannot return a value < 0, the function returns a signed integer. Most of the time, this function is used with a scatterlist structure. This structure uses an unsigned integer for the number of memory. A dma developer that has not read in detail DMA-API.txt, can wrongly return a value < 0 on error. The comment will help the driver developer, and the WARN_ON the dma developer. Signed-off-by: Ricardo Ribalda Delgado Signed-off-by: Marek Szyprowski --- include/asm-generic/dma-mapping-common.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/asm-generic/dma-mapping-common.h b/include/asm-generic/dma-mapping-common.h index 3378dcf4c31e..940d5ec122c9 100644 --- a/include/asm-generic/dma-mapping-common.h +++ b/include/asm-generic/dma-mapping-common.h @@ -39,6 +39,10 @@ static inline void dma_unmap_single_attrs(struct device *dev, dma_addr_t addr, debug_dma_unmap_page(dev, addr, size, dir, true); } +/* + * dma_maps_sg_attrs returns 0 on error and > 0 on success. + * It should never return a value < 0. + */ static inline int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction dir, struct dma_attrs *attrs) @@ -51,6 +55,7 @@ static inline int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg, kmemcheck_mark_initialized(sg_virt(s), s->length); BUG_ON(!valid_dma_direction(dir)); ents = ops->map_sg(dev, sg, nents, dir, attrs); + BUG_ON(ents < 0); debug_dma_map_sg(dev, sg, nents, ents, dir); return ents; -- GitLab From 04abab698285297115e5096b3100df1064045529 Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Delgado Date: Wed, 11 Feb 2015 13:53:15 +0100 Subject: [PATCH 03476/11651] include/dma-mapping: Clarify output of dma_map_sg Although dma_map_sg returns 0 on error and it cannot return a value < 0, the function returns a signed integer. Most of the time, this function is used with a scatterlist structure. This structure uses an unsigned integer for the number of memory. A dma developer that has not read in detail DMA-API.txt, can wrongly return a value < 0 on error. Signed-off-by: Ricardo Ribalda Delgado Signed-off-by: Marek Szyprowski --- include/linux/dma-mapping.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index c3007cb4bfa6..ac07ff090919 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h @@ -34,6 +34,10 @@ struct dma_map_ops { void (*unmap_page)(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction dir, struct dma_attrs *attrs); + /* + * map_sg returns 0 on error and a value > 0 on success. + * It should never return a value < 0. + */ int (*map_sg)(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction dir, struct dma_attrs *attrs); -- GitLab From b62a569e4ae2361bac6f601e75aa973d42d7c47d Mon Sep 17 00:00:00 2001 From: Somya Anand Date: Sat, 7 Mar 2015 23:20:01 +0530 Subject: [PATCH 03477/11651] Staging: iio: Change data type to u16 to avoid unnecessary typecast In the adis16220_read16bit() function we earlier used a s16 value 'val' which is used by the adis_read_reg_16 function to read data and takes a u16 value as a parameter. So, this patch changes the data type of 'val' from s16 to u16. It is safe to remove the extra sign extension, since the user of the function uses it to read a 10 unsigned value which will lead to the same result in both cases. Further this patch removes the unnecessary typecast for the simplification of code. In addition to this, initialization of 'val' to 0 is also dropped. This is due to the fact that not initializing helps the compiler provide useful warnings if the code gets changed to return an otherwise uninitialized result. Signed-off-by: Somya Anand Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/accel/adis16220_core.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/staging/iio/accel/adis16220_core.c b/drivers/staging/iio/accel/adis16220_core.c index d478f5130a0f..0396f24f4558 100644 --- a/drivers/staging/iio/accel/adis16220_core.c +++ b/drivers/staging/iio/accel/adis16220_core.c @@ -28,16 +28,15 @@ static ssize_t adis16220_read_16bit(struct device *dev, struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct adis16220_state *st = iio_priv(indio_dev); ssize_t ret; - s16 val = 0; + u16 val; /* Take the iio_dev status lock */ mutex_lock(&indio_dev->mlock); - ret = adis_read_reg_16(&st->adis, this_attr->address, - (u16 *)&val); + ret = adis_read_reg_16(&st->adis, this_attr->address, &val); mutex_unlock(&indio_dev->mlock); if (ret) return ret; - return sprintf(buf, "%d\n", val); + return sprintf(buf, "%u\n", val); } static ssize_t adis16220_write_16bit(struct device *dev, -- GitLab From acd3f6cf0579ef993bbfc50b84592fc8019f7887 Mon Sep 17 00:00:00 2001 From: Somya Anand Date: Sat, 7 Mar 2015 23:30:27 +0530 Subject: [PATCH 03478/11651] staging: rtl8188eu: Remove unneeded parentheses This patch removes unneeded parentheses from a if statement for better readability. This issue is identified by checkpatch.pl Signed-off-by: Somya Anand Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/core/rtw_wlan_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_wlan_util.c b/drivers/staging/rtl8188eu/core/rtw_wlan_util.c index 4f2f736598f2..509fc05ebea8 100644 --- a/drivers/staging/rtl8188eu/core/rtw_wlan_util.c +++ b/drivers/staging/rtl8188eu/core/rtw_wlan_util.c @@ -1297,7 +1297,7 @@ int support_short_GI(struct adapter *padapter, struct HT_caps_element *pHT_caps) if (!(pmlmeinfo->HT_enable)) return _FAIL; - if ((pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_RALINK)) + if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_RALINK) return _FAIL; bit_offset = (pmlmeext->cur_bwmode & HT_CHANNEL_WIDTH_40) ? 6 : 5; -- GitLab From d1da3ac0ee0d9a0a0589b309efcf9b1fabb43473 Mon Sep 17 00:00:00 2001 From: Greg Rose Date: Fri, 27 Feb 2015 09:18:29 +0000 Subject: [PATCH 03479/11651] i40e: Remove "hello world" strings from i40e driver While using the Linux "strings" command I found these two strings in the driver. There's no need for them and they're kinda silly. Change-ID: I4e19b02983d48b631e9a9979f49790492845f221 Signed-off-by: Greg Rose Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_debugfs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c index e802b6bc067d..305695596ae9 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c +++ b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c @@ -318,7 +318,7 @@ static const struct file_operations i40e_dbg_dump_fops = { * setup, adding or removing filters, or other things. Many of * these will be useful for some forms of unit testing. **************************************************************/ -static char i40e_dbg_command_buf[256] = "hello world"; +static char i40e_dbg_command_buf[256] = ""; /** * i40e_dbg_command_read - read for command datum @@ -1940,7 +1940,7 @@ static const struct file_operations i40e_dbg_command_fops = { * The netdev_ops entry in debugfs is for giving the driver commands * to be executed from the netdev operations. **************************************************************/ -static char i40e_dbg_netdev_ops_buf[256] = "hello world"; +static char i40e_dbg_netdev_ops_buf[256] = ""; /** * i40e_dbg_netdev_ops - read for netdev_ops datum -- GitLab From 1efc80eeee8c89188e78545c87a613e480aefd96 Mon Sep 17 00:00:00 2001 From: Shannon Nelson Date: Fri, 27 Feb 2015 09:18:30 +0000 Subject: [PATCH 03480/11651] i40e: future proof some sizeof calls Make sure the sizeof() calls are taking the size of the actual struct that we care about. By using the pointer variable, we'll always get the right struct size, even if the variable type changes sometime in the future. Change-ID: Id5858f883cf42447365ea3733080d7714f975bce Signed-off-by: Shannon Nelson Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_common.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c index fb78bdd2eb95..2ca3d0959a3c 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_common.c +++ b/drivers/net/ethernet/intel/i40e/i40e_common.c @@ -2017,7 +2017,7 @@ i40e_status i40e_aq_add_macvlan(struct i40e_hw *hw, u16 seid, if (count == 0 || !mv_list || !hw) return I40E_ERR_PARAM; - buf_size = count * sizeof(struct i40e_aqc_add_macvlan_element_data); + buf_size = count * sizeof(*mv_list); /* prep the rest of the request */ i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_add_macvlan); @@ -2059,7 +2059,7 @@ i40e_status i40e_aq_remove_macvlan(struct i40e_hw *hw, u16 seid, if (count == 0 || !mv_list || !hw) return I40E_ERR_PARAM; - buf_size = count * sizeof(struct i40e_aqc_remove_macvlan_element_data); + buf_size = count * sizeof(*mv_list); /* prep the rest of the request */ i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_remove_macvlan); -- GitLab From 3c8e0b989aa1afc01aa1b236b31b6c7628610c85 Mon Sep 17 00:00:00 2001 From: Mitch Williams Date: Fri, 27 Feb 2015 09:18:31 +0000 Subject: [PATCH 03481/11651] i40vf: don't stop me now If a reset occurs when the netdev is closed, the reset task will hang in napi_disable, causing deadlocks and general grumpiness. Check to make sure the device is actually running before stopping everything. This allows the reset task to complete and have a real good time. Change-ID: Iaaea84acbcb9b3810c216b14c3326e4287b75b58 Signed-off-by: Mitch Williams Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40evf/i40evf_main.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c b/drivers/net/ethernet/intel/i40evf/i40evf_main.c index f44911df286a..32d0a99ad2a9 100644 --- a/drivers/net/ethernet/intel/i40evf/i40evf_main.c +++ b/drivers/net/ethernet/intel/i40evf/i40evf_main.c @@ -1578,13 +1578,14 @@ continue_reset: adapter->flags &= ~I40EVF_FLAG_RESET_PENDING; i40evf_irq_disable(adapter); - i40evf_napi_disable_all(adapter); - - netif_tx_disable(netdev); - netif_tx_stop_all_queues(netdev); + if (netif_running(adapter->netdev)) { + i40evf_napi_disable_all(adapter); + netif_tx_disable(netdev); + netif_tx_stop_all_queues(netdev); + netif_carrier_off(netdev); + } - netif_carrier_off(netdev); adapter->state = __I40EVF_RESETTING; /* kill and reinit the admin queue */ -- GitLab From 97bf75f169d20c2aef1081fbe7bb5cc9656a4dc2 Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Fri, 27 Feb 2015 09:18:32 +0000 Subject: [PATCH 03482/11651] i40e/i40evf: fix accidental write to ITR registers Fix a bug introduced in the force writeback code, where the interrupt rate was set to 0 (maximum) by accident. The driver must correctly set the NOITR fields to avoid ITR update as a side effect of triggering the software interrupt. Change-ID: I290851ae04ef3811c43aab5ee33242029f26c1a3 Signed-off-by: Jesse Brandeburg Signed-off-by: Anjali Singhai Jain Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_txrx.c | 1 + drivers/net/ethernet/intel/i40evf/i40e_txrx.c | 1 + drivers/net/ethernet/intel/i40evf/i40evf_main.c | 3 +++ 3 files changed, 5 insertions(+) diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index f5a50b9366cb..6beab943e93a 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -859,6 +859,7 @@ static bool i40e_clean_tx_irq(struct i40e_ring *tx_ring, int budget) static void i40e_force_wb(struct i40e_vsi *vsi, struct i40e_q_vector *q_vector) { u32 val = I40E_PFINT_DYN_CTLN_INTENA_MASK | + I40E_PFINT_DYN_CTLN_ITR_INDX_MASK | /* set noitr */ I40E_PFINT_DYN_CTLN_SWINT_TRIG_MASK | I40E_PFINT_DYN_CTLN_SW_ITR_INDX_ENA_MASK; /* allow 00 to be written to the index */ diff --git a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c index d9f3db542c5f..f41da5d8047b 100644 --- a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c @@ -371,6 +371,7 @@ static bool i40e_clean_tx_irq(struct i40e_ring *tx_ring, int budget) static void i40e_force_wb(struct i40e_vsi *vsi, struct i40e_q_vector *q_vector) { u32 val = I40E_VFINT_DYN_CTLN_INTENA_MASK | + I40E_VFINT_DYN_CTLN1_ITR_INDX_MASK | /* set noitr */ I40E_VFINT_DYN_CTLN_SWINT_TRIG_MASK | I40E_VFINT_DYN_CTLN_SW_ITR_INDX_ENA_MASK; /* allow 00 to be written to the index */ diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c b/drivers/net/ethernet/intel/i40evf/i40evf_main.c index 32d0a99ad2a9..5ac777b99ede 100644 --- a/drivers/net/ethernet/intel/i40evf/i40evf_main.c +++ b/drivers/net/ethernet/intel/i40evf/i40evf_main.c @@ -244,6 +244,7 @@ void i40evf_irq_enable_queues(struct i40evf_adapter *adapter, u32 mask) if (mask & (1 << (i - 1))) { wr32(hw, I40E_VFINT_DYN_CTLN1(i - 1), I40E_VFINT_DYN_CTLN1_INTENA_MASK | + I40E_VFINT_DYN_CTLN1_ITR_INDX_MASK | I40E_VFINT_DYN_CTLN_CLEARPBA_MASK); } } @@ -263,6 +264,7 @@ static void i40evf_fire_sw_int(struct i40evf_adapter *adapter, u32 mask) if (mask & 1) { dyn_ctl = rd32(hw, I40E_VFINT_DYN_CTL01); dyn_ctl |= I40E_VFINT_DYN_CTLN_SWINT_TRIG_MASK | + I40E_VFINT_DYN_CTLN1_ITR_INDX_MASK | I40E_VFINT_DYN_CTLN_CLEARPBA_MASK; wr32(hw, I40E_VFINT_DYN_CTL01, dyn_ctl); } @@ -270,6 +272,7 @@ static void i40evf_fire_sw_int(struct i40evf_adapter *adapter, u32 mask) if (mask & (1 << i)) { dyn_ctl = rd32(hw, I40E_VFINT_DYN_CTLN1(i - 1)); dyn_ctl |= I40E_VFINT_DYN_CTLN_SWINT_TRIG_MASK | + I40E_VFINT_DYN_CTLN1_ITR_INDX_MASK | I40E_VFINT_DYN_CTLN_CLEARPBA_MASK; wr32(hw, I40E_VFINT_DYN_CTLN1(i - 1), dyn_ctl); } -- GitLab From 29a0645c7dfcd664f1e92ab8d7539bba600b7102 Mon Sep 17 00:00:00 2001 From: Shannon Nelson Date: Fri, 27 Feb 2015 09:18:33 +0000 Subject: [PATCH 03483/11651] i40e: tame the nvmupdate read and write complaints The NVMUpdate tool doesn't necessarily know the ReadOnly map of the current NVM image, and must try reading and writing words that may be protected. This generates an error out of the Firmware request that the driver logs. Unfortunately, this ends up spitting out hundreds of bogus read and write error message that looks rather messy. This patch checks the error type and under normal conditions will not print the typical read and write errors during NVMUpdate. This can be overridden by enabling the NVM update debugging. This results in a much less messy log file, and likely many fewer customer support questions. Change-ID: Id4ff2e9048c523b0ff503aa5ab181b025ec948ea Signed-off-by: Shannon Nelson Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c index 01c811c99ff7..9ff3dc15db25 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c @@ -917,7 +917,9 @@ static int i40e_get_eeprom(struct net_device *netdev, cmd = (struct i40e_nvm_access *)eeprom; ret_val = i40e_nvmupd_command(hw, cmd, bytes, &errno); - if (ret_val) + if (ret_val && + ((hw->aq.asq_last_status != I40E_AQ_RC_EACCES) || + (hw->debug_mask & I40E_DEBUG_NVM))) dev_info(&pf->pdev->dev, "NVMUpdate read failed err=%d status=0x%x errno=%d module=%d offset=0x%x size=%d\n", ret_val, hw->aq.asq_last_status, errno, @@ -1021,7 +1023,10 @@ static int i40e_set_eeprom(struct net_device *netdev, cmd = (struct i40e_nvm_access *)eeprom; ret_val = i40e_nvmupd_command(hw, cmd, bytes, &errno); - if (ret_val && hw->aq.asq_last_status != I40E_AQ_RC_EBUSY) + if (ret_val && + ((hw->aq.asq_last_status != I40E_AQ_RC_EPERM && + hw->aq.asq_last_status != I40E_AQ_RC_EBUSY) || + (hw->debug_mask & I40E_DEBUG_NVM))) dev_info(&pf->pdev->dev, "NVMUpdate write failed err=%d status=0x%x errno=%d module=%d offset=0x%x size=%d\n", ret_val, hw->aq.asq_last_status, errno, -- GitLab From b40c82e6ae85f110d1b53ba24b2ac657cb7bec8c Mon Sep 17 00:00:00 2001 From: Jeff Kirsher Date: Fri, 27 Feb 2015 09:18:34 +0000 Subject: [PATCH 03484/11651] i40e: Fix inconsistent use of PF/VF vs pf/vf Joe Perches pointed out that we were inconsistent in the use of PF vs pf or VF vs vf in our driver code. Since acronyms are usually capitalized to denote that it is an acronym, changed all references to be consistent throughout the code. Reported-by: Joe Perches Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e.h | 14 +- drivers/net/ethernet/intel/i40e/i40e_common.c | 6 +- drivers/net/ethernet/intel/i40e/i40e_dcb_nl.c | 4 +- .../net/ethernet/intel/i40e/i40e_debugfs.c | 20 +- drivers/net/ethernet/intel/i40e/i40e_fcoe.c | 10 +- drivers/net/ethernet/intel/i40e/i40e_main.c | 58 ++--- drivers/net/ethernet/intel/i40e/i40e_txrx.c | 2 +- .../ethernet/intel/i40e/i40e_virtchnl_pf.c | 222 +++++++++--------- .../ethernet/intel/i40e/i40e_virtchnl_pf.h | 12 +- 9 files changed, 174 insertions(+), 174 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h index 7ce8e600c13c..cc3f23685430 100644 --- a/drivers/net/ethernet/intel/i40e/i40e.h +++ b/drivers/net/ethernet/intel/i40e/i40e.h @@ -240,17 +240,17 @@ struct i40e_pf { bool fc_autoneg_status; u16 eeprom_version; - u16 num_vmdq_vsis; /* num vmdq vsis this pf has set up */ + u16 num_vmdq_vsis; /* num vmdq vsis this PF has set up */ u16 num_vmdq_qps; /* num queue pairs per vmdq pool */ u16 num_vmdq_msix; /* num queue vectors per vmdq pool */ - u16 num_req_vfs; /* num vfs requested for this vf */ - u16 num_vf_qps; /* num queue pairs per vf */ + u16 num_req_vfs; /* num VFs requested for this VF */ + u16 num_vf_qps; /* num queue pairs per VF */ #ifdef I40E_FCOE - u16 num_fcoe_qps; /* num fcoe queues this pf has set up */ + u16 num_fcoe_qps; /* num fcoe queues this PF has set up */ u16 num_fcoe_msix; /* num queue vectors per fcoe pool */ #endif /* I40E_FCOE */ - u16 num_lan_qps; /* num lan queues this pf has set up */ - u16 num_lan_msix; /* num queue vectors for the base pf vsi */ + u16 num_lan_qps; /* num lan queues this PF has set up */ + u16 num_lan_msix; /* num queue vectors for the base PF vsi */ int queues_left; /* queues left unclaimed */ u16 rss_size; /* num queues in the RSS array */ u16 rss_size_max; /* HW defined max RSS queues */ @@ -612,7 +612,7 @@ static inline bool i40e_rx_is_programming_status(u64 qw) /** * i40e_get_fd_cnt_all - get the total FD filter space available - * @pf: pointer to the pf struct + * @pf: pointer to the PF struct **/ static inline int i40e_get_fd_cnt_all(struct i40e_pf *pf) { diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c index 2ca3d0959a3c..d9f1fcb9c2be 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_common.c +++ b/drivers/net/ethernet/intel/i40e/i40e_common.c @@ -691,7 +691,7 @@ i40e_status i40e_get_port_mac_addr(struct i40e_hw *hw, u8 *mac_addr) /** * i40e_pre_tx_queue_cfg - pre tx queue configure * @hw: pointer to the HW structure - * @queue: target pf queue index + * @queue: target PF queue index * @enable: state change request * * Handles hw requirement to indicate intention to enable @@ -955,7 +955,7 @@ void i40e_clear_hw(struct i40e_hw *hw) u32 val; u32 eol = 0x7ff; - /* get number of interrupts, queues, and vfs */ + /* get number of interrupts, queues, and VFs */ val = rd32(hw, I40E_GLPCI_CNF2); num_pf_int = (val & I40E_GLPCI_CNF2_MSI_X_PF_N_MASK) >> I40E_GLPCI_CNF2_MSI_X_PF_N_SHIFT; @@ -2081,7 +2081,7 @@ i40e_status i40e_aq_remove_macvlan(struct i40e_hw *hw, u16 seid, /** * i40e_aq_send_msg_to_vf * @hw: pointer to the hardware structure - * @vfid: vf id to send msg + * @vfid: VF id to send msg * @v_opcode: opcodes for VF-PF communication * @v_retval: return error code * @msg: pointer to the msg buffer diff --git a/drivers/net/ethernet/intel/i40e/i40e_dcb_nl.c b/drivers/net/ethernet/intel/i40e/i40e_dcb_nl.c index 2f583554a260..400fb28db576 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_dcb_nl.c +++ b/drivers/net/ethernet/intel/i40e/i40e_dcb_nl.c @@ -223,7 +223,7 @@ static int i40e_dcbnl_vsi_del_app(struct i40e_vsi *vsi, /** * i40e_dcbnl_del_app - Delete APP on all VSIs - * @pf: the corresponding pf + * @pf: the corresponding PF * @app: APP to delete * * Delete given APP from all the VSIs for given PF @@ -268,7 +268,7 @@ static bool i40e_dcbnl_find_app(struct i40e_dcbx_config *cfg, /** * i40e_dcbnl_flush_apps - Delete all removed APPs - * @pf: the corresponding pf + * @pf: the corresponding PF * @old_cfg: old DCBX configuration data * @new_cfg: new DCBX configuration data * diff --git a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c index 305695596ae9..2cc73fea393b 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c +++ b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c @@ -35,7 +35,7 @@ static struct dentry *i40e_dbg_root; /** * i40e_dbg_find_vsi - searches for the vsi with the given seid - * @pf - the pf structure to search for the vsi + * @pf - the PF structure to search for the vsi * @seid - seid of the vsi it is searching for **/ static struct i40e_vsi *i40e_dbg_find_vsi(struct i40e_pf *pf, int seid) @@ -54,7 +54,7 @@ static struct i40e_vsi *i40e_dbg_find_vsi(struct i40e_pf *pf, int seid) /** * i40e_dbg_find_veb - searches for the veb with the given seid - * @pf - the pf structure to search for the veb + * @pf - the PF structure to search for the veb * @seid - seid of the veb it is searching for **/ static struct i40e_veb *i40e_dbg_find_veb(struct i40e_pf *pf, int seid) @@ -112,7 +112,7 @@ static ssize_t i40e_dbg_dump_read(struct file *filp, char __user *buffer, /** * i40e_dbg_prep_dump_buf - * @pf: the pf we're working with + * @pf: the PF we're working with * @buflen: the desired buffer length * * Return positive if success, 0 if failed @@ -675,7 +675,7 @@ static void i40e_dbg_dump_vsi_seid(struct i40e_pf *pf, int seid) vsi->info.resp_reserved[8], vsi->info.resp_reserved[9], vsi->info.resp_reserved[10], vsi->info.resp_reserved[11]); if (vsi->back) - dev_info(&pf->pdev->dev, " pf = %p\n", vsi->back); + dev_info(&pf->pdev->dev, " PF = %p\n", vsi->back); dev_info(&pf->pdev->dev, " idx = %d\n", vsi->idx); dev_info(&pf->pdev->dev, " tc_config: numtc = %d, enabled_tc = 0x%x\n", @@ -946,7 +946,7 @@ static void i40e_dbg_dump_veb_all(struct i40e_pf *pf) /** * i40e_dbg_cmd_fd_ctrl - Enable/disable FD sideband/ATR - * @pf: the pf that would be altered + * @pf: the PF that would be altered * @flag: flag that needs enabling or disabling * @enable: Enable/disable FD SD/ATR **/ @@ -958,7 +958,7 @@ static void i40e_dbg_cmd_fd_ctrl(struct i40e_pf *pf, u64 flag, bool enable) pf->flags &= ~flag; pf->auto_disable_flags |= flag; } - dev_info(&pf->pdev->dev, "requesting a pf reset\n"); + dev_info(&pf->pdev->dev, "requesting a PF reset\n"); i40e_do_reset_safe(pf, (1 << __I40E_PF_RESET_REQUESTED)); } @@ -2128,8 +2128,8 @@ static const struct file_operations i40e_dbg_netdev_ops_fops = { }; /** - * i40e_dbg_pf_init - setup the debugfs directory for the pf - * @pf: the pf that is starting up + * i40e_dbg_pf_init - setup the debugfs directory for the PF + * @pf: the PF that is starting up **/ void i40e_dbg_pf_init(struct i40e_pf *pf) { @@ -2165,8 +2165,8 @@ create_failed: } /** - * i40e_dbg_pf_exit - clear out the pf's debugfs entries - * @pf: the pf that is stopping + * i40e_dbg_pf_exit - clear out the PF's debugfs entries + * @pf: the PF that is stopping **/ void i40e_dbg_pf_exit(struct i40e_pf *pf) { diff --git a/drivers/net/ethernet/intel/i40e/i40e_fcoe.c b/drivers/net/ethernet/intel/i40e/i40e_fcoe.c index 0357b31e4a5c..1ca48458e668 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_fcoe.c +++ b/drivers/net/ethernet/intel/i40e/i40e_fcoe.c @@ -149,7 +149,7 @@ static inline bool i40e_fcoe_xid_is_valid(u16 xid) /** * i40e_fcoe_ddp_unmap - unmap the mapped sglist associated - * @pf: pointer to pf + * @pf: pointer to PF * @ddp: sw DDP context * * Unmap the scatter-gather list associated with the given SW DDP context @@ -268,7 +268,7 @@ out: /** * i40e_fcoe_sw_init - sets up the HW for FCoE - * @pf: pointer to pf + * @pf: pointer to PF * * Returns 0 if FCoE is supported otherwise the error code **/ @@ -328,7 +328,7 @@ int i40e_init_pf_fcoe(struct i40e_pf *pf) /** * i40e_get_fcoe_tc_map - Return TC map for FCoE APP - * @pf: pointer to pf + * @pf: pointer to PF * **/ u8 i40e_get_fcoe_tc_map(struct i40e_pf *pf) @@ -1531,7 +1531,7 @@ void i40e_fcoe_config_netdev(struct net_device *netdev, struct i40e_vsi *vsi) /** * i40e_fcoe_vsi_setup - allocate and set up FCoE VSI - * @pf: the pf that VSI is associated with + * @pf: the PF that VSI is associated with * **/ void i40e_fcoe_vsi_setup(struct i40e_pf *pf) @@ -1558,7 +1558,7 @@ void i40e_fcoe_vsi_setup(struct i40e_pf *pf) vsi = i40e_vsi_setup(pf, I40E_VSI_FCOE, seid, 0); if (vsi) { dev_dbg(&pf->pdev->dev, - "Successfully created FCoE VSI seid %d id %d uplink_seid %d pf seid %d\n", + "Successfully created FCoE VSI seid %d id %d uplink_seid %d PF seid %d\n", vsi->seid, vsi->id, vsi->uplink_seid, seid); } else { dev_info(&pf->pdev->dev, "Failed to create FCoE VSI\n"); diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 4bed881e3cb6..54a2d7bceb4f 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -450,7 +450,7 @@ void i40e_vsi_reset_stats(struct i40e_vsi *vsi) } /** - * i40e_pf_reset_stats - Reset all of the stats for the given pf + * i40e_pf_reset_stats - Reset all of the stats for the given PF * @pf: the PF to be reset **/ void i40e_pf_reset_stats(struct i40e_pf *pf) @@ -896,7 +896,7 @@ static void i40e_update_vsi_stats(struct i40e_vsi *vsi) } /** - * i40e_update_pf_stats - Update the pf statistics counters. + * i40e_update_pf_stats - Update the PF statistics counters. * @pf: the PF to be updated **/ static void i40e_update_pf_stats(struct i40e_pf *pf) @@ -1128,7 +1128,7 @@ void i40e_update_stats(struct i40e_vsi *vsi) * @vsi: the VSI to be searched * @macaddr: the MAC address * @vlan: the vlan - * @is_vf: make sure its a vf filter, else doesn't matter + * @is_vf: make sure its a VF filter, else doesn't matter * @is_netdev: make sure its a netdev filter, else doesn't matter * * Returns ptr to the filter object or NULL @@ -1156,7 +1156,7 @@ static struct i40e_mac_filter *i40e_find_filter(struct i40e_vsi *vsi, * i40e_find_mac - Find a mac addr in the macvlan filters list * @vsi: the VSI to be searched * @macaddr: the MAC address we are searching for - * @is_vf: make sure its a vf filter, else doesn't matter + * @is_vf: make sure its a VF filter, else doesn't matter * @is_netdev: make sure its a netdev filter, else doesn't matter * * Returns the first filter with the provided MAC address or NULL if @@ -1204,7 +1204,7 @@ bool i40e_is_vsi_in_vlan(struct i40e_vsi *vsi) * i40e_put_mac_in_vlan - Make macvlan filters from macaddrs and vlans * @vsi: the VSI to be searched * @macaddr: the mac address to be filtered - * @is_vf: true if it is a vf + * @is_vf: true if it is a VF * @is_netdev: true if it is a netdev * * Goes through all the macvlan filters and adds a @@ -1265,7 +1265,7 @@ static int i40e_rm_default_mac_filter(struct i40e_vsi *vsi, u8 *macaddr) * @vsi: the VSI to be searched * @macaddr: the MAC address * @vlan: the vlan - * @is_vf: make sure its a vf filter, else doesn't matter + * @is_vf: make sure its a VF filter, else doesn't matter * @is_netdev: make sure its a netdev filter, else doesn't matter * * Returns ptr to the filter object or NULL when no memory available. @@ -1325,7 +1325,7 @@ add_filter_out: * @vsi: the VSI to be searched * @macaddr: the MAC address * @vlan: the vlan - * @is_vf: make sure it's a vf filter, else doesn't matter + * @is_vf: make sure it's a VF filter, else doesn't matter * @is_netdev: make sure it's a netdev filter, else doesn't matter **/ void i40e_del_filter(struct i40e_vsi *vsi, @@ -1352,7 +1352,7 @@ void i40e_del_filter(struct i40e_vsi *vsi, f->counter--; } } else { - /* make sure we don't remove a filter in use by vf or netdev */ + /* make sure we don't remove a filter in use by VF or netdev */ int min_f = 0; min_f += (f->is_vf ? 1 : 0); min_f += (f->is_netdev ? 1 : 0); @@ -4029,7 +4029,7 @@ static int i40e_pf_wait_txq_disabled(struct i40e_pf *pf) #endif /** * i40e_get_iscsi_tc_map - Return TC map for iSCSI APP - * @pf: pointer to pf + * @pf: pointer to PF * * Get TC map for ISCSI PF type that will include iSCSI TC * and LAN TC. @@ -4204,7 +4204,7 @@ static int i40e_vsi_get_bw_info(struct i40e_vsi *vsi) aq_ret = i40e_aq_query_vsi_bw_config(hw, vsi->seid, &bw_config, NULL); if (aq_ret) { dev_info(&pf->pdev->dev, - "couldn't get pf vsi bw config, err %d, aq_err %d\n", + "couldn't get PF vsi bw config, err %d, aq_err %d\n", aq_ret, pf->hw.aq.asq_last_status); return -EINVAL; } @@ -4214,7 +4214,7 @@ static int i40e_vsi_get_bw_info(struct i40e_vsi *vsi) NULL); if (aq_ret) { dev_info(&pf->pdev->dev, - "couldn't get pf vsi ets bw config, err %d, aq_err %d\n", + "couldn't get PF vsi ets bw config, err %d, aq_err %d\n", aq_ret, pf->hw.aq.asq_last_status); return -EINVAL; } @@ -4976,7 +4976,7 @@ err_setup_tx: /** * i40e_fdir_filter_exit - Cleans up the Flow Director accounting - * @pf: Pointer to pf + * @pf: Pointer to PF * * This function destroys the hlist where all the Flow Director * filters were saved. @@ -5941,7 +5941,7 @@ static void i40e_verify_eeprom(struct i40e_pf *pf) /** * i40e_enable_pf_switch_lb - * @pf: pointer to the pf structure + * @pf: pointer to the PF structure * * enable switch loop back or die - no point in a return value **/ @@ -5957,7 +5957,7 @@ static void i40e_enable_pf_switch_lb(struct i40e_pf *pf) aq_ret = i40e_aq_get_vsi_params(&pf->hw, &ctxt, NULL); if (aq_ret) { dev_info(&pf->pdev->dev, - "%s couldn't get pf vsi config, err %d, aq_err %d\n", + "%s couldn't get PF vsi config, err %d, aq_err %d\n", __func__, aq_ret, pf->hw.aq.asq_last_status); return; } @@ -5975,7 +5975,7 @@ static void i40e_enable_pf_switch_lb(struct i40e_pf *pf) /** * i40e_disable_pf_switch_lb - * @pf: pointer to the pf structure + * @pf: pointer to the PF structure * * disable switch loop back or die - no point in a return value **/ @@ -5991,7 +5991,7 @@ static void i40e_disable_pf_switch_lb(struct i40e_pf *pf) aq_ret = i40e_aq_get_vsi_params(&pf->hw, &ctxt, NULL); if (aq_ret) { dev_info(&pf->pdev->dev, - "%s couldn't get pf vsi config, err %d, aq_err %d\n", + "%s couldn't get PF vsi config, err %d, aq_err %d\n", __func__, aq_ret, pf->hw.aq.asq_last_status); return; } @@ -6245,7 +6245,7 @@ static void i40e_fdir_teardown(struct i40e_pf *pf) * i40e_prep_for_reset - prep for the core to reset * @pf: board private structure * - * Close up the VFs and other things in prep for pf Reset. + * Close up the VFs and other things in prep for PF Reset. **/ static void i40e_prep_for_reset(struct i40e_pf *pf) { @@ -6471,7 +6471,7 @@ clear_recovery: } /** - * i40e_handle_reset_warning - prep for the pf to reset, reset and rebuild + * i40e_handle_reset_warning - prep for the PF to reset, reset and rebuild * @pf: board private structure * * Close up the VFs and other things in prep for a Core Reset, @@ -6485,7 +6485,7 @@ static void i40e_handle_reset_warning(struct i40e_pf *pf) /** * i40e_handle_mdd_event - * @pf: pointer to the pf structure + * @pf: pointer to the PF structure * * Called from the MDD irq handler to identify possibly malicious vfs **/ @@ -6514,7 +6514,7 @@ static void i40e_handle_mdd_event(struct i40e_pf *pf) I40E_GL_MDET_TX_QUEUE_SHIFT) - pf->hw.func_caps.base_queue; if (netif_msg_tx_err(pf)) - dev_info(&pf->pdev->dev, "Malicious Driver Detection event 0x%02x on TX queue %d pf number 0x%02x vf number 0x%02x\n", + dev_info(&pf->pdev->dev, "Malicious Driver Detection event 0x%02x on TX queue %d PF number 0x%02x VF number 0x%02x\n", event, queue, pf_num, vf_num); wr32(hw, I40E_GL_MDET_TX, 0xffffffff); mdd_detected = true; @@ -6917,7 +6917,7 @@ static int i40e_vsi_clear(struct i40e_vsi *vsi) goto unlock_vsi; } - /* updates the pf for this cleared vsi */ + /* updates the PF for this cleared vsi */ i40e_put_lump(pf->qp_pile, vsi->base_queue, vsi->idx); i40e_put_lump(pf->irq_pile, vsi->base_vector, vsi->idx); @@ -7491,7 +7491,7 @@ i40e_status i40e_set_npar_bw_setting(struct i40e_pf *pf) struct i40e_aqc_configure_partition_bw_data bw_data; i40e_status status; - /* Set the valid bit for this pf */ + /* Set the valid bit for this PF */ bw_data.pf_valid_bits = cpu_to_le16(1 << pf->hw.pf_id); bw_data.max_bw[pf->hw.pf_id] = pf->npar_max_bw & I40E_ALT_BW_VALUE_MASK; bw_data.min_bw[pf->hw.pf_id] = pf->npar_min_bw & I40E_ALT_BW_VALUE_MASK; @@ -7649,11 +7649,11 @@ static int i40e_sw_init(struct i40e_pf *pf) (pf->hw.func_caps.fd_filters_best_effort > 0)) { pf->flags |= I40E_FLAG_FD_ATR_ENABLED; pf->atr_sample_rate = I40E_DEFAULT_ATR_SAMPLE_RATE; - /* Setup a counter for fd_atr per pf */ + /* Setup a counter for fd_atr per PF */ pf->fd_atr_cnt_idx = I40E_FD_ATR_STAT_IDX(pf->hw.pf_id); if (!(pf->flags & I40E_FLAG_MFP_ENABLED)) { pf->flags |= I40E_FLAG_FD_SB_ENABLED; - /* Setup a counter for fd_sb per pf */ + /* Setup a counter for fd_sb per PF */ pf->fd_sb_cnt_idx = I40E_FD_SB_STAT_IDX(pf->hw.pf_id); } else { dev_info(&pf->pdev->dev, @@ -8257,7 +8257,7 @@ static int i40e_add_vsi(struct i40e_vsi *vsi) ctxt.flags = I40E_AQ_VSI_TYPE_PF; if (ret) { dev_info(&pf->pdev->dev, - "couldn't get pf vsi config, err %d, aq_err %d\n", + "couldn't get PF vsi config, err %d, aq_err %d\n", ret, pf->hw.aq.asq_last_status); return -ENOENT; } @@ -9158,7 +9158,7 @@ err_alloc: } /** - * i40e_setup_pf_switch_element - set pf vars based on switch type + * i40e_setup_pf_switch_element - set PF vars based on switch type * @pf: board private structure * @ele: element we are building info from * @num_reported: total number of elements @@ -9491,7 +9491,7 @@ static void i40e_determine_queue_usage(struct i40e_pf *pf) * i40e_setup_pf_filter_control - Setup PF static filter control * @pf: PF to be setup * - * i40e_setup_pf_filter_control sets up a pf's initial filter control + * i40e_setup_pf_filter_control sets up a PF's initial filter control * settings. If PE/FCoE are enabled then it will also set the per PF * based filter sizes required for them. It also enables Flow director, * ethertype and macvlan type filter settings for the pf. @@ -9568,8 +9568,8 @@ static void i40e_print_features(struct i40e_pf *pf) * @pdev: PCI device information struct * @ent: entry in i40e_pci_tbl * - * i40e_probe initializes a pf identified by a pci_dev structure. - * The OS initialization, configuring of the pf private structure, + * i40e_probe initializes a PF identified by a pci_dev structure. + * The OS initialization, configuring of the PF private structure, * and a hardware reset occur. * * Returns 0 on success, negative on failure diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index 6beab943e93a..9b11f2e7e361 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -45,7 +45,7 @@ static inline __le64 build_ctob(u32 td_cmd, u32 td_offset, unsigned int size, * i40e_program_fdir_filter - Program a Flow Director filter * @fdir_data: Packet data that will be filter parameters * @raw_packet: the pre-allocated packet buffer for FDir - * @pf: The pf pointer + * @pf: The PF pointer * @add: True for add/update, False for remove **/ int i40e_program_fdir_filter(struct i40e_fdir_filter *fdir_data, u8 *raw_packet, diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c index 7cc635e4c2e4..0a93684130b9 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c @@ -30,8 +30,8 @@ /** * i40e_vc_disable_vf - * @pf: pointer to the pf info - * @vf: pointer to the vf info + * @pf: pointer to the PF info + * @vf: pointer to the VF info * * Disable the VF through a SW reset **/ @@ -48,10 +48,10 @@ static inline void i40e_vc_disable_vf(struct i40e_pf *pf, struct i40e_vf *vf) /** * i40e_vc_isvalid_vsi_id - * @vf: pointer to the vf info - * @vsi_id: vf relative vsi id + * @vf: pointer to the VF info + * @vsi_id: VF relative VSI id * - * check for the valid vsi id + * check for the valid VSI id **/ static inline bool i40e_vc_isvalid_vsi_id(struct i40e_vf *vf, u8 vsi_id) { @@ -62,7 +62,7 @@ static inline bool i40e_vc_isvalid_vsi_id(struct i40e_vf *vf, u8 vsi_id) /** * i40e_vc_isvalid_queue_id - * @vf: pointer to the vf info + * @vf: pointer to the VF info * @vsi_id: vsi id * @qid: vsi relative queue id * @@ -78,8 +78,8 @@ static inline bool i40e_vc_isvalid_queue_id(struct i40e_vf *vf, u8 vsi_id, /** * i40e_vc_isvalid_vector_id - * @vf: pointer to the vf info - * @vector_id: vf relative vector id + * @vf: pointer to the VF info + * @vector_id: VF relative vector id * * check for the valid vector id **/ @@ -94,11 +94,11 @@ static inline bool i40e_vc_isvalid_vector_id(struct i40e_vf *vf, u8 vector_id) /** * i40e_vc_get_pf_queue_id - * @vf: pointer to the vf info + * @vf: pointer to the VF info * @vsi_idx: index of VSI in PF struct * @vsi_queue_id: vsi relative queue id * - * return pf relative queue id + * return PF relative queue id **/ static u16 i40e_vc_get_pf_queue_id(struct i40e_vf *vf, u8 vsi_idx, u8 vsi_queue_id) @@ -120,7 +120,7 @@ static u16 i40e_vc_get_pf_queue_id(struct i40e_vf *vf, u8 vsi_idx, /** * i40e_config_irq_link_list - * @vf: pointer to the vf info + * @vf: pointer to the VF info * @vsi_idx: index of VSI in PF struct * @vecmap: irq map info * @@ -220,7 +220,7 @@ irq_list_done: /** * i40e_config_vsi_tx_queue - * @vf: pointer to the vf info + * @vf: pointer to the VF info * @vsi_idx: index of VSI in PF struct * @vsi_queue_id: vsi relative queue index * @info: config. info @@ -287,7 +287,7 @@ error_context: /** * i40e_config_vsi_rx_queue - * @vf: pointer to the vf info + * @vf: pointer to the VF info * @vsi_idx: index of VSI in PF struct * @vsi_queue_id: vsi relative queue index * @info: config. info @@ -378,10 +378,10 @@ error_param: /** * i40e_alloc_vsi_res - * @vf: pointer to the vf info + * @vf: pointer to the VF info * @type: type of VSI to allocate * - * alloc vf vsi context & resources + * alloc VF vsi context & resources **/ static int i40e_alloc_vsi_res(struct i40e_vf *vf, enum i40e_vsi_type type) { @@ -394,7 +394,7 @@ static int i40e_alloc_vsi_res(struct i40e_vf *vf, enum i40e_vsi_type type) if (!vsi) { dev_err(&pf->pdev->dev, - "add vsi failed for vf %d, aq_err %d\n", + "add vsi failed for VF %d, aq_err %d\n", vf->vf_id, pf->hw.aq.asq_last_status); ret = -ENOENT; goto error_alloc_vsi_res; @@ -443,9 +443,9 @@ error_alloc_vsi_res: /** * i40e_enable_vf_mappings - * @vf: pointer to the vf info + * @vf: pointer to the VF info * - * enable vf mappings + * enable VF mappings **/ static void i40e_enable_vf_mappings(struct i40e_vf *vf) { @@ -493,9 +493,9 @@ static void i40e_enable_vf_mappings(struct i40e_vf *vf) /** * i40e_disable_vf_mappings - * @vf: pointer to the vf info + * @vf: pointer to the VF info * - * disable vf mappings + * disable VF mappings **/ static void i40e_disable_vf_mappings(struct i40e_vf *vf) { @@ -513,9 +513,9 @@ static void i40e_disable_vf_mappings(struct i40e_vf *vf) /** * i40e_free_vf_res - * @vf: pointer to the vf info + * @vf: pointer to the VF info * - * free vf resources + * free VF resources **/ static void i40e_free_vf_res(struct i40e_vf *vf) { @@ -568,9 +568,9 @@ static void i40e_free_vf_res(struct i40e_vf *vf) /** * i40e_alloc_vf_res - * @vf: pointer to the vf info + * @vf: pointer to the VF info * - * allocate vf resources + * allocate VF resources **/ static int i40e_alloc_vf_res(struct i40e_vf *vf) { @@ -586,11 +586,11 @@ static int i40e_alloc_vf_res(struct i40e_vf *vf) set_bit(I40E_VIRTCHNL_VF_CAP_PRIVILEGE, &vf->vf_caps); /* store the total qps number for the runtime - * vf req validation + * VF req validation */ vf->num_queue_pairs = total_queue_pairs; - /* vf is now completely initialized */ + /* VF is now completely initialized */ set_bit(I40E_VF_STAT_INIT, &vf->vf_states); error_alloc: @@ -604,7 +604,7 @@ error_alloc: #define VF_TRANS_PENDING_MASK 0x20 /** * i40e_quiesce_vf_pci - * @vf: pointer to the vf structure + * @vf: pointer to the VF structure * * Wait for VF PCI transactions to be cleared after reset. Returns -EIO * if the transactions never clear. @@ -631,10 +631,10 @@ static int i40e_quiesce_vf_pci(struct i40e_vf *vf) /** * i40e_reset_vf - * @vf: pointer to the vf structure + * @vf: pointer to the VF structure * @flr: VFLR was issued or not * - * reset the vf + * reset the VF **/ void i40e_reset_vf(struct i40e_vf *vf, bool flr) { @@ -654,7 +654,7 @@ void i40e_reset_vf(struct i40e_vf *vf, bool flr) * just need to clean up, so don't hit the VFRTRIG register. */ if (!flr) { - /* reset vf using VPGEN_VFRTRIG reg */ + /* reset VF using VPGEN_VFRTRIG reg */ reg = rd32(hw, I40E_VPGEN_VFRTRIG(vf->vf_id)); reg |= I40E_VPGEN_VFRTRIG_VFSWR_MASK; wr32(hw, I40E_VPGEN_VFRTRIG(vf->vf_id), reg); @@ -697,7 +697,7 @@ void i40e_reset_vf(struct i40e_vf *vf, bool flr) i40e_vsi_control_rings(pf->vsi[vf->lan_vsi_index], false); complete_reset: - /* reallocate vf resources to reset the VSI state */ + /* reallocate VF resources to reset the VSI state */ i40e_free_vf_res(vf); i40e_alloc_vf_res(vf); i40e_enable_vf_mappings(vf); @@ -711,9 +711,9 @@ complete_reset: /** * i40e_free_vfs - * @pf: pointer to the pf structure + * @pf: pointer to the PF structure * - * free vf resources + * free VF resources **/ void i40e_free_vfs(struct i40e_pf *pf) { @@ -735,7 +735,7 @@ void i40e_free_vfs(struct i40e_pf *pf) msleep(20); /* let any messages in transit get finished up */ - /* free up vf resources */ + /* free up VF resources */ tmp = pf->num_alloc_vfs; pf->num_alloc_vfs = 0; for (i = 0; i < tmp; i++) { @@ -771,10 +771,10 @@ void i40e_free_vfs(struct i40e_pf *pf) #ifdef CONFIG_PCI_IOV /** * i40e_alloc_vfs - * @pf: pointer to the pf structure - * @num_alloc_vfs: number of vfs to allocate + * @pf: pointer to the PF structure + * @num_alloc_vfs: number of VFs to allocate * - * allocate vf resources + * allocate VF resources **/ int i40e_alloc_vfs(struct i40e_pf *pf, u16 num_alloc_vfs) { @@ -811,10 +811,10 @@ int i40e_alloc_vfs(struct i40e_pf *pf, u16 num_alloc_vfs) /* assign default capabilities */ set_bit(I40E_VIRTCHNL_VF_CAP_L2, &vfs[i].vf_caps); vfs[i].spoofchk = true; - /* vf resources get allocated during reset */ + /* VF resources get allocated during reset */ i40e_reset_vf(&vfs[i], false); - /* enable vf vplan_qtable mappings */ + /* enable VF vplan_qtable mappings */ i40e_enable_vf_mappings(&vfs[i]); } pf->num_alloc_vfs = num_alloc_vfs; @@ -832,7 +832,7 @@ err_iov: /** * i40e_pci_sriov_enable * @pdev: pointer to a pci_dev structure - * @num_vfs: number of vfs to allocate + * @num_vfs: number of VFs to allocate * * Enable or change the number of VFs **/ @@ -872,7 +872,7 @@ err_out: /** * i40e_pci_sriov_configure * @pdev: pointer to a pci_dev structure - * @num_vfs: number of vfs to allocate + * @num_vfs: number of VFs to allocate * * Enable or change the number of VFs. Called when the user updates the number * of VFs in sysfs. @@ -897,13 +897,13 @@ int i40e_pci_sriov_configure(struct pci_dev *pdev, int num_vfs) /** * i40e_vc_send_msg_to_vf - * @vf: pointer to the vf info + * @vf: pointer to the VF info * @v_opcode: virtual channel opcode * @v_retval: virtual channel return value * @msg: pointer to the msg buffer * @msglen: msg length * - * send msg to vf + * send msg to VF **/ static int i40e_vc_send_msg_to_vf(struct i40e_vf *vf, u32 v_opcode, u32 v_retval, u8 *msg, u16 msglen) @@ -952,11 +952,11 @@ static int i40e_vc_send_msg_to_vf(struct i40e_vf *vf, u32 v_opcode, /** * i40e_vc_send_resp_to_vf - * @vf: pointer to the vf info + * @vf: pointer to the VF info * @opcode: operation code * @retval: return value * - * send resp msg to vf + * send resp msg to VF **/ static int i40e_vc_send_resp_to_vf(struct i40e_vf *vf, enum i40e_virtchnl_ops opcode, @@ -967,9 +967,9 @@ static int i40e_vc_send_resp_to_vf(struct i40e_vf *vf, /** * i40e_vc_get_version_msg - * @vf: pointer to the vf info + * @vf: pointer to the VF info * - * called from the vf to request the API version used by the PF + * called from the VF to request the API version used by the PF **/ static int i40e_vc_get_version_msg(struct i40e_vf *vf) { @@ -985,11 +985,11 @@ static int i40e_vc_get_version_msg(struct i40e_vf *vf) /** * i40e_vc_get_vf_resources_msg - * @vf: pointer to the vf info + * @vf: pointer to the VF info * @msg: pointer to the msg buffer * @msglen: msg length * - * called from the vf to request its resources + * called from the VF to request its resources **/ static int i40e_vc_get_vf_resources_msg(struct i40e_vf *vf) { @@ -1036,7 +1036,7 @@ static int i40e_vc_get_vf_resources_msg(struct i40e_vf *vf) set_bit(I40E_VF_STAT_ACTIVE, &vf->vf_states); err: - /* send the response back to the vf */ + /* send the response back to the VF */ ret = i40e_vc_send_msg_to_vf(vf, I40E_VIRTCHNL_OP_GET_VF_RESOURCES, aq_ret, (u8 *)vfres, len); @@ -1046,13 +1046,13 @@ err: /** * i40e_vc_reset_vf_msg - * @vf: pointer to the vf info + * @vf: pointer to the VF info * @msg: pointer to the msg buffer * @msglen: msg length * - * called from the vf to reset itself, - * unlike other virtchnl messages, pf driver - * doesn't send the response back to the vf + * called from the VF to reset itself, + * unlike other virtchnl messages, PF driver + * doesn't send the response back to the VF **/ static void i40e_vc_reset_vf_msg(struct i40e_vf *vf) { @@ -1062,12 +1062,12 @@ static void i40e_vc_reset_vf_msg(struct i40e_vf *vf) /** * i40e_vc_config_promiscuous_mode_msg - * @vf: pointer to the vf info + * @vf: pointer to the VF info * @msg: pointer to the msg buffer * @msglen: msg length * - * called from the vf to configure the promiscuous mode of - * vf vsis + * called from the VF to configure the promiscuous mode of + * VF vsis **/ static int i40e_vc_config_promiscuous_mode_msg(struct i40e_vf *vf, u8 *msg, u16 msglen) @@ -1094,7 +1094,7 @@ static int i40e_vc_config_promiscuous_mode_msg(struct i40e_vf *vf, allmulti, NULL); error_param: - /* send the response to the vf */ + /* send the response to the VF */ return i40e_vc_send_resp_to_vf(vf, I40E_VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE, aq_ret); @@ -1102,11 +1102,11 @@ error_param: /** * i40e_vc_config_queues_msg - * @vf: pointer to the vf info + * @vf: pointer to the VF info * @msg: pointer to the msg buffer * @msglen: msg length * - * called from the vf to configure the rx/tx + * called from the VF to configure the rx/tx * queues **/ static int i40e_vc_config_queues_msg(struct i40e_vf *vf, u8 *msg, u16 msglen) @@ -1148,22 +1148,22 @@ static int i40e_vc_config_queues_msg(struct i40e_vf *vf, u8 *msg, u16 msglen) goto error_param; } } - /* set vsi num_queue_pairs in use to num configured by vf */ + /* set vsi num_queue_pairs in use to num configured by VF */ pf->vsi[vf->lan_vsi_index]->num_queue_pairs = qci->num_queue_pairs; error_param: - /* send the response to the vf */ + /* send the response to the VF */ return i40e_vc_send_resp_to_vf(vf, I40E_VIRTCHNL_OP_CONFIG_VSI_QUEUES, aq_ret); } /** * i40e_vc_config_irq_map_msg - * @vf: pointer to the vf info + * @vf: pointer to the VF info * @msg: pointer to the msg buffer * @msglen: msg length * - * called from the vf to configure the irq to + * called from the VF to configure the irq to * queue map **/ static int i40e_vc_config_irq_map_msg(struct i40e_vf *vf, u8 *msg, u16 msglen) @@ -1215,18 +1215,18 @@ static int i40e_vc_config_irq_map_msg(struct i40e_vf *vf, u8 *msg, u16 msglen) i40e_config_irq_link_list(vf, vsi_id, map); } error_param: - /* send the response to the vf */ + /* send the response to the VF */ return i40e_vc_send_resp_to_vf(vf, I40E_VIRTCHNL_OP_CONFIG_IRQ_MAP, aq_ret); } /** * i40e_vc_enable_queues_msg - * @vf: pointer to the vf info + * @vf: pointer to the VF info * @msg: pointer to the msg buffer * @msglen: msg length * - * called from the vf to enable all or specific queue(s) + * called from the VF to enable all or specific queue(s) **/ static int i40e_vc_enable_queues_msg(struct i40e_vf *vf, u8 *msg, u16 msglen) { @@ -1253,18 +1253,18 @@ static int i40e_vc_enable_queues_msg(struct i40e_vf *vf, u8 *msg, u16 msglen) if (i40e_vsi_control_rings(pf->vsi[vsi_id], true)) aq_ret = I40E_ERR_TIMEOUT; error_param: - /* send the response to the vf */ + /* send the response to the VF */ return i40e_vc_send_resp_to_vf(vf, I40E_VIRTCHNL_OP_ENABLE_QUEUES, aq_ret); } /** * i40e_vc_disable_queues_msg - * @vf: pointer to the vf info + * @vf: pointer to the VF info * @msg: pointer to the msg buffer * @msglen: msg length * - * called from the vf to disable all or specific + * called from the VF to disable all or specific * queue(s) **/ static int i40e_vc_disable_queues_msg(struct i40e_vf *vf, u8 *msg, u16 msglen) @@ -1293,18 +1293,18 @@ static int i40e_vc_disable_queues_msg(struct i40e_vf *vf, u8 *msg, u16 msglen) aq_ret = I40E_ERR_TIMEOUT; error_param: - /* send the response to the vf */ + /* send the response to the VF */ return i40e_vc_send_resp_to_vf(vf, I40E_VIRTCHNL_OP_DISABLE_QUEUES, aq_ret); } /** * i40e_vc_get_stats_msg - * @vf: pointer to the vf info + * @vf: pointer to the VF info * @msg: pointer to the msg buffer * @msglen: msg length * - * called from the vf to get vsi stats + * called from the VF to get vsi stats **/ static int i40e_vc_get_stats_msg(struct i40e_vf *vf, u8 *msg, u16 msglen) { @@ -1336,14 +1336,14 @@ static int i40e_vc_get_stats_msg(struct i40e_vf *vf, u8 *msg, u16 msglen) stats = vsi->eth_stats; error_param: - /* send the response back to the vf */ + /* send the response back to the VF */ return i40e_vc_send_msg_to_vf(vf, I40E_VIRTCHNL_OP_GET_STATS, aq_ret, (u8 *)&stats, sizeof(stats)); } /** * i40e_check_vf_permission - * @vf: pointer to the vf info + * @vf: pointer to the VF info * @macaddr: pointer to the MAC Address being checked * * Check if the VF has permission to add or delete unicast MAC address @@ -1377,7 +1377,7 @@ static inline int i40e_check_vf_permission(struct i40e_vf *vf, u8 *macaddr) /** * i40e_vc_add_mac_addr_msg - * @vf: pointer to the vf info + * @vf: pointer to the VF info * @msg: pointer to the msg buffer * @msglen: msg length * @@ -1434,14 +1434,14 @@ static int i40e_vc_add_mac_addr_msg(struct i40e_vf *vf, u8 *msg, u16 msglen) dev_err(&pf->pdev->dev, "Unable to program VF MAC filters\n"); error_param: - /* send the response to the vf */ + /* send the response to the VF */ return i40e_vc_send_resp_to_vf(vf, I40E_VIRTCHNL_OP_ADD_ETHER_ADDRESS, ret); } /** * i40e_vc_del_mac_addr_msg - * @vf: pointer to the vf info + * @vf: pointer to the VF info * @msg: pointer to the msg buffer * @msglen: msg length * @@ -1485,14 +1485,14 @@ static int i40e_vc_del_mac_addr_msg(struct i40e_vf *vf, u8 *msg, u16 msglen) dev_err(&pf->pdev->dev, "Unable to program VF MAC filters\n"); error_param: - /* send the response to the vf */ + /* send the response to the VF */ return i40e_vc_send_resp_to_vf(vf, I40E_VIRTCHNL_OP_DEL_ETHER_ADDRESS, ret); } /** * i40e_vc_add_vlan_msg - * @vf: pointer to the vf info + * @vf: pointer to the VF info * @msg: pointer to the msg buffer * @msglen: msg length * @@ -1540,13 +1540,13 @@ static int i40e_vc_add_vlan_msg(struct i40e_vf *vf, u8 *msg, u16 msglen) } error_param: - /* send the response to the vf */ + /* send the response to the VF */ return i40e_vc_send_resp_to_vf(vf, I40E_VIRTCHNL_OP_ADD_VLAN, aq_ret); } /** * i40e_vc_remove_vlan_msg - * @vf: pointer to the vf info + * @vf: pointer to the VF info * @msg: pointer to the msg buffer * @msglen: msg length * @@ -1591,13 +1591,13 @@ static int i40e_vc_remove_vlan_msg(struct i40e_vf *vf, u8 *msg, u16 msglen) } error_param: - /* send the response to the vf */ + /* send the response to the VF */ return i40e_vc_send_resp_to_vf(vf, I40E_VIRTCHNL_OP_DEL_VLAN, aq_ret); } /** * i40e_vc_validate_vf_msg - * @vf: pointer to the vf info + * @vf: pointer to the VF info * @msg: pointer to the msg buffer * @msglen: msg length * @msghndl: msg handle @@ -1703,14 +1703,14 @@ static int i40e_vc_validate_vf_msg(struct i40e_vf *vf, u32 v_opcode, /** * i40e_vc_process_vf_msg - * @pf: pointer to the pf structure - * @vf_id: source vf id + * @pf: pointer to the PF structure + * @vf_id: source VF id * @msg: pointer to the msg buffer * @msglen: msg length * @msghndl: msg handle * * called from the common aeq/arq handler to - * process request from vf + * process request from VF **/ int i40e_vc_process_vf_msg(struct i40e_pf *pf, u16 vf_id, u32 v_opcode, u32 v_retval, u8 *msg, u16 msglen) @@ -1728,7 +1728,7 @@ int i40e_vc_process_vf_msg(struct i40e_pf *pf, u16 vf_id, u32 v_opcode, ret = i40e_vc_validate_vf_msg(vf, v_opcode, v_retval, msg, msglen); if (ret) { - dev_err(&pf->pdev->dev, "Invalid message from vf %d, opcode %d, len %d\n", + dev_err(&pf->pdev->dev, "Invalid message from VF %d, opcode %d, len %d\n", local_vf_id, v_opcode, msglen); return ret; } @@ -1776,7 +1776,7 @@ int i40e_vc_process_vf_msg(struct i40e_pf *pf, u16 vf_id, u32 v_opcode, break; case I40E_VIRTCHNL_OP_UNKNOWN: default: - dev_err(&pf->pdev->dev, "Unsupported opcode %d from vf %d\n", + dev_err(&pf->pdev->dev, "Unsupported opcode %d from VF %d\n", v_opcode, local_vf_id); ret = i40e_vc_send_resp_to_vf(vf, v_opcode, I40E_ERR_NOT_IMPLEMENTED); @@ -1788,10 +1788,10 @@ int i40e_vc_process_vf_msg(struct i40e_pf *pf, u16 vf_id, u32 v_opcode, /** * i40e_vc_process_vflr_event - * @pf: pointer to the pf structure + * @pf: pointer to the PF structure * * called from the vlfr irq handler to - * free up vf resources and state variables + * free up VF resources and state variables **/ int i40e_vc_process_vflr_event(struct i40e_pf *pf) { @@ -1812,7 +1812,7 @@ int i40e_vc_process_vflr_event(struct i40e_pf *pf) for (vf_id = 0; vf_id < pf->num_alloc_vfs; vf_id++) { reg_idx = (hw->func_caps.vf_base_id + vf_id) / 32; bit_idx = (hw->func_caps.vf_base_id + vf_id) % 32; - /* read GLGEN_VFLRSTAT register to find out the flr vfs */ + /* read GLGEN_VFLRSTAT register to find out the flr VFs */ vf = &pf->vf[vf_id]; reg = rd32(hw, I40E_GLGEN_VFLRSTAT(reg_idx)); if (reg & (1 << bit_idx)) { @@ -1829,7 +1829,7 @@ int i40e_vc_process_vflr_event(struct i40e_pf *pf) /** * i40e_vc_vf_broadcast - * @pf: pointer to the pf structure + * @pf: pointer to the PF structure * @opcode: operation code * @retval: return value * @msg: pointer to the msg buffer @@ -1848,7 +1848,7 @@ static void i40e_vc_vf_broadcast(struct i40e_pf *pf, for (i = 0; i < pf->num_alloc_vfs; i++, vf++) { int abs_vf_id = vf->vf_id + hw->func_caps.vf_base_id; - /* Not all vfs are enabled so skip the ones that are not */ + /* Not all VFs are enabled so skip the ones that are not */ if (!test_bit(I40E_VF_STAT_INIT, &vf->vf_states) && !test_bit(I40E_VF_STAT_ACTIVE, &vf->vf_states)) continue; @@ -1863,7 +1863,7 @@ static void i40e_vc_vf_broadcast(struct i40e_pf *pf, /** * i40e_vc_notify_link_state - * @pf: pointer to the pf structure + * @pf: pointer to the PF structure * * send a link status message to all VFs on a given PF **/ @@ -1896,7 +1896,7 @@ void i40e_vc_notify_link_state(struct i40e_pf *pf) /** * i40e_vc_notify_reset - * @pf: pointer to the pf structure + * @pf: pointer to the PF structure * * indicate a pending reset to all VFs on a given PF **/ @@ -1912,7 +1912,7 @@ void i40e_vc_notify_reset(struct i40e_pf *pf) /** * i40e_vc_notify_vf_reset - * @vf: pointer to the vf structure + * @vf: pointer to the VF structure * * indicate a pending reset to the given VF **/ @@ -1942,10 +1942,10 @@ void i40e_vc_notify_vf_reset(struct i40e_vf *vf) /** * i40e_ndo_set_vf_mac * @netdev: network interface device structure - * @vf_id: vf identifier + * @vf_id: VF identifier * @mac: mac address * - * program vf mac address + * program VF mac address **/ int i40e_ndo_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac) { @@ -2010,11 +2010,11 @@ error_param: /** * i40e_ndo_set_vf_port_vlan * @netdev: network interface device structure - * @vf_id: vf identifier + * @vf_id: VF identifier * @vlan_id: mac address * @qos: priority setting * - * program vf vlan id and/or qos + * program VF vlan id and/or qos **/ int i40e_ndo_set_vf_port_vlan(struct net_device *netdev, int vf_id, u16 vlan_id, u8 qos) @@ -2123,10 +2123,10 @@ error_pvid: /** * i40e_ndo_set_vf_bw * @netdev: network interface device structure - * @vf_id: vf identifier - * @tx_rate: tx rate + * @vf_id: VF identifier + * @tx_rate: Tx rate * - * configure vf tx rate + * configure VF Tx rate **/ int i40e_ndo_set_vf_bw(struct net_device *netdev, int vf_id, int min_tx_rate, int max_tx_rate) @@ -2146,7 +2146,7 @@ int i40e_ndo_set_vf_bw(struct net_device *netdev, int vf_id, int min_tx_rate, } if (min_tx_rate) { - dev_err(&pf->pdev->dev, "Invalid min tx rate (%d) (greater than 0) specified for vf %d.\n", + dev_err(&pf->pdev->dev, "Invalid min tx rate (%d) (greater than 0) specified for VF %d.\n", min_tx_rate, vf_id); return -EINVAL; } @@ -2174,7 +2174,7 @@ int i40e_ndo_set_vf_bw(struct net_device *netdev, int vf_id, int min_tx_rate, } if (max_tx_rate > speed) { - dev_err(&pf->pdev->dev, "Invalid max tx rate %d specified for vf %d.", + dev_err(&pf->pdev->dev, "Invalid max tx rate %d specified for VF %d.", max_tx_rate, vf->vf_id); ret = -EINVAL; goto error; @@ -2203,10 +2203,10 @@ error: /** * i40e_ndo_get_vf_config * @netdev: network interface device structure - * @vf_id: vf identifier - * @ivi: vf configuration structure + * @vf_id: VF identifier + * @ivi: VF configuration structure * - * return vf configuration + * return VF configuration **/ int i40e_ndo_get_vf_config(struct net_device *netdev, int vf_id, struct ifla_vf_info *ivi) @@ -2258,7 +2258,7 @@ error_param: /** * i40e_ndo_set_vf_link_state * @netdev: network interface device structure - * @vf_id: vf identifier + * @vf_id: VF identifier * @link: required link state * * Set the link state of a specified VF, regardless of physical link state @@ -2321,7 +2321,7 @@ error_out: /** * i40e_ndo_set_vf_spoofchk * @netdev: network interface device structure - * @vf_id: vf identifier + * @vf_id: VF identifier * @enable: flag to enable or disable feature * * Enable or disable VF spoof checking diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h index 21db113a64fa..9c3a41040835 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h +++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h @@ -71,12 +71,12 @@ enum i40e_vf_capabilities { struct i40e_vf { struct i40e_pf *pf; - /* vf id in the pf space */ + /* VF id in the PF space */ u16 vf_id; - /* all vf vsis connect to the same parent */ + /* all VF vsis connect to the same parent */ enum i40e_switch_element_types parent_type; - /* vf Port Extender (PE) stag if used */ + /* VF Port Extender (PE) stag if used */ u16 stag; struct i40e_virtchnl_ether_addr default_lan_addr; @@ -91,7 +91,7 @@ struct i40e_vf { u8 lan_vsi_index; /* index into PF struct */ u8 lan_vsi_id; /* ID as used by firmware */ - u8 num_queue_pairs; /* num of qps assigned to vf vsis */ + u8 num_queue_pairs; /* num of qps assigned to VF vsis */ u64 num_mdd_events; /* num of mdd events detected */ u64 num_invalid_msgs; /* num of malformed or invalid msgs detected */ u64 num_valid_msgs; /* num of valid msgs detected */ @@ -100,7 +100,7 @@ struct i40e_vf { unsigned long vf_states; /* vf's runtime states */ unsigned int tx_rate; /* Tx bandwidth limit in Mbps */ bool link_forced; - bool link_up; /* only valid if vf link is forced */ + bool link_up; /* only valid if VF link is forced */ bool spoofchk; }; @@ -113,7 +113,7 @@ int i40e_vc_process_vflr_event(struct i40e_pf *pf); void i40e_reset_vf(struct i40e_vf *vf, bool flr); void i40e_vc_notify_vf_reset(struct i40e_vf *vf); -/* vf configuration related iplink handlers */ +/* VF configuration related iplink handlers */ int i40e_ndo_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac); int i40e_ndo_set_vf_port_vlan(struct net_device *netdev, int vf_id, u16 vlan_id, u8 qos); -- GitLab From 8bd63cf1a426e69bf4f611b08978f721e46c194f Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Thu, 5 Mar 2015 00:52:33 +0100 Subject: [PATCH 03485/11651] bridge: move mac header copying into br_netfilter The mac header only has to be copied back into the skb for fragments generated by ip_fragment(), which only happens for bridge forwarded packets with nf-call-iptables=1 && active nf_defrag. Signed-off-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso --- include/linux/netfilter_bridge.h | 31 ------------------------------- net/bridge/br_forward.c | 4 +--- net/bridge/br_netfilter.c | 29 ++++++++++++++++++++++++++++- 3 files changed, 29 insertions(+), 35 deletions(-) diff --git a/include/linux/netfilter_bridge.h b/include/linux/netfilter_bridge.h index c755e4971fa3..332ef8ab37e9 100644 --- a/include/linux/netfilter_bridge.h +++ b/include/linux/netfilter_bridge.h @@ -44,36 +44,6 @@ static inline void nf_bridge_update_protocol(struct sk_buff *skb) skb->protocol = htons(ETH_P_PPP_SES); } -/* Fill in the header for fragmented IP packets handled by - * the IPv4 connection tracking code. - * - * Only used in br_forward.c - */ -static inline int nf_bridge_copy_header(struct sk_buff *skb) -{ - int err; - unsigned int header_size; - - nf_bridge_update_protocol(skb); - header_size = ETH_HLEN + nf_bridge_encap_header_len(skb); - err = skb_cow_head(skb, header_size); - if (err) - return err; - - skb_copy_to_linear_data_offset(skb, -header_size, - skb->nf_bridge->data, header_size); - __skb_push(skb, nf_bridge_encap_header_len(skb)); - return 0; -} - -static inline int nf_bridge_maybe_copy_header(struct sk_buff *skb) -{ - if (skb->nf_bridge && - skb->nf_bridge->mask & (BRNF_BRIDGED | BRNF_BRIDGED_DNAT)) - return nf_bridge_copy_header(skb); - return 0; -} - static inline unsigned int nf_bridge_mtu_reduction(const struct sk_buff *skb) { if (unlikely(skb->nf_bridge->mask & BRNF_PPPoE)) @@ -119,7 +89,6 @@ static inline void br_drop_fake_rtable(struct sk_buff *skb) } #else -#define nf_bridge_maybe_copy_header(skb) (0) #define nf_bridge_pad(skb) (0) #define br_drop_fake_rtable(skb) do { } while (0) #endif /* CONFIG_BRIDGE_NETFILTER */ diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c index f96933a823e3..32541d4f72e8 100644 --- a/net/bridge/br_forward.c +++ b/net/bridge/br_forward.c @@ -37,9 +37,7 @@ static inline int should_deliver(const struct net_bridge_port *p, int br_dev_queue_push_xmit(struct sk_buff *skb) { - /* ip_fragment doesn't copy the MAC header */ - if (nf_bridge_maybe_copy_header(skb) || - !is_skb_forwardable(skb->dev, skb)) { + if (!is_skb_forwardable(skb->dev, skb)) { kfree_skb(skb); } else { skb_push(skb, ETH_HLEN); diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index 0ee453fad3de..e5479112c4a3 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c @@ -764,6 +764,33 @@ static unsigned int br_nf_forward_arp(const struct nf_hook_ops *ops, } #if IS_ENABLED(CONFIG_NF_DEFRAG_IPV4) +static bool nf_bridge_copy_header(struct sk_buff *skb) +{ + int err; + unsigned int header_size; + + nf_bridge_update_protocol(skb); + header_size = ETH_HLEN + nf_bridge_encap_header_len(skb); + err = skb_cow_head(skb, header_size); + if (err) + return false; + + skb_copy_to_linear_data_offset(skb, -header_size, + skb->nf_bridge->data, header_size); + __skb_push(skb, nf_bridge_encap_header_len(skb)); + return true; +} + +static int br_nf_push_frag_xmit(struct sk_buff *skb) +{ + if (!nf_bridge_copy_header(skb)) { + kfree_skb(skb); + return 0; + } + + return br_dev_queue_push_xmit(skb); +} + static int br_nf_dev_queue_xmit(struct sk_buff *skb) { int ret; @@ -780,7 +807,7 @@ static int br_nf_dev_queue_xmit(struct sk_buff *skb) /* Drop invalid packet */ return NF_DROP; IPCB(skb)->frag_max_size = frag_max_size; - ret = ip_fragment(skb, br_dev_queue_push_xmit); + ret = ip_fragment(skb, br_nf_push_frag_xmit); } else ret = br_dev_queue_push_xmit(skb); -- GitLab From 4a9d2f200862683d6680d5565f30c126625afe65 Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Thu, 5 Mar 2015 00:52:34 +0100 Subject: [PATCH 03486/11651] netfilter: bridge: move nf_bridge_update_protocol to where its used no need to keep it in a header file. Signed-off-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso --- include/linux/netfilter_bridge.h | 8 -------- net/bridge/br_netfilter.c | 8 ++++++++ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/include/linux/netfilter_bridge.h b/include/linux/netfilter_bridge.h index 332ef8ab37e9..dd580a9a1add 100644 --- a/include/linux/netfilter_bridge.h +++ b/include/linux/netfilter_bridge.h @@ -36,14 +36,6 @@ static inline unsigned int nf_bridge_encap_header_len(const struct sk_buff *skb) } } -static inline void nf_bridge_update_protocol(struct sk_buff *skb) -{ - if (skb->nf_bridge->mask & BRNF_8021Q) - skb->protocol = htons(ETH_P_8021Q); - else if (skb->nf_bridge->mask & BRNF_PPPoE) - skb->protocol = htons(ETH_P_PPP_SES); -} - static inline unsigned int nf_bridge_mtu_reduction(const struct sk_buff *skb) { if (unlikely(skb->nf_bridge->mask & BRNF_PPPoE)) diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index e5479112c4a3..5b3bceb3ee62 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c @@ -239,6 +239,14 @@ drop: return -1; } +static void nf_bridge_update_protocol(struct sk_buff *skb) +{ + if (skb->nf_bridge->mask & BRNF_8021Q) + skb->protocol = htons(ETH_P_8021Q); + else if (skb->nf_bridge->mask & BRNF_PPPoE) + skb->protocol = htons(ETH_P_PPP_SES); +} + /* PF_BRIDGE/PRE_ROUTING *********************************************/ /* Undo the changes made for ip6tables PREROUTING and continue the * bridge PRE_ROUTING hook. */ -- GitLab From 7a8d831df5811f49957cc9b7976319973d088c34 Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Thu, 5 Mar 2015 00:52:36 +0100 Subject: [PATCH 03487/11651] netfilter: bridge: refactor conditional in br_nf_dev_queue_xmit simpilifies followup patch that re-works brnf ip_fragment handling. Signed-off-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso --- net/bridge/br_netfilter.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index 5b3bceb3ee62..ef1fe281ca11 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c @@ -803,13 +803,16 @@ static int br_nf_dev_queue_xmit(struct sk_buff *skb) { int ret; int frag_max_size; + unsigned int mtu_reserved; + if (skb_is_gso(skb) || skb->protocol != htons(ETH_P_IP)) + return br_dev_queue_push_xmit(skb); + + mtu_reserved = nf_bridge_mtu_reduction(skb); /* This is wrong! We should preserve the original fragment * boundaries by preserving frag_list rather than refragmenting. */ - if (skb->protocol == htons(ETH_P_IP) && - skb->len + nf_bridge_mtu_reduction(skb) > skb->dev->mtu && - !skb_is_gso(skb)) { + if (skb->len + mtu_reserved > skb->dev->mtu) { frag_max_size = BR_INPUT_SKB_CB(skb)->frag_max_size; if (br_parse_ip_options(skb)) /* Drop invalid packet */ -- GitLab From 6019ee4095d9a40927060d33e79344a3f34b8a96 Mon Sep 17 00:00:00 2001 From: Haneen Mohammed Date: Sun, 8 Mar 2015 00:02:34 +0300 Subject: [PATCH 03488/11651] Staging: dgap: Remove unused variable This patch removes variable that was used to store only the return value of a function call. The issue was detected and resolved using the following coccinelle script: @@ expression ret; identifier f; @@ -ret = +return f(...); -return ret; Signed-off-by: Haneen Mohammed Reviewed-by: Daniel Baluta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgap/dgap.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/dgap/dgap.c b/drivers/staging/dgap/dgap.c index d4d98a78f3ac..cea5b26032d9 100644 --- a/drivers/staging/dgap/dgap.c +++ b/drivers/staging/dgap/dgap.c @@ -1361,7 +1361,6 @@ static uint dgap_get_custom_baud(struct channel_t *ch) { u8 __iomem *vaddr; ulong offset; - uint value; if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) return 0; @@ -1384,8 +1383,7 @@ static uint dgap_get_custom_baud(struct channel_t *ch) offset = (ioread16(vaddr + ECS_SEG) << 4) + (ch->ch_portnum * 0x28) + LINE_SPEED; - value = readw(vaddr + offset); - return value; + return readw(vaddr + offset); } /* -- GitLab From f7d63547ea7fe7e4a666aa97e095855e5064b70e Mon Sep 17 00:00:00 2001 From: Haneen Mohammed Date: Sun, 8 Mar 2015 00:03:51 +0300 Subject: [PATCH 03489/11651] Staging: speakup: Remove unused variable This patch removes variable that was used to store only the return value of a function call. The issue was detected and resolved using the following coccinelle script: @@ expression ret; identifier f; @@ -ret = +return f(...); -return ret; Signed-off-by: Haneen Mohammed Signed-off-by: Greg Kroah-Hartman --- drivers/staging/speakup/kobjects.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/speakup/kobjects.c b/drivers/staging/speakup/kobjects.c index 3708bc13ae86..0211df60004a 100644 --- a/drivers/staging/speakup/kobjects.c +++ b/drivers/staging/speakup/kobjects.c @@ -840,12 +840,10 @@ static ssize_t message_show(struct kobject *kobj, static ssize_t message_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) { - ssize_t retval = 0; struct msg_group_t *group = spk_find_msg_group(attr->attr.name); BUG_ON(!group); - retval = message_store_helper(buf, count, group); - return retval; + return message_store_helper(buf, count, group); } /* -- GitLab From a3d81a379b0933f3a2e9ceba6cb770ceb4865c18 Mon Sep 17 00:00:00 2001 From: Darshana Padmadas Date: Sun, 8 Mar 2015 23:33:39 +0530 Subject: [PATCH 03490/11651] drivers: staging: dgnc: Replace min with min_t This patch replaces min with min_t and eliminates the following warning found by checkpatch.pl: WARNING: min() should probably be min_t(uint, n, 12) Signed-off-by: Darshana Padmadas Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgnc/dgnc_neo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/dgnc/dgnc_neo.c b/drivers/staging/dgnc/dgnc_neo.c index c9a8a9825cfb..1268aa945e9c 100644 --- a/drivers/staging/dgnc/dgnc_neo.c +++ b/drivers/staging/dgnc/dgnc_neo.c @@ -1203,7 +1203,7 @@ static void neo_copy_data_from_uart_to_queue(struct channel_t *ch) * IBM pSeries platform. * 15 bytes max appears to be the magic number. */ - n = min((uint) n, (uint) 12); + n = min_t(uint, n, 12); /* * Since we are grabbing the linestatus register, which -- GitLab From d009f0d7ae38bf1fdc0ff1a914a6dee538059869 Mon Sep 17 00:00:00 2001 From: Darshana Padmadas Date: Sun, 8 Mar 2015 23:33:40 +0530 Subject: [PATCH 03491/11651] staging: rtl8192e: Replace min with min_t This patch replaces min with min_t and eliminates the following warnings found by checkpatch.pl: WARNING: min() should probably be min_t Signed-off-by: Darshana Padmadas Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtllib_rx.c | 10 +++++----- drivers/staging/rtl8192e/rtllib_wx.c | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/staging/rtl8192e/rtllib_rx.c b/drivers/staging/rtl8192e/rtllib_rx.c index d640420f0076..e8261aec919f 100644 --- a/drivers/staging/rtl8192e/rtllib_rx.c +++ b/drivers/staging/rtl8192e/rtllib_rx.c @@ -1904,7 +1904,7 @@ int rtllib_parse_info_param(struct rtllib_device *ieee, info_element->data[2] == 0x4c && info_element->data[3] == 0x033) { - tmp_htcap_len = min(info_element->len, (u8)MAX_IE_LEN); + tmp_htcap_len = min_t(u8, info_element->len, MAX_IE_LEN); if (tmp_htcap_len != 0) { network->bssht.bdHTSpecVer = HT_SPEC_VER_EWC; network->bssht.bdHTCapLen = tmp_htcap_len > sizeof(network->bssht.bdHTCapBuf) ? @@ -1928,7 +1928,7 @@ int rtllib_parse_info_param(struct rtllib_device *ieee, info_element->data[1] == 0x90 && info_element->data[2] == 0x4c && info_element->data[3] == 0x034) { - tmp_htinfo_len = min(info_element->len, (u8)MAX_IE_LEN); + tmp_htinfo_len = min_t(u8, info_element->len, MAX_IE_LEN); if (tmp_htinfo_len != 0) { network->bssht.bdHTSpecVer = HT_SPEC_VER_EWC; if (tmp_htinfo_len) { @@ -1949,7 +1949,7 @@ int rtllib_parse_info_param(struct rtllib_device *ieee, info_element->data[1] == 0xe0 && info_element->data[2] == 0x4c && info_element->data[3] == 0x02) { - ht_realtek_agg_len = min(info_element->len, (u8)MAX_IE_LEN); + ht_realtek_agg_len = min_t(u8, info_element->len, MAX_IE_LEN); memcpy(ht_realtek_agg_buf, info_element->data, info_element->len); } if (ht_realtek_agg_len >= 5) { @@ -2079,7 +2079,7 @@ int rtllib_parse_info_param(struct rtllib_device *ieee, case MFIE_TYPE_HT_CAP: RTLLIB_DEBUG_SCAN("MFIE_TYPE_HT_CAP: %d bytes\n", info_element->len); - tmp_htcap_len = min(info_element->len, (u8)MAX_IE_LEN); + tmp_htcap_len = min_t(u8, info_element->len, MAX_IE_LEN); if (tmp_htcap_len != 0) { network->bssht.bdHTSpecVer = HT_SPEC_VER_EWC; network->bssht.bdHTCapLen = tmp_htcap_len > sizeof(network->bssht.bdHTCapBuf) ? @@ -2106,7 +2106,7 @@ int rtllib_parse_info_param(struct rtllib_device *ieee, case MFIE_TYPE_HT_INFO: RTLLIB_DEBUG_SCAN("MFIE_TYPE_HT_INFO: %d bytes\n", info_element->len); - tmp_htinfo_len = min(info_element->len, (u8)MAX_IE_LEN); + tmp_htinfo_len = min_t(u8, info_element->len, MAX_IE_LEN); if (tmp_htinfo_len) { network->bssht.bdHTSpecVer = HT_SPEC_VER_IEEE; network->bssht.bdHTInfoLen = tmp_htinfo_len > diff --git a/drivers/staging/rtl8192e/rtllib_wx.c b/drivers/staging/rtl8192e/rtllib_wx.c index 309cda0c0e67..2e665eddc100 100644 --- a/drivers/staging/rtl8192e/rtllib_wx.c +++ b/drivers/staging/rtl8192e/rtllib_wx.c @@ -74,7 +74,7 @@ static inline char *rtl819x_translate_scan(struct rtllib_device *ieee, iwe.cmd = SIOCGIWESSID; iwe.u.data.flags = 1; if (network->ssid_len > 0) { - iwe.u.data.length = min(network->ssid_len, (u8)32); + iwe.u.data.length = min_t(u8, network->ssid_len, 32); start = iwe_stream_add_point_rsl(info, start, stop, &iwe, network->ssid); } else if (network->hidden_ssid_len == 0) { @@ -82,7 +82,7 @@ static inline char *rtl819x_translate_scan(struct rtllib_device *ieee, start = iwe_stream_add_point_rsl(info, start, stop, &iwe, ""); } else { - iwe.u.data.length = min(network->hidden_ssid_len, (u8)32); + iwe.u.data.length = min_t(u8, network->hidden_ssid_len, 32); start = iwe_stream_add_point_rsl(info, start, stop, &iwe, network->hidden_ssid); } -- GitLab From a6a93bc03b3b1542f8871c4d631f2f6af60a0409 Mon Sep 17 00:00:00 2001 From: Dilek Uzulmez Date: Sat, 7 Mar 2015 23:15:39 +0200 Subject: [PATCH 03492/11651] Staging: rtl8192u: Added #include instead of The following patch fixes the checkpatch.pl warning: WARNING: Use #include instead of #include Signed-off-by: Dilek Uzulmez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c index f470cb601c89..32177c62e440 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include "ieee80211.h" -- GitLab From 9a4ed8c50668158135f5fe1ba8aa709656fde951 Mon Sep 17 00:00:00 2001 From: Dilek Uzulmez Date: Sat, 7 Mar 2015 23:26:36 +0200 Subject: [PATCH 03493/11651] Staging: rtl8192u: Added #include instead of The following patch fixes the checkpatch.pl warning: WARNING: Use #include instead of #include Signed-off-by: Dilek Uzulmez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c index 6201712e9c7d..e815c81b45dc 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include "ieee80211.h" -- GitLab From a429238b9afc35c90ad1c8cc584ff5b0023c1a59 Mon Sep 17 00:00:00 2001 From: Dilek Uzulmez Date: Sat, 7 Mar 2015 23:33:25 +0200 Subject: [PATCH 03494/11651] Staging: rtl8192u: Replace #include The following patch fixes the checkpatch.pl warning: WARNING: Use #include instead of #include Signed-off-by: Dilek Uzulmez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_wep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_wep.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_wep.c index f651a187d6db..0a17f84bb809 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_wep.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_wep.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include "ieee80211.h" -- GitLab From dce34aee0088fbe89c05cb8e1a21d5bed4fedc5b Mon Sep 17 00:00:00 2001 From: Tina Johnson Date: Mon, 9 Mar 2015 12:02:47 +0530 Subject: [PATCH 03495/11651] drivers: staging: rtl8188eu: core: Removed unnecessary parentheses Parentheses around the right side of an assignment statement are unnecessary and hence removed. Coccinelle was used to produce the patch: @rule1@ identifier x,y; constant c; @@ ( x = -( y << c -) ; | x = -( y >> c -) ; | x = -( y + c -) ; | x = -( y - c -) ; ) Signed-off-by: Tina Johnson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/core/rtw_security.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_security.c b/drivers/staging/rtl8188eu/core/rtw_security.c index f8981f56bafe..cc66997da262 100644 --- a/drivers/staging/rtl8188eu/core/rtw_security.c +++ b/drivers/staging/rtl8188eu/core/rtw_security.c @@ -1122,7 +1122,7 @@ static int aes_cipher(u8 *key, uint hdrlen, u8 *pframe, uint plen) num_blocks = plen / 16; /* Find start of payload */ - payload_index = (hdrlen + 8); + payload_index = hdrlen + 8; /* Calculate MIC */ aes128k128d(key, mic_iv, aes_out); @@ -1366,7 +1366,7 @@ static int aes_decipher(u8 *key, uint hdrlen, num_blocks = (plen-8) / 16; /* Find start of payload */ - payload_index = (hdrlen + 8); + payload_index = hdrlen + 8; /* Calculate MIC */ aes128k128d(key, mic_iv, aes_out); -- GitLab From 69e2b47fa082dffad06643c85be2d36f4ef6ab9c Mon Sep 17 00:00:00 2001 From: Tina Johnson Date: Mon, 9 Mar 2015 12:02:48 +0530 Subject: [PATCH 03496/11651] drivers: staging: rtl8712: Removed unnecessary parentheses Parentheses around the right side of an assignment statement are unnecessary and hence removed. Coccinelle was used to produce the patch: @rule1@ identifier x,y; constant c; @@ ( x = -( y << c -) ; | x = -( y >> c -) ; | x = -( y + c -) ; | x = -( y - c -) ; ) Signed-off-by: Tina Johnson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/rtl871x_security.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rtl8712/rtl871x_security.c b/drivers/staging/rtl8712/rtl871x_security.c index 4d5a2889b775..a178c232b44a 100644 --- a/drivers/staging/rtl8712/rtl871x_security.c +++ b/drivers/staging/rtl8712/rtl871x_security.c @@ -1086,7 +1086,7 @@ static sint aes_cipher(u8 *key, uint hdrlen, payload_remainder = plen % 16; num_blocks = plen / 16; /* Find start of payload */ - payload_index = (hdrlen + 8); + payload_index = hdrlen + 8; /* Calculate MIC */ aes128k128d(key, mic_iv, aes_out); bitwise_xor(aes_out, mic_header1, chain_buffer); @@ -1292,7 +1292,7 @@ static sint aes_decipher(u8 *key, uint hdrlen, payload_remainder = (plen - 8) % 16; num_blocks = (plen - 8) / 16; /* Find start of payload */ - payload_index = (hdrlen + 8); + payload_index = hdrlen + 8; /* Calculate MIC */ aes128k128d(key, mic_iv, aes_out); bitwise_xor(aes_out, mic_header1, chain_buffer); -- GitLab From 143ff119553af104ab5c151401bbef11136cfacd Mon Sep 17 00:00:00 2001 From: Tina Johnson Date: Mon, 9 Mar 2015 12:02:49 +0530 Subject: [PATCH 03497/11651] drivers: staging: rtl8723au: core: Removed unnecessary parentheses Parentheses around the right side of an assignment statement are unnecessary and hence removed. Coccinelle was used to produce the patch: @rule1@ identifier x,y; constant c; @@ ( x = -( y << c -) ; | x = -( y >> c -) ; | x = -( y + c -) ; | x = -( y - c -) ; ) Signed-off-by: Tina Johnson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/core/rtw_security.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rtl8723au/core/rtw_security.c b/drivers/staging/rtl8723au/core/rtw_security.c index 715a47414bdd..0610d5f1bdc4 100644 --- a/drivers/staging/rtl8723au/core/rtw_security.c +++ b/drivers/staging/rtl8723au/core/rtw_security.c @@ -1193,7 +1193,7 @@ static int aes_cipher(u8 *key, uint hdrlen, u8 *pframe, uint plen) num_blocks = plen / 16; /* Find start of payload */ - payload_index = (hdrlen + 8); + payload_index = hdrlen + 8; /* Calculate MIC */ aes128k128d(key, mic_iv, aes_out); @@ -1466,7 +1466,7 @@ static int aes_decipher(u8 *key, uint hdrlen, num_blocks = (plen-8) / 16; /* Find start of payload */ - payload_index = (hdrlen + 8); + payload_index = hdrlen + 8; /* Calculate MIC */ aes128k128d(key, mic_iv, aes_out); -- GitLab From c89ca085a5b287acd3bbf35d4cb6be392ae0798f Mon Sep 17 00:00:00 2001 From: Tina Johnson Date: Mon, 9 Mar 2015 12:02:50 +0530 Subject: [PATCH 03498/11651] drivers: staging: rtl8723au: hal: Removed unnecessary parentheses Parentheses around the right side of an assignment statement are unnecessary and hence removed. Coccinelle was used to produce the patch: @rule1@ identifier x,y; constant c; @@ ( x = -( y << c -) ; | x = -( y >> c -) ; | x = -( y + c -) ; | x = -( y - c -) ; ) Signed-off-by: Tina Johnson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/hal/HalDMOutSrc8723A_CE.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8723au/hal/HalDMOutSrc8723A_CE.c b/drivers/staging/rtl8723au/hal/HalDMOutSrc8723A_CE.c index ba373744ece9..3f9ec9e00e16 100644 --- a/drivers/staging/rtl8723au/hal/HalDMOutSrc8723A_CE.c +++ b/drivers/staging/rtl8723au/hal/HalDMOutSrc8723A_CE.c @@ -222,7 +222,7 @@ odm_TXPowerTrackingCallback_ThermalMeter_92C(struct rtw_adapter *Adapter) } if (CCK_index > (CCK_TABLE_SIZE-1)) - CCK_index = (CCK_TABLE_SIZE-1); + CCK_index = CCK_TABLE_SIZE-1; else if (CCK_index < 0) CCK_index = 0; } -- GitLab From 8d0514d5631d8ded3fe42c3a16727039b576f18c Mon Sep 17 00:00:00 2001 From: Vatika Harlalka Date: Mon, 9 Mar 2015 14:24:42 +0530 Subject: [PATCH 03499/11651] Staging rtl8172: Remove unnecessary typecast Using addressof and then casting to the original type is unneeded. So these casts can be removed. Issue detected via Coccinelle script. Signed-off-by: Vatika Harlalka Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/hal_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8712/hal_init.c b/drivers/staging/rtl8712/hal_init.c index 324da34383ea..0a1c6313e781 100644 --- a/drivers/staging/rtl8712/hal_init.c +++ b/drivers/staging/rtl8712/hal_init.c @@ -92,7 +92,7 @@ static u32 rtl871x_open_fw(struct _adapter *padapter, const u8 **ppmappedfw) static void fill_fwpriv(struct _adapter *padapter, struct fw_priv *pfwpriv) { - struct dvobj_priv *pdvobj = (struct dvobj_priv *)&padapter->dvobjpriv; + struct dvobj_priv *pdvobj = &padapter->dvobjpriv; struct registry_priv *pregpriv = &padapter->registrypriv; memset(pfwpriv, 0, sizeof(struct fw_priv)); -- GitLab From cc5797d28b1418872864da7e9a0c52841b2e9177 Mon Sep 17 00:00:00 2001 From: Tina Johnson Date: Mon, 9 Mar 2015 16:11:20 +0530 Subject: [PATCH 03500/11651] drivers: staging: iio: meter: Removed unnecessary variable Variable ret is used only to store the return value. Hence ret is removed and the return statement modified. Coccinelle was used to detect such removable variables: @rule1@ identifier ret; expression e; @@ -ret = +return e; -return ret; Signed-off-by: Tina Johnson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/meter/ade7854-spi.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/staging/iio/meter/ade7854-spi.c b/drivers/staging/iio/meter/ade7854-spi.c index 94f73bbbc0fd..9b255a5f62c3 100644 --- a/drivers/staging/iio/meter/ade7854-spi.c +++ b/drivers/staging/iio/meter/ade7854-spi.c @@ -274,7 +274,6 @@ error_ret: static int ade7854_spi_probe(struct spi_device *spi) { - int ret; struct ade7854_state *st; struct iio_dev *indio_dev; @@ -294,10 +293,7 @@ static int ade7854_spi_probe(struct spi_device *spi) st->irq = spi->irq; st->spi = spi; - - ret = ade7854_probe(indio_dev, &spi->dev); - - return ret; + return ade7854_probe(indio_dev, &spi->dev); } static int ade7854_spi_remove(struct spi_device *spi) -- GitLab From 07f83131e5b5d309dc8dd41911b66d3ce4c99323 Mon Sep 17 00:00:00 2001 From: Tina Johnson Date: Mon, 9 Mar 2015 16:11:19 +0530 Subject: [PATCH 03501/11651] drivers: staging: iio: meter: Removed unnecessary variable Variable ret is used only to store the return value. Hence ret is removed and the return statement modified. Coccinelle was used to detect such removable variables: @rule1@ identifier ret; expression e; @@ -ret = +return e; -return ret; Signed-off-by: Tina Johnson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/meter/ade7854-i2c.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/staging/iio/meter/ade7854-i2c.c b/drivers/staging/iio/meter/ade7854-i2c.c index 4e7a3829ea55..07cfe28b24e2 100644 --- a/drivers/staging/iio/meter/ade7854-i2c.c +++ b/drivers/staging/iio/meter/ade7854-i2c.c @@ -205,7 +205,6 @@ out: static int ade7854_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { - int ret; struct ade7854_state *st; struct iio_dev *indio_dev; @@ -225,9 +224,7 @@ static int ade7854_i2c_probe(struct i2c_client *client, st->i2c = client; st->irq = client->irq; - ret = ade7854_probe(indio_dev, &client->dev); - - return ret; + return ade7854_probe(indio_dev, &client->dev); } static int ade7854_i2c_remove(struct i2c_client *client) -- GitLab From 9d9f5a2dac916013d9b0560e176a7619f7bf958d Mon Sep 17 00:00:00 2001 From: Tina Johnson Date: Mon, 9 Mar 2015 16:11:18 +0530 Subject: [PATCH 03502/11651] drivers: staging: iio: meter: Removed unnecessary variable Variable ret is used only to store the error code to be returned. Hence use of ret is removed and the return statement modified. Coccinelle was used to prepare the patch: @rule1@ identifier ret; expression e; @@ -ret = +return e; -return ret; Signed-off-by: Tina Johnson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/meter/ade7758_ring.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/iio/meter/ade7758_ring.c b/drivers/staging/iio/meter/ade7758_ring.c index 3792b5761645..9725a04c0c92 100644 --- a/drivers/staging/iio/meter/ade7758_ring.c +++ b/drivers/staging/iio/meter/ade7758_ring.c @@ -120,8 +120,7 @@ int ade7758_configure_ring(struct iio_dev *indio_dev) buffer = iio_kfifo_allocate(); if (!buffer) { - ret = -ENOMEM; - return ret; + return -ENOMEM; } iio_device_attach_buffer(indio_dev, buffer); -- GitLab From 90a9de83578fb7890a2f5a96dd393621f165ba5a Mon Sep 17 00:00:00 2001 From: Tina Johnson Date: Mon, 9 Mar 2015 16:11:17 +0530 Subject: [PATCH 03503/11651] drivers: staging: iio: meter: Removed unnecessary variable Variable len is used only to store the return value. Hence len is removed and the return statement modified. Coccinelle was used to detect such removable variables: @rule1@ identifier ret; expression e; @@ -ret = +return e; -return ret; Signed-off-by: Tina Johnson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/meter/ade7758_core.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/staging/iio/meter/ade7758_core.c b/drivers/staging/iio/meter/ade7758_core.c index 7e287dae7b44..652aa1069b06 100644 --- a/drivers/staging/iio/meter/ade7758_core.c +++ b/drivers/staging/iio/meter/ade7758_core.c @@ -485,7 +485,7 @@ static ssize_t ade7758_read_frequency(struct device *dev, struct device_attribute *attr, char *buf) { - int ret, len = 0; + int ret; u8 t; int sps; @@ -498,8 +498,7 @@ static ssize_t ade7758_read_frequency(struct device *dev, t = (t >> 5) & 0x3; sps = 26040 / (1 << t); - len = sprintf(buf, "%d SPS\n", sps); - return len; + return sprintf(buf, "%d SPS\n", sps); } static ssize_t ade7758_write_frequency(struct device *dev, -- GitLab From 3194e14db920138f4a0a19a03cb4c26db9969445 Mon Sep 17 00:00:00 2001 From: Tina Johnson Date: Mon, 9 Mar 2015 16:11:16 +0530 Subject: [PATCH 03504/11651] drivers: staging: iio: accel: Removed unnecessary variable Variable len is used only to store the return value. Hence len is removed and the return statement modified. Coccinelle was used to detect such removable variables: @rule1@ identifier ret; expression e; @@ -ret = +return e; -return ret; Signed-off-by: Tina Johnson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/accel/sca3000_core.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/staging/iio/accel/sca3000_core.c b/drivers/staging/iio/accel/sca3000_core.c index 31fb2182c198..b614f272b5f4 100644 --- a/drivers/staging/iio/accel/sca3000_core.c +++ b/drivers/staging/iio/accel/sca3000_core.c @@ -870,7 +870,7 @@ static ssize_t sca3000_query_free_fall_mode(struct device *dev, struct device_attribute *attr, char *buf) { - int ret, len; + int ret; struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct sca3000_state *st = iio_priv(indio_dev); int val; @@ -881,9 +881,7 @@ static ssize_t sca3000_query_free_fall_mode(struct device *dev, mutex_unlock(&st->lock); if (ret < 0) return ret; - len = sprintf(buf, "%d\n", - !!(val & SCA3000_FREE_FALL_DETECT)); - return len; + return sprintf(buf, "%d\n", !!(val & SCA3000_FREE_FALL_DETECT)); } /** -- GitLab From 6706bbd843477600a72132c884bc5658d628aa8c Mon Sep 17 00:00:00 2001 From: Cristina Opriceana Date: Mon, 9 Mar 2015 02:27:43 +0200 Subject: [PATCH 03505/11651] Staging: rtl8192u: Remove unnecessary macro definition This patch removes the IEEE80211_PRINT_STR macro definition because it appears only in the header file and it doesn't serve any purpose in this context. Signed-off-by: Cristina Opriceana Signed-off-by: Greg Kroah-Hartman --- .../staging/rtl8192u/ieee80211/ieee80211.h | 27 ------------------- 1 file changed, 27 deletions(-) diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211.h b/drivers/staging/rtl8192u/ieee80211/ieee80211.h index b44aa17d30a7..7e81ae108fa8 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211.h @@ -606,33 +606,6 @@ do { if (ieee80211_debug_level & (level)) \ #define IEEE80211_DEBUG_RX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_RX, f, ## a) #define IEEE80211_DEBUG_QOS(f, a...) IEEE80211_DEBUG(IEEE80211_DL_QOS, f, ## a) -#ifdef CONFIG_IEEE80211_DEBUG -/* Added by Annie, 2005-11-22. */ -#define MAX_STR_LEN 64 -/* I want to see ASCII 33 to 126 only. Otherwise, I print '?'. Annie, 2005-11-22.*/ -#define PRINTABLE(_ch) (_ch>'!' && _ch<'~') -#define IEEE80211_PRINT_STR(_Comp, _TitleString, _Ptr, _Len) \ - if((_Comp) & level) \ - { \ - int __i; \ - u8 buffer[MAX_STR_LEN]; \ - int length = (_Len\n", _Len, buffer); \ - } -#else -#define IEEE80211_PRINT_STR(_Comp, _TitleString, _Ptr, _Len) do {} while (0) -#endif - -#include #include /* ARPHRD_ETHER */ #ifndef WIRELESS_SPY -- GitLab From e2dca7adff8f3fae0ab250a6362798550b3c79ee Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 9 Mar 2015 09:22:28 -0400 Subject: [PATCH 03506/11651] workqueue: make the workqueues list RCU walkable The workqueues list is protected by wq_pool_mutex and a workqueue and its subordinate data structures are freed directly on destruction. We want to add the ability dump workqueues from a sysrq callback which requires walking all workqueues without grabbing wq_pool_mutex. This patch makes freeing of workqueues RCU protected and makes the workqueues list walkable while holding RCU read lock. Note that pool_workqueues and pools are already sched-RCU protected. For consistency, workqueues are also protected with sched-RCU. While at it, reverse the workqueues list so that a workqueue which is created earlier comes before. The order of the list isn't significant functionally but this makes the planned sysrq dump list system workqueues first. Signed-off-by: Tejun Heo --- kernel/workqueue.c | 47 ++++++++++++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 41ff75b478c6..6b9b0dc3dea5 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -230,7 +230,7 @@ struct wq_device; */ struct workqueue_struct { struct list_head pwqs; /* WR: all pwqs of this wq */ - struct list_head list; /* PL: list of all workqueues */ + struct list_head list; /* PR: list of all workqueues */ struct mutex mutex; /* protects this wq */ int work_color; /* WQ: current work color */ @@ -257,6 +257,13 @@ struct workqueue_struct { #endif char name[WQ_NAME_LEN]; /* I: workqueue name */ + /* + * Destruction of workqueue_struct is sched-RCU protected to allow + * walking the workqueues list without grabbing wq_pool_mutex. + * This is used to dump all workqueues from sysrq. + */ + struct rcu_head rcu; + /* hot fields used during command issue, aligned to cacheline */ unsigned int flags ____cacheline_aligned; /* WQ: WQ_* flags */ struct pool_workqueue __percpu *cpu_pwqs; /* I: per-cpu pwqs */ @@ -288,7 +295,7 @@ static struct workqueue_attrs *wq_update_unbound_numa_attrs_buf; static DEFINE_MUTEX(wq_pool_mutex); /* protects pools and workqueues list */ static DEFINE_SPINLOCK(wq_mayday_lock); /* protects wq->maydays list */ -static LIST_HEAD(workqueues); /* PL: list of all workqueues */ +static LIST_HEAD(workqueues); /* PR: list of all workqueues */ static bool workqueue_freezing; /* PL: have wqs started freezing? */ /* the per-cpu worker pools */ @@ -3424,6 +3431,20 @@ static int init_worker_pool(struct worker_pool *pool) return 0; } +static void rcu_free_wq(struct rcu_head *rcu) +{ + struct workqueue_struct *wq = + container_of(rcu, struct workqueue_struct, rcu); + + if (!(wq->flags & WQ_UNBOUND)) + free_percpu(wq->cpu_pwqs); + else + free_workqueue_attrs(wq->unbound_attrs); + + kfree(wq->rescuer); + kfree(wq); +} + static void rcu_free_pool(struct rcu_head *rcu) { struct worker_pool *pool = container_of(rcu, struct worker_pool, rcu); @@ -3601,12 +3622,10 @@ static void pwq_unbound_release_workfn(struct work_struct *work) /* * If we're the last pwq going away, @wq is already dead and no one - * is gonna access it anymore. Free it. + * is gonna access it anymore. Schedule RCU free. */ - if (is_last) { - free_workqueue_attrs(wq->unbound_attrs); - kfree(wq); - } + if (is_last) + call_rcu_sched(&wq->rcu, rcu_free_wq); } /** @@ -4143,7 +4162,7 @@ struct workqueue_struct *__alloc_workqueue_key(const char *fmt, pwq_adjust_max_active(pwq); mutex_unlock(&wq->mutex); - list_add(&wq->list, &workqueues); + list_add_tail_rcu(&wq->list, &workqueues); mutex_unlock(&wq_pool_mutex); @@ -4199,24 +4218,20 @@ void destroy_workqueue(struct workqueue_struct *wq) * flushing is complete in case freeze races us. */ mutex_lock(&wq_pool_mutex); - list_del_init(&wq->list); + list_del_rcu(&wq->list); mutex_unlock(&wq_pool_mutex); workqueue_sysfs_unregister(wq); - if (wq->rescuer) { + if (wq->rescuer) kthread_stop(wq->rescuer->task); - kfree(wq->rescuer); - wq->rescuer = NULL; - } if (!(wq->flags & WQ_UNBOUND)) { /* * The base ref is never dropped on per-cpu pwqs. Directly - * free the pwqs and wq. + * schedule RCU free. */ - free_percpu(wq->cpu_pwqs); - kfree(wq); + call_rcu_sched(&wq->rcu, rcu_free_wq); } else { /* * We're the sole accessor of @wq at this point. Directly -- GitLab From 2607d7a6dba1e790aaacb14600ceffa3aa2f43e7 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 9 Mar 2015 09:22:28 -0400 Subject: [PATCH 03507/11651] workqueue: keep track of the flushing task and pool manager Add wq_barrier->task and worker_pool->manager to keep track of the flushing task and pool manager respectively. These are purely informational and will be used to implement sysrq dump of workqueues. Signed-off-by: Tejun Heo --- kernel/workqueue.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 6b9b0dc3dea5..0c329a6f0c51 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -159,6 +159,7 @@ struct worker_pool { /* see manage_workers() for details on the two manager mutexes */ struct mutex manager_arb; /* manager arbitration */ + struct worker *manager; /* L: purely informational */ struct mutex attach_mutex; /* attach/detach exclusion */ struct list_head workers; /* A: attached workers */ struct completion *detach_completion; /* all workers detached */ @@ -1918,9 +1919,11 @@ static bool manage_workers(struct worker *worker) */ if (!mutex_trylock(&pool->manager_arb)) return false; + pool->manager = worker; maybe_create_worker(pool); + pool->manager = NULL; mutex_unlock(&pool->manager_arb); return true; } @@ -2310,6 +2313,7 @@ repeat: struct wq_barrier { struct work_struct work; struct completion done; + struct task_struct *task; /* purely informational */ }; static void wq_barrier_func(struct work_struct *work) @@ -2358,6 +2362,7 @@ static void insert_wq_barrier(struct pool_workqueue *pwq, INIT_WORK_ONSTACK(&barr->work, wq_barrier_func); __set_bit(WORK_STRUCT_PENDING_BIT, work_data_bits(&barr->work)); init_completion(&barr->done); + barr->task = current; /* * If @target is currently being executed, schedule the -- GitLab From 3494fc30846dceb808de4cc02930ef347fabd21a Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 9 Mar 2015 09:22:28 -0400 Subject: [PATCH 03508/11651] workqueue: dump workqueues on sysrq-t Workqueues are used extensively throughout the kernel but sometimes it's difficult to debug stalls involving work items because visibility into its inner workings is fairly limited. Although sysrq-t task dump annotates each active worker task with the information on the work item being executed, it is challenging to find out which work items are pending or delayed on which queues and how pools are being managed. This patch implements show_workqueue_state() which dumps all busy workqueues and pools and is called from the sysrq-t handler. At the end of sysrq-t dump, something like the following is printed. Showing busy workqueues and worker pools: ... workqueue filler_wq: flags=0x0 pwq 2: cpus=1 node=0 flags=0x0 nice=0 active=2/256 in-flight: 491:filler_workfn, 507:filler_workfn pwq 0: cpus=0 node=0 flags=0x0 nice=0 active=2/256 in-flight: 501:filler_workfn pending: filler_workfn ... workqueue test_wq: flags=0x8 pwq 2: cpus=1 node=0 flags=0x0 nice=0 active=1/1 in-flight: 510(RESCUER):test_workfn BAR(69) BAR(500) delayed: test_workfn1 BAR(492), test_workfn2 ... pool 0: cpus=0 node=0 flags=0x0 nice=0 workers=2 manager: 137 pool 2: cpus=1 node=0 flags=0x0 nice=0 workers=3 manager: 469 pool 3: cpus=1 node=0 flags=0x0 nice=-20 workers=2 idle: 16 pool 8: cpus=0-3 flags=0x4 nice=0 workers=2 manager: 62 The above shows that test_wq is executing test_workfn() on pid 510 which is the rescuer and also that there are two tasks 69 and 500 waiting for the work item to finish in flush_work(). As test_wq has max_active of 1, there are two work items for test_workfn1() and test_workfn2() which are delayed till the current work item is finished. In addition, pid 492 is flushing test_workfn1(). The work item for test_workfn() is being executed on pwq of pool 2 which is the normal priority per-cpu pool for CPU 1. The pool has three workers, two of which are executing filler_workfn() for filler_wq and the last one is assuming the manager role trying to create more workers. This extra workqueue state dump will hopefully help chasing down hangs involving workqueues. v3: cpulist_pr_cont() replaced with "%*pbl" printf formatting. v2: As suggested by Andrew, minor formatting change in pr_cont_work(), printk()'s replaced with pr_info()'s, and cpumask printing now uses cpulist_pr_cont(). Signed-off-by: Tejun Heo Cc: Lai Jiangshan Cc: Linus Torvalds Cc: Andrew Morton CC: Ingo Molnar --- drivers/tty/sysrq.c | 1 + include/linux/workqueue.h | 1 + kernel/workqueue.c | 160 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 162 insertions(+) diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c index 259a4d5a4e8f..843f2cdc280b 100644 --- a/drivers/tty/sysrq.c +++ b/drivers/tty/sysrq.c @@ -275,6 +275,7 @@ static struct sysrq_key_op sysrq_showregs_op = { static void sysrq_handle_showstate(int key) { show_state(); + show_workqueue_state(); } static struct sysrq_key_op sysrq_showstate_op = { .handler = sysrq_handle_showstate, diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h index f597846ff605..deee212af8e0 100644 --- a/include/linux/workqueue.h +++ b/include/linux/workqueue.h @@ -454,6 +454,7 @@ extern bool workqueue_congested(int cpu, struct workqueue_struct *wq); extern unsigned int work_busy(struct work_struct *work); extern __printf(1, 2) void set_worker_desc(const char *fmt, ...); extern void print_worker_info(const char *log_lvl, struct task_struct *task); +extern void show_workqueue_state(void); /** * queue_work - queue work on a workqueue diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 0c329a6f0c51..1ca0b1d54e70 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -4457,6 +4457,166 @@ void print_worker_info(const char *log_lvl, struct task_struct *task) } } +static void pr_cont_pool_info(struct worker_pool *pool) +{ + pr_cont(" cpus=%*pbl", nr_cpumask_bits, pool->attrs->cpumask); + if (pool->node != NUMA_NO_NODE) + pr_cont(" node=%d", pool->node); + pr_cont(" flags=0x%x nice=%d", pool->flags, pool->attrs->nice); +} + +static void pr_cont_work(bool comma, struct work_struct *work) +{ + if (work->func == wq_barrier_func) { + struct wq_barrier *barr; + + barr = container_of(work, struct wq_barrier, work); + + pr_cont("%s BAR(%d)", comma ? "," : "", + task_pid_nr(barr->task)); + } else { + pr_cont("%s %pf", comma ? "," : "", work->func); + } +} + +static void show_pwq(struct pool_workqueue *pwq) +{ + struct worker_pool *pool = pwq->pool; + struct work_struct *work; + struct worker *worker; + bool has_in_flight = false, has_pending = false; + int bkt; + + pr_info(" pwq %d:", pool->id); + pr_cont_pool_info(pool); + + pr_cont(" active=%d/%d%s\n", pwq->nr_active, pwq->max_active, + !list_empty(&pwq->mayday_node) ? " MAYDAY" : ""); + + hash_for_each(pool->busy_hash, bkt, worker, hentry) { + if (worker->current_pwq == pwq) { + has_in_flight = true; + break; + } + } + if (has_in_flight) { + bool comma = false; + + pr_info(" in-flight:"); + hash_for_each(pool->busy_hash, bkt, worker, hentry) { + if (worker->current_pwq != pwq) + continue; + + pr_cont("%s %d%s:%pf", comma ? "," : "", + task_pid_nr(worker->task), + worker == pwq->wq->rescuer ? "(RESCUER)" : "", + worker->current_func); + list_for_each_entry(work, &worker->scheduled, entry) + pr_cont_work(false, work); + comma = true; + } + pr_cont("\n"); + } + + list_for_each_entry(work, &pool->worklist, entry) { + if (get_work_pwq(work) == pwq) { + has_pending = true; + break; + } + } + if (has_pending) { + bool comma = false; + + pr_info(" pending:"); + list_for_each_entry(work, &pool->worklist, entry) { + if (get_work_pwq(work) != pwq) + continue; + + pr_cont_work(comma, work); + comma = !(*work_data_bits(work) & WORK_STRUCT_LINKED); + } + pr_cont("\n"); + } + + if (!list_empty(&pwq->delayed_works)) { + bool comma = false; + + pr_info(" delayed:"); + list_for_each_entry(work, &pwq->delayed_works, entry) { + pr_cont_work(comma, work); + comma = !(*work_data_bits(work) & WORK_STRUCT_LINKED); + } + pr_cont("\n"); + } +} + +/** + * show_workqueue_state - dump workqueue state + * + * Called from a sysrq handler and prints out all busy workqueues and + * pools. + */ +void show_workqueue_state(void) +{ + struct workqueue_struct *wq; + struct worker_pool *pool; + unsigned long flags; + int pi; + + rcu_read_lock_sched(); + + pr_info("Showing busy workqueues and worker pools:\n"); + + list_for_each_entry_rcu(wq, &workqueues, list) { + struct pool_workqueue *pwq; + bool idle = true; + + for_each_pwq(pwq, wq) { + if (pwq->nr_active || !list_empty(&pwq->delayed_works)) { + idle = false; + break; + } + } + if (idle) + continue; + + pr_info("workqueue %s: flags=0x%x\n", wq->name, wq->flags); + + for_each_pwq(pwq, wq) { + spin_lock_irqsave(&pwq->pool->lock, flags); + if (pwq->nr_active || !list_empty(&pwq->delayed_works)) + show_pwq(pwq); + spin_unlock_irqrestore(&pwq->pool->lock, flags); + } + } + + for_each_pool(pool, pi) { + struct worker *worker; + bool first = true; + + spin_lock_irqsave(&pool->lock, flags); + if (pool->nr_workers == pool->nr_idle) + goto next_pool; + + pr_info("pool %d:", pool->id); + pr_cont_pool_info(pool); + pr_cont(" workers=%d", pool->nr_workers); + if (pool->manager) + pr_cont(" manager: %d", + task_pid_nr(pool->manager->task)); + list_for_each_entry(worker, &pool->idle_list, entry) { + pr_cont(" %s%d", first ? "idle: " : "", + task_pid_nr(worker->task)); + first = false; + } + pr_cont("\n"); + next_pool: + spin_unlock_irqrestore(&pool->lock, flags); + } + + rcu_read_unlock_sched(); +} + /* * CPU hotplug. * -- GitLab From debf6d843eaa3622786c45eb6edbc46f38f31a90 Mon Sep 17 00:00:00 2001 From: Roberta Dobrescu Date: Mon, 2 Mar 2015 12:39:12 +0200 Subject: [PATCH 03509/11651] iio: accel: mma9551: Check gpiod_to_irq return value MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The return value of gpiod_to_irq should be checked before giving it to devm_request_threaded_irq in order to not pass an error code in case it fails. Signed-off-by: Roberta Dobrescu Reviewed-by: Vlad Dogaru Acked-by: Uwe Kleine-König Signed-off-by: Jonathan Cameron --- drivers/iio/accel/mma9551.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/iio/accel/mma9551.c b/drivers/iio/accel/mma9551.c index 1277f407cd12..7db7cc0bf362 100644 --- a/drivers/iio/accel/mma9551.c +++ b/drivers/iio/accel/mma9551.c @@ -425,7 +425,11 @@ static int mma9551_gpio_probe(struct iio_dev *indio_dev) return PTR_ERR(gpio); } - data->irqs[i] = gpiod_to_irq(gpio); + ret = gpiod_to_irq(gpio); + if (ret < 0) + return ret; + + data->irqs[i] = ret; ret = devm_request_threaded_irq(dev, data->irqs[i], NULL, mma9551_event_handler, IRQF_TRIGGER_RISING | IRQF_ONESHOT, -- GitLab From d1bd4867b0959d5221dc528ccf60c8534aae865d Mon Sep 17 00:00:00 2001 From: Martin Fuzzey Date: Thu, 19 Feb 2015 15:16:04 +0100 Subject: [PATCH 03510/11651] iio: doc: Describe scale attributes for event thresholds Signed-off-by: Martin Fuzzey Signed-off-by: Jonathan Cameron --- Documentation/ABI/testing/sysfs-bus-iio | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio index 9a70c31619ea..923070934228 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio +++ b/Documentation/ABI/testing/sysfs-bus-iio @@ -661,6 +661,24 @@ Description: value is in raw device units or in processed units (as _raw and _input do on sysfs direct channel read attributes). +What: /sys/.../events/in_accel_scale +What: /sys/.../events/in_accel_peak_scale +What: /sys/.../events/in_anglvel_scale +What: /sys/.../events/in_magn_scale +What: /sys/.../events/in_rot_from_north_magnetic_scale +What: /sys/.../events/in_rot_from_north_true_scale +What: /sys/.../events/in_voltage_scale +What: /sys/.../events/in_voltage_supply_scale +What: /sys/.../events/in_temp_scale +What: /sys/.../events/in_illuminance_scale +What: /sys/.../events/in_proximity_scale +KernelVersion: 3.21 +Contact: linux-iio@vger.kernel.org +Description: + Specifies the conversion factor from the standard units + to device specific units used to set the event trigger + threshold. + What: /sys/.../events/in_accel_x_thresh_rising_hysteresis What: /sys/.../events/in_accel_x_thresh_falling_hysteresis What: /sys/.../events/in_accel_x_thresh_either_hysteresis -- GitLab From 1e970b7d6d4fb3d715a34842ec00646f4b94bd72 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Mon, 2 Mar 2015 15:30:58 -0600 Subject: [PATCH 03511/11651] gpio: pxa: simplify BANK_OFF macro offset calculation The macro BANK_OFF which calculates the base offset for each GPIO port. The macro is needlessly complex and unreadable. Simplify the calculation to a simple math operation. Signed-off-by: Rob Herring Cc: linux-gpio@vger.kernel.org Reviewed-by: Alexandre Courbot Signed-off-by: Linus Walleij --- drivers/gpio/gpio-pxa.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c index 2fdb04b6f101..cdbbcf0faf9d 100644 --- a/drivers/gpio/gpio-pxa.c +++ b/drivers/gpio/gpio-pxa.c @@ -59,8 +59,7 @@ #define GAFR_OFFSET 0x54 #define ED_MASK_OFFSET 0x9C /* GPIO edge detection for AP side */ -#define BANK_OFF(n) (((n) < 3) ? (n) << 2 : ((n) > 5 ? 0x200 : 0x100) \ - + (((n) % 3) << 2)) +#define BANK_OFF(n) (((n) / 3) << 8) + (((n) % 3) << 2) int pxa_last_gpio; static int irq_base; -- GitLab From c5ae732a443e2600823b930457eaab6e25f69b32 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Wed, 4 Mar 2015 17:36:32 +0100 Subject: [PATCH 03512/11651] ppc: Remove unused cpp symbols in kvm headers These don't seem to be used anywhere. Acked-by: Rik van Riel Cc: Benjamin Herrenschmidt Cc: Alexander Graf Cc: Paul E. McKenney Cc: Andy Lutomirski Cc: Will deacon Cc: Marcelo Tosatti Cc: Christian Borntraeger Cc: Luiz Capitulino Cc: Paolo Bonzini Signed-off-by: Frederic Weisbecker --- arch/powerpc/include/asm/kvm_book3s.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h index 942c7b1678e3..993090422690 100644 --- a/arch/powerpc/include/asm/kvm_book3s.h +++ b/arch/powerpc/include/asm/kvm_book3s.h @@ -106,10 +106,6 @@ struct kvmppc_vcpu_book3s { spinlock_t mmu_lock; }; -#define CONTEXT_HOST 0 -#define CONTEXT_GUEST 1 -#define CONTEXT_GUEST_END 2 - #define VSID_REAL 0x07ffffffffc00000ULL #define VSID_BAT 0x07ffffffffb00000ULL #define VSID_64K 0x0800000000000000ULL -- GitLab From c467ea763fd5d8795b7d1b5a78eb94b6ad8f66ad Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Wed, 4 Mar 2015 18:06:33 +0100 Subject: [PATCH 03513/11651] context_tracking: Rename context symbols to prepare for transition state Current context tracking symbols are designed to express living state. As such they are prefixed with "IN_": IN_USER, IN_KERNEL. Now we are going to use these symbols to also express state transitions such as context_tracking_enter(IN_USER) or context_tracking_exit(IN_USER). But while the "IN_" prefix works well to express entering a context, it's confusing to depict a context exit: context_tracking_exit(IN_USER) could mean two things: 1) We are exiting the current context to enter user context. 2) We are exiting the user context We want 2) but the reviewer may be confused and understand 1) So lets disambiguate these symbols and rename them to CONTEXT_USER and CONTEXT_KERNEL. Acked-by: Rik van Riel Cc: Paul E. McKenney Cc: Andy Lutomirski Cc: Will deacon Cc: Marcelo Tosatti Cc: Christian Borntraeger Cc: Luiz Capitulino Cc: Paolo Bonzini Signed-off-by: Frederic Weisbecker --- arch/x86/kernel/traps.c | 2 +- include/linux/context_tracking.h | 2 +- include/linux/context_tracking_state.h | 6 +++--- kernel/context_tracking.c | 8 ++++---- kernel/sched/core.c | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 9d2073e2ecc9..756f74eed35d 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -123,7 +123,7 @@ enum ctx_state ist_enter(struct pt_regs *regs) * but we need to notify RCU. */ rcu_nmi_enter(); - prev_state = IN_KERNEL; /* the value is irrelevant. */ + prev_state = CONTEXT_KERNEL; /* the value is irrelevant. */ } /* diff --git a/include/linux/context_tracking.h b/include/linux/context_tracking.h index 37b81bd51ec0..427b056dfd3d 100644 --- a/include/linux/context_tracking.h +++ b/include/linux/context_tracking.h @@ -43,7 +43,7 @@ static inline enum ctx_state exception_enter(void) static inline void exception_exit(enum ctx_state prev_ctx) { if (context_tracking_is_enabled()) { - if (prev_ctx == IN_USER) + if (prev_ctx == CONTEXT_USER) context_tracking_user_enter(); } } diff --git a/include/linux/context_tracking_state.h b/include/linux/context_tracking_state.h index 97a81225d037..8076f875c324 100644 --- a/include/linux/context_tracking_state.h +++ b/include/linux/context_tracking_state.h @@ -13,8 +13,8 @@ struct context_tracking { */ bool active; enum ctx_state { - IN_KERNEL = 0, - IN_USER, + CONTEXT_KERNEL = 0, + CONTEXT_USER, } state; }; @@ -34,7 +34,7 @@ static inline bool context_tracking_cpu_is_enabled(void) static inline bool context_tracking_in_user(void) { - return __this_cpu_read(context_tracking.state) == IN_USER; + return __this_cpu_read(context_tracking.state) == CONTEXT_USER; } #else static inline bool context_tracking_in_user(void) { return false; } diff --git a/kernel/context_tracking.c b/kernel/context_tracking.c index 937ecdfdf258..8ad53c9d38b6 100644 --- a/kernel/context_tracking.c +++ b/kernel/context_tracking.c @@ -75,7 +75,7 @@ void context_tracking_user_enter(void) WARN_ON_ONCE(!current->mm); local_irq_save(flags); - if ( __this_cpu_read(context_tracking.state) != IN_USER) { + if ( __this_cpu_read(context_tracking.state) != CONTEXT_USER) { if (__this_cpu_read(context_tracking.active)) { trace_user_enter(0); /* @@ -101,7 +101,7 @@ void context_tracking_user_enter(void) * OTOH we can spare the calls to vtime and RCU when context_tracking.active * is false because we know that CPU is not tickless. */ - __this_cpu_write(context_tracking.state, IN_USER); + __this_cpu_write(context_tracking.state, CONTEXT_USER); } local_irq_restore(flags); } @@ -129,7 +129,7 @@ void context_tracking_user_exit(void) return; local_irq_save(flags); - if (__this_cpu_read(context_tracking.state) == IN_USER) { + if (__this_cpu_read(context_tracking.state) == CONTEXT_USER) { if (__this_cpu_read(context_tracking.active)) { /* * We are going to run code that may use RCU. Inform @@ -139,7 +139,7 @@ void context_tracking_user_exit(void) vtime_user_exit(current); trace_user_exit(0); } - __this_cpu_write(context_tracking.state, IN_KERNEL); + __this_cpu_write(context_tracking.state, CONTEXT_KERNEL); } local_irq_restore(flags); } diff --git a/kernel/sched/core.c b/kernel/sched/core.c index f0f831e8a345..06b9a00871e0 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -2818,7 +2818,7 @@ asmlinkage __visible void __sched schedule_user(void) * we find a better solution. * * NB: There are buggy callers of this function. Ideally we - * should warn if prev_state != IN_USER, but that will trigger + * should warn if prev_state != CONTEXT_USER, but that will trigger * too frequently to make sense yet. */ enum ctx_state prev_state = exception_enter(); -- GitLab From 3aab4f50bff89bdea5066a05d4f3c5fa25bc37c7 Mon Sep 17 00:00:00 2001 From: Rik van Riel Date: Tue, 10 Feb 2015 15:27:50 -0500 Subject: [PATCH 03514/11651] context_tracking: Generalize context tracking APIs to support user and guest Generalize the context tracking APIs to support various nature of contexts. This is performed by splitting out the mechanism from context_tracking_user_enter and context_tracking_user_exit into context_tracking_enter and context_tracking_exit. The nature of the context we track is now detailed in a ctx_state parameter pushed to these APIs, allowing the same functions to not just track kernel <> user space switching, but also kernel <> guest transitions. But leave the old functions in order to avoid breaking ARM, which calls these functions from assembler code, and cannot easily use C enum parameters. Reviewed-by: Paul E. McKenney Signed-off-by: Rik van Riel Cc: Paul E. McKenney Cc: Andy Lutomirski Cc: Will deacon Cc: Marcelo Tosatti Cc: Christian Borntraeger Cc: Luiz Capitulino Cc: Paolo Bonzini Signed-off-by: Frederic Weisbecker --- include/linux/context_tracking.h | 9 ++++--- kernel/context_tracking.c | 43 +++++++++++++++++++++----------- 2 files changed, 34 insertions(+), 18 deletions(-) diff --git a/include/linux/context_tracking.h b/include/linux/context_tracking.h index 427b056dfd3d..7f1810a3b5a4 100644 --- a/include/linux/context_tracking.h +++ b/include/linux/context_tracking.h @@ -10,6 +10,8 @@ #ifdef CONFIG_CONTEXT_TRACKING extern void context_tracking_cpu_set(int cpu); +extern void context_tracking_enter(enum ctx_state state); +extern void context_tracking_exit(enum ctx_state state); extern void context_tracking_user_enter(void); extern void context_tracking_user_exit(void); extern void __context_tracking_task_switch(struct task_struct *prev, @@ -35,7 +37,8 @@ static inline enum ctx_state exception_enter(void) return 0; prev_ctx = this_cpu_read(context_tracking.state); - context_tracking_user_exit(); + if (prev_ctx != CONTEXT_KERNEL) + context_tracking_exit(prev_ctx); return prev_ctx; } @@ -43,8 +46,8 @@ static inline enum ctx_state exception_enter(void) static inline void exception_exit(enum ctx_state prev_ctx) { if (context_tracking_is_enabled()) { - if (prev_ctx == CONTEXT_USER) - context_tracking_user_enter(); + if (prev_ctx != CONTEXT_KERNEL) + context_tracking_enter(prev_ctx); } } diff --git a/kernel/context_tracking.c b/kernel/context_tracking.c index 8ad53c9d38b6..17715d811b71 100644 --- a/kernel/context_tracking.c +++ b/kernel/context_tracking.c @@ -39,15 +39,15 @@ void context_tracking_cpu_set(int cpu) } /** - * context_tracking_user_enter - Inform the context tracking that the CPU is going to - * enter userspace mode. + * context_tracking_enter - Inform the context tracking that the CPU is going + * enter user or guest space mode. * * This function must be called right before we switch from the kernel - * to userspace, when it's guaranteed the remaining kernel instructions - * to execute won't use any RCU read side critical section because this - * function sets RCU in extended quiescent state. + * to user or guest space, when it's guaranteed the remaining kernel + * instructions to execute won't use any RCU read side critical section + * because this function sets RCU in extended quiescent state. */ -void context_tracking_user_enter(void) +void context_tracking_enter(enum ctx_state state) { unsigned long flags; @@ -75,7 +75,7 @@ void context_tracking_user_enter(void) WARN_ON_ONCE(!current->mm); local_irq_save(flags); - if ( __this_cpu_read(context_tracking.state) != CONTEXT_USER) { + if ( __this_cpu_read(context_tracking.state) != state) { if (__this_cpu_read(context_tracking.active)) { trace_user_enter(0); /* @@ -101,24 +101,31 @@ void context_tracking_user_enter(void) * OTOH we can spare the calls to vtime and RCU when context_tracking.active * is false because we know that CPU is not tickless. */ - __this_cpu_write(context_tracking.state, CONTEXT_USER); + __this_cpu_write(context_tracking.state, state); } local_irq_restore(flags); } +NOKPROBE_SYMBOL(context_tracking_enter); + +void context_tracking_user_enter(void) +{ + context_tracking_enter(CONTEXT_USER); +} NOKPROBE_SYMBOL(context_tracking_user_enter); /** - * context_tracking_user_exit - Inform the context tracking that the CPU is - * exiting userspace mode and entering the kernel. + * context_tracking_exit - Inform the context tracking that the CPU is + * exiting user or guest mode and entering the kernel. * - * This function must be called after we entered the kernel from userspace - * before any use of RCU read side critical section. This potentially include - * any high level kernel code like syscalls, exceptions, signal handling, etc... + * This function must be called after we entered the kernel from user or + * guest space before any use of RCU read side critical section. This + * potentially include any high level kernel code like syscalls, exceptions, + * signal handling, etc... * * This call supports re-entrancy. This way it can be called from any exception * handler without needing to know if we came from userspace or not. */ -void context_tracking_user_exit(void) +void context_tracking_exit(enum ctx_state state) { unsigned long flags; @@ -129,7 +136,7 @@ void context_tracking_user_exit(void) return; local_irq_save(flags); - if (__this_cpu_read(context_tracking.state) == CONTEXT_USER) { + if (__this_cpu_read(context_tracking.state) == state) { if (__this_cpu_read(context_tracking.active)) { /* * We are going to run code that may use RCU. Inform @@ -143,6 +150,12 @@ void context_tracking_user_exit(void) } local_irq_restore(flags); } +NOKPROBE_SYMBOL(context_tracking_exit); + +void context_tracking_user_exit(void) +{ + context_tracking_exit(CONTEXT_USER); +} NOKPROBE_SYMBOL(context_tracking_user_exit); /** -- GitLab From a3a9c7dff25791f3a1041aa96e770af662d99a35 Mon Sep 17 00:00:00 2001 From: Rik van Riel Date: Tue, 10 Feb 2015 15:27:51 -0500 Subject: [PATCH 03515/11651] context_tracking: Add stub context_tracking_is_enabled With code elsewhere doing something conditional on whether or not context tracking is enabled, we want a stub function that tells us context tracking is not enabled, when CONFIG_CONTEXT_TRACKING is not set. Reviewed-by: Paul E. McKenney Signed-off-by: Rik van Riel Cc: Paul E. McKenney Cc: Andy Lutomirski Cc: Will deacon Cc: Marcelo Tosatti Cc: Christian Borntraeger Cc: Luiz Capitulino Cc: Paolo Bonzini Signed-off-by: Frederic Weisbecker --- include/linux/context_tracking_state.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/context_tracking_state.h b/include/linux/context_tracking_state.h index 8076f875c324..ad4458588b47 100644 --- a/include/linux/context_tracking_state.h +++ b/include/linux/context_tracking_state.h @@ -39,6 +39,8 @@ static inline bool context_tracking_in_user(void) #else static inline bool context_tracking_in_user(void) { return false; } static inline bool context_tracking_active(void) { return false; } +static inline bool context_tracking_is_enabled(void) { return false; } +static inline bool context_tracking_cpu_is_enabled(void) { return false; } #endif /* CONFIG_CONTEXT_TRACKING */ #endif -- GitLab From 19fdd98b6253404c6bdd6927bde9f962729376f7 Mon Sep 17 00:00:00 2001 From: Rik van Riel Date: Tue, 10 Feb 2015 15:27:52 -0500 Subject: [PATCH 03516/11651] context_tracking: Run vtime_user_enter/exit only when state == CONTEXT_USER Only run vtime_user_enter, vtime_user_exit, and the user enter & exit trace points when we are entering or exiting user state, respectively. The KVM code in guest_enter and guest_exit already take care of calling vtime_guest_enter and vtime_guest_exit, respectively. The RCU code only distinguishes between "idle" and "not idle or kernel". There should be no need to add an additional (unused) state there. Reviewed-by: Paul E. McKenney Signed-off-by: Rik van Riel Cc: Paul E. McKenney Cc: Andy Lutomirski Cc: Will deacon Cc: Marcelo Tosatti Cc: Christian Borntraeger Cc: Luiz Capitulino Cc: Paolo Bonzini Signed-off-by: Frederic Weisbecker --- kernel/context_tracking.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/kernel/context_tracking.c b/kernel/context_tracking.c index 17715d811b71..a2c0866384e8 100644 --- a/kernel/context_tracking.c +++ b/kernel/context_tracking.c @@ -77,7 +77,6 @@ void context_tracking_enter(enum ctx_state state) local_irq_save(flags); if ( __this_cpu_read(context_tracking.state) != state) { if (__this_cpu_read(context_tracking.active)) { - trace_user_enter(0); /* * At this stage, only low level arch entry code remains and * then we'll run in userspace. We can assume there won't be @@ -85,7 +84,10 @@ void context_tracking_enter(enum ctx_state state) * user_exit() or rcu_irq_enter(). Let's remove RCU's dependency * on the tick. */ - vtime_user_enter(current); + if (state == CONTEXT_USER) { + trace_user_enter(0); + vtime_user_enter(current); + } rcu_user_enter(); } /* @@ -143,8 +145,10 @@ void context_tracking_exit(enum ctx_state state) * RCU core about that (ie: we may need the tick again). */ rcu_user_exit(); - vtime_user_exit(current); - trace_user_exit(0); + if (state == CONTEXT_USER) { + vtime_user_exit(current); + trace_user_exit(0); + } } __this_cpu_write(context_tracking.state, CONTEXT_KERNEL); } -- GitLab From efc1e2c9bcbab73797d7bc214014cb916d6a8eb5 Mon Sep 17 00:00:00 2001 From: Rik van Riel Date: Tue, 10 Feb 2015 15:27:53 -0500 Subject: [PATCH 03517/11651] context_tracking: Export context_tracking_user_enter/exit Export context_tracking_user_enter/exit so it can be used by KVM. Reviewed-by: Paul E. McKenney Signed-off-by: Rik van Riel Cc: Paul E. McKenney Cc: Andy Lutomirski Cc: Will deacon Cc: Marcelo Tosatti Cc: Christian Borntraeger Cc: Luiz Capitulino Cc: Paolo Bonzini Signed-off-by: Frederic Weisbecker --- kernel/context_tracking.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/context_tracking.c b/kernel/context_tracking.c index a2c0866384e8..72d59a1a6eb6 100644 --- a/kernel/context_tracking.c +++ b/kernel/context_tracking.c @@ -108,6 +108,7 @@ void context_tracking_enter(enum ctx_state state) local_irq_restore(flags); } NOKPROBE_SYMBOL(context_tracking_enter); +EXPORT_SYMBOL_GPL(context_tracking_enter); void context_tracking_user_enter(void) { @@ -155,6 +156,7 @@ void context_tracking_exit(enum ctx_state state) local_irq_restore(flags); } NOKPROBE_SYMBOL(context_tracking_exit); +EXPORT_SYMBOL_GPL(context_tracking_exit); void context_tracking_user_exit(void) { -- GitLab From 126a6a542446f1a49b9f3c69237c87df3eb4e6e1 Mon Sep 17 00:00:00 2001 From: Rik van Riel Date: Tue, 10 Feb 2015 15:27:54 -0500 Subject: [PATCH 03518/11651] kvm,rcu,nohz: use RCU extended quiescent state when running KVM guest The host kernel is not doing anything while the CPU is executing a KVM guest VCPU, so it can be marked as being in an extended quiescent state, identical to that used when running user space code. The only exception to that rule is when the host handles an interrupt, which is already handled by the irq code, which calls rcu_irq_enter and rcu_irq_exit. The guest_enter and guest_exit functions already switch vtime accounting independent of context tracking. Leave those calls where they are, instead of moving them into the context tracking code. Reviewed-by: Paul E. McKenney Signed-off-by: Rik van Riel Cc: Paul E. McKenney Cc: Andy Lutomirski Cc: Will deacon Cc: Marcelo Tosatti Cc: Christian Borntraeger Cc: Luiz Capitulino Cc: Paolo Bonzini Signed-off-by: Frederic Weisbecker --- include/linux/context_tracking.h | 6 ++++++ include/linux/context_tracking_state.h | 1 + include/linux/kvm_host.h | 3 ++- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/include/linux/context_tracking.h b/include/linux/context_tracking.h index 7f1810a3b5a4..2821838256b4 100644 --- a/include/linux/context_tracking.h +++ b/include/linux/context_tracking.h @@ -81,10 +81,16 @@ static inline void guest_enter(void) vtime_guest_enter(current); else current->flags |= PF_VCPU; + + if (context_tracking_is_enabled()) + context_tracking_enter(CONTEXT_GUEST); } static inline void guest_exit(void) { + if (context_tracking_is_enabled()) + context_tracking_exit(CONTEXT_GUEST); + if (vtime_accounting_enabled()) vtime_guest_exit(current); else diff --git a/include/linux/context_tracking_state.h b/include/linux/context_tracking_state.h index ad4458588b47..6b7b96a32b75 100644 --- a/include/linux/context_tracking_state.h +++ b/include/linux/context_tracking_state.h @@ -15,6 +15,7 @@ struct context_tracking { enum ctx_state { CONTEXT_KERNEL = 0, CONTEXT_USER, + CONTEXT_GUEST, } state; }; diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index d12b2104d19b..cc8c61c5459c 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -766,7 +766,8 @@ static inline void kvm_guest_enter(void) * one time slice). Lets treat guest mode as quiescent state, just like * we do with user-mode execution. */ - rcu_virt_note_context_switch(smp_processor_id()); + if (!context_tracking_cpu_is_enabled()) + rcu_virt_note_context_switch(smp_processor_id()); } static inline void kvm_guest_exit(void) -- GitLab From 4e5a800c82ec21335349a97cf58d97fbb0d3c98e Mon Sep 17 00:00:00 2001 From: Nicholas Mc Guire Date: Wed, 4 Feb 2015 13:30:20 -0500 Subject: [PATCH 03519/11651] ncr5380: Harmonize jiffies conversion with msecs_to_jiffies Instances of var * HZ / 1000 are replaced by msecs_to_jiffies(var). In addition some timing constants that assumed HZ 100 were adjusted to HZ independent settings based on review comments from Michael Schmitz and review of the original drivers in 1.0.31 and 2.2.16. Signed-off-by: Nicholas Mc Guire Acked-by: Michael Schmitz Signed-off-by: Finn Thain Signed-off-by: James Bottomley --- drivers/scsi/NCR5380.c | 10 +++++----- drivers/scsi/atari_NCR5380.c | 2 +- drivers/scsi/g_NCR5380.c | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c index 8981701802ca..a777e5c412df 100644 --- a/drivers/scsi/NCR5380.c +++ b/drivers/scsi/NCR5380.c @@ -474,11 +474,11 @@ static void NCR5380_print_phase(struct Scsi_Host *instance) */ #ifndef USLEEP_SLEEP /* 20 ms (reasonable hard disk speed) */ -#define USLEEP_SLEEP (20*HZ/1000) +#define USLEEP_SLEEP msecs_to_jiffies(20) #endif /* 300 RPM (floppy speed) */ #ifndef USLEEP_POLL -#define USLEEP_POLL (200*HZ/1000) +#define USLEEP_POLL msecs_to_jiffies(200) #endif #ifndef USLEEP_WAITLONG /* RvC: (reasonable time to wait on select error) */ @@ -576,7 +576,7 @@ static int __init __maybe_unused NCR5380_probe_irq(struct Scsi_Host *instance, if ((mask & possible) && (request_irq(i, &probe_intr, 0, "NCR-probe", NULL) == 0)) trying_irqs |= mask; - timeout = jiffies + (250 * HZ / 1000); + timeout = jiffies + msecs_to_jiffies(250); probe_irq = NO_IRQ; /* @@ -634,7 +634,7 @@ static void prepare_info(struct Scsi_Host *instance) "sg_tablesize %d, this_id %d, " "flags { %s%s%s}, " #if defined(USLEEP_POLL) && defined(USLEEP_WAITLONG) - "USLEEP_POLL %d, USLEEP_WAITLONG %d, " + "USLEEP_POLL %lu, USLEEP_WAITLONG %lu, " #endif "options { %s} ", instance->hostt->name, instance->io_port, instance->n_io_port, @@ -1346,7 +1346,7 @@ static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd) * selection. */ - timeout = jiffies + (250 * HZ / 1000); + timeout = jiffies + msecs_to_jiffies(250); /* * XXX very interesting - we're seeing a bounce where the BSY we diff --git a/drivers/scsi/atari_NCR5380.c b/drivers/scsi/atari_NCR5380.c index a70255413e7f..db87ece6edb2 100644 --- a/drivers/scsi/atari_NCR5380.c +++ b/drivers/scsi/atari_NCR5380.c @@ -1486,7 +1486,7 @@ static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd) * selection. */ - timeout = jiffies + (250 * HZ / 1000); + timeout = jiffies + msecs_to_jiffies(250); /* * XXX very interesting - we're seeing a bounce where the BSY we diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c index 74ec2f5669ab..f8d2478b11cc 100644 --- a/drivers/scsi/g_NCR5380.c +++ b/drivers/scsi/g_NCR5380.c @@ -57,9 +57,9 @@ */ /* settings for DTC3181E card with only Mustek scanner attached */ -#define USLEEP_POLL 1 -#define USLEEP_SLEEP 20 -#define USLEEP_WAITLONG 500 +#define USLEEP_POLL msecs_to_jiffies(10) +#define USLEEP_SLEEP msecs_to_jiffies(200) +#define USLEEP_WAITLONG msecs_to_jiffies(5000) #define AUTOPROBE_IRQ -- GitLab From 39521090e93671c01fbc50d47b6422c2b0aa63b1 Mon Sep 17 00:00:00 2001 From: Josh Wu Date: Wed, 4 Mar 2015 11:50:29 +0800 Subject: [PATCH 03520/11651] gpio: mrvl: documentation: trivial: fix typo fix typo in the document. Signed-off-by: Josh Wu Signed-off-by: Linus Walleij --- Documentation/devicetree/bindings/gpio/mrvl-gpio.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/gpio/mrvl-gpio.txt b/Documentation/devicetree/bindings/gpio/mrvl-gpio.txt index 67a2e4e414a5..98d198396956 100644 --- a/Documentation/devicetree/bindings/gpio/mrvl-gpio.txt +++ b/Documentation/devicetree/bindings/gpio/mrvl-gpio.txt @@ -12,7 +12,7 @@ Required properties: gpio_mux. - interrupt-names : Should be the names of irq resources. Each interrupt uses its own interrupt name, so there should be as many interrupt names - as referenced interrups. + as referenced interrupts. - interrupt-controller : Identifies the node as an interrupt controller. - #interrupt-cells: Specifies the number of cells needed to encode an interrupt source. -- GitLab From b24d443b8f17d9776f5fc1f6c780a0a21eb02913 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Wed, 4 Mar 2015 23:10:28 -0500 Subject: [PATCH 03521/11651] ftrace: Clear REGS_EN and TRAMP_EN flags on disabling record via sysctl When /proc/sys/kernel/ftrace_enabled is set to zero, all function tracing is disabled. But the records that represent the functions still hold information about the ftrace_ops that are hooked to them. ftrace_ops may request "REGS" (have a full set of pt_regs passed to the callback), or "TRAMP" (the ops has its own trampoline to use). When the record is updated to represent the state of the ops hooked to it, it sets "REGS_EN" and/or "TRAMP_EN" to state that the callback points to the correct trampoline (REGS has its own trampoline). When ftrace_enabled is set to zero, all ftrace locations are a nop, so they do not point to any trampoline. But the _EN flags are still set. This can cause the accounting to go wrong when ftrace_enabled is cleared and an ops that has a trampoline is registered or unregistered. For example, the following will cause ftrace to crash: # echo function_graph > /sys/kernel/debug/tracing/current_tracer # echo 0 > /proc/sys/kernel/ftrace_enabled # echo nop > /sys/kernel/debug/tracing/current_tracer # echo 1 > /proc/sys/kernel/ftrace_enabled # echo function_graph > /sys/kernel/debug/tracing/current_tracer As function_graph uses a trampoline, when ftrace_enabled is set to zero the updates to the record are not done. When enabling function_graph again, the record will still have the TRAMP_EN flag set, and it will look for an op that has a trampoline other than the function_graph ops, and fail to find one. Cc: stable@vger.kernel.org # 3.17+ Reported-by: Pratyush Anand Signed-off-by: Steven Rostedt --- kernel/trace/ftrace.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 45e5cb143d17..14947e014b78 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -2041,8 +2041,12 @@ static int ftrace_check_record(struct dyn_ftrace *rec, int enable, int update) if (!ftrace_rec_count(rec)) rec->flags = 0; else - /* Just disable the record (keep REGS state) */ - rec->flags &= ~FTRACE_FL_ENABLED; + /* + * Just disable the record, but keep the ops TRAMP + * and REGS states. The _EN flags must be disabled though. + */ + rec->flags &= ~(FTRACE_FL_ENABLED | FTRACE_FL_TRAMP_EN | + FTRACE_FL_REGS_EN); } return FTRACE_UPDATE_MAKE_NOP; -- GitLab From 1619dc3f8f555ee1cdd3c75db3885d5715442b12 Mon Sep 17 00:00:00 2001 From: Pratyush Anand Date: Fri, 6 Mar 2015 23:58:06 +0530 Subject: [PATCH 03522/11651] ftrace: Fix en(dis)able graph caller when en(dis)abling record via sysctl When ftrace is enabled globally through the proc interface, we must check if ftrace_graph_active is set. If it is set, then we should also pass the FTRACE_START_FUNC_RET command to ftrace_run_update_code(). Similarly, when ftrace is disabled globally through the proc interface, we must check if ftrace_graph_active is set. If it is set, then we should also pass the FTRACE_STOP_FUNC_RET command to ftrace_run_update_code(). Consider the following situation. # echo 0 > /proc/sys/kernel/ftrace_enabled After this ftrace_enabled = 0. # echo function_graph > /sys/kernel/debug/tracing/current_tracer Since ftrace_enabled = 0, ftrace_enable_ftrace_graph_caller() is never called. # echo 1 > /proc/sys/kernel/ftrace_enabled Now ftrace_enabled will be set to true, but still ftrace_enable_ftrace_graph_caller() will not be called, which is not desired. Further if we execute the following after this: # echo nop > /sys/kernel/debug/tracing/current_tracer Now since ftrace_enabled is set it will call ftrace_disable_ftrace_graph_caller(), which causes a kernel warning on the ARM platform. On the ARM platform, when ftrace_enable_ftrace_graph_caller() is called, it checks whether the old instruction is a nop or not. If it's not a nop, then it returns an error. If it is a nop then it replaces instruction at that address with a branch to ftrace_graph_caller. ftrace_disable_ftrace_graph_caller() behaves just the opposite. Therefore, if generic ftrace code ever calls either ftrace_enable_ftrace_graph_caller() or ftrace_disable_ftrace_graph_caller() consecutively two times in a row, then it will return an error, which will cause the generic ftrace code to raise a warning. Note, x86 does not have an issue with this because the architecture specific code for ftrace_enable_ftrace_graph_caller() and ftrace_disable_ftrace_graph_caller() does not check the previous state, and calling either of these functions twice in a row has no ill effect. Link: http://lkml.kernel.org/r/e4fbe64cdac0dd0e86a3bf914b0f83c0b419f146.1425666454.git.panand@redhat.com Cc: stable@vger.kernel.org # 2.6.31+ Signed-off-by: Pratyush Anand [ removed extra if (ftrace_start_up) and defined ftrace_graph_active as 0 if CONFIG_FUNCTION_GRAPH_TRACER is not set. ] Signed-off-by: Steven Rostedt --- kernel/trace/ftrace.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 14947e014b78..ea520bb54d44 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -1059,6 +1059,12 @@ static __init void ftrace_profile_debugfs(struct dentry *d_tracer) static struct pid * const ftrace_swapper_pid = &init_struct_pid; +#ifdef CONFIG_FUNCTION_GRAPH_TRACER +static int ftrace_graph_active; +#else +# define ftrace_graph_active 0 +#endif + #ifdef CONFIG_DYNAMIC_FTRACE static struct ftrace_ops *removed_ops; @@ -2692,24 +2698,36 @@ static int ftrace_shutdown(struct ftrace_ops *ops, int command) static void ftrace_startup_sysctl(void) { + int command; + if (unlikely(ftrace_disabled)) return; /* Force update next time */ saved_ftrace_func = NULL; /* ftrace_start_up is true if we want ftrace running */ - if (ftrace_start_up) - ftrace_run_update_code(FTRACE_UPDATE_CALLS); + if (ftrace_start_up) { + command = FTRACE_UPDATE_CALLS; + if (ftrace_graph_active) + command |= FTRACE_START_FUNC_RET; + ftrace_run_update_code(command); + } } static void ftrace_shutdown_sysctl(void) { + int command; + if (unlikely(ftrace_disabled)) return; /* ftrace_start_up is true if ftrace is running */ - if (ftrace_start_up) - ftrace_run_update_code(FTRACE_DISABLE_CALLS); + if (ftrace_start_up) { + command = FTRACE_DISABLE_CALLS; + if (ftrace_graph_active) + command |= FTRACE_STOP_FUNC_RET; + ftrace_run_update_code(command); + } } static cycle_t ftrace_update_time; @@ -5594,8 +5612,6 @@ static struct ftrace_ops graph_ops = { ASSIGN_OPS_HASH(graph_ops, &global_ops.local_hash) }; -static int ftrace_graph_active; - int ftrace_graph_entry_stub(struct ftrace_graph_ent *trace) { return 0; -- GitLab From 60d3e3bbd5992bb4478f9f99a4e4c5748a1a1ba7 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 24 Feb 2015 13:24:41 +1100 Subject: [PATCH 03523/11651] iio: gyro: itg3200: add suspend/resume support. Unless we put the device to sleep when not it use, it wastes 6mA. If the device is asleep on probe, the 'id' register sometimes mis-reads - so reset first. If the device responds at all a command sent to the address, it is almost certainly the correct device already. Acked-by: Manuel Stahl Acked-by: Hartmut Knaack Signed-off-by: NeilBrown Signed-off-by: Jonathan Cameron --- drivers/iio/gyro/itg3200_core.c | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/drivers/iio/gyro/itg3200_core.c b/drivers/iio/gyro/itg3200_core.c index 6a8020d48140..f0fd94055d88 100644 --- a/drivers/iio/gyro/itg3200_core.c +++ b/drivers/iio/gyro/itg3200_core.c @@ -223,6 +223,10 @@ static int itg3200_initial_setup(struct iio_dev *indio_dev) int ret; u8 val; + ret = itg3200_reset(indio_dev); + if (ret) + goto err_ret; + ret = itg3200_read_reg_8(indio_dev, ITG3200_REG_ADDRESS, &val); if (ret) goto err_ret; @@ -233,10 +237,6 @@ static int itg3200_initial_setup(struct iio_dev *indio_dev) goto err_ret; } - ret = itg3200_reset(indio_dev); - if (ret) - goto err_ret; - ret = itg3200_enable_full_scale(indio_dev); err_ret: return ret; @@ -351,6 +351,26 @@ static int itg3200_remove(struct i2c_client *client) return 0; } +static int __maybe_unused itg3200_suspend(struct device *dev) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct itg3200 *st = iio_priv(indio_dev); + + dev_dbg(&st->i2c->dev, "suspend device"); + + return itg3200_write_reg_8(indio_dev, ITG3200_REG_POWER_MANAGEMENT, + ITG3200_SLEEP); +} + +static int __maybe_unused itg3200_resume(struct device *dev) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + + return itg3200_initial_setup(indio_dev); +} + +static SIMPLE_DEV_PM_OPS(itg3200_pm_ops, itg3200_suspend, itg3200_resume); + static const struct i2c_device_id itg3200_id[] = { { "itg3200", 0 }, { } @@ -361,6 +381,7 @@ static struct i2c_driver itg3200_driver = { .driver = { .owner = THIS_MODULE, .name = "itg3200", + .pm = &itg3200_pm_ops, }, .id_table = itg3200_id, .probe = itg3200_probe, -- GitLab From 524a38682573b2e15ab6317ccfe50280441514be Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Fri, 6 Mar 2015 19:55:13 -0500 Subject: [PATCH 03524/11651] ftrace: Fix ftrace enable ordering of sysctl ftrace_enabled Some archs (specifically PowerPC), are sensitive with the ordering of the enabling of the calls to function tracing and setting of the function to use to be traced. That is, update_ftrace_function() sets what function the ftrace_caller trampoline should call. Some archs require this to be set before calling ftrace_run_update_code(). Another bug was discovered, that ftrace_startup_sysctl() called ftrace_run_update_code() directly. If the function the ftrace_caller trampoline changes, then it will not be updated. Instead a call to ftrace_startup_enable() should be called because it tests to see if the callback changed since the code was disabled, and will tell the arch to update appropriately. Most archs do not need this notification, but PowerPC does. The problem could be seen by the following commands: # echo 0 > /proc/sys/kernel/ftrace_enabled # echo function > /sys/kernel/debug/tracing/current_tracer # echo 1 > /proc/sys/kernel/ftrace_enabled # cat /sys/kernel/debug/tracing/trace The trace will show that function tracing was not active. Cc: stable@vger.kernel.org # 2.6.27+ Signed-off-by: Steven Rostedt --- kernel/trace/ftrace.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index ea520bb54d44..4f228024055b 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -2710,7 +2710,7 @@ static void ftrace_startup_sysctl(void) command = FTRACE_UPDATE_CALLS; if (ftrace_graph_active) command |= FTRACE_START_FUNC_RET; - ftrace_run_update_code(command); + ftrace_startup_enable(command); } } @@ -5580,12 +5580,12 @@ ftrace_enable_sysctl(struct ctl_table *table, int write, if (ftrace_enabled) { - ftrace_startup_sysctl(); - /* we are starting ftrace again */ if (ftrace_ops_list != &ftrace_list_end) update_ftrace_function(); + ftrace_startup_sysctl(); + } else { /* stopping ftrace calls (just send to ftrace_stub) */ ftrace_trace_function = ftrace_stub; -- GitLab From c7586584c6fd4212e3eb2e83e5cf3c043ddf72be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vianney=20le=20Cl=C3=A9ment=20de=20Saint-Marcq?= Date: Wed, 25 Feb 2015 16:55:06 +0100 Subject: [PATCH 03525/11651] iio: mlx90614: Refactor register symbols MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The defined registers only make sense when used for accessing RAM. Make MLX90614_OP_RAM part of the symbol definition to avoid accidental access to the wrong register. Signed-off-by: Vianney le Clément de Saint-Marcq Cc: Arnout Vandecappelle (Essensium/Mind) Signed-off-by: Jonathan Cameron --- drivers/iio/temperature/mlx90614.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/iio/temperature/mlx90614.c b/drivers/iio/temperature/mlx90614.c index c8b6ac8b2d69..e2c6f1a0d27f 100644 --- a/drivers/iio/temperature/mlx90614.c +++ b/drivers/iio/temperature/mlx90614.c @@ -23,8 +23,8 @@ #define MLX90614_OP_RAM 0x00 /* RAM offsets with 16-bit data, MSB first */ -#define MLX90614_TA 0x06 /* ambient temperature */ -#define MLX90614_TOBJ1 0x07 /* object temperature */ +#define MLX90614_TA (MLX90614_OP_RAM | 0x06) /* ambient temperature */ +#define MLX90614_TOBJ1 (MLX90614_OP_RAM | 0x07) /* object 1 temperature */ struct mlx90614_data { struct i2c_client *client; @@ -42,13 +42,13 @@ static int mlx90614_read_raw(struct iio_dev *indio_dev, switch (channel->channel2) { case IIO_MOD_TEMP_AMBIENT: ret = i2c_smbus_read_word_data(data->client, - MLX90614_OP_RAM | MLX90614_TA); + MLX90614_TA); if (ret < 0) return ret; break; case IIO_MOD_TEMP_OBJECT: ret = i2c_smbus_read_word_data(data->client, - MLX90614_OP_RAM | MLX90614_TOBJ1); + MLX90614_TOBJ1); if (ret < 0) return ret; break; -- GitLab From d5638fcf15bc65584877f00d4b0094cc4a66ad4e Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 2 Feb 2015 17:14:12 -0600 Subject: [PATCH 03526/11651] usb: musb: gadget: get rid of stop_activity() that function is pretty close to a no-op by now, all we need is a call to musb_stop(). Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_gadget.c | 40 +--------------------------------- 1 file changed, 1 insertion(+), 39 deletions(-) diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index b2d9040c7685..4c481cd66c77 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -1876,44 +1876,6 @@ err: return retval; } -static void stop_activity(struct musb *musb, struct usb_gadget_driver *driver) -{ - int i; - struct musb_hw_ep *hw_ep; - - /* don't disconnect if it's not connected */ - if (musb->g.speed == USB_SPEED_UNKNOWN) - driver = NULL; - else - musb->g.speed = USB_SPEED_UNKNOWN; - - /* deactivate the hardware */ - if (musb->softconnect) { - musb->softconnect = 0; - musb_pullup(musb, 0); - } - musb_stop(musb); - - /* killing any outstanding requests will quiesce the driver; - * then report disconnect - */ - if (driver) { - for (i = 0, hw_ep = musb->endpoints; - i < musb->nr_endpoints; - i++, hw_ep++) { - musb_ep_select(musb->mregs, i); - if (hw_ep->is_shared_fifo /* || !epnum */) { - nuke(&hw_ep->ep_in, -ESHUTDOWN); - } else { - if (hw_ep->max_packet_sz_tx) - nuke(&hw_ep->ep_in, -ESHUTDOWN); - if (hw_ep->max_packet_sz_rx) - nuke(&hw_ep->ep_out, -ESHUTDOWN); - } - } - } -} - /* * Unregister the gadget driver. Used by gadget drivers when * unregistering themselves from the controller. @@ -1940,7 +1902,7 @@ static int musb_gadget_stop(struct usb_gadget *g) (void) musb_gadget_vbus_draw(&musb->g, 0); musb->xceiv->otg->state = OTG_STATE_UNDEFINED; - stop_activity(musb, NULL); + musb_stop(musb); otg_set_peripheral(musb->xceiv->otg, NULL); musb->is_active = 0; -- GitLab From e3c93e1a3f35be4cf1493d3ccfb0c6d9209e4922 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 30 Dec 2013 12:33:53 -0600 Subject: [PATCH 03527/11651] usb: musb: core: fix TX/RX endpoint order As per Mentor Graphics' documentation, we should always handle TX endpoints before RX endpoints. This patch fixes that error while also updating some hard-to-read comments which were scattered around musb_interrupt(). This patch should be backported as far back as possible since this error has been in the driver since it's conception. Cc: Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.c | 44 +++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 067920f2d570..461bfe8efcf2 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1597,16 +1597,30 @@ irqreturn_t musb_interrupt(struct musb *musb) is_host_active(musb) ? "host" : "peripheral", musb->int_usb, musb->int_tx, musb->int_rx); - /* the core can interrupt us for multiple reasons; docs have - * a generic interrupt flowchart to follow + /** + * According to Mentor Graphics' documentation, flowchart on page 98, + * IRQ should be handled as follows: + * + * . Resume IRQ + * . Session Request IRQ + * . VBUS Error IRQ + * . Suspend IRQ + * . Connect IRQ + * . Disconnect IRQ + * . Reset/Babble IRQ + * . SOF IRQ (we're not using this one) + * . Endpoint 0 IRQ + * . TX Endpoints + * . RX Endpoints + * + * We will be following that flowchart in order to avoid any problems + * that might arise with internal Finite State Machine. */ + if (musb->int_usb) retval |= musb_stage0_irq(musb, musb->int_usb, devctl); - /* "stage 1" is handling endpoint irqs */ - - /* handle endpoint 0 first */ if (musb->int_tx & 1) { if (is_host_active(musb)) retval |= musb_h_ep0_irq(musb); @@ -1614,37 +1628,31 @@ irqreturn_t musb_interrupt(struct musb *musb) retval |= musb_g_ep0_irq(musb); } - /* RX on endpoints 1-15 */ - reg = musb->int_rx >> 1; + reg = musb->int_tx >> 1; ep_num = 1; while (reg) { if (reg & 1) { - /* musb_ep_select(musb->mregs, ep_num); */ - /* REVISIT just retval = ep->rx_irq(...) */ retval = IRQ_HANDLED; if (is_host_active(musb)) - musb_host_rx(musb, ep_num); + musb_host_tx(musb, ep_num); else - musb_g_rx(musb, ep_num); + musb_g_tx(musb, ep_num); } - reg >>= 1; ep_num++; } - /* TX on endpoints 1-15 */ - reg = musb->int_tx >> 1; + reg = musb->int_rx >> 1; ep_num = 1; while (reg) { if (reg & 1) { - /* musb_ep_select(musb->mregs, ep_num); */ - /* REVISIT just retval |= ep->tx_irq(...) */ retval = IRQ_HANDLED; if (is_host_active(musb)) - musb_host_tx(musb, ep_num); + musb_host_rx(musb, ep_num); else - musb_g_tx(musb, ep_num); + musb_g_rx(musb, ep_num); } + reg >>= 1; ep_num++; } -- GitLab From 31a0ede0de49a5897d7d97c68228ae79f86c38f0 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 30 Dec 2013 12:42:38 -0600 Subject: [PATCH 03528/11651] usb: musb: core: improve musb_interrupt() a bit instead of using manually spelled out bit-shits and iterate over each of the 16-bits (one for each endpoint) on each direction, we can make use of for_each_set_bit() which internally uses find_first_bit(). This makes the code slightly more readable while also making we only iterate over bits which are actually set. Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.c | 52 +++++++++++++++++------------------- 1 file changed, 24 insertions(+), 28 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 461bfe8efcf2..e59ae7395ba8 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1587,9 +1587,12 @@ static int musb_core_init(u16 musb_type, struct musb *musb) irqreturn_t musb_interrupt(struct musb *musb) { irqreturn_t retval = IRQ_NONE; + unsigned long status; + unsigned long epnum; u8 devctl; - int ep_num; - u32 reg; + + if (!musb->int_usb && !musb->int_tx && !musb->int_rx) + return IRQ_NONE; devctl = musb_readb(musb->mregs, MUSB_DEVCTL); @@ -1618,43 +1621,36 @@ irqreturn_t musb_interrupt(struct musb *musb) */ if (musb->int_usb) - retval |= musb_stage0_irq(musb, musb->int_usb, - devctl); + retval |= musb_stage0_irq(musb, musb->int_usb, devctl); if (musb->int_tx & 1) { if (is_host_active(musb)) retval |= musb_h_ep0_irq(musb); else retval |= musb_g_ep0_irq(musb); + + /* we have just handled endpoint 0 IRQ, clear it */ + musb->int_tx &= ~BIT(0); } - reg = musb->int_tx >> 1; - ep_num = 1; - while (reg) { - if (reg & 1) { - retval = IRQ_HANDLED; - if (is_host_active(musb)) - musb_host_tx(musb, ep_num); - else - musb_g_tx(musb, ep_num); - } - reg >>= 1; - ep_num++; + status = musb->int_tx; + + for_each_set_bit(epnum, &status, 16) { + retval = IRQ_HANDLED; + if (is_host_active(musb)) + musb_host_tx(musb, epnum); + else + musb_g_tx(musb, epnum); } - reg = musb->int_rx >> 1; - ep_num = 1; - while (reg) { - if (reg & 1) { - retval = IRQ_HANDLED; - if (is_host_active(musb)) - musb_host_rx(musb, ep_num); - else - musb_g_rx(musb, ep_num); - } + status = musb->int_rx; - reg >>= 1; - ep_num++; + for_each_set_bit(epnum, &status, 16) { + retval = IRQ_HANDLED; + if (is_host_active(musb)) + musb_host_rx(musb, epnum); + else + musb_g_rx(musb, epnum); } return retval; -- GitLab From 3da1f6ee3563f84395e5d334349a4c9e25d8cbcb Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 2 Sep 2014 15:19:43 -0500 Subject: [PATCH 03529/11651] usb: dwc3: core: only reset res->start in case of error That trick is only needed if we end up with an error, so there's no point in messing that outside of an error path. In fact doing so causes problems when removing dwc3.ko, problems which commit c5a1fbc (usb: dwc3: dwc3-omap: Fix the crash on module removal) mistakenly tried to fix. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.c | 56 +++++++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 22 deletions(-) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 9f0e209b8f6c..cd59e919e27e 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -774,17 +774,13 @@ static int dwc3_probe(struct platform_device *pdev) * since it will be requested by the xhci-plat driver. */ regs = devm_ioremap_resource(dev, res); - if (IS_ERR(regs)) - return PTR_ERR(regs); + if (IS_ERR(regs)) { + ret = PTR_ERR(regs); + goto err0; + } dwc->regs = regs; dwc->regs_size = resource_size(res); - /* - * restore res->start back to its original value so that, - * in case the probe is deferred, we don't end up getting error in - * request the memory region the next time probe is called. - */ - res->start -= DWC3_GLOBALS_REGS_START; /* default to highest possible threshold */ lpm_nyet_threshold = 0xff; @@ -878,7 +874,7 @@ static int dwc3_probe(struct platform_device *pdev) ret = dwc3_core_get_phy(dwc); if (ret) - return ret; + goto err0; spin_lock_init(&dwc->lock); platform_set_drvdata(pdev, dwc); @@ -899,7 +895,7 @@ static int dwc3_probe(struct platform_device *pdev) if (ret) { dev_err(dwc->dev, "failed to allocate event buffers\n"); ret = -ENOMEM; - goto err0; + goto err1; } if (IS_ENABLED(CONFIG_USB_DWC3_HOST)) @@ -913,65 +909,81 @@ static int dwc3_probe(struct platform_device *pdev) ret = dwc3_core_init(dwc); if (ret) { dev_err(dev, "failed to initialize core\n"); - goto err0; + goto err1; } usb_phy_set_suspend(dwc->usb2_phy, 0); usb_phy_set_suspend(dwc->usb3_phy, 0); ret = phy_power_on(dwc->usb2_generic_phy); if (ret < 0) - goto err1; + goto err2; ret = phy_power_on(dwc->usb3_generic_phy); if (ret < 0) - goto err_usb2phy_power; + goto err3; ret = dwc3_event_buffers_setup(dwc); if (ret) { dev_err(dwc->dev, "failed to setup event buffers\n"); - goto err_usb3phy_power; + goto err4; } ret = dwc3_core_init_mode(dwc); if (ret) - goto err2; + goto err5; ret = dwc3_debugfs_init(dwc); if (ret) { dev_err(dev, "failed to initialize debugfs\n"); - goto err3; + goto err6; } pm_runtime_allow(dev); return 0; -err3: +err6: dwc3_core_exit_mode(dwc); -err2: +err5: dwc3_event_buffers_cleanup(dwc); -err_usb3phy_power: +err4: phy_power_off(dwc->usb3_generic_phy); -err_usb2phy_power: +err3: phy_power_off(dwc->usb2_generic_phy); -err1: +err2: usb_phy_set_suspend(dwc->usb2_phy, 1); usb_phy_set_suspend(dwc->usb3_phy, 1); dwc3_core_exit(dwc); -err0: +err1: dwc3_free_event_buffers(dwc); +err0: + /* + * restore res->start back to its original value so that, in case the + * probe is deferred, we don't end up getting error in request the + * memory region the next time probe is called. + */ + res->start -= DWC3_GLOBALS_REGS_START; + return ret; } static int dwc3_remove(struct platform_device *pdev) { struct dwc3 *dwc = platform_get_drvdata(pdev); + struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + + /* + * restore res->start back to its original value so that, in case the + * probe is deferred, we don't end up getting error in request the + * memory region the next time probe is called. + */ + res->start -= DWC3_GLOBALS_REGS_START; dwc3_debugfs_exit(dwc); dwc3_core_exit_mode(dwc); -- GitLab From 3d0184d087573b7606de45a8e4f01b6222caa47a Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 2 Sep 2014 14:12:26 -0500 Subject: [PATCH 03530/11651] usb: dwc3: omap: call of_platform_depopulate() instead This patch fixes a bug where removing dwc3-omap.ko would not trigger removal of dwc3.ko. of_platform_depopulate() already bakes an easy to use API for removing all our children which were populated during probe(); Let's use that one instead of cooking our own solution. Note that this is kind of a revert of commit c5a1fbc (usb: dwc3: dwc3-omap: Fix the crash on module removal) although we can't simply revert that because a direct call to platform_device_unregister would also be flakey. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-omap.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c index 52e0c4e5e48e..edba5348be18 100644 --- a/drivers/usb/dwc3/dwc3-omap.c +++ b/drivers/usb/dwc3/dwc3-omap.c @@ -325,15 +325,6 @@ static irqreturn_t dwc3_omap_interrupt(int irq, void *_omap) return IRQ_HANDLED; } -static int dwc3_omap_remove_core(struct device *dev, void *c) -{ - struct platform_device *pdev = to_platform_device(dev); - - of_device_unregister(pdev); - - return 0; -} - static void dwc3_omap_enable_irqs(struct dwc3_omap *omap) { u32 reg; @@ -600,7 +591,7 @@ static int dwc3_omap_remove(struct platform_device *pdev) if (omap->extcon_id_dev.edev) extcon_unregister_interest(&omap->extcon_id_dev); dwc3_omap_disable_irqs(omap); - device_for_each_child(&pdev->dev, NULL, dwc3_omap_remove_core); + of_platform_depopulate(omap->dev); pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); -- GitLab From 8f2c9544aba636134303105ecb164190a39dece4 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 4 Sep 2014 13:14:49 -0500 Subject: [PATCH 03531/11651] usb: dwc3: gadget: drop unnecessary loop when cleaning up TRBs Now that we're using XFERINPROGRESS for all endpoint types (except Control), we will *always* be completing one TRB at a time, so it's safe to remove the loop from dwc3_cleanup_done_reqs. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index a03a485205c7..8946c32047e9 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1855,32 +1855,27 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep, unsigned int i; int ret; + req = next_request(&dep->req_queued); + if (!req) { + WARN_ON_ONCE(1); + return 1; + } + i = 0; do { - req = next_request(&dep->req_queued); - if (!req) { - WARN_ON_ONCE(1); - return 1; - } - i = 0; - do { - slot = req->start_slot + i; - if ((slot == DWC3_TRB_NUM - 1) && + slot = req->start_slot + i; + if ((slot == DWC3_TRB_NUM - 1) && usb_endpoint_xfer_isoc(dep->endpoint.desc)) - slot++; - slot %= DWC3_TRB_NUM; - trb = &dep->trb_pool[slot]; - - ret = __dwc3_cleanup_done_trbs(dwc, dep, req, trb, - event, status); - if (ret) - break; - }while (++i < req->request.num_mapped_sgs); - - dwc3_gadget_giveback(dep, req, status); + slot++; + slot %= DWC3_TRB_NUM; + trb = &dep->trb_pool[slot]; + ret = __dwc3_cleanup_done_trbs(dwc, dep, req, trb, + event, status); if (ret) break; - } while (1); + } while (++i < req->request.num_mapped_sgs); + + dwc3_gadget_giveback(dep, req, status); if (usb_endpoint_xfer_isoc(dep->endpoint.desc) && list_empty(&dep->req_queued)) { -- GitLab From 798523973dcc93c2440932dc4dfe76fbf571f668 Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Wed, 4 Mar 2015 17:07:57 +0000 Subject: [PATCH 03532/11651] usb: isp1760: fix possible deadlock in isp1760_udc_irq Use spin_{un,}lock_irq{save,restore} in isp1760_udc_{start,stop} to prevent following potentially deadlock scenario between isp1760_udc_{start,stop} and isp1760_udc_irq : ================================= [ INFO: inconsistent lock state ] 4.0.0-rc2-00004-gf7bb2ef60173 #51 Not tainted --------------------------------- inconsistent {HARDIRQ-ON-W} -> {IN-HARDIRQ-W} usage. in:imklog/2118 [HC1[1]:SC0[0]:HE0:SE1] takes: (&(&udc->lock)->rlock){?.+...}, at: [] isp1760_udc_irq+0x367/0x9dc {HARDIRQ-ON-W} state was registered at: [] _raw_spin_lock+0x23/0x30 [] isp1760_udc_start+0x23/0xf8 [] udc_bind_to_driver+0x71/0xb0 [] usb_gadget_probe_driver+0x53/0x9c [] usb_composite_probe+0x8a/0xa4 [libcomposite] [] 0xbf8311a7 [] do_one_initcall+0x8d/0x17c [] do_init_module+0x49/0x148 [] load_module+0xb7f/0xbc4 [] SyS_finit_module+0x51/0x74 [] ret_fast_syscall+0x1/0x68 irq event stamp: 4966 hardirqs last enabled at (4965): [] _raw_spin_unlock_irq+0x1f/0x24 hardirqs last disabled at (4966): [] __irq_svc+0x33/0x64 softirqs last enabled at (4458): [] __do_softirq+0x23d/0x2d0 softirqs last disabled at (4389): [] irq_exit+0xef/0x15c other info that might help us debug this: Possible unsafe locking scenario: CPU0 ---- lock(&(&udc->lock)->rlock); lock(&(&udc->lock)->rlock); *** DEADLOCK *** 1 lock held by in:imklog/2118: #0: (&f->f_pos_lock){+.+.+.}, at: [] __fdget_pos+0x31/0x34 Signed-off-by: Sudeep Holla Cc: Greg Kroah-Hartman Acked-by: Laurent Pinchart Signed-off-by: Felipe Balbi --- drivers/usb/isp1760/isp1760-udc.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/usb/isp1760/isp1760-udc.c b/drivers/usb/isp1760/isp1760-udc.c index 9612d7990565..19e6a172ff82 100644 --- a/drivers/usb/isp1760/isp1760-udc.c +++ b/drivers/usb/isp1760/isp1760-udc.c @@ -1191,6 +1191,7 @@ static int isp1760_udc_start(struct usb_gadget *gadget, struct usb_gadget_driver *driver) { struct isp1760_udc *udc = gadget_to_udc(gadget); + unsigned long flags; /* The hardware doesn't support low speed. */ if (driver->max_speed < USB_SPEED_FULL) { @@ -1198,7 +1199,7 @@ static int isp1760_udc_start(struct usb_gadget *gadget, return -EINVAL; } - spin_lock(&udc->lock); + spin_lock_irqsave(&udc->lock, flags); if (udc->driver) { dev_err(udc->isp->dev, "UDC already has a gadget driver\n"); @@ -1208,7 +1209,7 @@ static int isp1760_udc_start(struct usb_gadget *gadget, udc->driver = driver; - spin_unlock(&udc->lock); + spin_unlock_irqrestore(&udc->lock, flags); dev_dbg(udc->isp->dev, "starting UDC with driver %s\n", driver->function); @@ -1232,6 +1233,7 @@ static int isp1760_udc_start(struct usb_gadget *gadget, static int isp1760_udc_stop(struct usb_gadget *gadget) { struct isp1760_udc *udc = gadget_to_udc(gadget); + unsigned long flags; dev_dbg(udc->isp->dev, "%s\n", __func__); @@ -1239,9 +1241,9 @@ static int isp1760_udc_stop(struct usb_gadget *gadget) isp1760_udc_write(udc, DC_MODE, 0); - spin_lock(&udc->lock); + spin_lock_irqsave(&udc->lock, flags); udc->driver = NULL; - spin_unlock(&udc->lock); + spin_unlock_irqrestore(&udc->lock, flags); return 0; } -- GitLab From 1c390eb360c3f6bc9a06d2260eccad195c505de5 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Sat, 28 Feb 2015 00:19:41 +0100 Subject: [PATCH 03533/11651] usb: musb: fix Kconfig regression A recent bug fix I did that was marked for stable backports introduced a slightly wrong dependency on CONFIG_OMAP_CONTROL_PHY. I was missing the fact that the PHY driver already stubs out the omap_control_usb_set_mode, and we only need to add a dependency to prevent the musb-omap2430 driver from being built-in when the phy driver is a loadable module, but we should not prevent it from being built altogether when the phy driver is disabled. Signed-off-by: Arnd Bergmann Fixes: ca784be36cc725 ("usb: start using the control module driver") Cc: # v3.9+ Acked-by: Acked-by: Pavel Machek Tested-by: Aaro Koskinen Signed-off-by: Felipe Balbi --- drivers/usb/musb/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index 14e1628483d9..39db8b603627 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig @@ -79,7 +79,8 @@ config USB_MUSB_TUSB6010 config USB_MUSB_OMAP2PLUS tristate "OMAP2430 and onwards" - depends on ARCH_OMAP2PLUS && USB && OMAP_CONTROL_PHY + depends on ARCH_OMAP2PLUS && USB + depends on OMAP_CONTROL_PHY || !OMAP_CONTROL_PHY select GENERIC_PHY config USB_MUSB_AM35X -- GitLab From 80b4a0f8feeb6ee7fa4430a2b4ae1155ed923bd2 Mon Sep 17 00:00:00 2001 From: Valentin Rothberg Date: Sun, 1 Mar 2015 16:54:32 +0100 Subject: [PATCH 03534/11651] usb: isp1760: set IRQ flags properly The IRQF_DISABLED is a NOOP and scheduled to be removed. According to commit e58aa3d2d0cc ("genirq: Run irq handlers with interrupts disabled") running IRQ handlers with interrupts enabled can cause stack overflows when the interrupt line of the issuing device is still active. This patch removes using this deprecated flag and additionally removes redundantly setting IRQF_SHARED for isp1760_udc_register(). Signed-off-by: Valentin Rothberg Acked-by: Laurent Pinchart Signed-off-by: Felipe Balbi --- drivers/usb/isp1760/isp1760-core.c | 3 +-- drivers/usb/isp1760/isp1760-udc.c | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/usb/isp1760/isp1760-core.c b/drivers/usb/isp1760/isp1760-core.c index b9827556455f..bfa402cf3a27 100644 --- a/drivers/usb/isp1760/isp1760-core.c +++ b/drivers/usb/isp1760/isp1760-core.c @@ -151,8 +151,7 @@ int isp1760_register(struct resource *mem, int irq, unsigned long irqflags, } if (IS_ENABLED(CONFIG_USB_ISP1761_UDC) && !udc_disabled) { - ret = isp1760_udc_register(isp, irq, irqflags | IRQF_SHARED | - IRQF_DISABLED); + ret = isp1760_udc_register(isp, irq, irqflags); if (ret < 0) { isp1760_hcd_unregister(&isp->hcd); return ret; diff --git a/drivers/usb/isp1760/isp1760-udc.c b/drivers/usb/isp1760/isp1760-udc.c index 19e6a172ff82..47674f9c6df2 100644 --- a/drivers/usb/isp1760/isp1760-udc.c +++ b/drivers/usb/isp1760/isp1760-udc.c @@ -1453,8 +1453,8 @@ int isp1760_udc_register(struct isp1760_device *isp, int irq, sprintf(udc->irqname, "%s (udc)", devname); - ret = request_irq(irq, isp1760_udc_irq, IRQF_SHARED | IRQF_DISABLED | - irqflags, udc->irqname, udc); + ret = request_irq(irq, isp1760_udc_irq, IRQF_SHARED | irqflags, + udc->irqname, udc); if (ret < 0) goto error; -- GitLab From 1998adab1c188076eaf356a8ae28217856f0ee92 Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Thu, 26 Feb 2015 11:47:57 +0000 Subject: [PATCH 03535/11651] usb: isp1760: add peripheral/device controller chip id As per the SAF1761 data sheet[0], the DcChipID register represents the hardware version number (0001h) and the chip ID (1582h) for the Peripheral Controller. However as per the ISP1761 data sheet[1], the DcChipID register represents the hardware version number (0015h) and the chip ID (8210h) for the Peripheral Controller. This patch adds support for both the chip ID values. [0] http://www.nxp.com/documents/data_sheet/SAF1761.pdf [1] http://pdf.datasheetcatalog.com/datasheets2/74/742102_1.pdf Acked-by: Laurent Pinchart Signed-off-by: Sudeep Holla Signed-off-by: Felipe Balbi --- drivers/usb/isp1760/isp1760-udc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/isp1760/isp1760-udc.c b/drivers/usb/isp1760/isp1760-udc.c index 47674f9c6df2..f32c292cc868 100644 --- a/drivers/usb/isp1760/isp1760-udc.c +++ b/drivers/usb/isp1760/isp1760-udc.c @@ -1413,7 +1413,7 @@ static int isp1760_udc_init(struct isp1760_udc *udc) return -ENODEV; } - if (chipid != 0x00011582) { + if (chipid != 0x00011582 && chipid != 0x00158210) { dev_err(udc->isp->dev, "udc: invalid chip ID 0x%08x\n", chipid); return -ENODEV; } -- GitLab From de3b696542d3e0fb897149680821dae480c314af Mon Sep 17 00:00:00 2001 From: Rojhalat Ibrahim Date: Thu, 5 Mar 2015 14:36:36 +0100 Subject: [PATCH 03536/11651] extend documentation for gpiod_set_array() functions Extend the documentation for the gpiod_set_array() functions and elaborate a bit on possible use cases. Signed-off-by: Rojhalat Ibrahim Signed-off-by: Linus Walleij --- Documentation/gpio/consumer.txt | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/Documentation/gpio/consumer.txt b/Documentation/gpio/consumer.txt index d29a9725c9e5..c21c1313f09e 100644 --- a/Documentation/gpio/consumer.txt +++ b/Documentation/gpio/consumer.txt @@ -259,6 +259,26 @@ GPIOs belonging to the same bank or chip simultaneously if supported by the corresponding chip driver. In that case a significantly improved performance can be expected. If simultaneous setting is not possible the GPIOs will be set sequentially. + +The gpiod_set_array() functions take three arguments: + * array_size - the number of array elements + * desc_array - an array of GPIO descriptors + * value_array - an array of values to assign to the GPIOs + +The descriptor array can be obtained using the gpiod_get_array() function +or one of its variants. If the group of descriptors returned by that function +matches the desired group of GPIOs, those GPIOs can be set by simply using +the struct gpio_descs returned by gpiod_get_array(): + + struct gpio_descs *my_gpio_descs = gpiod_get_array(...); + gpiod_set_array(my_gpio_descs->ndescs, my_gpio_descs->desc, + my_gpio_values); + +It is also possible to set a completely arbitrary array of descriptors. The +descriptors may be obtained using any combination of gpiod_get() and +gpiod_get_array(). Afterwards the array of descriptors has to be setup +manually before it can be used with gpiod_set_array(). + Note that for optimal performance GPIOs belonging to the same chip should be contiguous within the array of descriptors. -- GitLab From e5de75bf88858f5b3ab11e2504b86ec059f03102 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Mon, 9 Mar 2015 12:30:12 +0100 Subject: [PATCH 03537/11651] netfilter: bridge: move DNAT helper to br_netfilter Only one caller, there is no need to keep this in a header. Move it to br_netfilter.c where this belongs to. Based on patch from Florian Westphal. Signed-off-by: Pablo Neira Ayuso --- include/linux/netfilter_bridge.h | 12 ------------ net/bridge/br_device.c | 5 +---- net/bridge/br_netfilter.c | 32 ++++++++++++++++++++++++++++++++ net/bridge/br_private.h | 5 +++++ 4 files changed, 38 insertions(+), 16 deletions(-) diff --git a/include/linux/netfilter_bridge.h b/include/linux/netfilter_bridge.h index dd580a9a1add..bb39113ea596 100644 --- a/include/linux/netfilter_bridge.h +++ b/include/linux/netfilter_bridge.h @@ -44,18 +44,6 @@ static inline unsigned int nf_bridge_mtu_reduction(const struct sk_buff *skb) } int br_handle_frame_finish(struct sk_buff *skb); -/* Only used in br_device.c */ -static inline int br_nf_pre_routing_finish_bridge_slow(struct sk_buff *skb) -{ - struct nf_bridge_info *nf_bridge = skb->nf_bridge; - - skb_pull(skb, ETH_HLEN); - nf_bridge->mask ^= BRNF_BRIDGED_DNAT; - skb_copy_to_linear_data_offset(skb, -(ETH_HLEN-ETH_ALEN), - skb->nf_bridge->data, ETH_HLEN-ETH_ALEN); - skb->dev = nf_bridge->physindev; - return br_handle_frame_finish(skb); -} /* This is called by the IP fragmenting code and it ensures there is * enough room for the encapsulating header (if there is one). */ diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index ffd379db5938..294cbcc49263 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c @@ -36,13 +36,10 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev) u16 vid = 0; rcu_read_lock(); -#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) - if (skb->nf_bridge && (skb->nf_bridge->mask & BRNF_BRIDGED_DNAT)) { - br_nf_pre_routing_finish_bridge_slow(skb); + if (br_nf_prerouting_finish_bridge(skb)) { rcu_read_unlock(); return NETDEV_TX_OK; } -#endif u64_stats_update_begin(&brstats->syncp); brstats->tx_packets++; diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index ef1fe281ca11..a8361c7cdf81 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c @@ -892,6 +892,38 @@ static unsigned int ip_sabotage_in(const struct nf_hook_ops *ops, return NF_ACCEPT; } +/* This is called when br_netfilter has called into iptables/netfilter, + * and DNAT has taken place on a bridge-forwarded packet. + * + * neigh->output has created a new MAC header, with local br0 MAC + * as saddr. + * + * This restores the original MAC saddr of the bridged packet + * before invoking bridge forward logic to transmit the packet. + */ +static void br_nf_pre_routing_finish_bridge_slow(struct sk_buff *skb) +{ + struct nf_bridge_info *nf_bridge = skb->nf_bridge; + + skb_pull(skb, ETH_HLEN); + nf_bridge->mask &= ~BRNF_BRIDGED_DNAT; + + skb_copy_to_linear_data_offset(skb, -(ETH_HLEN-ETH_ALEN), + skb->nf_bridge->data, ETH_HLEN-ETH_ALEN); + skb->dev = nf_bridge->physindev; + br_handle_frame_finish(skb); +} + +int br_nf_prerouting_finish_bridge(struct sk_buff *skb) +{ + if (skb->nf_bridge && (skb->nf_bridge->mask & BRNF_BRIDGED_DNAT)) { + br_nf_pre_routing_finish_bridge_slow(skb); + return 1; + } + return 0; +} +EXPORT_SYMBOL_GPL(br_nf_prerouting_finish_bridge); + void br_netfilter_enable(void) { } diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index de0919975a25..d63fc17fe4f4 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -764,10 +764,15 @@ static inline int br_vlan_enabled(struct net_bridge *br) /* br_netfilter.c */ #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) +int br_nf_prerouting_finish_bridge(struct sk_buff *skb); int br_nf_core_init(void); void br_nf_core_fini(void); void br_netfilter_rtable_init(struct net_bridge *); #else +static inline int br_nf_prerouting_finish_bridge(struct sk_buff *skb) +{ + return 0; +} static inline int br_nf_core_init(void) { return 0; } static inline void br_nf_core_fini(void) {} #define br_netfilter_rtable_init(x) -- GitLab From 1055b5f90424056432430fa06f94f1d12db07fba Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Thu, 12 Feb 2015 15:15:16 +0100 Subject: [PATCH 03538/11651] hwmon: (coretemp) Allow format checking By extracting the only part that differs we can allow static checking of the format string, and possibly save a little .rodata. Signed-off-by: Rasmus Villemoes [Guenter Roeck: continuation line alignment] Signed-off-by: Guenter Roeck --- drivers/hwmon/coretemp.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index 5b7fec824f10..ed303ba3a593 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c @@ -397,14 +397,13 @@ static int create_core_attrs(struct temp_data *tdata, struct device *dev, struct device_attribute *devattr, char *buf) = { show_label, show_crit_alarm, show_temp, show_tjmax, show_ttarget }; - static const char *const names[TOTAL_ATTRS] = { - "temp%d_label", "temp%d_crit_alarm", - "temp%d_input", "temp%d_crit", - "temp%d_max" }; + static const char *const suffixes[TOTAL_ATTRS] = { + "label", "crit_alarm", "input", "crit", "max" + }; for (i = 0; i < tdata->attr_size; i++) { - snprintf(tdata->attr_name[i], CORETEMP_NAME_LENGTH, names[i], - attr_no); + snprintf(tdata->attr_name[i], CORETEMP_NAME_LENGTH, + "temp%d_%s", attr_no, suffixes[i]); sysfs_attr_init(&tdata->sd_attrs[i].dev_attr.attr); tdata->sd_attrs[i].dev_attr.attr.name = tdata->attr_name[i]; tdata->sd_attrs[i].dev_attr.attr.mode = S_IRUGO; -- GitLab From a0fc74d42d2215496302a0e2c03e9f2db30cc1b7 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Thu, 12 Feb 2015 15:15:17 +0100 Subject: [PATCH 03539/11651] hwmon: (ibmpex) Allow format string checking The only difference between the three power_sensor_name_templates is whether there is a suffix of "", "_lowest" or "_highest". We might as well pull those into an array and use a literal format string, allowing gcc to do type checking of the arguments to sprintf. Incidentially, the same three suffixes are used in the temp_sensor_name_templates case, so we end up eliminating one static array. Signed-off-by: Rasmus Villemoes [Guenter Roeck: Fixed line length over 80 characters] Signed-off-by: Guenter Roeck --- drivers/hwmon/ibmpex.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/drivers/hwmon/ibmpex.c b/drivers/hwmon/ibmpex.c index 030e7ff589be..21b9c72f16bd 100644 --- a/drivers/hwmon/ibmpex.c +++ b/drivers/hwmon/ibmpex.c @@ -56,15 +56,10 @@ static u8 const temp_sensor_sig[] = {0x74, 0x65, 0x6D}; static u8 const watt_sensor_sig[] = {0x41, 0x43}; #define PEX_NUM_SENSOR_FUNCS 3 -static char const * const power_sensor_name_templates[] = { - "%s%d_average", - "%s%d_average_lowest", - "%s%d_average_highest" -}; -static char const * const temp_sensor_name_templates[] = { - "%s%d_input", - "%s%d_input_lowest", - "%s%d_input_highest" +static const char * const sensor_name_suffixes[] = { + "", + "_lowest", + "_highest" }; static void ibmpex_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data); @@ -355,9 +350,11 @@ static int create_sensor(struct ibmpex_bmc_data *data, int type, return -ENOMEM; if (type == TEMP_SENSOR) - sprintf(n, temp_sensor_name_templates[func], "temp", counter); + sprintf(n, "temp%d_input%s", + counter, sensor_name_suffixes[func]); else if (type == POWER_SENSOR) - sprintf(n, power_sensor_name_templates[func], "power", counter); + sprintf(n, "power%d_average%s", + counter, sensor_name_suffixes[func]); sysfs_attr_init(&data->sensors[sensor].attr[func].dev_attr.attr); data->sensors[sensor].attr[func].dev_attr.attr.name = n; -- GitLab From 7bc32d298b0b597a0a8a6527c9929fac68524d4a Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 17 Jan 2015 14:10:24 -0800 Subject: [PATCH 03540/11651] hwmon: (it87) Add support for IT8781F IT8781F is mostly compatible to IT8782F. Major difference is that it only supports four instead of six UART channels, and therefore does not share the uart6 pins. Reviewed-by: Jean Delvare Signed-off-by: Guenter Roeck --- Documentation/hwmon/it87 | 22 +++++++++++++--------- drivers/hwmon/Kconfig | 4 ++-- drivers/hwmon/it87.c | 32 ++++++++++++++++++++++++-------- 3 files changed, 39 insertions(+), 19 deletions(-) diff --git a/Documentation/hwmon/it87 b/Documentation/hwmon/it87 index fe80e9adebfa..8e192fff10f4 100644 --- a/Documentation/hwmon/it87 +++ b/Documentation/hwmon/it87 @@ -42,6 +42,10 @@ Supported chips: Prefix: 'it8772' Addresses scanned: from Super I/O config space (8 I/O ports) Datasheet: Not publicly available + * IT8781F + Prefix: 'it8781' + Addresses scanned: from Super I/O config space (8 I/O ports) + Datasheet: Not publicly available * IT8782F Prefix: 'it8782' Addresses scanned: from Super I/O config space (8 I/O ports) @@ -96,7 +100,7 @@ Description This driver implements support for the IT8603E, IT8623E, IT8705F, IT8712F, IT8716F, IT8718F, IT8720F, IT8721F, IT8726F, IT8728F, IT8758E, IT8771E, -IT8772E, IT8782F, IT8783E/F, and SiS950 chips. +IT8772E, IT8781F, IT8782F, IT8783E/F, and SiS950 chips. These chips are 'Super I/O chips', supporting floppy disks, infrared ports, joysticks and other miscellaneous stuff. For hardware monitoring, they @@ -120,11 +124,11 @@ The IT8716F, IT8718F, IT8720F, IT8721F/IT8758E and later IT8712F revisions have support for 2 additional fans. The additional fans are supported by the driver. -The IT8716F, IT8718F, IT8720F, IT8721F/IT8758E, IT8782F, IT8783E/F, and late -IT8712F and IT8705F also have optional 16-bit tachometer counters for fans 1 to -3. This is better (no more fan clock divider mess) but not compatible with the -older chips and revisions. The 16-bit tachometer mode is enabled by the driver -when one of the above chips is detected. +The IT8716F, IT8718F, IT8720F, IT8721F/IT8758E, IT8781F, IT8782F, IT8783E/F, +and late IT8712F and IT8705F also have optional 16-bit tachometer counters +for fans 1 to 3. This is better (no more fan clock divider mess) but not +compatible with the older chips and revisions. The 16-bit tachometer mode +is enabled by the driver when one of the above chips is detected. The IT8726F is just bit enhanced IT8716F with additional hardware for AMD power sequencing. Therefore the chip will appear as IT8716F @@ -156,10 +160,10 @@ inputs can measure voltages between 0 and 4.08 volts, with a resolution of 0.016 volt (except IT8603E, IT8721F/IT8758E and IT8728F: 0.012 volt.) The battery voltage in8 does not have limit registers. -On the IT8603E, IT8721F/IT8758E, IT8782F, and IT8783E/F, some voltage inputs -are internal and scaled inside the chip: +On the IT8603E, IT8721F/IT8758E, IT8781F, IT8782F, and IT8783E/F, some +voltage inputs are internal and scaled inside the chip: * in3 (optional) -* in7 (optional for IT8782F and IT8783E/F) +* in7 (optional for IT8781F, IT8782F, and IT8783E/F) * in8 (always) * in9 (relevant for IT8603E only) The driver handles this transparently so user-space doesn't have to care. diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 110fade9cb74..f5fc54e24fea 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -599,8 +599,8 @@ config SENSORS_IT87 help If you say yes here you get support for ITE IT8705F, IT8712F, IT8716F, IT8718F, IT8720F, IT8721F, IT8726F, IT8728F, IT8758E, - IT8771E, IT8772E, IT8782F, IT8783E/F and IT8603E sensor chips, - and the SiS950 clone. + IT8771E, IT8772E, IT8781F, IT8782F, IT8783E/F and IT8603E + sensor chips, and the SiS950 clone. This driver can also be built as a module. If so, the module will be called it87. diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index 409116c52cc5..ed25e4bab978 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c @@ -23,6 +23,7 @@ * IT8758E Super I/O chip w/LPC interface * IT8771E Super I/O chip w/LPC interface * IT8772E Super I/O chip w/LPC interface + * IT8781F Super I/O chip w/LPC interface * IT8782F Super I/O chip w/LPC interface * IT8783E/F Super I/O chip w/LPC interface * Sis950 A clone of the IT8705F @@ -66,7 +67,7 @@ #define DRVNAME "it87" enum chips { it87, it8712, it8716, it8718, it8720, it8721, it8728, it8771, - it8772, it8782, it8783, it8603 }; + it8772, it8781, it8782, it8783, it8603 }; static unsigned short force_id; module_param(force_id, ushort, 0); @@ -146,6 +147,7 @@ static inline void superio_exit(void) #define IT8728F_DEVID 0x8728 #define IT8771E_DEVID 0x8771 #define IT8772E_DEVID 0x8772 +#define IT8781F_DEVID 0x8781 #define IT8782F_DEVID 0x8782 #define IT8783E_DEVID 0x8783 #define IT8603E_DEVID 0x8603 @@ -307,6 +309,12 @@ static const struct it87_devices it87_devices[] = { /* 16 bit fans (HWSensors4, OHM) */ .peci_mask = 0x07, }, + [it8781] = { + .name = "it8781", + .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET + | FEAT_TEMP_OLD_PECI, + .old_peci_mask = 0x4, + }, [it8782] = { .name = "it8782", .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET @@ -1761,6 +1769,9 @@ static int __init it87_find(unsigned short *address, case IT8772E_DEVID: sio_data->type = it8772; break; + case IT8781F_DEVID: + sio_data->type = it8781; + break; case IT8782F_DEVID: sio_data->type = it8782; break; @@ -1919,10 +1930,11 @@ static int __init it87_find(unsigned short *address, reg = superio_inb(IT87_SIO_GPIO3_REG); if (sio_data->type == it8721 || sio_data->type == it8728 || sio_data->type == it8771 || sio_data->type == it8772 || - sio_data->type == it8782) { + sio_data->type == it8781 || sio_data->type == it8782) { /* - * IT8721F/IT8758E, and IT8782F don't have VID pins - * at all, not sure about the IT8728F and compatibles. + * IT8721F/IT8758E, IT8728F, IT8772F, IT8781F, and + * IT8782F don't have VID pins at all, not sure about + * the IT8771F. */ sio_data->skip_vid = 1; } else { @@ -2147,7 +2159,8 @@ static int it87_probe(struct platform_device *pdev) data->in_scaled |= (1 << 8); /* in8 is Vbat */ if (sio_data->internal & (1 << 3)) data->in_scaled |= (1 << 9); /* in9 is AVCC */ - } else if (sio_data->type == it8782 || sio_data->type == it8783) { + } else if (sio_data->type == it8781 || sio_data->type == it8782 || + sio_data->type == it8783) { if (sio_data->internal & (1 << 0)) data->in_scaled |= (1 << 3); /* in3 is VCC5V */ if (sio_data->internal & (1 << 1)) @@ -2460,9 +2473,12 @@ static void it87_init_device(struct platform_device *pdev) it87_write_value(data, IT87_REG_FAN_16BIT, tmp | 0x07); } - /* IT8705F, IT8782F, and IT8783E/F only support three fans. */ - if (data->type != it87 && data->type != it8782 && - data->type != it8783) { + /* + * IT8705F, IT8781F, IT8782F, and IT8783E/F only support + * three fans. + */ + if (data->type != it87 && data->type != it8781 && + data->type != it8782 && data->type != it8783) { if (tmp & (1 << 4)) data->has_fan |= (1 << 3); /* fan4 enabled */ if (tmp & (1 << 5)) -- GitLab From 0ea2f1db8e6888029b781bbaf68547e2e0996402 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sun, 1 Feb 2015 17:20:38 -0800 Subject: [PATCH 03541/11651] hwmon: (jc42) Add support for additional IDT temperature sensors TS3000GB0 has a new device ID (0x2913). Since IDT's datasheets suggest that the upper 8 bit of the device ID reflect the chip ID and the lower 8 bit reflect the version number, modify the code to accept all chips with ID 0x29xx. Also add support for TS3001 and TSE2004. Some of the datasheets for older chips are no longer available from the IDT web site, so replace explicit links in the documentation with a generic note. Reviewed-by: Jean Delvare Signed-off-by: Guenter Roeck --- Documentation/hwmon/jc42 | 8 +++----- drivers/hwmon/Kconfig | 2 +- drivers/hwmon/jc42.c | 16 ++++++++++------ 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/Documentation/hwmon/jc42 b/Documentation/hwmon/jc42 index f3893f7440de..f7f1830a2566 100644 --- a/Documentation/hwmon/jc42 +++ b/Documentation/hwmon/jc42 @@ -11,12 +11,10 @@ Supported chips: http://www.atmel.com/Images/doc8711.pdf http://www.atmel.com/Images/Atmel-8852-SEEPROM-AT30TSE002A-Datasheet.pdf http://www.atmel.com/Images/Atmel-8868-DTS-AT30TSE004A-Datasheet.pdf - * IDT TSE2002B3, TSE2002GB2, TS3000B3, TS3000GB2 + * IDT TSE2002B3, TSE2002GB2, TSE2004GB2, TS3000B3, TS3000GB0, TS3000GB2, + TS3001GB2 Datasheets: - http://www.idt.com/sites/default/files/documents/IDT_TSE2002B3C_DST_20100512_120303152056.pdf - http://www.idt.com/sites/default/files/documents/IDT_TSE2002GB2A1_DST_20111107_120303145914.pdf - http://www.idt.com/sites/default/files/documents/IDT_TS3000B3A_DST_20101129_120303152013.pdf - http://www.idt.com/sites/default/files/documents/IDT_TS3000GB2A1_DST_20111104_120303151012.pdf + Available from IDT web site * Maxim MAX6604 Datasheets: http://datasheets.maxim-ic.com/en/ds/MAX6604.pdf diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index f5fc54e24fea..e96c0ebaaceb 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -624,7 +624,7 @@ config SENSORS_JC42 mobile devices and servers. Support will include, but not be limited to, ADT7408, AT30TS00, CAT34TS02, CAT6095, MAX6604, MCP9804, MCP9805, MCP98242, MCP98243, MCP98244, MCP9843, SE97, SE98, STTS424(E), - STTS2002, STTS3000, TSE2002B3, TSE2002GB2, TS3000B3, and TS3000GB2. + STTS2002, STTS3000, TSE2002, TSE2004, TS3000, and TS3001. This driver can also be built as a module. If so, the module will be called jc42. diff --git a/drivers/hwmon/jc42.c b/drivers/hwmon/jc42.c index 996bdfd5cf25..9887d3224a86 100644 --- a/drivers/hwmon/jc42.c +++ b/drivers/hwmon/jc42.c @@ -87,11 +87,14 @@ static const unsigned short normal_i2c[] = { #define AT30TSE004_DEVID_MASK 0xffff /* IDT */ -#define TS3000B3_DEVID 0x2903 /* Also matches TSE2002B3 */ -#define TS3000B3_DEVID_MASK 0xffff +#define TSE2004_DEVID 0x2200 +#define TSE2004_DEVID_MASK 0xff00 -#define TS3000GB2_DEVID 0x2912 /* Also matches TSE2002GB2 */ -#define TS3000GB2_DEVID_MASK 0xffff +#define TS3000_DEVID 0x2900 /* Also matches TSE2002 */ +#define TS3000_DEVID_MASK 0xff00 + +#define TS3001_DEVID 0x3000 +#define TS3001_DEVID_MASK 0xff00 /* Maxim */ #define MAX6604_DEVID 0x3e00 @@ -152,8 +155,9 @@ static struct jc42_chips jc42_chips[] = { { ADT_MANID, ADT7408_DEVID, ADT7408_DEVID_MASK }, { ATMEL_MANID, AT30TS00_DEVID, AT30TS00_DEVID_MASK }, { ATMEL_MANID2, AT30TSE004_DEVID, AT30TSE004_DEVID_MASK }, - { IDT_MANID, TS3000B3_DEVID, TS3000B3_DEVID_MASK }, - { IDT_MANID, TS3000GB2_DEVID, TS3000GB2_DEVID_MASK }, + { IDT_MANID, TSE2004_DEVID, TSE2004_DEVID_MASK }, + { IDT_MANID, TS3000_DEVID, TS3000_DEVID_MASK }, + { IDT_MANID, TS3001_DEVID, TS3001_DEVID_MASK }, { MAX_MANID, MAX6604_DEVID, MAX6604_DEVID_MASK }, { MCP_MANID, MCP9804_DEVID, MCP9804_DEVID_MASK }, { MCP_MANID, MCP98242_DEVID, MCP98242_DEVID_MASK }, -- GitLab From fd044868e8056720b52d41bb61da0fbf7f04fd50 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Tue, 24 Feb 2015 06:32:40 -0800 Subject: [PATCH 03542/11651] hwmon: (it87) Don't configure 16 bit fan counters it not necessary On IT8728F, IT8771E, and IT8772E, fans counters are always 16 bit and don't need to be configured for it. Reviewed-by: Jean Delvare Signed-off-by: Guenter Roeck --- drivers/hwmon/it87.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index ed25e4bab978..e8cbefb9c96d 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c @@ -2463,9 +2463,12 @@ static void it87_init_device(struct platform_device *pdev) } data->has_fan = (data->fan_main_ctrl >> 4) & 0x07; - /* Set tachometers to 16-bit mode if needed, IT8603E (and IT8728F?) - * has it by default */ - if (has_16bit_fans(data) && data->type != it8603) { + /* + * Set tachometers to 16-bit mode if needed. IT8603E, IT8728F, + * IT8771E (guesswork), and IT8772E have it by default. + */ + if (has_16bit_fans(data) && data->type != it8603 && data->type != it8728 + && data->type != it8771 && data->type != it8772) { tmp = it87_read_value(data, IT87_REG_FAN_16BIT); if (~tmp & 0x07 & data->has_fan) { dev_dbg(&pdev->dev, -- GitLab From 9faf28ca4beb24cd5a01f38c5655f5ae92d834ba Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Thu, 12 Feb 2015 07:11:38 -0800 Subject: [PATCH 03543/11651] hwmon: (it87) Add feature flags for fans count and 16-bit fan configuration Fans 4-5 are not supported on all chips and revisions. Also, 16-bit fan counters are always enabled on some chips. Provide feature flags to simplify adding support for new chips. Reviewed-by: Jean Delvare Signed-off-by: Guenter Roeck --- drivers/hwmon/it87.c | 69 +++++++++++++++++++++++--------------------- 1 file changed, 36 insertions(+), 33 deletions(-) diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index e8cbefb9c96d..48b48939d893 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c @@ -252,6 +252,8 @@ struct it87_devices { #define FEAT_TEMP_OFFSET (1 << 4) #define FEAT_TEMP_PECI (1 << 5) #define FEAT_TEMP_OLD_PECI (1 << 6) +#define FEAT_FAN16_CONFIG (1 << 7) /* Need to enable 16-bit fans */ +#define FEAT_FIVE_FANS (1 << 8) /* Supports five fans */ static const struct it87_devices it87_devices[] = { [it87] = { @@ -264,67 +266,71 @@ static const struct it87_devices it87_devices[] = { }, [it8716] = { .name = "it8716", - .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET, + .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET + | FEAT_FAN16_CONFIG | FEAT_FIVE_FANS, }, [it8718] = { .name = "it8718", .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET - | FEAT_TEMP_OLD_PECI, + | FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_FIVE_FANS, .old_peci_mask = 0x4, }, [it8720] = { .name = "it8720", .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET - | FEAT_TEMP_OLD_PECI, + | FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_FIVE_FANS, .old_peci_mask = 0x4, }, [it8721] = { .name = "it8721", .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS - | FEAT_TEMP_OFFSET | FEAT_TEMP_OLD_PECI | FEAT_TEMP_PECI, + | FEAT_TEMP_OFFSET | FEAT_TEMP_OLD_PECI | FEAT_TEMP_PECI + | FEAT_FAN16_CONFIG | FEAT_FIVE_FANS, .peci_mask = 0x05, .old_peci_mask = 0x02, /* Actually reports PCH */ }, [it8728] = { .name = "it8728", .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS - | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI, + | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_FIVE_FANS, .peci_mask = 0x07, }, [it8771] = { .name = "it8771", .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI, - /* PECI: guesswork */ - /* 12mV ADC (OHM) */ - /* 16 bit fans (OHM) */ + /* PECI: guesswork */ + /* 12mV ADC (OHM) */ + /* 16 bit fans (OHM) */ + /* three fans, always 16 bit (guesswork) */ .peci_mask = 0x07, }, [it8772] = { .name = "it8772", .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI, - /* PECI (coreboot) */ - /* 12mV ADC (HWSensors4, OHM) */ - /* 16 bit fans (HWSensors4, OHM) */ + /* PECI (coreboot) */ + /* 12mV ADC (HWSensors4, OHM) */ + /* 16 bit fans (HWSensors4, OHM) */ + /* three fans, always 16 bit (datasheet) */ .peci_mask = 0x07, }, [it8781] = { .name = "it8781", .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET - | FEAT_TEMP_OLD_PECI, + | FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG, .old_peci_mask = 0x4, }, [it8782] = { .name = "it8782", .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET - | FEAT_TEMP_OLD_PECI, + | FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG, .old_peci_mask = 0x4, }, [it8783] = { .name = "it8783", .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET - | FEAT_TEMP_OLD_PECI, + | FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG, .old_peci_mask = 0x4, }, [it8603] = { @@ -345,6 +351,8 @@ static const struct it87_devices it87_devices[] = { #define has_temp_old_peci(data, nr) \ (((data)->features & FEAT_TEMP_OLD_PECI) && \ ((data)->old_peci_mask & (1 << nr))) +#define has_fan16_config(data) ((data)->features & FEAT_FAN16_CONFIG) +#define has_five_fans(data) ((data)->features & FEAT_FIVE_FANS) struct it87_sio_data { enum chips type; @@ -2124,13 +2132,14 @@ static int it87_probe(struct platform_device *pdev) case it87: if (sio_data->revision >= 0x03) { data->features &= ~FEAT_OLD_AUTOPWM; - data->features |= FEAT_16BIT_FANS; + data->features |= FEAT_FAN16_CONFIG | FEAT_16BIT_FANS; } break; case it8712: if (sio_data->revision >= 0x08) { data->features &= ~FEAT_OLD_AUTOPWM; - data->features |= FEAT_16BIT_FANS; + data->features |= FEAT_FAN16_CONFIG | FEAT_16BIT_FANS | + FEAT_FIVE_FANS; } break; default: @@ -2463,12 +2472,8 @@ static void it87_init_device(struct platform_device *pdev) } data->has_fan = (data->fan_main_ctrl >> 4) & 0x07; - /* - * Set tachometers to 16-bit mode if needed. IT8603E, IT8728F, - * IT8771E (guesswork), and IT8772E have it by default. - */ - if (has_16bit_fans(data) && data->type != it8603 && data->type != it8728 - && data->type != it8771 && data->type != it8772) { + /* Set tachometers to 16-bit mode if needed */ + if (has_fan16_config(data)) { tmp = it87_read_value(data, IT87_REG_FAN_16BIT); if (~tmp & 0x07 & data->has_fan) { dev_dbg(&pdev->dev, @@ -2476,17 +2481,15 @@ static void it87_init_device(struct platform_device *pdev) it87_write_value(data, IT87_REG_FAN_16BIT, tmp | 0x07); } - /* - * IT8705F, IT8781F, IT8782F, and IT8783E/F only support - * three fans. - */ - if (data->type != it87 && data->type != it8781 && - data->type != it8782 && data->type != it8783) { - if (tmp & (1 << 4)) - data->has_fan |= (1 << 3); /* fan4 enabled */ - if (tmp & (1 << 5)) - data->has_fan |= (1 << 4); /* fan5 enabled */ - } + } + + /* Check for additional fans */ + if (has_five_fans(data)) { + tmp = it87_read_value(data, IT87_REG_FAN_16BIT); + if (tmp & (1 << 4)) + data->has_fan |= (1 << 3); /* fan4 enabled */ + if (tmp & (1 << 5)) + data->has_fan |= (1 << 4); /* fan5 enabled */ } /* Fan input pins may be used for alternative functions */ -- GitLab From 32dd7c409d52655c4ab68be8e0cdd0985c3fa138 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Thu, 12 Feb 2015 07:40:23 -0800 Subject: [PATCH 03544/11651] hwmon: (it87) Add feature flag for VID support Newer chips don't typically support VID inputs or control. Add a feature flag for VID support to simplify adding support for new chips. Reviewed-by: Jean Delvare Signed-off-by: Guenter Roeck --- drivers/hwmon/it87.c | 31 +++++++++++-------------------- 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index 48b48939d893..9ca10a73aee8 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c @@ -254,6 +254,7 @@ struct it87_devices { #define FEAT_TEMP_OLD_PECI (1 << 6) #define FEAT_FAN16_CONFIG (1 << 7) /* Need to enable 16-bit fans */ #define FEAT_FIVE_FANS (1 << 8) /* Supports five fans */ +#define FEAT_VID (1 << 9) /* Set if chip supports VID */ static const struct it87_devices it87_devices[] = { [it87] = { @@ -262,22 +263,23 @@ static const struct it87_devices it87_devices[] = { }, [it8712] = { .name = "it8712", - .features = FEAT_OLD_AUTOPWM, /* may need to overwrite */ + .features = FEAT_OLD_AUTOPWM | FEAT_VID, + /* may need to overwrite */ }, [it8716] = { .name = "it8716", - .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET + .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | FEAT_VID | FEAT_FAN16_CONFIG | FEAT_FIVE_FANS, }, [it8718] = { .name = "it8718", - .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET + .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | FEAT_VID | FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_FIVE_FANS, .old_peci_mask = 0x4, }, [it8720] = { .name = "it8720", - .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET + .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | FEAT_VID | FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_FIVE_FANS, .old_peci_mask = 0x4, }, @@ -353,6 +355,7 @@ static const struct it87_devices it87_devices[] = { ((data)->old_peci_mask & (1 << nr))) #define has_fan16_config(data) ((data)->features & FEAT_FAN16_CONFIG) #define has_five_fans(data) ((data)->features & FEAT_FIVE_FANS) +#define has_vid(data) ((data)->features & FEAT_VID) struct it87_sio_data { enum chips type; @@ -1822,19 +1825,17 @@ static int __init it87_find(unsigned short *address, if (sio_data->type != it8603) sio_data->skip_in |= (1 << 9); - /* Read GPIO config and VID value from LDN 7 (GPIO) */ - if (sio_data->type == it87) { - /* The IT8705F doesn't have VID pins at all */ + if (!(it87_devices[sio_data->type].features & FEAT_VID)) sio_data->skip_vid = 1; + /* Read GPIO config and VID value from LDN 7 (GPIO) */ + if (sio_data->type == it87) { /* The IT8705F has a different LD number for GPIO */ superio_select(5); sio_data->beep_pin = superio_inb(IT87_SIO_BEEP_PIN_REG) & 0x3f; } else if (sio_data->type == it8783) { int reg25, reg27, reg2a, reg2c, regef; - sio_data->skip_vid = 1; /* No VID */ - superio_select(GPIO); reg25 = superio_inb(IT87_SIO_GPIO1_REG); @@ -1900,7 +1901,6 @@ static int __init it87_find(unsigned short *address, } else if (sio_data->type == it8603) { int reg27, reg29; - sio_data->skip_vid = 1; /* No VID */ superio_select(GPIO); reg27 = superio_inb(IT87_SIO_GPIO3_REG); @@ -1936,16 +1936,7 @@ static int __init it87_find(unsigned short *address, superio_select(GPIO); reg = superio_inb(IT87_SIO_GPIO3_REG); - if (sio_data->type == it8721 || sio_data->type == it8728 || - sio_data->type == it8771 || sio_data->type == it8772 || - sio_data->type == it8781 || sio_data->type == it8782) { - /* - * IT8721F/IT8758E, IT8728F, IT8772F, IT8781F, and - * IT8782F don't have VID pins at all, not sure about - * the IT8771F. - */ - sio_data->skip_vid = 1; - } else { + if (!sio_data->skip_vid) { /* We need at least 4 VID pins */ if (reg & 0x0f) { pr_info("VID is disabled (pins used for GPIO)\n"); -- GitLab From a0c1424acb16326d9b741be8db7a3e776fc28b19 Mon Sep 17 00:00:00 2001 From: Thomas Lorblanches Date: Fri, 13 Feb 2015 13:19:06 +0100 Subject: [PATCH 03545/11651] hwmon: (it87) Add support for IT8786E IT8786E is mostly compatible with IT8771 / IT8772. Parameters determined by testing various combinations. Reviewed-by: Jean Delvare Signed-off-by: Thomas Lorblanches [Guenter Roeck: merged from github, addressed review comments] Signed-off-by: Guenter Roeck --- Documentation/hwmon/it87 | 6 +++++- drivers/hwmon/Kconfig | 4 ++-- drivers/hwmon/it87.c | 22 ++++++++++++++++------ 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/Documentation/hwmon/it87 b/Documentation/hwmon/it87 index 8e192fff10f4..19fbe775ae10 100644 --- a/Documentation/hwmon/it87 +++ b/Documentation/hwmon/it87 @@ -54,6 +54,10 @@ Supported chips: Prefix: 'it8783' Addresses scanned: from Super I/O config space (8 I/O ports) Datasheet: Not publicly available + * IT8786E + Prefix: 'it8786' + Addresses scanned: from Super I/O config space (8 I/O ports) + Datasheet: Not publicly available * SiS950 [clone of IT8705F] Prefix: 'it87' Addresses scanned: from Super I/O config space (8 I/O ports) @@ -100,7 +104,7 @@ Description This driver implements support for the IT8603E, IT8623E, IT8705F, IT8712F, IT8716F, IT8718F, IT8720F, IT8721F, IT8726F, IT8728F, IT8758E, IT8771E, -IT8772E, IT8781F, IT8782F, IT8783E/F, and SiS950 chips. +IT8772E, IT8781F, IT8782F, IT8783E/F, IT8786E, and SiS950 chips. These chips are 'Super I/O chips', supporting floppy disks, infrared ports, joysticks and other miscellaneous stuff. For hardware monitoring, they diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index e96c0ebaaceb..4b40ea79b20f 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -599,8 +599,8 @@ config SENSORS_IT87 help If you say yes here you get support for ITE IT8705F, IT8712F, IT8716F, IT8718F, IT8720F, IT8721F, IT8726F, IT8728F, IT8758E, - IT8771E, IT8772E, IT8781F, IT8782F, IT8783E/F and IT8603E - sensor chips, and the SiS950 clone. + IT8771E, IT8772E, IT8781F, IT8782F, IT8783E/F, IT8786E, + and IT8603E sensor chips, and the SiS950 clone. This driver can also be built as a module. If so, the module will be called it87. diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index 9ca10a73aee8..691067bbe07c 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c @@ -26,6 +26,7 @@ * IT8781F Super I/O chip w/LPC interface * IT8782F Super I/O chip w/LPC interface * IT8783E/F Super I/O chip w/LPC interface + * IT8786E Super I/O chip w/LPC interface * Sis950 A clone of the IT8705F * * Copyright (C) 2001 Chris Gauthron @@ -67,7 +68,7 @@ #define DRVNAME "it87" enum chips { it87, it8712, it8716, it8718, it8720, it8721, it8728, it8771, - it8772, it8781, it8782, it8783, it8603 }; + it8772, it8781, it8782, it8783, it8786, it8603 }; static unsigned short force_id; module_param(force_id, ushort, 0); @@ -150,6 +151,7 @@ static inline void superio_exit(void) #define IT8781F_DEVID 0x8781 #define IT8782F_DEVID 0x8782 #define IT8783E_DEVID 0x8783 +#define IT8786E_DEVID 0x8786 #define IT8603E_DEVID 0x8603 #define IT8623E_DEVID 0x8623 #define IT87_ACT_REG 0x30 @@ -335,6 +337,12 @@ static const struct it87_devices it87_devices[] = { | FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG, .old_peci_mask = 0x4, }, + [it8786] = { + .name = "it8786", + .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS + | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI, + .peci_mask = 0x07, + }, [it8603] = { .name = "it8603", .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS @@ -1789,6 +1797,9 @@ static int __init it87_find(unsigned short *address, case IT8783E_DEVID: sio_data->type = it8783; break; + case IT8786E_DEVID: + sio_data->type = it8786; + break; case IT8603E_DEVID: case IT8623E_DEVID: sio_data->type = it8603; @@ -1816,8 +1827,8 @@ static int __init it87_find(unsigned short *address, sio_data->revision = superio_inb(DEVREV) & 0x0f; pr_info("Found IT%04x%c chip at 0x%x, revision %d\n", chip_type, chip_type == 0x8771 || chip_type == 0x8772 || - chip_type == 0x8603 ? 'E' : 'F', *address, - sio_data->revision); + chip_type == 0x8786 || chip_type == 0x8603 ? 'E' : 'F', + *address, sio_data->revision); /* in8 (Vbat) is always internal */ sio_data->internal = (1 << 2); @@ -1987,9 +1998,8 @@ static int __init it87_find(unsigned short *address, if (reg & (1 << 0)) sio_data->internal |= (1 << 0); if ((reg & (1 << 1)) || sio_data->type == it8721 || - sio_data->type == it8728 || - sio_data->type == it8771 || - sio_data->type == it8772) + sio_data->type == it8728 || sio_data->type == it8771 || + sio_data->type == it8772 || sio_data->type == it8786) sio_data->internal |= (1 << 1); /* -- GitLab From e8433b42b60e799d55eb2476dc6cb3668c740063 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Fri, 13 Feb 2015 14:10:46 -0800 Subject: [PATCH 03546/11651] hwmon: (it87) No need to skip fan4 for IT8603 IT8603 only supports three fans, so it is not necessary to skip fan4. Reviewed-by: Jean Delvare Signed-off-by: Guenter Roeck --- drivers/hwmon/it87.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index 691067bbe07c..ab12dc2eb896 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c @@ -1932,10 +1932,6 @@ static int __init it87_find(unsigned short *address, sio_data->skip_in |= (1 << 5); /* No VIN5 */ sio_data->skip_in |= (1 << 6); /* No VIN6 */ - /* no fan4 */ - sio_data->skip_pwm |= (1 << 3); - sio_data->skip_fan |= (1 << 3); - sio_data->internal |= (1 << 1); /* in7 is VSB */ sio_data->internal |= (1 << 3); /* in9 is AVCC */ -- GitLab From 9c947d25c96ec93485d60f7b783403d518c1418d Mon Sep 17 00:00:00 2001 From: "Vadim V. Vlasov" Date: Fri, 27 Feb 2015 16:16:00 +0300 Subject: [PATCH 03547/11651] hwmon: Add Nuvoton NCT7904 hwmon driver The NCT7904D is a hardware monitor supporting up to 20 voltage sensors, internal temperature sensor, Intel PECI and AMD SB-TSI CPU temperature interface, up to 12 fan tachometer inputs, up to 4 fan control channels with SmartFan. Signed-off-by: Vadim V. Vlasov [Guenter Roeck: Fixed whitespace errors, dropped redundant comment] Signed-off-by: Guenter Roeck --- Documentation/hwmon/nct7904 | 60 ++++ drivers/hwmon/Kconfig | 10 + drivers/hwmon/Makefile | 1 + drivers/hwmon/nct7904.c | 592 ++++++++++++++++++++++++++++++++++++ 4 files changed, 663 insertions(+) create mode 100644 Documentation/hwmon/nct7904 create mode 100644 drivers/hwmon/nct7904.c diff --git a/Documentation/hwmon/nct7904 b/Documentation/hwmon/nct7904 new file mode 100644 index 000000000000..014f112e2a14 --- /dev/null +++ b/Documentation/hwmon/nct7904 @@ -0,0 +1,60 @@ +Kernel driver nct7904 +==================== + +Supported chip: + * Nuvoton NCT7904D + Prefix: nct7904 + Addresses: I2C 0x2d, 0x2e + Datasheet: Publicly available at Nuvoton website + http://www.nuvoton.com/ + +Author: Vadim V. Vlasov + + +Description +----------- + +The NCT7904D is a hardware monitor supporting up to 20 voltage sensors, +internal temperature sensor, Intel PECI and AMD SB-TSI CPU temperature +interface, up to 12 fan tachometer inputs, up to 4 fan control channels +with SmartFan. + + +Sysfs entries +------------- + +Currently, the driver supports only the following features: + +in[1-20]_input Input voltage measurements (mV) + +fan[1-12]_input Fan tachometer measurements (rpm) + +temp1_input Local temperature (1/1000 degree, + 0.125 degree resolution) + +temp[2-9]_input CPU temperatures (1/1000 degree, + 0.125 degree resolution) + +fan[1-4]_mode R/W, 0/1 for manual or SmartFan mode + Setting SmartFan mode is supported only if it has been + previously configured by BIOS (or configuration EEPROM) + +fan[1-4]_pwm R/O in SmartFan mode, R/W in manual control mode + +The driver checks sensor control registers and does not export the sensors +that are not enabled. Anyway, a sensor that is enabled may actually be not +connected and thus provide zero readings. + + +Limitations +----------- + +The following features are not supported in current version: + + - SmartFan control + - Watchdog + - GPIO + - external temperature sensors + - SMI + - min/max values + - many other... diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 4b40ea79b20f..2a5dd697c142 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -1145,6 +1145,16 @@ config SENSORS_NCT7802 This driver can also be built as a module. If so, the module will be called nct7802. +config SENSORS_NCT7904 + tristate "Nuvoton NCT7904" + depends on I2C + help + If you say yes here you get support for the Nuvoton NCT7904 + hardware monitoring chip, including manual fan speed control. + + This driver can also be built as a module. If so, the module + will be called nct7904. + config SENSORS_PCF8591 tristate "Philips PCF8591 ADC/DAC" depends on I2C diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 6c941472e707..b4a40f17e2aa 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile @@ -120,6 +120,7 @@ obj-$(CONFIG_SENSORS_MENF21BMC_HWMON) += menf21bmc_hwmon.o obj-$(CONFIG_SENSORS_NCT6683) += nct6683.o obj-$(CONFIG_SENSORS_NCT6775) += nct6775.o obj-$(CONFIG_SENSORS_NCT7802) += nct7802.o +obj-$(CONFIG_SENSORS_NCT7904) += nct7904.o obj-$(CONFIG_SENSORS_NTC_THERMISTOR) += ntc_thermistor.o obj-$(CONFIG_SENSORS_PC87360) += pc87360.o obj-$(CONFIG_SENSORS_PC87427) += pc87427.o diff --git a/drivers/hwmon/nct7904.c b/drivers/hwmon/nct7904.c new file mode 100644 index 000000000000..eaa8234e21d0 --- /dev/null +++ b/drivers/hwmon/nct7904.c @@ -0,0 +1,592 @@ +/* + * nct7904.c - driver for Nuvoton NCT7904D. + * + * Copyright (c) 2015 Kontron + * Author: Vadim V. Vlasov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 +#include +#include +#include +#include +#include +#include + +#define VENDOR_ID_REG 0x7A /* Any bank */ +#define NUVOTON_ID 0x50 +#define CHIP_ID_REG 0x7B /* Any bank */ +#define NCT7904_ID 0xC5 +#define DEVICE_ID_REG 0x7C /* Any bank */ + +#define BANK_SEL_REG 0xFF +#define BANK_0 0x00 +#define BANK_1 0x01 +#define BANK_2 0x02 +#define BANK_3 0x03 +#define BANK_4 0x04 +#define BANK_MAX 0x04 + +#define FANIN_MAX 12 /* Counted from 1 */ +#define VSEN_MAX 21 /* VSEN1..14, 3VDD, VBAT, V3VSB, + LTD (not a voltage), VSEN17..19 */ +#define FANCTL_MAX 4 /* Counted from 1 */ +#define TCPU_MAX 8 /* Counted from 1 */ +#define TEMP_MAX 4 /* Counted from 1 */ + +#define VT_ADC_CTRL0_REG 0x20 /* Bank 0 */ +#define VT_ADC_CTRL1_REG 0x21 /* Bank 0 */ +#define VT_ADC_CTRL2_REG 0x22 /* Bank 0 */ +#define FANIN_CTRL0_REG 0x24 +#define FANIN_CTRL1_REG 0x25 +#define DTS_T_CTRL0_REG 0x26 +#define DTS_T_CTRL1_REG 0x27 +#define VT_ADC_MD_REG 0x2E + +#define VSEN1_HV_REG 0x40 /* Bank 0; 2 regs (HV/LV) per sensor */ +#define TEMP_CH1_HV_REG 0x42 /* Bank 0; same as VSEN2_HV */ +#define LTD_HV_REG 0x62 /* Bank 0; 2 regs in VSEN range */ +#define FANIN1_HV_REG 0x80 /* Bank 0; 2 regs (HV/LV) per sensor */ +#define T_CPU1_HV_REG 0xA0 /* Bank 0; 2 regs (HV/LV) per sensor */ + +#define PRTS_REG 0x03 /* Bank 2 */ +#define FANCTL1_FMR_REG 0x00 /* Bank 3; 1 reg per channel */ +#define FANCTL1_OUT_REG 0x10 /* Bank 3; 1 reg per channel */ + +static const unsigned short normal_i2c[] = { + 0x2d, 0x2e, I2C_CLIENT_END +}; + +struct nct7904_data { + struct i2c_client *client; + struct mutex bank_lock; + int bank_sel; + u32 fanin_mask; + u32 vsen_mask; + u32 tcpu_mask; + u8 fan_mode[FANCTL_MAX]; +}; + +/* Access functions */ +static int nct7904_bank_lock(struct nct7904_data *data, unsigned bank) +{ + int ret; + + mutex_lock(&data->bank_lock); + if (data->bank_sel == bank) + return 0; + ret = i2c_smbus_write_byte_data(data->client, BANK_SEL_REG, bank); + if (ret == 0) + data->bank_sel = bank; + else + data->bank_sel = -1; + return ret; +} + +static inline void nct7904_bank_release(struct nct7904_data *data) +{ + mutex_unlock(&data->bank_lock); +} + +/* Read 1-byte register. Returns unsigned reg or -ERRNO on error. */ +static int nct7904_read_reg(struct nct7904_data *data, + unsigned bank, unsigned reg) +{ + struct i2c_client *client = data->client; + int ret; + + ret = nct7904_bank_lock(data, bank); + if (ret == 0) + ret = i2c_smbus_read_byte_data(client, reg); + + nct7904_bank_release(data); + return ret; +} + +/* + * Read 2-byte register. Returns register in big-endian format or + * -ERRNO on error. + */ +static int nct7904_read_reg16(struct nct7904_data *data, + unsigned bank, unsigned reg) +{ + struct i2c_client *client = data->client; + int ret, hi; + + ret = nct7904_bank_lock(data, bank); + if (ret == 0) { + ret = i2c_smbus_read_byte_data(client, reg); + if (ret >= 0) { + hi = ret; + ret = i2c_smbus_read_byte_data(client, reg + 1); + if (ret >= 0) + ret |= hi << 8; + } + } + + nct7904_bank_release(data); + return ret; +} + +/* Write 1-byte register. Returns 0 or -ERRNO on error. */ +static int nct7904_write_reg(struct nct7904_data *data, + unsigned bank, unsigned reg, u8 val) +{ + struct i2c_client *client = data->client; + int ret; + + ret = nct7904_bank_lock(data, bank); + if (ret == 0) + ret = i2c_smbus_write_byte_data(client, reg, val); + + nct7904_bank_release(data); + return ret; +} + +/* FANIN ATTR */ +static ssize_t show_fan(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + int index = to_sensor_dev_attr(devattr)->index; + struct nct7904_data *data = dev_get_drvdata(dev); + int ret; + unsigned cnt, rpm; + + ret = nct7904_read_reg16(data, BANK_0, FANIN1_HV_REG + index * 2); + if (ret < 0) + return ret; + cnt = ((ret & 0xff00) >> 3) | (ret & 0x1f); + if (cnt == 0x1fff) + rpm = 0; + else + rpm = 1350000 / cnt; + return sprintf(buf, "%u\n", rpm); +} + +static umode_t nct7904_fanin_is_visible(struct kobject *kobj, + struct attribute *a, int n) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct nct7904_data *data = dev_get_drvdata(dev); + + if (data->fanin_mask & (1 << n)) + return a->mode; + return 0; +} + +static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0); +static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1); +static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2); +static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 3); +static SENSOR_DEVICE_ATTR(fan5_input, S_IRUGO, show_fan, NULL, 4); +static SENSOR_DEVICE_ATTR(fan6_input, S_IRUGO, show_fan, NULL, 5); +static SENSOR_DEVICE_ATTR(fan7_input, S_IRUGO, show_fan, NULL, 6); +static SENSOR_DEVICE_ATTR(fan8_input, S_IRUGO, show_fan, NULL, 7); +static SENSOR_DEVICE_ATTR(fan9_input, S_IRUGO, show_fan, NULL, 8); +static SENSOR_DEVICE_ATTR(fan10_input, S_IRUGO, show_fan, NULL, 9); +static SENSOR_DEVICE_ATTR(fan11_input, S_IRUGO, show_fan, NULL, 10); +static SENSOR_DEVICE_ATTR(fan12_input, S_IRUGO, show_fan, NULL, 11); + +static struct attribute *nct7904_fanin_attrs[] = { + &sensor_dev_attr_fan1_input.dev_attr.attr, + &sensor_dev_attr_fan2_input.dev_attr.attr, + &sensor_dev_attr_fan3_input.dev_attr.attr, + &sensor_dev_attr_fan4_input.dev_attr.attr, + &sensor_dev_attr_fan5_input.dev_attr.attr, + &sensor_dev_attr_fan6_input.dev_attr.attr, + &sensor_dev_attr_fan7_input.dev_attr.attr, + &sensor_dev_attr_fan8_input.dev_attr.attr, + &sensor_dev_attr_fan9_input.dev_attr.attr, + &sensor_dev_attr_fan10_input.dev_attr.attr, + &sensor_dev_attr_fan11_input.dev_attr.attr, + &sensor_dev_attr_fan12_input.dev_attr.attr, + NULL +}; + +static const struct attribute_group nct7904_fanin_group = { + .attrs = nct7904_fanin_attrs, + .is_visible = nct7904_fanin_is_visible, +}; + +/* VSEN ATTR */ +static ssize_t show_voltage(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + int index = to_sensor_dev_attr(devattr)->index; + struct nct7904_data *data = dev_get_drvdata(dev); + int ret; + int volt; + + ret = nct7904_read_reg16(data, BANK_0, VSEN1_HV_REG + index * 2); + if (ret < 0) + return ret; + volt = ((ret & 0xff00) >> 5) | (ret & 0x7); + if (index < 14) + volt *= 2; /* 0.002V scale */ + else + volt *= 6; /* 0.006V scale */ + + return sprintf(buf, "%d\n", volt); +} + +static ssize_t show_ltemp(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + struct nct7904_data *data = dev_get_drvdata(dev); + int ret; + int temp; + + ret = nct7904_read_reg16(data, BANK_0, LTD_HV_REG); + if (ret < 0) + return ret; + temp = ((ret & 0xff00) >> 5) | (ret & 0x7); + temp = sign_extend32(temp, 10) * 125; + + return sprintf(buf, "%d\n", temp); +} + +static umode_t nct7904_vsen_is_visible(struct kobject *kobj, + struct attribute *a, int n) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct nct7904_data *data = dev_get_drvdata(dev); + + if (data->vsen_mask & (1 << n)) + return a->mode; + return 0; +} + +static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_voltage, NULL, 0); +static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_voltage, NULL, 1); +static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_voltage, NULL, 2); +static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, show_voltage, NULL, 3); +static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, show_voltage, NULL, 4); +static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, show_voltage, NULL, 5); +static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, show_voltage, NULL, 6); +static SENSOR_DEVICE_ATTR(in8_input, S_IRUGO, show_voltage, NULL, 7); +static SENSOR_DEVICE_ATTR(in9_input, S_IRUGO, show_voltage, NULL, 8); +static SENSOR_DEVICE_ATTR(in10_input, S_IRUGO, show_voltage, NULL, 9); +static SENSOR_DEVICE_ATTR(in11_input, S_IRUGO, show_voltage, NULL, 10); +static SENSOR_DEVICE_ATTR(in12_input, S_IRUGO, show_voltage, NULL, 11); +static SENSOR_DEVICE_ATTR(in13_input, S_IRUGO, show_voltage, NULL, 12); +static SENSOR_DEVICE_ATTR(in14_input, S_IRUGO, show_voltage, NULL, 13); +/* + * Next 3 voltage sensors have specific names in the Nuvoton doc + * (3VDD, VBAT, 3VSB) but we use vacant numbers for them. + */ +static SENSOR_DEVICE_ATTR(in15_input, S_IRUGO, show_voltage, NULL, 14); +static SENSOR_DEVICE_ATTR(in16_input, S_IRUGO, show_voltage, NULL, 15); +static SENSOR_DEVICE_ATTR(in20_input, S_IRUGO, show_voltage, NULL, 16); +/* This is not a voltage, but a local temperature sensor. */ +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_ltemp, NULL, 0); +static SENSOR_DEVICE_ATTR(in17_input, S_IRUGO, show_voltage, NULL, 18); +static SENSOR_DEVICE_ATTR(in18_input, S_IRUGO, show_voltage, NULL, 19); +static SENSOR_DEVICE_ATTR(in19_input, S_IRUGO, show_voltage, NULL, 20); + +static struct attribute *nct7904_vsen_attrs[] = { + &sensor_dev_attr_in1_input.dev_attr.attr, + &sensor_dev_attr_in2_input.dev_attr.attr, + &sensor_dev_attr_in3_input.dev_attr.attr, + &sensor_dev_attr_in4_input.dev_attr.attr, + &sensor_dev_attr_in5_input.dev_attr.attr, + &sensor_dev_attr_in6_input.dev_attr.attr, + &sensor_dev_attr_in7_input.dev_attr.attr, + &sensor_dev_attr_in8_input.dev_attr.attr, + &sensor_dev_attr_in9_input.dev_attr.attr, + &sensor_dev_attr_in10_input.dev_attr.attr, + &sensor_dev_attr_in11_input.dev_attr.attr, + &sensor_dev_attr_in12_input.dev_attr.attr, + &sensor_dev_attr_in13_input.dev_attr.attr, + &sensor_dev_attr_in14_input.dev_attr.attr, + &sensor_dev_attr_in15_input.dev_attr.attr, + &sensor_dev_attr_in16_input.dev_attr.attr, + &sensor_dev_attr_in20_input.dev_attr.attr, + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_in17_input.dev_attr.attr, + &sensor_dev_attr_in18_input.dev_attr.attr, + &sensor_dev_attr_in19_input.dev_attr.attr, + NULL +}; + +static const struct attribute_group nct7904_vsen_group = { + .attrs = nct7904_vsen_attrs, + .is_visible = nct7904_vsen_is_visible, +}; + +/* CPU_TEMP ATTR */ +static ssize_t show_tcpu(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + int index = to_sensor_dev_attr(devattr)->index; + struct nct7904_data *data = dev_get_drvdata(dev); + int ret; + int temp; + + ret = nct7904_read_reg16(data, BANK_0, T_CPU1_HV_REG + index * 2); + if (ret < 0) + return ret; + + temp = ((ret & 0xff00) >> 5) | (ret & 0x7); + temp = sign_extend32(temp, 10) * 125; + return sprintf(buf, "%d\n", temp); +} + +static umode_t nct7904_tcpu_is_visible(struct kobject *kobj, + struct attribute *a, int n) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct nct7904_data *data = dev_get_drvdata(dev); + + if (data->tcpu_mask & (1 << n)) + return a->mode; + return 0; +} + +/* "temp1_input" reserved for local temp */ +static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_tcpu, NULL, 0); +static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_tcpu, NULL, 1); +static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_tcpu, NULL, 2); +static SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO, show_tcpu, NULL, 3); +static SENSOR_DEVICE_ATTR(temp6_input, S_IRUGO, show_tcpu, NULL, 4); +static SENSOR_DEVICE_ATTR(temp7_input, S_IRUGO, show_tcpu, NULL, 5); +static SENSOR_DEVICE_ATTR(temp8_input, S_IRUGO, show_tcpu, NULL, 6); +static SENSOR_DEVICE_ATTR(temp9_input, S_IRUGO, show_tcpu, NULL, 7); + +static struct attribute *nct7904_tcpu_attrs[] = { + &sensor_dev_attr_temp2_input.dev_attr.attr, + &sensor_dev_attr_temp3_input.dev_attr.attr, + &sensor_dev_attr_temp4_input.dev_attr.attr, + &sensor_dev_attr_temp5_input.dev_attr.attr, + &sensor_dev_attr_temp6_input.dev_attr.attr, + &sensor_dev_attr_temp7_input.dev_attr.attr, + &sensor_dev_attr_temp8_input.dev_attr.attr, + &sensor_dev_attr_temp9_input.dev_attr.attr, + NULL +}; + +static const struct attribute_group nct7904_tcpu_group = { + .attrs = nct7904_tcpu_attrs, + .is_visible = nct7904_tcpu_is_visible, +}; + +/* PWM ATTR */ +static ssize_t store_pwm(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + int index = to_sensor_dev_attr(devattr)->index; + struct nct7904_data *data = dev_get_drvdata(dev); + unsigned long val; + int ret; + + if (kstrtoul(buf, 10, &val) < 0) + return -EINVAL; + if (val > 255) + return -EINVAL; + + ret = nct7904_write_reg(data, BANK_3, FANCTL1_OUT_REG + index, val); + + return ret ? ret : count; +} + +static ssize_t show_pwm(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + int index = to_sensor_dev_attr(devattr)->index; + struct nct7904_data *data = dev_get_drvdata(dev); + int val; + + val = nct7904_read_reg(data, BANK_3, FANCTL1_OUT_REG + index); + if (val < 0) + return val; + + return sprintf(buf, "%d\n", val); +} + +static ssize_t store_mode(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + int index = to_sensor_dev_attr(devattr)->index; + struct nct7904_data *data = dev_get_drvdata(dev); + unsigned long val; + int ret; + + if (kstrtoul(buf, 10, &val) < 0) + return -EINVAL; + if (val > 1 || (val && !data->fan_mode[index])) + return -EINVAL; + + ret = nct7904_write_reg(data, BANK_3, FANCTL1_FMR_REG + index, + val ? data->fan_mode[index] : 0); + + return ret ? ret : count; +} + +/* Return 0 for manual mode or 1 for SmartFan mode */ +static ssize_t show_mode(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + int index = to_sensor_dev_attr(devattr)->index; + struct nct7904_data *data = dev_get_drvdata(dev); + int val; + + val = nct7904_read_reg(data, BANK_3, FANCTL1_FMR_REG + index); + if (val < 0) + return val; + + return sprintf(buf, "%d\n", val ? 1 : 0); +} + +/* 2 attributes per channel: pwm and mode */ +static SENSOR_DEVICE_ATTR(fan1_pwm, S_IRUGO | S_IWUSR, + show_pwm, store_pwm, 0); +static SENSOR_DEVICE_ATTR(fan1_mode, S_IRUGO | S_IWUSR, + show_mode, store_mode, 0); +static SENSOR_DEVICE_ATTR(fan2_pwm, S_IRUGO | S_IWUSR, + show_pwm, store_pwm, 1); +static SENSOR_DEVICE_ATTR(fan2_mode, S_IRUGO | S_IWUSR, + show_mode, store_mode, 1); +static SENSOR_DEVICE_ATTR(fan3_pwm, S_IRUGO | S_IWUSR, + show_pwm, store_pwm, 2); +static SENSOR_DEVICE_ATTR(fan3_mode, S_IRUGO | S_IWUSR, + show_mode, store_mode, 2); +static SENSOR_DEVICE_ATTR(fan4_pwm, S_IRUGO | S_IWUSR, + show_pwm, store_pwm, 3); +static SENSOR_DEVICE_ATTR(fan4_mode, S_IRUGO | S_IWUSR, + show_mode, store_mode, 3); + +static struct attribute *nct7904_fanctl_attrs[] = { + &sensor_dev_attr_fan1_pwm.dev_attr.attr, + &sensor_dev_attr_fan1_mode.dev_attr.attr, + &sensor_dev_attr_fan2_pwm.dev_attr.attr, + &sensor_dev_attr_fan2_mode.dev_attr.attr, + &sensor_dev_attr_fan3_pwm.dev_attr.attr, + &sensor_dev_attr_fan3_mode.dev_attr.attr, + &sensor_dev_attr_fan4_pwm.dev_attr.attr, + &sensor_dev_attr_fan4_mode.dev_attr.attr, + NULL +}; + +static const struct attribute_group nct7904_fanctl_group = { + .attrs = nct7904_fanctl_attrs, +}; + +static const struct attribute_group *nct7904_groups[] = { + &nct7904_fanin_group, + &nct7904_vsen_group, + &nct7904_tcpu_group, + &nct7904_fanctl_group, + NULL +}; + +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int nct7904_detect(struct i2c_client *client, + struct i2c_board_info *info) +{ + struct i2c_adapter *adapter = client->adapter; + + if (!i2c_check_functionality(adapter, + I2C_FUNC_SMBUS_READ_BYTE | + I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) + return -ENODEV; + + /* Determine the chip type. */ + if (i2c_smbus_read_byte_data(client, VENDOR_ID_REG) != NUVOTON_ID || + i2c_smbus_read_byte_data(client, CHIP_ID_REG) != NCT7904_ID || + (i2c_smbus_read_byte_data(client, DEVICE_ID_REG) & 0xf0) != 0x50) + return -ENODEV; + + strlcpy(info->type, "nct7904", I2C_NAME_SIZE); + + return 0; +} + +static int nct7904_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct nct7904_data *data; + struct device *hwmon_dev; + struct device *dev = &client->dev; + int ret, i; + u32 mask; + + data = devm_kzalloc(dev, sizeof(struct nct7904_data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->client = client; + mutex_init(&data->bank_lock); + data->bank_sel = -1; + + /* Setup sensor groups. */ + /* FANIN attributes */ + ret = nct7904_read_reg16(data, BANK_0, FANIN_CTRL0_REG); + if (ret < 0) + return ret; + data->fanin_mask = (ret >> 8) | ((ret & 0xff) << 8); + + /* + * VSEN attributes + * + * Note: voltage sensors overlap with external temperature + * sensors. So, if we ever decide to support the latter + * we will have to adjust 'vsen_mask' accordingly. + */ + mask = 0; + ret = nct7904_read_reg16(data, BANK_0, VT_ADC_CTRL0_REG); + if (ret >= 0) + mask = (ret >> 8) | ((ret & 0xff) << 8); + ret = nct7904_read_reg(data, BANK_0, VT_ADC_CTRL2_REG); + if (ret >= 0) + mask |= (ret << 16); + data->vsen_mask = mask; + + /* CPU_TEMP attributes */ + ret = nct7904_read_reg16(data, BANK_0, DTS_T_CTRL0_REG); + if (ret < 0) + return ret; + data->tcpu_mask = ((ret >> 8) & 0xf) | ((ret & 0xf) << 4); + + for (i = 0; i < FANCTL_MAX; i++) { + ret = nct7904_read_reg(data, BANK_3, FANCTL1_FMR_REG + i); + if (ret < 0) + return ret; + data->fan_mode[i] = ret; + } + + hwmon_dev = + devm_hwmon_device_register_with_groups(dev, client->name, data, + nct7904_groups); + return PTR_ERR_OR_ZERO(hwmon_dev); +} + +static const struct i2c_device_id nct7904_id[] = { + {"nct7904", 0}, + {} +}; + +static struct i2c_driver nct7904_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "nct7904", + }, + .probe = nct7904_probe, + .id_table = nct7904_id, + .detect = nct7904_detect, + .address_list = normal_i2c, +}; + +module_i2c_driver(nct7904_driver); + +MODULE_AUTHOR("Vadim V. Vlasov "); +MODULE_DESCRIPTION("Hwmon driver for NUVOTON NCT7904"); +MODULE_LICENSE("GPL"); -- GitLab From 6552f327cab8eb6c773ba4f702cf6a371d1dc467 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Fri, 27 Feb 2015 08:23:37 -0800 Subject: [PATCH 03548/11651] hwmon: (nct7904) Strengthen detect function The bank register has five unused bits. Verify that those bits are zero to strengthen the detect function. Cc: Vadim V. Vlasov Signed-off-by: Guenter Roeck Reviewed-by: Jean Delvare --- drivers/hwmon/nct7904.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/hwmon/nct7904.c b/drivers/hwmon/nct7904.c index eaa8234e21d0..b77b82f24480 100644 --- a/drivers/hwmon/nct7904.c +++ b/drivers/hwmon/nct7904.c @@ -502,7 +502,8 @@ static int nct7904_detect(struct i2c_client *client, /* Determine the chip type. */ if (i2c_smbus_read_byte_data(client, VENDOR_ID_REG) != NUVOTON_ID || i2c_smbus_read_byte_data(client, CHIP_ID_REG) != NCT7904_ID || - (i2c_smbus_read_byte_data(client, DEVICE_ID_REG) & 0xf0) != 0x50) + (i2c_smbus_read_byte_data(client, DEVICE_ID_REG) & 0xf0) != 0x50 || + (i2c_smbus_read_byte_data(client, BANK_SEL_REG) & 0xf8) != 0x00) return -ENODEV; strlcpy(info->type, "nct7904", I2C_NAME_SIZE); -- GitLab From 73ef85f42da2df8b567fea109c67ed53db937bcc Mon Sep 17 00:00:00 2001 From: Simon Guinot Date: Wed, 25 Feb 2015 18:58:19 +0100 Subject: [PATCH 03549/11651] hwmon: (gpio-fan) allow to use alarm support alone from DT On some boards, such as the LaCie 2Big Network v2 or 2Big NAS (based on Marvell Kirkwood SoCs), an I2C fan controller is used but the alarm signal is wired to a separate GPIO. Unfortunately, the gpio-fan driver can't be used to handle GPIO alarm alone from DT: an error is returned if the "gpios" DT property is missing. This patch allows to use the gpio-fan driver even if the "alarm-gpios" DT property is defined alone. Signed-off-by: Simon Guinot Signed-off-by: Guenter Roeck --- .../devicetree/bindings/gpio/gpio-fan.txt | 6 ++- drivers/hwmon/gpio-fan.c | 44 ++++++++++--------- 2 files changed, 27 insertions(+), 23 deletions(-) diff --git a/Documentation/devicetree/bindings/gpio/gpio-fan.txt b/Documentation/devicetree/bindings/gpio/gpio-fan.txt index 2dd457a3469a..f996d428f132 100644 --- a/Documentation/devicetree/bindings/gpio/gpio-fan.txt +++ b/Documentation/devicetree/bindings/gpio/gpio-fan.txt @@ -2,16 +2,18 @@ Bindings for fan connected to GPIO lines Required properties: - compatible : "gpio-fan" + +Optional properties: - gpios: Specifies the pins that map to bits in the control value, ordered MSB-->LSB. - gpio-fan,speed-map: A mapping of possible fan RPM speeds and the control value that should be set to achieve them. This array must have the RPM values in ascending order. - -Optional properties: - alarm-gpios: This pin going active indicates something is wrong with the fan, and a udev event will be fired. +Note: At least one the "gpios" or "alarm-gpios" properties must be set. + Examples: gpio_fan { diff --git a/drivers/hwmon/gpio-fan.c b/drivers/hwmon/gpio-fan.c index 36abf814b8c7..c241f5b0b7cf 100644 --- a/drivers/hwmon/gpio-fan.c +++ b/drivers/hwmon/gpio-fan.c @@ -404,10 +404,32 @@ static int gpio_fan_get_of_pdata(struct device *dev, node = dev->of_node; + /* Alarm GPIO if one exists */ + if (of_gpio_named_count(node, "alarm-gpios") > 0) { + struct gpio_fan_alarm *alarm; + int val; + enum of_gpio_flags flags; + + alarm = devm_kzalloc(dev, sizeof(struct gpio_fan_alarm), + GFP_KERNEL); + if (!alarm) + return -ENOMEM; + + val = of_get_named_gpio_flags(node, "alarm-gpios", 0, &flags); + if (val < 0) + return val; + alarm->gpio = val; + alarm->active_low = flags & OF_GPIO_ACTIVE_LOW; + + pdata->alarm = alarm; + } + /* Fill GPIO pin array */ pdata->num_ctrl = of_gpio_count(node); if (pdata->num_ctrl <= 0) { - dev_err(dev, "gpios DT property empty / missing"); + if (pdata->alarm) + return 0; + dev_err(dev, "DT properties empty / missing"); return -ENODEV; } ctrl = devm_kzalloc(dev, pdata->num_ctrl * sizeof(unsigned), @@ -460,26 +482,6 @@ static int gpio_fan_get_of_pdata(struct device *dev, } pdata->speed = speed; - /* Alarm GPIO if one exists */ - if (of_gpio_named_count(node, "alarm-gpios") > 0) { - struct gpio_fan_alarm *alarm; - int val; - enum of_gpio_flags flags; - - alarm = devm_kzalloc(dev, sizeof(struct gpio_fan_alarm), - GFP_KERNEL); - if (!alarm) - return -ENOMEM; - - val = of_get_named_gpio_flags(node, "alarm-gpios", 0, &flags); - if (val < 0) - return val; - alarm->gpio = val; - alarm->active_low = flags & OF_GPIO_ACTIVE_LOW; - - pdata->alarm = alarm; - } - return 0; } -- GitLab From cb85ca332f4d72ca68464c55f63af0387f6bbdb1 Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Thu, 26 Feb 2015 14:59:35 +0100 Subject: [PATCH 03550/11651] hwmon: (pwm-fan) Extract __set_pwm() function to only modify PWM duty cycle It was necessary to decouple code handling writing to sysfs from the one responsible for setting PWM of the fan. Due to that, new __set_pwm() method was extracted, which is responsible for only setting new PWM duty cycle. Signed-off-by: Lukasz Majewski Signed-off-by: Guenter Roeck --- drivers/hwmon/pwm-fan.c | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/drivers/hwmon/pwm-fan.c b/drivers/hwmon/pwm-fan.c index 1991d9032c38..bd42d3996a86 100644 --- a/drivers/hwmon/pwm-fan.c +++ b/drivers/hwmon/pwm-fan.c @@ -33,20 +33,14 @@ struct pwm_fan_ctx { unsigned char pwm_value; }; -static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static int __set_pwm(struct pwm_fan_ctx *ctx, unsigned long pwm) { - struct pwm_fan_ctx *ctx = dev_get_drvdata(dev); - unsigned long pwm, duty; - ssize_t ret; - - if (kstrtoul(buf, 10, &pwm) || pwm > MAX_PWM) - return -EINVAL; + unsigned long duty; + int ret = 0; mutex_lock(&ctx->lock); - if (ctx->pwm_value == pwm) - goto exit_set_pwm_no_change; + goto exit_set_pwm_err; if (pwm == 0) { pwm_disable(ctx->pwm); @@ -66,13 +60,28 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, exit_set_pwm: ctx->pwm_value = pwm; -exit_set_pwm_no_change: - ret = count; exit_set_pwm_err: mutex_unlock(&ctx->lock); return ret; } +static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct pwm_fan_ctx *ctx = dev_get_drvdata(dev); + unsigned long pwm; + int ret; + + if (kstrtoul(buf, 10, &pwm) || pwm > MAX_PWM) + return -EINVAL; + + ret = __set_pwm(ctx, pwm); + if (ret) + return ret; + + return count; +} + static ssize_t show_pwm(struct device *dev, struct device_attribute *attr, char *buf) { -- GitLab From 2e5219c77183be47eb9ae4b1a4195e008d196c73 Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Thu, 26 Feb 2015 14:59:36 +0100 Subject: [PATCH 03551/11651] hwmon: (pwm-fan) Read PWM FAN configuration from device tree This patch provides code for reading PWM FAN configuration data via device tree. The pwm-fan can work with full speed when configuration is not provided. However, errors are propagated when wrong DT bindings are found. Additionally the struct pwm_fan_ctx has been extended. Signed-off-by: Lukasz Majewski Signed-off-by: Guenter Roeck --- drivers/hwmon/pwm-fan.c | 50 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/drivers/hwmon/pwm-fan.c b/drivers/hwmon/pwm-fan.c index bd42d3996a86..e6ed3532deac 100644 --- a/drivers/hwmon/pwm-fan.c +++ b/drivers/hwmon/pwm-fan.c @@ -30,7 +30,10 @@ struct pwm_fan_ctx { struct mutex lock; struct pwm_device *pwm; - unsigned char pwm_value; + unsigned int pwm_value; + unsigned int pwm_fan_state; + unsigned int pwm_fan_max_state; + unsigned int *pwm_fan_cooling_levels; }; static int __set_pwm(struct pwm_fan_ctx *ctx, unsigned long pwm) @@ -100,6 +103,46 @@ static struct attribute *pwm_fan_attrs[] = { ATTRIBUTE_GROUPS(pwm_fan); +int pwm_fan_of_get_cooling_data(struct device *dev, struct pwm_fan_ctx *ctx) +{ + struct device_node *np = dev->of_node; + int num, i, ret; + + if (!of_find_property(np, "cooling-levels", NULL)) + return 0; + + ret = of_property_count_u32_elems(np, "cooling-levels"); + if (ret <= 0) { + dev_err(dev, "Wrong data!\n"); + return ret ? : -EINVAL; + } + + num = ret; + ctx->pwm_fan_cooling_levels = devm_kzalloc(dev, num * sizeof(u32), + GFP_KERNEL); + if (!ctx->pwm_fan_cooling_levels) + return -ENOMEM; + + ret = of_property_read_u32_array(np, "cooling-levels", + ctx->pwm_fan_cooling_levels, num); + if (ret) { + dev_err(dev, "Property 'cooling-levels' cannot be read!\n"); + return ret; + } + + for (i = 0; i < num; i++) { + if (ctx->pwm_fan_cooling_levels[i] > MAX_PWM) { + dev_err(dev, "PWM fan state[%d]:%d > %d\n", i, + ctx->pwm_fan_cooling_levels[i], MAX_PWM); + return -EINVAL; + } + } + + ctx->pwm_fan_max_state = num - 1; + + return 0; +} + static int pwm_fan_probe(struct platform_device *pdev) { struct device *hwmon; @@ -145,6 +188,11 @@ static int pwm_fan_probe(struct platform_device *pdev) pwm_disable(ctx->pwm); return PTR_ERR(hwmon); } + + ret = pwm_fan_of_get_cooling_data(&pdev->dev, ctx); + if (ret) + return ret; + return 0; } -- GitLab From b6bddec01932b94a20b6a7bbb7ed9d98e82ec162 Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Thu, 26 Feb 2015 14:59:37 +0100 Subject: [PATCH 03552/11651] hwmon: (pwm-fan) Add support for using PWM FAN as a cooling device The PWM FAN device can now be used as a thermal cooling device. Signed-off-by: Lukasz Majewski Acked-by: Eduardo Valentin Signed-off-by: Guenter Roeck --- drivers/hwmon/pwm-fan.c | 89 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 88 insertions(+), 1 deletion(-) diff --git a/drivers/hwmon/pwm-fan.c b/drivers/hwmon/pwm-fan.c index e6ed3532deac..7c83dc4c8dbd 100644 --- a/drivers/hwmon/pwm-fan.c +++ b/drivers/hwmon/pwm-fan.c @@ -24,6 +24,7 @@ #include #include #include +#include #define MAX_PWM 255 @@ -34,6 +35,7 @@ struct pwm_fan_ctx { unsigned int pwm_fan_state; unsigned int pwm_fan_max_state; unsigned int *pwm_fan_cooling_levels; + struct thermal_cooling_device *cdev; }; static int __set_pwm(struct pwm_fan_ctx *ctx, unsigned long pwm) @@ -68,6 +70,17 @@ exit_set_pwm_err: return ret; } +static void pwm_fan_update_state(struct pwm_fan_ctx *ctx, unsigned long pwm) +{ + int i; + + for (i = 0; i < ctx->pwm_fan_max_state; ++i) + if (pwm < ctx->pwm_fan_cooling_levels[i + 1]) + break; + + ctx->pwm_fan_state = i; +} + static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { @@ -82,6 +95,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, if (ret) return ret; + pwm_fan_update_state(ctx, pwm); return count; } @@ -103,6 +117,62 @@ static struct attribute *pwm_fan_attrs[] = { ATTRIBUTE_GROUPS(pwm_fan); +/* thermal cooling device callbacks */ +static int pwm_fan_get_max_state(struct thermal_cooling_device *cdev, + unsigned long *state) +{ + struct pwm_fan_ctx *ctx = cdev->devdata; + + if (!ctx) + return -EINVAL; + + *state = ctx->pwm_fan_max_state; + + return 0; +} + +static int pwm_fan_get_cur_state(struct thermal_cooling_device *cdev, + unsigned long *state) +{ + struct pwm_fan_ctx *ctx = cdev->devdata; + + if (!ctx) + return -EINVAL; + + *state = ctx->pwm_fan_state; + + return 0; +} + +static int +pwm_fan_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state) +{ + struct pwm_fan_ctx *ctx = cdev->devdata; + int ret; + + if (!ctx || (state > ctx->pwm_fan_max_state)) + return -EINVAL; + + if (state == ctx->pwm_fan_state) + return 0; + + ret = __set_pwm(ctx, ctx->pwm_fan_cooling_levels[state]); + if (ret) { + dev_err(&cdev->device, "Cannot set pwm!\n"); + return ret; + } + + ctx->pwm_fan_state = state; + + return ret; +} + +static const struct thermal_cooling_device_ops pwm_fan_cooling_ops = { + .get_max_state = pwm_fan_get_max_state, + .get_cur_state = pwm_fan_get_cur_state, + .set_cur_state = pwm_fan_set_cur_state, +}; + int pwm_fan_of_get_cooling_data(struct device *dev, struct pwm_fan_ctx *ctx) { struct device_node *np = dev->of_node; @@ -145,8 +215,9 @@ int pwm_fan_of_get_cooling_data(struct device *dev, struct pwm_fan_ctx *ctx) static int pwm_fan_probe(struct platform_device *pdev) { - struct device *hwmon; + struct thermal_cooling_device *cdev; struct pwm_fan_ctx *ctx; + struct device *hwmon; int duty_cycle; int ret; @@ -193,6 +264,21 @@ static int pwm_fan_probe(struct platform_device *pdev) if (ret) return ret; + ctx->pwm_fan_state = ctx->pwm_fan_max_state; + if (IS_ENABLED(CONFIG_THERMAL)) { + cdev = thermal_of_cooling_device_register(pdev->dev.of_node, + "pwm-fan", ctx, + &pwm_fan_cooling_ops); + if (IS_ERR(cdev)) { + dev_err(&pdev->dev, + "Failed to register pwm-fan as cooling device"); + pwm_disable(ctx->pwm); + return PTR_ERR(cdev); + } + ctx->cdev = cdev; + thermal_cdev_update(cdev); + } + return 0; } @@ -200,6 +286,7 @@ static int pwm_fan_remove(struct platform_device *pdev) { struct pwm_fan_ctx *ctx = platform_get_drvdata(pdev); + thermal_cooling_device_unregister(ctx->cdev); if (ctx->pwm_value) pwm_disable(ctx->pwm); return 0; -- GitLab From b5cf88e46badea6d600d8515edea23814e03444d Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Thu, 8 Jan 2015 12:05:03 -0600 Subject: [PATCH 03553/11651] (gpio-fan): Add thermal control hooks Allow gpio-fan to be used as thermal cooling device for platforms that use GPIO maps to control fans. As part of this change, we make the shutdown and remove logic the same as well. Signed-off-by: Nishanth Menon Acked-by: Eduardo Valentin Signed-off-by: Guenter Roeck --- .../devicetree/bindings/gpio/gpio-fan.txt | 13 +++ drivers/hwmon/gpio-fan.c | 83 +++++++++++++++++-- 2 files changed, 89 insertions(+), 7 deletions(-) diff --git a/Documentation/devicetree/bindings/gpio/gpio-fan.txt b/Documentation/devicetree/bindings/gpio/gpio-fan.txt index f996d428f132..439a7430fc68 100644 --- a/Documentation/devicetree/bindings/gpio/gpio-fan.txt +++ b/Documentation/devicetree/bindings/gpio/gpio-fan.txt @@ -11,6 +11,9 @@ Optional properties: must have the RPM values in ascending order. - alarm-gpios: This pin going active indicates something is wrong with the fan, and a udev event will be fired. +- cooling-cells: If used as a cooling device, must be <2> + Also see: Documentation/devicetree/bindings/thermal/thermal.txt + min and max states are derived from the speed-map of the fan. Note: At least one the "gpios" or "alarm-gpios" properties must be set. @@ -25,3 +28,13 @@ Examples: 6000 2>; alarm-gpios = <&gpio1 15 1>; }; + gpio_fan_cool: gpio_fan { + compatible = "gpio-fan"; + gpios = <&gpio2 14 1 + &gpio2 13 1>; + gpio-fan,speed-map = <0 0>, + <3000 1>, + <6000 2>; + alarm-gpios = <&gpio2 15 1>; + #cooling-cells = <2>; /* min followed by max */ + }; diff --git a/drivers/hwmon/gpio-fan.c b/drivers/hwmon/gpio-fan.c index c241f5b0b7cf..632b8e3ff5bf 100644 --- a/drivers/hwmon/gpio-fan.c +++ b/drivers/hwmon/gpio-fan.c @@ -34,10 +34,13 @@ #include #include #include +#include struct gpio_fan_data { struct platform_device *pdev; struct device *hwmon_dev; + /* Cooling device if any */ + struct thermal_cooling_device *cdev; struct mutex lock; /* lock GPIOs operations. */ int num_ctrl; unsigned *ctrl; @@ -387,6 +390,53 @@ static int fan_ctrl_init(struct gpio_fan_data *fan_data, return 0; } +static int gpio_fan_get_max_state(struct thermal_cooling_device *cdev, + unsigned long *state) +{ + struct gpio_fan_data *fan_data = cdev->devdata; + + if (!fan_data) + return -EINVAL; + + *state = fan_data->num_speed - 1; + return 0; +} + +static int gpio_fan_get_cur_state(struct thermal_cooling_device *cdev, + unsigned long *state) +{ + struct gpio_fan_data *fan_data = cdev->devdata; + int r; + + if (!fan_data) + return -EINVAL; + + r = get_fan_speed_index(fan_data); + if (r < 0) + return r; + + *state = r; + return 0; +} + +static int gpio_fan_set_cur_state(struct thermal_cooling_device *cdev, + unsigned long state) +{ + struct gpio_fan_data *fan_data = cdev->devdata; + + if (!fan_data) + return -EINVAL; + + set_fan_speed(fan_data, state); + return 0; +} + +static const struct thermal_cooling_device_ops gpio_fan_cool_ops = { + .get_max_state = gpio_fan_get_max_state, + .get_cur_state = gpio_fan_get_cur_state, + .set_cur_state = gpio_fan_set_cur_state, +}; + #ifdef CONFIG_OF_GPIO /* * Translate OpenFirmware node properties into platform_data @@ -497,6 +547,11 @@ static int gpio_fan_probe(struct platform_device *pdev) struct gpio_fan_data *fan_data; struct gpio_fan_platform_data *pdata = dev_get_platdata(&pdev->dev); + fan_data = devm_kzalloc(&pdev->dev, sizeof(struct gpio_fan_data), + GFP_KERNEL); + if (!fan_data) + return -ENOMEM; + #ifdef CONFIG_OF_GPIO if (!pdata) { pdata = devm_kzalloc(&pdev->dev, @@ -508,17 +563,20 @@ static int gpio_fan_probe(struct platform_device *pdev) err = gpio_fan_get_of_pdata(&pdev->dev, pdata); if (err) return err; + /* Optional cooling device register for Device tree platforms */ + fan_data->cdev = + thermal_of_cooling_device_register(pdev->dev.of_node, + "gpio-fan", fan_data, + &gpio_fan_cool_ops); } #else /* CONFIG_OF_GPIO */ if (!pdata) return -EINVAL; + /* Optional cooling device register for non Device tree platforms */ + fan_data->cdev = thermal_cooling_device_register("gpio-fan", fan_data, + &gpio_fan_cool_ops); #endif /* CONFIG_OF_GPIO */ - fan_data = devm_kzalloc(&pdev->dev, sizeof(struct gpio_fan_data), - GFP_KERNEL); - if (!fan_data) - return -ENOMEM; - fan_data->pdev = pdev; platform_set_drvdata(pdev, fan_data); mutex_init(&fan_data->lock); @@ -552,12 +610,22 @@ static int gpio_fan_probe(struct platform_device *pdev) return 0; } -static void gpio_fan_shutdown(struct platform_device *pdev) +static int gpio_fan_remove(struct platform_device *pdev) { - struct gpio_fan_data *fan_data = dev_get_drvdata(&pdev->dev); + struct gpio_fan_data *fan_data = platform_get_drvdata(pdev); + + if (!IS_ERR(fan_data->cdev)) + thermal_cooling_device_unregister(fan_data->cdev); if (fan_data->ctrl) set_fan_speed(fan_data, 0); + + return 0; +} + +static void gpio_fan_shutdown(struct platform_device *pdev) +{ + gpio_fan_remove(pdev); } #ifdef CONFIG_PM_SLEEP @@ -591,6 +659,7 @@ static SIMPLE_DEV_PM_OPS(gpio_fan_pm, gpio_fan_suspend, gpio_fan_resume); static struct platform_driver gpio_fan_driver = { .probe = gpio_fan_probe, + .remove = gpio_fan_remove, .shutdown = gpio_fan_shutdown, .driver = { .name = "gpio-fan", -- GitLab From de52b049d6d5af635d628d17fcb466d53a9617af Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Wed, 4 Mar 2015 09:51:05 -0800 Subject: [PATCH 03554/11651] hwmon: (pwm-fan) Declare pwm_fan_of_get_cooling_data static Address the following sparse warnings. drivers/hwmon/pwm-fan.c:176:5: warning: symbol 'pwm_fan_of_get_cooling_data' was not declared. Should it be static? drivers/hwmon/pwm-fan.c:176:5: warning: no previous prototype for 'pwm_fan_of_get_cooling_data' pwm_fan_of_get_cooling_data is only used in the pwm-fan driver and thus should be declared static. Cc: Lukasz Majewski Acked-by: Lukasz Majewski Signed-off-by: Guenter Roeck --- drivers/hwmon/pwm-fan.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/hwmon/pwm-fan.c b/drivers/hwmon/pwm-fan.c index 7c83dc4c8dbd..417072863ebe 100644 --- a/drivers/hwmon/pwm-fan.c +++ b/drivers/hwmon/pwm-fan.c @@ -173,7 +173,8 @@ static const struct thermal_cooling_device_ops pwm_fan_cooling_ops = { .set_cur_state = pwm_fan_set_cur_state, }; -int pwm_fan_of_get_cooling_data(struct device *dev, struct pwm_fan_ctx *ctx) +static int pwm_fan_of_get_cooling_data(struct device *dev, + struct pwm_fan_ctx *ctx) { struct device_node *np = dev->of_node; int num, i, ret; -- GitLab From 18fd303fea21c98b0b72534e6db47e80d12bf311 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 5 Mar 2015 15:27:34 -0800 Subject: [PATCH 03555/11651] hwmon: (pwm-fan) Fix build when THERMAL=m Fix build errors when CONFIG_THERMAL=m and SENSORS_PWM_FAN=y by restricting SENSORS_PWM_FAN to 'm' when THERMAL=m. drivers/built-in.o: In function `pwm_fan_remove': pwm-fan.c:(.text+0x22ba58): undefined reference to `thermal_cooling_device_unregister' drivers/built-in.o: In function `pwm_fan_probe': pwm-fan.c:(.text+0x22bebb): undefined reference to `thermal_of_cooling_device_register' pwm-fan.c:(.text+0x22bf11): undefined reference to `thermal_cdev_update' Signed-off-by: Randy Dunlap Cc: Kamil Debski Signed-off-by: Guenter Roeck --- drivers/hwmon/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 2a5dd697c142..c7db7ded9db7 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -1174,6 +1174,7 @@ source drivers/hwmon/pmbus/Kconfig config SENSORS_PWM_FAN tristate "PWM fan" depends on (PWM && OF) || COMPILE_TEST + depends on THERMAL || THERMAL=n help If you say yes here you get support for fans connected to PWM lines. The driver uses the generic PWM interface, thus it will work on a -- GitLab From eaef1279fa349db0cbec953e745d91db019a729e Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sun, 15 Feb 2015 18:01:41 +0200 Subject: [PATCH 03556/11651] pinctrl: sh-pfc: Remove r8a7791 platform_device_id entry The r8a7791 platform is now DT-only, the driver doesn't need to match platform devices by name anymore. Remove the corresponding platform_device_id entry. Signed-off-by: Laurent Pinchart Acked-by: Simon Horman Acked-by: Geert Uytterhoeven Signed-off-by: Linus Walleij --- drivers/pinctrl/sh-pfc/core.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c index a56280814a3f..e2c442b64a2c 100644 --- a/drivers/pinctrl/sh-pfc/core.c +++ b/drivers/pinctrl/sh-pfc/core.c @@ -597,9 +597,6 @@ static const struct platform_device_id sh_pfc_id_table[] = { #ifdef CONFIG_PINCTRL_PFC_R8A7790 { "pfc-r8a7790", (kernel_ulong_t)&r8a7790_pinmux_info }, #endif -#ifdef CONFIG_PINCTRL_PFC_R8A7791 - { "pfc-r8a7791", (kernel_ulong_t)&r8a7791_pinmux_info }, -#endif #ifdef CONFIG_PINCTRL_PFC_SH7203 { "pfc-sh7203", (kernel_ulong_t)&sh7203_pinmux_info }, #endif -- GitLab From 05c5f265c6f72750d2a60f75ff3cfefe47379210 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 27 Feb 2015 18:38:02 +0100 Subject: [PATCH 03557/11651] pinctrl: sh-pfc: Do not overwrite bias configuration After the last user of the in_pd/in_pu bias parameters of the _PCRH() macro was removed in commit 80da8e02d22caaef ("sh-pfc: r8a7740: Add bias (pull-up/down) pinconf support"), bias parameters are supposed to be configured using the generic pinctl mechanism, which calls the .set_bias() method. However, the PORTCR() macro still represents the control register as consisting of two 4-bit fields. Hence the bias configuration in the uppermost 2 bits is always overwritten with zeroes when a pin is configured for GPIO, disabling any previously configured bias. Use the variable config register macro instead, to represent the register as having 4 fields, and to make sure only the input/output control and function fields are touched. This affects R-Mobile APE6 (r8a73a4), R-Mobile A1 (r8a7740), SH-Mobile AP4 (sh7372), and SH-Mobile AG5 (sh73a0). Signed-off-by: Geert Uytterhoeven Acked-by: Laurent Pinchart Signed-off-by: Linus Walleij --- drivers/pinctrl/sh-pfc/sh_pfc.h | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/drivers/pinctrl/sh-pfc/sh_pfc.h b/drivers/pinctrl/sh-pfc/sh_pfc.h index c83728626906..ed5cf4192fa1 100644 --- a/drivers/pinctrl/sh-pfc/sh_pfc.h +++ b/drivers/pinctrl/sh-pfc/sh_pfc.h @@ -302,20 +302,21 @@ struct sh_pfc_soc_info { /* * PORTnCR macro */ -#define _PCRH(in, in_pd, in_pu, out) \ - 0, (out), (in), 0, \ - 0, 0, 0, 0, \ - 0, 0, (in_pd), 0, \ - 0, 0, (in_pu), 0 - #define PORTCR(nr, reg) \ { \ - PINMUX_CFG_REG("PORT" nr "CR", reg, 8, 4) { \ - _PCRH(PORT##nr##_IN, 0, 0, PORT##nr##_OUT), \ - PORT##nr##_FN0, PORT##nr##_FN1, \ - PORT##nr##_FN2, PORT##nr##_FN3, \ - PORT##nr##_FN4, PORT##nr##_FN5, \ - PORT##nr##_FN6, PORT##nr##_FN7 } \ + PINMUX_CFG_REG_VAR("PORT" nr "CR", reg, 8, 2, 2, 1, 3) {\ + /* PULMD[1:0], handled by .set_bias() */ \ + 0, 0, 0, 0, \ + /* IE and OE */ \ + 0, PORT##nr##_OUT, PORT##nr##_IN, 0, \ + /* SEC, not supported */ \ + 0, 0, \ + /* PTMD[2:0] */ \ + PORT##nr##_FN0, PORT##nr##_FN1, \ + PORT##nr##_FN2, PORT##nr##_FN3, \ + PORT##nr##_FN4, PORT##nr##_FN5, \ + PORT##nr##_FN6, PORT##nr##_FN7 \ + } \ } #endif /* __SH_PFC_H */ -- GitLab From ace16867fa2b312b8a4a6f4ac5506dfbd791be34 Mon Sep 17 00:00:00 2001 From: Sanjeev Sharma Date: Tue, 3 Feb 2015 16:11:59 +0530 Subject: [PATCH 03558/11651] pinctrl: freescale: make of_device_id array const Make of_device_id array const. Signed-off-by: Sanjeev Sharma Signed-off-by: Linus Walleij --- drivers/pinctrl/freescale/pinctrl-vf610.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/freescale/pinctrl-vf610.c b/drivers/pinctrl/freescale/pinctrl-vf610.c index fc86276892fd..37a037543d29 100644 --- a/drivers/pinctrl/freescale/pinctrl-vf610.c +++ b/drivers/pinctrl/freescale/pinctrl-vf610.c @@ -302,7 +302,7 @@ static struct imx_pinctrl_soc_info vf610_pinctrl_info = { .flags = SHARE_MUX_CONF_REG, }; -static struct of_device_id vf610_pinctrl_of_match[] = { +static const struct of_device_id vf610_pinctrl_of_match[] = { { .compatible = "fsl,vf610-iomuxc", }, { /* sentinel */ } }; -- GitLab From af033612351b1850492ed7edbdbab4f9a869266f Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Tue, 3 Mar 2015 15:41:06 +0100 Subject: [PATCH 03559/11651] devicetree: bindings: add Device Tree bindings for Armada 39x pin-muxing controller This commit adds the Device Tree binding documentation to describe the pin-muxing controller of the Marvell Armada 39x processors. Two variants are supported for the moment: the 88F6920 (Armada 390) and 88F6928 (Armada 398). Signed-off-by: Thomas Petazzoni Signed-off-by: Linus Walleij --- .../pinctrl/marvell,armada-39x-pinctrl.txt | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 Documentation/devicetree/bindings/pinctrl/marvell,armada-39x-pinctrl.txt diff --git a/Documentation/devicetree/bindings/pinctrl/marvell,armada-39x-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/marvell,armada-39x-pinctrl.txt new file mode 100644 index 000000000000..5b1a9dc004f4 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/marvell,armada-39x-pinctrl.txt @@ -0,0 +1,78 @@ +* Marvell Armada 39x SoC pinctrl driver for mpp + +Please refer to marvell,mvebu-pinctrl.txt in this directory for common binding +part and usage. + +Required properties: +- compatible: "marvell,88f6920-pinctrl", "marvell,88f6928-pinctrl" + depending on the specific variant of the SoC being used. +- reg: register specifier of MPP registers + +Available mpp pins/groups and functions: +Note: brackets (x) are not part of the mpp name for marvell,function and given +only for more detailed description in this document. + +name pins functions +================================================================================ +mpp0 0 gpio, ua0(rxd) +mpp1 1 gpio, ua0(txd) +mpp2 2 gpio, i2c0(sck) +mpp3 3 gpio, i2c0(sda) +mpp4 4 gpio, ua1(txd), ua0(rts), smi(mdc) +mpp5 5 gpio, ua1(rxd), ua0(cts), smi(mdio) +mpp6 6 gpio, dev(cs3), xsmi(mdio) +mpp7 7 gpio, dev(ad9), xsmi(mdc) +mpp8 8 gpio, dev(ad10), ptp(trig) +mpp9 9 gpio, dev(ad11), ptp(clk) +mpp10 10 gpio, dev(ad12), ptp(event) +mpp11 11 gpio, dev(ad13), led(clk) +mpp12 12 gpio, pcie0(rstout), dev(ad14), led(stb) +mpp13 13 gpio, dev(ad15), led(data) +mpp14 14 gpio, m(vtt), dev(wen1), ua1(txd) +mpp15 15 gpio, pcie0(rstout), spi0(mosi), i2c1(sck) +mpp16 16 gpio, m(decc), spi0(miso), i2c1(sda) +mpp17 17 gpio, ua1(rxd), spi0(sck), smi(mdio) +mpp18 18 gpio, ua1(txd), spi0(cs0), i2c2(sck) +mpp19 19 gpio, sata1(present) [1], ua0(cts), ua1(rxd), i2c2(sda) +mpp20 20 gpio, sata0(present) [1], ua0(rts), ua1(txd), smi(mdc) +mpp21 21 gpio, spi0(cs1), sata0(present) [1], sd(cmd), dev(bootcs), ge(rxd0) +mpp22 22 gpio, spi0(mosi), dev(ad0) +mpp23 23 gpio, spi0(sck), dev(ad2) +mpp24 24 gpio, spi0(miso), ua0(cts), ua1(rxd), sd(d4), dev(readyn) +mpp25 25 gpio, spi0(cs0), ua0(rts), ua1(txd), sd(d5), dev(cs0) +mpp26 26 gpio, spi0(cs2), i2c1(sck), sd(d6), dev(cs1) +mpp27 27 gpio, spi0(cs3), i2c1(sda), sd(d7), dev(cs2), ge(txclkout) +mpp28 28 gpio, sd(clk), dev(ad5), ge(txd0) +mpp29 29 gpio, dev(ale0), ge(txd1) +mpp30 30 gpio, dev(oen), ge(txd2) +mpp31 31 gpio, dev(ale1), ge(txd3) +mpp32 32 gpio, dev(wen0), ge(txctl) +mpp33 33 gpio, m(decc), dev(ad3) +mpp34 34 gpio, dev(ad1) +mpp35 35 gpio, ref(clk), dev(a1) +mpp36 36 gpio, dev(a0) +mpp37 37 gpio, sd(d3), dev(ad8), ge(rxclk) +mpp38 38 gpio, ref(clk), sd(d0), dev(ad4), ge(rxd1) +mpp39 39 gpio, i2c1(sck), ua0(cts), sd(d1), dev(a2), ge(rxd2) +mpp40 40 gpio, i2c1(sda), ua0(rts), sd(d2), dev(ad6), ge(rxd3) +mpp41 41 gpio, ua1(rxd), ua0(cts), spi1(cs3), dev(burstn), nd(rbn0), ge(rxctl) +mpp42 42 gpio, ua1(txd), ua0(rts), dev(ad7) +mpp43 43 gpio, pcie0(clkreq), m(vtt), m(decc), spi1(cs2), dev(clkout), nd(rbn1) +mpp44 44 gpio, sata0(present) [1], sata1(present) [1], led(clk) +mpp45 45 gpio, ref(clk), pcie0(rstout), ua1(rxd) +mpp46 46 gpio, ref(clk), pcie0(rstout), ua1(txd), led(stb) +mpp47 47 gpio, sata0(present) [1], sata1(present) [1], led(data) +mpp48 48 gpio, sata0(present) [1], m(vtt), tdm(pclk) [1], audio(mclk) [1], sd(d4), pcie0(clkreq), ua1(txd) +mpp49 49 gpio, tdm(fsync) [1], audio(lrclk) [1], sd(d5), ua2(rxd) +mpp50 50 gpio, pcie0(rstout), tdm(drx) [1], audio(extclk) [1], sd(cmd), ua2(rxd) +mpp51 51 gpio, tdm(dtx) [1], audio(sdo) [1], m(decc), ua2(txd) +mpp52 52 gpio, pcie0(rstout), tdm(intn) [1], audio(sdi) [1], sd(d6), i2c3(sck) +mpp53 53 gpio, sata1(present) [1], sata0(present) [1], tdm(rstn) [1], audio(bclk) [1], sd(d7), i2c3(sda) +mpp54 54 gpio, sata0(present) [1], sata1(present) [1], pcie0(rstout), sd(d3), ua3(txd) +mpp55 55 gpio, ua1(cts), spi1(cs1), sd(d0), ua1(rxd), ua3(rxd) +mpp56 56 gpio, ua1(rts), m(decc), spi1(mosi), ua1(txd) +mpp57 57 gpio, spi1(sck), sd(clk), ua1(txd) +mpp58 58 gpio, i2c1(sck), pcie2(clkreq), spi1(miso), sd(d1), ua1(rxd) +mpp59 59 gpio, pcie0(rstout), i2c1(sda), spi1(cs0), sd(d2) + +[1]: only available on 88F6928 -- GitLab From b5eec4d061cad4a084c05c7dadd6884fd5fe0df9 Mon Sep 17 00:00:00 2001 From: Baruch Siach Date: Sun, 22 Feb 2015 19:55:47 +0200 Subject: [PATCH 03560/11651] pinctrl: lantiq: fix include guard #endif comment Signed-off-by: Baruch Siach Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-lantiq.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/pinctrl-lantiq.h b/drivers/pinctrl/pinctrl-lantiq.h index c7cfad5527d7..eb89ba045228 100644 --- a/drivers/pinctrl/pinctrl-lantiq.h +++ b/drivers/pinctrl/pinctrl-lantiq.h @@ -193,4 +193,4 @@ enum ltq_pin { extern int ltq_pinctrl_register(struct platform_device *pdev, struct ltq_pinmux_info *info); extern int ltq_pinctrl_unregister(struct platform_device *pdev); -#endif /* __PINCTRL_PXA3XX_H */ +#endif /* __PINCTRL_LANTIQ_H */ -- GitLab From 8d4684b39b5865ef5471a256adfcd8d7c3e18d43 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Tue, 24 Feb 2015 14:00:48 -0700 Subject: [PATCH 03561/11651] pinctrl: tegra: driver layout/consistency fixes Various non-semantic tweaks and layout/consistency fixes for existing Tegra pinctrl drivers. Move the definition of DRV_PINGROUP_REG() before the definition of PINGROUP() so that a future SoC driver can invoke the former from the latter. PINGROUP_BIT_Y(n) is just n, so replace it with n. Re-wrap the parameters to *PINGROUP(). Keep various enums sorted in the Tegra124 driver. Various white-space consistency fixes. These changes aim to update existing drivers to be consistent with future SoC drivers. While we could ignore these tweaks to the existing drivers, I'd like to keep everything as consistent as possible for easy comparison. Besides, I auto-generate the drivers, and maintaining special-cases to keep the differences in place is annoying. Signed-off-by: Stephen Warren Tested-by: Alexandre Courbot Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-tegra114.c | 14 ++-- drivers/pinctrl/pinctrl-tegra124.c | 29 ++++---- drivers/pinctrl/pinctrl-tegra30.c | 113 ++++++++++++++--------------- 3 files changed, 75 insertions(+), 81 deletions(-) diff --git a/drivers/pinctrl/pinctrl-tegra114.c b/drivers/pinctrl/pinctrl-tegra114.c index 52e4ec6386b4..0740cdba7508 100644 --- a/drivers/pinctrl/pinctrl-tegra114.c +++ b/drivers/pinctrl/pinctrl-tegra114.c @@ -1547,6 +1547,7 @@ static struct tegra_function tegra114_functions[] = { #define DRV_PINGROUP_REG_A 0x868 /* bank 0 */ #define PINGROUP_REG_A 0x3000 /* bank 1 */ +#define DRV_PINGROUP_REG(r) ((r) - DRV_PINGROUP_REG_A) #define PINGROUP_REG(r) ((r) - PINGROUP_REG_A) #define PINGROUP_BIT_Y(b) (b) @@ -1572,20 +1573,17 @@ static struct tegra_function tegra114_functions[] = { .tri_reg = PINGROUP_REG(r), \ .tri_bank = 1, \ .tri_bit = 4, \ - .einput_bit = PINGROUP_BIT_Y(5), \ + .einput_bit = 5, \ .odrain_bit = PINGROUP_BIT_##od(6), \ - .lock_bit = PINGROUP_BIT_Y(7), \ + .lock_bit = 7, \ .ioreset_bit = PINGROUP_BIT_##ior(8), \ .rcv_sel_bit = PINGROUP_BIT_##rcv_sel(9), \ .drv_reg = -1, \ } -#define DRV_PINGROUP_REG(r) ((r) - DRV_PINGROUP_REG_A) - -#define DRV_PINGROUP(pg_name, r, hsm_b, schmitt_b, lpmd_b, \ - drvdn_b, drvdn_w, drvup_b, drvup_w, \ - slwr_b, slwr_w, slwf_b, slwf_w, \ - drvtype) \ +#define DRV_PINGROUP(pg_name, r, hsm_b, schmitt_b, lpmd_b, drvdn_b, \ + drvdn_w, drvup_b, drvup_w, slwr_b, slwr_w, \ + slwf_b, slwf_w, drvtype) \ { \ .name = "drive_" #pg_name, \ .pins = drive_##pg_name##_pins, \ diff --git a/drivers/pinctrl/pinctrl-tegra124.c b/drivers/pinctrl/pinctrl-tegra124.c index 2b20906c5356..b7ba26064dbf 100644 --- a/drivers/pinctrl/pinctrl-tegra124.c +++ b/drivers/pinctrl/pinctrl-tegra124.c @@ -1536,6 +1536,7 @@ enum tegra_mux { TEGRA_MUX_CLK, TEGRA_MUX_CLK12, TEGRA_MUX_CPU, + TEGRA_MUX_CSI, TEGRA_MUX_DAP, TEGRA_MUX_DAP1, TEGRA_MUX_DAP2, @@ -1544,6 +1545,7 @@ enum tegra_mux { TEGRA_MUX_DISPLAYA_ALT, TEGRA_MUX_DISPLAYB, TEGRA_MUX_DP, + TEGRA_MUX_DSI_B, TEGRA_MUX_DTV, TEGRA_MUX_EXTPERIPH1, TEGRA_MUX_EXTPERIPH2, @@ -1613,8 +1615,6 @@ enum tegra_mux { TEGRA_MUX_VI_ALT3, TEGRA_MUX_VIMCLK2, TEGRA_MUX_VIMCLK2_ALT, - TEGRA_MUX_CSI, - TEGRA_MUX_DSI_B, }; #define FUNCTION(fname) \ @@ -1630,6 +1630,7 @@ static struct tegra_function tegra124_functions[] = { FUNCTION(clk), FUNCTION(clk12), FUNCTION(cpu), + FUNCTION(csi), FUNCTION(dap), FUNCTION(dap1), FUNCTION(dap2), @@ -1638,6 +1639,7 @@ static struct tegra_function tegra124_functions[] = { FUNCTION(displaya_alt), FUNCTION(displayb), FUNCTION(dp), + FUNCTION(dsi_b), FUNCTION(dtv), FUNCTION(extperiph1), FUNCTION(extperiph2), @@ -1707,15 +1709,15 @@ static struct tegra_function tegra124_functions[] = { FUNCTION(vi_alt3), FUNCTION(vimclk2), FUNCTION(vimclk2_alt), - FUNCTION(csi), - FUNCTION(dsi_b), }; #define DRV_PINGROUP_REG_A 0x868 /* bank 0 */ #define PINGROUP_REG_A 0x3000 /* bank 1 */ #define MIPI_PAD_CTRL_PINGROUP_REG_A 0x820 /* bank 2 */ +#define DRV_PINGROUP_REG(r) ((r) - DRV_PINGROUP_REG_A) #define PINGROUP_REG(r) ((r) - PINGROUP_REG_A) +#define MIPI_PAD_CTRL_PINGROUP_REG_Y(r) ((r) - MIPI_PAD_CTRL_PINGROUP_REG_A) #define PINGROUP_BIT_Y(b) (b) #define PINGROUP_BIT_N(b) (-1) @@ -1740,20 +1742,17 @@ static struct tegra_function tegra124_functions[] = { .tri_reg = PINGROUP_REG(r), \ .tri_bank = 1, \ .tri_bit = 4, \ - .einput_bit = PINGROUP_BIT_Y(5), \ + .einput_bit = 5, \ .odrain_bit = PINGROUP_BIT_##od(6), \ - .lock_bit = PINGROUP_BIT_Y(7), \ + .lock_bit = 7, \ .ioreset_bit = PINGROUP_BIT_##ior(8), \ .rcv_sel_bit = PINGROUP_BIT_##rcv_sel(9), \ .drv_reg = -1, \ } -#define DRV_PINGROUP_REG(r) ((r) - DRV_PINGROUP_REG_A) - -#define DRV_PINGROUP(pg_name, r, hsm_b, schmitt_b, lpmd_b, \ - drvdn_b, drvdn_w, drvup_b, drvup_w, \ - slwr_b, slwr_w, slwf_b, slwf_w, \ - drvtype) \ +#define DRV_PINGROUP(pg_name, r, hsm_b, schmitt_b, lpmd_b, drvdn_b, \ + drvdn_w, drvup_b, drvup_w, slwr_b, slwr_w, \ + slwf_b, slwf_w, drvtype) \ { \ .name = "drive_" #pg_name, \ .pins = drive_##pg_name##_pins, \ @@ -1782,8 +1781,6 @@ static struct tegra_function tegra124_functions[] = { .drvtype_bit = PINGROUP_BIT_##drvtype(6), \ } -#define MIPI_PAD_CTRL_PINGROUP_REG_Y(r) ((r) - MIPI_PAD_CTRL_PINGROUP_REG_A) - #define MIPI_PAD_CTRL_PINGROUP(pg_name, r, b, f0, f1) \ { \ .name = "mipi_pad_ctrl_" #pg_name, \ @@ -2044,8 +2041,8 @@ static const struct tegra_pingroup tegra124_groups[] = { DRV_PINGROUP(sdio4, 0x9c4, 2, 3, 4, 12, 5, 20, 5, 28, 2, 30, 2, N), DRV_PINGROUP(ao4, 0x9c8, 2, 3, 4, 12, 7, 20, 7, 28, 2, 30, 2, Y), - /* pg_name, r b f0, f1 */ - MIPI_PAD_CTRL_PINGROUP(dsi_b, 0x820, 1, CSI, DSI_B) + /* pg_name, r, b, f0, f1 */ + MIPI_PAD_CTRL_PINGROUP(dsi_b, 0x820, 1, CSI, DSI_B), }; static const struct tegra_pinctrl_soc_data tegra124_pinctrl = { diff --git a/drivers/pinctrl/pinctrl-tegra30.c b/drivers/pinctrl/pinctrl-tegra30.c index f6edc2ff5494..77c0768d5bd8 100644 --- a/drivers/pinctrl/pinctrl-tegra30.c +++ b/drivers/pinctrl/pinctrl-tegra30.c @@ -2108,70 +2108,69 @@ static struct tegra_function tegra30_functions[] = { #define DRV_PINGROUP_REG_A 0x868 /* bank 0 */ #define PINGROUP_REG_A 0x3000 /* bank 1 */ +#define DRV_PINGROUP_REG(r) ((r) - DRV_PINGROUP_REG_A) #define PINGROUP_REG(r) ((r) - PINGROUP_REG_A) #define PINGROUP_BIT_Y(b) (b) #define PINGROUP_BIT_N(b) (-1) -#define PINGROUP(pg_name, f0, f1, f2, f3, r, od, ior) \ - { \ - .name = #pg_name, \ - .pins = pg_name##_pins, \ - .npins = ARRAY_SIZE(pg_name##_pins), \ - .funcs = { \ - TEGRA_MUX_##f0, \ - TEGRA_MUX_##f1, \ - TEGRA_MUX_##f2, \ - TEGRA_MUX_##f3, \ - }, \ - .mux_reg = PINGROUP_REG(r), \ - .mux_bank = 1, \ - .mux_bit = 0, \ - .pupd_reg = PINGROUP_REG(r), \ - .pupd_bank = 1, \ - .pupd_bit = 2, \ - .tri_reg = PINGROUP_REG(r), \ - .tri_bank = 1, \ - .tri_bit = 4, \ - .einput_bit = PINGROUP_BIT_Y(5), \ - .odrain_bit = PINGROUP_BIT_##od(6), \ - .lock_bit = PINGROUP_BIT_Y(7), \ - .ioreset_bit = PINGROUP_BIT_##ior(8), \ - .rcv_sel_bit = -1, \ - .drv_reg = -1, \ +#define PINGROUP(pg_name, f0, f1, f2, f3, r, od, ior) \ + { \ + .name = #pg_name, \ + .pins = pg_name##_pins, \ + .npins = ARRAY_SIZE(pg_name##_pins), \ + .funcs = { \ + TEGRA_MUX_##f0, \ + TEGRA_MUX_##f1, \ + TEGRA_MUX_##f2, \ + TEGRA_MUX_##f3, \ + }, \ + .mux_reg = PINGROUP_REG(r), \ + .mux_bank = 1, \ + .mux_bit = 0, \ + .pupd_reg = PINGROUP_REG(r), \ + .pupd_bank = 1, \ + .pupd_bit = 2, \ + .tri_reg = PINGROUP_REG(r), \ + .tri_bank = 1, \ + .tri_bit = 4, \ + .einput_bit = 5, \ + .odrain_bit = PINGROUP_BIT_##od(6), \ + .lock_bit = 7, \ + .ioreset_bit = PINGROUP_BIT_##ior(8), \ + .rcv_sel_bit = -1, \ + .drv_reg = -1, \ } -#define DRV_PINGROUP_REG(r) ((r) - DRV_PINGROUP_REG_A) - -#define DRV_PINGROUP(pg_name, r, hsm_b, schmitt_b, lpmd_b, \ - drvdn_b, drvdn_w, drvup_b, drvup_w, \ - slwr_b, slwr_w, slwf_b, slwf_w) \ - { \ - .name = "drive_" #pg_name, \ - .pins = drive_##pg_name##_pins, \ - .npins = ARRAY_SIZE(drive_##pg_name##_pins), \ - .mux_reg = -1, \ - .pupd_reg = -1, \ - .tri_reg = -1, \ - .einput_bit = -1, \ - .odrain_bit = -1, \ - .lock_bit = -1, \ - .ioreset_bit = -1, \ - .rcv_sel_bit = -1, \ - .drv_reg = DRV_PINGROUP_REG(r), \ - .drv_bank = 0, \ - .hsm_bit = hsm_b, \ - .schmitt_bit = schmitt_b, \ - .lpmd_bit = lpmd_b, \ - .drvdn_bit = drvdn_b, \ - .drvdn_width = drvdn_w, \ - .drvup_bit = drvup_b, \ - .drvup_width = drvup_w, \ - .slwr_bit = slwr_b, \ - .slwr_width = slwr_w, \ - .slwf_bit = slwf_b, \ - .slwf_width = slwf_w, \ - .drvtype_bit = -1, \ +#define DRV_PINGROUP(pg_name, r, hsm_b, schmitt_b, lpmd_b, drvdn_b, \ + drvdn_w, drvup_b, drvup_w, slwr_b, slwr_w, \ + slwf_b, slwf_w) \ + { \ + .name = "drive_" #pg_name, \ + .pins = drive_##pg_name##_pins, \ + .npins = ARRAY_SIZE(drive_##pg_name##_pins), \ + .mux_reg = -1, \ + .pupd_reg = -1, \ + .tri_reg = -1, \ + .einput_bit = -1, \ + .odrain_bit = -1, \ + .lock_bit = -1, \ + .ioreset_bit = -1, \ + .rcv_sel_bit = -1, \ + .drv_reg = DRV_PINGROUP_REG(r), \ + .drv_bank = 0, \ + .hsm_bit = hsm_b, \ + .schmitt_bit = schmitt_b, \ + .lpmd_bit = lpmd_b, \ + .drvdn_bit = drvdn_b, \ + .drvdn_width = drvdn_w, \ + .drvup_bit = drvup_b, \ + .drvup_width = drvup_w, \ + .slwr_bit = slwr_b, \ + .slwr_width = slwr_w, \ + .slwf_bit = slwf_b, \ + .slwf_width = slwf_w, \ + .drvtype_bit = -1, \ } static const struct tegra_pingroup tegra30_groups[] = { -- GitLab From ea623061930ccf6d37b4a09a4e65a26fcf552c22 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Tue, 24 Feb 2015 14:00:49 -0700 Subject: [PATCH 03562/11651] pinctrl: tegra: some bits move between registers Some of the pinmux configuration bits that exist in "drive group" registers in Tegra30..Tegra124 move to the "pinmux" registers on future chips. Add a flag to support this. Signed-off-by: Stephen Warren Tested-by: Alexandre Courbot Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-tegra.c | 27 +++++++++++++++++++++------ drivers/pinctrl/pinctrl-tegra.h | 3 +++ drivers/pinctrl/pinctrl-tegra114.c | 3 +++ drivers/pinctrl/pinctrl-tegra124.c | 3 +++ drivers/pinctrl/pinctrl-tegra20.c | 3 +++ drivers/pinctrl/pinctrl-tegra30.c | 3 +++ 6 files changed, 36 insertions(+), 6 deletions(-) diff --git a/drivers/pinctrl/pinctrl-tegra.c b/drivers/pinctrl/pinctrl-tegra.c index e5949d51bc52..6cd651a88398 100644 --- a/drivers/pinctrl/pinctrl-tegra.c +++ b/drivers/pinctrl/pinctrl-tegra.c @@ -348,14 +348,24 @@ static int tegra_pinconf_reg(struct tegra_pmx *pmx, *width = 1; break; case TEGRA_PINCONF_PARAM_HIGH_SPEED_MODE: - *bank = g->drv_bank; - *reg = g->drv_reg; + if (pmx->soc->hsm_in_mux) { + *bank = g->mux_bank; + *reg = g->mux_reg; + } else { + *bank = g->drv_bank; + *reg = g->drv_reg; + } *bit = g->hsm_bit; *width = 1; break; case TEGRA_PINCONF_PARAM_SCHMITT: - *bank = g->drv_bank; - *reg = g->drv_reg; + if (pmx->soc->schmitt_in_mux) { + *bank = g->mux_bank; + *reg = g->mux_reg; + } else { + *bank = g->drv_bank; + *reg = g->drv_reg; + } *bit = g->schmitt_bit; *width = 1; break; @@ -390,8 +400,13 @@ static int tegra_pinconf_reg(struct tegra_pmx *pmx, *width = g->slwr_width; break; case TEGRA_PINCONF_PARAM_DRIVE_TYPE: - *bank = g->drv_bank; - *reg = g->drv_reg; + if (pmx->soc->drvtype_in_mux) { + *bank = g->mux_bank; + *reg = g->mux_reg; + } else { + *bank = g->drv_bank; + *reg = g->drv_reg; + } *bit = g->drvtype_bit; *width = 2; break; diff --git a/drivers/pinctrl/pinctrl-tegra.h b/drivers/pinctrl/pinctrl-tegra.h index 8d94d1332e7b..d54ab9d38792 100644 --- a/drivers/pinctrl/pinctrl-tegra.h +++ b/drivers/pinctrl/pinctrl-tegra.h @@ -182,6 +182,9 @@ struct tegra_pinctrl_soc_data { unsigned nfunctions; const struct tegra_pingroup *groups; unsigned ngroups; + bool hsm_in_mux; + bool schmitt_in_mux; + bool drvtype_in_mux; }; int tegra_pinctrl_probe(struct platform_device *pdev, diff --git a/drivers/pinctrl/pinctrl-tegra114.c b/drivers/pinctrl/pinctrl-tegra114.c index 0740cdba7508..05e49d5137ab 100644 --- a/drivers/pinctrl/pinctrl-tegra114.c +++ b/drivers/pinctrl/pinctrl-tegra114.c @@ -1841,6 +1841,9 @@ static const struct tegra_pinctrl_soc_data tegra114_pinctrl = { .nfunctions = ARRAY_SIZE(tegra114_functions), .groups = tegra114_groups, .ngroups = ARRAY_SIZE(tegra114_groups), + .hsm_in_mux = false, + .schmitt_in_mux = false, + .drvtype_in_mux = false, }; static int tegra114_pinctrl_probe(struct platform_device *pdev) diff --git a/drivers/pinctrl/pinctrl-tegra124.c b/drivers/pinctrl/pinctrl-tegra124.c index b7ba26064dbf..7cd44c7c296d 100644 --- a/drivers/pinctrl/pinctrl-tegra124.c +++ b/drivers/pinctrl/pinctrl-tegra124.c @@ -2053,6 +2053,9 @@ static const struct tegra_pinctrl_soc_data tegra124_pinctrl = { .nfunctions = ARRAY_SIZE(tegra124_functions), .groups = tegra124_groups, .ngroups = ARRAY_SIZE(tegra124_groups), + .hsm_in_mux = false, + .schmitt_in_mux = false, + .drvtype_in_mux = false, }; static int tegra124_pinctrl_probe(struct platform_device *pdev) diff --git a/drivers/pinctrl/pinctrl-tegra20.c b/drivers/pinctrl/pinctrl-tegra20.c index d3a5722e4acb..4833db4433d9 100644 --- a/drivers/pinctrl/pinctrl-tegra20.c +++ b/drivers/pinctrl/pinctrl-tegra20.c @@ -2221,6 +2221,9 @@ static const struct tegra_pinctrl_soc_data tegra20_pinctrl = { .nfunctions = ARRAY_SIZE(tegra20_functions), .groups = tegra20_groups, .ngroups = ARRAY_SIZE(tegra20_groups), + .hsm_in_mux = false, + .schmitt_in_mux = false, + .drvtype_in_mux = false, }; static int tegra20_pinctrl_probe(struct platform_device *pdev) diff --git a/drivers/pinctrl/pinctrl-tegra30.c b/drivers/pinctrl/pinctrl-tegra30.c index 77c0768d5bd8..47b2fd8bb2e9 100644 --- a/drivers/pinctrl/pinctrl-tegra30.c +++ b/drivers/pinctrl/pinctrl-tegra30.c @@ -2476,6 +2476,9 @@ static const struct tegra_pinctrl_soc_data tegra30_pinctrl = { .nfunctions = ARRAY_SIZE(tegra30_functions), .groups = tegra30_groups, .ngroups = ARRAY_SIZE(tegra30_groups), + .hsm_in_mux = false, + .schmitt_in_mux = false, + .drvtype_in_mux = false, }; static int tegra30_pinctrl_probe(struct platform_device *pdev) -- GitLab From ec654e50c67ad4ba89c9f9f81ccf6f061695e36d Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Tue, 24 Feb 2015 14:00:50 -0700 Subject: [PATCH 03563/11651] pinctrl: tegra: support nvidia,io-hv DT property Both nvidia,io-hv and nvidia,rcv-sel represent the fact that a particular pin's IO buffers are configured to accept "high voltage" input signals. The TRM for different chips names the register field rcv-sel on older SoCs and io_hv on newer SoCs. Add the new naming option into the pinctrl driver so that DT files can use naming consistent with the TRM. This new property name will be documented in the patch that adds support for the new SoC. Signed-off-by: Stephen Warren Tested-by: Alexandre Courbot Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-tegra.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pinctrl/pinctrl-tegra.c b/drivers/pinctrl/pinctrl-tegra.c index 6cd651a88398..4c95c2024a1c 100644 --- a/drivers/pinctrl/pinctrl-tegra.c +++ b/drivers/pinctrl/pinctrl-tegra.c @@ -103,6 +103,7 @@ static const struct cfg_param { {"nvidia,lock", TEGRA_PINCONF_PARAM_LOCK}, {"nvidia,io-reset", TEGRA_PINCONF_PARAM_IORESET}, {"nvidia,rcv-sel", TEGRA_PINCONF_PARAM_RCV_SEL}, + {"nvidia,io-hv", TEGRA_PINCONF_PARAM_RCV_SEL}, {"nvidia,high-speed-mode", TEGRA_PINCONF_PARAM_HIGH_SPEED_MODE}, {"nvidia,schmitt", TEGRA_PINCONF_PARAM_SCHMITT}, {"nvidia,low-power-mode", TEGRA_PINCONF_PARAM_LOW_POWER_MODE}, -- GitLab From 9184f756908ace8213099f21870b07491a7138a9 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Tue, 24 Feb 2015 14:00:51 -0700 Subject: [PATCH 03564/11651] pinctrl: tegra: add a driver for Tegra210 Tegra210's pinmux supports a different set of pins/options than earlier SoCs, so requires its own driver (well, table of pin-specific data). Cc: devicetree@vger.kernel.org Signed-off-by: Stephen Warren Tested-by: Alexandre Courbot Signed-off-by: Linus Walleij --- .../pinctrl/nvidia,tegra210-pinmux.txt | 166 ++ drivers/pinctrl/Kconfig | 4 + drivers/pinctrl/Makefile | 1 + drivers/pinctrl/pinctrl-tegra210.c | 1588 +++++++++++++++++ 4 files changed, 1759 insertions(+) create mode 100644 Documentation/devicetree/bindings/pinctrl/nvidia,tegra210-pinmux.txt create mode 100644 drivers/pinctrl/pinctrl-tegra210.c diff --git a/Documentation/devicetree/bindings/pinctrl/nvidia,tegra210-pinmux.txt b/Documentation/devicetree/bindings/pinctrl/nvidia,tegra210-pinmux.txt new file mode 100644 index 000000000000..a62d82d5fbe9 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/nvidia,tegra210-pinmux.txt @@ -0,0 +1,166 @@ +NVIDIA Tegra210 pinmux controller + +Required properties: +- compatible: "nvidia,tegra210-pinmux" +- reg: Should contain a list of base address and size pairs for: + - first entry: The APB_MISC_GP_*_PADCTRL registers (pad control) + - second entry: The PINMUX_AUX_* registers (pinmux) + +Please refer to pinctrl-bindings.txt in this directory for details of the +common pinctrl bindings used by client devices, including the meaning of the +phrase "pin configuration node". + +Tegra's pin configuration nodes act as a container for an arbitrary number of +subnodes. Each of these subnodes represents some desired configuration for a +pin, a group, or a list of pins or groups. This configuration can include the +mux function to select on those pin(s)/group(s), and various pin configuration +parameters, such as pull-up, tristate, drive strength, etc. + +The name of each subnode is not important; all subnodes should be enumerated +and processed purely based on their content. + +Each subnode only affects those parameters that are explicitly listed. In +other words, a subnode that lists a mux function but no pin configuration +parameters implies no information about any pin configuration parameters. +Similarly, a pin subnode that describes a pullup parameter implies no +information about e.g. the mux function or tristate parameter. For this +reason, even seemingly boolean values are actually tristates in this binding: +unspecified, off, or on. Unspecified is represented as an absent property, +and off/on are represented as integer values 0 and 1. + +See the TRM to determine which properties and values apply to each pin/group. +Macro values for property values are defined in +include/dt-binding/pinctrl/pinctrl-tegra.h. + +Required subnode-properties: +- nvidia,pins : An array of strings. Each string contains the name of a pin or + group. Valid values for these names are listed below. + +Optional subnode-properties: +- nvidia,function: A string containing the name of the function to mux to the + pin or group. +- nvidia,pull: Integer, representing the pull-down/up to apply to the pin. + 0: none, 1: down, 2: up. +- nvidia,tristate: Integer. + 0: drive, 1: tristate. +- nvidia,enable-input: Integer. Enable the pin's input path. + enable :TEGRA_PIN_ENABLE0 and + disable or output only: TEGRA_PIN_DISABLE. +- nvidia,open-drain: Integer. + enable: TEGRA_PIN_ENABLE. + disable: TEGRA_PIN_DISABLE. +- nvidia,lock: Integer. Lock the pin configuration against further changes + until reset. + enable: TEGRA_PIN_ENABLE. + disable: TEGRA_PIN_DISABLE. +- nvidia,io-hv: Integer. Select high-voltage receivers. + normal: TEGRA_PIN_DISABLE + high: TEGRA_PIN_ENABLE +- nvidia,high-speed-mode: Integer. Enable high speed mode the pins. + normal: TEGRA_PIN_DISABLE + high: TEGRA_PIN_ENABLE +- nvidia,schmitt: Integer. Enables Schmitt Trigger on the input. + normal: TEGRA_PIN_DISABLE + high: TEGRA_PIN_ENABLE +- nvidia,drive-type: Integer. Valid range 0...3. +- nvidia,pull-down-strength: Integer. Controls drive strength. 0 is weakest. + The range of valid values depends on the pingroup. See "CAL_DRVDN" in the + Tegra TRM. +- nvidia,pull-up-strength: Integer. Controls drive strength. 0 is weakest. + The range of valid values depends on the pingroup. See "CAL_DRVUP" in the + Tegra TRM. +- nvidia,slew-rate-rising: Integer. Controls rising signal slew rate. 0 is + fastest. The range of valid values depends on the pingroup. See + "DRVDN_SLWR" in the Tegra TRM. +- nvidia,slew-rate-falling: Integer. Controls falling signal slew rate. 0 is + fastest. The range of valid values depends on the pingroup. See + "DRVUP_SLWF" in the Tegra TRM. + +Valid values for pin and group names (nvidia,pin) are: + + Mux groups: + + These correspond to Tegra PINMUX_AUX_* (pinmux) registers. Any property + that exists in those registers may be set for the following pin names. + + In Tegra210, many pins also have a dedicated APB_MISC_GP_*_PADCTRL + register. Where that is true, and property that exists in that register + may also be set on the following pin names. + + als_prox_int_px3, ap_ready_pv5, ap_wake_bt_ph3, ap_wake_nfc_ph7, + aud_mclk_pbb0, batt_bcl, bt_rst_ph4, bt_wake_ap_ph5, button_home_py1, + button_power_on_px5, button_slide_sw_py0, button_vol_down_px7, + button_vol_up_px6, cam1_mclk_ps0, cam1_pwdn_ps7, cam1_strobe_pt1, + cam2_mclk_ps1, cam2_pwdn_pt0, cam_af_en_ps5, cam_flash_en_ps6, + cam_i2c_scl_ps2, cam_i2c_sda_ps3, cam_rst_ps4cam_rst_ps4, clk_32k_in, + clk_32k_out_py5, clk_req, core_pwr_req, cpu_pwr_req, dap1_din_pb1, + dap1_dout_pb2, dap1_fs_pb0, dap1_sclk_pb3, dap2_din_paa2, dap2_dout_paa3, + dap2_fs_paa0, dap2_sclk_paa1, dap4_din_pj5, dap4_dout_pj6, dap4_fs_pj4, + dap4_sclk_pj7, dmic1_clk_pe0, dmic1_dat_pe1, dmic2_clk_pe2, dmic2_dat_pe3, + dmic3_clk_pe4, dmic3_dat_pe5, dp_hpd0_pcc6, dvfs_clk_pbb2, dvfs_pwm_pbb1, + gen1_i2c_scl_pj1, gen1_i2c_sda_pj0, gen2_i2c_scl_pj2, gen2_i2c_sda_pj3, + gen3_i2c_scl_pf0, gen3_i2c_sda_pf1, gpio_x1_aud_pbb3, gpio_x3_aud_pbb4, + gps_en_pi2, gps_rst_pi3, hdmi_cec_pcc0, hdmi_int_dp_hpd_pcc1, jtag_rtck, + lcd_bl_en_pv1, lcd_bl_pwm_pv0, lcd_gpio1_pv3, lcd_gpio2_pv4, lcd_rst_pv2, + lcd_te_py2, modem_wake_ap_px0, motion_int_px2, nfc_en_pi0, nfc_int_pi1, + pa6, pcc7, pe6, pe7, pex_l0_clkreq_n_pa1, pex_l0_rst_n_pa0, + pex_l1_clkreq_n_pa4, pex_l1_rst_n_pa3, pex_wake_n_pa2, ph6, pk0, pk1, pk2, + pk3, pk4, pk5, pk6, pk7, pl0, pl1, pwr_i2c_scl_py3, pwr_i2c_sda_py4, + pwr_int_n, pz0, pz1, pz2, pz3, pz4, pz5, qspi_cs_n_pee1, qspi_io0_pee2, + qspi_io1_pee3, qspi_io2_pee4, qspi_io3_pee5, qspi_sck_pee0, + sata_led_active_pa5, sdmmc1_clk_pm0, sdmmc1_cmd_pm1, sdmmc1_dat0_pm5, + sdmmc1_dat1_pm4, sdmmc1_dat2_pm3, sdmmc1_dat3_pm2, sdmmc3_clk_pp0, + sdmmc3_cmd_pp1, sdmmc3_dat0_pp5, sdmmc3_dat1_pp4, sdmmc3_dat2_pp3, + sdmmc3_dat3_pp2, shutdown, spdif_in_pcc3, spdif_out_pcc2, spi1_cs0_pc3, + spi1_cs1_pc4, spi1_miso_pc1, spi1_mosi_pc0, spi1_sck_pc2, spi2_cs0_pb7, + spi2_cs1_pdd0, spi2_miso_pb5, spi2_mosi_pb4, spi2_sck_pb6, spi4_cs0_pc6, + spi4_miso_pd0, spi4_mosi_pc7, spi4_sck_pc5, temp_alert_px4, touch_clk_pv7, + touch_int_px1, touch_rst_pv6, uart1_cts_pu3, uart1_rts_pu2, uart1_rx_pu1, + uart1_tx_pu0, uart2_cts_pg3, uart2_rts_pg2, uart2_rx_pg1, uart2_tx_pg0, + uart3_cts_pd4, uart3_rts_pd3, uart3_rx_pd2, uart3_tx_pd1, uart4_cts_pi7, + uart4_rts_pi6, uart4_rx_pi5, uart4_tx_pi4, usb_vbus_en0_pcc4, + usb_vbus_en1_pcc5, wifi_en_ph0, wifi_rst_ph1, wifi_wake_ap_ph2 + + Drive groups: + + These correspond to the Tegra APB_MISC_GP_*_PADCTRL (pad control) + registers. Note that where one of these registers controls a single pin + for which a PINMUX_AUX_* exists, see the list above for the pin name to + use when configuring the pinmux. + + pa6, pcc7, pe6, pe7, ph6, pk0, pk1, pk2, pk3, pk4, pk5, pk6, pk7, pl0, pl1, + pz0, pz1, pz2, pz3, pz4, pz5, sdmmc1, sdmmc2, sdmmc3, sdmmc4 + +Valid values for nvidia,functions are: + + aud, bcl, blink, ccla, cec, cldvfs, clk, core, cpu, displaya, displayb, + dmic1, dmic2, dmic3, dp, dtv, extperiph3, i2c1, i2c2, i2c3, i2cpmu, i2cvi, + i2s1, i2s2, i2s3, i2s4a, i2s4b, i2s5a, i2s5b, iqc0, iqc1, jtag, pe, pe0, + pe1, pmi, pwm0, pwm1, pwm2, pwm3, qspi, rsvd0, rsvd1, rsvd2, rsvd3, sata, + sdmmc1, sdmmc3, shutdown, soc, sor0, sor1, spdif, spi1, spi2, spi3, spi4, + sys, touch, uart, uarta, uartb, uartc, uartd, usb, vgp1, vgp2, vgp3, vgp4, + vgp5, vgp6, vimclk, vimclk2 + +Example: + + pinmux: pinmux@70000800 { + compatible = "nvidia,tegra210-pinmux"; + reg = <0x0 0x700008d4 0x0 0x2a8>, /* Pad control registers */ + <0x0 0x70003000 0x0 0x1000>; /* Mux registers */ + + pinctrl-names = "boot"; + pinctrl-0 = <&state_boot>; + + state_boot: pinmux { + gen1_i2c_scl_pj1 { + nvidia,pins = "gen1_i2c_scl_pj1", + nvidia,function = "i2c1"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + nvidia,open-drain = ; + nvidia,io-hv = ; + }; + }; + }; +}; diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index ee9f44ad7f02..17b7f6ac8b25 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -154,6 +154,10 @@ config PINCTRL_TEGRA124 bool select PINCTRL_TEGRA +config PINCTRL_TEGRA210 + bool + select PINCTRL_TEGRA + config PINCTRL_TEGRA_XUSB def_bool y if ARCH_TEGRA select GENERIC_PHY diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index 0475206dd600..9b4d6c7f4277 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_PINCTRL_TEGRA20) += pinctrl-tegra20.o obj-$(CONFIG_PINCTRL_TEGRA30) += pinctrl-tegra30.o obj-$(CONFIG_PINCTRL_TEGRA114) += pinctrl-tegra114.o obj-$(CONFIG_PINCTRL_TEGRA124) += pinctrl-tegra124.o +obj-$(CONFIG_PINCTRL_TEGRA210) += pinctrl-tegra210.o obj-$(CONFIG_PINCTRL_TEGRA_XUSB) += pinctrl-tegra-xusb.o obj-$(CONFIG_PINCTRL_TZ1090) += pinctrl-tz1090.o obj-$(CONFIG_PINCTRL_TZ1090_PDC) += pinctrl-tz1090-pdc.o diff --git a/drivers/pinctrl/pinctrl-tegra210.c b/drivers/pinctrl/pinctrl-tegra210.c new file mode 100644 index 000000000000..252b464901c0 --- /dev/null +++ b/drivers/pinctrl/pinctrl-tegra210.c @@ -0,0 +1,1588 @@ +/* + * Pinctrl data for the NVIDIA Tegra210 pinmux + * + * Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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 +#include +#include +#include +#include + +#include "pinctrl-tegra.h" + +/* + * Most pins affected by the pinmux can also be GPIOs. Define these first. + * These must match how the GPIO driver names/numbers its pins. + */ +#define _GPIO(offset) (offset) + +#define TEGRA_PIN_PEX_L0_RST_N_PA0 _GPIO(0) +#define TEGRA_PIN_PEX_L0_CLKREQ_N_PA1 _GPIO(1) +#define TEGRA_PIN_PEX_WAKE_N_PA2 _GPIO(2) +#define TEGRA_PIN_PEX_L1_RST_N_PA3 _GPIO(3) +#define TEGRA_PIN_PEX_L1_CLKREQ_N_PA4 _GPIO(4) +#define TEGRA_PIN_SATA_LED_ACTIVE_PA5 _GPIO(5) +#define TEGRA_PIN_PA6 _GPIO(6) +#define TEGRA_PIN_DAP1_FS_PB0 _GPIO(8) +#define TEGRA_PIN_DAP1_DIN_PB1 _GPIO(9) +#define TEGRA_PIN_DAP1_DOUT_PB2 _GPIO(10) +#define TEGRA_PIN_DAP1_SCLK_PB3 _GPIO(11) +#define TEGRA_PIN_SPI2_MOSI_PB4 _GPIO(12) +#define TEGRA_PIN_SPI2_MISO_PB5 _GPIO(13) +#define TEGRA_PIN_SPI2_SCK_PB6 _GPIO(14) +#define TEGRA_PIN_SPI2_CS0_PB7 _GPIO(15) +#define TEGRA_PIN_SPI1_MOSI_PC0 _GPIO(16) +#define TEGRA_PIN_SPI1_MISO_PC1 _GPIO(17) +#define TEGRA_PIN_SPI1_SCK_PC2 _GPIO(18) +#define TEGRA_PIN_SPI1_CS0_PC3 _GPIO(19) +#define TEGRA_PIN_SPI1_CS1_PC4 _GPIO(20) +#define TEGRA_PIN_SPI4_SCK_PC5 _GPIO(21) +#define TEGRA_PIN_SPI4_CS0_PC6 _GPIO(22) +#define TEGRA_PIN_SPI4_MOSI_PC7 _GPIO(23) +#define TEGRA_PIN_SPI4_MISO_PD0 _GPIO(24) +#define TEGRA_PIN_UART3_TX_PD1 _GPIO(25) +#define TEGRA_PIN_UART3_RX_PD2 _GPIO(26) +#define TEGRA_PIN_UART3_RTS_PD3 _GPIO(27) +#define TEGRA_PIN_UART3_CTS_PD4 _GPIO(28) +#define TEGRA_PIN_DMIC1_CLK_PE0 _GPIO(32) +#define TEGRA_PIN_DMIC1_DAT_PE1 _GPIO(33) +#define TEGRA_PIN_DMIC2_CLK_PE2 _GPIO(34) +#define TEGRA_PIN_DMIC2_DAT_PE3 _GPIO(35) +#define TEGRA_PIN_DMIC3_CLK_PE4 _GPIO(36) +#define TEGRA_PIN_DMIC3_DAT_PE5 _GPIO(37) +#define TEGRA_PIN_PE6 _GPIO(38) +#define TEGRA_PIN_PE7 _GPIO(39) +#define TEGRA_PIN_GEN3_I2C_SCL_PF0 _GPIO(40) +#define TEGRA_PIN_GEN3_I2C_SDA_PF1 _GPIO(41) +#define TEGRA_PIN_UART2_TX_PG0 _GPIO(48) +#define TEGRA_PIN_UART2_RX_PG1 _GPIO(49) +#define TEGRA_PIN_UART2_RTS_PG2 _GPIO(50) +#define TEGRA_PIN_UART2_CTS_PG3 _GPIO(51) +#define TEGRA_PIN_WIFI_EN_PH0 _GPIO(56) +#define TEGRA_PIN_WIFI_RST_PH1 _GPIO(57) +#define TEGRA_PIN_WIFI_WAKE_AP_PH2 _GPIO(58) +#define TEGRA_PIN_AP_WAKE_BT_PH3 _GPIO(59) +#define TEGRA_PIN_BT_RST_PH4 _GPIO(60) +#define TEGRA_PIN_BT_WAKE_AP_PH5 _GPIO(61) +#define TEGRA_PIN_PH6 _GPIO(62) +#define TEGRA_PIN_AP_WAKE_NFC_PH7 _GPIO(63) +#define TEGRA_PIN_NFC_EN_PI0 _GPIO(64) +#define TEGRA_PIN_NFC_INT_PI1 _GPIO(65) +#define TEGRA_PIN_GPS_EN_PI2 _GPIO(66) +#define TEGRA_PIN_GPS_RST_PI3 _GPIO(67) +#define TEGRA_PIN_UART4_TX_PI4 _GPIO(68) +#define TEGRA_PIN_UART4_RX_PI5 _GPIO(69) +#define TEGRA_PIN_UART4_RTS_PI6 _GPIO(70) +#define TEGRA_PIN_UART4_CTS_PI7 _GPIO(71) +#define TEGRA_PIN_GEN1_I2C_SDA_PJ0 _GPIO(72) +#define TEGRA_PIN_GEN1_I2C_SCL_PJ1 _GPIO(73) +#define TEGRA_PIN_GEN2_I2C_SCL_PJ2 _GPIO(74) +#define TEGRA_PIN_GEN2_I2C_SDA_PJ3 _GPIO(75) +#define TEGRA_PIN_DAP4_FS_PJ4 _GPIO(76) +#define TEGRA_PIN_DAP4_DIN_PJ5 _GPIO(77) +#define TEGRA_PIN_DAP4_DOUT_PJ6 _GPIO(78) +#define TEGRA_PIN_DAP4_SCLK_PJ7 _GPIO(79) +#define TEGRA_PIN_PK0 _GPIO(80) +#define TEGRA_PIN_PK1 _GPIO(81) +#define TEGRA_PIN_PK2 _GPIO(82) +#define TEGRA_PIN_PK3 _GPIO(83) +#define TEGRA_PIN_PK4 _GPIO(84) +#define TEGRA_PIN_PK5 _GPIO(85) +#define TEGRA_PIN_PK6 _GPIO(86) +#define TEGRA_PIN_PK7 _GPIO(87) +#define TEGRA_PIN_PL0 _GPIO(88) +#define TEGRA_PIN_PL1 _GPIO(89) +#define TEGRA_PIN_SDMMC1_CLK_PM0 _GPIO(96) +#define TEGRA_PIN_SDMMC1_CMD_PM1 _GPIO(97) +#define TEGRA_PIN_SDMMC1_DAT3_PM2 _GPIO(98) +#define TEGRA_PIN_SDMMC1_DAT2_PM3 _GPIO(99) +#define TEGRA_PIN_SDMMC1_DAT1_PM4 _GPIO(100) +#define TEGRA_PIN_SDMMC1_DAT0_PM5 _GPIO(101) +#define TEGRA_PIN_SDMMC3_CLK_PP0 _GPIO(120) +#define TEGRA_PIN_SDMMC3_CMD_PP1 _GPIO(121) +#define TEGRA_PIN_SDMMC3_DAT3_PP2 _GPIO(122) +#define TEGRA_PIN_SDMMC3_DAT2_PP3 _GPIO(123) +#define TEGRA_PIN_SDMMC3_DAT1_PP4 _GPIO(124) +#define TEGRA_PIN_SDMMC3_DAT0_PP5 _GPIO(125) +#define TEGRA_PIN_CAM1_MCLK_PS0 _GPIO(144) +#define TEGRA_PIN_CAM2_MCLK_PS1 _GPIO(145) +#define TEGRA_PIN_CAM_I2C_SCL_PS2 _GPIO(146) +#define TEGRA_PIN_CAM_I2C_SDA_PS3 _GPIO(147) +#define TEGRA_PIN_CAM_RST_PS4 _GPIO(148) +#define TEGRA_PIN_CAM_AF_EN_PS5 _GPIO(149) +#define TEGRA_PIN_CAM_FLASH_EN_PS6 _GPIO(150) +#define TEGRA_PIN_CAM1_PWDN_PS7 _GPIO(151) +#define TEGRA_PIN_CAM2_PWDN_PT0 _GPIO(152) +#define TEGRA_PIN_CAM1_STROBE_PT1 _GPIO(153) +#define TEGRA_PIN_UART1_TX_PU0 _GPIO(160) +#define TEGRA_PIN_UART1_RX_PU1 _GPIO(161) +#define TEGRA_PIN_UART1_RTS_PU2 _GPIO(162) +#define TEGRA_PIN_UART1_CTS_PU3 _GPIO(163) +#define TEGRA_PIN_LCD_BL_PWM_PV0 _GPIO(168) +#define TEGRA_PIN_LCD_BL_EN_PV1 _GPIO(169) +#define TEGRA_PIN_LCD_RST_PV2 _GPIO(170) +#define TEGRA_PIN_LCD_GPIO1_PV3 _GPIO(171) +#define TEGRA_PIN_LCD_GPIO2_PV4 _GPIO(172) +#define TEGRA_PIN_AP_READY_PV5 _GPIO(173) +#define TEGRA_PIN_TOUCH_RST_PV6 _GPIO(174) +#define TEGRA_PIN_TOUCH_CLK_PV7 _GPIO(175) +#define TEGRA_PIN_MODEM_WAKE_AP_PX0 _GPIO(184) +#define TEGRA_PIN_TOUCH_INT_PX1 _GPIO(185) +#define TEGRA_PIN_MOTION_INT_PX2 _GPIO(186) +#define TEGRA_PIN_ALS_PROX_INT_PX3 _GPIO(187) +#define TEGRA_PIN_TEMP_ALERT_PX4 _GPIO(188) +#define TEGRA_PIN_BUTTON_POWER_ON_PX5 _GPIO(189) +#define TEGRA_PIN_BUTTON_VOL_UP_PX6 _GPIO(190) +#define TEGRA_PIN_BUTTON_VOL_DOWN_PX7 _GPIO(191) +#define TEGRA_PIN_BUTTON_SLIDE_SW_PY0 _GPIO(192) +#define TEGRA_PIN_BUTTON_HOME_PY1 _GPIO(193) +#define TEGRA_PIN_LCD_TE_PY2 _GPIO(194) +#define TEGRA_PIN_PWR_I2C_SCL_PY3 _GPIO(195) +#define TEGRA_PIN_PWR_I2C_SDA_PY4 _GPIO(196) +#define TEGRA_PIN_CLK_32K_OUT_PY5 _GPIO(197) +#define TEGRA_PIN_PZ0 _GPIO(200) +#define TEGRA_PIN_PZ1 _GPIO(201) +#define TEGRA_PIN_PZ2 _GPIO(202) +#define TEGRA_PIN_PZ3 _GPIO(203) +#define TEGRA_PIN_PZ4 _GPIO(204) +#define TEGRA_PIN_PZ5 _GPIO(205) +#define TEGRA_PIN_DAP2_FS_PAA0 _GPIO(208) +#define TEGRA_PIN_DAP2_SCLK_PAA1 _GPIO(209) +#define TEGRA_PIN_DAP2_DIN_PAA2 _GPIO(210) +#define TEGRA_PIN_DAP2_DOUT_PAA3 _GPIO(211) +#define TEGRA_PIN_AUD_MCLK_PBB0 _GPIO(216) +#define TEGRA_PIN_DVFS_PWM_PBB1 _GPIO(217) +#define TEGRA_PIN_DVFS_CLK_PBB2 _GPIO(218) +#define TEGRA_PIN_GPIO_X1_AUD_PBB3 _GPIO(219) +#define TEGRA_PIN_GPIO_X3_AUD_PBB4 _GPIO(220) +#define TEGRA_PIN_HDMI_CEC_PCC0 _GPIO(224) +#define TEGRA_PIN_HDMI_INT_DP_HPD_PCC1 _GPIO(225) +#define TEGRA_PIN_SPDIF_OUT_PCC2 _GPIO(226) +#define TEGRA_PIN_SPDIF_IN_PCC3 _GPIO(227) +#define TEGRA_PIN_USB_VBUS_EN0_PCC4 _GPIO(228) +#define TEGRA_PIN_USB_VBUS_EN1_PCC5 _GPIO(229) +#define TEGRA_PIN_DP_HPD0_PCC6 _GPIO(230) +#define TEGRA_PIN_PCC7 _GPIO(231) +#define TEGRA_PIN_SPI2_CS1_PDD0 _GPIO(232) +#define TEGRA_PIN_QSPI_SCK_PEE0 _GPIO(240) +#define TEGRA_PIN_QSPI_CS_N_PEE1 _GPIO(241) +#define TEGRA_PIN_QSPI_IO0_PEE2 _GPIO(242) +#define TEGRA_PIN_QSPI_IO1_PEE3 _GPIO(243) +#define TEGRA_PIN_QSPI_IO2_PEE4 _GPIO(244) +#define TEGRA_PIN_QSPI_IO3_PEE5 _GPIO(245) + +/* All non-GPIO pins follow */ +#define NUM_GPIOS (TEGRA_PIN_QSPI_IO3_PEE5 + 1) +#define _PIN(offset) (NUM_GPIOS + (offset)) + +/* Non-GPIO pins */ +#define TEGRA_PIN_CORE_PWR_REQ _PIN(0) +#define TEGRA_PIN_CPU_PWR_REQ _PIN(1) +#define TEGRA_PIN_PWR_INT_N _PIN(2) +#define TEGRA_PIN_CLK_32K_IN _PIN(3) +#define TEGRA_PIN_JTAG_RTCK _PIN(4) +#define TEGRA_PIN_BATT_BCL _PIN(5) +#define TEGRA_PIN_CLK_REQ _PIN(6) +#define TEGRA_PIN_SHUTDOWN _PIN(7) + +static const struct pinctrl_pin_desc tegra210_pins[] = { + PINCTRL_PIN(TEGRA_PIN_PEX_L0_RST_N_PA0, "PEX_L0_RST_N PA0"), + PINCTRL_PIN(TEGRA_PIN_PEX_L0_CLKREQ_N_PA1, "PEX_L0_CLKREQ_N PA1"), + PINCTRL_PIN(TEGRA_PIN_PEX_WAKE_N_PA2, "PEX_WAKE_N PA2"), + PINCTRL_PIN(TEGRA_PIN_PEX_L1_RST_N_PA3, "PEX_L1_RST_N PA3"), + PINCTRL_PIN(TEGRA_PIN_PEX_L1_CLKREQ_N_PA4, "PEX_L1_CLKREQ_N PA4"), + PINCTRL_PIN(TEGRA_PIN_SATA_LED_ACTIVE_PA5, "SATA_LED_ACTIVE PA5"), + PINCTRL_PIN(TEGRA_PIN_PA6, "PA6"), + PINCTRL_PIN(TEGRA_PIN_DAP1_FS_PB0, "DAP1_FS PB0"), + PINCTRL_PIN(TEGRA_PIN_DAP1_DIN_PB1, "DAP1_DIN PB1"), + PINCTRL_PIN(TEGRA_PIN_DAP1_DOUT_PB2, "DAP1_DOUT PB2"), + PINCTRL_PIN(TEGRA_PIN_DAP1_SCLK_PB3, "DAP1_SCLK PB3"), + PINCTRL_PIN(TEGRA_PIN_SPI2_MOSI_PB4, "SPI2_MOSI PB4"), + PINCTRL_PIN(TEGRA_PIN_SPI2_MISO_PB5, "SPI2_MISO PB5"), + PINCTRL_PIN(TEGRA_PIN_SPI2_SCK_PB6, "SPI2_SCK PB6"), + PINCTRL_PIN(TEGRA_PIN_SPI2_CS0_PB7, "SPI2_CS0 PB7"), + PINCTRL_PIN(TEGRA_PIN_SPI1_MOSI_PC0, "SPI1_MOSI PC0"), + PINCTRL_PIN(TEGRA_PIN_SPI1_MISO_PC1, "SPI1_MISO PC1"), + PINCTRL_PIN(TEGRA_PIN_SPI1_SCK_PC2, "SPI1_SCK PC2"), + PINCTRL_PIN(TEGRA_PIN_SPI1_CS0_PC3, "SPI1_CS0 PC3"), + PINCTRL_PIN(TEGRA_PIN_SPI1_CS1_PC4, "SPI1_CS1 PC4"), + PINCTRL_PIN(TEGRA_PIN_SPI4_SCK_PC5, "SPI4_SCK PC5"), + PINCTRL_PIN(TEGRA_PIN_SPI4_CS0_PC6, "SPI4_CS0 PC6"), + PINCTRL_PIN(TEGRA_PIN_SPI4_MOSI_PC7, "SPI4_MOSI PC7"), + PINCTRL_PIN(TEGRA_PIN_SPI4_MISO_PD0, "SPI4_MISO PD0"), + PINCTRL_PIN(TEGRA_PIN_UART3_TX_PD1, "UART3_TX PD1"), + PINCTRL_PIN(TEGRA_PIN_UART3_RX_PD2, "UART3_RX PD2"), + PINCTRL_PIN(TEGRA_PIN_UART3_RTS_PD3, "UART3_RTS PD3"), + PINCTRL_PIN(TEGRA_PIN_UART3_CTS_PD4, "UART3_CTS PD4"), + PINCTRL_PIN(TEGRA_PIN_DMIC1_CLK_PE0, "DMIC1_CLK PE0"), + PINCTRL_PIN(TEGRA_PIN_DMIC1_DAT_PE1, "DMIC1_DAT PE1"), + PINCTRL_PIN(TEGRA_PIN_DMIC2_CLK_PE2, "DMIC2_CLK PE2"), + PINCTRL_PIN(TEGRA_PIN_DMIC2_DAT_PE3, "DMIC2_DAT PE3"), + PINCTRL_PIN(TEGRA_PIN_DMIC3_CLK_PE4, "DMIC3_CLK PE4"), + PINCTRL_PIN(TEGRA_PIN_DMIC3_DAT_PE5, "DMIC3_DAT PE5"), + PINCTRL_PIN(TEGRA_PIN_PE6, "PE6"), + PINCTRL_PIN(TEGRA_PIN_PE7, "PE7"), + PINCTRL_PIN(TEGRA_PIN_GEN3_I2C_SCL_PF0, "GEN3_I2C_SCL PF0"), + PINCTRL_PIN(TEGRA_PIN_GEN3_I2C_SDA_PF1, "GEN3_I2C_SDA PF1"), + PINCTRL_PIN(TEGRA_PIN_UART2_TX_PG0, "UART2_TX PG0"), + PINCTRL_PIN(TEGRA_PIN_UART2_RX_PG1, "UART2_RX PG1"), + PINCTRL_PIN(TEGRA_PIN_UART2_RTS_PG2, "UART2_RTS PG2"), + PINCTRL_PIN(TEGRA_PIN_UART2_CTS_PG3, "UART2_CTS PG3"), + PINCTRL_PIN(TEGRA_PIN_WIFI_EN_PH0, "WIFI_EN PH0"), + PINCTRL_PIN(TEGRA_PIN_WIFI_RST_PH1, "WIFI_RST PH1"), + PINCTRL_PIN(TEGRA_PIN_WIFI_WAKE_AP_PH2, "WIFI_WAKE_AP PH2"), + PINCTRL_PIN(TEGRA_PIN_AP_WAKE_BT_PH3, "AP_WAKE_BT PH3"), + PINCTRL_PIN(TEGRA_PIN_BT_RST_PH4, "BT_RST PH4"), + PINCTRL_PIN(TEGRA_PIN_BT_WAKE_AP_PH5, "BT_WAKE_AP PH5"), + PINCTRL_PIN(TEGRA_PIN_PH6, "PH6"), + PINCTRL_PIN(TEGRA_PIN_AP_WAKE_NFC_PH7, "AP_WAKE_NFC PH7"), + PINCTRL_PIN(TEGRA_PIN_NFC_EN_PI0, "NFC_EN PI0"), + PINCTRL_PIN(TEGRA_PIN_NFC_INT_PI1, "NFC_INT PI1"), + PINCTRL_PIN(TEGRA_PIN_GPS_EN_PI2, "GPS_EN PI2"), + PINCTRL_PIN(TEGRA_PIN_GPS_RST_PI3, "GPS_RST PI3"), + PINCTRL_PIN(TEGRA_PIN_UART4_TX_PI4, "UART4_TX PI4"), + PINCTRL_PIN(TEGRA_PIN_UART4_RX_PI5, "UART4_RX PI5"), + PINCTRL_PIN(TEGRA_PIN_UART4_RTS_PI6, "UART4_RTS PI6"), + PINCTRL_PIN(TEGRA_PIN_UART4_CTS_PI7, "UART4_CTS PI7"), + PINCTRL_PIN(TEGRA_PIN_GEN1_I2C_SDA_PJ0, "GEN1_I2C_SDA PJ0"), + PINCTRL_PIN(TEGRA_PIN_GEN1_I2C_SCL_PJ1, "GEN1_I2C_SCL PJ1"), + PINCTRL_PIN(TEGRA_PIN_GEN2_I2C_SCL_PJ2, "GEN2_I2C_SCL PJ2"), + PINCTRL_PIN(TEGRA_PIN_GEN2_I2C_SDA_PJ3, "GEN2_I2C_SDA PJ3"), + PINCTRL_PIN(TEGRA_PIN_DAP4_FS_PJ4, "DAP4_FS PJ4"), + PINCTRL_PIN(TEGRA_PIN_DAP4_DIN_PJ5, "DAP4_DIN PJ5"), + PINCTRL_PIN(TEGRA_PIN_DAP4_DOUT_PJ6, "DAP4_DOUT PJ6"), + PINCTRL_PIN(TEGRA_PIN_DAP4_SCLK_PJ7, "DAP4_SCLK PJ7"), + PINCTRL_PIN(TEGRA_PIN_PK0, "PK0"), + PINCTRL_PIN(TEGRA_PIN_PK1, "PK1"), + PINCTRL_PIN(TEGRA_PIN_PK2, "PK2"), + PINCTRL_PIN(TEGRA_PIN_PK3, "PK3"), + PINCTRL_PIN(TEGRA_PIN_PK4, "PK4"), + PINCTRL_PIN(TEGRA_PIN_PK5, "PK5"), + PINCTRL_PIN(TEGRA_PIN_PK6, "PK6"), + PINCTRL_PIN(TEGRA_PIN_PK7, "PK7"), + PINCTRL_PIN(TEGRA_PIN_PL0, "PL0"), + PINCTRL_PIN(TEGRA_PIN_PL1, "PL1"), + PINCTRL_PIN(TEGRA_PIN_SDMMC1_CLK_PM0, "SDMMC1_CLK PM0"), + PINCTRL_PIN(TEGRA_PIN_SDMMC1_CMD_PM1, "SDMMC1_CMD PM1"), + PINCTRL_PIN(TEGRA_PIN_SDMMC1_DAT3_PM2, "SDMMC1_DAT3 PM2"), + PINCTRL_PIN(TEGRA_PIN_SDMMC1_DAT2_PM3, "SDMMC1_DAT2 PM3"), + PINCTRL_PIN(TEGRA_PIN_SDMMC1_DAT1_PM4, "SDMMC1_DAT1 PM4"), + PINCTRL_PIN(TEGRA_PIN_SDMMC1_DAT0_PM5, "SDMMC1_DAT0 PM5"), + PINCTRL_PIN(TEGRA_PIN_SDMMC3_CLK_PP0, "SDMMC3_CLK PP0"), + PINCTRL_PIN(TEGRA_PIN_SDMMC3_CMD_PP1, "SDMMC3_CMD PP1"), + PINCTRL_PIN(TEGRA_PIN_SDMMC3_DAT3_PP2, "SDMMC3_DAT3 PP2"), + PINCTRL_PIN(TEGRA_PIN_SDMMC3_DAT2_PP3, "SDMMC3_DAT2 PP3"), + PINCTRL_PIN(TEGRA_PIN_SDMMC3_DAT1_PP4, "SDMMC3_DAT1 PP4"), + PINCTRL_PIN(TEGRA_PIN_SDMMC3_DAT0_PP5, "SDMMC3_DAT0 PP5"), + PINCTRL_PIN(TEGRA_PIN_CAM1_MCLK_PS0, "CAM1_MCLK PS0"), + PINCTRL_PIN(TEGRA_PIN_CAM2_MCLK_PS1, "CAM2_MCLK PS1"), + PINCTRL_PIN(TEGRA_PIN_CAM_I2C_SCL_PS2, "CAM_I2C_SCL PS2"), + PINCTRL_PIN(TEGRA_PIN_CAM_I2C_SDA_PS3, "CAM_I2C_SDA PS3"), + PINCTRL_PIN(TEGRA_PIN_CAM_RST_PS4, "CAM_RST PS4"), + PINCTRL_PIN(TEGRA_PIN_CAM_AF_EN_PS5, "CAM_AF_EN PS5"), + PINCTRL_PIN(TEGRA_PIN_CAM_FLASH_EN_PS6, "CAM_FLASH_EN PS6"), + PINCTRL_PIN(TEGRA_PIN_CAM1_PWDN_PS7, "CAM1_PWDN PS7"), + PINCTRL_PIN(TEGRA_PIN_CAM2_PWDN_PT0, "CAM2_PWDN PT0"), + PINCTRL_PIN(TEGRA_PIN_CAM1_STROBE_PT1, "CAM1_STROBE PT1"), + PINCTRL_PIN(TEGRA_PIN_UART1_TX_PU0, "UART1_TX PU0"), + PINCTRL_PIN(TEGRA_PIN_UART1_RX_PU1, "UART1_RX PU1"), + PINCTRL_PIN(TEGRA_PIN_UART1_RTS_PU2, "UART1_RTS PU2"), + PINCTRL_PIN(TEGRA_PIN_UART1_CTS_PU3, "UART1_CTS PU3"), + PINCTRL_PIN(TEGRA_PIN_LCD_BL_PWM_PV0, "LCD_BL_PWM PV0"), + PINCTRL_PIN(TEGRA_PIN_LCD_BL_EN_PV1, "LCD_BL_EN PV1"), + PINCTRL_PIN(TEGRA_PIN_LCD_RST_PV2, "LCD_RST PV2"), + PINCTRL_PIN(TEGRA_PIN_LCD_GPIO1_PV3, "LCD_GPIO1 PV3"), + PINCTRL_PIN(TEGRA_PIN_LCD_GPIO2_PV4, "LCD_GPIO2 PV4"), + PINCTRL_PIN(TEGRA_PIN_AP_READY_PV5, "AP_READY PV5"), + PINCTRL_PIN(TEGRA_PIN_TOUCH_RST_PV6, "TOUCH_RST PV6"), + PINCTRL_PIN(TEGRA_PIN_TOUCH_CLK_PV7, "TOUCH_CLK PV7"), + PINCTRL_PIN(TEGRA_PIN_MODEM_WAKE_AP_PX0, "MODEM_WAKE_AP PX0"), + PINCTRL_PIN(TEGRA_PIN_TOUCH_INT_PX1, "TOUCH_INT PX1"), + PINCTRL_PIN(TEGRA_PIN_MOTION_INT_PX2, "MOTION_INT PX2"), + PINCTRL_PIN(TEGRA_PIN_ALS_PROX_INT_PX3, "ALS_PROX_INT PX3"), + PINCTRL_PIN(TEGRA_PIN_TEMP_ALERT_PX4, "TEMP_ALERT PX4"), + PINCTRL_PIN(TEGRA_PIN_BUTTON_POWER_ON_PX5, "BUTTON_POWER_ON PX5"), + PINCTRL_PIN(TEGRA_PIN_BUTTON_VOL_UP_PX6, "BUTTON_VOL_UP PX6"), + PINCTRL_PIN(TEGRA_PIN_BUTTON_VOL_DOWN_PX7, "BUTTON_VOL_DOWN PX7"), + PINCTRL_PIN(TEGRA_PIN_BUTTON_SLIDE_SW_PY0, "BUTTON_SLIDE_SW PY0"), + PINCTRL_PIN(TEGRA_PIN_BUTTON_HOME_PY1, "BUTTON_HOME PY1"), + PINCTRL_PIN(TEGRA_PIN_LCD_TE_PY2, "LCD_TE PY2"), + PINCTRL_PIN(TEGRA_PIN_PWR_I2C_SCL_PY3, "PWR_I2C_SCL PY3"), + PINCTRL_PIN(TEGRA_PIN_PWR_I2C_SDA_PY4, "PWR_I2C_SDA PY4"), + PINCTRL_PIN(TEGRA_PIN_CLK_32K_OUT_PY5, "CLK_32K_OUT PY5"), + PINCTRL_PIN(TEGRA_PIN_PZ0, "PZ0"), + PINCTRL_PIN(TEGRA_PIN_PZ1, "PZ1"), + PINCTRL_PIN(TEGRA_PIN_PZ2, "PZ2"), + PINCTRL_PIN(TEGRA_PIN_PZ3, "PZ3"), + PINCTRL_PIN(TEGRA_PIN_PZ4, "PZ4"), + PINCTRL_PIN(TEGRA_PIN_PZ5, "PZ5"), + PINCTRL_PIN(TEGRA_PIN_DAP2_FS_PAA0, "DAP2_FS PAA0"), + PINCTRL_PIN(TEGRA_PIN_DAP2_SCLK_PAA1, "DAP2_SCLK PAA1"), + PINCTRL_PIN(TEGRA_PIN_DAP2_DIN_PAA2, "DAP2_DIN PAA2"), + PINCTRL_PIN(TEGRA_PIN_DAP2_DOUT_PAA3, "DAP2_DOUT PAA3"), + PINCTRL_PIN(TEGRA_PIN_AUD_MCLK_PBB0, "AUD_MCLK PBB0"), + PINCTRL_PIN(TEGRA_PIN_DVFS_PWM_PBB1, "DVFS_PWM PBB1"), + PINCTRL_PIN(TEGRA_PIN_DVFS_CLK_PBB2, "DVFS_CLK PBB2"), + PINCTRL_PIN(TEGRA_PIN_GPIO_X1_AUD_PBB3, "GPIO_X1_AUD PBB3"), + PINCTRL_PIN(TEGRA_PIN_GPIO_X3_AUD_PBB4, "GPIO_X3_AUD PBB4"), + PINCTRL_PIN(TEGRA_PIN_HDMI_CEC_PCC0, "HDMI_CEC PCC0"), + PINCTRL_PIN(TEGRA_PIN_HDMI_INT_DP_HPD_PCC1, "HDMI_INT_DP_HPD PCC1"), + PINCTRL_PIN(TEGRA_PIN_SPDIF_OUT_PCC2, "SPDIF_OUT PCC2"), + PINCTRL_PIN(TEGRA_PIN_SPDIF_IN_PCC3, "SPDIF_IN PCC3"), + PINCTRL_PIN(TEGRA_PIN_USB_VBUS_EN0_PCC4, "USB_VBUS_EN0 PCC4"), + PINCTRL_PIN(TEGRA_PIN_USB_VBUS_EN1_PCC5, "USB_VBUS_EN1 PCC5"), + PINCTRL_PIN(TEGRA_PIN_DP_HPD0_PCC6, "DP_HPD0 PCC6"), + PINCTRL_PIN(TEGRA_PIN_PCC7, "PCC7"), + PINCTRL_PIN(TEGRA_PIN_SPI2_CS1_PDD0, "SPI2_CS1 PDD0"), + PINCTRL_PIN(TEGRA_PIN_QSPI_SCK_PEE0, "QSPI_SCK PEE0"), + PINCTRL_PIN(TEGRA_PIN_QSPI_CS_N_PEE1, "QSPI_CS_N PEE1"), + PINCTRL_PIN(TEGRA_PIN_QSPI_IO0_PEE2, "QSPI_IO0 PEE2"), + PINCTRL_PIN(TEGRA_PIN_QSPI_IO1_PEE3, "QSPI_IO1 PEE3"), + PINCTRL_PIN(TEGRA_PIN_QSPI_IO2_PEE4, "QSPI_IO2 PEE4"), + PINCTRL_PIN(TEGRA_PIN_QSPI_IO3_PEE5, "QSPI_IO3 PEE5"), + PINCTRL_PIN(TEGRA_PIN_CORE_PWR_REQ, "CORE_PWR_REQ"), + PINCTRL_PIN(TEGRA_PIN_CPU_PWR_REQ, "CPU_PWR_REQ"), + PINCTRL_PIN(TEGRA_PIN_PWR_INT_N, "PWR_INT_N"), + PINCTRL_PIN(TEGRA_PIN_CLK_32K_IN, "CLK_32K_IN"), + PINCTRL_PIN(TEGRA_PIN_JTAG_RTCK, "JTAG_RTCK"), + PINCTRL_PIN(TEGRA_PIN_BATT_BCL, "BATT_BCL"), + PINCTRL_PIN(TEGRA_PIN_CLK_REQ, "CLK_REQ"), + PINCTRL_PIN(TEGRA_PIN_SHUTDOWN, "SHUTDOWN"), +}; + +static const unsigned pex_l0_rst_n_pa0_pins[] = { + TEGRA_PIN_PEX_L0_RST_N_PA0, +}; + +static const unsigned pex_l0_clkreq_n_pa1_pins[] = { + TEGRA_PIN_PEX_L0_CLKREQ_N_PA1, +}; + +static const unsigned pex_wake_n_pa2_pins[] = { + TEGRA_PIN_PEX_WAKE_N_PA2, +}; + +static const unsigned pex_l1_rst_n_pa3_pins[] = { + TEGRA_PIN_PEX_L1_RST_N_PA3, +}; + +static const unsigned pex_l1_clkreq_n_pa4_pins[] = { + TEGRA_PIN_PEX_L1_CLKREQ_N_PA4, +}; + +static const unsigned sata_led_active_pa5_pins[] = { + TEGRA_PIN_SATA_LED_ACTIVE_PA5, +}; + +static const unsigned pa6_pins[] = { + TEGRA_PIN_PA6, +}; + +static const unsigned dap1_fs_pb0_pins[] = { + TEGRA_PIN_DAP1_FS_PB0, +}; + +static const unsigned dap1_din_pb1_pins[] = { + TEGRA_PIN_DAP1_DIN_PB1, +}; + +static const unsigned dap1_dout_pb2_pins[] = { + TEGRA_PIN_DAP1_DOUT_PB2, +}; + +static const unsigned dap1_sclk_pb3_pins[] = { + TEGRA_PIN_DAP1_SCLK_PB3, +}; + +static const unsigned spi2_mosi_pb4_pins[] = { + TEGRA_PIN_SPI2_MOSI_PB4, +}; + +static const unsigned spi2_miso_pb5_pins[] = { + TEGRA_PIN_SPI2_MISO_PB5, +}; + +static const unsigned spi2_sck_pb6_pins[] = { + TEGRA_PIN_SPI2_SCK_PB6, +}; + +static const unsigned spi2_cs0_pb7_pins[] = { + TEGRA_PIN_SPI2_CS0_PB7, +}; + +static const unsigned spi1_mosi_pc0_pins[] = { + TEGRA_PIN_SPI1_MOSI_PC0, +}; + +static const unsigned spi1_miso_pc1_pins[] = { + TEGRA_PIN_SPI1_MISO_PC1, +}; + +static const unsigned spi1_sck_pc2_pins[] = { + TEGRA_PIN_SPI1_SCK_PC2, +}; + +static const unsigned spi1_cs0_pc3_pins[] = { + TEGRA_PIN_SPI1_CS0_PC3, +}; + +static const unsigned spi1_cs1_pc4_pins[] = { + TEGRA_PIN_SPI1_CS1_PC4, +}; + +static const unsigned spi4_sck_pc5_pins[] = { + TEGRA_PIN_SPI4_SCK_PC5, +}; + +static const unsigned spi4_cs0_pc6_pins[] = { + TEGRA_PIN_SPI4_CS0_PC6, +}; + +static const unsigned spi4_mosi_pc7_pins[] = { + TEGRA_PIN_SPI4_MOSI_PC7, +}; + +static const unsigned spi4_miso_pd0_pins[] = { + TEGRA_PIN_SPI4_MISO_PD0, +}; + +static const unsigned uart3_tx_pd1_pins[] = { + TEGRA_PIN_UART3_TX_PD1, +}; + +static const unsigned uart3_rx_pd2_pins[] = { + TEGRA_PIN_UART3_RX_PD2, +}; + +static const unsigned uart3_rts_pd3_pins[] = { + TEGRA_PIN_UART3_RTS_PD3, +}; + +static const unsigned uart3_cts_pd4_pins[] = { + TEGRA_PIN_UART3_CTS_PD4, +}; + +static const unsigned dmic1_clk_pe0_pins[] = { + TEGRA_PIN_DMIC1_CLK_PE0, +}; + +static const unsigned dmic1_dat_pe1_pins[] = { + TEGRA_PIN_DMIC1_DAT_PE1, +}; + +static const unsigned dmic2_clk_pe2_pins[] = { + TEGRA_PIN_DMIC2_CLK_PE2, +}; + +static const unsigned dmic2_dat_pe3_pins[] = { + TEGRA_PIN_DMIC2_DAT_PE3, +}; + +static const unsigned dmic3_clk_pe4_pins[] = { + TEGRA_PIN_DMIC3_CLK_PE4, +}; + +static const unsigned dmic3_dat_pe5_pins[] = { + TEGRA_PIN_DMIC3_DAT_PE5, +}; + +static const unsigned pe6_pins[] = { + TEGRA_PIN_PE6, +}; + +static const unsigned pe7_pins[] = { + TEGRA_PIN_PE7, +}; + +static const unsigned gen3_i2c_scl_pf0_pins[] = { + TEGRA_PIN_GEN3_I2C_SCL_PF0, +}; + +static const unsigned gen3_i2c_sda_pf1_pins[] = { + TEGRA_PIN_GEN3_I2C_SDA_PF1, +}; + +static const unsigned uart2_tx_pg0_pins[] = { + TEGRA_PIN_UART2_TX_PG0, +}; + +static const unsigned uart2_rx_pg1_pins[] = { + TEGRA_PIN_UART2_RX_PG1, +}; + +static const unsigned uart2_rts_pg2_pins[] = { + TEGRA_PIN_UART2_RTS_PG2, +}; + +static const unsigned uart2_cts_pg3_pins[] = { + TEGRA_PIN_UART2_CTS_PG3, +}; + +static const unsigned wifi_en_ph0_pins[] = { + TEGRA_PIN_WIFI_EN_PH0, +}; + +static const unsigned wifi_rst_ph1_pins[] = { + TEGRA_PIN_WIFI_RST_PH1, +}; + +static const unsigned wifi_wake_ap_ph2_pins[] = { + TEGRA_PIN_WIFI_WAKE_AP_PH2, +}; + +static const unsigned ap_wake_bt_ph3_pins[] = { + TEGRA_PIN_AP_WAKE_BT_PH3, +}; + +static const unsigned bt_rst_ph4_pins[] = { + TEGRA_PIN_BT_RST_PH4, +}; + +static const unsigned bt_wake_ap_ph5_pins[] = { + TEGRA_PIN_BT_WAKE_AP_PH5, +}; + +static const unsigned ph6_pins[] = { + TEGRA_PIN_PH6, +}; + +static const unsigned ap_wake_nfc_ph7_pins[] = { + TEGRA_PIN_AP_WAKE_NFC_PH7, +}; + +static const unsigned nfc_en_pi0_pins[] = { + TEGRA_PIN_NFC_EN_PI0, +}; + +static const unsigned nfc_int_pi1_pins[] = { + TEGRA_PIN_NFC_INT_PI1, +}; + +static const unsigned gps_en_pi2_pins[] = { + TEGRA_PIN_GPS_EN_PI2, +}; + +static const unsigned gps_rst_pi3_pins[] = { + TEGRA_PIN_GPS_RST_PI3, +}; + +static const unsigned uart4_tx_pi4_pins[] = { + TEGRA_PIN_UART4_TX_PI4, +}; + +static const unsigned uart4_rx_pi5_pins[] = { + TEGRA_PIN_UART4_RX_PI5, +}; + +static const unsigned uart4_rts_pi6_pins[] = { + TEGRA_PIN_UART4_RTS_PI6, +}; + +static const unsigned uart4_cts_pi7_pins[] = { + TEGRA_PIN_UART4_CTS_PI7, +}; + +static const unsigned gen1_i2c_sda_pj0_pins[] = { + TEGRA_PIN_GEN1_I2C_SDA_PJ0, +}; + +static const unsigned gen1_i2c_scl_pj1_pins[] = { + TEGRA_PIN_GEN1_I2C_SCL_PJ1, +}; + +static const unsigned gen2_i2c_scl_pj2_pins[] = { + TEGRA_PIN_GEN2_I2C_SCL_PJ2, +}; + +static const unsigned gen2_i2c_sda_pj3_pins[] = { + TEGRA_PIN_GEN2_I2C_SDA_PJ3, +}; + +static const unsigned dap4_fs_pj4_pins[] = { + TEGRA_PIN_DAP4_FS_PJ4, +}; + +static const unsigned dap4_din_pj5_pins[] = { + TEGRA_PIN_DAP4_DIN_PJ5, +}; + +static const unsigned dap4_dout_pj6_pins[] = { + TEGRA_PIN_DAP4_DOUT_PJ6, +}; + +static const unsigned dap4_sclk_pj7_pins[] = { + TEGRA_PIN_DAP4_SCLK_PJ7, +}; + +static const unsigned pk0_pins[] = { + TEGRA_PIN_PK0, +}; + +static const unsigned pk1_pins[] = { + TEGRA_PIN_PK1, +}; + +static const unsigned pk2_pins[] = { + TEGRA_PIN_PK2, +}; + +static const unsigned pk3_pins[] = { + TEGRA_PIN_PK3, +}; + +static const unsigned pk4_pins[] = { + TEGRA_PIN_PK4, +}; + +static const unsigned pk5_pins[] = { + TEGRA_PIN_PK5, +}; + +static const unsigned pk6_pins[] = { + TEGRA_PIN_PK6, +}; + +static const unsigned pk7_pins[] = { + TEGRA_PIN_PK7, +}; + +static const unsigned pl0_pins[] = { + TEGRA_PIN_PL0, +}; + +static const unsigned pl1_pins[] = { + TEGRA_PIN_PL1, +}; + +static const unsigned sdmmc1_clk_pm0_pins[] = { + TEGRA_PIN_SDMMC1_CLK_PM0, +}; + +static const unsigned sdmmc1_cmd_pm1_pins[] = { + TEGRA_PIN_SDMMC1_CMD_PM1, +}; + +static const unsigned sdmmc1_dat3_pm2_pins[] = { + TEGRA_PIN_SDMMC1_DAT3_PM2, +}; + +static const unsigned sdmmc1_dat2_pm3_pins[] = { + TEGRA_PIN_SDMMC1_DAT2_PM3, +}; + +static const unsigned sdmmc1_dat1_pm4_pins[] = { + TEGRA_PIN_SDMMC1_DAT1_PM4, +}; + +static const unsigned sdmmc1_dat0_pm5_pins[] = { + TEGRA_PIN_SDMMC1_DAT0_PM5, +}; + +static const unsigned sdmmc3_clk_pp0_pins[] = { + TEGRA_PIN_SDMMC3_CLK_PP0, +}; + +static const unsigned sdmmc3_cmd_pp1_pins[] = { + TEGRA_PIN_SDMMC3_CMD_PP1, +}; + +static const unsigned sdmmc3_dat3_pp2_pins[] = { + TEGRA_PIN_SDMMC3_DAT3_PP2, +}; + +static const unsigned sdmmc3_dat2_pp3_pins[] = { + TEGRA_PIN_SDMMC3_DAT2_PP3, +}; + +static const unsigned sdmmc3_dat1_pp4_pins[] = { + TEGRA_PIN_SDMMC3_DAT1_PP4, +}; + +static const unsigned sdmmc3_dat0_pp5_pins[] = { + TEGRA_PIN_SDMMC3_DAT0_PP5, +}; + +static const unsigned cam1_mclk_ps0_pins[] = { + TEGRA_PIN_CAM1_MCLK_PS0, +}; + +static const unsigned cam2_mclk_ps1_pins[] = { + TEGRA_PIN_CAM2_MCLK_PS1, +}; + +static const unsigned cam_i2c_scl_ps2_pins[] = { + TEGRA_PIN_CAM_I2C_SCL_PS2, +}; + +static const unsigned cam_i2c_sda_ps3_pins[] = { + TEGRA_PIN_CAM_I2C_SDA_PS3, +}; + +static const unsigned cam_rst_ps4_pins[] = { + TEGRA_PIN_CAM_RST_PS4, +}; + +static const unsigned cam_af_en_ps5_pins[] = { + TEGRA_PIN_CAM_AF_EN_PS5, +}; + +static const unsigned cam_flash_en_ps6_pins[] = { + TEGRA_PIN_CAM_FLASH_EN_PS6, +}; + +static const unsigned cam1_pwdn_ps7_pins[] = { + TEGRA_PIN_CAM1_PWDN_PS7, +}; + +static const unsigned cam2_pwdn_pt0_pins[] = { + TEGRA_PIN_CAM2_PWDN_PT0, +}; + +static const unsigned cam1_strobe_pt1_pins[] = { + TEGRA_PIN_CAM1_STROBE_PT1, +}; + +static const unsigned uart1_tx_pu0_pins[] = { + TEGRA_PIN_UART1_TX_PU0, +}; + +static const unsigned uart1_rx_pu1_pins[] = { + TEGRA_PIN_UART1_RX_PU1, +}; + +static const unsigned uart1_rts_pu2_pins[] = { + TEGRA_PIN_UART1_RTS_PU2, +}; + +static const unsigned uart1_cts_pu3_pins[] = { + TEGRA_PIN_UART1_CTS_PU3, +}; + +static const unsigned lcd_bl_pwm_pv0_pins[] = { + TEGRA_PIN_LCD_BL_PWM_PV0, +}; + +static const unsigned lcd_bl_en_pv1_pins[] = { + TEGRA_PIN_LCD_BL_EN_PV1, +}; + +static const unsigned lcd_rst_pv2_pins[] = { + TEGRA_PIN_LCD_RST_PV2, +}; + +static const unsigned lcd_gpio1_pv3_pins[] = { + TEGRA_PIN_LCD_GPIO1_PV3, +}; + +static const unsigned lcd_gpio2_pv4_pins[] = { + TEGRA_PIN_LCD_GPIO2_PV4, +}; + +static const unsigned ap_ready_pv5_pins[] = { + TEGRA_PIN_AP_READY_PV5, +}; + +static const unsigned touch_rst_pv6_pins[] = { + TEGRA_PIN_TOUCH_RST_PV6, +}; + +static const unsigned touch_clk_pv7_pins[] = { + TEGRA_PIN_TOUCH_CLK_PV7, +}; + +static const unsigned modem_wake_ap_px0_pins[] = { + TEGRA_PIN_MODEM_WAKE_AP_PX0, +}; + +static const unsigned touch_int_px1_pins[] = { + TEGRA_PIN_TOUCH_INT_PX1, +}; + +static const unsigned motion_int_px2_pins[] = { + TEGRA_PIN_MOTION_INT_PX2, +}; + +static const unsigned als_prox_int_px3_pins[] = { + TEGRA_PIN_ALS_PROX_INT_PX3, +}; + +static const unsigned temp_alert_px4_pins[] = { + TEGRA_PIN_TEMP_ALERT_PX4, +}; + +static const unsigned button_power_on_px5_pins[] = { + TEGRA_PIN_BUTTON_POWER_ON_PX5, +}; + +static const unsigned button_vol_up_px6_pins[] = { + TEGRA_PIN_BUTTON_VOL_UP_PX6, +}; + +static const unsigned button_vol_down_px7_pins[] = { + TEGRA_PIN_BUTTON_VOL_DOWN_PX7, +}; + +static const unsigned button_slide_sw_py0_pins[] = { + TEGRA_PIN_BUTTON_SLIDE_SW_PY0, +}; + +static const unsigned button_home_py1_pins[] = { + TEGRA_PIN_BUTTON_HOME_PY1, +}; + +static const unsigned lcd_te_py2_pins[] = { + TEGRA_PIN_LCD_TE_PY2, +}; + +static const unsigned pwr_i2c_scl_py3_pins[] = { + TEGRA_PIN_PWR_I2C_SCL_PY3, +}; + +static const unsigned pwr_i2c_sda_py4_pins[] = { + TEGRA_PIN_PWR_I2C_SDA_PY4, +}; + +static const unsigned clk_32k_out_py5_pins[] = { + TEGRA_PIN_CLK_32K_OUT_PY5, +}; + +static const unsigned pz0_pins[] = { + TEGRA_PIN_PZ0, +}; + +static const unsigned pz1_pins[] = { + TEGRA_PIN_PZ1, +}; + +static const unsigned pz2_pins[] = { + TEGRA_PIN_PZ2, +}; + +static const unsigned pz3_pins[] = { + TEGRA_PIN_PZ3, +}; + +static const unsigned pz4_pins[] = { + TEGRA_PIN_PZ4, +}; + +static const unsigned pz5_pins[] = { + TEGRA_PIN_PZ5, +}; + +static const unsigned dap2_fs_paa0_pins[] = { + TEGRA_PIN_DAP2_FS_PAA0, +}; + +static const unsigned dap2_sclk_paa1_pins[] = { + TEGRA_PIN_DAP2_SCLK_PAA1, +}; + +static const unsigned dap2_din_paa2_pins[] = { + TEGRA_PIN_DAP2_DIN_PAA2, +}; + +static const unsigned dap2_dout_paa3_pins[] = { + TEGRA_PIN_DAP2_DOUT_PAA3, +}; + +static const unsigned aud_mclk_pbb0_pins[] = { + TEGRA_PIN_AUD_MCLK_PBB0, +}; + +static const unsigned dvfs_pwm_pbb1_pins[] = { + TEGRA_PIN_DVFS_PWM_PBB1, +}; + +static const unsigned dvfs_clk_pbb2_pins[] = { + TEGRA_PIN_DVFS_CLK_PBB2, +}; + +static const unsigned gpio_x1_aud_pbb3_pins[] = { + TEGRA_PIN_GPIO_X1_AUD_PBB3, +}; + +static const unsigned gpio_x3_aud_pbb4_pins[] = { + TEGRA_PIN_GPIO_X3_AUD_PBB4, +}; + +static const unsigned hdmi_cec_pcc0_pins[] = { + TEGRA_PIN_HDMI_CEC_PCC0, +}; + +static const unsigned hdmi_int_dp_hpd_pcc1_pins[] = { + TEGRA_PIN_HDMI_INT_DP_HPD_PCC1, +}; + +static const unsigned spdif_out_pcc2_pins[] = { + TEGRA_PIN_SPDIF_OUT_PCC2, +}; + +static const unsigned spdif_in_pcc3_pins[] = { + TEGRA_PIN_SPDIF_IN_PCC3, +}; + +static const unsigned usb_vbus_en0_pcc4_pins[] = { + TEGRA_PIN_USB_VBUS_EN0_PCC4, +}; + +static const unsigned usb_vbus_en1_pcc5_pins[] = { + TEGRA_PIN_USB_VBUS_EN1_PCC5, +}; + +static const unsigned dp_hpd0_pcc6_pins[] = { + TEGRA_PIN_DP_HPD0_PCC6, +}; + +static const unsigned pcc7_pins[] = { + TEGRA_PIN_PCC7, +}; + +static const unsigned spi2_cs1_pdd0_pins[] = { + TEGRA_PIN_SPI2_CS1_PDD0, +}; + +static const unsigned qspi_sck_pee0_pins[] = { + TEGRA_PIN_QSPI_SCK_PEE0, +}; + +static const unsigned qspi_cs_n_pee1_pins[] = { + TEGRA_PIN_QSPI_CS_N_PEE1, +}; + +static const unsigned qspi_io0_pee2_pins[] = { + TEGRA_PIN_QSPI_IO0_PEE2, +}; + +static const unsigned qspi_io1_pee3_pins[] = { + TEGRA_PIN_QSPI_IO1_PEE3, +}; + +static const unsigned qspi_io2_pee4_pins[] = { + TEGRA_PIN_QSPI_IO2_PEE4, +}; + +static const unsigned qspi_io3_pee5_pins[] = { + TEGRA_PIN_QSPI_IO3_PEE5, +}; + +static const unsigned core_pwr_req_pins[] = { + TEGRA_PIN_CORE_PWR_REQ, +}; + +static const unsigned cpu_pwr_req_pins[] = { + TEGRA_PIN_CPU_PWR_REQ, +}; + +static const unsigned pwr_int_n_pins[] = { + TEGRA_PIN_PWR_INT_N, +}; + +static const unsigned clk_32k_in_pins[] = { + TEGRA_PIN_CLK_32K_IN, +}; + +static const unsigned jtag_rtck_pins[] = { + TEGRA_PIN_JTAG_RTCK, +}; + +static const unsigned batt_bcl_pins[] = { + TEGRA_PIN_BATT_BCL, +}; + +static const unsigned clk_req_pins[] = { + TEGRA_PIN_CLK_REQ, +}; + +static const unsigned shutdown_pins[] = { + TEGRA_PIN_SHUTDOWN, +}; + +static const unsigned drive_pa6_pins[] = { + TEGRA_PIN_PA6, +}; + +static const unsigned drive_pcc7_pins[] = { + TEGRA_PIN_PCC7, +}; + +static const unsigned drive_pe6_pins[] = { + TEGRA_PIN_PE6, +}; + +static const unsigned drive_pe7_pins[] = { + TEGRA_PIN_PE7, +}; + +static const unsigned drive_ph6_pins[] = { + TEGRA_PIN_PH6, +}; + +static const unsigned drive_pk0_pins[] = { + TEGRA_PIN_PK0, +}; + +static const unsigned drive_pk1_pins[] = { + TEGRA_PIN_PK1, +}; + +static const unsigned drive_pk2_pins[] = { + TEGRA_PIN_PK2, +}; + +static const unsigned drive_pk3_pins[] = { + TEGRA_PIN_PK3, +}; + +static const unsigned drive_pk4_pins[] = { + TEGRA_PIN_PK4, +}; + +static const unsigned drive_pk5_pins[] = { + TEGRA_PIN_PK5, +}; + +static const unsigned drive_pk6_pins[] = { + TEGRA_PIN_PK6, +}; + +static const unsigned drive_pk7_pins[] = { + TEGRA_PIN_PK7, +}; + +static const unsigned drive_pl0_pins[] = { + TEGRA_PIN_PL0, +}; + +static const unsigned drive_pl1_pins[] = { + TEGRA_PIN_PL1, +}; + +static const unsigned drive_pz0_pins[] = { + TEGRA_PIN_PZ0, +}; + +static const unsigned drive_pz1_pins[] = { + TEGRA_PIN_PZ1, +}; + +static const unsigned drive_pz2_pins[] = { + TEGRA_PIN_PZ2, +}; + +static const unsigned drive_pz3_pins[] = { + TEGRA_PIN_PZ3, +}; + +static const unsigned drive_pz4_pins[] = { + TEGRA_PIN_PZ4, +}; + +static const unsigned drive_pz5_pins[] = { + TEGRA_PIN_PZ5, +}; + +static const unsigned drive_sdmmc1_pins[] = { + TEGRA_PIN_SDMMC1_CLK_PM0, + TEGRA_PIN_SDMMC1_CMD_PM1, + TEGRA_PIN_SDMMC1_DAT3_PM2, + TEGRA_PIN_SDMMC1_DAT2_PM3, + TEGRA_PIN_SDMMC1_DAT1_PM4, + TEGRA_PIN_SDMMC1_DAT0_PM5, +}; + +static const unsigned drive_sdmmc2_pins[] = { +}; + +static const unsigned drive_sdmmc3_pins[] = { + TEGRA_PIN_SDMMC3_CLK_PP0, + TEGRA_PIN_SDMMC3_CMD_PP1, + TEGRA_PIN_SDMMC3_DAT3_PP2, + TEGRA_PIN_SDMMC3_DAT2_PP3, + TEGRA_PIN_SDMMC3_DAT1_PP4, + TEGRA_PIN_SDMMC3_DAT0_PP5, +}; + +static const unsigned drive_sdmmc4_pins[] = { +}; + +enum tegra_mux { + TEGRA_MUX_AUD, + TEGRA_MUX_BCL, + TEGRA_MUX_BLINK, + TEGRA_MUX_CCLA, + TEGRA_MUX_CEC, + TEGRA_MUX_CLDVFS, + TEGRA_MUX_CLK, + TEGRA_MUX_CORE, + TEGRA_MUX_CPU, + TEGRA_MUX_DISPLAYA, + TEGRA_MUX_DISPLAYB, + TEGRA_MUX_DMIC1, + TEGRA_MUX_DMIC2, + TEGRA_MUX_DMIC3, + TEGRA_MUX_DP, + TEGRA_MUX_DTV, + TEGRA_MUX_EXTPERIPH3, + TEGRA_MUX_I2C1, + TEGRA_MUX_I2C2, + TEGRA_MUX_I2C3, + TEGRA_MUX_I2CPMU, + TEGRA_MUX_I2CVI, + TEGRA_MUX_I2S1, + TEGRA_MUX_I2S2, + TEGRA_MUX_I2S3, + TEGRA_MUX_I2S4A, + TEGRA_MUX_I2S4B, + TEGRA_MUX_I2S5A, + TEGRA_MUX_I2S5B, + TEGRA_MUX_IQC0, + TEGRA_MUX_IQC1, + TEGRA_MUX_JTAG, + TEGRA_MUX_PE, + TEGRA_MUX_PE0, + TEGRA_MUX_PE1, + TEGRA_MUX_PMI, + TEGRA_MUX_PWM0, + TEGRA_MUX_PWM1, + TEGRA_MUX_PWM2, + TEGRA_MUX_PWM3, + TEGRA_MUX_QSPI, + TEGRA_MUX_RSVD0, + TEGRA_MUX_RSVD1, + TEGRA_MUX_RSVD2, + TEGRA_MUX_RSVD3, + TEGRA_MUX_SATA, + TEGRA_MUX_SDMMC1, + TEGRA_MUX_SDMMC3, + TEGRA_MUX_SHUTDOWN, + TEGRA_MUX_SOC, + TEGRA_MUX_SOR0, + TEGRA_MUX_SOR1, + TEGRA_MUX_SPDIF, + TEGRA_MUX_SPI1, + TEGRA_MUX_SPI2, + TEGRA_MUX_SPI3, + TEGRA_MUX_SPI4, + TEGRA_MUX_SYS, + TEGRA_MUX_TOUCH, + TEGRA_MUX_UART, + TEGRA_MUX_UARTA, + TEGRA_MUX_UARTB, + TEGRA_MUX_UARTC, + TEGRA_MUX_UARTD, + TEGRA_MUX_USB, + TEGRA_MUX_VGP1, + TEGRA_MUX_VGP2, + TEGRA_MUX_VGP3, + TEGRA_MUX_VGP4, + TEGRA_MUX_VGP5, + TEGRA_MUX_VGP6, + TEGRA_MUX_VIMCLK, + TEGRA_MUX_VIMCLK2, +}; + +#define FUNCTION(fname) \ + { \ + .name = #fname, \ + } + +static struct tegra_function tegra210_functions[] = { + FUNCTION(aud), + FUNCTION(bcl), + FUNCTION(blink), + FUNCTION(ccla), + FUNCTION(cec), + FUNCTION(cldvfs), + FUNCTION(clk), + FUNCTION(core), + FUNCTION(cpu), + FUNCTION(displaya), + FUNCTION(displayb), + FUNCTION(dmic1), + FUNCTION(dmic2), + FUNCTION(dmic3), + FUNCTION(dp), + FUNCTION(dtv), + FUNCTION(extperiph3), + FUNCTION(i2c1), + FUNCTION(i2c2), + FUNCTION(i2c3), + FUNCTION(i2cpmu), + FUNCTION(i2cvi), + FUNCTION(i2s1), + FUNCTION(i2s2), + FUNCTION(i2s3), + FUNCTION(i2s4a), + FUNCTION(i2s4b), + FUNCTION(i2s5a), + FUNCTION(i2s5b), + FUNCTION(iqc0), + FUNCTION(iqc1), + FUNCTION(jtag), + FUNCTION(pe), + FUNCTION(pe0), + FUNCTION(pe1), + FUNCTION(pmi), + FUNCTION(pwm0), + FUNCTION(pwm1), + FUNCTION(pwm2), + FUNCTION(pwm3), + FUNCTION(qspi), + FUNCTION(rsvd0), + FUNCTION(rsvd1), + FUNCTION(rsvd2), + FUNCTION(rsvd3), + FUNCTION(sata), + FUNCTION(sdmmc1), + FUNCTION(sdmmc3), + FUNCTION(shutdown), + FUNCTION(soc), + FUNCTION(sor0), + FUNCTION(sor1), + FUNCTION(spdif), + FUNCTION(spi1), + FUNCTION(spi2), + FUNCTION(spi3), + FUNCTION(spi4), + FUNCTION(sys), + FUNCTION(touch), + FUNCTION(uart), + FUNCTION(uarta), + FUNCTION(uartb), + FUNCTION(uartc), + FUNCTION(uartd), + FUNCTION(usb), + FUNCTION(vgp1), + FUNCTION(vgp2), + FUNCTION(vgp3), + FUNCTION(vgp4), + FUNCTION(vgp5), + FUNCTION(vgp6), + FUNCTION(vimclk), + FUNCTION(vimclk2), +}; + +#define DRV_PINGROUP_REG_A 0x8d4 /* bank 0 */ +#define PINGROUP_REG_A 0x3000 /* bank 1 */ + +#define DRV_PINGROUP_REG(r) ((r) - DRV_PINGROUP_REG_A) +#define PINGROUP_REG(r) ((r) - PINGROUP_REG_A) + +#define PINGROUP_BIT_Y(b) (b) +#define PINGROUP_BIT_N(b) (-1) + +#define PINGROUP(pg_name, f0, f1, f2, f3, r, hsm, drvtype, e_io_hv, \ + rdrv, drvdn_b, drvdn_w, drvup_b, drvup_w, slwr_b, \ + slwr_w, slwf_b, slwf_w) \ + { \ + .name = #pg_name, \ + .pins = pg_name##_pins, \ + .npins = ARRAY_SIZE(pg_name##_pins), \ + .funcs = { \ + TEGRA_MUX_##f0, \ + TEGRA_MUX_##f1, \ + TEGRA_MUX_##f2, \ + TEGRA_MUX_##f3, \ + }, \ + .mux_reg = PINGROUP_REG(r), \ + .mux_bank = 1, \ + .mux_bit = 0, \ + .pupd_reg = PINGROUP_REG(r), \ + .pupd_bank = 1, \ + .pupd_bit = 2, \ + .tri_reg = PINGROUP_REG(r), \ + .tri_bank = 1, \ + .tri_bit = 4, \ + .einput_bit = 6, \ + .odrain_bit = 11, \ + .lock_bit = 7, \ + .ioreset_bit = -1, \ + .rcv_sel_bit = PINGROUP_BIT_##e_io_hv(10), \ + .hsm_bit = PINGROUP_BIT_##hsm(9), \ + .schmitt_bit = 12, \ + .drvtype_bit = PINGROUP_BIT_##drvtype(13), \ + .drv_reg = DRV_PINGROUP_REG(rdrv), \ + .drv_bank = 0, \ + .lpmd_bit = -1, \ + .drvdn_bit = drvdn_b, \ + .drvdn_width = drvdn_w, \ + .drvup_bit = drvup_b, \ + .drvup_width = drvup_w, \ + .slwr_bit = slwr_b, \ + .slwr_width = slwr_w, \ + .slwf_bit = slwf_b, \ + .slwf_width = slwf_w, \ + } + +#define DRV_PINGROUP(pg_name, r, drvdn_b, drvdn_w, drvup_b, drvup_w, \ + slwr_b, slwr_w, slwf_b, slwf_w) \ + { \ + .name = "drive_" #pg_name, \ + .pins = drive_##pg_name##_pins, \ + .npins = ARRAY_SIZE(drive_##pg_name##_pins), \ + .mux_reg = -1, \ + .pupd_reg = -1, \ + .tri_reg = -1, \ + .einput_bit = -1, \ + .odrain_bit = -1, \ + .lock_bit = -1, \ + .ioreset_bit = -1, \ + .rcv_sel_bit = -1, \ + .drv_reg = DRV_PINGROUP_REG(r), \ + .drv_bank = 0, \ + .hsm_bit = -1, \ + .schmitt_bit = -1, \ + .lpmd_bit = -1, \ + .drvdn_bit = drvdn_b, \ + .drvdn_width = drvdn_w, \ + .drvup_bit = drvup_b, \ + .drvup_width = drvup_w, \ + .slwr_bit = slwr_b, \ + .slwr_width = slwr_w, \ + .slwf_bit = slwf_b, \ + .slwf_width = slwf_w, \ + .drvtype_bit = -1, \ + } + +static const struct tegra_pingroup tegra210_groups[] = { + /* pg_name, f0, f1, f2, f3, r, hsm, drvtype, e_io_hv, rdrv, drvdn_b, drvdn_w, drvup_b, drvup_w, slwr_b, slwr_w, slwf_b, slwf_w */ + PINGROUP(sdmmc1_clk_pm0, SDMMC1, RSVD1, RSVD2, RSVD3, 0x3000, Y, Y, N, -1, -1, -1, -1, -1, -1, -1, -1, -1), + PINGROUP(sdmmc1_cmd_pm1, SDMMC1, SPI3, RSVD2, RSVD3, 0x3004, Y, Y, N, -1, -1, -1, -1, -1, -1, -1, -1, -1), + PINGROUP(sdmmc1_dat3_pm2, SDMMC1, SPI3, RSVD2, RSVD3, 0x3008, Y, Y, N, -1, -1, -1, -1, -1, -1, -1, -1, -1), + PINGROUP(sdmmc1_dat2_pm3, SDMMC1, SPI3, RSVD2, RSVD3, 0x300c, Y, Y, N, -1, -1, -1, -1, -1, -1, -1, -1, -1), + PINGROUP(sdmmc1_dat1_pm4, SDMMC1, SPI3, RSVD2, RSVD3, 0x3010, Y, Y, N, -1, -1, -1, -1, -1, -1, -1, -1, -1), + PINGROUP(sdmmc1_dat0_pm5, SDMMC1, RSVD1, RSVD2, RSVD3, 0x3014, Y, Y, N, -1, -1, -1, -1, -1, -1, -1, -1, -1), + PINGROUP(sdmmc3_clk_pp0, SDMMC3, RSVD1, RSVD2, RSVD3, 0x301c, Y, Y, N, -1, -1, -1, -1, -1, -1, -1, -1, -1), + PINGROUP(sdmmc3_cmd_pp1, SDMMC3, RSVD1, RSVD2, RSVD3, 0x3020, Y, Y, N, -1, -1, -1, -1, -1, -1, -1, -1, -1), + PINGROUP(sdmmc3_dat0_pp5, SDMMC3, RSVD1, RSVD2, RSVD3, 0x3024, Y, Y, N, -1, -1, -1, -1, -1, -1, -1, -1, -1), + PINGROUP(sdmmc3_dat1_pp4, SDMMC3, RSVD1, RSVD2, RSVD3, 0x3028, Y, Y, N, -1, -1, -1, -1, -1, -1, -1, -1, -1), + PINGROUP(sdmmc3_dat2_pp3, SDMMC3, RSVD1, RSVD2, RSVD3, 0x302c, Y, Y, N, -1, -1, -1, -1, -1, -1, -1, -1, -1), + PINGROUP(sdmmc3_dat3_pp2, SDMMC3, RSVD1, RSVD2, RSVD3, 0x3030, Y, Y, N, -1, -1, -1, -1, -1, -1, -1, -1, -1), + PINGROUP(pex_l0_rst_n_pa0, PE0, RSVD1, RSVD2, RSVD3, 0x3038, N, N, Y, 0xa5c, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(pex_l0_clkreq_n_pa1, PE0, RSVD1, RSVD2, RSVD3, 0x303c, N, N, Y, 0xa58, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(pex_wake_n_pa2, PE, RSVD1, RSVD2, RSVD3, 0x3040, N, N, Y, 0xa68, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(pex_l1_rst_n_pa3, PE1, RSVD1, RSVD2, RSVD3, 0x3044, N, N, Y, 0xa64, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(pex_l1_clkreq_n_pa4, PE1, RSVD1, RSVD2, RSVD3, 0x3048, N, N, Y, 0xa60, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(sata_led_active_pa5, SATA, RSVD1, RSVD2, RSVD3, 0x304c, N, N, N, 0xa94, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(spi1_mosi_pc0, SPI1, RSVD1, RSVD2, RSVD3, 0x3050, Y, Y, N, 0xae0, -1, -1, -1, -1, 28, 2, 30, 2), + PINGROUP(spi1_miso_pc1, SPI1, RSVD1, RSVD2, RSVD3, 0x3054, Y, Y, N, 0xadc, -1, -1, -1, -1, 28, 2, 30, 2), + PINGROUP(spi1_sck_pc2, SPI1, RSVD1, RSVD2, RSVD3, 0x3058, Y, Y, N, 0xae4, -1, -1, -1, -1, 28, 2, 30, 2), + PINGROUP(spi1_cs0_pc3, SPI1, RSVD1, RSVD2, RSVD3, 0x305c, Y, Y, N, 0xad4, -1, -1, -1, -1, 28, 2, 30, 2), + PINGROUP(spi1_cs1_pc4, SPI1, RSVD1, RSVD2, RSVD3, 0x3060, Y, Y, N, 0xad8, -1, -1, -1, -1, 28, 2, 30, 2), + PINGROUP(spi2_mosi_pb4, SPI2, DTV, RSVD2, RSVD3, 0x3064, Y, Y, N, 0xaf4, -1, -1, -1, -1, 28, 2, 30, 2), + PINGROUP(spi2_miso_pb5, SPI2, DTV, RSVD2, RSVD3, 0x3068, Y, Y, N, 0xaf0, -1, -1, -1, -1, 28, 2, 30, 2), + PINGROUP(spi2_sck_pb6, SPI2, DTV, RSVD2, RSVD3, 0x306c, Y, Y, N, 0xaf8, -1, -1, -1, -1, 28, 2, 30, 2), + PINGROUP(spi2_cs0_pb7, SPI2, DTV, RSVD2, RSVD3, 0x3070, Y, Y, N, 0xae8, -1, -1, -1, -1, 28, 2, 30, 2), + PINGROUP(spi2_cs1_pdd0, SPI2, RSVD1, RSVD2, RSVD3, 0x3074, Y, Y, N, 0xaec, -1, -1, -1, -1, 28, 2, 30, 2), + PINGROUP(spi4_mosi_pc7, SPI4, RSVD1, RSVD2, RSVD3, 0x3078, Y, Y, N, 0xb04, -1, -1, -1, -1, 28, 2, 30, 2), + PINGROUP(spi4_miso_pd0, SPI4, RSVD1, RSVD2, RSVD3, 0x307c, Y, Y, N, 0xb00, -1, -1, -1, -1, 28, 2, 30, 2), + PINGROUP(spi4_sck_pc5, SPI4, RSVD1, RSVD2, RSVD3, 0x3080, Y, Y, N, 0xb08, -1, -1, -1, -1, 28, 2, 30, 2), + PINGROUP(spi4_cs0_pc6, SPI4, RSVD1, RSVD2, RSVD3, 0x3084, Y, Y, N, 0xafc, -1, -1, -1, -1, 28, 2, 30, 2), + PINGROUP(qspi_sck_pee0, QSPI, RSVD1, RSVD2, RSVD3, 0x3088, Y, Y, N, 0xa90, -1, -1, -1, -1, 28, 2, 30, 2), + PINGROUP(qspi_cs_n_pee1, QSPI, RSVD1, RSVD2, RSVD3, 0x308c, Y, Y, N, -1, -1, -1, -1, -1, -1, -1, -1, -1), + PINGROUP(qspi_io0_pee2, QSPI, RSVD1, RSVD2, RSVD3, 0x3090, Y, Y, N, -1, -1, -1, -1, -1, -1, -1, -1, -1), + PINGROUP(qspi_io1_pee3, QSPI, RSVD1, RSVD2, RSVD3, 0x3094, Y, Y, N, -1, -1, -1, -1, -1, -1, -1, -1, -1), + PINGROUP(qspi_io2_pee4, QSPI, RSVD1, RSVD2, RSVD3, 0x3098, Y, Y, N, -1, -1, -1, -1, -1, -1, -1, -1, -1), + PINGROUP(qspi_io3_pee5, QSPI, RSVD1, RSVD2, RSVD3, 0x309c, Y, Y, N, -1, -1, -1, -1, -1, -1, -1, -1, -1), + PINGROUP(dmic1_clk_pe0, DMIC1, I2S3, RSVD2, RSVD3, 0x30a4, N, N, N, 0x984, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(dmic1_dat_pe1, DMIC1, I2S3, RSVD2, RSVD3, 0x30a8, N, N, N, 0x988, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(dmic2_clk_pe2, DMIC2, I2S3, RSVD2, RSVD3, 0x30ac, N, N, N, 0x98c, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(dmic2_dat_pe3, DMIC2, I2S3, RSVD2, RSVD3, 0x30b0, N, N, N, 0x990, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(dmic3_clk_pe4, DMIC3, I2S5A, RSVD2, RSVD3, 0x30b4, N, N, N, 0x994, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(dmic3_dat_pe5, DMIC3, I2S5A, RSVD2, RSVD3, 0x30b8, N, N, N, 0x998, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(gen1_i2c_scl_pj1, I2C1, RSVD1, RSVD2, RSVD3, 0x30bc, N, N, Y, 0x9a8, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(gen1_i2c_sda_pj0, I2C1, RSVD1, RSVD2, RSVD3, 0x30c0, N, N, Y, 0x9ac, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(gen2_i2c_scl_pj2, I2C2, RSVD1, RSVD2, RSVD3, 0x30c4, N, N, Y, 0x9b0, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(gen2_i2c_sda_pj3, I2C2, RSVD1, RSVD2, RSVD3, 0x30c8, N, N, Y, 0x9b4, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(gen3_i2c_scl_pf0, I2C3, RSVD1, RSVD2, RSVD3, 0x30cc, N, N, Y, 0x9b8, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(gen3_i2c_sda_pf1, I2C3, RSVD1, RSVD2, RSVD3, 0x30d0, N, N, Y, 0x9bc, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(cam_i2c_scl_ps2, I2C3, I2CVI, RSVD2, RSVD3, 0x30d4, N, N, Y, 0x934, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(cam_i2c_sda_ps3, I2C3, I2CVI, RSVD2, RSVD3, 0x30d8, N, N, Y, 0x938, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(pwr_i2c_scl_py3, I2CPMU, RSVD1, RSVD2, RSVD3, 0x30dc, N, N, Y, 0xa6c, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(pwr_i2c_sda_py4, I2CPMU, RSVD1, RSVD2, RSVD3, 0x30e0, N, N, Y, 0xa70, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(uart1_tx_pu0, UARTA, RSVD1, RSVD2, RSVD3, 0x30e4, N, N, N, 0xb28, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(uart1_rx_pu1, UARTA, RSVD1, RSVD2, RSVD3, 0x30e8, N, N, N, 0xb24, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(uart1_rts_pu2, UARTA, RSVD1, RSVD2, RSVD3, 0x30ec, N, N, N, 0xb20, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(uart1_cts_pu3, UARTA, RSVD1, RSVD2, RSVD3, 0x30f0, N, N, N, 0xb1c, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(uart2_tx_pg0, UARTB, I2S4A, SPDIF, UART, 0x30f4, N, N, N, 0xb38, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(uart2_rx_pg1, UARTB, I2S4A, SPDIF, UART, 0x30f8, N, N, N, 0xb34, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(uart2_rts_pg2, UARTB, I2S4A, RSVD2, UART, 0x30fc, N, N, N, 0xb30, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(uart2_cts_pg3, UARTB, I2S4A, RSVD2, UART, 0x3100, N, N, N, 0xb2c, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(uart3_tx_pd1, UARTC, SPI4, RSVD2, RSVD3, 0x3104, N, N, N, 0xb48, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(uart3_rx_pd2, UARTC, SPI4, RSVD2, RSVD3, 0x3108, N, N, N, 0xb44, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(uart3_rts_pd3, UARTC, SPI4, RSVD2, RSVD3, 0x310c, N, N, N, 0xb40, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(uart3_cts_pd4, UARTC, SPI4, RSVD2, RSVD3, 0x3110, N, N, N, 0xb3c, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(uart4_tx_pi4, UARTD, UART, RSVD2, RSVD3, 0x3114, N, N, N, 0xb58, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(uart4_rx_pi5, UARTD, UART, RSVD2, RSVD3, 0x3118, N, N, N, 0xb54, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(uart4_rts_pi6, UARTD, UART, RSVD2, RSVD3, 0x311c, N, N, N, 0xb50, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(uart4_cts_pi7, UARTD, UART, RSVD2, RSVD3, 0x3120, N, N, N, 0xb4c, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(dap1_fs_pb0, I2S1, RSVD1, RSVD2, RSVD3, 0x3124, Y, Y, N, 0x95c, -1, -1, -1, -1, 28, 2, 30, 2), + PINGROUP(dap1_din_pb1, I2S1, RSVD1, RSVD2, RSVD3, 0x3128, Y, Y, N, 0x954, -1, -1, -1, -1, 28, 2, 30, 2), + PINGROUP(dap1_dout_pb2, I2S1, RSVD1, RSVD2, RSVD3, 0x312c, Y, Y, N, 0x958, -1, -1, -1, -1, 28, 2, 30, 2), + PINGROUP(dap1_sclk_pb3, I2S1, RSVD1, RSVD2, RSVD3, 0x3130, Y, Y, N, 0x960, -1, -1, -1, -1, 28, 2, 30, 2), + PINGROUP(dap2_fs_paa0, I2S2, RSVD1, RSVD2, RSVD3, 0x3134, Y, Y, N, 0x96c, -1, -1, -1, -1, 28, 2, 30, 2), + PINGROUP(dap2_din_paa2, I2S2, RSVD1, RSVD2, RSVD3, 0x3138, Y, Y, N, 0x964, -1, -1, -1, -1, 28, 2, 30, 2), + PINGROUP(dap2_dout_paa3, I2S2, RSVD1, RSVD2, RSVD3, 0x313c, Y, Y, N, 0x968, -1, -1, -1, -1, 28, 2, 30, 2), + PINGROUP(dap2_sclk_paa1, I2S2, RSVD1, RSVD2, RSVD3, 0x3140, Y, Y, N, 0x970, -1, -1, -1, -1, 28, 2, 30, 2), + PINGROUP(dap4_fs_pj4, I2S4B, RSVD1, RSVD2, RSVD3, 0x3144, N, N, N, 0x97c, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(dap4_din_pj5, I2S4B, RSVD1, RSVD2, RSVD3, 0x3148, N, N, N, 0x974, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(dap4_dout_pj6, I2S4B, RSVD1, RSVD2, RSVD3, 0x314c, N, N, N, 0x978, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(dap4_sclk_pj7, I2S4B, RSVD1, RSVD2, RSVD3, 0x3150, N, N, N, 0x980, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(cam1_mclk_ps0, EXTPERIPH3, RSVD1, RSVD2, RSVD3, 0x3154, N, N, N, 0x918, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(cam2_mclk_ps1, EXTPERIPH3, RSVD1, RSVD2, RSVD3, 0x3158, N, N, N, 0x924, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(jtag_rtck, JTAG, RSVD1, RSVD2, RSVD3, 0x315c, N, N, N, 0xa2c, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(clk_32k_in, CLK, RSVD1, RSVD2, RSVD3, 0x3160, N, N, N, 0x940, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(clk_32k_out_py5, SOC, BLINK, RSVD2, RSVD3, 0x3164, N, N, N, 0x944, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(batt_bcl, BCL, RSVD1, RSVD2, RSVD3, 0x3168, N, N, Y, 0x8f8, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(clk_req, SYS, RSVD1, RSVD2, RSVD3, 0x316c, N, N, N, 0x948, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(cpu_pwr_req, CPU, RSVD1, RSVD2, RSVD3, 0x3170, N, N, N, 0x950, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(pwr_int_n, PMI, RSVD1, RSVD2, RSVD3, 0x3174, N, N, N, 0xa74, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(shutdown, SHUTDOWN, RSVD1, RSVD2, RSVD3, 0x3178, N, N, N, 0xac8, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(core_pwr_req, CORE, RSVD1, RSVD2, RSVD3, 0x317c, N, N, N, 0x94c, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(aud_mclk_pbb0, AUD, RSVD1, RSVD2, RSVD3, 0x3180, N, N, N, 0x8f4, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(dvfs_pwm_pbb1, RSVD0, CLDVFS, SPI3, RSVD3, 0x3184, N, N, N, 0x9a4, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(dvfs_clk_pbb2, RSVD0, CLDVFS, SPI3, RSVD3, 0x3188, N, N, N, 0x9a0, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(gpio_x1_aud_pbb3, RSVD0, RSVD1, SPI3, RSVD3, 0x318c, N, N, N, 0xa14, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(gpio_x3_aud_pbb4, RSVD0, RSVD1, SPI3, RSVD3, 0x3190, N, N, N, 0xa18, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(pcc7, RSVD0, RSVD1, RSVD2, RSVD3, 0x3194, N, N, Y, -1, -1, -1, -1, -1, -1, -1, -1, -1), + PINGROUP(hdmi_cec_pcc0, CEC, RSVD1, RSVD2, RSVD3, 0x3198, N, N, Y, 0xa24, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(hdmi_int_dp_hpd_pcc1, DP, RSVD1, RSVD2, RSVD3, 0x319c, N, N, Y, 0xa28, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(spdif_out_pcc2, SPDIF, RSVD1, RSVD2, RSVD3, 0x31a0, N, N, N, 0xad0, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(spdif_in_pcc3, SPDIF, RSVD1, RSVD2, RSVD3, 0x31a4, N, N, N, 0xacc, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(usb_vbus_en0_pcc4, USB, RSVD1, RSVD2, RSVD3, 0x31a8, N, N, Y, 0xb5c, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(usb_vbus_en1_pcc5, USB, RSVD1, RSVD2, RSVD3, 0x31ac, N, N, Y, 0xb60, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(dp_hpd0_pcc6, DP, RSVD1, RSVD2, RSVD3, 0x31b0, N, N, N, 0x99c, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(wifi_en_ph0, RSVD0, RSVD1, RSVD2, RSVD3, 0x31b4, N, N, N, 0xb64, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(wifi_rst_ph1, RSVD0, RSVD1, RSVD2, RSVD3, 0x31b8, N, N, N, 0xb68, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(wifi_wake_ap_ph2, RSVD0, RSVD1, RSVD2, RSVD3, 0x31bc, N, N, N, 0xb6c, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(ap_wake_bt_ph3, RSVD0, UARTB, SPDIF, RSVD3, 0x31c0, N, N, N, 0x8ec, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(bt_rst_ph4, RSVD0, UARTB, SPDIF, RSVD3, 0x31c4, N, N, N, 0x8fc, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(bt_wake_ap_ph5, RSVD0, RSVD1, RSVD2, RSVD3, 0x31c8, N, N, N, 0x900, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(ap_wake_nfc_ph7, RSVD0, RSVD1, RSVD2, RSVD3, 0x31cc, N, N, N, 0x8f0, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(nfc_en_pi0, RSVD0, RSVD1, RSVD2, RSVD3, 0x31d0, N, N, N, 0xa50, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(nfc_int_pi1, RSVD0, RSVD1, RSVD2, RSVD3, 0x31d4, N, N, N, 0xa54, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(gps_en_pi2, RSVD0, RSVD1, RSVD2, RSVD3, 0x31d8, N, N, N, 0xa1c, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(gps_rst_pi3, RSVD0, RSVD1, RSVD2, RSVD3, 0x31dc, N, N, N, 0xa20, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(cam_rst_ps4, VGP1, RSVD1, RSVD2, RSVD3, 0x31e0, N, N, N, 0x93c, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(cam_af_en_ps5, VIMCLK, VGP2, RSVD2, RSVD3, 0x31e4, N, N, N, 0x92c, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(cam_flash_en_ps6, VIMCLK, VGP3, RSVD2, RSVD3, 0x31e8, N, N, N, 0x930, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(cam1_pwdn_ps7, VGP4, RSVD1, RSVD2, RSVD3, 0x31ec, N, N, N, 0x91c, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(cam2_pwdn_pt0, VGP5, RSVD1, RSVD2, RSVD3, 0x31f0, N, N, N, 0x928, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(cam1_strobe_pt1, VGP6, RSVD1, RSVD2, RSVD3, 0x31f4, N, N, N, 0x920, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(lcd_te_py2, DISPLAYA, RSVD1, RSVD2, RSVD3, 0x31f8, N, N, N, 0xa44, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(lcd_bl_pwm_pv0, DISPLAYA, PWM0, SOR0, RSVD3, 0x31fc, N, N, N, 0xa34, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(lcd_bl_en_pv1, RSVD0, RSVD1, RSVD2, RSVD3, 0x3200, N, N, N, 0xa30, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(lcd_rst_pv2, RSVD0, RSVD1, RSVD2, RSVD3, 0x3204, N, N, N, 0xa40, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(lcd_gpio1_pv3, DISPLAYB, RSVD1, RSVD2, RSVD3, 0x3208, N, N, N, 0xa38, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(lcd_gpio2_pv4, DISPLAYB, PWM1, RSVD2, SOR1, 0x320c, N, N, N, 0xa3c, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(ap_ready_pv5, RSVD0, RSVD1, RSVD2, RSVD3, 0x3210, N, N, N, 0x8e8, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(touch_rst_pv6, RSVD0, RSVD1, RSVD2, RSVD3, 0x3214, N, N, N, 0xb18, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(touch_clk_pv7, TOUCH, RSVD1, RSVD2, RSVD3, 0x3218, N, N, N, 0xb10, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(modem_wake_ap_px0, RSVD0, RSVD1, RSVD2, RSVD3, 0x321c, N, N, N, 0xa48, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(touch_int_px1, RSVD0, RSVD1, RSVD2, RSVD3, 0x3220, N, N, N, 0xb14, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(motion_int_px2, RSVD0, RSVD1, RSVD2, RSVD3, 0x3224, N, N, N, 0xa4c, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(als_prox_int_px3, RSVD0, RSVD1, RSVD2, RSVD3, 0x3228, N, N, N, 0x8e4, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(temp_alert_px4, RSVD0, RSVD1, RSVD2, RSVD3, 0x322c, N, N, N, 0xb0c, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(button_power_on_px5, RSVD0, RSVD1, RSVD2, RSVD3, 0x3230, N, N, N, 0x908, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(button_vol_up_px6, RSVD0, RSVD1, RSVD2, RSVD3, 0x3234, N, N, N, 0x914, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(button_vol_down_px7, RSVD0, RSVD1, RSVD2, RSVD3, 0x3238, N, N, N, 0x910, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(button_slide_sw_py0, RSVD0, RSVD1, RSVD2, RSVD3, 0x323c, N, N, N, 0x90c, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(button_home_py1, RSVD0, RSVD1, RSVD2, RSVD3, 0x3240, N, N, N, 0x904, 12, 5, 20, 5, -1, -1, -1, -1), + PINGROUP(pa6, SATA, RSVD1, RSVD2, RSVD3, 0x3244, N, N, N, -1, -1, -1, -1, -1, -1, -1, -1, -1), + PINGROUP(pe6, RSVD0, I2S5A, PWM2, RSVD3, 0x3248, N, N, N, -1, -1, -1, -1, -1, -1, -1, -1, -1), + PINGROUP(pe7, RSVD0, I2S5A, PWM3, RSVD3, 0x324c, N, N, N, -1, -1, -1, -1, -1, -1, -1, -1, -1), + PINGROUP(ph6, RSVD0, RSVD1, RSVD2, RSVD3, 0x3250, N, N, N, -1, -1, -1, -1, -1, -1, -1, -1, -1), + PINGROUP(pk0, IQC0, I2S5B, RSVD2, RSVD3, 0x3254, Y, Y, N, -1, -1, -1, -1, -1, -1, -1, -1, -1), + PINGROUP(pk1, IQC0, I2S5B, RSVD2, RSVD3, 0x3258, Y, Y, N, -1, -1, -1, -1, -1, -1, -1, -1, -1), + PINGROUP(pk2, IQC0, I2S5B, RSVD2, RSVD3, 0x325c, Y, Y, N, -1, -1, -1, -1, -1, -1, -1, -1, -1), + PINGROUP(pk3, IQC0, I2S5B, RSVD2, RSVD3, 0x3260, Y, Y, N, -1, -1, -1, -1, -1, -1, -1, -1, -1), + PINGROUP(pk4, IQC1, RSVD1, RSVD2, RSVD3, 0x3264, Y, Y, N, -1, -1, -1, -1, -1, -1, -1, -1, -1), + PINGROUP(pk5, IQC1, RSVD1, RSVD2, RSVD3, 0x3268, Y, Y, N, -1, -1, -1, -1, -1, -1, -1, -1, -1), + PINGROUP(pk6, IQC1, RSVD1, RSVD2, RSVD3, 0x326c, Y, Y, N, -1, -1, -1, -1, -1, -1, -1, -1, -1), + PINGROUP(pk7, IQC1, RSVD1, RSVD2, RSVD3, 0x3270, Y, Y, N, -1, -1, -1, -1, -1, -1, -1, -1, -1), + PINGROUP(pl0, RSVD0, RSVD1, RSVD2, RSVD3, 0x3274, Y, Y, N, -1, -1, -1, -1, -1, -1, -1, -1, -1), + PINGROUP(pl1, SOC, RSVD1, RSVD2, RSVD3, 0x3278, Y, Y, N, -1, -1, -1, -1, -1, -1, -1, -1, -1), + PINGROUP(pz0, VIMCLK2, RSVD1, RSVD2, RSVD3, 0x327c, N, N, N, -1, -1, -1, -1, -1, -1, -1, -1, -1), + PINGROUP(pz1, VIMCLK2, SDMMC1, RSVD2, RSVD3, 0x3280, N, N, N, -1, -1, -1, -1, -1, -1, -1, -1, -1), + PINGROUP(pz2, SDMMC3, CCLA, RSVD2, RSVD3, 0x3284, N, N, N, -1, -1, -1, -1, -1, -1, -1, -1, -1), + PINGROUP(pz3, SDMMC3, RSVD1, RSVD2, RSVD3, 0x3288, N, N, N, -1, -1, -1, -1, -1, -1, -1, -1, -1), + PINGROUP(pz4, SDMMC1, RSVD1, RSVD2, RSVD3, 0x328c, N, N, N, -1, -1, -1, -1, -1, -1, -1, -1, -1), + PINGROUP(pz5, SOC, RSVD1, RSVD2, RSVD3, 0x3290, N, N, N, -1, -1, -1, -1, -1, -1, -1, -1, -1), + + /* pg_name, r, drvdn_b, drvdn_w, drvup_b, drvup_w, slwr_b, slwr_w, slwf_b, slwf_w */ + DRV_PINGROUP(pa6, 0x9c0, 12, 5, 20, 5, -1, -1, -1, -1), + DRV_PINGROUP(pcc7, 0x9c4, 12, 5, 20, 5, -1, -1, -1, -1), + DRV_PINGROUP(pe6, 0x9c8, 12, 5, 20, 5, -1, -1, -1, -1), + DRV_PINGROUP(pe7, 0x9cc, 12, 5, 20, 5, -1, -1, -1, -1), + DRV_PINGROUP(ph6, 0x9d0, 12, 5, 20, 5, -1, -1, -1, -1), + DRV_PINGROUP(pk0, 0x9d4, -1, -1, -1, -1, 28, 2, 30, 2), + DRV_PINGROUP(pk1, 0x9d8, -1, -1, -1, -1, 28, 2, 30, 2), + DRV_PINGROUP(pk2, 0x9dc, -1, -1, -1, -1, 28, 2, 30, 2), + DRV_PINGROUP(pk3, 0x9e0, -1, -1, -1, -1, 28, 2, 30, 2), + DRV_PINGROUP(pk4, 0x9e4, -1, -1, -1, -1, 28, 2, 30, 2), + DRV_PINGROUP(pk5, 0x9e8, -1, -1, -1, -1, 28, 2, 30, 2), + DRV_PINGROUP(pk6, 0x9ec, -1, -1, -1, -1, 28, 2, 30, 2), + DRV_PINGROUP(pk7, 0x9f0, -1, -1, -1, -1, 28, 2, 30, 2), + DRV_PINGROUP(pl0, 0x9f4, -1, -1, -1, -1, 28, 2, 30, 2), + DRV_PINGROUP(pl1, 0x9f8, -1, -1, -1, -1, 28, 2, 30, 2), + DRV_PINGROUP(pz0, 0x9fc, 12, 7, 20, 7, -1, -1, -1, -1), + DRV_PINGROUP(pz1, 0xa00, 12, 7, 20, 7, -1, -1, -1, -1), + DRV_PINGROUP(pz2, 0xa04, 12, 7, 20, 7, -1, -1, -1, -1), + DRV_PINGROUP(pz3, 0xa08, 12, 7, 20, 7, -1, -1, -1, -1), + DRV_PINGROUP(pz4, 0xa0c, 12, 7, 20, 7, -1, -1, -1, -1), + DRV_PINGROUP(pz5, 0xa10, 12, 7, 20, 7, -1, -1, -1, -1), + DRV_PINGROUP(sdmmc1, 0xa98, 12, 7, 20, 7, 28, 2, 30, 2), + DRV_PINGROUP(sdmmc2, 0xa9c, 2, 6, 8, 6, 28, 2, 30, 2), + DRV_PINGROUP(sdmmc3, 0xab0, 12, 7, 20, 7, 28, 2, 30, 2), + DRV_PINGROUP(sdmmc4, 0xab4, 2, 6, 8, 6, 28, 2, 30, 2), +}; + +static const struct tegra_pinctrl_soc_data tegra210_pinctrl = { + .ngpios = NUM_GPIOS, + .pins = tegra210_pins, + .npins = ARRAY_SIZE(tegra210_pins), + .functions = tegra210_functions, + .nfunctions = ARRAY_SIZE(tegra210_functions), + .groups = tegra210_groups, + .ngroups = ARRAY_SIZE(tegra210_groups), + .hsm_in_mux = true, + .schmitt_in_mux = true, + .drvtype_in_mux = true, +}; + +static int tegra210_pinctrl_probe(struct platform_device *pdev) +{ + return tegra_pinctrl_probe(pdev, &tegra210_pinctrl); +} + +static const struct of_device_id tegra210_pinctrl_of_match[] = { + { .compatible = "nvidia,tegra210-pinmux", }, + { }, +}; +MODULE_DEVICE_TABLE(of, tegra210_pinctrl_of_match); + +static struct platform_driver tegra210_pinctrl_driver = { + .driver = { + .name = "tegra210-pinctrl", + .of_match_table = tegra210_pinctrl_of_match, + }, + .probe = tegra210_pinctrl_probe, + .remove = tegra_pinctrl_remove, +}; +module_platform_driver(tegra210_pinctrl_driver); + +MODULE_AUTHOR("NVIDIA"); +MODULE_DESCRIPTION("NVIDIA Tegra210 pinctrl driver"); +MODULE_LICENSE("GPL v2"); -- GitLab From 28b30c306a530ad327b6d1fa0116240d49ac7839 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Sat, 28 Feb 2015 20:46:24 +0000 Subject: [PATCH 03565/11651] pinctrl: sirf: fix typo in kernel warning on a bad interrupt Fix typo, "flaged" -> "flagged" Signed-off-by: Colin Ian King Signed-off-by: Linus Walleij --- drivers/pinctrl/sirf/pinctrl-sirf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/sirf/pinctrl-sirf.c b/drivers/pinctrl/sirf/pinctrl-sirf.c index 2a1f07249b2f..abc5c475ea85 100644 --- a/drivers/pinctrl/sirf/pinctrl-sirf.c +++ b/drivers/pinctrl/sirf/pinctrl-sirf.c @@ -568,7 +568,7 @@ static void sirfsoc_gpio_handle_irq(unsigned int irq, struct irq_desc *desc) status = readl(sgpio->chip.regs + SIRFSOC_GPIO_INT_STATUS(bank->id)); if (!status) { printk(KERN_WARNING - "%s: gpio id %d status %#x no interrupt is flaged\n", + "%s: gpio id %d status %#x no interrupt is flagged\n", __func__, bank->id, status); handle_bad_irq(irq, desc); return; -- GitLab From 939417bd8b909ae34a3b2106531594f5115eaea5 Mon Sep 17 00:00:00 2001 From: Baruch Siach Date: Mon, 2 Mar 2015 16:55:02 +0200 Subject: [PATCH 03566/11651] pinctrl: remove maxpin from documentation struct pinctrl_desc does not contain the maxpin member since commit 0d2006bbf0 (pinctrl: remove unnecessary max pin number). Fixes: 0d2006bbf0 ('pinctrl: remove unnecessary max pin number') Signed-off-by: Baruch Siach Signed-off-by: Linus Walleij --- Documentation/pinctrl.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/Documentation/pinctrl.txt b/Documentation/pinctrl.txt index b8f2147b96dd..348a8af8d06c 100644 --- a/Documentation/pinctrl.txt +++ b/Documentation/pinctrl.txt @@ -72,7 +72,6 @@ static struct pinctrl_desc foo_desc = { .name = "foo", .pins = foo_pins, .npins = ARRAY_SIZE(foo_pins), - .maxpin = 63, .owner = THIS_MODULE, }; -- GitLab From 11131ba435252cae6099c04417bcf83997ec3241 Mon Sep 17 00:00:00 2001 From: Baruch Siach Date: Mon, 2 Mar 2015 19:28:45 +0200 Subject: [PATCH 03567/11651] pinctrl: at91: simplify probe error handling There is no code ender the 'err' label. Just return the error code directly. Signed-off-by: Baruch Siach Reviewed-by: Alexandre Belloni Acked-by: Ludovic Desroches Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-at91.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c index f4cd0b9b2438..6cfe534ab27e 100644 --- a/drivers/pinctrl/pinctrl-at91.c +++ b/drivers/pinctrl/pinctrl-at91.c @@ -1240,8 +1240,7 @@ static int at91_pinctrl_probe(struct platform_device *pdev) if (!info->pctl) { dev_err(&pdev->dev, "could not register AT91 pinctrl driver\n"); - ret = -EINVAL; - goto err; + return -EINVAL; } /* We will handle a range of GPIO pins */ @@ -1252,9 +1251,6 @@ static int at91_pinctrl_probe(struct platform_device *pdev) dev_info(&pdev->dev, "initialized AT91 pinctrl driver\n"); return 0; - -err: - return ret; } static int at91_pinctrl_remove(struct platform_device *pdev) -- GitLab From 38d756af7202c7cb1fde0c132076b0a6acd0d9d7 Mon Sep 17 00:00:00 2001 From: Stanimir Varbanov Date: Wed, 4 Mar 2015 12:41:56 +0200 Subject: [PATCH 03568/11651] pinctrl: qcom: enable generic pinconf This makes the pinctrl driver to use the generic pinconf interface. Mainly it gives us a way to use debugfs to dump group configurations. Signed-off-by: Stanimir Varbanov Acked-by: Bjorn Andersson Reviewed-by: Stephen Boyd Signed-off-by: Linus Walleij --- drivers/pinctrl/qcom/pinctrl-msm.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c index a535f9c23678..d36e51172567 100644 --- a/drivers/pinctrl/qcom/pinctrl-msm.c +++ b/drivers/pinctrl/qcom/pinctrl-msm.c @@ -197,7 +197,6 @@ static int msm_config_reg(struct msm_pinctrl *pctrl, *mask = 1; break; default: - dev_err(pctrl->dev, "Invalid config param %04x\n", param); return -ENOTSUPP; } @@ -262,9 +261,7 @@ static int msm_config_group_get(struct pinctrl_dev *pctldev, arg = !!(val & BIT(g->in_bit)); break; default: - dev_err(pctrl->dev, "Unsupported config parameter: %x\n", - param); - return -EINVAL; + return -ENOTSUPP; } *config = pinconf_to_config_packed(param, arg); @@ -357,6 +354,7 @@ static int msm_config_group_set(struct pinctrl_dev *pctldev, } static const struct pinconf_ops msm_pinconf_ops = { + .is_generic = true, .pin_config_group_get = msm_config_group_get, .pin_config_group_set = msm_config_group_set, }; -- GitLab From 407f5e392f9c5b9c16178c5e6b2112234fdf9fad Mon Sep 17 00:00:00 2001 From: Stanimir Varbanov Date: Wed, 4 Mar 2015 12:41:57 +0200 Subject: [PATCH 03569/11651] pinctrl: qcom: handle input-enable pinconf property This enables support of 'input-enable' pinconf generic property in the pinctrl driver. Signed-off-by: Stanimir Varbanov Acked-by: Bjorn Andersson Reviewed-by: Stephen Boyd Signed-off-by: Linus Walleij --- drivers/pinctrl/qcom/pinctrl-msm.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c index d36e51172567..f3d800f796c2 100644 --- a/drivers/pinctrl/qcom/pinctrl-msm.c +++ b/drivers/pinctrl/qcom/pinctrl-msm.c @@ -193,6 +193,7 @@ static int msm_config_reg(struct msm_pinctrl *pctrl, *mask = 7; break; case PIN_CONFIG_OUTPUT: + case PIN_CONFIG_INPUT_ENABLE: *bit = g->oe_bit; *mask = 1; break; @@ -260,6 +261,12 @@ static int msm_config_group_get(struct pinctrl_dev *pctldev, val = readl(pctrl->regs + g->io_reg); arg = !!(val & BIT(g->in_bit)); break; + case PIN_CONFIG_INPUT_ENABLE: + /* Pin is output */ + if (arg) + return -EINVAL; + arg = 1; + break; default: return -ENOTSUPP; } @@ -330,6 +337,10 @@ static int msm_config_group_set(struct pinctrl_dev *pctldev, /* enable output */ arg = 1; break; + case PIN_CONFIG_INPUT_ENABLE: + /* disable output */ + arg = 0; + break; default: dev_err(pctrl->dev, "Unsupported config parameter: %x\n", param); -- GitLab From 95763859c0205417cf94966f87c3839e54a8005d Mon Sep 17 00:00:00 2001 From: Roberta Dobrescu Date: Thu, 26 Feb 2015 10:49:23 +0200 Subject: [PATCH 03570/11651] staging: iio: Documentation: iio_event_monitor: Include linux/iio/types.h By adding this line and installing the kernel headers with make headers_install, iio_event_monitor can be compiled without any hacks. Signed-off-by: Roberta Dobrescu Signed-off-by: Jonathan Cameron --- drivers/staging/iio/Documentation/iio_event_monitor.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/iio/Documentation/iio_event_monitor.c b/drivers/staging/iio/Documentation/iio_event_monitor.c index 72c96aa6e992..019a6e5cdcd8 100644 --- a/drivers/staging/iio/Documentation/iio_event_monitor.c +++ b/drivers/staging/iio/Documentation/iio_event_monitor.c @@ -28,6 +28,7 @@ #include #include "iio_utils.h" #include +#include static const char * const iio_chan_type_name_spec[] = { [IIO_VOLTAGE] = "voltage", -- GitLab From bdcb31d048074d82ed7c50ed45f737d7637f1224 Mon Sep 17 00:00:00 2001 From: Roberta Dobrescu Date: Thu, 26 Feb 2015 10:49:24 +0200 Subject: [PATCH 03571/11651] staging: iio: Documentation: Introduce iio_utils.c This patch removes inline functions from iio_utils.h in order to clean the code. iio_utils.c contains the implementation of the functions used by iio_event_monitor.c, lsiio.c or generic_buffer.c and iio_utils.h contains the declarations of these functions. Since iio_utils.h is modified, generic_buffer.c and iio_event_monitor.c must include stdlib.h. Signed-off-by: Roberta Dobrescu Signed-off-by: Jonathan Cameron --- .../iio/Documentation/generic_buffer.c | 1 + .../iio/Documentation/iio_event_monitor.c | 1 + drivers/staging/iio/Documentation/iio_utils.c | 651 +++++++++++++++++ drivers/staging/iio/Documentation/iio_utils.h | 664 +----------------- 4 files changed, 679 insertions(+), 638 deletions(-) create mode 100644 drivers/staging/iio/Documentation/iio_utils.c diff --git a/drivers/staging/iio/Documentation/generic_buffer.c b/drivers/staging/iio/Documentation/generic_buffer.c index de4647e2495e..01266c2556da 100644 --- a/drivers/staging/iio/Documentation/generic_buffer.c +++ b/drivers/staging/iio/Documentation/generic_buffer.c @@ -21,6 +21,7 @@ #define _GNU_SOURCE #include +#include #include #include #include diff --git a/drivers/staging/iio/Documentation/iio_event_monitor.c b/drivers/staging/iio/Documentation/iio_event_monitor.c index 019a6e5cdcd8..f19cff19900e 100644 --- a/drivers/staging/iio/Documentation/iio_event_monitor.c +++ b/drivers/staging/iio/Documentation/iio_event_monitor.c @@ -19,6 +19,7 @@ #define _GNU_SOURCE #include +#include #include #include #include diff --git a/drivers/staging/iio/Documentation/iio_utils.c b/drivers/staging/iio/Documentation/iio_utils.c new file mode 100644 index 000000000000..aea928210187 --- /dev/null +++ b/drivers/staging/iio/Documentation/iio_utils.c @@ -0,0 +1,651 @@ +/* IIO - useful set of util functionality + * + * Copyright (c) 2008 Jonathan Cameron + * + * 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 +#include +#include +#include +#include +#include +#include +#include "iio_utils.h" + +const char *iio_dir = "/sys/bus/iio/devices/"; + +/** + * iioutils_break_up_name() - extract generic name from full channel name + * @full_name: the full channel name + * @generic_name: the output generic channel name + **/ +int iioutils_break_up_name(const char *full_name, + char **generic_name) +{ + char *current; + char *w, *r; + char *working; + + current = strdup(full_name); + working = strtok(current, "_\0"); + w = working; + r = working; + + while (*r != '\0') { + if (!isdigit(*r)) { + *w = *r; + w++; + } + r++; + } + *w = '\0'; + *generic_name = strdup(working); + free(current); + + return 0; +} + +/** + * iioutils_get_type() - find and process _type attribute data + * @is_signed: output whether channel is signed + * @bytes: output how many bytes the channel storage occupies + * @mask: output a bit mask for the raw data + * @be: big endian + * @device_dir: the iio device directory + * @name: the channel name + * @generic_name: the channel type name + **/ +int iioutils_get_type(unsigned *is_signed, + unsigned *bytes, + unsigned *bits_used, + unsigned *shift, + uint64_t *mask, + unsigned *be, + const char *device_dir, + const char *name, + const char *generic_name) +{ + FILE *sysfsfp; + int ret; + DIR *dp; + char *scan_el_dir, *builtname, *builtname_generic, *filename = 0; + char signchar, endianchar; + unsigned padint; + const struct dirent *ent; + + ret = asprintf(&scan_el_dir, FORMAT_SCAN_ELEMENTS_DIR, device_dir); + if (ret < 0) { + ret = -ENOMEM; + goto error_ret; + } + ret = asprintf(&builtname, FORMAT_TYPE_FILE, name); + if (ret < 0) { + ret = -ENOMEM; + goto error_free_scan_el_dir; + } + ret = asprintf(&builtname_generic, FORMAT_TYPE_FILE, generic_name); + if (ret < 0) { + ret = -ENOMEM; + goto error_free_builtname; + } + + dp = opendir(scan_el_dir); + if (dp == NULL) { + ret = -errno; + goto error_free_builtname_generic; + } + while (ent = readdir(dp), ent != NULL) + /* + * Do we allow devices to override a generic name with + * a specific one? + */ + if ((strcmp(builtname, ent->d_name) == 0) || + (strcmp(builtname_generic, ent->d_name) == 0)) { + ret = asprintf(&filename, + "%s/%s", scan_el_dir, ent->d_name); + if (ret < 0) { + ret = -ENOMEM; + goto error_closedir; + } + sysfsfp = fopen(filename, "r"); + if (sysfsfp == NULL) { + printf("failed to open %s\n", filename); + ret = -errno; + goto error_free_filename; + } + + ret = fscanf(sysfsfp, + "%ce:%c%u/%u>>%u", + &endianchar, + &signchar, + bits_used, + &padint, shift); + if (ret < 0) { + printf("failed to pass scan type description\n"); + ret = -errno; + goto error_close_sysfsfp; + } + *be = (endianchar == 'b'); + *bytes = padint / 8; + if (*bits_used == 64) + *mask = ~0; + else + *mask = (1 << *bits_used) - 1; + if (signchar == 's') + *is_signed = 1; + else + *is_signed = 0; + fclose(sysfsfp); + free(filename); + + filename = 0; + sysfsfp = 0; + } +error_close_sysfsfp: + if (sysfsfp) + fclose(sysfsfp); +error_free_filename: + if (filename) + free(filename); +error_closedir: + closedir(dp); +error_free_builtname_generic: + free(builtname_generic); +error_free_builtname: + free(builtname); +error_free_scan_el_dir: + free(scan_el_dir); +error_ret: + return ret; +} + +int iioutils_get_param_float(float *output, + const char *param_name, + const char *device_dir, + const char *name, + const char *generic_name) +{ + FILE *sysfsfp; + int ret; + DIR *dp; + char *builtname, *builtname_generic; + char *filename = NULL; + const struct dirent *ent; + + ret = asprintf(&builtname, "%s_%s", name, param_name); + if (ret < 0) { + ret = -ENOMEM; + goto error_ret; + } + ret = asprintf(&builtname_generic, + "%s_%s", generic_name, param_name); + if (ret < 0) { + ret = -ENOMEM; + goto error_free_builtname; + } + dp = opendir(device_dir); + if (dp == NULL) { + ret = -errno; + goto error_free_builtname_generic; + } + while (ent = readdir(dp), ent != NULL) + if ((strcmp(builtname, ent->d_name) == 0) || + (strcmp(builtname_generic, ent->d_name) == 0)) { + ret = asprintf(&filename, + "%s/%s", device_dir, ent->d_name); + if (ret < 0) { + ret = -ENOMEM; + goto error_closedir; + } + sysfsfp = fopen(filename, "r"); + if (!sysfsfp) { + ret = -errno; + goto error_free_filename; + } + fscanf(sysfsfp, "%f", output); + break; + } +error_free_filename: + if (filename) + free(filename); +error_closedir: + closedir(dp); +error_free_builtname_generic: + free(builtname_generic); +error_free_builtname: + free(builtname); +error_ret: + return ret; +} + +/** + * bsort_channel_array_by_index() - reorder so that the array is in index order + * + **/ + +void bsort_channel_array_by_index(struct iio_channel_info **ci_array, + int cnt) +{ + + struct iio_channel_info temp; + int x, y; + + for (x = 0; x < cnt; x++) + for (y = 0; y < (cnt - 1); y++) + if ((*ci_array)[y].index > (*ci_array)[y+1].index) { + temp = (*ci_array)[y + 1]; + (*ci_array)[y + 1] = (*ci_array)[y]; + (*ci_array)[y] = temp; + } +} + +/** + * build_channel_array() - function to figure out what channels are present + * @device_dir: the IIO device directory in sysfs + * @ + **/ +int build_channel_array(const char *device_dir, + struct iio_channel_info **ci_array, + int *counter) +{ + DIR *dp; + FILE *sysfsfp; + int count, i; + struct iio_channel_info *current; + int ret; + const struct dirent *ent; + char *scan_el_dir; + char *filename; + + *counter = 0; + ret = asprintf(&scan_el_dir, FORMAT_SCAN_ELEMENTS_DIR, device_dir); + if (ret < 0) { + ret = -ENOMEM; + goto error_ret; + } + dp = opendir(scan_el_dir); + if (dp == NULL) { + ret = -errno; + goto error_free_name; + } + while (ent = readdir(dp), ent != NULL) + if (strcmp(ent->d_name + strlen(ent->d_name) - strlen("_en"), + "_en") == 0) { + ret = asprintf(&filename, + "%s/%s", scan_el_dir, ent->d_name); + if (ret < 0) { + ret = -ENOMEM; + goto error_close_dir; + } + sysfsfp = fopen(filename, "r"); + if (sysfsfp == NULL) { + ret = -errno; + free(filename); + goto error_close_dir; + } + fscanf(sysfsfp, "%i", &ret); + if (ret == 1) + (*counter)++; + fclose(sysfsfp); + free(filename); + } + *ci_array = malloc(sizeof(**ci_array) * (*counter)); + if (*ci_array == NULL) { + ret = -ENOMEM; + goto error_close_dir; + } + seekdir(dp, 0); + count = 0; + while (ent = readdir(dp), ent != NULL) { + if (strcmp(ent->d_name + strlen(ent->d_name) - strlen("_en"), + "_en") == 0) { + int current_enabled = 0; + + current = &(*ci_array)[count++]; + ret = asprintf(&filename, + "%s/%s", scan_el_dir, ent->d_name); + if (ret < 0) { + ret = -ENOMEM; + /* decrement count to avoid freeing name */ + count--; + goto error_cleanup_array; + } + sysfsfp = fopen(filename, "r"); + if (sysfsfp == NULL) { + free(filename); + ret = -errno; + goto error_cleanup_array; + } + fscanf(sysfsfp, "%i", ¤t_enabled); + fclose(sysfsfp); + + if (!current_enabled) { + free(filename); + count--; + continue; + } + + current->scale = 1.0; + current->offset = 0; + current->name = strndup(ent->d_name, + strlen(ent->d_name) - + strlen("_en")); + if (current->name == NULL) { + free(filename); + ret = -ENOMEM; + goto error_cleanup_array; + } + /* Get the generic and specific name elements */ + ret = iioutils_break_up_name(current->name, + ¤t->generic_name); + if (ret) { + free(filename); + goto error_cleanup_array; + } + ret = asprintf(&filename, + "%s/%s_index", + scan_el_dir, + current->name); + if (ret < 0) { + free(filename); + ret = -ENOMEM; + goto error_cleanup_array; + } + sysfsfp = fopen(filename, "r"); + fscanf(sysfsfp, "%u", ¤t->index); + fclose(sysfsfp); + free(filename); + /* Find the scale */ + ret = iioutils_get_param_float(¤t->scale, + "scale", + device_dir, + current->name, + current->generic_name); + if (ret < 0) + goto error_cleanup_array; + ret = iioutils_get_param_float(¤t->offset, + "offset", + device_dir, + current->name, + current->generic_name); + if (ret < 0) + goto error_cleanup_array; + ret = iioutils_get_type(¤t->is_signed, + ¤t->bytes, + ¤t->bits_used, + ¤t->shift, + ¤t->mask, + ¤t->be, + device_dir, + current->name, + current->generic_name); + } + } + + closedir(dp); + /* reorder so that the array is in index order */ + bsort_channel_array_by_index(ci_array, *counter); + + return 0; + +error_cleanup_array: + for (i = count - 1; i >= 0; i--) + free((*ci_array)[i].name); + free(*ci_array); +error_close_dir: + closedir(dp); +error_free_name: + free(scan_el_dir); +error_ret: + return ret; +} + +/** + * find_type_by_name() - function to match top level types by name + * @name: top level type instance name + * @type: the type of top level instance being sort + * + * Typical types this is used for are device and trigger. + **/ +int find_type_by_name(const char *name, const char *type) +{ + const struct dirent *ent; + int number, numstrlen; + + FILE *nameFile; + DIR *dp; + char thisname[IIO_MAX_NAME_LENGTH]; + char *filename; + + dp = opendir(iio_dir); + if (dp == NULL) { + printf("No industrialio devices available\n"); + return -ENODEV; + } + + while (ent = readdir(dp), ent != NULL) { + if (strcmp(ent->d_name, ".") != 0 && + strcmp(ent->d_name, "..") != 0 && + strlen(ent->d_name) > strlen(type) && + strncmp(ent->d_name, type, strlen(type)) == 0) { + numstrlen = sscanf(ent->d_name + strlen(type), + "%d", + &number); + /* verify the next character is not a colon */ + if (strncmp(ent->d_name + strlen(type) + numstrlen, + ":", + 1) != 0) { + filename = malloc(strlen(iio_dir) + + strlen(type) + + numstrlen + + 6); + if (filename == NULL) { + closedir(dp); + return -ENOMEM; + } + sprintf(filename, "%s%s%d/name", + iio_dir, + type, + number); + nameFile = fopen(filename, "r"); + if (!nameFile) { + free(filename); + continue; + } + free(filename); + fscanf(nameFile, "%s", thisname); + fclose(nameFile); + if (strcmp(name, thisname) == 0) { + closedir(dp); + return number; + } + } + } + } + closedir(dp); + return -ENODEV; +} + +int _write_sysfs_int(char *filename, char *basedir, int val, int verify) +{ + int ret = 0; + FILE *sysfsfp; + int test; + char *temp = malloc(strlen(basedir) + strlen(filename) + 2); + + if (temp == NULL) + return -ENOMEM; + sprintf(temp, "%s/%s", basedir, filename); + sysfsfp = fopen(temp, "w"); + if (sysfsfp == NULL) { + printf("failed to open %s\n", temp); + ret = -errno; + goto error_free; + } + fprintf(sysfsfp, "%d", val); + fclose(sysfsfp); + if (verify) { + sysfsfp = fopen(temp, "r"); + if (sysfsfp == NULL) { + printf("failed to open %s\n", temp); + ret = -errno; + goto error_free; + } + fscanf(sysfsfp, "%d", &test); + fclose(sysfsfp); + if (test != val) { + printf("Possible failure in int write %d to %s%s\n", + val, + basedir, + filename); + ret = -1; + } + } +error_free: + free(temp); + return ret; +} + +int write_sysfs_int(char *filename, char *basedir, int val) +{ + return _write_sysfs_int(filename, basedir, val, 0); +} + +int write_sysfs_int_and_verify(char *filename, char *basedir, int val) +{ + return _write_sysfs_int(filename, basedir, val, 1); +} + +int _write_sysfs_string(char *filename, char *basedir, char *val, int verify) +{ + int ret = 0; + FILE *sysfsfp; + char *temp = malloc(strlen(basedir) + strlen(filename) + 2); + + if (temp == NULL) { + printf("Memory allocation failed\n"); + return -ENOMEM; + } + sprintf(temp, "%s/%s", basedir, filename); + sysfsfp = fopen(temp, "w"); + if (sysfsfp == NULL) { + printf("Could not open %s\n", temp); + ret = -errno; + goto error_free; + } + fprintf(sysfsfp, "%s", val); + fclose(sysfsfp); + if (verify) { + sysfsfp = fopen(temp, "r"); + if (sysfsfp == NULL) { + printf("could not open file to verify\n"); + ret = -errno; + goto error_free; + } + fscanf(sysfsfp, "%s", temp); + fclose(sysfsfp); + if (strcmp(temp, val) != 0) { + printf("Possible failure in string write of %s " + "Should be %s " + "written to %s\%s\n", + temp, + val, + basedir, + filename); + ret = -1; + } + } +error_free: + free(temp); + + return ret; +} + +/** + * write_sysfs_string_and_verify() - string write, readback and verify + * @filename: name of file to write to + * @basedir: the sysfs directory in which the file is to be found + * @val: the string to write + **/ +int write_sysfs_string_and_verify(char *filename, char *basedir, char *val) +{ + return _write_sysfs_string(filename, basedir, val, 1); +} + +int write_sysfs_string(char *filename, char *basedir, char *val) +{ + return _write_sysfs_string(filename, basedir, val, 0); +} + +int read_sysfs_posint(char *filename, char *basedir) +{ + int ret; + FILE *sysfsfp; + char *temp = malloc(strlen(basedir) + strlen(filename) + 2); + + if (temp == NULL) { + printf("Memory allocation failed"); + return -ENOMEM; + } + sprintf(temp, "%s/%s", basedir, filename); + sysfsfp = fopen(temp, "r"); + if (sysfsfp == NULL) { + ret = -errno; + goto error_free; + } + fscanf(sysfsfp, "%d\n", &ret); + fclose(sysfsfp); +error_free: + free(temp); + return ret; +} + +int read_sysfs_float(char *filename, char *basedir, float *val) +{ + int ret = 0; + FILE *sysfsfp; + char *temp = malloc(strlen(basedir) + strlen(filename) + 2); + + if (temp == NULL) { + printf("Memory allocation failed"); + return -ENOMEM; + } + sprintf(temp, "%s/%s", basedir, filename); + sysfsfp = fopen(temp, "r"); + if (sysfsfp == NULL) { + ret = -errno; + goto error_free; + } + fscanf(sysfsfp, "%f\n", val); + fclose(sysfsfp); +error_free: + free(temp); + return ret; +} + +int read_sysfs_string(const char *filename, const char *basedir, char *str) +{ + int ret = 0; + FILE *sysfsfp; + char *temp = malloc(strlen(basedir) + strlen(filename) + 2); + + if (temp == NULL) { + printf("Memory allocation failed"); + return -ENOMEM; + } + sprintf(temp, "%s/%s", basedir, filename); + sysfsfp = fopen(temp, "r"); + if (sysfsfp == NULL) { + ret = -errno; + goto error_free; + } + fscanf(sysfsfp, "%s\n", str); + fclose(sysfsfp); +error_free: + free(temp); + return ret; +} diff --git a/drivers/staging/iio/Documentation/iio_utils.h b/drivers/staging/iio/Documentation/iio_utils.h index 568eff06f803..1bc837b2d769 100644 --- a/drivers/staging/iio/Documentation/iio_utils.h +++ b/drivers/staging/iio/Documentation/iio_utils.h @@ -1,3 +1,6 @@ +#ifndef _IIO_UTILS_H_ +#define _IIO_UTILS_H_ + /* IIO - useful set of util functionality * * Copyright (c) 2008 Jonathan Cameron @@ -7,13 +10,7 @@ * the Free Software Foundation. */ -#include -#include -#include -#include #include -#include -#include /* Made up value to limit allocation sizes */ #define IIO_MAX_NAME_LENGTH 30 @@ -21,38 +18,7 @@ #define FORMAT_SCAN_ELEMENTS_DIR "%s/scan_elements" #define FORMAT_TYPE_FILE "%s_type" -const char *iio_dir = "/sys/bus/iio/devices/"; - -/** - * iioutils_break_up_name() - extract generic name from full channel name - * @full_name: the full channel name - * @generic_name: the output generic channel name - **/ -inline int iioutils_break_up_name(const char *full_name, - char **generic_name) -{ - char *current; - char *w, *r; - char *working; - - current = strdup(full_name); - working = strtok(current, "_\0"); - w = working; - r = working; - - while (*r != '\0') { - if (!isdigit(*r)) { - *w = *r; - w++; - } - r++; - } - *w = '\0'; - *generic_name = strdup(working); - free(current); - - return 0; -} +extern const char *iio_dir; /** * struct iio_channel_info - information about a given channel @@ -81,603 +47,25 @@ struct iio_channel_info { unsigned location; }; -/** - * iioutils_get_type() - find and process _type attribute data - * @is_signed: output whether channel is signed - * @bytes: output how many bytes the channel storage occupies - * @mask: output a bit mask for the raw data - * @be: big endian - * @device_dir: the iio device directory - * @name: the channel name - * @generic_name: the channel type name - **/ -inline int iioutils_get_type(unsigned *is_signed, - unsigned *bytes, - unsigned *bits_used, - unsigned *shift, - uint64_t *mask, - unsigned *be, - const char *device_dir, - const char *name, - const char *generic_name) -{ - FILE *sysfsfp; - int ret; - DIR *dp; - char *scan_el_dir, *builtname, *builtname_generic, *filename = 0; - char signchar, endianchar; - unsigned padint; - const struct dirent *ent; - - ret = asprintf(&scan_el_dir, FORMAT_SCAN_ELEMENTS_DIR, device_dir); - if (ret < 0) { - ret = -ENOMEM; - goto error_ret; - } - ret = asprintf(&builtname, FORMAT_TYPE_FILE, name); - if (ret < 0) { - ret = -ENOMEM; - goto error_free_scan_el_dir; - } - ret = asprintf(&builtname_generic, FORMAT_TYPE_FILE, generic_name); - if (ret < 0) { - ret = -ENOMEM; - goto error_free_builtname; - } - - dp = opendir(scan_el_dir); - if (dp == NULL) { - ret = -errno; - goto error_free_builtname_generic; - } - while (ent = readdir(dp), ent != NULL) - /* - * Do we allow devices to override a generic name with - * a specific one? - */ - if ((strcmp(builtname, ent->d_name) == 0) || - (strcmp(builtname_generic, ent->d_name) == 0)) { - ret = asprintf(&filename, - "%s/%s", scan_el_dir, ent->d_name); - if (ret < 0) { - ret = -ENOMEM; - goto error_closedir; - } - sysfsfp = fopen(filename, "r"); - if (sysfsfp == NULL) { - printf("failed to open %s\n", filename); - ret = -errno; - goto error_free_filename; - } - - ret = fscanf(sysfsfp, - "%ce:%c%u/%u>>%u", - &endianchar, - &signchar, - bits_used, - &padint, shift); - if (ret < 0) { - printf("failed to pass scan type description\n"); - ret = -errno; - goto error_close_sysfsfp; - } - *be = (endianchar == 'b'); - *bytes = padint / 8; - if (*bits_used == 64) - *mask = ~0; - else - *mask = (1 << *bits_used) - 1; - if (signchar == 's') - *is_signed = 1; - else - *is_signed = 0; - fclose(sysfsfp); - free(filename); - - filename = 0; - sysfsfp = 0; - } -error_close_sysfsfp: - if (sysfsfp) - fclose(sysfsfp); -error_free_filename: - if (filename) - free(filename); -error_closedir: - closedir(dp); -error_free_builtname_generic: - free(builtname_generic); -error_free_builtname: - free(builtname); -error_free_scan_el_dir: - free(scan_el_dir); -error_ret: - return ret; -} - -inline int iioutils_get_param_float(float *output, - const char *param_name, - const char *device_dir, - const char *name, - const char *generic_name) -{ - FILE *sysfsfp; - int ret; - DIR *dp; - char *builtname, *builtname_generic; - char *filename = NULL; - const struct dirent *ent; - - ret = asprintf(&builtname, "%s_%s", name, param_name); - if (ret < 0) { - ret = -ENOMEM; - goto error_ret; - } - ret = asprintf(&builtname_generic, - "%s_%s", generic_name, param_name); - if (ret < 0) { - ret = -ENOMEM; - goto error_free_builtname; - } - dp = opendir(device_dir); - if (dp == NULL) { - ret = -errno; - goto error_free_builtname_generic; - } - while (ent = readdir(dp), ent != NULL) - if ((strcmp(builtname, ent->d_name) == 0) || - (strcmp(builtname_generic, ent->d_name) == 0)) { - ret = asprintf(&filename, - "%s/%s", device_dir, ent->d_name); - if (ret < 0) { - ret = -ENOMEM; - goto error_closedir; - } - sysfsfp = fopen(filename, "r"); - if (!sysfsfp) { - ret = -errno; - goto error_free_filename; - } - fscanf(sysfsfp, "%f", output); - break; - } -error_free_filename: - if (filename) - free(filename); -error_closedir: - closedir(dp); -error_free_builtname_generic: - free(builtname_generic); -error_free_builtname: - free(builtname); -error_ret: - return ret; -} - -/** - * bsort_channel_array_by_index() - reorder so that the array is in index order - * - **/ - -inline void bsort_channel_array_by_index(struct iio_channel_info **ci_array, - int cnt) -{ - - struct iio_channel_info temp; - int x, y; - - for (x = 0; x < cnt; x++) - for (y = 0; y < (cnt - 1); y++) - if ((*ci_array)[y].index > (*ci_array)[y+1].index) { - temp = (*ci_array)[y + 1]; - (*ci_array)[y + 1] = (*ci_array)[y]; - (*ci_array)[y] = temp; - } -} - -/** - * build_channel_array() - function to figure out what channels are present - * @device_dir: the IIO device directory in sysfs - * @ - **/ -inline int build_channel_array(const char *device_dir, - struct iio_channel_info **ci_array, - int *counter) -{ - DIR *dp; - FILE *sysfsfp; - int count, i; - struct iio_channel_info *current; - int ret; - const struct dirent *ent; - char *scan_el_dir; - char *filename; - - *counter = 0; - ret = asprintf(&scan_el_dir, FORMAT_SCAN_ELEMENTS_DIR, device_dir); - if (ret < 0) { - ret = -ENOMEM; - goto error_ret; - } - dp = opendir(scan_el_dir); - if (dp == NULL) { - ret = -errno; - goto error_free_name; - } - while (ent = readdir(dp), ent != NULL) - if (strcmp(ent->d_name + strlen(ent->d_name) - strlen("_en"), - "_en") == 0) { - ret = asprintf(&filename, - "%s/%s", scan_el_dir, ent->d_name); - if (ret < 0) { - ret = -ENOMEM; - goto error_close_dir; - } - sysfsfp = fopen(filename, "r"); - if (sysfsfp == NULL) { - ret = -errno; - free(filename); - goto error_close_dir; - } - fscanf(sysfsfp, "%i", &ret); - if (ret == 1) - (*counter)++; - fclose(sysfsfp); - free(filename); - } - *ci_array = malloc(sizeof(**ci_array) * (*counter)); - if (*ci_array == NULL) { - ret = -ENOMEM; - goto error_close_dir; - } - seekdir(dp, 0); - count = 0; - while (ent = readdir(dp), ent != NULL) { - if (strcmp(ent->d_name + strlen(ent->d_name) - strlen("_en"), - "_en") == 0) { - int current_enabled = 0; - - current = &(*ci_array)[count++]; - ret = asprintf(&filename, - "%s/%s", scan_el_dir, ent->d_name); - if (ret < 0) { - ret = -ENOMEM; - /* decrement count to avoid freeing name */ - count--; - goto error_cleanup_array; - } - sysfsfp = fopen(filename, "r"); - if (sysfsfp == NULL) { - free(filename); - ret = -errno; - goto error_cleanup_array; - } - fscanf(sysfsfp, "%i", ¤t_enabled); - fclose(sysfsfp); - - if (!current_enabled) { - free(filename); - count--; - continue; - } - - current->scale = 1.0; - current->offset = 0; - current->name = strndup(ent->d_name, - strlen(ent->d_name) - - strlen("_en")); - if (current->name == NULL) { - free(filename); - ret = -ENOMEM; - goto error_cleanup_array; - } - /* Get the generic and specific name elements */ - ret = iioutils_break_up_name(current->name, - ¤t->generic_name); - if (ret) { - free(filename); - goto error_cleanup_array; - } - ret = asprintf(&filename, - "%s/%s_index", - scan_el_dir, - current->name); - if (ret < 0) { - free(filename); - ret = -ENOMEM; - goto error_cleanup_array; - } - sysfsfp = fopen(filename, "r"); - fscanf(sysfsfp, "%u", ¤t->index); - fclose(sysfsfp); - free(filename); - /* Find the scale */ - ret = iioutils_get_param_float(¤t->scale, - "scale", - device_dir, - current->name, - current->generic_name); - if (ret < 0) - goto error_cleanup_array; - ret = iioutils_get_param_float(¤t->offset, - "offset", - device_dir, - current->name, - current->generic_name); - if (ret < 0) - goto error_cleanup_array; - ret = iioutils_get_type(¤t->is_signed, - ¤t->bytes, - ¤t->bits_used, - ¤t->shift, - ¤t->mask, - ¤t->be, - device_dir, - current->name, - current->generic_name); - } - } - - closedir(dp); - /* reorder so that the array is in index order */ - bsort_channel_array_by_index(ci_array, *counter); - - return 0; - -error_cleanup_array: - for (i = count - 1; i >= 0; i--) - free((*ci_array)[i].name); - free(*ci_array); -error_close_dir: - closedir(dp); -error_free_name: - free(scan_el_dir); -error_ret: - return ret; -} - -/** - * find_type_by_name() - function to match top level types by name - * @name: top level type instance name - * @type: the type of top level instance being sort - * - * Typical types this is used for are device and trigger. - **/ -inline int find_type_by_name(const char *name, const char *type) -{ - const struct dirent *ent; - int number, numstrlen; - - FILE *nameFile; - DIR *dp; - char thisname[IIO_MAX_NAME_LENGTH]; - char *filename; - - dp = opendir(iio_dir); - if (dp == NULL) { - printf("No industrialio devices available\n"); - return -ENODEV; - } - - while (ent = readdir(dp), ent != NULL) { - if (strcmp(ent->d_name, ".") != 0 && - strcmp(ent->d_name, "..") != 0 && - strlen(ent->d_name) > strlen(type) && - strncmp(ent->d_name, type, strlen(type)) == 0) { - numstrlen = sscanf(ent->d_name + strlen(type), - "%d", - &number); - /* verify the next character is not a colon */ - if (strncmp(ent->d_name + strlen(type) + numstrlen, - ":", - 1) != 0) { - filename = malloc(strlen(iio_dir) - + strlen(type) - + numstrlen - + 6); - if (filename == NULL) { - closedir(dp); - return -ENOMEM; - } - sprintf(filename, "%s%s%d/name", - iio_dir, - type, - number); - nameFile = fopen(filename, "r"); - if (!nameFile) { - free(filename); - continue; - } - free(filename); - fscanf(nameFile, "%s", thisname); - fclose(nameFile); - if (strcmp(name, thisname) == 0) { - closedir(dp); - return number; - } - } - } - } - closedir(dp); - return -ENODEV; -} - -inline int _write_sysfs_int(char *filename, char *basedir, int val, int verify) -{ - int ret = 0; - FILE *sysfsfp; - int test; - char *temp = malloc(strlen(basedir) + strlen(filename) + 2); - - if (temp == NULL) - return -ENOMEM; - sprintf(temp, "%s/%s", basedir, filename); - sysfsfp = fopen(temp, "w"); - if (sysfsfp == NULL) { - printf("failed to open %s\n", temp); - ret = -errno; - goto error_free; - } - fprintf(sysfsfp, "%d", val); - fclose(sysfsfp); - if (verify) { - sysfsfp = fopen(temp, "r"); - if (sysfsfp == NULL) { - printf("failed to open %s\n", temp); - ret = -errno; - goto error_free; - } - fscanf(sysfsfp, "%d", &test); - fclose(sysfsfp); - if (test != val) { - printf("Possible failure in int write %d to %s%s\n", - val, - basedir, - filename); - ret = -1; - } - } -error_free: - free(temp); - return ret; -} - -int write_sysfs_int(char *filename, char *basedir, int val) -{ - return _write_sysfs_int(filename, basedir, val, 0); -} - -int write_sysfs_int_and_verify(char *filename, char *basedir, int val) -{ - return _write_sysfs_int(filename, basedir, val, 1); -} - -int _write_sysfs_string(char *filename, char *basedir, char *val, int verify) -{ - int ret = 0; - FILE *sysfsfp; - char *temp = malloc(strlen(basedir) + strlen(filename) + 2); - - if (temp == NULL) { - printf("Memory allocation failed\n"); - return -ENOMEM; - } - sprintf(temp, "%s/%s", basedir, filename); - sysfsfp = fopen(temp, "w"); - if (sysfsfp == NULL) { - printf("Could not open %s\n", temp); - ret = -errno; - goto error_free; - } - fprintf(sysfsfp, "%s", val); - fclose(sysfsfp); - if (verify) { - sysfsfp = fopen(temp, "r"); - if (sysfsfp == NULL) { - printf("could not open file to verify\n"); - ret = -errno; - goto error_free; - } - fscanf(sysfsfp, "%s", temp); - fclose(sysfsfp); - if (strcmp(temp, val) != 0) { - printf("Possible failure in string write of %s " - "Should be %s " - "written to %s\%s\n", - temp, - val, - basedir, - filename); - ret = -1; - } - } -error_free: - free(temp); - - return ret; -} - -/** - * write_sysfs_string_and_verify() - string write, readback and verify - * @filename: name of file to write to - * @basedir: the sysfs directory in which the file is to be found - * @val: the string to write - **/ -int write_sysfs_string_and_verify(char *filename, char *basedir, char *val) -{ - return _write_sysfs_string(filename, basedir, val, 1); -} - -int write_sysfs_string(char *filename, char *basedir, char *val) -{ - return _write_sysfs_string(filename, basedir, val, 0); -} - -int read_sysfs_posint(char *filename, char *basedir) -{ - int ret; - FILE *sysfsfp; - char *temp = malloc(strlen(basedir) + strlen(filename) + 2); - - if (temp == NULL) { - printf("Memory allocation failed"); - return -ENOMEM; - } - sprintf(temp, "%s/%s", basedir, filename); - sysfsfp = fopen(temp, "r"); - if (sysfsfp == NULL) { - ret = -errno; - goto error_free; - } - fscanf(sysfsfp, "%d\n", &ret); - fclose(sysfsfp); -error_free: - free(temp); - return ret; -} - -int read_sysfs_float(char *filename, char *basedir, float *val) -{ - int ret = 0; - FILE *sysfsfp; - char *temp = malloc(strlen(basedir) + strlen(filename) + 2); - - if (temp == NULL) { - printf("Memory allocation failed"); - return -ENOMEM; - } - sprintf(temp, "%s/%s", basedir, filename); - sysfsfp = fopen(temp, "r"); - if (sysfsfp == NULL) { - ret = -errno; - goto error_free; - } - fscanf(sysfsfp, "%f\n", val); - fclose(sysfsfp); -error_free: - free(temp); - return ret; -} - -int read_sysfs_string(const char *filename, const char *basedir, char *str) -{ - int ret = 0; - FILE *sysfsfp; - char *temp = malloc(strlen(basedir) + strlen(filename) + 2); - - if (temp == NULL) { - printf("Memory allocation failed"); - return -ENOMEM; - } - sprintf(temp, "%s/%s", basedir, filename); - sysfsfp = fopen(temp, "r"); - if (sysfsfp == NULL) { - ret = -errno; - goto error_free; - } - fscanf(sysfsfp, "%s\n", str); - fclose(sysfsfp); -error_free: - free(temp); - return ret; -} +int iioutils_break_up_name(const char *full_name, char **generic_name); +int iioutils_get_type(unsigned *is_signed, unsigned *bytes, + unsigned *bits_used, unsigned *shift, + uint64_t *mask, unsigned *be, + const char *device_dir, const char *name, + const char *generic_name); +int iioutils_get_param_float(float *output, const char *param_name, + const char *device_dir, const char *name, + const char *generic_name); +void bsort_channel_array_by_index(struct iio_channel_info **ci_array, int cnt); +int build_channel_array(const char *device_dir, + struct iio_channel_info **ci_array, int *counter); +int find_type_by_name(const char *name, const char *type); +int write_sysfs_int(char *filename, char *basedir, int val); +int write_sysfs_int_and_verify(char *filename, char *basedir, int val); +int write_sysfs_string_and_verify(char *filename, char *basedir, char *val); +int write_sysfs_string(char *filename, char *basedir, char *val); +int read_sysfs_posint(char *filename, char *basedir); +int read_sysfs_float(char *filename, char *basedir, float *val); +int read_sysfs_string(const char *filename, const char *basedir, char *str); + +#endif /* _IIO_UTILS_H_ */ -- GitLab From 817020cfb3a2649064a1e14e083934234e2c208d Mon Sep 17 00:00:00 2001 From: Roberta Dobrescu Date: Thu, 26 Feb 2015 10:49:25 +0200 Subject: [PATCH 03572/11651] iio: Move iio userspace applications out of staging This patch moves iio userspace applications out of staging, to tools/iio/ and adds a Makefile in order to compile them easily. It also adds tools/iio/ to MAINTAINERS file. Signed-off-by: Roberta Dobrescu Signed-off-by: Jonathan Cameron --- MAINTAINERS | 1 + tools/iio/Makefile | 16 ++++++++++++++++ .../Documentation => tools/iio}/generic_buffer.c | 0 .../iio}/iio_event_monitor.c | 0 .../iio/Documentation => tools/iio}/iio_utils.c | 0 .../iio/Documentation => tools/iio}/iio_utils.h | 0 .../iio/Documentation => tools/iio}/lsiio.c | 0 7 files changed, 17 insertions(+) create mode 100644 tools/iio/Makefile rename {drivers/staging/iio/Documentation => tools/iio}/generic_buffer.c (100%) rename {drivers/staging/iio/Documentation => tools/iio}/iio_event_monitor.c (100%) rename {drivers/staging/iio/Documentation => tools/iio}/iio_utils.c (100%) rename {drivers/staging/iio/Documentation => tools/iio}/iio_utils.h (100%) rename {drivers/staging/iio/Documentation => tools/iio}/lsiio.c (100%) diff --git a/MAINTAINERS b/MAINTAINERS index 873f496c6364..6fb6bdc2eb3f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4871,6 +4871,7 @@ S: Maintained F: drivers/iio/ F: drivers/staging/iio/ F: include/linux/iio/ +F: tools/iio/ IKANOS/ADI EAGLE ADSL USB DRIVER M: Matthieu Castet diff --git a/tools/iio/Makefile b/tools/iio/Makefile new file mode 100644 index 000000000000..83813ad379f9 --- /dev/null +++ b/tools/iio/Makefile @@ -0,0 +1,16 @@ +CC = gcc +CFLAGS = -Wall -g + +all: iio_event_monitor lsiio generic_buffer + +iio_event_monitor: iio_event_monitor.o iio_utils.o + +lsiio: lsiio.o iio_utils.o + +generic_buffer: generic_buffer.o iio_utils.o + +%.o: %.c iio_utils.h + +.PHONY: clean +clean: + rm -f *.o iio_event_monitor lsiio generic_buffer diff --git a/drivers/staging/iio/Documentation/generic_buffer.c b/tools/iio/generic_buffer.c similarity index 100% rename from drivers/staging/iio/Documentation/generic_buffer.c rename to tools/iio/generic_buffer.c diff --git a/drivers/staging/iio/Documentation/iio_event_monitor.c b/tools/iio/iio_event_monitor.c similarity index 100% rename from drivers/staging/iio/Documentation/iio_event_monitor.c rename to tools/iio/iio_event_monitor.c diff --git a/drivers/staging/iio/Documentation/iio_utils.c b/tools/iio/iio_utils.c similarity index 100% rename from drivers/staging/iio/Documentation/iio_utils.c rename to tools/iio/iio_utils.c diff --git a/drivers/staging/iio/Documentation/iio_utils.h b/tools/iio/iio_utils.h similarity index 100% rename from drivers/staging/iio/Documentation/iio_utils.h rename to tools/iio/iio_utils.h diff --git a/drivers/staging/iio/Documentation/lsiio.c b/tools/iio/lsiio.c similarity index 100% rename from drivers/staging/iio/Documentation/lsiio.c rename to tools/iio/lsiio.c -- GitLab From 976d9ab112bdef7b25827f576b33068704df78ee Mon Sep 17 00:00:00 2001 From: Roberta Dobrescu Date: Thu, 26 Feb 2015 10:49:26 +0200 Subject: [PATCH 03573/11651] tools: iio: Define _GNU_SOURCE in Makefile Definition of _GNU_SOURCE is needed to get rid of some warnings, such as: warning: implicit declaration of function `asprintf'. generic_buffer.c and iio_event_monitor.c define _GNU_SOURCE, but it is also needed in lsiio.c and iio_utils.c. For this reason, this patch adds the definition in Makefile and removes it from where it already exists. Signed-off-by: Roberta Dobrescu Signed-off-by: Jonathan Cameron --- tools/iio/Makefile | 2 +- tools/iio/generic_buffer.c | 2 -- tools/iio/iio_event_monitor.c | 2 -- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/tools/iio/Makefile b/tools/iio/Makefile index 83813ad379f9..bf7ae6d6612a 100644 --- a/tools/iio/Makefile +++ b/tools/iio/Makefile @@ -1,5 +1,5 @@ CC = gcc -CFLAGS = -Wall -g +CFLAGS = -Wall -g -D_GNU_SOURCE all: iio_event_monitor lsiio generic_buffer diff --git a/tools/iio/generic_buffer.c b/tools/iio/generic_buffer.c index 01266c2556da..8f8f058eb807 100644 --- a/tools/iio/generic_buffer.c +++ b/tools/iio/generic_buffer.c @@ -18,8 +18,6 @@ * */ -#define _GNU_SOURCE - #include #include #include diff --git a/tools/iio/iio_event_monitor.c b/tools/iio/iio_event_monitor.c index f19cff19900e..427c271ac0d6 100644 --- a/tools/iio/iio_event_monitor.c +++ b/tools/iio/iio_event_monitor.c @@ -16,8 +16,6 @@ * */ -#define _GNU_SOURCE - #include #include #include -- GitLab From 3fca6a2f4623122f5f4d79a2c0d4642ff30b6654 Mon Sep 17 00:00:00 2001 From: Roberta Dobrescu Date: Thu, 26 Feb 2015 10:49:27 +0200 Subject: [PATCH 03574/11651] tools: iio: lsiio: Remove unused variables This patch removes unused variables from lsiio.c in order to get rid of the warnings regarding them. Signed-off-by: Roberta Dobrescu Signed-off-by: Jonathan Cameron --- tools/iio/lsiio.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tools/iio/lsiio.c b/tools/iio/lsiio.c index 98a0de098130..c585440f864e 100644 --- a/tools/iio/lsiio.c +++ b/tools/iio/lsiio.c @@ -95,12 +95,7 @@ static int dump_one_trigger(const char *dev_dir_name) static void dump_devices(void) { const struct dirent *ent; - int number, numstrlen; - - FILE *nameFile; DIR *dp; - char thisname[IIO_MAX_NAME_LENGTH]; - char *filename; dp = opendir(iio_dir); if (dp == NULL) { -- GitLab From 878ce05894284d3eb683e7d249d09c796c02d73b Mon Sep 17 00:00:00 2001 From: Grygorii Strashko Date: Fri, 6 Mar 2015 21:26:56 +0200 Subject: [PATCH 03575/11651] gpio: omap: irq_shutdown: remove unnecessary call of gpiochip_unlock_as_irq GPIOLib core implemnts irqchip->irq_request/release_resources callbacks internally and these callbacks already contain clalls of gpiochip_lock/unlock_as_irq(). Hence, remove unnecessary call of gpiochip_unlock_as_irq() from omap_gpio_irq_shutdown(). Signed-off-by: Grygorii Strashko Signed-off-by: Linus Walleij --- drivers/gpio/gpio-omap.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index f476ae2eb0b3..2b2fc4ba8c6d 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -826,7 +826,6 @@ static void omap_gpio_irq_shutdown(struct irq_data *d) unsigned offset = GPIO_INDEX(bank, gpio); spin_lock_irqsave(&bank->lock, flags); - gpiochip_unlock_as_irq(&bank->chip, offset); bank->irq_usage &= ~(BIT(offset)); omap_disable_gpio_module(bank, offset); omap_reset_gpio(bank, gpio); -- GitLab From 2ddb80c9c4b1810feb214ed38400ac68e167c369 Mon Sep 17 00:00:00 2001 From: Shannon Nelson Date: Fri, 27 Feb 2015 09:18:36 +0000 Subject: [PATCH 03576/11651] i40e: add MAC printing to debugfs dump VSI Print the LAN, SAN, and Port MACs for the VSI if debugfs command dump VSI is used on the PF's VSI. Example output: [260221.871244] i40e 0000:04:00.0: MAC address: 68:05:ca:26:15:e0 SAN MAC: 00:00:00:00:02:00 Port MAC: 68:05:ca:26:15:e3 Change-ID: I0b393113dfb5ee7ff4f9e5227e4177885f0cc15e Signed-off-by: Shannon Nelson Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_debugfs.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c index 2cc73fea393b..daa88263af66 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c +++ b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c @@ -390,6 +390,11 @@ static void i40e_dbg_dump_vsi_seid(struct i40e_pf *pf, int seid) " netdev_registered = %i, current_netdev_flags = 0x%04x, state = %li flags = 0x%08lx\n", vsi->netdev_registered, vsi->current_netdev_flags, vsi->state, vsi->flags); + if (vsi == pf->vsi[pf->lan_vsi]) + dev_info(&pf->pdev->dev, "MAC address: %pM SAN MAC: %pM Port MAC: %pM\n", + pf->hw.mac.addr, + pf->hw.mac.san_addr, + pf->hw.mac.port_addr); list_for_each_entry(f, &vsi->mac_filter_list, list) { dev_info(&pf->pdev->dev, " mac_filter_list: %pM vid=%d, is_netdev=%d is_vf=%d counter=%d\n", -- GitLab From ec7a06fd6d6822db287e59d67362b2207cf42ca9 Mon Sep 17 00:00:00 2001 From: Catherine Sullivan Date: Fri, 27 Feb 2015 09:18:37 +0000 Subject: [PATCH 03577/11651] i40e/i40evf: Bump i40e/i40evf version Bump PF version to 1.2.37 and VF version to 1.2.25 Change-ID: I0287a750408250dc055c03e1f744fd5f0caefd68 Signed-off-by: Catherine Sullivan Tested-by: Jim Young Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_main.c | 2 +- drivers/net/ethernet/intel/i40evf/i40evf_main.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 54a2d7bceb4f..c1eaab532c15 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -39,7 +39,7 @@ static const char i40e_driver_string[] = #define DRV_VERSION_MAJOR 1 #define DRV_VERSION_MINOR 2 -#define DRV_VERSION_BUILD 12 +#define DRV_VERSION_BUILD 37 #define DRV_VERSION __stringify(DRV_VERSION_MAJOR) "." \ __stringify(DRV_VERSION_MINOR) "." \ __stringify(DRV_VERSION_BUILD) DRV_KERN diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c b/drivers/net/ethernet/intel/i40evf/i40evf_main.c index 5ac777b99ede..812b1200f35c 100644 --- a/drivers/net/ethernet/intel/i40evf/i40evf_main.c +++ b/drivers/net/ethernet/intel/i40evf/i40evf_main.c @@ -36,7 +36,7 @@ char i40evf_driver_name[] = "i40evf"; static const char i40evf_driver_string[] = "Intel(R) XL710/X710 Virtual Function Network Driver"; -#define DRV_VERSION "1.2.6" +#define DRV_VERSION "1.2.25" const char i40evf_driver_version[] = DRV_VERSION; static const char i40evf_copyright[] = "Copyright (c) 2013 - 2014 Intel Corporation."; -- GitLab From b29e13bb9198d2a79ab3370eb1d3ed69a05de61f Mon Sep 17 00:00:00 2001 From: Mitch A Williams Date: Thu, 5 Mar 2015 04:14:40 +0000 Subject: [PATCH 03578/11651] i40e: add ethtool RSS support Add support for setting the RSS hash table and hash key through ethtool. This patch incorporates suggestions from Ben Hutchings . Reported-by: Ben Hutchings Signed-off-by: Mitch Williams Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e.h | 2 + .../net/ethernet/intel/i40e/i40e_ethtool.c | 108 ++++++++++++++++++ 2 files changed, 110 insertions(+) diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h index cc3f23685430..1c8bd7c152c2 100644 --- a/drivers/net/ethernet/intel/i40e/i40e.h +++ b/drivers/net/ethernet/intel/i40e/i40e.h @@ -177,6 +177,8 @@ struct i40e_lump_tracking { #define I40E_FDIR_BUFFER_HEAD_ROOM 32 #define I40E_FDIR_BUFFER_HEAD_ROOM_FOR_ATR (I40E_FDIR_BUFFER_HEAD_ROOM * 4) +#define I40E_HKEY_ARRAY_SIZE ((I40E_PFQF_HKEY_MAX_INDEX + 1) * 4) + enum i40e_fd_stat_idx { I40E_FD_STAT_ATR, I40E_FD_STAT_SB, diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c index 9ff3dc15db25..b7d0aaac5480 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c @@ -2375,6 +2375,110 @@ static int i40e_set_channels(struct net_device *dev, return -EINVAL; } +#define I40E_HLUT_ARRAY_SIZE ((I40E_PFQF_HLUT_MAX_INDEX + 1) * 4) +/** + * i40e_get_rxfh_key_size - get the RSS hash key size + * @netdev: network interface device structure + * + * Returns the table size. + **/ +static u32 i40e_get_rxfh_key_size(struct net_device *netdev) +{ + return I40E_HKEY_ARRAY_SIZE; +} + +/** + * i40e_get_rxfh_indir_size - get the rx flow hash indirection table size + * @netdev: network interface device structure + * + * Returns the table size. + **/ +static u32 i40e_get_rxfh_indir_size(struct net_device *netdev) +{ + return I40E_HLUT_ARRAY_SIZE; +} + +static int i40e_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key, + u8 *hfunc) +{ + struct i40e_netdev_priv *np = netdev_priv(netdev); + struct i40e_vsi *vsi = np->vsi; + struct i40e_pf *pf = vsi->back; + struct i40e_hw *hw = &pf->hw; + u32 reg_val; + int i, j; + + if (hfunc) + *hfunc = ETH_RSS_HASH_TOP; + + if (!indir) + return 0; + + for (i = 0, j = 0; i <= I40E_PFQF_HLUT_MAX_INDEX; i++) { + reg_val = rd32(hw, I40E_PFQF_HLUT(i)); + indir[j++] = reg_val & 0xff; + indir[j++] = (reg_val >> 8) & 0xff; + indir[j++] = (reg_val >> 16) & 0xff; + indir[j++] = (reg_val >> 24) & 0xff; + } + + if (key) { + for (i = 0, j = 0; i <= I40E_PFQF_HKEY_MAX_INDEX; i++) { + reg_val = rd32(hw, I40E_PFQF_HKEY(i)); + key[j++] = (u8)(reg_val & 0xff); + key[j++] = (u8)((reg_val >> 8) & 0xff); + key[j++] = (u8)((reg_val >> 16) & 0xff); + key[j++] = (u8)((reg_val >> 24) & 0xff); + } + } + return 0; +} + +/** + * i40e_set_rxfh - set the rx flow hash indirection table + * @netdev: network interface device structure + * @indir: indirection table + * @key: hash key + * + * Returns -EINVAL if the table specifies an inavlid queue id, otherwise + * returns 0 after programming the table. + **/ +static int i40e_set_rxfh(struct net_device *netdev, const u32 *indir, + const u8 *key, const u8 hfunc) +{ + struct i40e_netdev_priv *np = netdev_priv(netdev); + struct i40e_vsi *vsi = np->vsi; + struct i40e_pf *pf = vsi->back; + struct i40e_hw *hw = &pf->hw; + u32 reg_val; + int i, j; + + if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP) + return -EOPNOTSUPP; + + if (!indir) + return 0; + + for (i = 0, j = 0; i <= I40E_PFQF_HLUT_MAX_INDEX; i++) { + reg_val = indir[j++]; + reg_val |= indir[j++] << 8; + reg_val |= indir[j++] << 16; + reg_val |= indir[j++] << 24; + wr32(hw, I40E_PFQF_HLUT(i), reg_val); + } + + if (key) { + for (i = 0, j = 0; i <= I40E_PFQF_HKEY_MAX_INDEX; i++) { + reg_val = key[j++]; + reg_val |= key[j++] << 8; + reg_val |= key[j++] << 16; + reg_val |= key[j++] << 24; + wr32(hw, I40E_PFQF_HKEY(i), reg_val); + } + } + return 0; +} + /** * i40e_get_priv_flags - report device private flags * @dev: network interface device structure @@ -2426,6 +2530,10 @@ static const struct ethtool_ops i40e_ethtool_ops = { .get_ethtool_stats = i40e_get_ethtool_stats, .get_coalesce = i40e_get_coalesce, .set_coalesce = i40e_set_coalesce, + .get_rxfh_key_size = i40e_get_rxfh_key_size, + .get_rxfh_indir_size = i40e_get_rxfh_indir_size, + .get_rxfh = i40e_get_rxfh, + .set_rxfh = i40e_set_rxfh, .get_channels = i40e_get_channels, .set_channels = i40e_set_channels, .get_ts_info = i40e_get_ts_info, -- GitLab From 38b6484e5b7be96ec93ec2c29b752b7d9540e9d4 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 9 Mar 2015 09:46:15 +0100 Subject: [PATCH 03579/11651] spi: cadence: Remove Kconfig dependency MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove Kconfig dependency and enable driver for all ARCHs. Also update help description. Signed-off-by: Michal Simek Acked-by: Sören Brinkmann Signed-off-by: Mark Brown --- drivers/spi/Kconfig | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index ab8dfbef6f1b..0c008162d0af 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -159,10 +159,9 @@ config SPI_BUTTERFLY config SPI_CADENCE tristate "Cadence SPI controller" - depends on ARM help This selects the Cadence SPI controller master driver - used by Xilinx Zynq. + used by Xilinx Zynq and ZynqMP. config SPI_CLPS711X tristate "CLPS711X host SPI controller" -- GitLab From 967beb2e87771411e08467152e3d9f1c3ae73a67 Mon Sep 17 00:00:00 2001 From: Zubair Lutfullah Kakakhel Date: Mon, 9 Mar 2015 12:11:08 +0000 Subject: [PATCH 03580/11651] ASoC: jz4740: Add jz4780 support The jz4780 and jz4740 have very similar i2s blocks. The slight difference is in Rx/Tx fifos. And the bitclocks for input/output are different. This patch adds jz4780 support to the driver Signed-off-by: Zubair Lutfullah Kakakhel Acked-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- .../bindings/sound/ingenic,jz4740-i2s.txt | 2 +- sound/soc/jz4740/jz4740-i2s.c | 84 ++++++++++++++++--- 2 files changed, 75 insertions(+), 11 deletions(-) diff --git a/Documentation/devicetree/bindings/sound/ingenic,jz4740-i2s.txt b/Documentation/devicetree/bindings/sound/ingenic,jz4740-i2s.txt index b41433386e2f..b623d50004fb 100644 --- a/Documentation/devicetree/bindings/sound/ingenic,jz4740-i2s.txt +++ b/Documentation/devicetree/bindings/sound/ingenic,jz4740-i2s.txt @@ -1,7 +1,7 @@ Ingenic JZ4740 I2S controller Required properties: -- compatible : "ingenic,jz4740-i2s" +- compatible : "ingenic,jz4740-i2s" or "ingenic,jz4780-i2s" - reg : I2S registers location and length - clocks : AIC and I2S PLL clock specifiers. - clock-names: "aic" and "i2s" diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c index 07f77815a586..b05fb1c1a848 100644 --- a/sound/soc/jz4740/jz4740-i2s.c +++ b/sound/soc/jz4740/jz4740-i2s.c @@ -58,6 +58,12 @@ #define JZ_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET 12 #define JZ_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET 8 +#define JZ4780_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET 24 +#define JZ4780_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET 16 +#define JZ4780_AIC_CONF_FIFO_RX_THRESHOLD_MASK \ + (0xf << JZ4780_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET) +#define JZ4780_AIC_CONF_FIFO_TX_THRESHOLD_MASK \ + (0x1f << JZ4780_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET) #define JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE_MASK (0x7 << 19) #define JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_MASK (0x7 << 16) @@ -79,6 +85,7 @@ #define JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_OFFSET 16 #define JZ_AIC_I2S_FMT_DISABLE_BIT_CLK BIT(12) +#define JZ_AIC_I2S_FMT_DISABLE_BIT_ICLK BIT(13) #define JZ_AIC_I2S_FMT_ENABLE_SYS_CLK BIT(4) #define JZ_AIC_I2S_FMT_MSB BIT(0) @@ -87,6 +94,13 @@ #define JZ_AIC_CLK_DIV_MASK 0xf #define I2SDIV_DV_SHIFT 8 #define I2SDIV_DV_MASK (0xf << I2SDIV_DV_SHIFT) +#define I2SDIV_IDV_SHIFT 8 +#define I2SDIV_IDV_MASK (0xf << I2SDIV_IDV_SHIFT) + +enum jz47xx_i2s_version { + JZ_I2S_JZ4740, + JZ_I2S_JZ4780, +}; struct jz4740_i2s { struct resource *mem; @@ -98,6 +112,8 @@ struct jz4740_i2s { struct snd_dmaengine_dai_dma_data playback_dma_data; struct snd_dmaengine_dai_dma_data capture_dma_data; + + enum jz47xx_i2s_version version; }; static inline uint32_t jz4740_i2s_read(const struct jz4740_i2s *i2s, @@ -267,13 +283,22 @@ static int jz4740_i2s_hw_params(struct snd_pcm_substream *substream, ctrl |= JZ_AIC_CTRL_MONO_TO_STEREO; else ctrl &= ~JZ_AIC_CTRL_MONO_TO_STEREO; + + div_reg &= ~I2SDIV_DV_MASK; + div_reg |= (div - 1) << I2SDIV_DV_SHIFT; } else { ctrl &= ~JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_MASK; ctrl |= sample_size << JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_OFFSET; + + if (i2s->version >= JZ_I2S_JZ4780) { + div_reg &= ~I2SDIV_IDV_MASK; + div_reg |= (div - 1) << I2SDIV_IDV_SHIFT; + } else { + div_reg &= ~I2SDIV_DV_MASK; + div_reg |= (div - 1) << I2SDIV_DV_SHIFT; + } } - div_reg &= ~I2SDIV_DV_MASK; - div_reg |= (div - 1) << I2SDIV_DV_SHIFT; jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl); jz4740_i2s_write(i2s, JZ_REG_AIC_CLK_DIV, div_reg); @@ -369,11 +394,19 @@ static int jz4740_i2s_dai_probe(struct snd_soc_dai *dai) snd_soc_dai_init_dma_data(dai, &i2s->playback_dma_data, &i2s->capture_dma_data); - conf = (7 << JZ_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET) | - (8 << JZ_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET) | - JZ_AIC_CONF_OVERFLOW_PLAY_LAST | - JZ_AIC_CONF_I2S | - JZ_AIC_CONF_INTERNAL_CODEC; + if (i2s->version >= JZ_I2S_JZ4780) { + conf = (7 << JZ4780_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET) | + (8 << JZ4780_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET) | + JZ_AIC_CONF_OVERFLOW_PLAY_LAST | + JZ_AIC_CONF_I2S | + JZ_AIC_CONF_INTERNAL_CODEC; + } else { + conf = (7 << JZ_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET) | + (8 << JZ_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET) | + JZ_AIC_CONF_OVERFLOW_PLAY_LAST | + JZ_AIC_CONF_I2S | + JZ_AIC_CONF_INTERNAL_CODEC; + } jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, JZ_AIC_CONF_RESET); jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf); @@ -422,13 +455,34 @@ static struct snd_soc_dai_driver jz4740_i2s_dai = { .resume = jz4740_i2s_resume, }; +static struct snd_soc_dai_driver jz4780_i2s_dai = { + .probe = jz4740_i2s_dai_probe, + .remove = jz4740_i2s_dai_remove, + .playback = { + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = JZ4740_I2S_FMTS, + }, + .capture = { + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = JZ4740_I2S_FMTS, + }, + .ops = &jz4740_i2s_dai_ops, + .suspend = jz4740_i2s_suspend, + .resume = jz4740_i2s_resume, +}; + static const struct snd_soc_component_driver jz4740_i2s_component = { .name = "jz4740-i2s", }; #ifdef CONFIG_OF static const struct of_device_id jz4740_of_matches[] = { - { .compatible = "ingenic,jz4740-i2s" }, + { .compatible = "ingenic,jz4740-i2s", .data = (void *)JZ_I2S_JZ4740 }, + { .compatible = "ingenic,jz4780-i2s", .data = (void *)JZ_I2S_JZ4780 }, { /* sentinel */ } }; #endif @@ -438,11 +492,16 @@ static int jz4740_i2s_dev_probe(struct platform_device *pdev) struct jz4740_i2s *i2s; struct resource *mem; int ret; + const struct of_device_id *match; i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL); if (!i2s) return -ENOMEM; + match = of_match_device(jz4740_of_matches, &pdev->dev); + if (match) + i2s->version = (enum jz47xx_i2s_version)match->data; + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); i2s->base = devm_ioremap_resource(&pdev->dev, mem); if (IS_ERR(i2s->base)) @@ -460,8 +519,13 @@ static int jz4740_i2s_dev_probe(struct platform_device *pdev) platform_set_drvdata(pdev, i2s); - ret = devm_snd_soc_register_component(&pdev->dev, - &jz4740_i2s_component, &jz4740_i2s_dai, 1); + if (i2s->version == JZ_I2S_JZ4780) + ret = devm_snd_soc_register_component(&pdev->dev, + &jz4740_i2s_component, &jz4780_i2s_dai, 1); + else + ret = devm_snd_soc_register_component(&pdev->dev, + &jz4740_i2s_component, &jz4740_i2s_dai, 1); + if (ret) return ret; -- GitLab From e31abce778bc05b94d406e8cbebd9953d12e84b8 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 9 Mar 2015 16:48:45 +0200 Subject: [PATCH 03581/11651] spi: dw-mid: convert value of dma_width to enum dma_slave_buswidth DMAEngine has a specific type to be used for bus width. This patch converts the code to use the values of the specific type when configure DMA transfer. Signed-off-by: Andy Shevchenko Signed-off-by: Mark Brown --- drivers/spi/spi-dw-mid.c | 13 +++++++++++-- drivers/spi/spi-dw.c | 12 ++++++++---- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/drivers/spi/spi-dw-mid.c b/drivers/spi/spi-dw-mid.c index c8416ef01f9a..25c8fa7d073f 100644 --- a/drivers/spi/spi-dw-mid.c +++ b/drivers/spi/spi-dw-mid.c @@ -100,6 +100,15 @@ static void mid_spi_dma_exit(struct dw_spi *dws) dma_release_channel(dws->rxchan); } +static enum dma_slave_buswidth convert_dma_width(u32 dma_width) { + if (dma_width == 1) + return DMA_SLAVE_BUSWIDTH_1_BYTE; + else if (dma_width == 2) + return DMA_SLAVE_BUSWIDTH_2_BYTES; + + return DMA_SLAVE_BUSWIDTH_UNDEFINED; +} + /* * dws->dma_chan_busy is set before the dma transfer starts, callback for tx * channel will clear a corresponding bit. @@ -126,7 +135,7 @@ static struct dma_async_tx_descriptor *dw_spi_dma_prepare_tx(struct dw_spi *dws) txconf.dst_addr = dws->dma_addr; txconf.dst_maxburst = LNW_DMA_MSIZE_16; txconf.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; - txconf.dst_addr_width = dws->dma_width; + txconf.dst_addr_width = convert_dma_width(dws->dma_width); txconf.device_fc = false; dmaengine_slave_config(dws->txchan, &txconf); @@ -175,7 +184,7 @@ static struct dma_async_tx_descriptor *dw_spi_dma_prepare_rx(struct dw_spi *dws) rxconf.src_addr = dws->dma_addr; rxconf.src_maxburst = LNW_DMA_MSIZE_16; rxconf.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; - rxconf.src_addr_width = dws->dma_width; + rxconf.src_addr_width = convert_dma_width(dws->dma_width); rxconf.device_fc = false; dmaengine_slave_config(dws->rxchan, &rxconf); diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c index 950bc50361b3..f3e4092cd8dc 100644 --- a/drivers/spi/spi-dw.c +++ b/drivers/spi/spi-dw.c @@ -315,7 +315,6 @@ static int dw_spi_transfer_one(struct spi_master *master, { struct dw_spi *dws = spi_master_get_devdata(master); struct chip_data *chip = spi_get_ctldata(spi); - u8 bits = 0; u8 imask = 0; u8 cs_change = 0; u16 txlevel = 0; @@ -357,9 +356,14 @@ static int dw_spi_transfer_one(struct spi_master *master, } } if (transfer->bits_per_word) { - bits = transfer->bits_per_word; - dws->n_bytes = dws->dma_width = bits >> 3; - cr0 = (bits - 1) + if (transfer->bits_per_word == 8) { + dws->n_bytes = 1; + dws->dma_width = 1; + } else if (transfer->bits_per_word == 16) { + dws->n_bytes = 2; + dws->dma_width = 2; + } + cr0 = (transfer->bits_per_word - 1) | (chip->type << SPI_FRF_OFFSET) | (spi->mode << SPI_MODE_OFFSET) | (chip->tmode << SPI_TMOD_OFFSET); -- GitLab From 9f14538ecd1a210eff244a0a2281f6744fe4a59d Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 9 Mar 2015 16:48:46 +0200 Subject: [PATCH 03582/11651] spi: dw-mid: split dma_setup() from dma_transfer() The patch splits DMA preparatory code to dma_setup() callback. The change also converts transfer_one() to program DMA whenever the transfer is DMA mapped. The change is a follow up of the converion to use SPI core transfer_one_message(). Since the DMA mapped transfers can be interleaved with PIO ones the DMA related configuration should respect that. Signed-off-by: Andy Shevchenko Signed-off-by: Mark Brown --- drivers/spi/spi-dw-mid.c | 17 ++++++----------- drivers/spi/spi-dw.c | 23 +++++++++++++---------- drivers/spi/spi-dw.h | 4 ++-- 3 files changed, 21 insertions(+), 23 deletions(-) diff --git a/drivers/spi/spi-dw-mid.c b/drivers/spi/spi-dw-mid.c index 25c8fa7d073f..4b4d266aff9f 100644 --- a/drivers/spi/spi-dw-mid.c +++ b/drivers/spi/spi-dw-mid.c @@ -207,12 +207,10 @@ static struct dma_async_tx_descriptor *dw_spi_dma_prepare_rx(struct dw_spi *dws) return rxdesc; } -static void dw_spi_dma_setup(struct dw_spi *dws) +static int mid_spi_dma_setup(struct dw_spi *dws) { u16 dma_ctrl = 0; - spi_enable_chip(dws, 0); - dw_writew(dws, DW_SPI_DMARDLR, 0xf); dw_writew(dws, DW_SPI_DMATDLR, 0x10); @@ -222,21 +220,17 @@ static void dw_spi_dma_setup(struct dw_spi *dws) dma_ctrl |= SPI_DMA_RDMAE; dw_writew(dws, DW_SPI_DMACR, dma_ctrl); - spi_enable_chip(dws, 1); + return 0; } -static int mid_spi_dma_transfer(struct dw_spi *dws, int cs_change) +static int mid_spi_dma_transfer(struct dw_spi *dws) { struct dma_async_tx_descriptor *txdesc, *rxdesc; - /* 1. setup DMA related registers */ - if (cs_change) - dw_spi_dma_setup(dws); - - /* 2. Prepare the TX dma transfer */ + /* Prepare the TX dma transfer */ txdesc = dw_spi_dma_prepare_tx(dws); - /* 3. Prepare the RX dma transfer */ + /* Prepare the RX dma transfer */ rxdesc = dw_spi_dma_prepare_rx(dws); /* rx must be started before tx due to spi instinct */ @@ -258,6 +252,7 @@ static int mid_spi_dma_transfer(struct dw_spi *dws, int cs_change) static struct dw_spi_dma_ops mid_dma_ops = { .dma_init = mid_spi_dma_init, .dma_exit = mid_spi_dma_exit, + .dma_setup = mid_spi_dma_setup, .dma_transfer = mid_spi_dma_transfer, }; #endif diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c index f3e4092cd8dc..c7c2fcc2b58e 100644 --- a/drivers/spi/spi-dw.c +++ b/drivers/spi/spi-dw.c @@ -316,11 +316,11 @@ static int dw_spi_transfer_one(struct spi_master *master, struct dw_spi *dws = spi_master_get_devdata(master); struct chip_data *chip = spi_get_ctldata(spi); u8 imask = 0; - u8 cs_change = 0; u16 txlevel = 0; u16 clk_div = 0; u32 speed = 0; u32 cr0 = 0; + int ret; dws->n_bytes = chip->n_bytes; dws->dma_width = chip->dma_width; @@ -332,8 +332,6 @@ static int dw_spi_transfer_one(struct spi_master *master, dws->rx = transfer->rx_buf; dws->rx_end = dws->rx + transfer->len; dws->len = transfer->len; - if (chip != dws->prev_chip) - cs_change = 1; spi_enable_chip(dws, 0); @@ -397,7 +395,13 @@ static int dw_spi_transfer_one(struct spi_master *master, * Interrupt mode * we only need set the TXEI IRQ, as TX/RX always happen syncronizely */ - if (!dws->dma_mapped && !chip->poll_mode) { + if (dws->dma_mapped) { + ret = dws->dma_ops->dma_setup(dws); + if (ret < 0) { + spi_enable_chip(dws, 1); + return ret; + } + } else if (!chip->poll_mode) { txlevel = min_t(u16, dws->fifo_len / 2, dws->len / dws->n_bytes); dw_writew(dws, DW_SPI_TXFLTR, txlevel); @@ -411,11 +415,11 @@ static int dw_spi_transfer_one(struct spi_master *master, spi_enable_chip(dws, 1); - if (cs_change) - dws->prev_chip = chip; - - if (dws->dma_mapped) - dws->dma_ops->dma_transfer(dws, cs_change); + if (dws->dma_mapped) { + ret = dws->dma_ops->dma_transfer(dws); + if (ret < 0) + return ret; + } if (chip->poll_mode) return poll_transfer(dws); @@ -546,7 +550,6 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws) dws->master = master; dws->type = SSI_MOTO_SPI; - dws->prev_chip = NULL; dws->dma_inited = 0; dws->dma_addr = (dma_addr_t)(dws->paddr + 0x60); snprintf(dws->name, sizeof(dws->name), "dw_spi%d", dws->bus_num); diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h index 855bfdd7b433..7351692494ec 100644 --- a/drivers/spi/spi-dw.h +++ b/drivers/spi/spi-dw.h @@ -91,7 +91,8 @@ struct dw_spi; struct dw_spi_dma_ops { int (*dma_init)(struct dw_spi *dws); void (*dma_exit)(struct dw_spi *dws); - int (*dma_transfer)(struct dw_spi *dws, int cs_change); + int (*dma_setup)(struct dw_spi *dws); + int (*dma_transfer)(struct dw_spi *dws); }; struct dw_spi { @@ -109,7 +110,6 @@ struct dw_spi { u16 num_cs; /* supported slave numbers */ /* Current message transfer state info */ - struct chip_data *prev_chip; size_t len; void *tx; void *tx_end; -- GitLab From f051fc8f117d95baaa3654d40e779c56c2c6d180 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 9 Mar 2015 16:48:47 +0200 Subject: [PATCH 03583/11651] spi: dw-mid: take care of FIFO overrun/underrun when do DMA In according to documentation SPI in DMA mode may encounter underrun/overrun failures in rare cases. When such failure occurs, an error recovery protocol is expected to be implemented in the device driver so that the failed transaction can be restarted. This patch enables FIFO overrun / underrun interrupts in DMA case and adds a handler for that. Signed-off-by: Andy Shevchenko Signed-off-by: Mark Brown --- drivers/spi/spi-dw-mid.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drivers/spi/spi-dw-mid.c b/drivers/spi/spi-dw-mid.c index 4b4d266aff9f..3729cdd84e94 100644 --- a/drivers/spi/spi-dw-mid.c +++ b/drivers/spi/spi-dw-mid.c @@ -100,6 +100,22 @@ static void mid_spi_dma_exit(struct dw_spi *dws) dma_release_channel(dws->rxchan); } +static irqreturn_t dma_transfer(struct dw_spi *dws) +{ + u16 irq_status = dw_readw(dws, DW_SPI_ISR); + + if (!irq_status) + return IRQ_NONE; + + dw_readw(dws, DW_SPI_ICR); + spi_reset_chip(dws); + + dev_err(&dws->master->dev, "%s: FIFO overrun/underrun\n", __func__); + dws->master->cur_msg->status = -EIO; + spi_finalize_current_transfer(dws->master); + return IRQ_HANDLED; +} + static enum dma_slave_buswidth convert_dma_width(u32 dma_width) { if (dma_width == 1) return DMA_SLAVE_BUSWIDTH_1_BYTE; @@ -220,6 +236,11 @@ static int mid_spi_dma_setup(struct dw_spi *dws) dma_ctrl |= SPI_DMA_RDMAE; dw_writew(dws, DW_SPI_DMACR, dma_ctrl); + /* Set the interrupt mask */ + spi_umask_intr(dws, SPI_INT_TXOI | SPI_INT_RXUI | SPI_INT_RXOI); + + dws->transfer_handler = dma_transfer; + return 0; } -- GitLab From 4d5ac1edfdd79aea31983333cb53dd5db29559f9 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 9 Mar 2015 16:48:48 +0200 Subject: [PATCH 03584/11651] spi: dw-mid: clear ongoing DMA transfers on timeout This patch shuts up any ongoing DMA transfer in case of error. Signed-off-by: Andy Shevchenko Signed-off-by: Mark Brown --- drivers/spi/spi-dw-mid.c | 13 +++++++++++++ drivers/spi/spi-dw.c | 3 +++ drivers/spi/spi-dw.h | 1 + 3 files changed, 17 insertions(+) diff --git a/drivers/spi/spi-dw-mid.c b/drivers/spi/spi-dw-mid.c index 3729cdd84e94..e614190daef6 100644 --- a/drivers/spi/spi-dw-mid.c +++ b/drivers/spi/spi-dw-mid.c @@ -270,11 +270,24 @@ static int mid_spi_dma_transfer(struct dw_spi *dws) return 0; } +static void mid_spi_dma_stop(struct dw_spi *dws) +{ + if (test_bit(TX_BUSY, &dws->dma_chan_busy)) { + dmaengine_terminate_all(dws->txchan); + clear_bit(TX_BUSY, &dws->dma_chan_busy); + } + if (test_bit(RX_BUSY, &dws->dma_chan_busy)) { + dmaengine_terminate_all(dws->rxchan); + clear_bit(RX_BUSY, &dws->dma_chan_busy); + } +} + static struct dw_spi_dma_ops mid_dma_ops = { .dma_init = mid_spi_dma_init, .dma_exit = mid_spi_dma_exit, .dma_setup = mid_spi_dma_setup, .dma_transfer = mid_spi_dma_transfer, + .dma_stop = mid_spi_dma_stop, }; #endif diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c index c7c2fcc2b58e..d53cffe7ff22 100644 --- a/drivers/spi/spi-dw.c +++ b/drivers/spi/spi-dw.c @@ -432,6 +432,9 @@ static void dw_spi_handle_err(struct spi_master *master, { struct dw_spi *dws = spi_master_get_devdata(master); + if (dws->dma_mapped) + dws->dma_ops->dma_stop(dws); + spi_reset_chip(dws); } diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h index 7351692494ec..7f130bd8f37a 100644 --- a/drivers/spi/spi-dw.h +++ b/drivers/spi/spi-dw.h @@ -93,6 +93,7 @@ struct dw_spi_dma_ops { void (*dma_exit)(struct dw_spi *dws); int (*dma_setup)(struct dw_spi *dws); int (*dma_transfer)(struct dw_spi *dws); + void (*dma_stop)(struct dw_spi *dws); }; struct dw_spi { -- GitLab From f89a6d8f43ebe9508bb5492c846ad997ad50eafe Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 9 Mar 2015 16:48:49 +0200 Subject: [PATCH 03585/11651] spi: dw-mid: move to use core SPI DMA mappings SPI core has a comprehensive function set to map and unmap a message when it's needed. This patch converts driver to use that advantage. Signed-off-by: Andy Shevchenko Signed-off-by: Mark Brown --- drivers/spi/spi-dw-mid.c | 52 +++++++++++++++++++++++----------------- drivers/spi/spi-dw.c | 40 ++++++------------------------- drivers/spi/spi-dw.h | 17 +++++-------- 3 files changed, 43 insertions(+), 66 deletions(-) diff --git a/drivers/spi/spi-dw-mid.c b/drivers/spi/spi-dw-mid.c index e614190daef6..599dad40a3ec 100644 --- a/drivers/spi/spi-dw-mid.c +++ b/drivers/spi/spi-dw-mid.c @@ -69,6 +69,7 @@ static int mid_spi_dma_init(struct dw_spi *dws) rxs->hs_mode = LNW_DMA_HW_HS; rxs->cfg_mode = LNW_DMA_PER_TO_MEM; dws->rxchan->private = rxs; + dws->master->dma_rx = dws->rxchan; /* 2. Init tx channel */ dws->txchan = dma_request_channel(mask, mid_spi_dma_chan_filter, dws); @@ -78,6 +79,7 @@ static int mid_spi_dma_init(struct dw_spi *dws) txs->hs_mode = LNW_DMA_HW_HS; txs->cfg_mode = LNW_DMA_MEM_TO_PER; dws->txchan->private = txs; + dws->master->dma_tx = dws->txchan; dws->dma_inited = 1; return 0; @@ -116,6 +118,17 @@ static irqreturn_t dma_transfer(struct dw_spi *dws) return IRQ_HANDLED; } +static bool mid_spi_can_dma(struct spi_master *master, struct spi_device *spi, + struct spi_transfer *xfer) +{ + struct dw_spi *dws = spi_master_get_devdata(master); + + if (!dws->dma_inited) + return false; + + return xfer->len > dws->fifo_len; +} + static enum dma_slave_buswidth convert_dma_width(u32 dma_width) { if (dma_width == 1) return DMA_SLAVE_BUSWIDTH_1_BYTE; @@ -139,12 +152,13 @@ static void dw_spi_dma_tx_done(void *arg) spi_finalize_current_transfer(dws->master); } -static struct dma_async_tx_descriptor *dw_spi_dma_prepare_tx(struct dw_spi *dws) +static struct dma_async_tx_descriptor *dw_spi_dma_prepare_tx(struct dw_spi *dws, + struct spi_transfer *xfer) { struct dma_slave_config txconf; struct dma_async_tx_descriptor *txdesc; - if (!dws->tx_dma) + if (!xfer->tx_buf) return NULL; txconf.direction = DMA_MEM_TO_DEV; @@ -156,13 +170,9 @@ static struct dma_async_tx_descriptor *dw_spi_dma_prepare_tx(struct dw_spi *dws) dmaengine_slave_config(dws->txchan, &txconf); - memset(&dws->tx_sgl, 0, sizeof(dws->tx_sgl)); - dws->tx_sgl.dma_address = dws->tx_dma; - dws->tx_sgl.length = dws->len; - txdesc = dmaengine_prep_slave_sg(dws->txchan, - &dws->tx_sgl, - 1, + xfer->tx_sg.sgl, + xfer->tx_sg.nents, DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); if (!txdesc) @@ -188,12 +198,13 @@ static void dw_spi_dma_rx_done(void *arg) spi_finalize_current_transfer(dws->master); } -static struct dma_async_tx_descriptor *dw_spi_dma_prepare_rx(struct dw_spi *dws) +static struct dma_async_tx_descriptor *dw_spi_dma_prepare_rx(struct dw_spi *dws, + struct spi_transfer *xfer) { struct dma_slave_config rxconf; struct dma_async_tx_descriptor *rxdesc; - if (!dws->rx_dma) + if (!xfer->rx_buf) return NULL; rxconf.direction = DMA_DEV_TO_MEM; @@ -205,13 +216,9 @@ static struct dma_async_tx_descriptor *dw_spi_dma_prepare_rx(struct dw_spi *dws) dmaengine_slave_config(dws->rxchan, &rxconf); - memset(&dws->rx_sgl, 0, sizeof(dws->rx_sgl)); - dws->rx_sgl.dma_address = dws->rx_dma; - dws->rx_sgl.length = dws->len; - rxdesc = dmaengine_prep_slave_sg(dws->rxchan, - &dws->rx_sgl, - 1, + xfer->rx_sg.sgl, + xfer->rx_sg.nents, DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); if (!rxdesc) @@ -223,16 +230,16 @@ static struct dma_async_tx_descriptor *dw_spi_dma_prepare_rx(struct dw_spi *dws) return rxdesc; } -static int mid_spi_dma_setup(struct dw_spi *dws) +static int mid_spi_dma_setup(struct dw_spi *dws, struct spi_transfer *xfer) { u16 dma_ctrl = 0; dw_writew(dws, DW_SPI_DMARDLR, 0xf); dw_writew(dws, DW_SPI_DMATDLR, 0x10); - if (dws->tx_dma) + if (xfer->tx_buf) dma_ctrl |= SPI_DMA_TDMAE; - if (dws->rx_dma) + if (xfer->rx_buf) dma_ctrl |= SPI_DMA_RDMAE; dw_writew(dws, DW_SPI_DMACR, dma_ctrl); @@ -244,15 +251,15 @@ static int mid_spi_dma_setup(struct dw_spi *dws) return 0; } -static int mid_spi_dma_transfer(struct dw_spi *dws) +static int mid_spi_dma_transfer(struct dw_spi *dws, struct spi_transfer *xfer) { struct dma_async_tx_descriptor *txdesc, *rxdesc; /* Prepare the TX dma transfer */ - txdesc = dw_spi_dma_prepare_tx(dws); + txdesc = dw_spi_dma_prepare_tx(dws, xfer); /* Prepare the RX dma transfer */ - rxdesc = dw_spi_dma_prepare_rx(dws); + rxdesc = dw_spi_dma_prepare_rx(dws, xfer); /* rx must be started before tx due to spi instinct */ if (rxdesc) { @@ -286,6 +293,7 @@ static struct dw_spi_dma_ops mid_dma_ops = { .dma_init = mid_spi_dma_init, .dma_exit = mid_spi_dma_exit, .dma_setup = mid_spi_dma_setup, + .can_dma = mid_spi_can_dma, .dma_transfer = mid_spi_dma_transfer, .dma_stop = mid_spi_dma_stop, }; diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c index d53cffe7ff22..2437bfcbf2f8 100644 --- a/drivers/spi/spi-dw.c +++ b/drivers/spi/spi-dw.c @@ -217,32 +217,6 @@ static void dw_reader(struct dw_spi *dws) } } -/* - * Note: first step is the protocol driver prepares - * a dma-capable memory, and this func just need translate - * the virt addr to physical - */ -static int map_dma_buffers(struct spi_master *master, - struct spi_device *spi, struct spi_transfer *transfer) -{ - struct dw_spi *dws = spi_master_get_devdata(master); - struct chip_data *chip = spi_get_ctldata(spi); - - if (!master->cur_msg->is_dma_mapped - || !dws->dma_inited - || !chip->enable_dma - || !dws->dma_ops) - return 0; - - if (transfer->tx_dma) - dws->tx_dma = transfer->tx_dma; - - if (transfer->rx_dma) - dws->rx_dma = transfer->rx_dma; - - return 1; -} - static void int_error_stop(struct dw_spi *dws, const char *msg) { spi_reset_chip(dws); @@ -322,11 +296,10 @@ static int dw_spi_transfer_one(struct spi_master *master, u32 cr0 = 0; int ret; + dws->dma_mapped = 0; dws->n_bytes = chip->n_bytes; dws->dma_width = chip->dma_width; - dws->rx_dma = transfer->rx_dma; - dws->tx_dma = transfer->tx_dma; dws->tx = (void *)transfer->tx_buf; dws->tx_end = dws->tx + transfer->len; dws->rx = transfer->rx_buf; @@ -386,7 +359,8 @@ static int dw_spi_transfer_one(struct spi_master *master, dw_writew(dws, DW_SPI_CTRL0, cr0); /* Check if current transfer is a DMA transaction */ - dws->dma_mapped = map_dma_buffers(master, spi, transfer); + if (master->can_dma && master->can_dma(master, spi, transfer)) + dws->dma_mapped = master->cur_msg_mapped; /* For poll mode just disable all interrupts */ spi_mask_intr(dws, 0xff); @@ -396,7 +370,7 @@ static int dw_spi_transfer_one(struct spi_master *master, * we only need set the TXEI IRQ, as TX/RX always happen syncronizely */ if (dws->dma_mapped) { - ret = dws->dma_ops->dma_setup(dws); + ret = dws->dma_ops->dma_setup(dws, transfer); if (ret < 0) { spi_enable_chip(dws, 1); return ret; @@ -416,7 +390,7 @@ static int dw_spi_transfer_one(struct spi_master *master, spi_enable_chip(dws, 1); if (dws->dma_mapped) { - ret = dws->dma_ops->dma_transfer(dws); + ret = dws->dma_ops->dma_transfer(dws, transfer); if (ret < 0) return ret; } @@ -470,8 +444,6 @@ static int dw_spi_setup(struct spi_device *spi) chip->rx_threshold = 0; chip->tx_threshold = 0; - - chip->enable_dma = chip_info->enable_dma; } if (spi->bits_per_word == 8) { @@ -584,6 +556,8 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws) if (ret) { dev_warn(dev, "DMA init failed\n"); dws->dma_inited = 0; + } else { + master->can_dma = dws->dma_ops->can_dma; } } diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h index 7f130bd8f37a..f298df59381b 100644 --- a/drivers/spi/spi-dw.h +++ b/drivers/spi/spi-dw.h @@ -91,8 +91,10 @@ struct dw_spi; struct dw_spi_dma_ops { int (*dma_init)(struct dw_spi *dws); void (*dma_exit)(struct dw_spi *dws); - int (*dma_setup)(struct dw_spi *dws); - int (*dma_transfer)(struct dw_spi *dws); + int (*dma_setup)(struct dw_spi *dws, struct spi_transfer *xfer); + bool (*can_dma)(struct spi_master *master, struct spi_device *spi, + struct spi_transfer *xfer); + int (*dma_transfer)(struct dw_spi *dws, struct spi_transfer *xfer); void (*dma_stop)(struct dw_spi *dws); }; @@ -117,20 +119,14 @@ struct dw_spi { void *rx; void *rx_end; int dma_mapped; - dma_addr_t rx_dma; - dma_addr_t tx_dma; - size_t rx_map_len; - size_t tx_map_len; u8 n_bytes; /* current is a 1/2 bytes op */ u32 dma_width; irqreturn_t (*transfer_handler)(struct dw_spi *dws); - /* Dma info */ + /* DMA info */ int dma_inited; struct dma_chan *txchan; - struct scatterlist tx_sgl; struct dma_chan *rxchan; - struct scatterlist rx_sgl; unsigned long dma_chan_busy; struct device *dma_dev; dma_addr_t dma_addr; /* phy address of the Data register */ @@ -206,14 +202,13 @@ static inline void spi_reset_chip(struct dw_spi *dws) /* * Each SPI slave device to work with dw_api controller should - * has such a structure claiming its working mode (PIO/DMA etc), + * has such a structure claiming its working mode (poll or PIO/DMA), * which can be save in the "controller_data" member of the * struct spi_device. */ struct dw_spi_chip { u8 poll_mode; /* 1 for controller polling mode */ u8 type; /* SPI/SSP/MicroWire */ - u8 enable_dma; void (*cs_control)(u32 command); }; -- GitLab From d744f82683e8cc8b49ca8f329a289c6692a9fb06 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 9 Mar 2015 16:48:50 +0200 Subject: [PATCH 03586/11651] spi: dw-mid: convert to use dw_dmac instead of intel_mid_dma intel_mid_dma seems to be unmaintained for a long time. Moreover, the IP block of DMA itself is the same in both dw_dmac and intel_mid_dma. This patch moves spi-dw-midpci to use dw_dmac driver. Signed-off-by: Andy Shevchenko Signed-off-by: Mark Brown --- drivers/spi/Kconfig | 2 +- drivers/spi/spi-dw-mid.c | 45 +++++++++++++++++----------------------- drivers/spi/spi-dw.h | 4 ++-- 3 files changed, 22 insertions(+), 29 deletions(-) diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index ab8dfbef6f1b..913107964573 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -632,7 +632,7 @@ config SPI_DW_PCI config SPI_DW_MID_DMA bool "DMA support for DW SPI controller on Intel MID platform" - depends on SPI_DW_PCI && INTEL_MID_DMAC + depends on SPI_DW_PCI && DW_DMAC_PCI config SPI_DW_MMIO tristate "Memory-mapped io interface driver for DW SPI core" diff --git a/drivers/spi/spi-dw-mid.c b/drivers/spi/spi-dw-mid.c index 599dad40a3ec..d4109f6dd3c0 100644 --- a/drivers/spi/spi-dw-mid.c +++ b/drivers/spi/spi-dw-mid.c @@ -23,29 +23,31 @@ #include "spi-dw.h" #ifdef CONFIG_SPI_DW_MID_DMA -#include #include +#include #define RX_BUSY 0 #define TX_BUSY 1 -struct mid_dma { - struct intel_mid_dma_slave dmas_tx; - struct intel_mid_dma_slave dmas_rx; -}; +static struct dw_dma_slave mid_dma_tx = { .dst_id = 1 }; +static struct dw_dma_slave mid_dma_rx = { .src_id = 0 }; static bool mid_spi_dma_chan_filter(struct dma_chan *chan, void *param) { - struct dw_spi *dws = param; + struct dw_dma_slave *s = param; + + if (s->dma_dev != chan->device->dev) + return false; - return dws->dma_dev == chan->device->dev; + chan->private = s; + return true; } static int mid_spi_dma_init(struct dw_spi *dws) { - struct mid_dma *dw_dma = dws->dma_priv; struct pci_dev *dma_dev; - struct intel_mid_dma_slave *rxs, *txs; + struct dw_dma_slave *tx = dws->dma_tx; + struct dw_dma_slave *rx = dws->dma_rx; dma_cap_mask_t mask; /* @@ -56,29 +58,21 @@ static int mid_spi_dma_init(struct dw_spi *dws) if (!dma_dev) return -ENODEV; - dws->dma_dev = &dma_dev->dev; - dma_cap_zero(mask); dma_cap_set(DMA_SLAVE, mask); /* 1. Init rx channel */ - dws->rxchan = dma_request_channel(mask, mid_spi_dma_chan_filter, dws); + rx->dma_dev = &dma_dev->dev; + dws->rxchan = dma_request_channel(mask, mid_spi_dma_chan_filter, rx); if (!dws->rxchan) goto err_exit; - rxs = &dw_dma->dmas_rx; - rxs->hs_mode = LNW_DMA_HW_HS; - rxs->cfg_mode = LNW_DMA_PER_TO_MEM; - dws->rxchan->private = rxs; dws->master->dma_rx = dws->rxchan; /* 2. Init tx channel */ - dws->txchan = dma_request_channel(mask, mid_spi_dma_chan_filter, dws); + tx->dma_dev = &dma_dev->dev; + dws->txchan = dma_request_channel(mask, mid_spi_dma_chan_filter, tx); if (!dws->txchan) goto free_rxchan; - txs = &dw_dma->dmas_tx; - txs->hs_mode = LNW_DMA_HW_HS; - txs->cfg_mode = LNW_DMA_MEM_TO_PER; - dws->txchan->private = txs; dws->master->dma_tx = dws->txchan; dws->dma_inited = 1; @@ -163,7 +157,7 @@ static struct dma_async_tx_descriptor *dw_spi_dma_prepare_tx(struct dw_spi *dws, txconf.direction = DMA_MEM_TO_DEV; txconf.dst_addr = dws->dma_addr; - txconf.dst_maxburst = LNW_DMA_MSIZE_16; + txconf.dst_maxburst = 16; txconf.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; txconf.dst_addr_width = convert_dma_width(dws->dma_width); txconf.device_fc = false; @@ -209,7 +203,7 @@ static struct dma_async_tx_descriptor *dw_spi_dma_prepare_rx(struct dw_spi *dws, rxconf.direction = DMA_DEV_TO_MEM; rxconf.src_addr = dws->dma_addr; - rxconf.src_maxburst = LNW_DMA_MSIZE_16; + rxconf.src_maxburst = 16; rxconf.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; rxconf.src_addr_width = convert_dma_width(dws->dma_width); rxconf.device_fc = false; @@ -328,9 +322,8 @@ int dw_spi_mid_init(struct dw_spi *dws) iounmap(clk_reg); #ifdef CONFIG_SPI_DW_MID_DMA - dws->dma_priv = kzalloc(sizeof(struct mid_dma), GFP_KERNEL); - if (!dws->dma_priv) - return -ENOMEM; + dws->dma_tx = &mid_dma_tx; + dws->dma_rx = &mid_dma_rx; dws->dma_ops = &mid_dma_ops; #endif return 0; diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h index f298df59381b..41f77e2ccf63 100644 --- a/drivers/spi/spi-dw.h +++ b/drivers/spi/spi-dw.h @@ -128,10 +128,10 @@ struct dw_spi { struct dma_chan *txchan; struct dma_chan *rxchan; unsigned long dma_chan_busy; - struct device *dma_dev; dma_addr_t dma_addr; /* phy address of the Data register */ struct dw_spi_dma_ops *dma_ops; - void *dma_priv; /* platform relate info */ + void *dma_tx; + void *dma_rx; /* Bus interface info */ void *priv; -- GitLab From bd22f9d405eb14cc074d294919d0b909e0bc6170 Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Mon, 9 Mar 2015 16:55:22 +0800 Subject: [PATCH 03587/11651] ASoC: rt5670: Revert Keep sysclk on patch The "Keep sysclk on if JD func is used" patch force enable/disable pin in rt5670_set_dai_sysclk. But some machine driver call it in dapm widget event. It will cause kernel crash. Signed-off-by: Bard Liao Signed-off-by: Mark Brown --- sound/soc/codecs/rt5670.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c index 592f961b5de5..32cd26678bae 100644 --- a/sound/soc/codecs/rt5670.c +++ b/sound/soc/codecs/rt5670.c @@ -2273,13 +2273,6 @@ static int rt5670_set_dai_sysclk(struct snd_soc_dai *dai, if (freq == rt5670->sysclk && clk_id == rt5670->sysclk_src) return 0; - if (rt5670->pdata.jd_mode) { - if (clk_id == RT5670_SCLK_S_PLL1) - snd_soc_dapm_force_enable_pin(&codec->dapm, "PLL1"); - else - snd_soc_dapm_disable_pin(&codec->dapm, "PLL1"); - snd_soc_dapm_sync(&codec->dapm); - } switch (clk_id) { case RT5670_SCLK_S_MCLK: reg_val |= RT5670_SCLK_SRC_MCLK; @@ -2724,10 +2717,6 @@ static int rt5670_i2c_probe(struct i2c_client *i2c, } if (rt5670->pdata.jd_mode) { - regmap_update_bits(rt5670->regmap, RT5670_GLB_CLK, - RT5670_SCLK_SRC_MASK, RT5670_SCLK_SRC_RCCLK); - rt5670->sysclk = 0; - rt5670->sysclk_src = RT5670_SCLK_S_RCCLK; regmap_update_bits(rt5670->regmap, RT5670_PWR_ANLG1, RT5670_PWR_MB, RT5670_PWR_MB); regmap_update_bits(rt5670->regmap, RT5670_PWR_ANLG2, -- GitLab From 485372dc24ca2eaac18ce41a51b9dd017bc11400 Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Mon, 9 Mar 2015 16:55:23 +0800 Subject: [PATCH 03588/11651] ASoC: rt5670: Check sysclk source by private data Currently, is_sys_clk_from_pll check sysclk source by reading codec register value. And it will be invoked before updating dapm widget power. In some machine driver, snd_soc_dai_set_sysclk is called in dapm event to switch codec sysclk to RC clock in idle mode. And in some use cases (such as syspend/resume) hw_params will not be called when the dapm widget is powered up. As a result, is_sys_clk_from_pll will return 0 although it is supposed to be 1. To solve this, we let is_sys_clk_from_pll check sysclk sysclk_src which is stored in private data and don't change the value of sysclk_src when codec sysclk is switched to internal clock. The internal clock can only be used in idle mode, so it sould be fine if we don't set sysclk_src to internal clock. Signed-off-by: Bard Liao Signed-off-by: Mark Brown --- sound/soc/codecs/rt5670.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c index 32cd26678bae..9e3bc43178f1 100644 --- a/sound/soc/codecs/rt5670.c +++ b/sound/soc/codecs/rt5670.c @@ -517,11 +517,10 @@ static int set_dmic_clk(struct snd_soc_dapm_widget *w, static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source, struct snd_soc_dapm_widget *sink) { - unsigned int val; + struct snd_soc_codec *codec = source->codec; + struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec); - val = snd_soc_read(source->codec, RT5670_GLB_CLK); - val &= RT5670_SCLK_SRC_MASK; - if (val == RT5670_SCLK_SRC_PLL1) + if (rt5670->sysclk_src == RT5670_SCLK_S_PLL1) return 1; else return 0; @@ -2270,9 +2269,6 @@ static int rt5670_set_dai_sysclk(struct snd_soc_dai *dai, struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec); unsigned int reg_val = 0; - if (freq == rt5670->sysclk && clk_id == rt5670->sysclk_src) - return 0; - switch (clk_id) { case RT5670_SCLK_S_MCLK: reg_val |= RT5670_SCLK_SRC_MCLK; @@ -2290,7 +2286,8 @@ static int rt5670_set_dai_sysclk(struct snd_soc_dai *dai, snd_soc_update_bits(codec, RT5670_GLB_CLK, RT5670_SCLK_SRC_MASK, reg_val); rt5670->sysclk = freq; - rt5670->sysclk_src = clk_id; + if (clk_id != RT5670_SCLK_S_RCCLK) + rt5670->sysclk_src = clk_id; dev_dbg(dai->dev, "Sysclk is %dHz and clock id is %d\n", freq, clk_id); -- GitLab From 62c76fe2e580f6a975679e8711bade09e24c204b Mon Sep 17 00:00:00 2001 From: Nicholas Mc Guire Date: Sun, 8 Mar 2015 06:02:15 -0400 Subject: [PATCH 03589/11651] ASoC: wm8996: match wait_for_completion_timeout return type return type of wait_for_completion_timeout is unsigned long not int. An appropriately named unsigned long is added and the assignment fixed up in case of completion occurring the remaining time is >=1 so ret is set to 1 if no timeout occurred. Signed-off-by: Nicholas Mc Guire Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm8996.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c index dc92d5e4e942..7a2b96959589 100644 --- a/sound/soc/codecs/wm8996.c +++ b/sound/soc/codecs/wm8996.c @@ -2009,7 +2009,7 @@ static int wm8996_set_fll(struct snd_soc_codec *codec, int fll_id, int source, struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); struct i2c_client *i2c = to_i2c_client(codec->dev); struct _fll_div fll_div; - unsigned long timeout; + unsigned long timeout, time_left; int ret, reg, retry; /* Any change? */ @@ -2113,10 +2113,11 @@ static int wm8996_set_fll(struct snd_soc_codec *codec, int fll_id, int source, timeout /= 2; for (retry = 0; retry < 10; retry++) { - ret = wait_for_completion_timeout(&wm8996->fll_lock, - timeout); - if (ret != 0) { + time_left = wait_for_completion_timeout(&wm8996->fll_lock, + timeout); + if (time_left != 0) { WARN_ON(!i2c->irq); + ret = 1; break; } -- GitLab From 159366ea38706402e8ebd0f55eef52931333deac Mon Sep 17 00:00:00 2001 From: Nicholas Mc Guire Date: Sun, 8 Mar 2015 06:02:38 -0400 Subject: [PATCH 03590/11651] ASoC: wm8996: ensure lower bounds of 1 for timeout wait_for_completion_timeout can be called with timeout == 0 due to msecs_to_jiffies(2) == 1 for HZ < 1000 and usecs_to_jiffies(300) == 1 for all reasonable values of HZ, thus the following timeout /= 2; sets timeout to 0. This patch simply adds a lower-bounds of 1. Signed-off-by: Nicholas Mc Guire Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm8996.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c index 7a2b96959589..308748a022c5 100644 --- a/sound/soc/codecs/wm8996.c +++ b/sound/soc/codecs/wm8996.c @@ -2110,7 +2110,8 @@ static int wm8996_set_fll(struct snd_soc_codec *codec, int fll_id, int source, if (i2c->irq) timeout *= 10; else - timeout /= 2; + /* ensure timeout of atleast 1 jiffies */ + timeout = timeout/2 ? : 1; for (retry = 0; retry < 10; retry++) { time_left = wait_for_completion_timeout(&wm8996->fll_lock, -- GitLab From 17f4ad601d2753be7f15cd2928e89309759e4936 Mon Sep 17 00:00:00 2001 From: Nicholas Mc Guire Date: Sun, 8 Mar 2015 09:16:49 -0400 Subject: [PATCH 03591/11651] ASoC: arizona: match wait_for_completion_timeout return type return type of wait_for_completion_timeout is unsigned long not int. An appropriately named unsigned long is added and the assignment fixed up. Signed-off-by: Nicholas Mc Guire Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/arizona.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index 29202610dd0d..9015b44a9e11 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c @@ -1901,7 +1901,7 @@ static int arizona_is_enabled_fll(struct arizona_fll *fll) static int arizona_enable_fll(struct arizona_fll *fll) { struct arizona *arizona = fll->arizona; - int ret; + unsigned long time_left; bool use_sync = false; int already_enabled = arizona_is_enabled_fll(fll); struct arizona_fll_cfg cfg; @@ -1977,9 +1977,9 @@ static int arizona_enable_fll(struct arizona_fll *fll) regmap_update_bits_async(arizona->regmap, fll->base + 1, ARIZONA_FLL1_FREERUN, 0); - ret = wait_for_completion_timeout(&fll->ok, + time_left = wait_for_completion_timeout(&fll->ok, msecs_to_jiffies(250)); - if (ret == 0) + if (time_left == 0) arizona_fll_warn(fll, "Timed out waiting for lock\n"); return 0; -- GitLab From 905a808664402dec0ac11376833e79da4ae7b2fd Mon Sep 17 00:00:00 2001 From: Nicholas Mc Guire Date: Sun, 8 Mar 2015 06:57:07 -0400 Subject: [PATCH 03592/11651] ASoC: wm5100: match wait_for_completion_timeout return type return type of wait_for_completion_timeout is unsigned long not int. An appropriately named unsigned long is added and the assignment fixed up. Signed-off-by: Nicholas Mc Guire Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm5100.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c index ea09db585aa1..96740379b711 100644 --- a/sound/soc/codecs/wm5100.c +++ b/sound/soc/codecs/wm5100.c @@ -1762,6 +1762,7 @@ static int wm5100_set_fll(struct snd_soc_codec *codec, int fll_id, int source, struct _fll_div factors; struct wm5100_fll *fll; int ret, base, lock, i, timeout; + unsigned long time_left; switch (fll_id) { case WM5100_FLL1: @@ -1842,9 +1843,9 @@ static int wm5100_set_fll(struct snd_soc_codec *codec, int fll_id, int source, /* Poll for the lock; will use interrupt when we can test */ for (i = 0; i < timeout; i++) { if (i2c->irq) { - ret = wait_for_completion_timeout(&fll->lock, - msecs_to_jiffies(25)); - if (ret > 0) + time_left = wait_for_completion_timeout(&fll->lock, + msecs_to_jiffies(25)); + if (time_left > 0) break; } else { msleep(1); -- GitLab From 78bb997ace926451ec8d1ed15178b161dc61b805 Mon Sep 17 00:00:00 2001 From: Nicholas Mc Guire Date: Sun, 8 Mar 2015 07:06:05 -0400 Subject: [PATCH 03593/11651] ASoC: wm2200: match wait_for_completion_timeout return type return type of wait_for_completion_timeout is unsigned long not int. An appropriately named unsigned long is added and the assignment fixed up. Signed-off-by: Nicholas Mc Guire Signed-off-by: Mark Brown --- sound/soc/codecs/wm2200.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/wm2200.c b/sound/soc/codecs/wm2200.c index 15599845a660..b48694a8d213 100644 --- a/sound/soc/codecs/wm2200.c +++ b/sound/soc/codecs/wm2200.c @@ -1942,6 +1942,7 @@ static int wm2200_set_fll(struct snd_soc_codec *codec, int fll_id, int source, struct wm2200_priv *wm2200 = snd_soc_codec_get_drvdata(codec); struct _fll_div factors; int ret, i, timeout; + unsigned long time_left; if (!Fout) { dev_dbg(codec->dev, "FLL disabled"); @@ -2021,9 +2022,10 @@ static int wm2200_set_fll(struct snd_soc_codec *codec, int fll_id, int source, /* Poll for the lock; will use the interrupt to exit quickly */ for (i = 0; i < timeout; i++) { if (i2c->irq) { - ret = wait_for_completion_timeout(&wm2200->fll_lock, - msecs_to_jiffies(25)); - if (ret > 0) + time_left = wait_for_completion_timeout( + &wm2200->fll_lock, + msecs_to_jiffies(25)); + if (time_left > 0) break; } else { msleep(1); -- GitLab From 32556394501a27c02e7185c4d11a51b636b02f4b Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 9 Mar 2015 11:15:28 -0700 Subject: [PATCH 03594/11651] ASoC: cx20442: remove incorerct __exit markups Even if bus is not hot-pluggable, the devices can be unbound from the driver via sysfs, so we should not be using __exit annotations on remove() methods. The only exception is drivers registered with platform_driver_probe() which specifically disables sysfs bind/unbind attributes. Signed-off-by: Dmitry Torokhov Signed-off-by: Mark Brown --- sound/soc/codecs/cx20442.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c index 0b10979513c4..0f334bc1b63c 100644 --- a/sound/soc/codecs/cx20442.c +++ b/sound/soc/codecs/cx20442.c @@ -420,7 +420,7 @@ static int cx20442_platform_probe(struct platform_device *pdev) &cx20442_codec_dev, &cx20442_dai, 1); } -static int __exit cx20442_platform_remove(struct platform_device *pdev) +static int cx20442_platform_remove(struct platform_device *pdev) { snd_soc_unregister_codec(&pdev->dev); return 0; @@ -431,7 +431,7 @@ static struct platform_driver cx20442_platform_driver = { .name = "cx20442-codec", }, .probe = cx20442_platform_probe, - .remove = __exit_p(cx20442_platform_remove), + .remove = cx20442_platform_remove, }; module_platform_driver(cx20442_platform_driver); -- GitLab From f580f8afd0d81c3f04d8b393c9d675ef289e4d40 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 9 Mar 2015 11:18:14 -0700 Subject: [PATCH 03595/11651] ASoC: tlv320aic23: remove incorrect __exit markups Even if bus is not hot-pluggable, the devices can be unbound from the driver via sysfs, so we should not be using __exit annotations on remove() methods. The only exception is drivers registered with platform_driver_probe() which specifically disables sysfs bind/unbind attributes. Signed-off-by: Dmitry Torokhov Signed-off-by: Mark Brown --- sound/soc/codecs/tlv320aic23-i2c.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/tlv320aic23-i2c.c b/sound/soc/codecs/tlv320aic23-i2c.c index f13701995482..78a94af65518 100644 --- a/sound/soc/codecs/tlv320aic23-i2c.c +++ b/sound/soc/codecs/tlv320aic23-i2c.c @@ -31,7 +31,7 @@ static int tlv320aic23_i2c_probe(struct i2c_client *i2c, return tlv320aic23_probe(&i2c->dev, regmap); } -static int __exit tlv320aic23_i2c_remove(struct i2c_client *i2c) +static int tlv320aic23_i2c_remove(struct i2c_client *i2c) { snd_soc_unregister_codec(&i2c->dev); return 0; @@ -56,7 +56,7 @@ static struct i2c_driver tlv320aic23_i2c_driver = { .of_match_table = of_match_ptr(tlv320aic23_of_match), }, .probe = tlv320aic23_i2c_probe, - .remove = __exit_p(tlv320aic23_i2c_remove), + .remove = tlv320aic23_i2c_remove, .id_table = tlv320aic23_id, }; -- GitLab From e39ce48f5362df9f87400b4909a6fb0f51b109ac Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Wed, 11 Feb 2015 19:35:27 -0800 Subject: [PATCH 03596/11651] regulator: Rename regulator_set_optimum_mode Rename the regulator_set_optimum_mode() function regulator_set_load() to better represent what's going on. Signed-off-by: Bjorn Andersson Signed-off-by: Mark Brown --- Documentation/power/regulator/consumer.txt | 2 +- drivers/regulator/core.c | 8 ++++---- include/linux/regulator/consumer.h | 12 +++++++++--- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/Documentation/power/regulator/consumer.txt b/Documentation/power/regulator/consumer.txt index 8afb236ca765..e51564c1a140 100644 --- a/Documentation/power/regulator/consumer.txt +++ b/Documentation/power/regulator/consumer.txt @@ -137,7 +137,7 @@ Indirect operating mode control. Consumer drivers can request a change in their supply regulator operating mode by calling :- -int regulator_set_optimum_mode(struct regulator *regulator, int load_uA); +int regulator_set_load(struct regulator *regulator, int load_uA); This will cause the core to recalculate the total load on the regulator (based on all its consumers) and change operating mode (if necessary and permitted) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index b899947d839d..03088f9c3d4f 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -2994,7 +2994,7 @@ unsigned int regulator_get_mode(struct regulator *regulator) EXPORT_SYMBOL_GPL(regulator_get_mode); /** - * regulator_set_optimum_mode - set regulator optimum operating mode + * regulator_set_load - set regulator load * @regulator: regulator source * @uA_load: load current * @@ -3017,9 +3017,9 @@ EXPORT_SYMBOL_GPL(regulator_get_mode); * DRMS will sum the total requested load on the regulator and change * to the most efficient operating mode if platform constraints allow. * - * Returns the new regulator mode or error. + * On error a negative errno is returned. */ -int regulator_set_optimum_mode(struct regulator *regulator, int uA_load) +int regulator_set_load(struct regulator *regulator, int uA_load) { struct regulator_dev *rdev = regulator->rdev; int ret; @@ -3031,7 +3031,7 @@ int regulator_set_optimum_mode(struct regulator *regulator, int uA_load) return ret; } -EXPORT_SYMBOL_GPL(regulator_set_optimum_mode); +EXPORT_SYMBOL_GPL(regulator_set_load); /** * regulator_allow_bypass - allow the regulator to go into bypass mode diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h index d17e1ff7ad01..6d4e9d2289f0 100644 --- a/include/linux/regulator/consumer.h +++ b/include/linux/regulator/consumer.h @@ -238,7 +238,7 @@ int regulator_get_current_limit(struct regulator *regulator); int regulator_set_mode(struct regulator *regulator, unsigned int mode); unsigned int regulator_get_mode(struct regulator *regulator); -int regulator_set_optimum_mode(struct regulator *regulator, int load_uA); +int regulator_set_load(struct regulator *regulator, int load_uA); int regulator_allow_bypass(struct regulator *regulator, bool allow); @@ -479,8 +479,7 @@ static inline unsigned int regulator_get_mode(struct regulator *regulator) return REGULATOR_MODE_NORMAL; } -static inline int regulator_set_optimum_mode(struct regulator *regulator, - int load_uA) +static inline int regulator_set_load(struct regulator *regulator, int load_uA) { return REGULATOR_MODE_NORMAL; } @@ -555,4 +554,11 @@ static inline int regulator_is_supported_voltage_tol(struct regulator *regulator target_uV + tol_uV); } +/* TEMP: Wrapper to keep bisectability */ +static inline int regulator_set_optimum_mode(struct regulator *regulator, + int load_uA) +{ + return regulator_set_load(regulator, load_uA); +} + #endif -- GitLab From 7b16a07c32935ea7f59f4408b7c9200d9cd0cced Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Wed, 11 Feb 2015 19:35:28 -0800 Subject: [PATCH 03597/11651] ufs: Rename of regulator_set_optimum_mode The function regulator_set_optimum_mode() is changing name to regulator_set_load(), so update the code accordingly. Also cleaned up ufshcd_config_vreg_load() while touching the code. Signed-off-by: Bjorn Andersson Signed-off-by: Mark Brown --- drivers/scsi/ufs/ufshcd.c | 27 +++++++-------------------- 1 file changed, 7 insertions(+), 20 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 5d60a868830d..2aa85e398f76 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -4225,22 +4225,15 @@ static struct scsi_host_template ufshcd_driver_template = { static int ufshcd_config_vreg_load(struct device *dev, struct ufs_vreg *vreg, int ua) { - int ret = 0; - struct regulator *reg = vreg->reg; - const char *name = vreg->name; + int ret; - BUG_ON(!vreg); + if (!vreg) + return 0; - ret = regulator_set_optimum_mode(reg, ua); - if (ret >= 0) { - /* - * regulator_set_optimum_mode() returns new regulator - * mode upon success. - */ - ret = 0; - } else { - dev_err(dev, "%s: %s set optimum mode(ua=%d) failed, err=%d\n", - __func__, name, ua, ret); + ret = regulator_set_load(vreg->reg, ua); + if (ret < 0) { + dev_err(dev, "%s: %s set load (ua=%d) failed, err=%d\n", + __func__, vreg->name, ua, ret); } return ret; @@ -4249,18 +4242,12 @@ static int ufshcd_config_vreg_load(struct device *dev, struct ufs_vreg *vreg, static inline int ufshcd_config_vreg_lpm(struct ufs_hba *hba, struct ufs_vreg *vreg) { - if (!vreg) - return 0; - return ufshcd_config_vreg_load(hba->dev, vreg, UFS_VREG_LPM_LOAD_UA); } static inline int ufshcd_config_vreg_hpm(struct ufs_hba *hba, struct ufs_vreg *vreg) { - if (!vreg) - return 0; - return ufshcd_config_vreg_load(hba->dev, vreg, vreg->max_uA); } -- GitLab From 1d61a6948121d73e897df0f96a0fd8aa3b3b1ac9 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Wed, 11 Feb 2015 19:35:29 -0800 Subject: [PATCH 03598/11651] usb: phy: ab8500-usb: Rename regulator_set_optimum_mode The function regulator_set_optimum_mode() is changing name to regulator_set_load(), so update the code accordingly. Signed-off-by: Bjorn Andersson Acked-by: Felipe Balbi Signed-off-by: Mark Brown --- drivers/usb/phy/phy-ab8500-usb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/phy/phy-ab8500-usb.c b/drivers/usb/phy/phy-ab8500-usb.c index 0b1bd2369293..f5b3b928941b 100644 --- a/drivers/usb/phy/phy-ab8500-usb.c +++ b/drivers/usb/phy/phy-ab8500-usb.c @@ -277,7 +277,7 @@ static void ab8500_usb_regulator_enable(struct ab8500_usb *ab) dev_err(ab->dev, "Failed to set the Vintcore to 1.3V, ret=%d\n", ret); - ret = regulator_set_optimum_mode(ab->v_ulpi, 28000); + ret = regulator_set_load(ab->v_ulpi, 28000); if (ret < 0) dev_err(ab->dev, "Failed to set optimum mode (ret=%d)\n", ret); @@ -317,7 +317,7 @@ static void ab8500_usb_regulator_disable(struct ab8500_usb *ab) ab->saved_v_ulpi, ret); } - ret = regulator_set_optimum_mode(ab->v_ulpi, 0); + ret = regulator_set_load(ab->v_ulpi, 0); if (ret < 0) dev_err(ab->dev, "Failed to set optimum mode (ret=%d)\n", ret); -- GitLab From fa53e351e81259644717b381e095eaf9173c9ca8 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Wed, 11 Feb 2015 19:35:30 -0800 Subject: [PATCH 03599/11651] usb: phy: phy-msm-usb: Rename regulator_set_optimum_mode The function regulator_set_optimum_mode() is changing name to regulator_set_load(), so update the code accordingly. Signed-off-by: Bjorn Andersson Acked-by: Felipe Balbi Signed-off-by: Mark Brown --- drivers/usb/phy/phy-msm-usb.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c index 000fd892455f..6ed67ea4ef7e 100644 --- a/drivers/usb/phy/phy-msm-usb.c +++ b/drivers/usb/phy/phy-msm-usb.c @@ -142,27 +142,22 @@ static int msm_hsusb_ldo_set_mode(struct msm_otg *motg, int on) int ret = 0; if (on) { - ret = regulator_set_optimum_mode(motg->v1p8, - USB_PHY_1P8_HPM_LOAD); + ret = regulator_set_load(motg->v1p8, USB_PHY_1P8_HPM_LOAD); if (ret < 0) { pr_err("Could not set HPM for v1p8\n"); return ret; } - ret = regulator_set_optimum_mode(motg->v3p3, - USB_PHY_3P3_HPM_LOAD); + ret = regulator_set_load(motg->v3p3, USB_PHY_3P3_HPM_LOAD); if (ret < 0) { pr_err("Could not set HPM for v3p3\n"); - regulator_set_optimum_mode(motg->v1p8, - USB_PHY_1P8_LPM_LOAD); + regulator_set_load(motg->v1p8, USB_PHY_1P8_LPM_LOAD); return ret; } } else { - ret = regulator_set_optimum_mode(motg->v1p8, - USB_PHY_1P8_LPM_LOAD); + ret = regulator_set_load(motg->v1p8, USB_PHY_1P8_LPM_LOAD); if (ret < 0) pr_err("Could not set LPM for v1p8\n"); - ret = regulator_set_optimum_mode(motg->v3p3, - USB_PHY_3P3_LPM_LOAD); + ret = regulator_set_load(motg->v3p3, USB_PHY_3P3_LPM_LOAD); if (ret < 0) pr_err("Could not set LPM for v3p3\n"); } -- GitLab From ae6e808f15742fcbc0097ac2fb3055d553266965 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Wed, 11 Feb 2015 19:35:31 -0800 Subject: [PATCH 03600/11651] regulator: Drop temporary regulator_set_optimum_mode wrapper Signed-off-by: Bjorn Andersson Signed-off-by: Mark Brown --- include/linux/regulator/consumer.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h index 6d4e9d2289f0..d8944f508235 100644 --- a/include/linux/regulator/consumer.h +++ b/include/linux/regulator/consumer.h @@ -554,11 +554,4 @@ static inline int regulator_is_supported_voltage_tol(struct regulator *regulator target_uV + tol_uV); } -/* TEMP: Wrapper to keep bisectability */ -static inline int regulator_set_optimum_mode(struct regulator *regulator, - int load_uA) -{ - return regulator_set_load(regulator, load_uA); -} - #endif -- GitLab From 2306509605d3cb45b8480089af2d282600650e9e Mon Sep 17 00:00:00 2001 From: Thor Thayer Date: Fri, 6 Mar 2015 17:46:32 -0600 Subject: [PATCH 03601/11651] spi: dw-spi: Single Register read to clear IRQs Instead of clearing the RxU, RxO, and TxO IRQs individually with 3 register reads, a single read of the ICR register will do the same thing. Signed-off-by: Thor Thayer Signed-off-by: Andy Shevchenko Signed-off-by: Mark Brown --- drivers/spi/spi-dw.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c index 2437bfcbf2f8..0f0106933b52 100644 --- a/drivers/spi/spi-dw.c +++ b/drivers/spi/spi-dw.c @@ -232,9 +232,7 @@ static irqreturn_t interrupt_transfer(struct dw_spi *dws) /* Error handling */ if (irq_status & (SPI_INT_TXOI | SPI_INT_RXOI | SPI_INT_RXUI)) { - dw_readw(dws, DW_SPI_TXOICR); - dw_readw(dws, DW_SPI_RXOICR); - dw_readw(dws, DW_SPI_RXUICR); + dw_readw(dws, DW_SPI_ICR); int_error_stop(dws, "interrupt_transfer: fifo overrun/underrun"); return IRQ_HANDLED; } -- GitLab From 1e052be69d045c8d0f82ff1116fd3e5a79661745 Mon Sep 17 00:00:00 2001 From: Cong Wang Date: Fri, 6 Mar 2015 11:47:59 -0800 Subject: [PATCH 03602/11651] net_sched: destroy proto tp when all filters are gone Kernel automatically creates a tp for each (kind, protocol, priority) tuple, which has handle 0, when we add a new filter, but it still is left there after we remove our own, unless we don't specify the handle (literally means all the filters under the tuple). For example this one is left: # tc filter show dev eth0 filter parent 8001: protocol arp pref 49152 basic The user-space is hard to clean up these for kernel because filters like u32 are organized in a complex way. So kernel is responsible to remove it after all filters are gone. Each type of filter has its own way to store the filters, so each type has to provide its way to check if all filters are gone. Cc: Jamal Hadi Salim Signed-off-by: Cong Wang Signed-off-by: Cong Wang Acked-by: Jamal Hadi Salim Signed-off-by: David S. Miller --- include/net/sch_generic.h | 4 ++-- net/sched/cls_api.c | 14 ++++++++++---- net/sched/cls_basic.c | 6 +++++- net/sched/cls_bpf.c | 6 +++++- net/sched/cls_cgroup.c | 6 +++++- net/sched/cls_flow.c | 6 +++++- net/sched/cls_fw.c | 11 +++++++++-- net/sched/cls_route.c | 12 ++++++++++-- net/sched/cls_rsvp.h | 12 ++++++++++-- net/sched/cls_tcindex.c | 6 +++++- net/sched/cls_u32.c | 25 ++++++++++++++++++++++++- net/sched/sch_api.c | 14 +++++++++----- 12 files changed, 99 insertions(+), 23 deletions(-) diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index c605d305c577..6d778efcfdfd 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -213,7 +213,7 @@ struct tcf_proto_ops { const struct tcf_proto *, struct tcf_result *); int (*init)(struct tcf_proto*); - void (*destroy)(struct tcf_proto*); + bool (*destroy)(struct tcf_proto*, bool); unsigned long (*get)(struct tcf_proto*, u32 handle); int (*change)(struct net *net, struct sk_buff *, @@ -399,7 +399,7 @@ struct Qdisc *qdisc_create_dflt(struct netdev_queue *dev_queue, const struct Qdisc_ops *ops, u32 parentid); void __qdisc_calculate_pkt_len(struct sk_buff *skb, const struct qdisc_size_table *stab); -void tcf_destroy(struct tcf_proto *tp); +bool tcf_destroy(struct tcf_proto *tp, bool force); void tcf_destroy_chain(struct tcf_proto __rcu **fl); /* Reset all TX qdiscs greater then index of a device. */ diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index baef987fe2c0..8b0470e418dc 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c @@ -286,7 +286,7 @@ replay: RCU_INIT_POINTER(*back, next); tfilter_notify(net, skb, n, tp, fh, RTM_DELTFILTER); - tcf_destroy(tp); + tcf_destroy(tp, true); err = 0; goto errout; } @@ -301,14 +301,20 @@ replay: err = -EEXIST; if (n->nlmsg_flags & NLM_F_EXCL) { if (tp_created) - tcf_destroy(tp); + tcf_destroy(tp, true); goto errout; } break; case RTM_DELTFILTER: err = tp->ops->delete(tp, fh); - if (err == 0) + if (err == 0) { tfilter_notify(net, skb, n, tp, fh, RTM_DELTFILTER); + if (tcf_destroy(tp, false)) { + struct tcf_proto *next = rtnl_dereference(tp->next); + + RCU_INIT_POINTER(*back, next); + } + } goto errout; case RTM_GETTFILTER: err = tfilter_notify(net, skb, n, tp, fh, RTM_NEWTFILTER); @@ -329,7 +335,7 @@ replay: tfilter_notify(net, skb, n, tp, fh, RTM_NEWTFILTER); } else { if (tp_created) - tcf_destroy(tp); + tcf_destroy(tp, true); } errout: diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c index fc399db86f11..0b8c3ace671f 100644 --- a/net/sched/cls_basic.c +++ b/net/sched/cls_basic.c @@ -96,11 +96,14 @@ static void basic_delete_filter(struct rcu_head *head) kfree(f); } -static void basic_destroy(struct tcf_proto *tp) +static bool basic_destroy(struct tcf_proto *tp, bool force) { struct basic_head *head = rtnl_dereference(tp->root); struct basic_filter *f, *n; + if (!force && !list_empty(&head->flist)) + return false; + list_for_each_entry_safe(f, n, &head->flist, link) { list_del_rcu(&f->link); tcf_unbind_filter(tp, &f->res); @@ -108,6 +111,7 @@ static void basic_destroy(struct tcf_proto *tp) } RCU_INIT_POINTER(tp->root, NULL); kfree_rcu(head, rcu); + return true; } static int basic_delete(struct tcf_proto *tp, unsigned long arg) diff --git a/net/sched/cls_bpf.c b/net/sched/cls_bpf.c index 6f7ed8f8e6ee..243c9f225a73 100644 --- a/net/sched/cls_bpf.c +++ b/net/sched/cls_bpf.c @@ -137,11 +137,14 @@ static int cls_bpf_delete(struct tcf_proto *tp, unsigned long arg) return 0; } -static void cls_bpf_destroy(struct tcf_proto *tp) +static bool cls_bpf_destroy(struct tcf_proto *tp, bool force) { struct cls_bpf_head *head = rtnl_dereference(tp->root); struct cls_bpf_prog *prog, *tmp; + if (!force && !list_empty(&head->plist)) + return false; + list_for_each_entry_safe(prog, tmp, &head->plist, link) { list_del_rcu(&prog->link); tcf_unbind_filter(tp, &prog->res); @@ -150,6 +153,7 @@ static void cls_bpf_destroy(struct tcf_proto *tp) RCU_INIT_POINTER(tp->root, NULL); kfree_rcu(head, rcu); + return true; } static unsigned long cls_bpf_get(struct tcf_proto *tp, u32 handle) diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c index 221697ab0247..ea611b216412 100644 --- a/net/sched/cls_cgroup.c +++ b/net/sched/cls_cgroup.c @@ -143,14 +143,18 @@ errout: return err; } -static void cls_cgroup_destroy(struct tcf_proto *tp) +static bool cls_cgroup_destroy(struct tcf_proto *tp, bool force) { struct cls_cgroup_head *head = rtnl_dereference(tp->root); + if (!force) + return false; + if (head) { RCU_INIT_POINTER(tp->root, NULL); call_rcu(&head->rcu, cls_cgroup_destroy_rcu); } + return true; } static int cls_cgroup_delete(struct tcf_proto *tp, unsigned long arg) diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c index 461410394d08..a620c4e288a5 100644 --- a/net/sched/cls_flow.c +++ b/net/sched/cls_flow.c @@ -557,17 +557,21 @@ static int flow_init(struct tcf_proto *tp) return 0; } -static void flow_destroy(struct tcf_proto *tp) +static bool flow_destroy(struct tcf_proto *tp, bool force) { struct flow_head *head = rtnl_dereference(tp->root); struct flow_filter *f, *next; + if (!force && !list_empty(&head->filters)) + return false; + list_for_each_entry_safe(f, next, &head->filters, list) { list_del_rcu(&f->list); call_rcu(&f->rcu, flow_destroy_filter); } RCU_INIT_POINTER(tp->root, NULL); kfree_rcu(head, rcu); + return true; } static unsigned long flow_get(struct tcf_proto *tp, u32 handle) diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c index 9d9aa3e82b10..715e01e5910a 100644 --- a/net/sched/cls_fw.c +++ b/net/sched/cls_fw.c @@ -133,14 +133,20 @@ static void fw_delete_filter(struct rcu_head *head) kfree(f); } -static void fw_destroy(struct tcf_proto *tp) +static bool fw_destroy(struct tcf_proto *tp, bool force) { struct fw_head *head = rtnl_dereference(tp->root); struct fw_filter *f; int h; if (head == NULL) - return; + return true; + + if (!force) { + for (h = 0; h < HTSIZE; h++) + if (rcu_access_pointer(head->ht[h])) + return false; + } for (h = 0; h < HTSIZE; h++) { while ((f = rtnl_dereference(head->ht[h])) != NULL) { @@ -152,6 +158,7 @@ static void fw_destroy(struct tcf_proto *tp) } RCU_INIT_POINTER(tp->root, NULL); kfree_rcu(head, rcu); + return true; } static int fw_delete(struct tcf_proto *tp, unsigned long arg) diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c index bb8a60235d01..08a3b0a6f5ab 100644 --- a/net/sched/cls_route.c +++ b/net/sched/cls_route.c @@ -277,13 +277,20 @@ route4_delete_filter(struct rcu_head *head) kfree(f); } -static void route4_destroy(struct tcf_proto *tp) +static bool route4_destroy(struct tcf_proto *tp, bool force) { struct route4_head *head = rtnl_dereference(tp->root); int h1, h2; if (head == NULL) - return; + return true; + + if (!force) { + for (h1 = 0; h1 <= 256; h1++) { + if (rcu_access_pointer(head->table[h1])) + return false; + } + } for (h1 = 0; h1 <= 256; h1++) { struct route4_bucket *b; @@ -308,6 +315,7 @@ static void route4_destroy(struct tcf_proto *tp) } RCU_INIT_POINTER(tp->root, NULL); kfree_rcu(head, rcu); + return true; } static int route4_delete(struct tcf_proto *tp, unsigned long arg) diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h index edd8ade3fbc1..02fa82792dab 100644 --- a/net/sched/cls_rsvp.h +++ b/net/sched/cls_rsvp.h @@ -291,13 +291,20 @@ rsvp_delete_filter(struct tcf_proto *tp, struct rsvp_filter *f) kfree_rcu(f, rcu); } -static void rsvp_destroy(struct tcf_proto *tp) +static bool rsvp_destroy(struct tcf_proto *tp, bool force) { struct rsvp_head *data = rtnl_dereference(tp->root); int h1, h2; if (data == NULL) - return; + return true; + + if (!force) { + for (h1 = 0; h1 < 256; h1++) { + if (rcu_access_pointer(data->ht[h1])) + return false; + } + } RCU_INIT_POINTER(tp->root, NULL); @@ -319,6 +326,7 @@ static void rsvp_destroy(struct tcf_proto *tp) } } kfree_rcu(data, rcu); + return true; } static int rsvp_delete(struct tcf_proto *tp, unsigned long arg) diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c index bd49bf547a47..a557dbaf5afe 100644 --- a/net/sched/cls_tcindex.c +++ b/net/sched/cls_tcindex.c @@ -468,11 +468,14 @@ static void tcindex_walk(struct tcf_proto *tp, struct tcf_walker *walker) } } -static void tcindex_destroy(struct tcf_proto *tp) +static bool tcindex_destroy(struct tcf_proto *tp, bool force) { struct tcindex_data *p = rtnl_dereference(tp->root); struct tcf_walker walker; + if (!force) + return false; + pr_debug("tcindex_destroy(tp %p),p %p\n", tp, p); walker.count = 0; walker.skip = 0; @@ -481,6 +484,7 @@ static void tcindex_destroy(struct tcf_proto *tp) RCU_INIT_POINTER(tp->root, NULL); call_rcu(&p->rcu, __tcindex_destroy); + return true; } diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index 09487afbfd51..375e51b71c80 100644 --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c @@ -460,13 +460,35 @@ static int u32_destroy_hnode(struct tcf_proto *tp, struct tc_u_hnode *ht) return -ENOENT; } -static void u32_destroy(struct tcf_proto *tp) +static bool ht_empty(struct tc_u_hnode *ht) +{ + unsigned int h; + + for (h = 0; h <= ht->divisor; h++) + if (rcu_access_pointer(ht->ht[h])) + return false; + + return true; +} + +static bool u32_destroy(struct tcf_proto *tp, bool force) { struct tc_u_common *tp_c = tp->data; struct tc_u_hnode *root_ht = rtnl_dereference(tp->root); WARN_ON(root_ht == NULL); + if (!force) { + if (root_ht) { + if (root_ht->refcnt > 1) + return false; + if (root_ht->refcnt == 1) { + if (!ht_empty(root_ht)) + return false; + } + } + } + if (root_ht && --root_ht->refcnt == 0) u32_destroy_hnode(tp, root_ht); @@ -491,6 +513,7 @@ static void u32_destroy(struct tcf_proto *tp) } tp->data = NULL; + return true; } static int u32_delete(struct tcf_proto *tp, unsigned long arg) diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index 243b7d169d61..ad9eed70bc8f 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c @@ -1858,11 +1858,15 @@ reclassify: } EXPORT_SYMBOL(tc_classify); -void tcf_destroy(struct tcf_proto *tp) +bool tcf_destroy(struct tcf_proto *tp, bool force) { - tp->ops->destroy(tp); - module_put(tp->ops->owner); - kfree_rcu(tp, rcu); + if (tp->ops->destroy(tp, force)) { + module_put(tp->ops->owner); + kfree_rcu(tp, rcu); + return true; + } + + return false; } void tcf_destroy_chain(struct tcf_proto __rcu **fl) @@ -1871,7 +1875,7 @@ void tcf_destroy_chain(struct tcf_proto __rcu **fl) while ((tp = rtnl_dereference(*fl)) != NULL) { RCU_INIT_POINTER(*fl, tp->next); - tcf_destroy(tp); + tcf_destroy(tp, true); } } EXPORT_SYMBOL(tcf_destroy_chain); -- GitLab From 4fee6be8134a69545caf88d8b439936a326d6d77 Mon Sep 17 00:00:00 2001 From: Erik Hugne Date: Mon, 9 Mar 2015 10:19:31 +0100 Subject: [PATCH 03603/11651] tipc: sparse: fix htons conversion warnings Commit d0f91938bede ("tipc: add ip/udp media type") introduced some new sparse warnings. Clean them up. Signed-off-by: Erik Hugne Signed-off-by: David S. Miller --- net/tipc/udp_media.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/net/tipc/udp_media.c b/net/tipc/udp_media.c index 0d10001db40d..fc2fb11a354d 100644 --- a/net/tipc/udp_media.c +++ b/net/tipc/udp_media.c @@ -162,7 +162,7 @@ static int tipc_udp_send_msg(struct net *net, struct sk_buff *skb, err = -ENODEV; goto tx_error; } - if (htons(dst->proto) == ETH_P_IP) { + if (dst->proto == htons(ETH_P_IP)) { struct flowi4 fl = { .daddr = dst->ipv4.s_addr, .saddr = src->ipv4.s_addr, @@ -334,7 +334,7 @@ static int tipc_udp_enable(struct net *net, struct tipc_bearer *b, struct udp_media_addr *remote; struct udp_media_addr local = {0}; struct udp_port_cfg udp_conf = {0}; - struct udp_tunnel_sock_cfg tuncfg = {0}; + struct udp_tunnel_sock_cfg tuncfg = {NULL}; ub = kzalloc(sizeof(*ub), GFP_ATOMIC); if (!ub) @@ -351,7 +351,7 @@ static int tipc_udp_enable(struct net *net, struct tipc_bearer *b, rcu_assign_pointer(b->media_ptr, ub); rcu_assign_pointer(ub->bearer, b); tipc_udp_media_addr_set(&b->addr, &local); - if (htons(local.proto) == ETH_P_IP) { + if (local.proto == htons(ETH_P_IP)) { struct net_device *dev; dev = __ip_dev_find(net, local.ipv4.s_addr, false); @@ -366,7 +366,7 @@ static int tipc_udp_enable(struct net *net, struct tipc_bearer *b, b->mtu = dev->mtu - sizeof(struct iphdr) - sizeof(struct udphdr); #if IS_ENABLED(CONFIG_IPV6) - } else if (htons(local.proto) == ETH_P_IPV6) { + } else if (local.proto == htons(ETH_P_IPV6)) { udp_conf.family = AF_INET6; udp_conf.use_udp6_tx_checksums = true; udp_conf.use_udp6_rx_checksums = true; -- GitLab From f4427bc3e2735831fdf66f091429ec328feda246 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Mon, 9 Mar 2015 10:26:24 +0100 Subject: [PATCH 03604/11651] switchdev: use gpl variant of symbol export Signed-off-by: Jiri Pirko Acked-by: Scott Feldman Acked-by: Andy Gospodarek Acked-by: Florian Fainelli Signed-off-by: David S. Miller --- net/switchdev/switchdev.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c index 19e4e72a1e39..aba6aa2656d8 100644 --- a/net/switchdev/switchdev.c +++ b/net/switchdev/switchdev.c @@ -33,7 +33,7 @@ int netdev_switch_parent_id_get(struct net_device *dev, return -EOPNOTSUPP; return ops->ndo_switch_parent_id_get(dev, psid); } -EXPORT_SYMBOL(netdev_switch_parent_id_get); +EXPORT_SYMBOL_GPL(netdev_switch_parent_id_get); /** * netdev_switch_port_stp_update - Notify switch device port of STP @@ -52,7 +52,7 @@ int netdev_switch_port_stp_update(struct net_device *dev, u8 state) WARN_ON(!ops->ndo_switch_parent_id_get); return ops->ndo_switch_port_stp_update(dev, state); } -EXPORT_SYMBOL(netdev_switch_port_stp_update); +EXPORT_SYMBOL_GPL(netdev_switch_port_stp_update); static DEFINE_MUTEX(netdev_switch_mutex); static RAW_NOTIFIER_HEAD(netdev_switch_notif_chain); @@ -74,7 +74,7 @@ int register_netdev_switch_notifier(struct notifier_block *nb) mutex_unlock(&netdev_switch_mutex); return err; } -EXPORT_SYMBOL(register_netdev_switch_notifier); +EXPORT_SYMBOL_GPL(register_netdev_switch_notifier); /** * unregister_netdev_switch_notifier - Unregister nofifier @@ -92,7 +92,7 @@ int unregister_netdev_switch_notifier(struct notifier_block *nb) mutex_unlock(&netdev_switch_mutex); return err; } -EXPORT_SYMBOL(unregister_netdev_switch_notifier); +EXPORT_SYMBOL_GPL(unregister_netdev_switch_notifier); /** * call_netdev_switch_notifiers - Call nofifiers @@ -115,7 +115,7 @@ int call_netdev_switch_notifiers(unsigned long val, struct net_device *dev, mutex_unlock(&netdev_switch_mutex); return err; } -EXPORT_SYMBOL(call_netdev_switch_notifiers); +EXPORT_SYMBOL_GPL(call_netdev_switch_notifiers); /** * netdev_switch_port_bridge_setlink - Notify switch device port of bridge @@ -140,7 +140,7 @@ int netdev_switch_port_bridge_setlink(struct net_device *dev, return ops->ndo_bridge_setlink(dev, nlh, flags); } -EXPORT_SYMBOL(netdev_switch_port_bridge_setlink); +EXPORT_SYMBOL_GPL(netdev_switch_port_bridge_setlink); /** * netdev_switch_port_bridge_dellink - Notify switch device port of bridge @@ -165,7 +165,7 @@ int netdev_switch_port_bridge_dellink(struct net_device *dev, return ops->ndo_bridge_dellink(dev, nlh, flags); } -EXPORT_SYMBOL(netdev_switch_port_bridge_dellink); +EXPORT_SYMBOL_GPL(netdev_switch_port_bridge_dellink); /** * ndo_dflt_netdev_switch_port_bridge_setlink - default ndo bridge setlink @@ -195,7 +195,7 @@ int ndo_dflt_netdev_switch_port_bridge_setlink(struct net_device *dev, return ret; } -EXPORT_SYMBOL(ndo_dflt_netdev_switch_port_bridge_setlink); +EXPORT_SYMBOL_GPL(ndo_dflt_netdev_switch_port_bridge_setlink); /** * ndo_dflt_netdev_switch_port_bridge_dellink - default ndo bridge dellink @@ -225,7 +225,7 @@ int ndo_dflt_netdev_switch_port_bridge_dellink(struct net_device *dev, return ret; } -EXPORT_SYMBOL(ndo_dflt_netdev_switch_port_bridge_dellink); +EXPORT_SYMBOL_GPL(ndo_dflt_netdev_switch_port_bridge_dellink); static struct net_device *netdev_switch_get_lowest_dev(struct net_device *dev) { @@ -331,7 +331,7 @@ int netdev_switch_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi, return err; } -EXPORT_SYMBOL(netdev_switch_fib_ipv4_add); +EXPORT_SYMBOL_GPL(netdev_switch_fib_ipv4_add); /** * netdev_switch_fib_ipv4_del - Delete IPv4 route entry from switch @@ -369,7 +369,7 @@ int netdev_switch_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi, return err; } -EXPORT_SYMBOL(netdev_switch_fib_ipv4_del); +EXPORT_SYMBOL_GPL(netdev_switch_fib_ipv4_del); /** * netdev_switch_fib_ipv4_abort - Abort an IPv4 FIB operation @@ -389,4 +389,4 @@ void netdev_switch_fib_ipv4_abort(struct fib_info *fi) fib_flush_external(fi->fib_net); fi->fib_net->ipv4.fib_offload_disabled = true; } -EXPORT_SYMBOL(netdev_switch_fib_ipv4_abort); +EXPORT_SYMBOL_GPL(netdev_switch_fib_ipv4_abort); -- GitLab From 143fe22f50a8be855bba77b5b2dc9dd1a5982b1c Mon Sep 17 00:00:00 2001 From: Erik Hugne Date: Mon, 9 Mar 2015 10:43:42 +0100 Subject: [PATCH 03605/11651] tipc: fix inconsistent signal handling regression MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 9bbb4ecc6819 ("tipc: standardize recvmsg routine") changed the sleep/wakeup behaviour for sockets entering recv() or accept(). In this process the order of reporting -EAGAIN/-EINTR was reversed. This caused problems with wrong errno being reported back if the timeout expires. The same problem happens if the socket is nonblocking and recv()/accept() is called when the process have pending signals. If there is no pending data read or connections to accept, -EINTR will be returned instead of -EAGAIN. Signed-off-by: Erik Hugne Reviewed-by: Ying Xue Reviewed-by: Jon Maloy Reported-by László Benedek Signed-off-by: David S. Miller --- net/tipc/socket.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 95c514a1d7d9..934947f038b6 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -1318,12 +1318,12 @@ static int tipc_wait_for_rcvmsg(struct socket *sock, long *timeop) err = 0; if (!skb_queue_empty(&sk->sk_receive_queue)) break; - err = sock_intr_errno(timeo); - if (signal_pending(current)) - break; err = -EAGAIN; if (!timeo) break; + err = sock_intr_errno(timeo); + if (signal_pending(current)) + break; } finish_wait(sk_sleep(sk), &wait); *timeop = timeo; @@ -2026,12 +2026,12 @@ static int tipc_wait_for_accept(struct socket *sock, long timeo) err = -EINVAL; if (sock->state != SS_LISTENING) break; - err = sock_intr_errno(timeo); - if (signal_pending(current)) - break; err = -EAGAIN; if (!timeo) break; + err = sock_intr_errno(timeo); + if (signal_pending(current)) + break; } finish_wait(sk_sleep(sk), &wait); return err; -- GitLab From 208d51154c8d7f2c3808b4401132233c5ab21572 Mon Sep 17 00:00:00 2001 From: Valentin Rothberg Date: Wed, 25 Feb 2015 15:15:23 +0100 Subject: [PATCH 03606/11651] checkkconfigsymbols.py: filter reports for tools/ Recent changes to the build system of tools suggest to filter reports for the entire tools directory. Various C preprocessor identifiers are prefixed with CONFIG_ but are NOT defined in Kconfig but in Makefiles in the tools directory. Such identifiers are false positives for most static analysis tools (i.e., scripts/checkkconfigsymbols.py) since the CONFIG_ prefix and the _MODULE suffix is reserved for Kconfig features in CPP and Make syntax. Signed-off-by: Valentin Rothberg Signed-off-by: Greg Kroah-Hartman --- scripts/checkkconfigsymbols.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) mode change 100644 => 100755 scripts/checkkconfigsymbols.py diff --git a/scripts/checkkconfigsymbols.py b/scripts/checkkconfigsymbols.py old mode 100644 new mode 100755 index e9cc689033fe..6445693df669 --- a/scripts/checkkconfigsymbols.py +++ b/scripts/checkkconfigsymbols.py @@ -2,7 +2,7 @@ """Find Kconfig identifiers that are referenced but not defined.""" -# (c) 2014 Valentin Rothberg +# (c) 2014-2015 Valentin Rothberg # (c) 2014 Stefan Hengelein # # Licensed under the terms of the GNU GPL License version 2 @@ -46,8 +46,9 @@ def main(): stdout = stdout[:-1] for gitfile in stdout.rsplit("\n"): - if ".git" in gitfile or "ChangeLog" in gitfile or \ - ".log" in gitfile or os.path.isdir(gitfile): + if ".git" in gitfile or "ChangeLog" in gitfile or \ + ".log" in gitfile or os.path.isdir(gitfile) or \ + gitfile.startswith("tools/"): continue if REGEX_FILE_KCONFIG.match(gitfile): kconfig_files.append(gitfile) -- GitLab From 26c459a8072f2bb0680081205376e1371c114b12 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 9 Mar 2015 12:54:48 +0100 Subject: [PATCH 03607/11651] mpls: Spelling: s/conceved/conceived/, s/as/a/ Signed-off-by: Geert Uytterhoeven Acked-by: "Eric W. Biederman" Signed-off-by: David S. Miller --- net/mpls/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/mpls/Kconfig b/net/mpls/Kconfig index f4286ee7e2b0..dfca485863e9 100644 --- a/net/mpls/Kconfig +++ b/net/mpls/Kconfig @@ -7,9 +7,9 @@ menuconfig MPLS default n ---help--- MultiProtocol Label Switching routes packets through logical - circuits. Originally conceved as a way of routing packets at + circuits. Originally conceived as a way of routing packets at hardware speeds (before hardware was capable of routing ipv4 packets), - MPLS remains as simple way of making tunnels. + MPLS remains a simple way of making tunnels. If you have not heard of MPLS you probably want to say N here. -- GitLab From 0b2eb3e9bc738c23784b9281dd035ee0b450d98a Mon Sep 17 00:00:00 2001 From: Josh Cartwright Date: Mon, 9 Mar 2015 11:14:39 -0500 Subject: [PATCH 03608/11651] net: macb: constify macb configuration data The configurations are not modified by the driver. Make them 'const' so that they may be placed in a read-only section. Signed-off-by: Josh Cartwright Signed-off-by: David S. Miller --- drivers/net/ethernet/cadence/macb.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c index ad76b8e35a00..81d41539fcba 100644 --- a/drivers/net/ethernet/cadence/macb.c +++ b/drivers/net/ethernet/cadence/macb.c @@ -2113,17 +2113,17 @@ static const struct net_device_ops macb_netdev_ops = { }; #if defined(CONFIG_OF) -static struct macb_config pc302gem_config = { +static const struct macb_config pc302gem_config = { .caps = MACB_CAPS_SG_DISABLED | MACB_CAPS_GIGABIT_MODE_AVAILABLE, .dma_burst_length = 16, }; -static struct macb_config sama5d3_config = { +static const struct macb_config sama5d3_config = { .caps = MACB_CAPS_SG_DISABLED | MACB_CAPS_GIGABIT_MODE_AVAILABLE, .dma_burst_length = 16, }; -static struct macb_config sama5d4_config = { +static const struct macb_config sama5d4_config = { .caps = 0, .dma_burst_length = 4, }; @@ -2154,7 +2154,7 @@ static void macb_configure_caps(struct macb *bp) if (bp->pdev->dev.of_node) { match = of_match_node(macb_dt_ids, bp->pdev->dev.of_node); if (match && match->data) { - config = (const struct macb_config *)match->data; + config = match->data; bp->caps = config->caps; /* -- GitLab From ddb3b6033ca68d71a5f0611b58b2642729342245 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Mon, 9 Mar 2015 13:14:37 -0500 Subject: [PATCH 03609/11651] net: Remove protocol from struct dst_ops After my change to neigh_hh_init to obtain the protocol from the neigh_table there are no more users of protocol in struct dst_ops. Remove the protocol field from dst_ops and all of it's initializers. Signed-off-by: "Eric W. Biederman" Signed-off-by: David S. Miller --- include/net/dst_ops.h | 1 - net/bridge/br_nf_core.c | 1 - net/decnet/dn_route.c | 1 - net/ipv4/route.c | 2 -- net/ipv4/xfrm4_policy.c | 1 - net/ipv6/route.c | 2 -- net/ipv6/xfrm6_policy.c | 1 - 7 files changed, 9 deletions(-) diff --git a/include/net/dst_ops.h b/include/net/dst_ops.h index 1f99a1de0e4f..d64253914a6a 100644 --- a/include/net/dst_ops.h +++ b/include/net/dst_ops.h @@ -12,7 +12,6 @@ struct sock; struct dst_ops { unsigned short family; - __be16 protocol; unsigned int gc_thresh; int (*gc)(struct dst_ops *ops); diff --git a/net/bridge/br_nf_core.c b/net/bridge/br_nf_core.c index 387cb3bd017c..20cbb727df4d 100644 --- a/net/bridge/br_nf_core.c +++ b/net/bridge/br_nf_core.c @@ -54,7 +54,6 @@ static unsigned int fake_mtu(const struct dst_entry *dst) static struct dst_ops fake_dst_ops = { .family = AF_INET, - .protocol = cpu_to_be16(ETH_P_IP), .update_pmtu = fake_update_pmtu, .redirect = fake_redirect, .cow_metrics = fake_cow_metrics, diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index 771815575dbd..9ab0c4ba297f 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c @@ -136,7 +136,6 @@ int decnet_dst_gc_interval = 2; static struct dst_ops dn_dst_ops = { .family = PF_DECnet, - .protocol = cpu_to_be16(ETH_P_DNA_RT), .gc_thresh = 128, .gc = dn_dst_gc, .check = dn_dst_check, diff --git a/net/ipv4/route.c b/net/ipv4/route.c index ad5064362c5c..649c8a3f0189 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -152,7 +152,6 @@ static struct neighbour *ipv4_neigh_lookup(const struct dst_entry *dst, static struct dst_ops ipv4_dst_ops = { .family = AF_INET, - .protocol = cpu_to_be16(ETH_P_IP), .check = ipv4_dst_check, .default_advmss = ipv4_default_advmss, .mtu = ipv4_mtu, @@ -2225,7 +2224,6 @@ static u32 *ipv4_rt_blackhole_cow_metrics(struct dst_entry *dst, static struct dst_ops ipv4_dst_blackhole_ops = { .family = AF_INET, - .protocol = cpu_to_be16(ETH_P_IP), .check = ipv4_blackhole_dst_check, .mtu = ipv4_blackhole_mtu, .default_advmss = ipv4_default_advmss, diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index 6156f68a1e90..c224c856247b 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c @@ -232,7 +232,6 @@ static void xfrm4_dst_ifdown(struct dst_entry *dst, struct net_device *dev, static struct dst_ops xfrm4_dst_ops = { .family = AF_INET, - .protocol = cpu_to_be16(ETH_P_IP), .gc = xfrm4_garbage_collect, .update_pmtu = xfrm4_update_pmtu, .redirect = xfrm4_redirect, diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 4688bd4d7f59..06fa819c43c9 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -194,7 +194,6 @@ static struct neighbour *ip6_neigh_lookup(const struct dst_entry *dst, static struct dst_ops ip6_dst_ops_template = { .family = AF_INET6, - .protocol = cpu_to_be16(ETH_P_IPV6), .gc = ip6_dst_gc, .gc_thresh = 1024, .check = ip6_dst_check, @@ -236,7 +235,6 @@ static u32 *ip6_rt_blackhole_cow_metrics(struct dst_entry *dst, static struct dst_ops ip6_dst_blackhole_ops = { .family = AF_INET6, - .protocol = cpu_to_be16(ETH_P_IPV6), .destroy = ip6_dst_destroy, .check = ip6_dst_check, .mtu = ip6_blackhole_mtu, diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index 48bf5a06847b..8ddf2b545151 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c @@ -292,7 +292,6 @@ static void xfrm6_dst_ifdown(struct dst_entry *dst, struct net_device *dev, static struct dst_ops xfrm6_dst_ops = { .family = AF_INET6, - .protocol = cpu_to_be16(ETH_P_IPV6), .gc = xfrm6_garbage_collect, .update_pmtu = xfrm6_update_pmtu, .redirect = xfrm6_redirect, -- GitLab From 115403df818abf1e84c3554b14c8e0f8746bf3a6 Mon Sep 17 00:00:00 2001 From: Jon Paul Maloy Date: Mon, 9 Mar 2015 14:44:13 -0400 Subject: [PATCH 03610/11651] tipc: Add Ying Xue to TIPC maintainers list We remove Allan Stephens, who has moved on to other tasks, from the TIPC maintainers list. He is replaced by Ying Xue, who has been doing the maintenance on behalf of WindRiver since almost three years. Acked-by: Ying Xue Acked-by: Allan Stephens Signed-off-by: Jon Maloy Signed-off-by: David S. Miller --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index a6ae6eb0c545..89425367bf09 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9800,7 +9800,7 @@ F: include/linux/wl12xx.h TIPC NETWORK LAYER M: Jon Maloy -M: Allan Stephens +M: Ying Xue L: netdev@vger.kernel.org (core kernel code) L: tipc-discussion@lists.sourceforge.net (user apps, general discussion) W: http://tipc.sourceforge.net/ -- GitLab From 82f17091e68254d1612b42cf23291cad63cfaf04 Mon Sep 17 00:00:00 2001 From: Francesco Ruggeri Date: Mon, 9 Mar 2015 11:51:04 -0700 Subject: [PATCH 03611/11651] net: delete stale packet_mclist entries When an interface is deleted from a net namespace the ifindex in the corresponding entries in PF_PACKET sockets' mclists becomes stale. This can create inconsistencies if later an interface with the same ifindex is moved from a different namespace (not that unlikely since ifindexes are per-namespace). In particular we saw problems with dev->promiscuity, resulting in "promiscuity touches roof, set promiscuity failed. promiscuity feature of device might be broken" warnings and EOVERFLOW failures of setsockopt(PACKET_ADD_MEMBERSHIP). This patch deletes the mclist entries for interfaces that are deleted. Since this now causes setsockopt(PACKET_DROP_MEMBERSHIP) to fail with EADDRNOTAVAIL if called after the interface is deleted, also make packet_mc_drop not fail. Signed-off-by: Francesco Ruggeri Signed-off-by: David S. Miller --- net/packet/af_packet.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 5bf1e968a728..f8db7064d81c 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -3123,11 +3123,18 @@ static int packet_dev_mc(struct net_device *dev, struct packet_mclist *i, return 0; } -static void packet_dev_mclist(struct net_device *dev, struct packet_mclist *i, int what) +static void packet_dev_mclist_delete(struct net_device *dev, + struct packet_mclist **mlp) { - for ( ; i; i = i->next) { - if (i->ifindex == dev->ifindex) - packet_dev_mc(dev, i, what); + struct packet_mclist *ml; + + while ((ml = *mlp) != NULL) { + if (ml->ifindex == dev->ifindex) { + packet_dev_mc(dev, ml, -1); + *mlp = ml->next; + kfree(ml); + } else + mlp = &ml->next; } } @@ -3204,12 +3211,11 @@ static int packet_mc_drop(struct sock *sk, struct packet_mreq_max *mreq) packet_dev_mc(dev, ml, -1); kfree(ml); } - rtnl_unlock(); - return 0; + break; } } rtnl_unlock(); - return -EADDRNOTAVAIL; + return 0; } static void packet_flush_mclist(struct sock *sk) @@ -3559,7 +3565,7 @@ static int packet_notifier(struct notifier_block *this, switch (msg) { case NETDEV_UNREGISTER: if (po->mclist) - packet_dev_mclist(dev, po->mclist, -1); + packet_dev_mclist_delete(dev, &po->mclist); /* fallthrough */ case NETDEV_DOWN: -- GitLab From e6441bae326271090755e1707196ad05aa1dc703 Mon Sep 17 00:00:00 2001 From: Jon Paul Maloy Date: Mon, 9 Mar 2015 16:16:22 -0400 Subject: [PATCH 03612/11651] tipc: fix bug in link failover handling In commit c637c1035534867b85b78b453c38c495b58e2c5a ("tipc: resolve race problem at unicast message reception") we introduced a new mechanism for delivering buffers upwards from link to socket layer. That code contains a bug in how we handle the new link input queue during failover. When a link is reset, some of its users may be blocked because of congestion, and in order to resolve this, we add any pending wakeup pseudo messages to the link's input queue, and deliver them to the socket. This misses the case where the other, remaining link also may have congested users. Currently, the owner node's reference to the remaining link's input queue is unconditionally overwritten by the reset link's input queue. This has the effect that wakeup events from the remaining link may be unduely delayed (but not lost) for a potentially long period. We fix this by adding the pending events from the reset link to the input queue that is currently referenced by the node, whichever one it is. This commit should be applied to both net and net-next. Signed-off-by: Jon Maloy Signed-off-by: David S. Miller --- net/tipc/link.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/net/tipc/link.c b/net/tipc/link.c index a4cf364316de..14f09b3cb87c 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -464,10 +464,11 @@ void tipc_link_reset(struct tipc_link *l_ptr) /* Clean up all queues, except inputq: */ __skb_queue_purge(&l_ptr->outqueue); __skb_queue_purge(&l_ptr->deferred_queue); - skb_queue_splice_init(&l_ptr->wakeupq, &l_ptr->inputq); - if (!skb_queue_empty(&l_ptr->inputq)) + if (!owner->inputq) + owner->inputq = &l_ptr->inputq; + skb_queue_splice_init(&l_ptr->wakeupq, owner->inputq); + if (!skb_queue_empty(owner->inputq)) owner->action_flags |= TIPC_MSG_EVT; - owner->inputq = &l_ptr->inputq; l_ptr->next_out = NULL; l_ptr->unacked_window = 0; l_ptr->checkpoint = 1; -- GitLab From ca1bb4ee4c3a017bb66840d11d5efdf4e8f3f66d Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Mon, 23 Feb 2015 16:11:41 -0800 Subject: [PATCH 03613/11651] leds: Introduce devres helper for led_classdev_register (cooloney@gmail.com: add _unregister function into the document) Suggested-by: Stephen Boyd Signed-off-by: Bjorn Andersson Signed-off-by: Bryan Wu --- Documentation/driver-model/devres.txt | 4 ++ drivers/leds/led-class.c | 57 +++++++++++++++++++++++++++ include/linux/leds.h | 4 ++ 3 files changed, 65 insertions(+) diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt index 6d1e8eeb5990..e1e2bbd7a404 100644 --- a/Documentation/driver-model/devres.txt +++ b/Documentation/driver-model/devres.txt @@ -289,6 +289,10 @@ IRQ devm_request_irq() devm_request_threaded_irq() +LED + devm_led_classdev_register() + devm_led_classdev_unregister() + MDIO devm_mdiobus_alloc() devm_mdiobus_alloc_size() diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index 795ec994c663..768d33a79881 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c @@ -288,6 +288,63 @@ void led_classdev_unregister(struct led_classdev *led_cdev) } EXPORT_SYMBOL_GPL(led_classdev_unregister); +static void devm_led_classdev_release(struct device *dev, void *res) +{ + led_classdev_unregister(*(struct led_classdev **)res); +} + +/** + * devm_led_classdev_register - resource managed led_classdev_register() + * @parent: The device to register. + * @led_cdev: the led_classdev structure for this device. + */ +int devm_led_classdev_register(struct device *parent, + struct led_classdev *led_cdev) +{ + struct led_classdev **dr; + int rc; + + dr = devres_alloc(devm_led_classdev_release, sizeof(*dr), GFP_KERNEL); + if (!dr) + return -ENOMEM; + + rc = led_classdev_register(parent, led_cdev); + if (rc) { + devres_free(dr); + return rc; + } + + *dr = led_cdev; + devres_add(parent, dr); + + return 0; +} +EXPORT_SYMBOL_GPL(devm_led_classdev_register); + +static int devm_led_classdev_match(struct device *dev, void *res, void *data) +{ + struct led_cdev **p = res; + + if (WARN_ON(!p || !*p)) + return 0; + + return *p == data; +} + +/** + * devm_led_classdev_unregister() - resource managed led_classdev_unregister() + * @parent: The device to unregister. + * @led_cdev: the led_classdev structure for this device. + */ +void devm_led_classdev_unregister(struct device *dev, + struct led_classdev *led_cdev) +{ + WARN_ON(devres_release(dev, + devm_led_classdev_release, + devm_led_classdev_match, led_cdev)); +} +EXPORT_SYMBOL_GPL(devm_led_classdev_unregister); + static int __init leds_init(void) { leds_class = class_create(THIS_MODULE, "leds"); diff --git a/include/linux/leds.h b/include/linux/leds.h index f70f84f35674..ed634279062e 100644 --- a/include/linux/leds.h +++ b/include/linux/leds.h @@ -105,7 +105,11 @@ struct led_classdev { extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev); +extern int devm_led_classdev_register(struct device *parent, + struct led_classdev *led_cdev); extern void led_classdev_unregister(struct led_classdev *led_cdev); +extern void devm_led_classdev_unregister(struct device *parent, + struct led_classdev *led_cdev); extern void led_classdev_suspend(struct led_classdev *led_cdev); extern void led_classdev_resume(struct led_classdev *led_cdev); -- GitLab From da321133b53caf7889ed3ca1dabe4cc368db2604 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Sat, 21 Feb 2015 11:40:23 +0100 Subject: [PATCH 03614/11651] clk: divider: fix calculation of maximal parent rate for a given divider MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The rate provided at the output of a clk-divider is calculated as: DIV_ROUND_UP(parent_rate, div) since commit b11d282dbea2 (clk: divider: fix rate calculation for fractional rates). So to yield a rate not bigger than r parent_rate must be <= r * div. The effect of choosing a parent rate that is too big as was done before this patch results in wrongly ruling out good dividers. Note that this is not a complete fix as __clk_round_rate might return a value >= its 2nd parameter. Also for dividers with CLK_DIVIDER_ROUND_CLOSEST set the calculation is not accurate. But this fixes the test case by Sascha Hauer that uses a chain of three dividers under a fixed clock. Fixes: b11d282dbea2 (clk: divider: fix rate calculation for fractional rates) Suggested-by: Sascha Hauer Signed-off-by: Uwe Kleine-König Acked-by: Sascha Hauer Signed-off-by: Michael Turquette --- drivers/clk/clk-divider.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c index eff8a862eb08..a1a029092c8d 100644 --- a/drivers/clk/clk-divider.c +++ b/drivers/clk/clk-divider.c @@ -144,12 +144,6 @@ static unsigned long clk_divider_recalc_rate(struct clk_hw *hw, divider->flags); } -/* - * The reverse of DIV_ROUND_UP: The maximum number which - * divided by m is r - */ -#define MULT_ROUND_UP(r, m) ((r) * (m) + (m) - 1) - static bool _is_valid_table_div(const struct clk_div_table *table, unsigned int div) { @@ -313,7 +307,7 @@ static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate, return i; } parent_rate = __clk_round_rate(__clk_get_parent(hw->clk), - MULT_ROUND_UP(rate, i)); + rate * i); now = DIV_ROUND_UP(parent_rate, i); if (_is_best_div(rate, now, best, flags)) { bestdiv = i; -- GitLab From 26bac95aa88c2b1747808c0b885abe7814c0165d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Sat, 21 Feb 2015 11:40:24 +0100 Subject: [PATCH 03615/11651] clk: divider: fix selection of divider when rounding to closest MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's an invalid approach to assume that among two divider values the one nearer the exact divider is the better one. Assume a parent rate of 1000 Hz, a divider with CLK_DIVIDER_POWER_OF_TWO and a target rate of 89 Hz. The exact divider is ~ 11.236 so 8 and 16 are the candidates to choose from yielding rates 125 Hz and 62.5 Hz respectivly. While 8 is nearer to 11.236 than 16 is, the latter is still the better divider as 62.5 is nearer to 89 than 125 is. Fixes: 774b514390b1 (clk: divider: Add round to closest divider) Signed-off-by: Uwe Kleine-König Acked-by: Sascha Hauer Acked-by: Maxime Coquelin Signed-off-by: Michael Turquette --- drivers/clk/clk-divider.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c index a1a029092c8d..78b2e656ff6a 100644 --- a/drivers/clk/clk-divider.c +++ b/drivers/clk/clk-divider.c @@ -220,6 +220,7 @@ static int _div_round_closest(const struct clk_div_table *table, unsigned long flags) { int up, down, div; + unsigned long up_rate, down_rate; up = down = div = DIV_ROUND_CLOSEST(parent_rate, rate); @@ -231,7 +232,10 @@ static int _div_round_closest(const struct clk_div_table *table, down = _round_down_table(table, div); } - return (up - div) <= (div - down) ? up : down; + up_rate = DIV_ROUND_UP(parent_rate, up); + down_rate = DIV_ROUND_UP(parent_rate, down); + + return (rate - up_rate) <= (down_rate - rate) ? up : down; } static int _div_round(const struct clk_div_table *table, -- GitLab From 9315514252a95bca37be3ef8a93f835ed91c2855 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Sat, 21 Feb 2015 11:40:25 +0100 Subject: [PATCH 03616/11651] clk: divider: fix calculation of initial best divider when rounding to closest MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Similar to the reasoning for the previous commit DIV_ROUND_CLOSEST(parent_rate, rate) might not be the best integer divisor to get a good approximation for rate from parent_rate (given the metric for CLK_DIVIDER_ROUND_CLOSEST). For example assume a parent rate of 1000 Hz and a target rate of 700. Using DIV_ROUND_CLOSEST the suggested divisor gets calculated to 1 resulting in a target rate of 1000 with a delta of 300 to the desired rate. With choosing 2 as divisor however the resulting rate is 500 which is nearer to 700. Signed-off-by: Uwe Kleine-König Acked-by: Sascha Hauer Acked-by: Maxime Coquelin Signed-off-by: Michael Turquette --- drivers/clk/clk-divider.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c index 78b2e656ff6a..25006a8bb8e6 100644 --- a/drivers/clk/clk-divider.c +++ b/drivers/clk/clk-divider.c @@ -219,17 +219,18 @@ static int _div_round_closest(const struct clk_div_table *table, unsigned long parent_rate, unsigned long rate, unsigned long flags) { - int up, down, div; + int up, down; unsigned long up_rate, down_rate; - up = down = div = DIV_ROUND_CLOSEST(parent_rate, rate); + up = DIV_ROUND_UP(parent_rate, rate); + down = parent_rate / rate; if (flags & CLK_DIVIDER_POWER_OF_TWO) { - up = __roundup_pow_of_two(div); - down = __rounddown_pow_of_two(div); + up = __roundup_pow_of_two(up); + down = __rounddown_pow_of_two(down); } else if (table) { - up = _round_up_table(table, div); - down = _round_down_table(table, div); + up = _round_up_table(table, up); + down = _round_down_table(table, down); } up_rate = DIV_ROUND_UP(parent_rate, up); -- GitLab From 3a656b54c8433ada6dd7ee6227854c48682d5e4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 9 Mar 2015 21:08:37 +0200 Subject: [PATCH 03617/11651] drm/i915: Fix struct_mutex deadlock due to merge fumble MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit a8c6ecb3be7029881f7c95e5e201a629094a4e1a Merge: 8dd0eb35 9eccca0 Author: Dave Airlie Date: Mon Mar 9 19:58:30 2015 +1000 Merge tag 'v4.0-rc3' into drm-next managed to pick the wrong code to resolve the conflict and left us with a mutex_lock(struct_mutex) without the mutex_unlock(struct_mutex) leading to a deadlock. Fix the problem by recovering the correct code which doesn't need the lock. Cc: Dave Airlie Signed-off-by: Ville Syrjälä Signed-off-by: Dave Airlie --- drivers/gpu/drm/i915/intel_display.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 31f3b11589b9..1aa1cbd16c19 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -12295,9 +12295,7 @@ intel_check_cursor_plane(struct drm_plane *plane, return -ENOMEM; } - /* we only need to pin inside GTT if cursor is non-phy */ - mutex_lock(&dev->struct_mutex); - if (!INTEL_INFO(dev)->cursor_needs_physical && obj->tiling_mode) { + if (fb->modifier[0] != DRM_FORMAT_MOD_NONE) { DRM_DEBUG_KMS("cursor cannot be tiled\n"); ret = -EINVAL; } -- GitLab From fcf0789a96777d79d20290e08bf43943a5619387 Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Fri, 6 Mar 2015 15:48:38 +0200 Subject: [PATCH 03618/11651] ACPI / LPSS: provide con_id for the clkdev Commit 7d78cbefaa (serial: 8250_dw: add ability to handle the peripheral clock) introduces handling for a second clk to 8250_dw.c which is the driver also for LPSS UART. The second clk forces us to provide identifier (con_id) for the clkdev we create. This fixes an issue where 8250_dw.c is getting the same handler for both clocks. Fixes: 7d78cbefaa (serial: 8250_dw: add ability to handle the peripheral clock) Signed-off-by: Heikki Krogerus Cc: 3.17+ # 3.17+ Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpi_lpss.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c index 657964e8ab7e..37fb19047603 100644 --- a/drivers/acpi/acpi_lpss.c +++ b/drivers/acpi/acpi_lpss.c @@ -65,6 +65,7 @@ struct lpss_private_data; struct lpss_device_desc { unsigned int flags; + const char *clk_con_id; unsigned int prv_offset; size_t prv_size_override; void (*setup)(struct lpss_private_data *pdata); @@ -140,6 +141,7 @@ static struct lpss_device_desc lpt_i2c_dev_desc = { static struct lpss_device_desc lpt_uart_dev_desc = { .flags = LPSS_CLK | LPSS_CLK_GATE | LPSS_CLK_DIVIDER | LPSS_LTR, + .clk_con_id = "baudclk", .prv_offset = 0x800, .setup = lpss_uart_setup, }; @@ -156,6 +158,7 @@ static struct lpss_device_desc byt_pwm_dev_desc = { static struct lpss_device_desc byt_uart_dev_desc = { .flags = LPSS_CLK | LPSS_CLK_GATE | LPSS_CLK_DIVIDER | LPSS_SAVE_CTX, + .clk_con_id = "baudclk", .prv_offset = 0x800, .setup = lpss_uart_setup, }; @@ -313,7 +316,7 @@ out: return PTR_ERR(clk); pdata->clk = clk; - clk_register_clkdev(clk, NULL, devname); + clk_register_clkdev(clk, dev_desc->clk_con_id, devname); return 0; } -- GitLab From 3535a3c126651616a111491726c241e801fd9418 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Fri, 27 Feb 2015 14:48:15 +0800 Subject: [PATCH 03619/11651] ACPI / EC: Cleanup logging/debugging splitter support. This patch refines logging/debugging splitter support so that when DEBUG is disabled, splitters won't be visible in the kernel logs while they are still available for developers when DEBUG is enabled. This patch also refines the splitters to mark the following handling process boundaries: +++++: boundary of driver starting/stopping boundary of IRQ storming =====: boundary of transaction advancement *****: boundary of EC command boundary of EC query #####: boundary of EC _Qxx evaluation The following 2 log entries are originally logged using pr_info() in order to be used as the boot/suspend/resume log entries for the EC device, this patch also restores them to pr_info() logging level: ACPI : EC: EC started ACPI : EC: EC stopped In this patch, one log entry around "Polling quirk" is converted into ec_dbg_raw() which doesn't contain the boundary marker. Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/ec.c | 108 +++++++++++++++++++++++++++++++--------------- 1 file changed, 74 insertions(+), 34 deletions(-) diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index a8dd2f763382..07426c8c255b 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -136,6 +136,48 @@ static int EC_FLAGS_SKIP_DSDT_SCAN; /* Not all BIOS survive early DSDT scan */ static int EC_FLAGS_CLEAR_ON_RESUME; /* Needs acpi_ec_clear() on boot/resume */ static int EC_FLAGS_QUERY_HANDSHAKE; /* Needs QR_EC issued when SCI_EVT set */ +/* -------------------------------------------------------------------------- + * Logging/Debugging + * -------------------------------------------------------------------------- */ + +/* + * Splitters used by the developers to track the boundary of the EC + * handling processes. + */ +#ifdef DEBUG +#define EC_DBG_SEP " " +#define EC_DBG_DRV "+++++" +#define EC_DBG_STM "=====" +#define EC_DBG_REQ "*****" +#define EC_DBG_EVT "#####" +#else +#define EC_DBG_SEP "" +#define EC_DBG_DRV +#define EC_DBG_STM +#define EC_DBG_REQ +#define EC_DBG_EVT +#endif + +#define ec_log_raw(fmt, ...) \ + pr_info(fmt "\n", ##__VA_ARGS__) +#define ec_dbg_raw(fmt, ...) \ + pr_debug(fmt "\n", ##__VA_ARGS__) +#define ec_log(filter, fmt, ...) \ + ec_log_raw(filter EC_DBG_SEP fmt EC_DBG_SEP filter, ##__VA_ARGS__) +#define ec_dbg(filter, fmt, ...) \ + ec_dbg_raw(filter EC_DBG_SEP fmt EC_DBG_SEP filter, ##__VA_ARGS__) + +#define ec_log_drv(fmt, ...) \ + ec_log(EC_DBG_DRV, fmt, ##__VA_ARGS__) +#define ec_dbg_drv(fmt, ...) \ + ec_dbg(EC_DBG_DRV, fmt, ##__VA_ARGS__) +#define ec_dbg_stm(fmt, ...) \ + ec_dbg(EC_DBG_STM, fmt, ##__VA_ARGS__) +#define ec_dbg_req(fmt, ...) \ + ec_dbg(EC_DBG_REQ, fmt, ##__VA_ARGS__) +#define ec_dbg_evt(fmt, ...) \ + ec_dbg(EC_DBG_EVT, fmt, ##__VA_ARGS__) + /* -------------------------------------------------------------------------- * Device Flags * -------------------------------------------------------------------------- */ @@ -159,14 +201,14 @@ static inline u8 acpi_ec_read_status(struct acpi_ec *ec) { u8 x = inb(ec->command_addr); - pr_debug("EC_SC(R) = 0x%2.2x " - "SCI_EVT=%d BURST=%d CMD=%d IBF=%d OBF=%d\n", - x, - !!(x & ACPI_EC_FLAG_SCI), - !!(x & ACPI_EC_FLAG_BURST), - !!(x & ACPI_EC_FLAG_CMD), - !!(x & ACPI_EC_FLAG_IBF), - !!(x & ACPI_EC_FLAG_OBF)); + ec_dbg_raw("EC_SC(R) = 0x%2.2x " + "SCI_EVT=%d BURST=%d CMD=%d IBF=%d OBF=%d", + x, + !!(x & ACPI_EC_FLAG_SCI), + !!(x & ACPI_EC_FLAG_BURST), + !!(x & ACPI_EC_FLAG_CMD), + !!(x & ACPI_EC_FLAG_IBF), + !!(x & ACPI_EC_FLAG_OBF)); return x; } @@ -175,20 +217,20 @@ static inline u8 acpi_ec_read_data(struct acpi_ec *ec) u8 x = inb(ec->data_addr); ec->curr->timestamp = jiffies; - pr_debug("EC_DATA(R) = 0x%2.2x\n", x); + ec_dbg_raw("EC_DATA(R) = 0x%2.2x", x); return x; } static inline void acpi_ec_write_cmd(struct acpi_ec *ec, u8 command) { - pr_debug("EC_SC(W) = 0x%2.2x\n", command); + ec_dbg_raw("EC_SC(W) = 0x%2.2x", command); outb(command, ec->command_addr); ec->curr->timestamp = jiffies; } static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data) { - pr_debug("EC_DATA(W) = 0x%2.2x\n", data); + ec_dbg_raw("EC_DATA(W) = 0x%2.2x", data); outb(data, ec->data_addr); ec->curr->timestamp = jiffies; } @@ -240,7 +282,7 @@ static inline void acpi_ec_enable_gpe(struct acpi_ec *ec, bool open) * software need to manually trigger a pseudo GPE event on * EN=1 writes. */ - pr_debug("***** Polling quirk *****\n"); + ec_dbg_raw("Polling quirk"); advance_transaction(ec); } } @@ -299,7 +341,7 @@ static void acpi_ec_set_storm(struct acpi_ec *ec, u8 flag) { if (!test_bit(flag, &ec->flags)) { acpi_ec_disable_gpe(ec, false); - pr_debug("+++++ Polling enabled +++++\n"); + ec_dbg_drv("Polling enabled"); set_bit(flag, &ec->flags); } } @@ -309,7 +351,7 @@ static void acpi_ec_clear_storm(struct acpi_ec *ec, u8 flag) if (test_bit(flag, &ec->flags)) { clear_bit(flag, &ec->flags); acpi_ec_enable_gpe(ec, false); - pr_debug("+++++ Polling disabled +++++\n"); + ec_dbg_drv("Polling disabled"); } } @@ -335,7 +377,7 @@ static bool acpi_ec_submit_flushable_request(struct acpi_ec *ec) static void acpi_ec_submit_query(struct acpi_ec *ec) { if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) { - pr_debug("***** Event started *****\n"); + ec_dbg_req("Event started"); schedule_work(&ec->work); } } @@ -344,7 +386,7 @@ static void acpi_ec_complete_query(struct acpi_ec *ec) { if (ec->curr->command == ACPI_EC_COMMAND_QUERY) { clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); - pr_debug("***** Event stopped *****\n"); + ec_dbg_req("Event stopped"); } } @@ -366,8 +408,8 @@ static void advance_transaction(struct acpi_ec *ec) u8 status; bool wakeup = false; - pr_debug("===== %s (%d) =====\n", - in_interrupt() ? "IRQ" : "TASK", smp_processor_id()); + ec_dbg_stm("%s (%d)", in_interrupt() ? "IRQ" : "TASK", + smp_processor_id()); /* * By always clearing STS before handling all indications, we can * ensure a hardware STS 0->1 change after this clearing can always @@ -390,8 +432,8 @@ static void advance_transaction(struct acpi_ec *ec) if (t->rlen == t->ri) { t->flags |= ACPI_EC_COMMAND_COMPLETE; if (t->command == ACPI_EC_COMMAND_QUERY) - pr_debug("***** Command(%s) hardware completion *****\n", - acpi_ec_cmd_string(t->command)); + ec_dbg_req("Command(%s) hardware completion", + acpi_ec_cmd_string(t->command)); wakeup = true; } } else @@ -410,8 +452,8 @@ static void advance_transaction(struct acpi_ec *ec) acpi_ec_complete_query(ec); t->rdata[t->ri++] = 0x00; t->flags |= ACPI_EC_COMMAND_COMPLETE; - pr_debug("***** Command(%s) software completion *****\n", - acpi_ec_cmd_string(t->command)); + ec_dbg_req("Command(%s) software completion", + acpi_ec_cmd_string(t->command)); wakeup = true; } else if ((status & ACPI_EC_FLAG_IBF) == 0) { acpi_ec_write_cmd(ec, t->command); @@ -504,16 +546,14 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, } /* following two actions should be kept atomic */ ec->curr = t; - pr_debug("***** Command(%s) started *****\n", - acpi_ec_cmd_string(t->command)); + ec_dbg_req("Command(%s) started", acpi_ec_cmd_string(t->command)); start_transaction(ec); spin_unlock_irqrestore(&ec->lock, tmp); ret = ec_poll(ec); spin_lock_irqsave(&ec->lock, tmp); if (t->irq_count == ec_storm_threshold) acpi_ec_clear_storm(ec, EC_FLAGS_COMMAND_STORM); - pr_debug("***** Command(%s) stopped *****\n", - acpi_ec_cmd_string(t->command)); + ec_dbg_req("Command(%s) stopped", acpi_ec_cmd_string(t->command)); ec->curr = NULL; /* Disable GPE for command processing (IBF=0/OBF=1) */ acpi_ec_complete_request(ec); @@ -676,11 +716,11 @@ static void acpi_ec_start(struct acpi_ec *ec, bool resuming) spin_lock_irqsave(&ec->lock, flags); if (!test_and_set_bit(EC_FLAGS_STARTED, &ec->flags)) { - pr_debug("+++++ Starting EC +++++\n"); + ec_dbg_drv("Starting EC"); /* Enable GPE for event processing (SCI_EVT=1) */ if (!resuming) acpi_ec_submit_request(ec); - pr_debug("EC started\n"); + ec_log_drv("EC started"); } spin_unlock_irqrestore(&ec->lock, flags); } @@ -702,7 +742,7 @@ static void acpi_ec_stop(struct acpi_ec *ec, bool suspending) spin_lock_irqsave(&ec->lock, flags); if (acpi_ec_started(ec)) { - pr_debug("+++++ Stopping EC +++++\n"); + ec_dbg_drv("Stopping EC"); set_bit(EC_FLAGS_STOPPED, &ec->flags); spin_unlock_irqrestore(&ec->lock, flags); wait_event(ec->wait, acpi_ec_stopped(ec)); @@ -712,7 +752,7 @@ static void acpi_ec_stop(struct acpi_ec *ec, bool suspending) acpi_ec_complete_request(ec); clear_bit(EC_FLAGS_STARTED, &ec->flags); clear_bit(EC_FLAGS_STOPPED, &ec->flags); - pr_debug("EC stopped\n"); + ec_log_drv("EC stopped"); } spin_unlock_irqrestore(&ec->lock, flags); } @@ -824,12 +864,12 @@ static void acpi_ec_run(void *cxt) if (!handler) return; - pr_debug("##### Query(0x%02x) started #####\n", handler->query_bit); + ec_dbg_evt("Query(0x%02x) started", handler->query_bit); if (handler->func) handler->func(handler->data); else if (handler->handle) acpi_evaluate_object(handler->handle, NULL, NULL, NULL); - pr_debug("##### Query(0x%02x) stopped #####\n", handler->query_bit); + ec_dbg_evt("Query(0x%02x) stopped", handler->query_bit); acpi_ec_put_query_handler(handler); } @@ -861,8 +901,8 @@ static int acpi_ec_query(struct acpi_ec *ec, u8 *data) if (value == handler->query_bit) { /* have custom handler for this bit */ handler = acpi_ec_get_query_handler(handler); - pr_debug("##### Query(0x%02x) scheduled #####\n", - handler->query_bit); + ec_dbg_evt("Query(0x%02x) scheduled", + handler->query_bit); status = acpi_os_execute((handler->func) ? OSL_NOTIFY_HANDLER : OSL_GPE_HANDLER, acpi_ec_run, handler); -- GitLab From 770970f0b40a7c303765f0593acd4ceeb54831f7 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Fri, 27 Feb 2015 14:48:24 +0800 Subject: [PATCH 03620/11651] ACPI / EC: Add GPE reference counting debugging messages. This patch enhances debugging with the GPE reference count messages added. This kind of log entries can be used by the platform validators to validate if there is an EC transaction broken because of firmware/driver bugs. No functional changes. Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/ec.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 07426c8c255b..a362f20c6c8b 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -177,6 +177,8 @@ static int EC_FLAGS_QUERY_HANDSHAKE; /* Needs QR_EC issued when SCI_EVT set */ ec_dbg(EC_DBG_REQ, fmt, ##__VA_ARGS__) #define ec_dbg_evt(fmt, ...) \ ec_dbg(EC_DBG_EVT, fmt, ##__VA_ARGS__) +#define ec_dbg_ref(ec, fmt, ...) \ + ec_dbg_raw("%lu: " fmt, ec->reference_count, ## __VA_ARGS__) /* -------------------------------------------------------------------------- * Device Flags @@ -544,6 +546,7 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, ret = -EINVAL; goto unlock; } + ec_dbg_ref(ec, "Increase command"); /* following two actions should be kept atomic */ ec->curr = t; ec_dbg_req("Command(%s) started", acpi_ec_cmd_string(t->command)); @@ -557,6 +560,7 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, ec->curr = NULL; /* Disable GPE for command processing (IBF=0/OBF=1) */ acpi_ec_complete_request(ec); + ec_dbg_ref(ec, "Decrease command"); unlock: spin_unlock_irqrestore(&ec->lock, tmp); return ret; @@ -718,8 +722,10 @@ static void acpi_ec_start(struct acpi_ec *ec, bool resuming) if (!test_and_set_bit(EC_FLAGS_STARTED, &ec->flags)) { ec_dbg_drv("Starting EC"); /* Enable GPE for event processing (SCI_EVT=1) */ - if (!resuming) + if (!resuming) { acpi_ec_submit_request(ec); + ec_dbg_ref(ec, "Increase driver"); + } ec_log_drv("EC started"); } spin_unlock_irqrestore(&ec->lock, flags); @@ -748,8 +754,10 @@ static void acpi_ec_stop(struct acpi_ec *ec, bool suspending) wait_event(ec->wait, acpi_ec_stopped(ec)); spin_lock_irqsave(&ec->lock, flags); /* Disable GPE for event processing (SCI_EVT=1) */ - if (!suspending) + if (!suspending) { acpi_ec_complete_request(ec); + ec_dbg_ref(ec, "Decrease driver"); + } clear_bit(EC_FLAGS_STARTED, &ec->flags); clear_bit(EC_FLAGS_STOPPED, &ec->flags); ec_log_drv("EC stopped"); -- GitLab From 7b1a13228b321ea27bd53070bcd332417069ace8 Mon Sep 17 00:00:00 2001 From: Nan Li Date: Wed, 4 Mar 2015 18:48:35 +0800 Subject: [PATCH 03621/11651] ACPI / sysfs: Treat the count field of counter_show() as unsigned The count field is an unsigned 32bit value, and the counter_show() function should also treat it as a unsigned value. Otherwise the counter may show negative number as we found on a machine: ... gpe23: 0 invalid gpe24: -2071733 enabled gpe25: 0 invalid ... gpe_all: -2070980 sci: -2070949 Signed-off-by: Nan Li Signed-off-by: Lee, Chun-Yi Signed-off-by: Rafael J. Wysocki --- drivers/acpi/sysfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c index 13e577c80201..0876d77b3206 100644 --- a/drivers/acpi/sysfs.c +++ b/drivers/acpi/sysfs.c @@ -527,7 +527,7 @@ static ssize_t counter_show(struct kobject *kobj, acpi_irq_not_handled; all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_GPE].count = acpi_gpe_count; - size = sprintf(buf, "%8d", all_counters[index].count); + size = sprintf(buf, "%8u", all_counters[index].count); /* "gpe_all" or "sci" */ if (index >= num_gpes + ACPI_NUM_FIXED_EVENTS) -- GitLab From f13b2065de8147a1652b830ea5db961cf80c09df Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 9 Mar 2015 17:03:07 -0700 Subject: [PATCH 03622/11651] Input: i8042 - allow KBD and AUX ports to wake up from suspend-to-idle While registering serio device for i8042, mark them as wakeup-capable and check their user space wakeup settings in i8042_pm_suspend() and i8042_pm_resume() to enable or disable, respectively, their interrupts to wake up the system. This makes it possible to use the PC keyboard to wake up the system from suspend-to-idle, among other things, after writing "enabled" to the keyboard serio device's power/wakeup sysfs attribute. Signed-off-by: Rafael J. Wysocki Signed-off-by: Dmitry Torokhov --- drivers/input/serio/i8042.c | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index 986a71c614b0..cb5ece77fd7d 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c @@ -1162,13 +1162,32 @@ static int i8042_controller_resume(bool force_reset) static int i8042_pm_suspend(struct device *dev) { + int i; + i8042_controller_reset(true); + /* Set up serio interrupts for system wakeup. */ + for (i = 0; i < I8042_NUM_PORTS; i++) { + struct serio *serio = i8042_ports[i].serio; + + if (serio && device_may_wakeup(&serio->dev)) + enable_irq_wake(i8042_ports[i].irq); + } + return 0; } static int i8042_pm_resume(struct device *dev) { + int i; + + for (i = 0; i < I8042_NUM_PORTS; i++) { + struct serio *serio = i8042_ports[i].serio; + + if (serio && device_may_wakeup(&serio->dev)) + disable_irq_wake(i8042_ports[i].irq); + } + /* * On resume from S2R we always try to reset the controller * to bring it in a sane state. (In case of S2D we expect @@ -1300,13 +1319,16 @@ static void __init i8042_register_ports(void) int i; for (i = 0; i < I8042_NUM_PORTS; i++) { - if (i8042_ports[i].serio) { + struct serio *serio = i8042_ports[i].serio; + + if (serio) { printk(KERN_INFO "serio: %s at %#lx,%#lx irq %d\n", - i8042_ports[i].serio->name, + serio->name, (unsigned long) I8042_DATA_REG, (unsigned long) I8042_COMMAND_REG, i8042_ports[i].irq); - serio_register_port(i8042_ports[i].serio); + serio_register_port(serio); + device_set_wakeup_capable(&serio->dev, true); } } } -- GitLab From 94fdec768dc72a6993479f59a17daa413f30029e Mon Sep 17 00:00:00 2001 From: Jacek Anaszewski Date: Wed, 4 Mar 2015 08:14:22 -0800 Subject: [PATCH 03623/11651] leds: flash: Remove synchronized flash strobe feature Synchronized flash strobe feature has been considered not fitting for LED subsystem sysfs interface and thus is being removed. Signed-off-by: Jacek Anaszewski Acked-by: Kyungmin Park Cc: Richard Purdie Signed-off-by: Bryan Wu --- drivers/leds/led-class-flash.c | 82 --------------------------------- include/linux/led-class-flash.h | 14 ------ include/linux/leds.h | 1 - 3 files changed, 97 deletions(-) diff --git a/drivers/leds/led-class-flash.c b/drivers/leds/led-class-flash.c index 4a19fd44f93f..3b2573411a37 100644 --- a/drivers/leds/led-class-flash.c +++ b/drivers/leds/led-class-flash.c @@ -216,75 +216,6 @@ static ssize_t flash_fault_show(struct device *dev, } static DEVICE_ATTR_RO(flash_fault); -static ssize_t available_sync_leds_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct led_classdev *led_cdev = dev_get_drvdata(dev); - struct led_classdev_flash *fled_cdev = lcdev_to_flcdev(led_cdev); - char *pbuf = buf; - int i, buf_len; - - buf_len = sprintf(pbuf, "[0: none] "); - pbuf += buf_len; - - for (i = 0; i < fled_cdev->num_sync_leds; ++i) { - buf_len = sprintf(pbuf, "[%d: %s] ", i + 1, - fled_cdev->sync_leds[i]->led_cdev.name); - pbuf += buf_len; - } - - return sprintf(buf, "%s\n", buf); -} -static DEVICE_ATTR_RO(available_sync_leds); - -static ssize_t flash_sync_strobe_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t size) -{ - struct led_classdev *led_cdev = dev_get_drvdata(dev); - struct led_classdev_flash *fled_cdev = lcdev_to_flcdev(led_cdev); - unsigned long led_id; - ssize_t ret; - - mutex_lock(&led_cdev->led_access); - - if (led_sysfs_is_disabled(led_cdev)) { - ret = -EBUSY; - goto unlock; - } - - ret = kstrtoul(buf, 10, &led_id); - if (ret) - goto unlock; - - if (led_id > fled_cdev->num_sync_leds) { - ret = -ERANGE; - goto unlock; - } - - fled_cdev->sync_led_id = led_id; - - ret = size; -unlock: - mutex_unlock(&led_cdev->led_access); - return ret; -} - -static ssize_t flash_sync_strobe_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct led_classdev *led_cdev = dev_get_drvdata(dev); - struct led_classdev_flash *fled_cdev = lcdev_to_flcdev(led_cdev); - int sled_id = fled_cdev->sync_led_id; - char *sync_led_name = "none"; - - if (fled_cdev->sync_led_id > 0) - sync_led_name = (char *) - fled_cdev->sync_leds[sled_id - 1]->led_cdev.name; - - return sprintf(buf, "[%d: %s]\n", sled_id, sync_led_name); -} -static DEVICE_ATTR_RW(flash_sync_strobe); - static struct attribute *led_flash_strobe_attrs[] = { &dev_attr_flash_strobe.attr, NULL, @@ -307,12 +238,6 @@ static struct attribute *led_flash_fault_attrs[] = { NULL, }; -static struct attribute *led_flash_sync_strobe_attrs[] = { - &dev_attr_available_sync_leds.attr, - &dev_attr_flash_sync_strobe.attr, - NULL, -}; - static const struct attribute_group led_flash_strobe_group = { .attrs = led_flash_strobe_attrs, }; @@ -329,10 +254,6 @@ static const struct attribute_group led_flash_fault_group = { .attrs = led_flash_fault_attrs, }; -static const struct attribute_group led_flash_sync_strobe_group = { - .attrs = led_flash_sync_strobe_attrs, -}; - static void led_flash_resume(struct led_classdev *led_cdev) { struct led_classdev_flash *fled_cdev = lcdev_to_flcdev(led_cdev); @@ -361,9 +282,6 @@ static void led_flash_init_sysfs_groups(struct led_classdev_flash *fled_cdev) if (ops->fault_get) flash_groups[num_sysfs_groups++] = &led_flash_fault_group; - if (led_cdev->flags & LED_DEV_CAP_SYNC_STROBE) - flash_groups[num_sysfs_groups++] = &led_flash_sync_strobe_group; - led_cdev->groups = flash_groups; } diff --git a/include/linux/led-class-flash.h b/include/linux/led-class-flash.h index 3b5b9643cea1..21ec91e13c47 100644 --- a/include/linux/led-class-flash.h +++ b/include/linux/led-class-flash.h @@ -81,20 +81,6 @@ struct led_classdev_flash { /* LED Flash class sysfs groups */ const struct attribute_group *sysfs_groups[LED_FLASH_MAX_SYSFS_GROUPS]; - - /* LEDs available for flash strobe synchronization */ - struct led_classdev_flash **sync_leds; - - /* Number of LEDs available for flash strobe synchronization */ - int num_sync_leds; - - /* - * The identifier of the sub-led to synchronize the flash strobe with. - * Identifiers start from 1, which reflects the first element from the - * sync_leds array. 0 means that the flash strobe should not be - * synchronized. - */ - u32 sync_led_id; }; static inline struct led_classdev_flash *lcdev_to_flcdev( diff --git a/include/linux/leds.h b/include/linux/leds.h index ed634279062e..9a2b000094cf 100644 --- a/include/linux/leds.h +++ b/include/linux/leds.h @@ -47,7 +47,6 @@ struct led_classdev { #define SET_BRIGHTNESS_ASYNC (1 << 21) #define SET_BRIGHTNESS_SYNC (1 << 22) #define LED_DEV_CAP_FLASH (1 << 23) -#define LED_DEV_CAP_SYNC_STROBE (1 << 24) /* Set LED brightness level */ /* Must not sleep, use a workqueue if needed */ -- GitLab From 9c4a8e138cfe2cc7262d5d2224162add5632b546 Mon Sep 17 00:00:00 2001 From: Jacek Anaszewski Date: Wed, 4 Mar 2015 08:14:23 -0800 Subject: [PATCH 03624/11651] leds: flash: document sysfs interface Add a documentation of LED Flash class specific sysfs attributes. Signed-off-by: Jacek Anaszewski Acked-by: Kyungmin Park Cc: Richard Purdie Signed-off-by: Bryan Wu --- .../ABI/testing/sysfs-class-led-flash | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-class-led-flash diff --git a/Documentation/ABI/testing/sysfs-class-led-flash b/Documentation/ABI/testing/sysfs-class-led-flash new file mode 100644 index 000000000000..220a0270b47b --- /dev/null +++ b/Documentation/ABI/testing/sysfs-class-led-flash @@ -0,0 +1,80 @@ +What: /sys/class/leds//flash_brightness +Date: March 2015 +KernelVersion: 4.0 +Contact: Jacek Anaszewski +Description: read/write + Set the brightness of this LED in the flash strobe mode, in + microamperes. The file is created only for the flash LED devices + that support setting flash brightness. + + The value is between 0 and + /sys/class/leds//max_flash_brightness. + +What: /sys/class/leds//max_flash_brightness +Date: March 2015 +KernelVersion: 4.0 +Contact: Jacek Anaszewski +Description: read only + Maximum brightness level for this LED in the flash strobe mode, + in microamperes. + +What: /sys/class/leds//flash_timeout +Date: March 2015 +KernelVersion: 4.0 +Contact: Jacek Anaszewski +Description: read/write + Hardware timeout for flash, in microseconds. The flash strobe + is stopped after this period of time has passed from the start + of the strobe. The file is created only for the flash LED + devices that support setting flash timeout. + +What: /sys/class/leds//max_flash_timeout +Date: March 2015 +KernelVersion: 4.0 +Contact: Jacek Anaszewski +Description: read only + Maximum flash timeout for this LED, in microseconds. + +What: /sys/class/leds//flash_strobe +Date: March 2015 +KernelVersion: 4.0 +Contact: Jacek Anaszewski +Description: read/write + Flash strobe state. When written with 1 it triggers flash strobe + and when written with 0 it turns the flash off. + + On read 1 means that flash is currently strobing and 0 means + that flash is off. + +What: /sys/class/leds//flash_fault +Date: March 2015 +KernelVersion: 4.0 +Contact: Jacek Anaszewski +Description: read only + Space separated list of flash faults that may have occurred. + Flash faults are re-read after strobing the flash. Possible + flash faults: + + * led-over-voltage - flash controller voltage to the flash LED + has exceeded the limit specific to the flash controller + * flash-timeout-exceeded - the flash strobe was still on when + the timeout set by the user has expired; not all flash + controllers may set this in all such conditions + * controller-over-temperature - the flash controller has + overheated + * controller-short-circuit - the short circuit protection + of the flash controller has been triggered + * led-power-supply-over-current - current in the LED power + supply has exceeded the limit specific to the flash + controller + * indicator-led-fault - the flash controller has detected + a short or open circuit condition on the indicator LED + * led-under-voltage - flash controller voltage to the flash + LED has been below the minimum limit specific to + the flash + * controller-under-voltage - the input voltage of the flash + controller is below the limit under which strobing the + flash at full current will not be possible; + the condition persists until this flag is no longer set + * led-over-temperature - the temperature of the LED has exceeded + its allowed upper limit -- GitLab From f6ad395bad57dcd15c6423715d15d91363a62ae8 Mon Sep 17 00:00:00 2001 From: Jacek Anaszewski Date: Wed, 4 Mar 2015 08:14:24 -0800 Subject: [PATCH 03625/11651] Documentation: leds: Add description of LED Flash class extension The documentation being added contains overall description of the LED Flash Class and the related sysfs attributes. Signed-off-by: Jacek Anaszewski Acked-by: Kyungmin Park Cc: Richard Purdie Signed-off-by: Bryan Wu --- Documentation/leds/leds-class-flash.txt | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 Documentation/leds/leds-class-flash.txt diff --git a/Documentation/leds/leds-class-flash.txt b/Documentation/leds/leds-class-flash.txt new file mode 100644 index 000000000000..19bb67355424 --- /dev/null +++ b/Documentation/leds/leds-class-flash.txt @@ -0,0 +1,22 @@ + +Flash LED handling under Linux +============================== + +Some LED devices provide two modes - torch and flash. In the LED subsystem +those modes are supported by LED class (see Documentation/leds/leds-class.txt) +and LED Flash class respectively. The torch mode related features are enabled +by default and the flash ones only if a driver declares it by setting +LED_DEV_CAP_FLASH flag. + +In order to enable the support for flash LEDs CONFIG_LEDS_CLASS_FLASH symbol +must be defined in the kernel config. A LED Flash class driver must be +registered in the LED subsystem with led_classdev_flash_register function. + +Following sysfs attributes are exposed for controlling flash LED devices: +(see Documentation/ABI/testing/sysfs-class-led-flash) + - flash_brightness + - max_flash_brightness + - flash_timeout + - max_flash_timeout + - flash_strobe + - flash_fault -- GitLab From 88660f7fb94cda1f8f63ee92bfcd0db39a6361e2 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 5 Mar 2015 13:24:41 +1030 Subject: [PATCH 03626/11651] virtio_balloon: set DRIVER_OK before using device virtio spec requires that all drivers set DRIVER_OK before using devices. While balloon isn't yet included in the virtio 1 spec, previous spec versions also required this. virtio balloon might violate this rule: probe calls kthread_run before setting DRIVER_OK, which might run immediately and cause balloon to inflate/deflate. To fix, call virtio_device_ready before running the kthread. Signed-off-by: Michael S. Tsirkin Signed-off-by: Rusty Russell Cc: stable@kernel.org --- drivers/virtio/virtio_balloon.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c index 0413157f3b49..b36fe56677d5 100644 --- a/drivers/virtio/virtio_balloon.c +++ b/drivers/virtio/virtio_balloon.c @@ -499,6 +499,8 @@ static int virtballoon_probe(struct virtio_device *vdev) if (err < 0) goto out_oom_notify; + virtio_device_ready(vdev); + vb->thread = kthread_run(balloon, vb, "vballoon"); if (IS_ERR(vb->thread)) { err = PTR_ERR(vb->thread); -- GitLab From 7e41a9def062167b5405711a42c9ecfd163e31a9 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Fri, 6 Mar 2015 12:50:03 +1030 Subject: [PATCH 03627/11651] virtio_blk: typo fix Now that QEmu reuses linux virtio headers, we noticed a typo in the exported virtio block header. Fix it up. Signed-off-by: Michael S. Tsirkin Signed-off-by: Rusty Russell --- include/uapi/linux/virtio_blk.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/uapi/linux/virtio_blk.h b/include/uapi/linux/virtio_blk.h index 3c53eec4ae22..b695ba959186 100644 --- a/include/uapi/linux/virtio_blk.h +++ b/include/uapi/linux/virtio_blk.h @@ -60,7 +60,7 @@ struct virtio_blk_config { __u32 size_max; /* The maximum number of segments (if VIRTIO_BLK_F_SEG_MAX) */ __u32 seg_max; - /* geometry the device (if VIRTIO_BLK_F_GEOMETRY) */ + /* geometry of the device (if VIRTIO_BLK_F_GEOMETRY) */ struct virtio_blk_geometry { __u16 cylinders; __u8 heads; -- GitLab From 0fa2a56437d0b7ef5d86eef2778ad3469ca72d5a Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Fri, 6 Mar 2015 12:50:03 +1030 Subject: [PATCH 03628/11651] virtio_blk: fix comment for virtio 1.0 Fix up comment to match virtio 1.0 logic: virtio_blk_outhdr isn't the first elements anymore, the only requirement is that it comes first in the s/g list. Signed-off-by: Michael S. Tsirkin Signed-off-by: Rusty Russell --- include/uapi/linux/virtio_blk.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/uapi/linux/virtio_blk.h b/include/uapi/linux/virtio_blk.h index b695ba959186..19c66fcbab8a 100644 --- a/include/uapi/linux/virtio_blk.h +++ b/include/uapi/linux/virtio_blk.h @@ -119,7 +119,11 @@ struct virtio_blk_config { #define VIRTIO_BLK_T_BARRIER 0x80000000 #endif /* !VIRTIO_BLK_NO_LEGACY */ -/* This is the first element of the read scatter-gather list. */ +/* + * This comes first in the read scatter-gather list. + * For legacy virtio, if VIRTIO_F_ANY_LAYOUT is not negotiated, + * this is the first element of the read scatter-gather list. + */ struct virtio_blk_outhdr { /* VIRTIO_BLK_T* */ __virtio32 type; -- GitLab From 3d2a3774c1b046f548ebea0391a602fd5685a307 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Tue, 10 Mar 2015 11:55:08 +1030 Subject: [PATCH 03629/11651] virtio-balloon: do not call blocking ops when !TASK_RUNNING virtio balloon has this code: wait_event_interruptible(vb->config_change, (diff = towards_target(vb)) != 0 || vb->need_stats_update || kthread_should_stop() || freezing(current)); Which is a problem because towards_target() call might block after wait_event_interruptible sets task state to TAST_INTERRUPTIBLE, causing the task_struct::state collision typical of nesting of sleeping primitives See also http://lwn.net/Articles/628628/ or Thomas's bug report http://article.gmane.org/gmane.linux.kernel.virtualization/24846 for a fuller explanation. To fix, rewrite using wait_woken. Cc: stable@vger.kernel.org Reported-by: Thomas Huth Signed-off-by: Michael S. Tsirkin Tested-by: Thomas Huth Reviewed-by: Cornelia Huck Signed-off-by: Rusty Russell --- drivers/virtio/virtio_balloon.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c index b36fe56677d5..6a356e344f82 100644 --- a/drivers/virtio/virtio_balloon.c +++ b/drivers/virtio/virtio_balloon.c @@ -29,6 +29,7 @@ #include #include #include +#include /* * Balloon device works in 4K page units. So each page is pointed to by @@ -334,17 +335,25 @@ static int virtballoon_oom_notify(struct notifier_block *self, static int balloon(void *_vballoon) { struct virtio_balloon *vb = _vballoon; + DEFINE_WAIT_FUNC(wait, woken_wake_function); set_freezable(); while (!kthread_should_stop()) { s64 diff; try_to_freeze(); - wait_event_interruptible(vb->config_change, - (diff = towards_target(vb)) != 0 - || vb->need_stats_update - || kthread_should_stop() - || freezing(current)); + + add_wait_queue(&vb->config_change, &wait); + for (;;) { + if ((diff = towards_target(vb)) != 0 || + vb->need_stats_update || + kthread_should_stop() || + freezing(current)) + break; + wait_woken(&wait, TASK_INTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT); + } + remove_wait_queue(&vb->config_change, &wait); + if (vb->need_stats_update) stats_handle_request(vb); if (diff > 0) -- GitLab From 9a6f5130143c17b91e0a3cbf5cc2d8c1e5a80a63 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 25 Feb 2015 13:45:26 +0000 Subject: [PATCH 03630/11651] drm: Don't assign fbs for universal cursor support to files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The internal framebuffers we create to remap legacy cursor ioctls to plane operations for the universal plane support shouldn't be linke to the file like normal userspace framebuffers. This bug goes back to the original universal cursor plane support introduced in commit 161d0dc1dccb17ff7a38f462c7c0d4ef8bcc5662 Author: Matt Roper Date: Tue Jun 10 08:28:10 2014 -0700 drm: Support legacy cursor ioctls via universal planes when possible (v4) The isn't too disastrous since fbs are small, we only create one when the cursor bo gets changed and ultimately they'll be reaped when the window server restarts. Conceptually we'd want to just pass NULL for file_priv when creating it, but the driver needs the file to lookup the underlying buffer object for cursor id. Instead let's move the file_priv linking out of add_framebuffer_internal() into the addfb ioctl implementation, which is the only place it is needed. And also rename the function for a more accurate since it only creates the fb, but doesn't add it anywhere. Signed-off-by: Daniel Vetter (fix & commit msg) Signed-off-by: Chris Wilson (provider of lipstick) Reviewed-by: Matt Roper Cc: Ville Syrjälä Cc: Matt Roper Cc: Rob Clark Cc: stable@vger.kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_crtc.c | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 6b6b07ff720b..f6d04c7b5115 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -43,9 +43,10 @@ #include "drm_crtc_internal.h" #include "drm_internal.h" -static struct drm_framebuffer *add_framebuffer_internal(struct drm_device *dev, - struct drm_mode_fb_cmd2 *r, - struct drm_file *file_priv); +static struct drm_framebuffer * +internal_framebuffer_create(struct drm_device *dev, + struct drm_mode_fb_cmd2 *r, + struct drm_file *file_priv); /* Avoid boilerplate. I'm tired of typing. */ #define DRM_ENUM_NAME_FN(fnname, list) \ @@ -2908,13 +2909,11 @@ static int drm_mode_cursor_universal(struct drm_crtc *crtc, */ if (req->flags & DRM_MODE_CURSOR_BO) { if (req->handle) { - fb = add_framebuffer_internal(dev, &fbreq, file_priv); + fb = internal_framebuffer_create(dev, &fbreq, file_priv); if (IS_ERR(fb)) { DRM_DEBUG_KMS("failed to wrap cursor buffer in drm framebuffer\n"); return PTR_ERR(fb); } - - drm_framebuffer_reference(fb); } else { fb = NULL; } @@ -3267,9 +3266,10 @@ static int framebuffer_check(const struct drm_mode_fb_cmd2 *r) return 0; } -static struct drm_framebuffer *add_framebuffer_internal(struct drm_device *dev, - struct drm_mode_fb_cmd2 *r, - struct drm_file *file_priv) +static struct drm_framebuffer * +internal_framebuffer_create(struct drm_device *dev, + struct drm_mode_fb_cmd2 *r, + struct drm_file *file_priv) { struct drm_mode_config *config = &dev->mode_config; struct drm_framebuffer *fb; @@ -3301,12 +3301,6 @@ static struct drm_framebuffer *add_framebuffer_internal(struct drm_device *dev, return fb; } - mutex_lock(&file_priv->fbs_lock); - r->fb_id = fb->base.id; - list_add(&fb->filp_head, &file_priv->fbs); - DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id); - mutex_unlock(&file_priv->fbs_lock); - return fb; } @@ -3328,15 +3322,24 @@ static struct drm_framebuffer *add_framebuffer_internal(struct drm_device *dev, int drm_mode_addfb2(struct drm_device *dev, void *data, struct drm_file *file_priv) { + struct drm_mode_fb_cmd2 *r = data; struct drm_framebuffer *fb; if (!drm_core_check_feature(dev, DRIVER_MODESET)) return -EINVAL; - fb = add_framebuffer_internal(dev, data, file_priv); + fb = internal_framebuffer_create(dev, r, file_priv); if (IS_ERR(fb)) return PTR_ERR(fb); + /* Transfer ownership to the filp for reaping on close */ + + DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id); + mutex_lock(&file_priv->fbs_lock); + r->fb_id = fb->base.id; + list_add(&fb->filp_head, &file_priv->fbs); + mutex_unlock(&file_priv->fbs_lock); + return 0; } -- GitLab From 8ac467e837a24eb024177b4b01013d8e6764913a Mon Sep 17 00:00:00 2001 From: Petri Gynther Date: Mon, 9 Mar 2015 13:40:00 -0700 Subject: [PATCH 03631/11651] net: bcmgenet: core changes for supporting multiple Rx queues 1. Add struct bcmgenet_rx_ring to hold all necessary information for a single Rx queue. 2. Add bcmgenet_init_rx_queues() to initialize all Rx queues. 3. Modify bcmgenet_init_rx_ring() to initialize a single Rx queue. 4. Modify Rx interrupt path code to use per-queue data. 5. Modify bcmgenet_rx_refill() to use RxCB->bd_addr. Signed-off-by: Petri Gynther Reviewed-by: Florian Fainelli Signed-off-by: David S. Miller --- .../net/ethernet/broadcom/genet/bcmgenet.c | 156 ++++++++++++------ .../net/ethernet/broadcom/genet/bcmgenet.h | 16 +- 2 files changed, 119 insertions(+), 53 deletions(-) diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index 83c0cb323e0c..275be56fd324 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -1363,16 +1363,7 @@ static int bcmgenet_rx_refill(struct bcmgenet_priv *priv, struct enet_cb *cb) } dma_unmap_addr_set(cb, dma_addr, mapping); - /* assign packet, prepare descriptor, and advance pointer */ - - dmadesc_set_addr(priv, priv->rx_bd_assign_ptr, mapping); - - /* turn on the newly assigned BD for DMA to use */ - priv->rx_bd_assign_index++; - priv->rx_bd_assign_index &= (priv->num_rx_bds - 1); - - priv->rx_bd_assign_ptr = priv->rx_bds + - (priv->rx_bd_assign_index * DMA_DESC_SIZE); + dmadesc_set_addr(priv, cb->bd_addr, mapping); return 0; } @@ -1381,8 +1372,10 @@ static int bcmgenet_rx_refill(struct bcmgenet_priv *priv, struct enet_cb *cb) * this could be called from bottom half, or from NAPI polling method. */ static unsigned int bcmgenet_desc_rx(struct bcmgenet_priv *priv, + unsigned int index, unsigned int budget) { + struct bcmgenet_rx_ring *ring = &priv->rx_rings[index]; struct net_device *dev = priv->dev; struct enet_cb *cb; struct sk_buff *skb; @@ -1393,21 +1386,21 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_priv *priv, unsigned int p_index; unsigned int chksum_ok = 0; - p_index = bcmgenet_rdma_ring_readl(priv, DESC_INDEX, RDMA_PROD_INDEX); + p_index = bcmgenet_rdma_ring_readl(priv, index, RDMA_PROD_INDEX); p_index &= DMA_P_INDEX_MASK; - if (p_index < priv->rx_c_index) - rxpkttoprocess = (DMA_C_INDEX_MASK + 1) - - priv->rx_c_index + p_index; + if (likely(p_index >= ring->c_index)) + rxpkttoprocess = p_index - ring->c_index; else - rxpkttoprocess = p_index - priv->rx_c_index; + rxpkttoprocess = (DMA_C_INDEX_MASK + 1) - ring->c_index + + p_index; netif_dbg(priv, rx_status, dev, "RDMA: rxpkttoprocess=%d\n", rxpkttoprocess); while ((rxpktprocessed < rxpkttoprocess) && (rxpktprocessed < budget)) { - cb = &priv->rx_cbs[priv->rx_read_ptr]; + cb = &priv->rx_cbs[ring->read_ptr]; skb = cb->skb; /* We do not have a backing SKB, so we do not have a @@ -1430,10 +1423,7 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_priv *priv, if (!priv->desc_64b_en) { dma_length_status = - dmadesc_get_length_status(priv, - priv->rx_bds + - (priv->rx_read_ptr * - DMA_DESC_SIZE)); + dmadesc_get_length_status(priv, cb->bd_addr); } else { struct status_64 *status; @@ -1449,8 +1439,8 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_priv *priv, netif_dbg(priv, rx_status, dev, "%s:p_ind=%d c_ind=%d read_ptr=%d len_stat=0x%08x\n", - __func__, p_index, priv->rx_c_index, - priv->rx_read_ptr, dma_length_status); + __func__, p_index, ring->c_index, + ring->read_ptr, dma_length_status); if (unlikely(!(dma_flag & DMA_EOP) || !(dma_flag & DMA_SOP))) { netif_err(priv, rx_status, dev, @@ -1528,25 +1518,31 @@ refill: } rxpktprocessed++; - priv->rx_read_ptr++; - priv->rx_read_ptr &= (priv->num_rx_bds - 1); + if (likely(ring->read_ptr < ring->end_ptr)) + ring->read_ptr++; + else + ring->read_ptr = ring->cb_ptr; + + ring->c_index = (ring->c_index + 1) & DMA_C_INDEX_MASK; + bcmgenet_rdma_ring_writel(priv, index, ring->c_index, RDMA_CONS_INDEX); } return rxpktprocessed; } /* Assign skb to RX DMA descriptor. */ -static int bcmgenet_alloc_rx_buffers(struct bcmgenet_priv *priv) +static int bcmgenet_alloc_rx_buffers(struct bcmgenet_priv *priv, + struct bcmgenet_rx_ring *ring) { struct enet_cb *cb; int ret = 0; int i; - netif_dbg(priv, hw, priv->dev, "%s:\n", __func__); + netif_dbg(priv, hw, priv->dev, "%s\n", __func__); /* loop here for each buffer needing assign */ - for (i = 0; i < priv->num_rx_bds; i++) { - cb = &priv->rx_cbs[priv->rx_bd_assign_index]; + for (i = 0; i < ring->size; i++) { + cb = ring->cbs + i; if (cb->skb) continue; @@ -1778,20 +1774,24 @@ static void bcmgenet_fini_tx_ring(struct bcmgenet_priv *priv, /* Initialize a RDMA ring */ static int bcmgenet_init_rx_ring(struct bcmgenet_priv *priv, - unsigned int index, unsigned int size) + unsigned int index, unsigned int size, + unsigned int start_ptr, unsigned int end_ptr) { + struct bcmgenet_rx_ring *ring = &priv->rx_rings[index]; u32 words_per_bd = WORDS_PER_BD(priv); int ret; - priv->rx_bd_assign_ptr = priv->rx_bds; - priv->rx_bd_assign_index = 0; - priv->rx_c_index = 0; - priv->rx_read_ptr = 0; + ring->index = index; + ring->cbs = priv->rx_cbs + start_ptr; + ring->size = size; + ring->c_index = 0; + ring->read_ptr = start_ptr; + ring->cb_ptr = start_ptr; + ring->end_ptr = end_ptr - 1; - ret = bcmgenet_alloc_rx_buffers(priv); - if (ret) { + ret = bcmgenet_alloc_rx_buffers(priv, ring); + if (ret) return ret; - } bcmgenet_rdma_ring_writel(priv, index, 0, RDMA_PROD_INDEX); bcmgenet_rdma_ring_writel(priv, index, 0, RDMA_CONS_INDEX); @@ -1805,10 +1805,13 @@ static int bcmgenet_init_rx_ring(struct bcmgenet_priv *priv, DMA_FC_THRESH_HI, RDMA_XON_XOFF_THRESH); /* Set start and end address, read and write pointers */ - bcmgenet_rdma_ring_writel(priv, index, 0, DMA_START_ADDR); - bcmgenet_rdma_ring_writel(priv, index, 0, RDMA_READ_PTR); - bcmgenet_rdma_ring_writel(priv, index, 0, RDMA_WRITE_PTR); - bcmgenet_rdma_ring_writel(priv, index, words_per_bd * size - 1, + bcmgenet_rdma_ring_writel(priv, index, start_ptr * words_per_bd, + DMA_START_ADDR); + bcmgenet_rdma_ring_writel(priv, index, start_ptr * words_per_bd, + RDMA_READ_PTR); + bcmgenet_rdma_ring_writel(priv, index, start_ptr * words_per_bd, + RDMA_WRITE_PTR); + bcmgenet_rdma_ring_writel(priv, index, end_ptr * words_per_bd - 1, DMA_END_ADDR); return ret; @@ -1883,6 +1886,66 @@ static void bcmgenet_init_tx_queues(struct net_device *dev) bcmgenet_tdma_writel(priv, dma_ctrl, DMA_CTRL); } +/* Initialize Rx queues + * + * Queues 0-15 are priority queues. Hardware Filtering Block (HFB) can be + * used to direct traffic to these queues. + * + * Queue 16 is the default Rx queue with GENET_Q16_RX_BD_CNT descriptors. + */ +static int bcmgenet_init_rx_queues(struct net_device *dev) +{ + struct bcmgenet_priv *priv = netdev_priv(dev); + u32 i; + u32 dma_enable; + u32 dma_ctrl; + u32 ring_cfg; + int ret; + + dma_ctrl = bcmgenet_rdma_readl(priv, DMA_CTRL); + dma_enable = dma_ctrl & DMA_EN; + dma_ctrl &= ~DMA_EN; + bcmgenet_rdma_writel(priv, dma_ctrl, DMA_CTRL); + + dma_ctrl = 0; + ring_cfg = 0; + + /* Initialize Rx priority queues */ + for (i = 0; i < priv->hw_params->rx_queues; i++) { + ret = bcmgenet_init_rx_ring(priv, i, + priv->hw_params->rx_bds_per_q, + i * priv->hw_params->rx_bds_per_q, + (i + 1) * + priv->hw_params->rx_bds_per_q); + if (ret) + return ret; + + ring_cfg |= (1 << i); + dma_ctrl |= (1 << (i + DMA_RING_BUF_EN_SHIFT)); + } + + /* Initialize Rx default queue 16 */ + ret = bcmgenet_init_rx_ring(priv, DESC_INDEX, GENET_Q16_RX_BD_CNT, + priv->hw_params->rx_queues * + priv->hw_params->rx_bds_per_q, + TOTAL_DESC); + if (ret) + return ret; + + ring_cfg |= (1 << DESC_INDEX); + dma_ctrl |= (1 << (DESC_INDEX + DMA_RING_BUF_EN_SHIFT)); + + /* Enable rings */ + bcmgenet_rdma_writel(priv, ring_cfg, DMA_RING_CFG); + + /* Configure ring as descriptor ring and re-enable DMA if enabled */ + if (dma_enable) + dma_ctrl |= DMA_EN; + bcmgenet_rdma_writel(priv, dma_ctrl, DMA_CTRL); + + return 0; +} + static int bcmgenet_dma_teardown(struct bcmgenet_priv *priv) { int ret = 0; @@ -1990,10 +2053,10 @@ static int bcmgenet_init_dma(struct bcmgenet_priv *priv) cb->bd_addr = priv->rx_bds + i * DMA_DESC_SIZE; } - /* Initialize Rx default queue 16 */ - ret = bcmgenet_init_rx_ring(priv, DESC_INDEX, TOTAL_DESC); + /* Initialize Rx queues */ + ret = bcmgenet_init_rx_queues(priv->dev); if (ret) { - netdev_err(priv->dev, "failed to initialize RX ring\n"); + netdev_err(priv->dev, "failed to initialize Rx queues\n"); bcmgenet_free_rx_buffers(priv); kfree(priv->rx_cbs); return ret; @@ -2030,13 +2093,8 @@ static int bcmgenet_poll(struct napi_struct *napi, int budget) struct bcmgenet_priv, napi); unsigned int work_done; - work_done = bcmgenet_desc_rx(priv, budget); + work_done = bcmgenet_desc_rx(priv, DESC_INDEX, budget); - /* Advancing our consumer index*/ - priv->rx_c_index += work_done; - priv->rx_c_index &= DMA_C_INDEX_MASK; - bcmgenet_rdma_ring_writel(priv, DESC_INDEX, - priv->rx_c_index, RDMA_CONS_INDEX); if (work_done < budget) { napi_complete(napi); bcmgenet_intrl2_0_writel(priv, UMAC_IRQ_RXDMA_BDONE, diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.h b/drivers/net/ethernet/broadcom/genet/bcmgenet.h index 5684e8529ecc..17443db8dc53 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h @@ -540,6 +540,16 @@ struct bcmgenet_tx_ring { struct bcmgenet_priv *priv; }; +struct bcmgenet_rx_ring { + unsigned int index; /* Rx ring index */ + struct enet_cb *cbs; /* Rx ring buffer control block */ + unsigned int size; /* Rx ring size */ + unsigned int c_index; /* Rx last consumer index */ + unsigned int read_ptr; /* Rx ring read pointer */ + unsigned int cb_ptr; /* Rx ring initial CB ptr */ + unsigned int end_ptr; /* Rx ring end CB ptr */ +}; + /* device context */ struct bcmgenet_priv { void __iomem *base; @@ -560,13 +570,11 @@ struct bcmgenet_priv { /* receive variables */ void __iomem *rx_bds; - void __iomem *rx_bd_assign_ptr; - int rx_bd_assign_index; struct enet_cb *rx_cbs; unsigned int num_rx_bds; unsigned int rx_buf_len; - unsigned int rx_read_ptr; - unsigned int rx_c_index; + + struct bcmgenet_rx_ring rx_rings[DESC_INDEX + 1]; /* other misc variables */ struct bcmgenet_hw_params *hw_params; -- GitLab From 87313df7b47c5048d8920a486f77835a49406754 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 10 Mar 2015 12:28:29 +1030 Subject: [PATCH 03632/11651] powerpc: fix deprecated CPU_MASK_CPU0 usage. Signed-off-by: Rusty Russell --- arch/powerpc/include/asm/cputhreads.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/include/asm/cputhreads.h b/arch/powerpc/include/asm/cputhreads.h index 2bf8e9307be9..42e04a6a2b58 100644 --- a/arch/powerpc/include/asm/cputhreads.h +++ b/arch/powerpc/include/asm/cputhreads.h @@ -25,7 +25,7 @@ extern cpumask_t threads_core_mask; #define threads_per_core 1 #define threads_per_subcore 1 #define threads_shift 0 -#define threads_core_mask (CPU_MASK_CPU0) +#define threads_core_mask (*get_cpu_mask(0)) #endif /* cpu_thread_mask_to_cores - Return a cpumask of one per cores -- GitLab From 394838c96013ba414a24ffe7a2a593a9154daadf Mon Sep 17 00:00:00 2001 From: Andy Lutomirski Date: Mon, 9 Mar 2015 17:42:31 -0700 Subject: [PATCH 03633/11651] x86/asm/entry/32: Fix user_mode() misuses The one in do_debug() is probably harmless, but better safe than sorry. Signed-off-by: Andy Lutomirski Cc: Cc: Borislav Petkov Cc: Dave Hansen Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Thomas Gleixner Link: http://lkml.kernel.org/r/d67deaa9df5458363623001f252d1aee3215d014.1425948056.git.luto@amacapital.net Signed-off-by: Ingo Molnar --- arch/x86/kernel/traps.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 9d2073e2ecc9..4ff5d162ff9f 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -384,7 +384,7 @@ dotraplinkage void do_bounds(struct pt_regs *regs, long error_code) goto exit; conditional_sti(regs); - if (!user_mode(regs)) + if (!user_mode_vm(regs)) die("bounds", regs, error_code); if (!cpu_feature_enabled(X86_FEATURE_MPX)) { @@ -637,7 +637,7 @@ dotraplinkage void do_debug(struct pt_regs *regs, long error_code) * then it's very likely the result of an icebp/int01 trap. * User wants a sigtrap for that. */ - if (!dr6 && user_mode(regs)) + if (!dr6 && user_mode_vm(regs)) user_icebp = 1; /* Catch kmemcheck conditions first of all! */ -- GitLab From 6a4bd8d1412a6cd72b65d7c86a2c08e9ec1d6b97 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 10 Mar 2015 12:42:03 +1030 Subject: [PATCH 03634/11651] ia64: remove deprecated cpus_ usage. Signed-off-by: Rusty Russell --- arch/ia64/kernel/irq_ia64.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c index 9f40d972969c..eaa3199f98c8 100644 --- a/arch/ia64/kernel/irq_ia64.c +++ b/arch/ia64/kernel/irq_ia64.c @@ -173,7 +173,7 @@ static void __clear_irq_vector(int irq) cfg->vector = IRQ_VECTOR_UNASSIGNED; cfg->domain = CPU_MASK_NONE; irq_status[irq] = IRQ_UNUSED; - cpus_andnot(vector_table[vector], vector_table[vector], domain); + cpumask_andnot(&vector_table[vector], &vector_table[vector], &domain); } static void clear_irq_vector(int irq) @@ -259,7 +259,7 @@ static enum vector_domain_type { static cpumask_t vector_allocation_domain(int cpu) { if (vector_domain_type == VECTOR_DOMAIN_PERCPU) - return cpumask_of_cpu(cpu); + return *cpumask_of(cpu); return CPU_MASK_ALL; } -- GitLab From fdaf3a6539d6b9b6a7240c3b00bd81c813b2760d Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 10 Mar 2015 12:43:45 +1030 Subject: [PATCH 03635/11651] x86: fix more deprecated cpu function usage. Signed-off-by: Rusty Russell --- arch/x86/kernel/apic/x2apic_cluster.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/apic/x2apic_cluster.c b/arch/x86/kernel/apic/x2apic_cluster.c index d9d0bd2faaf4..ab3219b3fbda 100644 --- a/arch/x86/kernel/apic/x2apic_cluster.c +++ b/arch/x86/kernel/apic/x2apic_cluster.c @@ -171,8 +171,8 @@ update_clusterinfo(struct notifier_block *nfb, unsigned long action, void *hcpu) for_each_online_cpu(cpu) { if (x2apic_cluster(this_cpu) != x2apic_cluster(cpu)) continue; - __cpu_clear(this_cpu, per_cpu(cpus_in_cluster, cpu)); - __cpu_clear(cpu, per_cpu(cpus_in_cluster, this_cpu)); + cpumask_clear_cpu(this_cpu, per_cpu(cpus_in_cluster, cpu)); + cpumask_clear_cpu(cpu, per_cpu(cpus_in_cluster, this_cpu)); } free_cpumask_var(per_cpu(cpus_in_cluster, this_cpu)); free_cpumask_var(per_cpu(ipi_mask, this_cpu)); -- GitLab From 1ed1835f5fadf057ab081cbe31ac353d4547a25b Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 10 Mar 2015 13:00:43 +1030 Subject: [PATCH 03636/11651] mips: fix obsolete cpumask_of_cpu usage. Plus, it's weird. Signed-off-by: Rusty Russell --- arch/mips/include/asm/smp.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/include/asm/smp.h b/arch/mips/include/asm/smp.h index eacf865d21c2..bb02fac9b4fa 100644 --- a/arch/mips/include/asm/smp.h +++ b/arch/mips/include/asm/smp.h @@ -88,7 +88,7 @@ static inline void arch_send_call_function_single_ipi(int cpu) { extern struct plat_smp_ops *mp_ops; /* private */ - mp_ops->send_ipi_mask(&cpumask_of_cpu(cpu), SMP_CALL_FUNCTION); + mp_ops->send_ipi_mask(cpumask_of(cpu), SMP_CALL_FUNCTION); } static inline void arch_send_call_function_ipi_mask(const struct cpumask *mask) -- GitLab From 2f0f267ea0720ec6adbe9cf7386450425fac8258 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 5 Mar 2015 10:49:19 +1030 Subject: [PATCH 03637/11651] cpumask: remove deprecated functions. Using these functions with offstack cpus is unsafe. They use all NR_CPUS bits, unstead of nr_cpumask_bits. In particular, lustre (in staging) used cpus_ and that caused a bug. Reported-by: Oleg Drokin Signed-off-by: Rusty Russell --- include/linux/cpumask.h | 151 ---------------------------------------- lib/Kconfig | 4 -- 2 files changed, 155 deletions(-) diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h index dc037ae6f4f2..646fadee5caf 100644 --- a/include/linux/cpumask.h +++ b/include/linux/cpumask.h @@ -815,155 +815,4 @@ cpumap_print_to_pagebuf(bool list, char *buf, const struct cpumask *mask) [0 ... BITS_TO_LONGS(NR_CPUS)-1] = 0UL \ } } -/* - * - * From here down, all obsolete. Use cpumask_ variants! - * - */ -#ifndef CONFIG_DISABLE_OBSOLETE_CPUMASK_FUNCTIONS - -#define CPU_MASK_CPU0 \ -(cpumask_t) { { \ - [0] = 1UL \ -} } - -#if NR_CPUS == 1 -#define first_cpu(src) ({ (void)(src); 0; }) -#define next_cpu(n, src) ({ (void)(src); 1; }) -#define any_online_cpu(mask) 0 -#define for_each_cpu_mask(cpu, mask) \ - for ((cpu) = 0; (cpu) < 1; (cpu)++, (void)mask) -#else /* NR_CPUS > 1 */ -int __first_cpu(const cpumask_t *srcp); -int __next_cpu(int n, const cpumask_t *srcp); - -#define first_cpu(src) __first_cpu(&(src)) -#define next_cpu(n, src) __next_cpu((n), &(src)) -#define any_online_cpu(mask) cpumask_any_and(&mask, cpu_online_mask) -#define for_each_cpu_mask(cpu, mask) \ - for ((cpu) = -1; \ - (cpu) = next_cpu((cpu), (mask)), \ - (cpu) < NR_CPUS; ) -#endif /* SMP */ - -#if NR_CPUS <= 64 - -#define for_each_cpu_mask_nr(cpu, mask) for_each_cpu_mask(cpu, mask) - -#else /* NR_CPUS > 64 */ - -int __next_cpu_nr(int n, const cpumask_t *srcp); -#define for_each_cpu_mask_nr(cpu, mask) \ - for ((cpu) = -1; \ - (cpu) = __next_cpu_nr((cpu), &(mask)), \ - (cpu) < nr_cpu_ids; ) - -#endif /* NR_CPUS > 64 */ - -#define cpus_addr(src) ((src).bits) - -#define cpu_set(cpu, dst) __cpu_set((cpu), &(dst)) -static inline void __cpu_set(int cpu, volatile cpumask_t *dstp) -{ - set_bit(cpu, dstp->bits); -} - -#define cpu_clear(cpu, dst) __cpu_clear((cpu), &(dst)) -static inline void __cpu_clear(int cpu, volatile cpumask_t *dstp) -{ - clear_bit(cpu, dstp->bits); -} - -#define cpus_setall(dst) __cpus_setall(&(dst), NR_CPUS) -static inline void __cpus_setall(cpumask_t *dstp, unsigned int nbits) -{ - bitmap_fill(dstp->bits, nbits); -} - -#define cpus_clear(dst) __cpus_clear(&(dst), NR_CPUS) -static inline void __cpus_clear(cpumask_t *dstp, unsigned int nbits) -{ - bitmap_zero(dstp->bits, nbits); -} - -/* No static inline type checking - see Subtlety (1) above. */ -#define cpu_isset(cpu, cpumask) test_bit((cpu), (cpumask).bits) - -#define cpu_test_and_set(cpu, cpumask) __cpu_test_and_set((cpu), &(cpumask)) -static inline int __cpu_test_and_set(int cpu, cpumask_t *addr) -{ - return test_and_set_bit(cpu, addr->bits); -} - -#define cpus_and(dst, src1, src2) __cpus_and(&(dst), &(src1), &(src2), NR_CPUS) -static inline int __cpus_and(cpumask_t *dstp, const cpumask_t *src1p, - const cpumask_t *src2p, unsigned int nbits) -{ - return bitmap_and(dstp->bits, src1p->bits, src2p->bits, nbits); -} - -#define cpus_or(dst, src1, src2) __cpus_or(&(dst), &(src1), &(src2), NR_CPUS) -static inline void __cpus_or(cpumask_t *dstp, const cpumask_t *src1p, - const cpumask_t *src2p, unsigned int nbits) -{ - bitmap_or(dstp->bits, src1p->bits, src2p->bits, nbits); -} - -#define cpus_xor(dst, src1, src2) __cpus_xor(&(dst), &(src1), &(src2), NR_CPUS) -static inline void __cpus_xor(cpumask_t *dstp, const cpumask_t *src1p, - const cpumask_t *src2p, unsigned int nbits) -{ - bitmap_xor(dstp->bits, src1p->bits, src2p->bits, nbits); -} - -#define cpus_andnot(dst, src1, src2) \ - __cpus_andnot(&(dst), &(src1), &(src2), NR_CPUS) -static inline int __cpus_andnot(cpumask_t *dstp, const cpumask_t *src1p, - const cpumask_t *src2p, unsigned int nbits) -{ - return bitmap_andnot(dstp->bits, src1p->bits, src2p->bits, nbits); -} - -#define cpus_equal(src1, src2) __cpus_equal(&(src1), &(src2), NR_CPUS) -static inline int __cpus_equal(const cpumask_t *src1p, - const cpumask_t *src2p, unsigned int nbits) -{ - return bitmap_equal(src1p->bits, src2p->bits, nbits); -} - -#define cpus_intersects(src1, src2) __cpus_intersects(&(src1), &(src2), NR_CPUS) -static inline int __cpus_intersects(const cpumask_t *src1p, - const cpumask_t *src2p, unsigned int nbits) -{ - return bitmap_intersects(src1p->bits, src2p->bits, nbits); -} - -#define cpus_subset(src1, src2) __cpus_subset(&(src1), &(src2), NR_CPUS) -static inline int __cpus_subset(const cpumask_t *src1p, - const cpumask_t *src2p, unsigned int nbits) -{ - return bitmap_subset(src1p->bits, src2p->bits, nbits); -} - -#define cpus_empty(src) __cpus_empty(&(src), NR_CPUS) -static inline int __cpus_empty(const cpumask_t *srcp, unsigned int nbits) -{ - return bitmap_empty(srcp->bits, nbits); -} - -#define cpus_weight(cpumask) __cpus_weight(&(cpumask), NR_CPUS) -static inline int __cpus_weight(const cpumask_t *srcp, unsigned int nbits) -{ - return bitmap_weight(srcp->bits, nbits); -} - -#define cpus_shift_left(dst, src, n) \ - __cpus_shift_left(&(dst), &(src), (n), NR_CPUS) -static inline void __cpus_shift_left(cpumask_t *dstp, - const cpumask_t *srcp, int n, int nbits) -{ - bitmap_shift_left(dstp->bits, srcp->bits, n, nbits); -} -#endif /* !CONFIG_DISABLE_OBSOLETE_CPUMASK_FUNCTIONS */ - #endif /* __LINUX_CPUMASK_H */ diff --git a/lib/Kconfig b/lib/Kconfig index 87da53bb1fef..47d262b3251e 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -397,10 +397,6 @@ config CPUMASK_OFFSTACK them on the stack. This is a bit more expensive, but avoids stack overflow. -config DISABLE_OBSOLETE_CPUMASK_FUNCTIONS - bool "Disable obsolete cpumask functions" if DEBUG_PER_CPU_MAPS - depends on BROKEN - config CPU_RMAP bool depends on SMP -- GitLab From c8ed00107b60b4a890798677d75e5c2910f393bb Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 5 Mar 2015 10:49:19 +1030 Subject: [PATCH 03638/11651] Fix weird uses of num_online_cpus(). This may be OK in archs with contiguous CPU numbers and without hotplug CPUs, but it sets a terrible example. And open-coding it like drivers/scsi/hpsa.c is just weird. BTRFS has a weird comparison with num_online_cpus() too, but since BTRFS just screwed up my test machines' root partition, I'm not touching it :) Signed-off-by: Rusty Russell Reported-by: Oleg Drokin --- arch/m32r/kernel/smpboot.c | 2 +- arch/sh/include/asm/mmu_context.h | 2 +- arch/sh/kernel/smp.c | 6 +++--- arch/um/kernel/smp.c | 2 +- drivers/scsi/hpsa.c | 6 ++---- 5 files changed, 8 insertions(+), 10 deletions(-) diff --git a/arch/m32r/kernel/smpboot.c b/arch/m32r/kernel/smpboot.c index bb21f4f63170..a468467542f4 100644 --- a/arch/m32r/kernel/smpboot.c +++ b/arch/m32r/kernel/smpboot.c @@ -376,7 +376,7 @@ void __init smp_cpus_done(unsigned int max_cpus) if (!cpumask_equal(&cpu_callin_map, cpu_online_mask)) BUG(); - for (cpu_id = 0 ; cpu_id < num_online_cpus() ; cpu_id++) + for_each_online_cpu(cpu_id) show_cpu_info(cpu_id); /* diff --git a/arch/sh/include/asm/mmu_context.h b/arch/sh/include/asm/mmu_context.h index b9d9489a5012..9f417feaf6e8 100644 --- a/arch/sh/include/asm/mmu_context.h +++ b/arch/sh/include/asm/mmu_context.h @@ -99,7 +99,7 @@ static inline int init_new_context(struct task_struct *tsk, { int i; - for (i = 0; i < num_online_cpus(); i++) + for_each_online_cpu(i) cpu_context(i, mm) = NO_CONTEXT; return 0; diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c index fc5acfc93c92..de6be008fc01 100644 --- a/arch/sh/kernel/smp.c +++ b/arch/sh/kernel/smp.c @@ -363,7 +363,7 @@ void flush_tlb_mm(struct mm_struct *mm) smp_call_function(flush_tlb_mm_ipi, (void *)mm, 1); } else { int i; - for (i = 0; i < num_online_cpus(); i++) + for_each_online_cpu(i) if (smp_processor_id() != i) cpu_context(i, mm) = 0; } @@ -400,7 +400,7 @@ void flush_tlb_range(struct vm_area_struct *vma, smp_call_function(flush_tlb_range_ipi, (void *)&fd, 1); } else { int i; - for (i = 0; i < num_online_cpus(); i++) + for_each_online_cpu(i) if (smp_processor_id() != i) cpu_context(i, mm) = 0; } @@ -443,7 +443,7 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long page) smp_call_function(flush_tlb_page_ipi, (void *)&fd, 1); } else { int i; - for (i = 0; i < num_online_cpus(); i++) + for_each_online_cpu(i) if (smp_processor_id() != i) cpu_context(i, vma->vm_mm) = 0; } diff --git a/arch/um/kernel/smp.c b/arch/um/kernel/smp.c index 74077892b34a..525c3657a6af 100644 --- a/arch/um/kernel/smp.c +++ b/arch/um/kernel/smp.c @@ -45,7 +45,7 @@ void smp_send_stop(void) int i; printk(KERN_INFO "Stopping all CPUs..."); - for (i = 0; i < num_online_cpus(); i++) { + for_each_online_cpu(i) { if (i == current_thread->cpu) continue; os_write_file(cpu_data[i].ipi_pipe[1], "S", 1); diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index a1cfbd3dda47..8eab107b53fb 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -6632,14 +6632,12 @@ static void fail_all_outstanding_cmds(struct ctlr_info *h) static void set_lockup_detected_for_all_cpus(struct ctlr_info *h, u32 value) { - int i, cpu; + int cpu; - cpu = cpumask_first(cpu_online_mask); - for (i = 0; i < num_online_cpus(); i++) { + for_each_online_cpu(cpu) { u32 *lockup_detected; lockup_detected = per_cpu_ptr(h->lockup_detected, cpu); *lockup_detected = value; - cpu = cpumask_next(cpu, cpu_online_mask); } wmb(); /* be sure the per-cpu variables are out to memory */ } -- GitLab From cdfdef75e795fb5ab76c66f3329e509f3ab8b9b5 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 5 Mar 2015 10:49:19 +1030 Subject: [PATCH 03639/11651] cpumask: only allocate nr_cpumask_bits. Now we'll find out the hard way if anyone has CPUMASK_OFFSTACK and is returning these or assigning them. Signed-off-by: Rusty Russell --- include/linux/cpumask.h | 5 ++--- lib/cpumask.c | 7 ------- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h index 646fadee5caf..4ad2d3c8e21f 100644 --- a/include/linux/cpumask.h +++ b/include/linux/cpumask.h @@ -11,6 +11,7 @@ #include #include +/* Don't assign or return these: may not be this big! */ typedef struct cpumask { DECLARE_BITMAP(bits, NR_CPUS); } cpumask_t; /** @@ -609,9 +610,7 @@ static inline int cpulist_parse(const char *buf, struct cpumask *dstp) */ static inline size_t cpumask_size(void) { - /* FIXME: Once all cpumask assignments are eliminated, this - * can be nr_cpumask_bits */ - return BITS_TO_LONGS(NR_CPUS) * sizeof(long); + return BITS_TO_LONGS(nr_cpumask_bits) * sizeof(long); } /* diff --git a/lib/cpumask.c b/lib/cpumask.c index b6513a9f2892..ba379d12bb57 100644 --- a/lib/cpumask.c +++ b/lib/cpumask.c @@ -89,13 +89,6 @@ bool alloc_cpumask_var_node(cpumask_var_t *mask, gfp_t flags, int node) dump_stack(); } #endif - /* FIXME: Bandaid to save us from old primitives which go to NR_CPUS. */ - if (*mask) { - unsigned char *ptr = (unsigned char *)cpumask_bits(*mask); - unsigned int tail; - tail = BITS_TO_LONGS(NR_CPUS - nr_cpumask_bits) * sizeof(long); - memset(ptr + cpumask_size() - tail, 0, tail); - } return *mask != NULL; } -- GitLab From 5778d39d070b4ac5f889928175b7f2d53ae7504e Mon Sep 17 00:00:00 2001 From: WANG Cong Date: Mon, 9 Mar 2015 17:03:40 -0700 Subject: [PATCH 03640/11651] net_sched: fix struct tc_u_hnode layout in u32 We dynamically allocate divisor+1 entries for ->ht[] in tc_u_hnode: ht = kzalloc(sizeof(*ht) + divisor*sizeof(void *), GFP_KERNEL); So ->ht is supposed to be the last field of this struct, however this is broken, since an rcu head is appended after it. Fixes: 1ce87720d456 ("net: sched: make cls_u32 lockless") Cc: Jamal Hadi Salim Cc: John Fastabend Signed-off-by: Cong Wang Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- net/sched/cls_u32.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index 09487afbfd51..95fdf4e40051 100644 --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c @@ -78,8 +78,11 @@ struct tc_u_hnode { struct tc_u_common *tp_c; int refcnt; unsigned int divisor; - struct tc_u_knode __rcu *ht[1]; struct rcu_head rcu; + /* The 'ht' field MUST be the last field in structure to allow for + * more entries allocated at end of structure. + */ + struct tc_u_knode __rcu *ht[1]; }; struct tc_u_common { -- GitLab From cd961bb9eebb630452f49dcbf3e5f0059428614a Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 28 Jan 2015 10:02:23 +0100 Subject: [PATCH 03641/11651] drm/mst: fix recursive sleep warning on qlock With drm-next, we can get a backtrace from sleeping with mutex detection. this is due to the callback checking the txmsg state taking the mutex, which can cause a sleep inside a sleep, Daniel went over it and was happy we could drop this mutex in this case. Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_dp_mst_topology.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index 9a5b68717ec8..379ab4555756 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c @@ -733,10 +733,14 @@ static bool check_txmsg_state(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_sideband_msg_tx *txmsg) { bool ret; - mutex_lock(&mgr->qlock); + + /* + * All updates to txmsg->state are protected by mgr->qlock, and the two + * cases we check here are terminal states. For those the barriers + * provided by the wake_up/wait_event pair are enough. + */ ret = (txmsg->state == DRM_DP_SIDEBAND_TX_RX || txmsg->state == DRM_DP_SIDEBAND_TX_TIMEOUT); - mutex_unlock(&mgr->qlock); return ret; } @@ -1363,12 +1367,13 @@ static int process_single_tx_qlock(struct drm_dp_mst_topology_mgr *mgr, return 0; } -/* must be called holding qlock */ static void process_single_down_tx_qlock(struct drm_dp_mst_topology_mgr *mgr) { struct drm_dp_sideband_msg_tx *txmsg; int ret; + WARN_ON(!mutex_is_locked(&mgr->qlock)); + /* construct a chunk from the first msg in the tx_msg queue */ if (list_empty(&mgr->tx_msg_downq)) { mgr->tx_down_in_progress = false; -- GitLab From aa836df958886e57ff0d43fb3d79d1af4aec0cc8 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 9 Mar 2015 14:31:20 -0700 Subject: [PATCH 03642/11651] net: core: add of_find_net_device_by_node() Add a helper function which allows getting the struct net_device pointer associated with a given struct device_node pointer. This is useful for instance for DSA Ethernet devices not backed by a platform_device, but a PCI device. Since we need to access net_class which is not accessible outside of net/core/net-sysfs.c, this helper function is also added here and gated with CONFIG_OF_NET. Network devices initialized with SET_NETDEV_DEV() are also taken into account by checking for dev->parent first and then falling back to checking the device pointer within struct net_device. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- include/linux/of_net.h | 8 ++++++++ net/core/net-sysfs.c | 25 +++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/include/linux/of_net.h b/include/linux/of_net.h index 34597c8c1a4c..9cd72aab76fe 100644 --- a/include/linux/of_net.h +++ b/include/linux/of_net.h @@ -9,8 +9,11 @@ #ifdef CONFIG_OF_NET #include + +struct net_device; extern int of_get_phy_mode(struct device_node *np); extern const void *of_get_mac_address(struct device_node *np); +extern struct net_device *of_find_net_device_by_node(struct device_node *np); #else static inline int of_get_phy_mode(struct device_node *np) { @@ -21,6 +24,11 @@ static inline const void *of_get_mac_address(struct device_node *np) { return NULL; } + +static inline struct net_device *of_find_net_device_by_node(struct device_node *np) +{ + return NULL; +} #endif #endif /* __LINUX_OF_NET_H */ diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index f2aa73bfb0e4..cf30620a88e1 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "net-sysfs.h" @@ -1374,6 +1375,30 @@ static struct class net_class = { .namespace = net_namespace, }; +#ifdef CONFIG_OF_NET +static int of_dev_node_match(struct device *dev, const void *data) +{ + int ret = 0; + + if (dev->parent) + ret = dev->parent->of_node == data; + + return ret == 0 ? dev->of_node == data : ret; +} + +struct net_device *of_find_net_device_by_node(struct device_node *np) +{ + struct device *dev; + + dev = class_find_device(&net_class, NULL, np, of_dev_node_match); + if (!dev) + return NULL; + + return to_net_dev(dev); +} +EXPORT_SYMBOL(of_find_net_device_by_node); +#endif + /* Delete sysfs entries but hold kobject reference until after all * netdev references are gone. */ -- GitLab From 769a020289bc8f68b7e48faf8fee970346d71a3b Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 9 Mar 2015 14:31:21 -0700 Subject: [PATCH 03643/11651] net: dsa: utilize of_find_net_device_by_node Using of_find_device_by_node() restricts the search to platform_device that match the specified device_node pointer. This is not even remotely true for network devices backed by a pci_device for instance. of_find_net_device_by_node() allows us to do a more thorough lookup to find the struct net_device corresponding to a particular device_node pointer. For symetry with the non-OF code path, we hold the net_device pointer in dsa_probe() just like what dev_to_net_dev() does when we call this function. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- include/net/dsa.h | 1 + net/dsa/dsa.c | 16 +++++++++++----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/include/net/dsa.h b/include/net/dsa.h index b525ac516559..47917e5e1e12 100644 --- a/include/net/dsa.h +++ b/include/net/dsa.h @@ -72,6 +72,7 @@ struct dsa_platform_data { * to the root switch chip of the tree. */ struct device *netdev; + struct net_device *of_netdev; /* * Info structs describing each of the switch chips diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c index b40f11bb419c..899772108ee3 100644 --- a/net/dsa/dsa.c +++ b/net/dsa/dsa.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include "dsa_priv.h" @@ -583,7 +584,7 @@ static int dsa_of_probe(struct device *dev) struct device_node *np = dev->of_node; struct device_node *child, *mdio, *ethernet, *port, *link; struct mii_bus *mdio_bus; - struct platform_device *ethernet_dev; + struct net_device *ethernet_dev; struct dsa_platform_data *pd; struct dsa_chip_data *cd; const char *port_name; @@ -604,7 +605,7 @@ static int dsa_of_probe(struct device *dev) if (!ethernet) return -EINVAL; - ethernet_dev = of_find_device_by_node(ethernet); + ethernet_dev = of_find_net_device_by_node(ethernet); if (!ethernet_dev) return -EPROBE_DEFER; @@ -613,7 +614,7 @@ static int dsa_of_probe(struct device *dev) return -ENOMEM; dev->platform_data = pd; - pd->netdev = ðernet_dev->dev; + pd->of_netdev = ethernet_dev; pd->nr_chips = of_get_available_child_count(np); if (pd->nr_chips > DSA_MAX_SWITCHES) pd->nr_chips = DSA_MAX_SWITCHES; @@ -771,10 +772,15 @@ static int dsa_probe(struct platform_device *pdev) pd = pdev->dev.platform_data; } - if (pd == NULL || pd->netdev == NULL) + if (pd == NULL || (pd->netdev == NULL && pd->of_netdev == NULL)) return -EINVAL; - dev = dev_to_net_device(pd->netdev); + if (pd->of_netdev) { + dev = pd->of_netdev; + dev_hold(dev); + } else { + dev = dev_to_net_device(pd->netdev); + } if (dev == NULL) { ret = -EPROBE_DEFER; goto out; -- GitLab From f8f2147150de303e814c0452075d467734d3544b Mon Sep 17 00:00:00 2001 From: Scott Feldman Date: Mon, 9 Mar 2015 13:59:09 -0700 Subject: [PATCH 03644/11651] switchdev: add netlink flags to IPv4 FIB add op Pass in the netlink flags (NLM_F_*) into switchdev driver for IPv4 FIB add op to allow driver to 1) optimize hardware updates, 2) handle ip route prepend and append commands correctly. Suggested-by: Jamal Hadi Salim Suggested-by: Roopa Prabhu Signed-off-by: Scott Feldman Reviewed-by: Simon Horman Acked-by: Roopa Prabhu Signed-off-by: David S. Miller --- drivers/net/ethernet/rocker/rocker.c | 3 ++- include/linux/netdevice.h | 3 ++- include/net/switchdev.h | 6 ++++-- net/ipv4/fib_trie.c | 5 ++++- net/switchdev/switchdev.c | 7 +++++-- 5 files changed, 17 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/rocker/rocker.c b/drivers/net/ethernet/rocker/rocker.c index 65e140315a58..223348d8cc07 100644 --- a/drivers/net/ethernet/rocker/rocker.c +++ b/drivers/net/ethernet/rocker/rocker.c @@ -4152,7 +4152,8 @@ static int rocker_port_switch_port_stp_update(struct net_device *dev, u8 state) static int rocker_port_switch_fib_ipv4_add(struct net_device *dev, __be32 dst, int dst_len, struct fib_info *fi, - u8 tos, u8 type, u32 tb_id) + u8 tos, u8 type, + u32 nlflags, u32 tb_id) { struct rocker_port *rocker_port = netdev_priv(dev); int flags = 0; diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 45413784a3b1..1354ae83efc8 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1035,7 +1035,7 @@ struct fib_info; * state change. * int (*ndo_sw_parent_fib_ipv4_add)(struct net_device *dev, __be32 dst, * int dst_len, struct fib_info *fi, - * u8 tos, u8 type, u32 tb_id); + * u8 tos, u8 type, u32 nlflags, u32 tb_id); * Called to add/modify IPv4 route to switch device. * int (*ndo_sw_parent_fib_ipv4_del)(struct net_device *dev, __be32 dst, * int dst_len, struct fib_info *fi, @@ -1207,6 +1207,7 @@ struct net_device_ops { int dst_len, struct fib_info *fi, u8 tos, u8 type, + u32 nlflags, u32 tb_id); int (*ndo_switch_fib_ipv4_del)(struct net_device *dev, __be32 dst, diff --git a/include/net/switchdev.h b/include/net/switchdev.h index 933fac410a7a..1a9382febcc3 100644 --- a/include/net/switchdev.h +++ b/include/net/switchdev.h @@ -1,6 +1,7 @@ /* * include/net/switchdev.h - Switch device API * Copyright (c) 2014 Jiri Pirko + * Copyright (c) 2014-2015 Scott Feldman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -52,7 +53,7 @@ int ndo_dflt_netdev_switch_port_bridge_dellink(struct net_device *dev, int ndo_dflt_netdev_switch_port_bridge_setlink(struct net_device *dev, struct nlmsghdr *nlh, u16 flags); int netdev_switch_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi, - u8 tos, u8 type, u32 tb_id); + u8 tos, u8 type, u32 nlflags, u32 tb_id); int netdev_switch_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi, u8 tos, u8 type, u32 tb_id); void netdev_switch_fib_ipv4_abort(struct fib_info *fi); @@ -117,7 +118,8 @@ static inline int ndo_dflt_netdev_switch_port_bridge_setlink(struct net_device * static inline int netdev_switch_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi, - u8 tos, u8 type, u32 tb_id) + u8 tos, u8 type, + u32 nlflags, u32 tb_id) { return 0; } diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 90955455884e..fcfa9825a816 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -1155,6 +1155,7 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg) err = netdev_switch_fib_ipv4_add(key, plen, fi, new_fa->fa_tos, cfg->fc_type, + cfg->fc_nlflags, tb->tb_id); if (err) { netdev_switch_fib_ipv4_abort(fi); @@ -1201,7 +1202,9 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg) /* (Optionally) offload fib entry to switch hardware. */ err = netdev_switch_fib_ipv4_add(key, plen, fi, tos, - cfg->fc_type, tb->tb_id); + cfg->fc_type, + cfg->fc_nlflags, + tb->tb_id); if (err) { netdev_switch_fib_ipv4_abort(fi); goto out_free_new_fa; diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c index aba6aa2656d8..8cf42a69baf4 100644 --- a/net/switchdev/switchdev.c +++ b/net/switchdev/switchdev.c @@ -1,6 +1,7 @@ /* * net/switchdev/switchdev.c - Switch device API * Copyright (c) 2014 Jiri Pirko + * Copyright (c) 2014-2015 Scott Feldman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -294,12 +295,13 @@ static struct net_device *netdev_switch_get_dev_by_nhs(struct fib_info *fi) * @fi: route FIB info structure * @tos: route TOS * @type: route type + * @nlflags: netlink flags passed in (NLM_F_*) * @tb_id: route table ID * * Add IPv4 route entry to switch device. */ int netdev_switch_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi, - u8 tos, u8 type, u32 tb_id) + u8 tos, u8 type, u32 nlflags, u32 tb_id) { struct net_device *dev; const struct net_device_ops *ops; @@ -324,7 +326,8 @@ int netdev_switch_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi, if (ops->ndo_switch_fib_ipv4_add) { err = ops->ndo_switch_fib_ipv4_add(dev, htonl(dst), dst_len, - fi, tos, type, tb_id); + fi, tos, type, nlflags, + tb_id); if (!err) fi->fib_flags |= RTNH_F_EXTERNAL; } -- GitLab From 59e33c2b021322db92ca27c4d9958e57630443b6 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 9 Mar 2015 15:44:13 -0700 Subject: [PATCH 03645/11651] net: phy: bcm7xxx: add alternate id for 7439 BCM7439 has an alternate PHY OUI: 0xae025080 which is to be found in some variants of this chip. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/phy/bcm7xxx.c | 1 + include/linux/brcmphy.h | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/net/phy/bcm7xxx.c b/drivers/net/phy/bcm7xxx.c index 974ec4515269..64c74c6a4828 100644 --- a/drivers/net/phy/bcm7xxx.c +++ b/drivers/net/phy/bcm7xxx.c @@ -396,6 +396,7 @@ static struct phy_driver bcm7xxx_driver[] = { BCM7XXX_28NM_GPHY(PHY_ID_BCM7364, "Broadcom BCM7364"), BCM7XXX_28NM_GPHY(PHY_ID_BCM7366, "Broadcom BCM7366"), BCM7XXX_28NM_GPHY(PHY_ID_BCM7439, "Broadcom BCM7439"), + BCM7XXX_28NM_GPHY(PHY_ID_BCM7439_2, "Broadcom BCM7439 (2)"), BCM7XXX_28NM_GPHY(PHY_ID_BCM7445, "Broadcom BCM7445"), { .phy_id = PHY_ID_BCM7425, diff --git a/include/linux/brcmphy.h b/include/linux/brcmphy.h index 7ccd928cc1f2..cab606617522 100644 --- a/include/linux/brcmphy.h +++ b/include/linux/brcmphy.h @@ -19,6 +19,7 @@ #define PHY_ID_BCM7425 0x03625e60 #define PHY_ID_BCM7429 0x600d8730 #define PHY_ID_BCM7439 0x600d8480 +#define PHY_ID_BCM7439_2 0xae025080 #define PHY_ID_BCM7445 0x600d8510 #define PHY_BCM_OUI_MASK 0xfffffc00 -- GitLab From 4736edc764b5464d625385ef89ed0c3c88b09897 Mon Sep 17 00:00:00 2001 From: Yongbae Park Date: Tue, 10 Mar 2015 11:15:39 +0900 Subject: [PATCH 03646/11651] ibmveth: enable interrupts after napi_complete() The interrupt is enabled before napi_complete(). A network timeout occurs if the interrupt handler is called before napi_complete(). Fix the bug by enabling the interrupt after napi_complete(). Signed-off-by: Yongbae Park Signed-off-by: David S. Miller --- drivers/net/ethernet/ibm/ibmveth.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c index 072426a72745..cd7675ac5bf9 100644 --- a/drivers/net/ethernet/ibm/ibmveth.c +++ b/drivers/net/ethernet/ibm/ibmveth.c @@ -1136,6 +1136,8 @@ restart_poll: ibmveth_replenish_task(adapter); if (frames_processed < budget) { + napi_complete(napi); + /* We think we are done - reenable interrupts, * then check once more to make sure we are done. */ @@ -1144,8 +1146,6 @@ restart_poll: BUG_ON(lpar_rc != H_SUCCESS); - napi_complete(napi); - if (ibmveth_rxq_pending_buffer(adapter) && napi_reschedule(napi)) { lpar_rc = h_vio_signal(adapter->vdev->unit_address, -- GitLab From 5a3dba7a5fcc02b78d92c35e2ca53f21ae3402c9 Mon Sep 17 00:00:00 2001 From: Yongbae Park Date: Tue, 10 Mar 2015 11:35:07 +0900 Subject: [PATCH 03647/11651] net: WIZnet drivers: enable interrupts after napi_complete() The interrupt is enabled before napi_complete(). A network timeout occurs if the interrupt handler is called before napi_complete(). Fix the bug by enabling the interrupt after napi_complete(). Signed-off-by: Yongbae Park Signed-off-by: David S. Miller --- drivers/net/ethernet/wiznet/w5100.c | 2 +- drivers/net/ethernet/wiznet/w5300.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/wiznet/w5100.c b/drivers/net/ethernet/wiznet/w5100.c index a495931a66a1..0e0fbb5842b3 100644 --- a/drivers/net/ethernet/wiznet/w5100.c +++ b/drivers/net/ethernet/wiznet/w5100.c @@ -498,9 +498,9 @@ static int w5100_napi_poll(struct napi_struct *napi, int budget) } if (rx_count < budget) { + napi_complete(napi); w5100_write(priv, W5100_IMR, IR_S0); mmiowb(); - napi_complete(napi); } return rx_count; diff --git a/drivers/net/ethernet/wiznet/w5300.c b/drivers/net/ethernet/wiznet/w5300.c index 09322d9db578..4b310002258d 100644 --- a/drivers/net/ethernet/wiznet/w5300.c +++ b/drivers/net/ethernet/wiznet/w5300.c @@ -418,9 +418,9 @@ static int w5300_napi_poll(struct napi_struct *napi, int budget) } if (rx_count < budget) { + napi_complete(napi); w5300_write(priv, W5300_IMR, IR_S0); mmiowb(); - napi_complete(napi); } return rx_count; -- GitLab From 44fb085bfa17628c6d2aaa6af6b292a8499e9cbd Mon Sep 17 00:00:00 2001 From: Wanpeng Li Date: Tue, 10 Mar 2015 12:20:00 +0800 Subject: [PATCH 03648/11651] sched/deadline: Add rq->clock update skip for dl task yield This patch adds rq->clock update skip for SCHED_DEADLINE task yield, to tell update_rq_clock() that we've just updated the clock, so that we don't do a microscopic update in schedule() and double the fastpath cost. Signed-off-by: Wanpeng Li Cc: Juri Lelli Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1425961200-3809-1-git-send-email-wanpeng.li@linux.intel.com Signed-off-by: Ingo Molnar --- kernel/sched/deadline.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c index 3fa8fa6d9403..0a81a954c041 100644 --- a/kernel/sched/deadline.c +++ b/kernel/sched/deadline.c @@ -914,6 +914,12 @@ static void yield_task_dl(struct rq *rq) } update_rq_clock(rq); update_curr_dl(rq); + /* + * Tell update_rq_clock() that we've just updated, + * so we don't do microscopic update in schedule() + * and double the fastpath cost. + */ + rq_clock_skip_update(rq, true); } #ifdef CONFIG_SMP -- GitLab From e7f180dcd8ab48f18b20d7e8a7e9b39192bdf8e0 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Tue, 10 Mar 2015 07:06:24 +0100 Subject: [PATCH 03649/11651] x86/fpu: Change xstateregs_get()/set() to use ->xsave.i387 rather than ->fxsave This is a cosmetic change: xstateregs_get() and xstateregs_set() abuse ->fxsave to access xsave->i387.sw_reserved. This practice is correct, ->fxsave and xsave->i387 share the same memory, but IMHO this looks confusing. And we can make this code more readable if we add a "struct xsave_struct *" local variable as well. Signed-off-by: Oleg Nesterov Signed-off-by: Borislav Petkov Reviewed-by: Rik van Riel Cc: Andy Lutomirski Cc: Borislav Petkov Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Tavis Ormandy Cc: Thomas Gleixner Link: http://lkml.kernel.org/r/1425967585-4725-1-git-send-email-bp@alien8.de Link: http://lkml.kernel.org/r/20150302183237.GB23085@redhat.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/i387.c | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/arch/x86/kernel/i387.c b/arch/x86/kernel/i387.c index 8416b5f85806..03cc0add8694 100644 --- a/arch/x86/kernel/i387.c +++ b/arch/x86/kernel/i387.c @@ -339,6 +339,7 @@ int xstateregs_get(struct task_struct *target, const struct user_regset *regset, unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) { + struct xsave_struct *xsave = &target->thread.fpu.state->xsave; int ret; if (!cpu_has_xsave) @@ -353,14 +354,12 @@ int xstateregs_get(struct task_struct *target, const struct user_regset *regset, * memory layout in the thread struct, so that we can copy the entire * xstateregs to the user using one user_regset_copyout(). */ - memcpy(&target->thread.fpu.state->fxsave.sw_reserved, - xstate_fx_sw_bytes, sizeof(xstate_fx_sw_bytes)); - + memcpy(&xsave->i387.sw_reserved, + xstate_fx_sw_bytes, sizeof(xstate_fx_sw_bytes)); /* * Copy the xstate memory layout. */ - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, - &target->thread.fpu.state->xsave, 0, -1); + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, xsave, 0, -1); return ret; } @@ -368,8 +367,8 @@ int xstateregs_set(struct task_struct *target, const struct user_regset *regset, unsigned int pos, unsigned int count, const void *kbuf, const void __user *ubuf) { + struct xsave_struct *xsave = &target->thread.fpu.state->xsave; int ret; - struct xsave_hdr_struct *xsave_hdr; if (!cpu_has_xsave) return -ENODEV; @@ -378,22 +377,16 @@ int xstateregs_set(struct task_struct *target, const struct user_regset *regset, if (ret) return ret; - ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, - &target->thread.fpu.state->xsave, 0, -1); - + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, xsave, 0, -1); /* * mxcsr reserved bits must be masked to zero for security reasons. */ - target->thread.fpu.state->fxsave.mxcsr &= mxcsr_feature_mask; - - xsave_hdr = &target->thread.fpu.state->xsave.xsave_hdr; - - xsave_hdr->xstate_bv &= pcntxt_mask; + xsave->i387.mxcsr &= mxcsr_feature_mask; + xsave->xsave_hdr.xstate_bv &= pcntxt_mask; /* * These bits must be zero. */ - memset(xsave_hdr->reserved, 0, 48); - + memset(&xsave->xsave_hdr.reserved, 0, 48); return ret; } -- GitLab From 1d23c4518b1f3a03c278f23333149245c178d2a6 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Tue, 10 Mar 2015 07:06:25 +0100 Subject: [PATCH 03650/11651] x86/fpu: Factor out memset(xstate, 0) in fpu_finit() paths fx_finit() has two users but only fpu_finit() needs to clear xstate, alloc_bootmem_align() in setup_init_fpu_buf() returns zero-filled memory. And note that both memset()'s look confusing. Yes, offsetof() is 0 for ->fxsave or ->fsave, but it would be cleaner to turn them into a single memset() which zeroes fpu->state. Signed-off-by: Oleg Nesterov Signed-off-by: Borislav Petkov Acked-by: Rik van Riel Cc: Andy Lutomirski Cc: Borislav Petkov Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Tavis Ormandy Cc: Thomas Gleixner Link: http://lkml.kernel.org/r/1425967585-4725-2-git-send-email-bp@alien8.de Link: http://lkml.kernel.org/r/20150302183257.GC23085@redhat.com Signed-off-by: Ingo Molnar --- arch/x86/include/asm/fpu-internal.h | 1 - arch/x86/kernel/i387.c | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/include/asm/fpu-internal.h b/arch/x86/include/asm/fpu-internal.h index 61609b963eab..5fa1be21ac2a 100644 --- a/arch/x86/include/asm/fpu-internal.h +++ b/arch/x86/include/asm/fpu-internal.h @@ -135,7 +135,6 @@ static __always_inline __pure bool use_fxsr(void) static inline void fx_finit(struct i387_fxsave_struct *fx) { - memset(fx, 0, xstate_size); fx->cwd = 0x37f; fx->mxcsr = MXCSR_DEFAULT; } diff --git a/arch/x86/kernel/i387.c b/arch/x86/kernel/i387.c index 03cc0add8694..0f3de6674ae3 100644 --- a/arch/x86/kernel/i387.c +++ b/arch/x86/kernel/i387.c @@ -224,11 +224,12 @@ void fpu_finit(struct fpu *fpu) return; } + memset(fpu->state, 0, xstate_size); + if (cpu_has_fxsr) { fx_finit(&fpu->state->fxsave); } else { struct i387_fsave_struct *fp = &fpu->state->fsave; - memset(fp, 0, xstate_size); fp->cwd = 0xffff037fu; fp->swd = 0xffff0000u; fp->twd = 0xffffffffu; -- GitLab From 549e783f6a1504fcd24576302bc3818538b677f0 Mon Sep 17 00:00:00 2001 From: "qipeng.zha" Date: Tue, 3 Mar 2015 18:13:22 +0800 Subject: [PATCH 03651/11651] pinctrl: update direction_output function of cherryview driver From the comments of gpiod_direction_output(), need to set @value as initial output, so update the lowlevel routine to make it work. Signed-off-by: jason.cj.chen Signed-off-by: qipeng.zha Acked-by: Mika Westerberg Signed-off-by: Linus Walleij --- drivers/pinctrl/intel/pinctrl-cherryview.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pinctrl/intel/pinctrl-cherryview.c b/drivers/pinctrl/intel/pinctrl-cherryview.c index 3034fd03bced..82f691eeeec4 100644 --- a/drivers/pinctrl/intel/pinctrl-cherryview.c +++ b/drivers/pinctrl/intel/pinctrl-cherryview.c @@ -1226,6 +1226,7 @@ static int chv_gpio_direction_input(struct gpio_chip *chip, unsigned offset) static int chv_gpio_direction_output(struct gpio_chip *chip, unsigned offset, int value) { + chv_gpio_set(chip, offset, value); return pinctrl_gpio_direction_output(chip->base + offset); } -- GitLab From 82ffb676c820629b7f1b62d15f6bc546f29a7025 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sun, 1 Mar 2015 22:31:34 +0800 Subject: [PATCH 03652/11651] phy: berlin-usb: Use PTR_ERR_OR_ZERO PTR_ERR_OR_ZERO simplifies the code. Signed-off-by: Axel Lin Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/phy-berlin-usb.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/phy/phy-berlin-usb.c b/drivers/phy/phy-berlin-usb.c index c8a8d53a6ece..9f7cc7eed292 100644 --- a/drivers/phy/phy-berlin-usb.c +++ b/drivers/phy/phy-berlin-usb.c @@ -202,10 +202,7 @@ static int phy_berlin_usb_probe(struct platform_device *pdev) phy_provider = devm_of_phy_provider_register(&pdev->dev, of_phy_simple_xlate); - if (IS_ERR(phy_provider)) - return PTR_ERR(phy_provider); - - return 0; + return PTR_ERR_OR_ZERO(phy_provider); } static struct platform_driver phy_berlin_usb_driver = { -- GitLab From 8fd0ea395f96b1419083f850190f175d5ddd98e9 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 5 Mar 2015 09:33:38 +0800 Subject: [PATCH 03653/11651] phy: xgene: Use PTR_ERR_OR_ZERO Also remove unneeded goto and rc variable. Signed-off-by: Axel Lin Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/phy-xgene.c | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/drivers/phy/phy-xgene.c b/drivers/phy/phy-xgene.c index 29214a36ea28..bae9cccc08f0 100644 --- a/drivers/phy/phy-xgene.c +++ b/drivers/phy/phy-xgene.c @@ -1657,7 +1657,6 @@ static int xgene_phy_probe(struct platform_device *pdev) struct phy_provider *phy_provider; struct xgene_phy_ctx *ctx; struct resource *res; - int rc = 0; u32 default_spd[] = DEFAULT_SATA_SPD_SEL; u32 default_txboost_gain[] = DEFAULT_SATA_TXBOOST_GAIN; u32 default_txeye_direction[] = DEFAULT_SATA_TXEYEDIRECTION; @@ -1676,10 +1675,8 @@ static int xgene_phy_probe(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ctx->sds_base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(ctx->sds_base)) { - rc = PTR_ERR(ctx->sds_base); - goto error; - } + if (IS_ERR(ctx->sds_base)) + return PTR_ERR(ctx->sds_base); /* Retrieve optional clock */ ctx->clk = clk_get(&pdev->dev, NULL); @@ -1710,22 +1707,12 @@ static int xgene_phy_probe(struct platform_device *pdev) ctx->phy = devm_phy_create(ctx->dev, NULL, &xgene_phy_ops); if (IS_ERR(ctx->phy)) { dev_dbg(&pdev->dev, "Failed to create PHY\n"); - rc = PTR_ERR(ctx->phy); - goto error; + return PTR_ERR(ctx->phy); } phy_set_drvdata(ctx->phy, ctx); - phy_provider = devm_of_phy_provider_register(ctx->dev, - xgene_phy_xlate); - if (IS_ERR(phy_provider)) { - rc = PTR_ERR(phy_provider); - goto error; - } - - return 0; - -error: - return rc; + phy_provider = devm_of_phy_provider_register(ctx->dev, xgene_phy_xlate); + return PTR_ERR_OR_ZERO(phy_provider); } static const struct of_device_id xgene_phy_of_match[] = { -- GitLab From f8f55393b2860a2a5c97ff3b18c6ee02cef021c4 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 5 Mar 2015 09:40:41 +0800 Subject: [PATCH 03654/11651] phy: berlin-sata: Use devm_kcalloc at appropriate place Prefer devm_kcalloc over devm_kzalloc with multiply. Signed-off-by: Axel Lin Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/phy-berlin-sata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/phy/phy-berlin-sata.c b/drivers/phy/phy-berlin-sata.c index 099eee8851e5..6f3e06d687de 100644 --- a/drivers/phy/phy-berlin-sata.c +++ b/drivers/phy/phy-berlin-sata.c @@ -218,7 +218,7 @@ static int phy_berlin_sata_probe(struct platform_device *pdev) if (priv->nphys == 0) return -ENODEV; - priv->phys = devm_kzalloc(dev, priv->nphys * sizeof(*priv->phys), + priv->phys = devm_kcalloc(dev, priv->nphys, sizeof(*priv->phys), GFP_KERNEL); if (!priv->phys) return -ENOMEM; -- GitLab From 320c3fcec64a9e115a3d8a5d005d2fb21c15ef01 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 5 Mar 2015 09:44:06 +0800 Subject: [PATCH 03655/11651] phy: miphy28lp: Use PTR_ERR_OR_ZERO PTR_ERR_OR_ZERO simplifies the code. Signed-off-by: Axel Lin Acked-by: Gabriel Fernandez Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/phy-miphy28lp.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/phy/phy-miphy28lp.c b/drivers/phy/phy-miphy28lp.c index 9b2848e6115d..174ffd037ef7 100644 --- a/drivers/phy/phy-miphy28lp.c +++ b/drivers/phy/phy-miphy28lp.c @@ -1258,10 +1258,7 @@ static int miphy28lp_probe(struct platform_device *pdev) } provider = devm_of_phy_provider_register(&pdev->dev, miphy28lp_xlate); - if (IS_ERR(provider)) - return PTR_ERR(provider); - - return 0; + return PTR_ERR_OR_ZERO(provider); } static const struct of_device_id miphy28lp_of_match[] = { -- GitLab From 1f9ba767d5918796c7f32724777087f321fde30d Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 5 Mar 2015 18:18:45 +0800 Subject: [PATCH 03656/11651] phy: omap-control: Remove unneeded ifdef CONFIG_OF guard and of_match_ptr if !CONFIG_OF, the probe fails. This is a dt-only driver, so the ifdef CONFIG_OF guard and of_match_ptr are not needed. Signed-off-by: Axel Lin Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/phy-omap-control.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/phy/phy-omap-control.c b/drivers/phy/phy-omap-control.c index efe724f97e02..a7653d930e6b 100644 --- a/drivers/phy/phy-omap-control.c +++ b/drivers/phy/phy-omap-control.c @@ -216,7 +216,6 @@ void omap_control_usb_set_mode(struct device *dev, return; ctrl_phy = dev_get_drvdata(dev); - if (!ctrl_phy) { dev_err(dev, "Invalid control phy device\n"); return; @@ -241,8 +240,6 @@ void omap_control_usb_set_mode(struct device *dev, } EXPORT_SYMBOL_GPL(omap_control_usb_set_mode); -#ifdef CONFIG_OF - static const enum omap_control_phy_type otghs_data = OMAP_CTRL_TYPE_OTGHS; static const enum omap_control_phy_type usb2_data = OMAP_CTRL_TYPE_USB2; static const enum omap_control_phy_type pipe3_data = OMAP_CTRL_TYPE_PIPE3; @@ -278,8 +275,6 @@ static const struct of_device_id omap_control_phy_id_table[] = { {}, }; MODULE_DEVICE_TABLE(of, omap_control_phy_id_table); -#endif - static int omap_control_phy_probe(struct platform_device *pdev) { @@ -287,8 +282,7 @@ static int omap_control_phy_probe(struct platform_device *pdev) const struct of_device_id *of_id; struct omap_control_phy *control_phy; - of_id = of_match_device(of_match_ptr(omap_control_phy_id_table), - &pdev->dev); + of_id = of_match_device(omap_control_phy_id_table, &pdev->dev); if (!of_id) return -EINVAL; @@ -344,7 +338,7 @@ static struct platform_driver omap_control_phy_driver = { .probe = omap_control_phy_probe, .driver = { .name = "omap-control-phy", - .of_match_table = of_match_ptr(omap_control_phy_id_table), + .of_match_table = omap_control_phy_id_table, }, }; -- GitLab From 52a4a72a1ad675b66ec241c0e33ee6e50df63a93 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 5 Mar 2015 18:20:07 +0800 Subject: [PATCH 03657/11651] phy: omap-usb2: Remove unneeded ifdef CONFIG_OF guard and of_match_ptr if !CONFIG_OF, the probe fails. This is a dt-only driver, so the ifdef CONFIG_OF guard and of_match_ptr are not needed. Signed-off-by: Axel Lin Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/phy-omap-usb2.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/phy/phy-omap-usb2.c b/drivers/phy/phy-omap-usb2.c index 6f4aef3db248..18b33cedadba 100644 --- a/drivers/phy/phy-omap-usb2.c +++ b/drivers/phy/phy-omap-usb2.c @@ -144,7 +144,6 @@ static struct phy_ops ops = { .owner = THIS_MODULE, }; -#ifdef CONFIG_OF static const struct usb_phy_data omap_usb2_data = { .label = "omap_usb2", .flags = OMAP_USB2_HAS_START_SRP | OMAP_USB2_HAS_SET_VBUS, @@ -185,7 +184,6 @@ static const struct of_device_id omap_usb2_id_table[] = { {}, }; MODULE_DEVICE_TABLE(of, omap_usb2_id_table); -#endif static int omap_usb2_probe(struct platform_device *pdev) { @@ -200,7 +198,7 @@ static int omap_usb2_probe(struct platform_device *pdev) const struct of_device_id *of_id; struct usb_phy_data *phy_data; - of_id = of_match_device(of_match_ptr(omap_usb2_id_table), &pdev->dev); + of_id = of_match_device(omap_usb2_id_table, &pdev->dev); if (!of_id) return -EINVAL; @@ -377,7 +375,7 @@ static struct platform_driver omap_usb2_driver = { .driver = { .name = "omap-usb2", .pm = DEV_PM_OPS, - .of_match_table = of_match_ptr(omap_usb2_id_table), + .of_match_table = omap_usb2_id_table, }, }; -- GitLab From 298fe56ee2b9551ca8cd675e7a6ebaf1c03632f8 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 5 Mar 2015 18:20:53 +0800 Subject: [PATCH 03658/11651] phy: ti-pipe3: Remove unneeded ifdef CONFIG_OF guard and of_match_ptr if !CONFIG_OF, the probe fails. This is a dt-only driver, so the ifdef CONFIG_OF guard and of_match_ptr are not needed. Signed-off-by: Axel Lin Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/phy-ti-pipe3.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/phy/phy-ti-pipe3.c b/drivers/phy/phy-ti-pipe3.c index 95c88f929f27..ad3fbc80e044 100644 --- a/drivers/phy/phy-ti-pipe3.c +++ b/drivers/phy/phy-ti-pipe3.c @@ -291,9 +291,7 @@ static struct phy_ops ops = { .owner = THIS_MODULE, }; -#ifdef CONFIG_OF static const struct of_device_id ti_pipe3_id_table[]; -#endif static int ti_pipe3_probe(struct platform_device *pdev) { @@ -315,8 +313,7 @@ static int ti_pipe3_probe(struct platform_device *pdev) spin_lock_init(&phy->lock); if (!of_device_is_compatible(node, "ti,phy-pipe3-pcie")) { - match = of_match_device(of_match_ptr(ti_pipe3_id_table), - &pdev->dev); + match = of_match_device(ti_pipe3_id_table, &pdev->dev); if (!match) return -EINVAL; @@ -574,7 +571,6 @@ static const struct dev_pm_ops ti_pipe3_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(ti_pipe3_suspend, ti_pipe3_resume) }; -#ifdef CONFIG_OF static const struct of_device_id ti_pipe3_id_table[] = { { .compatible = "ti,phy-usb3", @@ -594,7 +590,6 @@ static const struct of_device_id ti_pipe3_id_table[] = { {} }; MODULE_DEVICE_TABLE(of, ti_pipe3_id_table); -#endif static struct platform_driver ti_pipe3_driver = { .probe = ti_pipe3_probe, @@ -602,7 +597,7 @@ static struct platform_driver ti_pipe3_driver = { .driver = { .name = "ti-pipe3", .pm = &ti_pipe3_pm_ops, - .of_match_table = of_match_ptr(ti_pipe3_id_table), + .of_match_table = ti_pipe3_id_table, }, }; -- GitLab From 844285317c90910ab6e467b358df697f70e21417 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 25 Feb 2015 17:52:05 +0100 Subject: [PATCH 03659/11651] drm: Remove redundant code in the getencoder ioctl When enabling atomic state object for this ioctl in commit abd69c55dd8f1f71b33b8c6165217f4329db8f25 Author: Daniel Vetter Date: Tue Nov 25 23:50:05 2014 +0100 drm: Handle atomic state properly in kms getfoo ioctl I've forgotten to remove this hunk in one of the later revisions. drm_encoder_get_crtc already does this. Cc: Rob Clark Cc: Sean Paul Reviewed-by: Rob Clark Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_crtc.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 927f3445ff38..62f485c952e8 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -2285,8 +2285,6 @@ int drm_mode_getencoder(struct drm_device *dev, void *data, crtc = drm_encoder_get_crtc(encoder); if (crtc) enc_resp->crtc_id = crtc->base.id; - else if (encoder->crtc) - enc_resp->crtc_id = encoder->crtc->base.id; else enc_resp->crtc_id = 0; drm_modeset_unlock(&dev->mode_config.connection_mutex); -- GitLab From 2e3afd47ab0c1fe8742878e25ab06f10d4517e6e Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 26 Feb 2015 14:17:38 +0100 Subject: [PATCH 03660/11651] drm/atomic-helper: Fix kerneldoc for prepare_planes Copypaste-fail from cleanup_planes. Reported by Tvrtko. Cc: Tvrtko Ursulin Reviewed-by: Tvrtko Ursulin Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_atomic_helper.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 7715c40d4e74..a7458813af2b 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -1096,9 +1096,9 @@ EXPORT_SYMBOL(drm_atomic_helper_commit); */ /** - * drm_atomic_helper_prepare_planes - prepare plane resources after commit + * drm_atomic_helper_prepare_planes - prepare plane resources before commit * @dev: DRM device - * @state: atomic state object with old state structures + * @state: atomic state object with new state structures * * This function prepares plane state, specifically framebuffers, for the new * configuration. If any failure is encountered this function will call -- GitLab From bd5da992b96bc018c3e64ffc5ac15cbe301f6440 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 25 Feb 2015 14:46:51 +0200 Subject: [PATCH 03661/11651] drm/dp: indentation and ordering cleanups Keep the DPCD macros ordered by address, and make indentation conform to the rest of the file. commit e045d20bef41707dbba676e58624b54f9f39e172 Author: Sonika Jindal Date: Thu Feb 19 13:16:44 2015 +0530 drm: Adding edp1.4 specific dpcd macros Signed-off-by: Jani Nikula Reviewed-by: Sonika Jindal Signed-off-by: Daniel Vetter --- include/drm/drm_dp_helper.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index d4803224028f..98fefe45d158 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h @@ -92,9 +92,6 @@ # define DP_MSA_TIMING_PAR_IGNORED (1 << 6) /* eDP */ # define DP_OUI_SUPPORT (1 << 7) -#define DP_SUPPORTED_LINK_RATES 0x010 /*eDP 1.4*/ -#define DP_MAX_SUPPORTED_RATES 0x8 - #define DP_I2C_SPEED_CAP 0x00c /* DPI */ # define DP_I2C_SPEED_1K 0x01 # define DP_I2C_SPEED_5K 0x02 @@ -105,8 +102,12 @@ #define DP_EDP_CONFIGURATION_CAP 0x00d /* XXX 1.2? */ # define DP_DPCD_DISPLAY_CONTROL_CAPABLE (1 << 3) /* edp v1.2 or higher */ + #define DP_TRAINING_AUX_RD_INTERVAL 0x00e /* XXX 1.2? */ +#define DP_SUPPORTED_LINK_RATES 0x010 /* eDP 1.4 */ +# define DP_MAX_SUPPORTED_RATES 8 /* 16-bit little-endian */ + /* Multiple stream transport */ #define DP_FAUX_CAP 0x020 /* 1.2 */ # define DP_FAUX_CAP_1 (1 << 0) @@ -225,7 +226,7 @@ # define DP_UP_REQ_EN (1 << 1) # define DP_UPSTREAM_IS_SRC (1 << 2) -#define DP_LINK_RATE_SET 0x115 +#define DP_LINK_RATE_SET 0x115 /* eDP 1.4 */ #define DP_PSR_EN_CFG 0x170 /* XXX 1.2? */ # define DP_PSR_ENABLE (1 << 0) @@ -338,7 +339,7 @@ # define DP_SET_POWER_D3 0x2 # define DP_SET_POWER_MASK 0x3 -#define DP_EDP_DPCD_REV 0x700 +#define DP_EDP_DPCD_REV 0x700 /* eDP 1.2 */ #define DP_SIDEBAND_MSG_DOWN_REQ_BASE 0x1000 /* 1.2 MST */ #define DP_SIDEBAND_MSG_UP_REP_BASE 0x1200 /* 1.2 MST */ -- GitLab From 0e71244c1bb873f0e3be3b79d3436d7ef2601029 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 25 Feb 2015 14:46:53 +0200 Subject: [PATCH 03662/11651] drm/dp: add DPCD definitions from eDP 1.2 Mostly display control related DPCD addresses. Signed-off-by: Jani Nikula Reviewed-by: Sonika Jindal Signed-off-by: Daniel Vetter --- include/drm/drm_dp_helper.h | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index 98fefe45d158..a3ecaa06c9db 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h @@ -341,6 +341,38 @@ #define DP_EDP_DPCD_REV 0x700 /* eDP 1.2 */ +#define DP_EDP_GENERAL_CAP_1 0x701 + +#define DP_EDP_BACKLIGHT_ADJUSTMENT_CAP 0x702 + +#define DP_EDP_GENERAL_CAP_2 0x703 + +#define DP_EDP_DISPLAY_CONTROL_REGISTER 0x720 + +#define DP_EDP_BACKLIGHT_MODE_SET_REGISTER 0x721 + +#define DP_EDP_BACKLIGHT_BRIGHTNESS_MSB 0x722 +#define DP_EDP_BACKLIGHT_BRIGHTNESS_LSB 0x723 + +#define DP_EDP_PWMGEN_BIT_COUNT 0x724 +#define DP_EDP_PWMGEN_BIT_COUNT_CAP_MIN 0x725 +#define DP_EDP_PWMGEN_BIT_COUNT_CAP_MAX 0x726 + +#define DP_EDP_BACKLIGHT_CONTROL_STATUS 0x727 + +#define DP_EDP_BACKLIGHT_FREQ_SET 0x728 + +#define DP_EDP_BACKLIGHT_FREQ_CAP_MIN_MSB 0x72a +#define DP_EDP_BACKLIGHT_FREQ_CAP_MIN_MID 0x72b +#define DP_EDP_BACKLIGHT_FREQ_CAP_MIN_LSB 0x72c + +#define DP_EDP_BACKLIGHT_FREQ_CAP_MAX_MSB 0x72d +#define DP_EDP_BACKLIGHT_FREQ_CAP_MAX_MID 0x72e +#define DP_EDP_BACKLIGHT_FREQ_CAP_MAX_LSB 0x72f + +#define DP_EDP_DBC_MINIMUM_BRIGHTNESS_SET 0x732 +#define DP_EDP_DBC_MAXIMUM_BRIGHTNESS_SET 0x733 + #define DP_SIDEBAND_MSG_DOWN_REQ_BASE 0x1000 /* 1.2 MST */ #define DP_SIDEBAND_MSG_UP_REP_BASE 0x1200 /* 1.2 MST */ #define DP_SIDEBAND_MSG_DOWN_REP_BASE 0x1400 /* 1.2 MST */ -- GitLab From 4cda09ca5978f58866d41866bb9a92a7b631b782 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Thu, 26 Feb 2015 13:49:17 +0000 Subject: [PATCH 03663/11651] drm: Complete moving rotation property to core Commit 1da30627fc511a57c9bd23a02c97f0576379f761 "drm: Add rotation value to plane state" moved the rotation property to DRM core but only did the set property part. This does the get property part as well. Signed-off-by: Tvrtko Ursulin Cc: Matt Roper Cc: dri-devel@lists.freedesktop.org Reviewed-by: Matt Roper Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_atomic.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 321e098ddf04..7ca54cb6b15b 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -450,6 +450,8 @@ drm_atomic_plane_get_property(struct drm_plane *plane, *val = state->src_w; } else if (property == config->prop_src_h) { *val = state->src_h; + } else if (property == config->rotation_property) { + *val = state->rotation; } else if (plane->funcs->atomic_get_property) { return plane->funcs->atomic_get_property(plane, state, property, val); } else { -- GitLab From aaed1aa540acc6dde7dbba3307c98e697763ec1a Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Thu, 26 Feb 2015 13:49:18 +0000 Subject: [PATCH 03664/11651] drm/i915: Rotation property is now handled in DRM core So no need to have code which never gets called in the driver. Signed-off-by: Tvrtko Ursulin Cc: Matt Roper Cc: dri-devel@lists.freedesktop.org Reviewed-by: Matt Roper Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_atomic_plane.c | 24 ++++------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c index 9e6f727dfd19..976b89156570 100644 --- a/drivers/gpu/drm/i915/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/intel_atomic_plane.c @@ -203,16 +203,8 @@ intel_plane_atomic_get_property(struct drm_plane *plane, struct drm_property *property, uint64_t *val) { - struct drm_mode_config *config = &plane->dev->mode_config; - - if (property == config->rotation_property) { - *val = state->rotation; - } else { - DRM_DEBUG_KMS("Unknown plane property '%s'\n", property->name); - return -EINVAL; - } - - return 0; + DRM_DEBUG_KMS("Unknown plane property '%s'\n", property->name); + return -EINVAL; } /** @@ -233,14 +225,6 @@ intel_plane_atomic_set_property(struct drm_plane *plane, struct drm_property *property, uint64_t val) { - struct drm_mode_config *config = &plane->dev->mode_config; - - if (property == config->rotation_property) { - state->rotation = val; - } else { - DRM_DEBUG_KMS("Unknown plane property '%s'\n", property->name); - return -EINVAL; - } - - return 0; + DRM_DEBUG_KMS("Unknown plane property '%s'\n", property->name); + return -EINVAL; } -- GitLab From 220dd2bc43e23f72fcdf6cc6ced3107c7023f123 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 27 Feb 2015 12:58:13 +0100 Subject: [PATCH 03665/11651] drm: Fixup racy refcounting in plane_force_disable Originally it was impossible to be dropping the last refcount in this function since there was always one around still from the idr. But in commit 83f45fc360c8e16a330474860ebda872d1384c8c Author: Daniel Vetter Date: Wed Aug 6 09:10:18 2014 +0200 drm: Don't grab an fb reference for the idr we've switched to weak references, broke that assumption but forgot to fix it up. Since we still force-disable planes it's only possible to hit this when racing multiple rmfb with fbdev restoring or similar evil things. As long as userspace is nice it's impossible to hit the BUG_ON. But the BUG_ON would most likely be hit from fbdev code, which usually invovles the console_lock besides all modeset locks. So very likely we'd never get the bug reports if this was hit in the wild, hence better be safe than sorry and backport. Spotted by Matt Roper while reviewing other patches. Cc: stable@vger.kernel.org Cc: Matt Roper Reviewed-by: Matt Roper Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_crtc.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 62f485c952e8..c83e4db0adf7 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -524,17 +524,6 @@ void drm_framebuffer_reference(struct drm_framebuffer *fb) } EXPORT_SYMBOL(drm_framebuffer_reference); -static void drm_framebuffer_free_bug(struct kref *kref) -{ - BUG(); -} - -static void __drm_framebuffer_unreference(struct drm_framebuffer *fb) -{ - DRM_DEBUG("%p: FB ID: %d (%d)\n", fb, fb->base.id, atomic_read(&fb->refcount.refcount)); - kref_put(&fb->refcount, drm_framebuffer_free_bug); -} - /** * drm_framebuffer_unregister_private - unregister a private fb from the lookup idr * @fb: fb to unregister @@ -1319,7 +1308,7 @@ void drm_plane_force_disable(struct drm_plane *plane) return; } /* disconnect the plane from the fb and crtc: */ - __drm_framebuffer_unreference(plane->old_fb); + drm_framebuffer_unreference(plane->old_fb); plane->old_fb = NULL; plane->fb = NULL; plane->crtc = NULL; -- GitLab From 9474675afa9fe9d1145df0acb9fc15b6ad56a9f9 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 27 Feb 2015 13:10:38 +0200 Subject: [PATCH 03666/11651] drm/dp: add DPCD definitions from DP 1.1 and 1.2a Add a number of DPCD definitions from DP 1.1 and 1.2a. v2: drop wrong DP version reference, rename DP training set macros (Sonika). Reviewed-by: Sonika Jindal Signed-off-by: Jani Nikula Signed-off-by: Daniel Vetter --- include/drm/drm_dp_helper.h | 93 +++++++++++++++++++++++++++++++++++-- 1 file changed, 88 insertions(+), 5 deletions(-) diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index a3ecaa06c9db..319d5edfb3b5 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h @@ -92,6 +92,15 @@ # define DP_MSA_TIMING_PAR_IGNORED (1 << 6) /* eDP */ # define DP_OUI_SUPPORT (1 << 7) +#define DP_RECEIVE_PORT_0_CAP_0 0x008 +# define DP_LOCAL_EDID_PRESENT (1 << 1) +# define DP_ASSOCIATED_TO_PRECEDING_PORT (1 << 2) + +#define DP_RECEIVE_PORT_0_BUFFER_SIZE 0x009 + +#define DP_RECEIVE_PORT_1_CAP_0 0x00a +#define DP_RECEIVE_PORT_1_BUFFER_SIZE 0x00b + #define DP_I2C_SPEED_CAP 0x00c /* DPI */ # define DP_I2C_SPEED_1K 0x01 # define DP_I2C_SPEED_5K 0x02 @@ -101,10 +110,16 @@ # define DP_I2C_SPEED_1M 0x20 #define DP_EDP_CONFIGURATION_CAP 0x00d /* XXX 1.2? */ +# define DP_ALTERNATE_SCRAMBLER_RESET_CAP (1 << 0) +# define DP_FRAMING_CHANGE_CAP (1 << 1) # define DP_DPCD_DISPLAY_CONTROL_CAPABLE (1 << 3) /* edp v1.2 or higher */ #define DP_TRAINING_AUX_RD_INTERVAL 0x00e /* XXX 1.2? */ +#define DP_ADAPTER_CAP 0x00f /* 1.2 */ +# define DP_FORCE_LOAD_SENSE_CAP (1 << 0) +# define DP_ALTERNATE_I2C_PATTERN_CAP (1 << 1) + #define DP_SUPPORTED_LINK_RATES 0x010 /* eDP 1.4 */ # define DP_MAX_SUPPORTED_RATES 8 /* 16-bit little-endian */ @@ -115,6 +130,44 @@ #define DP_MSTM_CAP 0x021 /* 1.2 */ # define DP_MST_CAP (1 << 0) +#define DP_NUMBER_OF_AUDIO_ENDPOINTS 0x022 /* 1.2 */ + +/* AV_SYNC_DATA_BLOCK 1.2 */ +#define DP_AV_GRANULARITY 0x023 +# define DP_AG_FACTOR_MASK (0xf << 0) +# define DP_AG_FACTOR_3MS (0 << 0) +# define DP_AG_FACTOR_2MS (1 << 0) +# define DP_AG_FACTOR_1MS (2 << 0) +# define DP_AG_FACTOR_500US (3 << 0) +# define DP_AG_FACTOR_200US (4 << 0) +# define DP_AG_FACTOR_100US (5 << 0) +# define DP_AG_FACTOR_10US (6 << 0) +# define DP_AG_FACTOR_1US (7 << 0) +# define DP_VG_FACTOR_MASK (0xf << 4) +# define DP_VG_FACTOR_3MS (0 << 4) +# define DP_VG_FACTOR_2MS (1 << 4) +# define DP_VG_FACTOR_1MS (2 << 4) +# define DP_VG_FACTOR_500US (3 << 4) +# define DP_VG_FACTOR_200US (4 << 4) +# define DP_VG_FACTOR_100US (5 << 4) + +#define DP_AUD_DEC_LAT0 0x024 +#define DP_AUD_DEC_LAT1 0x025 + +#define DP_AUD_PP_LAT0 0x026 +#define DP_AUD_PP_LAT1 0x027 + +#define DP_VID_INTER_LAT 0x028 + +#define DP_VID_PROG_LAT 0x029 + +#define DP_REP_LAT 0x02a + +#define DP_AUD_DEL_INS0 0x02b +#define DP_AUD_DEL_INS1 0x02c +#define DP_AUD_DEL_INS2 0x02d +/* End of AV_SYNC_DATA_BLOCK */ + #define DP_GUID 0x030 /* 1.2 */ #define DP_PSR_SUPPORT 0x070 /* XXX 1.2? */ @@ -173,11 +226,12 @@ # define DP_TRAINING_PATTERN_3 3 /* 1.2 */ # define DP_TRAINING_PATTERN_MASK 0x3 -# define DP_LINK_QUAL_PATTERN_DISABLE (0 << 2) -# define DP_LINK_QUAL_PATTERN_D10_2 (1 << 2) -# define DP_LINK_QUAL_PATTERN_ERROR_RATE (2 << 2) -# define DP_LINK_QUAL_PATTERN_PRBS7 (3 << 2) -# define DP_LINK_QUAL_PATTERN_MASK (3 << 2) +/* DPCD 1.1 only. For DPCD >= 1.2 see per-lane DP_LINK_QUAL_LANEn_SET */ +# define DP_LINK_QUAL_PATTERN_11_DISABLE (0 << 2) +# define DP_LINK_QUAL_PATTERN_11_D10_2 (1 << 2) +# define DP_LINK_QUAL_PATTERN_11_ERROR_RATE (2 << 2) +# define DP_LINK_QUAL_PATTERN_11_PRBS7 (3 << 2) +# define DP_LINK_QUAL_PATTERN_11_MASK (3 << 2) # define DP_RECOVERED_CLOCK_OUT_EN (1 << 4) # define DP_LINK_SCRAMBLING_DISABLE (1 << 5) @@ -220,14 +274,43 @@ /* bitmask as for DP_I2C_SPEED_CAP */ #define DP_EDP_CONFIGURATION_SET 0x10a /* XXX 1.2? */ +# define DP_ALTERNATE_SCRAMBLER_RESET_ENABLE (1 << 0) +# define DP_FRAMING_CHANGE_ENABLE (1 << 1) +# define DP_PANEL_SELF_TEST_ENABLE (1 << 7) + +#define DP_LINK_QUAL_LANE0_SET 0x10b /* DPCD >= 1.2 */ +#define DP_LINK_QUAL_LANE1_SET 0x10c +#define DP_LINK_QUAL_LANE2_SET 0x10d +#define DP_LINK_QUAL_LANE3_SET 0x10e +# define DP_LINK_QUAL_PATTERN_DISABLE 0 +# define DP_LINK_QUAL_PATTERN_D10_2 1 +# define DP_LINK_QUAL_PATTERN_ERROR_RATE 2 +# define DP_LINK_QUAL_PATTERN_PRBS7 3 +# define DP_LINK_QUAL_PATTERN_80BIT_CUSTOM 4 +# define DP_LINK_QUAL_PATTERN_HBR2_EYE 5 +# define DP_LINK_QUAL_PATTERN_MASK 7 + +#define DP_TRAINING_LANE0_1_SET2 0x10f +#define DP_TRAINING_LANE2_3_SET2 0x110 +# define DP_LANE02_POST_CURSOR2_SET_MASK (3 << 0) +# define DP_LANE02_MAX_POST_CURSOR2_REACHED (1 << 2) +# define DP_LANE13_POST_CURSOR2_SET_MASK (3 << 4) +# define DP_LANE13_MAX_POST_CURSOR2_REACHED (1 << 6) #define DP_MSTM_CTRL 0x111 /* 1.2 */ # define DP_MST_EN (1 << 0) # define DP_UP_REQ_EN (1 << 1) # define DP_UPSTREAM_IS_SRC (1 << 2) +#define DP_AUDIO_DELAY0 0x112 /* 1.2 */ +#define DP_AUDIO_DELAY1 0x113 +#define DP_AUDIO_DELAY2 0x114 + #define DP_LINK_RATE_SET 0x115 /* eDP 1.4 */ +#define DP_UPSTREAM_DEVICE_DP_PWR_NEED 0x118 /* 1.2 */ +# define DP_PWR_NOT_NEEDED (1 << 0) + #define DP_PSR_EN_CFG 0x170 /* XXX 1.2? */ # define DP_PSR_ENABLE (1 << 0) # define DP_PSR_MAIN_LINK_ACTIVE (1 << 1) -- GitLab From 6b1e3f615482f308ae74af13fae6c1d9191d2906 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 27 Feb 2015 13:11:14 +0200 Subject: [PATCH 03667/11651] drm/dp: add DPCD definitions from eDP 1.4 Add a number of DPCD definitions from eDP 1.4. v2: s/DP_ALPM_LOCK_TIMEOUT_ERROR_STATUS/DP_ALPM_LOCK_TIMEOUT_ERROR/ (Sonika) Signed-off-by: Jani Nikula Reviewed-by: Sonika Jindal Signed-off-by: Daniel Vetter --- include/drm/drm_dp_helper.h | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index 319d5edfb3b5..c5fdc2d3ca97 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h @@ -168,10 +168,18 @@ #define DP_AUD_DEL_INS2 0x02d /* End of AV_SYNC_DATA_BLOCK */ +#define DP_RECEIVER_ALPM_CAP 0x02e /* eDP 1.4 */ +# define DP_ALPM_CAP (1 << 0) + +#define DP_SINK_DEVICE_AUX_FRAME_SYNC_CAP 0x02f /* eDP 1.4 */ +# define DP_AUX_FRAME_SYNC_CAP (1 << 0) + #define DP_GUID 0x030 /* 1.2 */ #define DP_PSR_SUPPORT 0x070 /* XXX 1.2? */ # define DP_PSR_IS_SUPPORTED 1 +# define DP_PSR2_IS_SUPPORTED 2 /* eDP 1.4 */ + #define DP_PSR_CAPS 0x071 /* XXX 1.2? */ # define DP_PSR_NO_TRAIN_ON_EXIT 1 # define DP_PSR_SETUP_TIME_330 (0 << 1) @@ -211,6 +219,7 @@ /* link configuration */ #define DP_LINK_BW_SET 0x100 +# define DP_LINK_RATE_TABLE 0x00 /* eDP 1.4 */ # define DP_LINK_BW_1_62 0x06 # define DP_LINK_BW_2_7 0x0a # define DP_LINK_BW_5_4 0x14 /* 1.2 */ @@ -307,15 +316,30 @@ #define DP_AUDIO_DELAY2 0x114 #define DP_LINK_RATE_SET 0x115 /* eDP 1.4 */ +# define DP_LINK_RATE_SET_SHIFT 0 +# define DP_LINK_RATE_SET_MASK (7 << 0) + +#define DP_RECEIVER_ALPM_CONFIG 0x116 /* eDP 1.4 */ +# define DP_ALPM_ENABLE (1 << 0) +# define DP_ALPM_LOCK_ERROR_IRQ_HPD_ENABLE (1 << 1) + +#define DP_SINK_DEVICE_AUX_FRAME_SYNC_CONF 0x117 /* eDP 1.4 */ +# define DP_AUX_FRAME_SYNC_ENABLE (1 << 0) +# define DP_IRQ_HPD_ENABLE (1 << 1) #define DP_UPSTREAM_DEVICE_DP_PWR_NEED 0x118 /* 1.2 */ # define DP_PWR_NOT_NEEDED (1 << 0) +#define DP_AUX_FRAME_SYNC_VALUE 0x15c /* eDP 1.4 */ +# define DP_AUX_FRAME_SYNC_VALID (1 << 0) + #define DP_PSR_EN_CFG 0x170 /* XXX 1.2? */ # define DP_PSR_ENABLE (1 << 0) # define DP_PSR_MAIN_LINK_ACTIVE (1 << 1) # define DP_PSR_CRC_VERIFICATION (1 << 2) # define DP_PSR_FRAME_CAPTURE (1 << 3) +# define DP_PSR_SELECTIVE_UPDATE (1 << 4) +# define DP_PSR_IRQ_HPD_WITH_CRC_ERRORS (1 << 5) #define DP_ADAPTER_CTRL 0x1a0 # define DP_ADAPTER_CTRL_FORCE_LOAD_SENSE (1 << 0) @@ -423,6 +447,10 @@ # define DP_SET_POWER_MASK 0x3 #define DP_EDP_DPCD_REV 0x700 /* eDP 1.2 */ +# define DP_EDP_11 0x00 +# define DP_EDP_12 0x01 +# define DP_EDP_13 0x02 +# define DP_EDP_14 0x03 #define DP_EDP_GENERAL_CAP_1 0x701 @@ -430,6 +458,8 @@ #define DP_EDP_GENERAL_CAP_2 0x703 +#define DP_EDP_GENERAL_CAP_3 0x704 /* eDP 1.4 */ + #define DP_EDP_DISPLAY_CONTROL_REGISTER 0x720 #define DP_EDP_BACKLIGHT_MODE_SET_REGISTER 0x721 @@ -456,6 +486,9 @@ #define DP_EDP_DBC_MINIMUM_BRIGHTNESS_SET 0x732 #define DP_EDP_DBC_MAXIMUM_BRIGHTNESS_SET 0x733 +#define DP_EDP_REGIONAL_BACKLIGHT_BASE 0x740 /* eDP 1.4 */ +#define DP_EDP_REGIONAL_BACKLIGHT_0 0x741 /* eDP 1.4 */ + #define DP_SIDEBAND_MSG_DOWN_REQ_BASE 0x1000 /* 1.2 MST */ #define DP_SIDEBAND_MSG_UP_REP_BASE 0x1200 /* 1.2 MST */ #define DP_SIDEBAND_MSG_DOWN_REP_BASE 0x1400 /* 1.2 MST */ @@ -474,6 +507,7 @@ #define DP_PSR_ERROR_STATUS 0x2006 /* XXX 1.2? */ # define DP_PSR_LINK_CRC_ERROR (1 << 0) # define DP_PSR_RFB_STORAGE_ERROR (1 << 1) +# define DP_PSR_VSC_SDP_UNCORRECTABLE_ERROR (1 << 2) /* eDP 1.4 */ #define DP_PSR_ESI 0x2007 /* XXX 1.2? */ # define DP_PSR_CAPS_CHANGE (1 << 0) @@ -487,6 +521,9 @@ # define DP_PSR_SINK_INTERNAL_ERROR 7 # define DP_PSR_SINK_STATE_MASK 0x07 +#define DP_RECEIVER_ALPM_STATUS 0x200b /* eDP 1.4 */ +# define DP_ALPM_LOCK_TIMEOUT_ERROR (1 << 0) + /* DP 1.2 Sideband message defines */ /* peer device type - DP 1.2a Table 2-92 */ #define DP_PEER_DEVICE_NONE 0x0 -- GitLab From 2a97acd6376922bb9d23b5f4421745d2a6690060 Mon Sep 17 00:00:00 2001 From: Yannick Guerrini Date: Wed, 4 Mar 2015 09:30:09 +0100 Subject: [PATCH 03668/11651] drm: Fix trivial typos in comments Change 'pixes' to 'pixels' Change 'enabel' to 'enable' Change 'enabeling' to 'enabling' Signed-off-by: Yannick Guerrini Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_modes.c | 4 ++-- drivers/gpu/drm/i2c/adv7511.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index 487d0e35c134..2cca85f23138 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c @@ -278,7 +278,7 @@ struct drm_display_mode *drm_cvt_mode(struct drm_device *dev, int hdisplay, hblank = drm_mode->hdisplay * hblank_percentage / (100 * HV_FACTOR - hblank_percentage); hblank -= hblank % (2 * CVT_H_GRANULARITY); - /* 14. find the total pixes per line */ + /* 14. find the total pixels per line */ drm_mode->htotal = drm_mode->hdisplay + hblank; drm_mode->hsync_end = drm_mode->hdisplay + hblank / 2; drm_mode->hsync_start = drm_mode->hsync_end - @@ -1209,7 +1209,7 @@ EXPORT_SYMBOL(drm_mode_connector_list_update); * x[M][R][-][@][i][m][eDd] * * The intermediate drm_cmdline_mode structure is required to store additional - * options from the command line modline like the force-enabel/disable flag. + * options from the command line modline like the force-enable/disable flag. * * Returns: * True if a valid modeline has been parsed, false otherwise. diff --git a/drivers/gpu/drm/i2c/adv7511.c b/drivers/gpu/drm/i2c/adv7511.c index fa140e04d5fa..61aa824d45d2 100644 --- a/drivers/gpu/drm/i2c/adv7511.c +++ b/drivers/gpu/drm/i2c/adv7511.c @@ -573,7 +573,7 @@ static void adv7511_encoder_dpms(struct drm_encoder *encoder, int mode) * goes low the adv7511 is reset and the outputs are disabled * which might cause the monitor to go to standby again. To * avoid this we ignore the HDP pin for the first few seconds - * after enabeling the output. + * after enabling the output. */ regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2, ADV7511_REG_POWER2_HDP_SRC_MASK, -- GitLab From ead8610d42105a3d01f755522f11b96c60dc648f Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 5 Mar 2015 02:25:43 +0200 Subject: [PATCH 03669/11651] drm: Share plane pixel format check code between legacy and atomic Both the legacy and atomic helpers need to check whether a plane supports a given pixel format. The code is currently duplicated, share it. Signed-off-by: Laurent Pinchart [danvet: Slightly extend the docbook.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_atomic.c | 10 ++++------ drivers/gpu/drm/drm_crtc.c | 29 +++++++++++++++++++++++------ include/drm/drm_crtc.h | 2 ++ 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 7ca54cb6b15b..a6caaae40b9e 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -475,7 +475,7 @@ static int drm_atomic_plane_check(struct drm_plane *plane, struct drm_plane_state *state) { unsigned int fb_width, fb_height; - unsigned int i; + int ret; /* either *both* CRTC and FB must be set, or neither */ if (WARN_ON(state->crtc && !state->fb)) { @@ -497,13 +497,11 @@ static int drm_atomic_plane_check(struct drm_plane *plane, } /* Check whether this plane supports the fb pixel format. */ - for (i = 0; i < plane->format_count; i++) - if (state->fb->pixel_format == plane->format_types[i]) - break; - if (i == plane->format_count) { + ret = drm_plane_check_pixel_format(plane, state->fb->pixel_format); + if (ret) { DRM_DEBUG_ATOMIC("Invalid pixel format %s\n", drm_get_format_name(state->fb->pixel_format)); - return -EINVAL; + return ret; } /* Give drivers some help against integer overflows */ diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index c83e4db0adf7..447db50e6838 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -2408,6 +2408,27 @@ int drm_mode_getplane(struct drm_device *dev, void *data, return 0; } +/** + * drm_plane_check_pixel_format - Check if the plane supports the pixel format + * @plane: plane to check for format support + * @format: the pixel format + * + * Returns: + * Zero of @plane has @format in its list of supported pixel formats, -EINVAL + * otherwise. + */ +int drm_plane_check_pixel_format(const struct drm_plane *plane, u32 format) +{ + unsigned int i; + + for (i = 0; i < plane->format_count; i++) { + if (format == plane->format_types[i]) + return 0; + } + + return -EINVAL; +} + /* * setplane_internal - setplane handler for internal callers * @@ -2428,7 +2449,6 @@ static int __setplane_internal(struct drm_plane *plane, { int ret = 0; unsigned int fb_width, fb_height; - unsigned int i; /* No fb means shut it down */ if (!fb) { @@ -2451,13 +2471,10 @@ static int __setplane_internal(struct drm_plane *plane, } /* Check whether this plane supports the fb pixel format. */ - for (i = 0; i < plane->format_count; i++) - if (fb->pixel_format == plane->format_types[i]) - break; - if (i == plane->format_count) { + ret = drm_plane_check_pixel_format(plane, fb->pixel_format); + if (ret) { DRM_DEBUG_KMS("Invalid pixel format %s\n", drm_get_format_name(fb->pixel_format)); - ret = -EINVAL; goto out; } diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index b1465d6fbe94..da83d39e37d4 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -1263,6 +1263,8 @@ extern int drm_plane_init(struct drm_device *dev, extern void drm_plane_cleanup(struct drm_plane *plane); extern unsigned int drm_plane_index(struct drm_plane *plane); extern void drm_plane_force_disable(struct drm_plane *plane); +extern int drm_plane_check_pixel_format(const struct drm_plane *plane, + u32 format); extern void drm_crtc_get_hv_timing(const struct drm_display_mode *mode, int *hdisplay, int *vdisplay); extern int drm_crtc_check_viewport(const struct drm_crtc *crtc, -- GitLab From 3461b30b3e171e16498f3d7bc59ab703aec475c8 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 5 Mar 2015 10:32:44 +0100 Subject: [PATCH 03670/11651] drm/plane-helper: unexport drm_primary_helper_create_plane We shouldn't tempt driver writers into using this since it uses a default format list which is likely wrong. And when that's done we can simplify the code a bit, too. Noticed while reviewing a patch from Laurent. Cc: Laurent Pinchart Cc: Matt Roper Reviewed-by: Matt Roper Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_plane_helper.c | 26 ++++---------------------- include/drm/drm_plane_helper.h | 4 ---- 2 files changed, 4 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/drm_plane_helper.c b/drivers/gpu/drm/drm_plane_helper.c index 813a06627eb3..8e56783265e1 100644 --- a/drivers/gpu/drm/drm_plane_helper.c +++ b/drivers/gpu/drm/drm_plane_helper.c @@ -344,20 +344,7 @@ const struct drm_plane_funcs drm_primary_helper_funcs = { }; EXPORT_SYMBOL(drm_primary_helper_funcs); -/** - * drm_primary_helper_create_plane() - Create a generic primary plane - * @dev: drm device - * @formats: pixel formats supported, or NULL for a default safe list - * @num_formats: size of @formats; ignored if @formats is NULL - * - * Allocates and initializes a primary plane that can be used with the primary - * plane helpers. Drivers that wish to use driver-specific plane structures or - * provide custom handler functions may perform their own allocation and - * initialization rather than calling this function. - */ -struct drm_plane *drm_primary_helper_create_plane(struct drm_device *dev, - const uint32_t *formats, - int num_formats) +static struct drm_plane *create_primary_plane(struct drm_device *dev) { struct drm_plane *primary; int ret; @@ -368,15 +355,11 @@ struct drm_plane *drm_primary_helper_create_plane(struct drm_device *dev, return NULL; } - if (formats == NULL) { - formats = safe_modeset_formats; - num_formats = ARRAY_SIZE(safe_modeset_formats); - } - /* possible_crtc's will be filled in later by crtc_init */ ret = drm_universal_plane_init(dev, primary, 0, &drm_primary_helper_funcs, - formats, num_formats, + safe_modeset_formats, + ARRAY_SIZE(safe_modeset_formats), DRM_PLANE_TYPE_PRIMARY); if (ret) { kfree(primary); @@ -385,7 +368,6 @@ struct drm_plane *drm_primary_helper_create_plane(struct drm_device *dev, return primary; } -EXPORT_SYMBOL(drm_primary_helper_create_plane); /** * drm_crtc_init - Legacy CRTC initialization function @@ -404,7 +386,7 @@ int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, { struct drm_plane *primary; - primary = drm_primary_helper_create_plane(dev, NULL, 0); + primary = create_primary_plane(dev); return drm_crtc_init_with_planes(dev, crtc, primary, NULL, funcs); } EXPORT_SYMBOL(drm_crtc_init); diff --git a/include/drm/drm_plane_helper.h b/include/drm/drm_plane_helper.h index 72ddab02ebd9..e48157a5a59c 100644 --- a/include/drm/drm_plane_helper.h +++ b/include/drm/drm_plane_helper.h @@ -100,10 +100,6 @@ extern int drm_primary_helper_update(struct drm_plane *plane, extern int drm_primary_helper_disable(struct drm_plane *plane); extern void drm_primary_helper_destroy(struct drm_plane *plane); extern const struct drm_plane_funcs drm_primary_helper_funcs; -extern struct drm_plane *drm_primary_helper_create_plane(struct drm_device *dev, - const uint32_t *formats, - int num_formats); - int drm_plane_helper_update(struct drm_plane *plane, struct drm_crtc *crtc, struct drm_framebuffer *fb, -- GitLab From c484f02d0f02fbbfc6decc945a69aae011041a27 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 6 Mar 2015 12:36:42 +0000 Subject: [PATCH 03671/11651] drm: Lighten sysfs connector 'status' Since the beginning, sysfs/connector/status has done a heavyweight detection of the current connector status. But no user, such as upowerd or logind, has ever desired to initiate a probe. Move the probing into a new attribute so that existing readers get the behaviour they desire. v2: David Herrmann suggested using "echo detect > /sys/.../status" to trigger the probing, which is a fine idea. This extends that to also allow the user to apply the force detection overrides at runtime. v3: Now with airlied's email address fixed! Requires sysfs_streq() Signed-off-by: Chris Wilson Cc: Daniel Vetter Cc: David Herrmann Cc: Dave Airlie Cc: Alex Deucher Reviewed-by: David Herrmann Reviewed-by: Alex Deucher Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_sysfs.c | 61 ++++++++++++++++++++++++++++++++----- 1 file changed, 53 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c index 5c99d3773212..ffc305fc2076 100644 --- a/drivers/gpu/drm/drm_sysfs.c +++ b/drivers/gpu/drm/drm_sysfs.c @@ -166,23 +166,68 @@ void drm_sysfs_destroy(void) /* * Connector properties */ -static ssize_t status_show(struct device *device, +static ssize_t status_store(struct device *device, struct device_attribute *attr, - char *buf) + const char *buf, size_t count) { struct drm_connector *connector = to_drm_connector(device); - enum drm_connector_status status; + struct drm_device *dev = connector->dev; + enum drm_connector_status old_status; int ret; - ret = mutex_lock_interruptible(&connector->dev->mode_config.mutex); + ret = mutex_lock_interruptible(&dev->mode_config.mutex); if (ret) return ret; - status = connector->funcs->detect(connector, true); - mutex_unlock(&connector->dev->mode_config.mutex); + old_status = connector->status; + + if (sysfs_streq(buf, "detect")) { + connector->force = 0; + connector->status = connector->funcs->detect(connector, true); + } else if (sysfs_streq(buf, "on")) { + connector->force = DRM_FORCE_ON; + } else if (sysfs_streq(buf, "on-digital")) { + connector->force = DRM_FORCE_ON_DIGITAL; + } else if (sysfs_streq(buf, "off")) { + connector->force = DRM_FORCE_OFF; + } else + ret = -EINVAL; + + if (ret == 0 && connector->force) { + if (connector->force == DRM_FORCE_ON || + connector->force == DRM_FORCE_ON_DIGITAL) + connector->status = connector_status_connected; + else + connector->status = connector_status_disconnected; + if (connector->funcs->force) + connector->funcs->force(connector); + } + + if (old_status != connector->status) { + DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %d to %d\n", + connector->base.id, + connector->name, + old_status, connector->status); + + dev->mode_config.delayed_event = true; + if (dev->mode_config.poll_enabled) + schedule_delayed_work(&dev->mode_config.output_poll_work, + 0); + } + + mutex_unlock(&dev->mode_config.mutex); + + return ret; +} + +static ssize_t status_show(struct device *device, + struct device_attribute *attr, + char *buf) +{ + struct drm_connector *connector = to_drm_connector(device); return snprintf(buf, PAGE_SIZE, "%s\n", - drm_get_connector_status_name(status)); + drm_get_connector_status_name(connector->status)); } static ssize_t dpms_show(struct device *device, @@ -339,7 +384,7 @@ static ssize_t select_subconnector_show(struct device *device, drm_get_dvi_i_select_name((int)subconnector)); } -static DEVICE_ATTR_RO(status); +static DEVICE_ATTR_RW(status); static DEVICE_ATTR_RO(enabled); static DEVICE_ATTR_RO(dpms); static DEVICE_ATTR_RO(modes); -- GitLab From 7eb5f302bbe78b88da8b2008c502c1975e75db05 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Mon, 9 Mar 2015 10:41:07 +0200 Subject: [PATCH 03672/11651] drm: Check in setcrtc if the primary plane supports the fb pixel format Drivers implementing the universal planes API report the list of supported pixel formats for the primary plane. Make sure the fb passed to the setcrtc ioctl is compatible. Drivers not implementing the universal planes API will have no format reported for the primary plane, skip the check in that case. Signed-off-by: Laurent Pinchart Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_crtc.c | 17 +++++++++++++++++ drivers/gpu/drm/drm_plane_helper.c | 5 +++++ include/drm/drm_crtc.h | 2 ++ 3 files changed, 24 insertions(+) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 447db50e6838..5785336695ca 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -2798,6 +2798,23 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data, drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V); + /* + * Check whether the primary plane supports the fb pixel format. + * Drivers not implementing the universal planes API use a + * default formats list provided by the DRM core which doesn't + * match real hardware capabilities. Skip the check in that + * case. + */ + if (!crtc->primary->format_default) { + ret = drm_plane_check_pixel_format(crtc->primary, + fb->pixel_format); + if (ret) { + DRM_DEBUG_KMS("Invalid pixel format %s\n", + drm_get_format_name(fb->pixel_format)); + goto out; + } + } + ret = drm_crtc_check_viewport(crtc, crtc_req->x, crtc_req->y, mode, fb); if (ret) diff --git a/drivers/gpu/drm/drm_plane_helper.c b/drivers/gpu/drm/drm_plane_helper.c index 8e56783265e1..b62b03635050 100644 --- a/drivers/gpu/drm/drm_plane_helper.c +++ b/drivers/gpu/drm/drm_plane_helper.c @@ -353,6 +353,11 @@ static struct drm_plane *create_primary_plane(struct drm_device *dev) if (primary == NULL) { DRM_DEBUG_KMS("Failed to allocate primary plane\n"); return NULL; + /* + * Remove the format_default field from drm_plane when dropping + * this helper. + */ + primary->format_default = true; } /* possible_crtc's will be filled in later by crtc_init */ diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index da83d39e37d4..adc9ea5acf02 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -830,6 +830,7 @@ enum drm_plane_type { * @possible_crtcs: pipes this plane can be bound to * @format_types: array of formats supported by this plane * @format_count: number of formats supported + * @format_default: driver hasn't supplied supported formats for the plane * @crtc: currently bound CRTC * @fb: currently bound fb * @old_fb: Temporary tracking of the old fb while a modeset is ongoing. Used by @@ -850,6 +851,7 @@ struct drm_plane { uint32_t possible_crtcs; uint32_t *format_types; uint32_t format_count; + bool format_default; struct drm_crtc *crtc; struct drm_framebuffer *fb; -- GitLab From 6c51d46f135b00c00373fcd029786ccef2b02b5b Mon Sep 17 00:00:00 2001 From: Dave Gordon Date: Fri, 6 Mar 2015 15:34:26 +0000 Subject: [PATCH 03673/11651] drm/i915: use in_interrupt() not in_irq() to check context The kernel in_irq() function tests for hard-IRQ context only, so if a system is run with the kernel 'threadirqs' option selected, the test in intel_check_page_flip() generates lots of warnings, because then it gets called in soft-IRQ context. We can instead use in_interrupt() which allows for either type of interrupt, while still detecting and complaining about misuse of the page flip code if it is ever called from non-interrupt context. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=89321 Signed-off-by: Dave Gordon Reviewed-by: Daniel Vetter Cc: stable@vger.kernel.org Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e730789b53b7..9943c20a741d 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -9716,7 +9716,7 @@ void intel_check_page_flip(struct drm_device *dev, int pipe) struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - WARN_ON(!in_irq()); + WARN_ON(!in_interrupt()); if (crtc == NULL) return; -- GitLab From 0e4f93e5017d9d8080bbd34db17836e090eb46fe Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Tue, 10 Mar 2015 10:45:30 +0100 Subject: [PATCH 03674/11651] goldfish: goldfish_tty_probe() is not using 'i' any more The only place where 'i' has been used was a dead code that got removed by 2a2483685a9de ("goldfish: remove unreachable line of code"). Remove the last reference to the variable as well. Fixes: 2a2483685a9de ("goldfish: remove unreachable line of code") Reported-by: Stephen Rothwell Signed-off-by: Jiri Kosina --- drivers/tty/goldfish.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/tty/goldfish.c b/drivers/tty/goldfish.c index e423550c3516..d6e332cba3ea 100644 --- a/drivers/tty/goldfish.c +++ b/drivers/tty/goldfish.c @@ -229,7 +229,6 @@ static int goldfish_tty_probe(struct platform_device *pdev) { struct goldfish_tty *qtty; int ret = -EINVAL; - int i; struct resource *r; struct device *ttydev; void __iomem *base; -- GitLab From 9b2de7ff424220c731276aaef9025cdd1d4052a8 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 8 Mar 2015 22:07:41 +0200 Subject: [PATCH 03675/11651] crypto: octeon - don't disable bottom half in octeon-md5 Don't disable bottom half while the crypto engine is in use, as it should be unnecessary: All kernel crypto engine usage is wrapped with crypto engine state save/restore, so if we get interrupted by softirq that uses crypto they should save and restore our context. This actually fixes an issue when running OCTEON MD5 with interrupts disabled (tcrypt mode=302). There's a WARNING because the module is trying to enable the bottom half with irqs disabled: [ 52.656610] ------------[ cut here ]------------ [ 52.661439] WARNING: CPU: 1 PID: 428 at /home/aaro/git/linux/kernel/softirq.c:150 __local_bh_enable_ip+0x9c/0xd8() [ 52.671780] Modules linked in: tcrypt(+) [...] [ 52.763539] [] warn_slowpath_common+0x94/0xd8 [ 52.769465] [] __local_bh_enable_ip+0x9c/0xd8 [ 52.775390] [] octeon_md5_final+0x12c/0x1e8 [ 52.781144] [] shash_compat_digest+0xd0/0x1b0 Signed-off-by: Aaro Koskinen Signed-off-by: Herbert Xu --- arch/mips/cavium-octeon/crypto/octeon-md5.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/arch/mips/cavium-octeon/crypto/octeon-md5.c b/arch/mips/cavium-octeon/crypto/octeon-md5.c index b909881ba6c1..3dd88450d440 100644 --- a/arch/mips/cavium-octeon/crypto/octeon-md5.c +++ b/arch/mips/cavium-octeon/crypto/octeon-md5.c @@ -97,7 +97,6 @@ static int octeon_md5_update(struct shash_desc *desc, const u8 *data, memcpy((char *)mctx->block + (sizeof(mctx->block) - avail), data, avail); - local_bh_disable(); preempt_disable(); flags = octeon_crypto_enable(&state); octeon_md5_store_hash(mctx); @@ -115,7 +114,6 @@ static int octeon_md5_update(struct shash_desc *desc, const u8 *data, octeon_md5_read_hash(mctx); octeon_crypto_disable(&state, flags); preempt_enable(); - local_bh_enable(); memcpy(mctx->block, data, len); @@ -133,7 +131,6 @@ static int octeon_md5_final(struct shash_desc *desc, u8 *out) *p++ = 0x80; - local_bh_disable(); preempt_disable(); flags = octeon_crypto_enable(&state); octeon_md5_store_hash(mctx); @@ -153,7 +150,6 @@ static int octeon_md5_final(struct shash_desc *desc, u8 *out) octeon_md5_read_hash(mctx); octeon_crypto_disable(&state, flags); preempt_enable(); - local_bh_enable(); memcpy(out, mctx->hash, sizeof(mctx->hash)); memset(mctx, 0, sizeof(*mctx)); -- GitLab From c3bc38d9fb30cca2567a4f6f0d52a12d4565c7e5 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 8 Mar 2015 22:07:42 +0200 Subject: [PATCH 03676/11651] crypto: octeon - always disable preemption when using crypto engine Always disable preemption on behalf of the drivers when crypto engine is taken into use. This will simplify the usage. Signed-off-by: Aaro Koskinen Signed-off-by: Herbert Xu --- arch/mips/cavium-octeon/crypto/octeon-crypto.c | 4 +++- arch/mips/cavium-octeon/crypto/octeon-md5.c | 4 ---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/arch/mips/cavium-octeon/crypto/octeon-crypto.c b/arch/mips/cavium-octeon/crypto/octeon-crypto.c index 7c82ff463b65..f66bd1adc7ff 100644 --- a/arch/mips/cavium-octeon/crypto/octeon-crypto.c +++ b/arch/mips/cavium-octeon/crypto/octeon-crypto.c @@ -17,7 +17,7 @@ * crypto operations in calls to octeon_crypto_enable/disable in order to make * sure the state of COP2 isn't corrupted if userspace is also performing * hardware crypto operations. Allocate the state parameter on the stack. - * Preemption must be disabled to prevent context switches. + * Returns with preemption disabled. * * @state: Pointer to state structure to store current COP2 state in. * @@ -28,6 +28,7 @@ unsigned long octeon_crypto_enable(struct octeon_cop2_state *state) int status; unsigned long flags; + preempt_disable(); local_irq_save(flags); status = read_c0_status(); write_c0_status(status | ST0_CU2); @@ -62,5 +63,6 @@ void octeon_crypto_disable(struct octeon_cop2_state *state, else write_c0_status(read_c0_status() & ~ST0_CU2); local_irq_restore(flags); + preempt_enable(); } EXPORT_SYMBOL_GPL(octeon_crypto_disable); diff --git a/arch/mips/cavium-octeon/crypto/octeon-md5.c b/arch/mips/cavium-octeon/crypto/octeon-md5.c index 3dd88450d440..12dccdb38286 100644 --- a/arch/mips/cavium-octeon/crypto/octeon-md5.c +++ b/arch/mips/cavium-octeon/crypto/octeon-md5.c @@ -97,7 +97,6 @@ static int octeon_md5_update(struct shash_desc *desc, const u8 *data, memcpy((char *)mctx->block + (sizeof(mctx->block) - avail), data, avail); - preempt_disable(); flags = octeon_crypto_enable(&state); octeon_md5_store_hash(mctx); @@ -113,7 +112,6 @@ static int octeon_md5_update(struct shash_desc *desc, const u8 *data, octeon_md5_read_hash(mctx); octeon_crypto_disable(&state, flags); - preempt_enable(); memcpy(mctx->block, data, len); @@ -131,7 +129,6 @@ static int octeon_md5_final(struct shash_desc *desc, u8 *out) *p++ = 0x80; - preempt_disable(); flags = octeon_crypto_enable(&state); octeon_md5_store_hash(mctx); @@ -149,7 +146,6 @@ static int octeon_md5_final(struct shash_desc *desc, u8 *out) octeon_md5_read_hash(mctx); octeon_crypto_disable(&state, flags); - preempt_enable(); memcpy(out, mctx->hash, sizeof(mctx->hash)); memset(mctx, 0, sizeof(*mctx)); -- GitLab From da3cd5d7a7031a4a9e0b3f84732620c9db8bc65a Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 8 Mar 2015 22:07:43 +0200 Subject: [PATCH 03677/11651] crypto: octeon - add instruction definitions for SHA1/256/512 Add instruction definitions for SHA1/256/512. Signed-off-by: Aaro Koskinen Signed-off-by: Herbert Xu --- .../mips/cavium-octeon/crypto/octeon-crypto.h | 83 ++++++++++++++++++- 1 file changed, 79 insertions(+), 4 deletions(-) diff --git a/arch/mips/cavium-octeon/crypto/octeon-crypto.h b/arch/mips/cavium-octeon/crypto/octeon-crypto.h index e2a4aece9c24..355072535110 100644 --- a/arch/mips/cavium-octeon/crypto/octeon-crypto.h +++ b/arch/mips/cavium-octeon/crypto/octeon-crypto.h @@ -5,7 +5,8 @@ * * Copyright (C) 2012-2013 Cavium Inc., All Rights Reserved. * - * MD5 instruction definitions added by Aaro Koskinen . + * MD5/SHA1/SHA256/SHA512 instruction definitions added by + * Aaro Koskinen . * */ #ifndef __LINUX_OCTEON_CRYPTO_H @@ -21,11 +22,11 @@ extern void octeon_crypto_disable(struct octeon_cop2_state *state, unsigned long flags); /* - * Macros needed to implement MD5: + * Macros needed to implement MD5/SHA1/SHA256: */ /* - * The index can be 0-1. + * The index can be 0-1 (MD5) or 0-2 (SHA1), 0-3 (SHA256). */ #define write_octeon_64bit_hash_dword(value, index) \ do { \ @@ -36,7 +37,7 @@ do { \ } while (0) /* - * The index can be 0-1. + * The index can be 0-1 (MD5) or 0-2 (SHA1), 0-3 (SHA256). */ #define read_octeon_64bit_hash_dword(index) \ ({ \ @@ -72,4 +73,78 @@ do { \ : [rt] "d" (value)); \ } while (0) +/* + * The value is the final block dword (64-bit). + */ +#define octeon_sha1_start(value) \ +do { \ + __asm__ __volatile__ ( \ + "dmtc2 %[rt],0x4057" \ + : \ + : [rt] "d" (value)); \ +} while (0) + +/* + * The value is the final block dword (64-bit). + */ +#define octeon_sha256_start(value) \ +do { \ + __asm__ __volatile__ ( \ + "dmtc2 %[rt],0x404f" \ + : \ + : [rt] "d" (value)); \ +} while (0) + +/* + * Macros needed to implement SHA512: + */ + +/* + * The index can be 0-7. + */ +#define write_octeon_64bit_hash_sha512(value, index) \ +do { \ + __asm__ __volatile__ ( \ + "dmtc2 %[rt],0x0250+" STR(index) \ + : \ + : [rt] "d" (value)); \ +} while (0) + +/* + * The index can be 0-7. + */ +#define read_octeon_64bit_hash_sha512(index) \ +({ \ + u64 __value; \ + \ + __asm__ __volatile__ ( \ + "dmfc2 %[rt],0x0250+" STR(index) \ + : [rt] "=d" (__value) \ + : ); \ + \ + __value; \ +}) + +/* + * The index can be 0-14. + */ +#define write_octeon_64bit_block_sha512(value, index) \ +do { \ + __asm__ __volatile__ ( \ + "dmtc2 %[rt],0x0240+" STR(index) \ + : \ + : [rt] "d" (value)); \ +} while (0) + +/* + * The value is the final block word (64-bit). + */ +#define octeon_sha512_start(value) \ +do { \ + __asm__ __volatile__ ( \ + "dmtc2 %[rt],0x424f" \ + : \ + : [rt] "d" (value)); \ +} while (0) + #endif /* __LINUX_OCTEON_CRYPTO_H */ -- GitLab From 82be2dcfa6a1eebe0fc608296547ec80b55d512d Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 8 Mar 2015 22:07:44 +0200 Subject: [PATCH 03678/11651] crypto: octeon - add SHA1 module Add OCTEON SHA1 module. Signed-off-by: Aaro Koskinen Signed-off-by: Herbert Xu --- arch/mips/cavium-octeon/crypto/Makefile | 3 +- arch/mips/cavium-octeon/crypto/octeon-sha1.c | 241 +++++++++++++++++++ 2 files changed, 243 insertions(+), 1 deletion(-) create mode 100644 arch/mips/cavium-octeon/crypto/octeon-sha1.c diff --git a/arch/mips/cavium-octeon/crypto/Makefile b/arch/mips/cavium-octeon/crypto/Makefile index a74f76d85a2f..3f671d60a3d9 100644 --- a/arch/mips/cavium-octeon/crypto/Makefile +++ b/arch/mips/cavium-octeon/crypto/Makefile @@ -4,4 +4,5 @@ obj-y += octeon-crypto.o -obj-$(CONFIG_CRYPTO_MD5_OCTEON) += octeon-md5.o +obj-$(CONFIG_CRYPTO_MD5_OCTEON) += octeon-md5.o +obj-$(CONFIG_CRYPTO_SHA1_OCTEON) += octeon-sha1.o diff --git a/arch/mips/cavium-octeon/crypto/octeon-sha1.c b/arch/mips/cavium-octeon/crypto/octeon-sha1.c new file mode 100644 index 000000000000..2b74b5b67cae --- /dev/null +++ b/arch/mips/cavium-octeon/crypto/octeon-sha1.c @@ -0,0 +1,241 @@ +/* + * Cryptographic API. + * + * SHA1 Secure Hash Algorithm. + * + * Adapted for OCTEON by Aaro Koskinen . + * + * Based on crypto/sha1_generic.c, which is: + * + * Copyright (c) Alan Smithee. + * Copyright (c) Andrew McDonald + * Copyright (c) Jean-Francois Dive + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "octeon-crypto.h" + +/* + * We pass everything as 64-bit. OCTEON can handle misaligned data. + */ + +static void octeon_sha1_store_hash(struct sha1_state *sctx) +{ + u64 *hash = (u64 *)sctx->state; + union { + u32 word[2]; + u64 dword; + } hash_tail = { { sctx->state[4], } }; + + write_octeon_64bit_hash_dword(hash[0], 0); + write_octeon_64bit_hash_dword(hash[1], 1); + write_octeon_64bit_hash_dword(hash_tail.dword, 2); + memzero_explicit(&hash_tail.word[0], sizeof(hash_tail.word[0])); +} + +static void octeon_sha1_read_hash(struct sha1_state *sctx) +{ + u64 *hash = (u64 *)sctx->state; + union { + u32 word[2]; + u64 dword; + } hash_tail; + + hash[0] = read_octeon_64bit_hash_dword(0); + hash[1] = read_octeon_64bit_hash_dword(1); + hash_tail.dword = read_octeon_64bit_hash_dword(2); + sctx->state[4] = hash_tail.word[0]; + memzero_explicit(&hash_tail.dword, sizeof(hash_tail.dword)); +} + +static void octeon_sha1_transform(const void *_block) +{ + const u64 *block = _block; + + write_octeon_64bit_block_dword(block[0], 0); + write_octeon_64bit_block_dword(block[1], 1); + write_octeon_64bit_block_dword(block[2], 2); + write_octeon_64bit_block_dword(block[3], 3); + write_octeon_64bit_block_dword(block[4], 4); + write_octeon_64bit_block_dword(block[5], 5); + write_octeon_64bit_block_dword(block[6], 6); + octeon_sha1_start(block[7]); +} + +static int octeon_sha1_init(struct shash_desc *desc) +{ + struct sha1_state *sctx = shash_desc_ctx(desc); + + sctx->state[0] = SHA1_H0; + sctx->state[1] = SHA1_H1; + sctx->state[2] = SHA1_H2; + sctx->state[3] = SHA1_H3; + sctx->state[4] = SHA1_H4; + sctx->count = 0; + + return 0; +} + +static void __octeon_sha1_update(struct sha1_state *sctx, const u8 *data, + unsigned int len) +{ + unsigned int partial; + unsigned int done; + const u8 *src; + + partial = sctx->count % SHA1_BLOCK_SIZE; + sctx->count += len; + done = 0; + src = data; + + if ((partial + len) >= SHA1_BLOCK_SIZE) { + if (partial) { + done = -partial; + memcpy(sctx->buffer + partial, data, + done + SHA1_BLOCK_SIZE); + src = sctx->buffer; + } + + do { + octeon_sha1_transform(src); + done += SHA1_BLOCK_SIZE; + src = data + done; + } while (done + SHA1_BLOCK_SIZE <= len); + + partial = 0; + } + memcpy(sctx->buffer + partial, src, len - done); +} + +static int octeon_sha1_update(struct shash_desc *desc, const u8 *data, + unsigned int len) +{ + struct sha1_state *sctx = shash_desc_ctx(desc); + struct octeon_cop2_state state; + unsigned long flags; + + /* + * Small updates never reach the crypto engine, so the generic sha1 is + * faster because of the heavyweight octeon_crypto_enable() / + * octeon_crypto_disable(). + */ + if ((sctx->count % SHA1_BLOCK_SIZE) + len < SHA1_BLOCK_SIZE) + return crypto_sha1_update(desc, data, len); + + flags = octeon_crypto_enable(&state); + octeon_sha1_store_hash(sctx); + + __octeon_sha1_update(sctx, data, len); + + octeon_sha1_read_hash(sctx); + octeon_crypto_disable(&state, flags); + + return 0; +} + +static int octeon_sha1_final(struct shash_desc *desc, u8 *out) +{ + struct sha1_state *sctx = shash_desc_ctx(desc); + static const u8 padding[64] = { 0x80, }; + struct octeon_cop2_state state; + __be32 *dst = (__be32 *)out; + unsigned int pad_len; + unsigned long flags; + unsigned int index; + __be64 bits; + int i; + + /* Save number of bits. */ + bits = cpu_to_be64(sctx->count << 3); + + /* Pad out to 56 mod 64. */ + index = sctx->count & 0x3f; + pad_len = (index < 56) ? (56 - index) : ((64+56) - index); + + flags = octeon_crypto_enable(&state); + octeon_sha1_store_hash(sctx); + + __octeon_sha1_update(sctx, padding, pad_len); + + /* Append length (before padding). */ + __octeon_sha1_update(sctx, (const u8 *)&bits, sizeof(bits)); + + octeon_sha1_read_hash(sctx); + octeon_crypto_disable(&state, flags); + + /* Store state in digest */ + for (i = 0; i < 5; i++) + dst[i] = cpu_to_be32(sctx->state[i]); + + /* Zeroize sensitive information. */ + memset(sctx, 0, sizeof(*sctx)); + + return 0; +} + +static int octeon_sha1_export(struct shash_desc *desc, void *out) +{ + struct sha1_state *sctx = shash_desc_ctx(desc); + + memcpy(out, sctx, sizeof(*sctx)); + return 0; +} + +static int octeon_sha1_import(struct shash_desc *desc, const void *in) +{ + struct sha1_state *sctx = shash_desc_ctx(desc); + + memcpy(sctx, in, sizeof(*sctx)); + return 0; +} + +static struct shash_alg octeon_sha1_alg = { + .digestsize = SHA1_DIGEST_SIZE, + .init = octeon_sha1_init, + .update = octeon_sha1_update, + .final = octeon_sha1_final, + .export = octeon_sha1_export, + .import = octeon_sha1_import, + .descsize = sizeof(struct sha1_state), + .statesize = sizeof(struct sha1_state), + .base = { + .cra_name = "sha1", + .cra_driver_name= "octeon-sha1", + .cra_priority = OCTEON_CR_OPCODE_PRIORITY, + .cra_flags = CRYPTO_ALG_TYPE_SHASH, + .cra_blocksize = SHA1_BLOCK_SIZE, + .cra_module = THIS_MODULE, + } +}; + +static int __init octeon_sha1_mod_init(void) +{ + if (!octeon_has_crypto()) + return -ENOTSUPP; + return crypto_register_shash(&octeon_sha1_alg); +} + +static void __exit octeon_sha1_mod_fini(void) +{ + crypto_unregister_shash(&octeon_sha1_alg); +} + +module_init(octeon_sha1_mod_init); +module_exit(octeon_sha1_mod_fini); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm (OCTEON)"); +MODULE_AUTHOR("Aaro Koskinen "); -- GitLab From c3d0def6200158cfdd280146da0109c264aede49 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 8 Mar 2015 22:07:45 +0200 Subject: [PATCH 03679/11651] crypto: octeon - add SHA256 module Add OCTEON SHA256 module. Signed-off-by: Aaro Koskinen Signed-off-by: Herbert Xu --- arch/mips/cavium-octeon/crypto/Makefile | 1 + .../mips/cavium-octeon/crypto/octeon-sha256.c | 280 ++++++++++++++++++ 2 files changed, 281 insertions(+) create mode 100644 arch/mips/cavium-octeon/crypto/octeon-sha256.c diff --git a/arch/mips/cavium-octeon/crypto/Makefile b/arch/mips/cavium-octeon/crypto/Makefile index 3f671d60a3d9..47806a5c5d71 100644 --- a/arch/mips/cavium-octeon/crypto/Makefile +++ b/arch/mips/cavium-octeon/crypto/Makefile @@ -6,3 +6,4 @@ obj-y += octeon-crypto.o obj-$(CONFIG_CRYPTO_MD5_OCTEON) += octeon-md5.o obj-$(CONFIG_CRYPTO_SHA1_OCTEON) += octeon-sha1.o +obj-$(CONFIG_CRYPTO_SHA256_OCTEON) += octeon-sha256.o diff --git a/arch/mips/cavium-octeon/crypto/octeon-sha256.c b/arch/mips/cavium-octeon/crypto/octeon-sha256.c new file mode 100644 index 000000000000..97e96fead08a --- /dev/null +++ b/arch/mips/cavium-octeon/crypto/octeon-sha256.c @@ -0,0 +1,280 @@ +/* + * Cryptographic API. + * + * SHA-224 and SHA-256 Secure Hash Algorithm. + * + * Adapted for OCTEON by Aaro Koskinen . + * + * Based on crypto/sha256_generic.c, which is: + * + * Copyright (c) Jean-Luc Cooke + * Copyright (c) Andrew McDonald + * Copyright (c) 2002 James Morris + * SHA224 Support Copyright 2007 Intel Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "octeon-crypto.h" + +/* + * We pass everything as 64-bit. OCTEON can handle misaligned data. + */ + +static void octeon_sha256_store_hash(struct sha256_state *sctx) +{ + u64 *hash = (u64 *)sctx->state; + + write_octeon_64bit_hash_dword(hash[0], 0); + write_octeon_64bit_hash_dword(hash[1], 1); + write_octeon_64bit_hash_dword(hash[2], 2); + write_octeon_64bit_hash_dword(hash[3], 3); +} + +static void octeon_sha256_read_hash(struct sha256_state *sctx) +{ + u64 *hash = (u64 *)sctx->state; + + hash[0] = read_octeon_64bit_hash_dword(0); + hash[1] = read_octeon_64bit_hash_dword(1); + hash[2] = read_octeon_64bit_hash_dword(2); + hash[3] = read_octeon_64bit_hash_dword(3); +} + +static void octeon_sha256_transform(const void *_block) +{ + const u64 *block = _block; + + write_octeon_64bit_block_dword(block[0], 0); + write_octeon_64bit_block_dword(block[1], 1); + write_octeon_64bit_block_dword(block[2], 2); + write_octeon_64bit_block_dword(block[3], 3); + write_octeon_64bit_block_dword(block[4], 4); + write_octeon_64bit_block_dword(block[5], 5); + write_octeon_64bit_block_dword(block[6], 6); + octeon_sha256_start(block[7]); +} + +static int octeon_sha224_init(struct shash_desc *desc) +{ + struct sha256_state *sctx = shash_desc_ctx(desc); + + sctx->state[0] = SHA224_H0; + sctx->state[1] = SHA224_H1; + sctx->state[2] = SHA224_H2; + sctx->state[3] = SHA224_H3; + sctx->state[4] = SHA224_H4; + sctx->state[5] = SHA224_H5; + sctx->state[6] = SHA224_H6; + sctx->state[7] = SHA224_H7; + sctx->count = 0; + + return 0; +} + +static int octeon_sha256_init(struct shash_desc *desc) +{ + struct sha256_state *sctx = shash_desc_ctx(desc); + + sctx->state[0] = SHA256_H0; + sctx->state[1] = SHA256_H1; + sctx->state[2] = SHA256_H2; + sctx->state[3] = SHA256_H3; + sctx->state[4] = SHA256_H4; + sctx->state[5] = SHA256_H5; + sctx->state[6] = SHA256_H6; + sctx->state[7] = SHA256_H7; + sctx->count = 0; + + return 0; +} + +static void __octeon_sha256_update(struct sha256_state *sctx, const u8 *data, + unsigned int len) +{ + unsigned int partial; + unsigned int done; + const u8 *src; + + partial = sctx->count % SHA256_BLOCK_SIZE; + sctx->count += len; + done = 0; + src = data; + + if ((partial + len) >= SHA256_BLOCK_SIZE) { + if (partial) { + done = -partial; + memcpy(sctx->buf + partial, data, + done + SHA256_BLOCK_SIZE); + src = sctx->buf; + } + + do { + octeon_sha256_transform(src); + done += SHA256_BLOCK_SIZE; + src = data + done; + } while (done + SHA256_BLOCK_SIZE <= len); + + partial = 0; + } + memcpy(sctx->buf + partial, src, len - done); +} + +static int octeon_sha256_update(struct shash_desc *desc, const u8 *data, + unsigned int len) +{ + struct sha256_state *sctx = shash_desc_ctx(desc); + struct octeon_cop2_state state; + unsigned long flags; + + /* + * Small updates never reach the crypto engine, so the generic sha256 is + * faster because of the heavyweight octeon_crypto_enable() / + * octeon_crypto_disable(). + */ + if ((sctx->count % SHA256_BLOCK_SIZE) + len < SHA256_BLOCK_SIZE) + return crypto_sha256_update(desc, data, len); + + flags = octeon_crypto_enable(&state); + octeon_sha256_store_hash(sctx); + + __octeon_sha256_update(sctx, data, len); + + octeon_sha256_read_hash(sctx); + octeon_crypto_disable(&state, flags); + + return 0; +} + +static int octeon_sha256_final(struct shash_desc *desc, u8 *out) +{ + struct sha256_state *sctx = shash_desc_ctx(desc); + static const u8 padding[64] = { 0x80, }; + struct octeon_cop2_state state; + __be32 *dst = (__be32 *)out; + unsigned int pad_len; + unsigned long flags; + unsigned int index; + __be64 bits; + int i; + + /* Save number of bits. */ + bits = cpu_to_be64(sctx->count << 3); + + /* Pad out to 56 mod 64. */ + index = sctx->count & 0x3f; + pad_len = (index < 56) ? (56 - index) : ((64+56) - index); + + flags = octeon_crypto_enable(&state); + octeon_sha256_store_hash(sctx); + + __octeon_sha256_update(sctx, padding, pad_len); + + /* Append length (before padding). */ + __octeon_sha256_update(sctx, (const u8 *)&bits, sizeof(bits)); + + octeon_sha256_read_hash(sctx); + octeon_crypto_disable(&state, flags); + + /* Store state in digest */ + for (i = 0; i < 8; i++) + dst[i] = cpu_to_be32(sctx->state[i]); + + /* Zeroize sensitive information. */ + memset(sctx, 0, sizeof(*sctx)); + + return 0; +} + +static int octeon_sha224_final(struct shash_desc *desc, u8 *hash) +{ + u8 D[SHA256_DIGEST_SIZE]; + + octeon_sha256_final(desc, D); + + memcpy(hash, D, SHA224_DIGEST_SIZE); + memzero_explicit(D, SHA256_DIGEST_SIZE); + + return 0; +} + +static int octeon_sha256_export(struct shash_desc *desc, void *out) +{ + struct sha256_state *sctx = shash_desc_ctx(desc); + + memcpy(out, sctx, sizeof(*sctx)); + return 0; +} + +static int octeon_sha256_import(struct shash_desc *desc, const void *in) +{ + struct sha256_state *sctx = shash_desc_ctx(desc); + + memcpy(sctx, in, sizeof(*sctx)); + return 0; +} + +static struct shash_alg octeon_sha256_algs[2] = { { + .digestsize = SHA256_DIGEST_SIZE, + .init = octeon_sha256_init, + .update = octeon_sha256_update, + .final = octeon_sha256_final, + .export = octeon_sha256_export, + .import = octeon_sha256_import, + .descsize = sizeof(struct sha256_state), + .statesize = sizeof(struct sha256_state), + .base = { + .cra_name = "sha256", + .cra_driver_name= "octeon-sha256", + .cra_priority = OCTEON_CR_OPCODE_PRIORITY, + .cra_flags = CRYPTO_ALG_TYPE_SHASH, + .cra_blocksize = SHA256_BLOCK_SIZE, + .cra_module = THIS_MODULE, + } +}, { + .digestsize = SHA224_DIGEST_SIZE, + .init = octeon_sha224_init, + .update = octeon_sha256_update, + .final = octeon_sha224_final, + .descsize = sizeof(struct sha256_state), + .base = { + .cra_name = "sha224", + .cra_driver_name= "octeon-sha224", + .cra_flags = CRYPTO_ALG_TYPE_SHASH, + .cra_blocksize = SHA224_BLOCK_SIZE, + .cra_module = THIS_MODULE, + } +} }; + +static int __init octeon_sha256_mod_init(void) +{ + if (!octeon_has_crypto()) + return -ENOTSUPP; + return crypto_register_shashes(octeon_sha256_algs, + ARRAY_SIZE(octeon_sha256_algs)); +} + +static void __exit octeon_sha256_mod_fini(void) +{ + crypto_unregister_shashes(octeon_sha256_algs, + ARRAY_SIZE(octeon_sha256_algs)); +} + +module_init(octeon_sha256_mod_init); +module_exit(octeon_sha256_mod_fini); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("SHA-224 and SHA-256 Secure Hash Algorithm (OCTEON)"); +MODULE_AUTHOR("Aaro Koskinen "); -- GitLab From fbaa4dfd51a0bfec1e03d4f887c250993f9dc18d Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 8 Mar 2015 22:07:46 +0200 Subject: [PATCH 03680/11651] crypto: octeon - add SHA512 module Add OCTEON SHA512 module. Signed-off-by: Aaro Koskinen Signed-off-by: Herbert Xu --- arch/mips/cavium-octeon/crypto/Makefile | 1 + .../mips/cavium-octeon/crypto/octeon-sha512.c | 277 ++++++++++++++++++ 2 files changed, 278 insertions(+) create mode 100644 arch/mips/cavium-octeon/crypto/octeon-sha512.c diff --git a/arch/mips/cavium-octeon/crypto/Makefile b/arch/mips/cavium-octeon/crypto/Makefile index 47806a5c5d71..f7aa9d5d3b87 100644 --- a/arch/mips/cavium-octeon/crypto/Makefile +++ b/arch/mips/cavium-octeon/crypto/Makefile @@ -7,3 +7,4 @@ obj-y += octeon-crypto.o obj-$(CONFIG_CRYPTO_MD5_OCTEON) += octeon-md5.o obj-$(CONFIG_CRYPTO_SHA1_OCTEON) += octeon-sha1.o obj-$(CONFIG_CRYPTO_SHA256_OCTEON) += octeon-sha256.o +obj-$(CONFIG_CRYPTO_SHA512_OCTEON) += octeon-sha512.o diff --git a/arch/mips/cavium-octeon/crypto/octeon-sha512.c b/arch/mips/cavium-octeon/crypto/octeon-sha512.c new file mode 100644 index 000000000000..d5fb3c6f22ae --- /dev/null +++ b/arch/mips/cavium-octeon/crypto/octeon-sha512.c @@ -0,0 +1,277 @@ +/* + * Cryptographic API. + * + * SHA-512 and SHA-384 Secure Hash Algorithm. + * + * Adapted for OCTEON by Aaro Koskinen . + * + * Based on crypto/sha512_generic.c, which is: + * + * Copyright (c) Jean-Luc Cooke + * Copyright (c) Andrew McDonald + * Copyright (c) 2003 Kyle McMartin + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "octeon-crypto.h" + +/* + * We pass everything as 64-bit. OCTEON can handle misaligned data. + */ + +static void octeon_sha512_store_hash(struct sha512_state *sctx) +{ + write_octeon_64bit_hash_sha512(sctx->state[0], 0); + write_octeon_64bit_hash_sha512(sctx->state[1], 1); + write_octeon_64bit_hash_sha512(sctx->state[2], 2); + write_octeon_64bit_hash_sha512(sctx->state[3], 3); + write_octeon_64bit_hash_sha512(sctx->state[4], 4); + write_octeon_64bit_hash_sha512(sctx->state[5], 5); + write_octeon_64bit_hash_sha512(sctx->state[6], 6); + write_octeon_64bit_hash_sha512(sctx->state[7], 7); +} + +static void octeon_sha512_read_hash(struct sha512_state *sctx) +{ + sctx->state[0] = read_octeon_64bit_hash_sha512(0); + sctx->state[1] = read_octeon_64bit_hash_sha512(1); + sctx->state[2] = read_octeon_64bit_hash_sha512(2); + sctx->state[3] = read_octeon_64bit_hash_sha512(3); + sctx->state[4] = read_octeon_64bit_hash_sha512(4); + sctx->state[5] = read_octeon_64bit_hash_sha512(5); + sctx->state[6] = read_octeon_64bit_hash_sha512(6); + sctx->state[7] = read_octeon_64bit_hash_sha512(7); +} + +static void octeon_sha512_transform(const void *_block) +{ + const u64 *block = _block; + + write_octeon_64bit_block_sha512(block[0], 0); + write_octeon_64bit_block_sha512(block[1], 1); + write_octeon_64bit_block_sha512(block[2], 2); + write_octeon_64bit_block_sha512(block[3], 3); + write_octeon_64bit_block_sha512(block[4], 4); + write_octeon_64bit_block_sha512(block[5], 5); + write_octeon_64bit_block_sha512(block[6], 6); + write_octeon_64bit_block_sha512(block[7], 7); + write_octeon_64bit_block_sha512(block[8], 8); + write_octeon_64bit_block_sha512(block[9], 9); + write_octeon_64bit_block_sha512(block[10], 10); + write_octeon_64bit_block_sha512(block[11], 11); + write_octeon_64bit_block_sha512(block[12], 12); + write_octeon_64bit_block_sha512(block[13], 13); + write_octeon_64bit_block_sha512(block[14], 14); + octeon_sha512_start(block[15]); +} + +static int octeon_sha512_init(struct shash_desc *desc) +{ + struct sha512_state *sctx = shash_desc_ctx(desc); + + sctx->state[0] = SHA512_H0; + sctx->state[1] = SHA512_H1; + sctx->state[2] = SHA512_H2; + sctx->state[3] = SHA512_H3; + sctx->state[4] = SHA512_H4; + sctx->state[5] = SHA512_H5; + sctx->state[6] = SHA512_H6; + sctx->state[7] = SHA512_H7; + sctx->count[0] = sctx->count[1] = 0; + + return 0; +} + +static int octeon_sha384_init(struct shash_desc *desc) +{ + struct sha512_state *sctx = shash_desc_ctx(desc); + + sctx->state[0] = SHA384_H0; + sctx->state[1] = SHA384_H1; + sctx->state[2] = SHA384_H2; + sctx->state[3] = SHA384_H3; + sctx->state[4] = SHA384_H4; + sctx->state[5] = SHA384_H5; + sctx->state[6] = SHA384_H6; + sctx->state[7] = SHA384_H7; + sctx->count[0] = sctx->count[1] = 0; + + return 0; +} + +static void __octeon_sha512_update(struct sha512_state *sctx, const u8 *data, + unsigned int len) +{ + unsigned int part_len; + unsigned int index; + unsigned int i; + + /* Compute number of bytes mod 128. */ + index = sctx->count[0] % SHA512_BLOCK_SIZE; + + /* Update number of bytes. */ + if ((sctx->count[0] += len) < len) + sctx->count[1]++; + + part_len = SHA512_BLOCK_SIZE - index; + + /* Transform as many times as possible. */ + if (len >= part_len) { + memcpy(&sctx->buf[index], data, part_len); + octeon_sha512_transform(sctx->buf); + + for (i = part_len; i + SHA512_BLOCK_SIZE <= len; + i += SHA512_BLOCK_SIZE) + octeon_sha512_transform(&data[i]); + + index = 0; + } else { + i = 0; + } + + /* Buffer remaining input. */ + memcpy(&sctx->buf[index], &data[i], len - i); +} + +static int octeon_sha512_update(struct shash_desc *desc, const u8 *data, + unsigned int len) +{ + struct sha512_state *sctx = shash_desc_ctx(desc); + struct octeon_cop2_state state; + unsigned long flags; + + /* + * Small updates never reach the crypto engine, so the generic sha512 is + * faster because of the heavyweight octeon_crypto_enable() / + * octeon_crypto_disable(). + */ + if ((sctx->count[0] % SHA512_BLOCK_SIZE) + len < SHA512_BLOCK_SIZE) + return crypto_sha512_update(desc, data, len); + + flags = octeon_crypto_enable(&state); + octeon_sha512_store_hash(sctx); + + __octeon_sha512_update(sctx, data, len); + + octeon_sha512_read_hash(sctx); + octeon_crypto_disable(&state, flags); + + return 0; +} + +static int octeon_sha512_final(struct shash_desc *desc, u8 *hash) +{ + struct sha512_state *sctx = shash_desc_ctx(desc); + static u8 padding[128] = { 0x80, }; + struct octeon_cop2_state state; + __be64 *dst = (__be64 *)hash; + unsigned int pad_len; + unsigned long flags; + unsigned int index; + __be64 bits[2]; + int i; + + /* Save number of bits. */ + bits[1] = cpu_to_be64(sctx->count[0] << 3); + bits[0] = cpu_to_be64(sctx->count[1] << 3 | sctx->count[0] >> 61); + + /* Pad out to 112 mod 128. */ + index = sctx->count[0] & 0x7f; + pad_len = (index < 112) ? (112 - index) : ((128+112) - index); + + flags = octeon_crypto_enable(&state); + octeon_sha512_store_hash(sctx); + + __octeon_sha512_update(sctx, padding, pad_len); + + /* Append length (before padding). */ + __octeon_sha512_update(sctx, (const u8 *)bits, sizeof(bits)); + + octeon_sha512_read_hash(sctx); + octeon_crypto_disable(&state, flags); + + /* Store state in digest. */ + for (i = 0; i < 8; i++) + dst[i] = cpu_to_be64(sctx->state[i]); + + /* Zeroize sensitive information. */ + memset(sctx, 0, sizeof(struct sha512_state)); + + return 0; +} + +static int octeon_sha384_final(struct shash_desc *desc, u8 *hash) +{ + u8 D[64]; + + octeon_sha512_final(desc, D); + + memcpy(hash, D, 48); + memzero_explicit(D, 64); + + return 0; +} + +static struct shash_alg octeon_sha512_algs[2] = { { + .digestsize = SHA512_DIGEST_SIZE, + .init = octeon_sha512_init, + .update = octeon_sha512_update, + .final = octeon_sha512_final, + .descsize = sizeof(struct sha512_state), + .base = { + .cra_name = "sha512", + .cra_driver_name= "octeon-sha512", + .cra_priority = OCTEON_CR_OPCODE_PRIORITY, + .cra_flags = CRYPTO_ALG_TYPE_SHASH, + .cra_blocksize = SHA512_BLOCK_SIZE, + .cra_module = THIS_MODULE, + } +}, { + .digestsize = SHA384_DIGEST_SIZE, + .init = octeon_sha384_init, + .update = octeon_sha512_update, + .final = octeon_sha384_final, + .descsize = sizeof(struct sha512_state), + .base = { + .cra_name = "sha384", + .cra_driver_name= "octeon-sha384", + .cra_priority = OCTEON_CR_OPCODE_PRIORITY, + .cra_flags = CRYPTO_ALG_TYPE_SHASH, + .cra_blocksize = SHA384_BLOCK_SIZE, + .cra_module = THIS_MODULE, + } +} }; + +static int __init octeon_sha512_mod_init(void) +{ + if (!octeon_has_crypto()) + return -ENOTSUPP; + return crypto_register_shashes(octeon_sha512_algs, + ARRAY_SIZE(octeon_sha512_algs)); +} + +static void __exit octeon_sha512_mod_fini(void) +{ + crypto_unregister_shashes(octeon_sha512_algs, + ARRAY_SIZE(octeon_sha512_algs)); +} + +module_init(octeon_sha512_mod_init); +module_exit(octeon_sha512_mod_fini); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("SHA-512 and SHA-384 Secure Hash Algorithms (OCTEON)"); +MODULE_AUTHOR("Aaro Koskinen "); -- GitLab From efdb6f6edb526f160b8db1670b93a07180ac8306 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 8 Mar 2015 22:07:47 +0200 Subject: [PATCH 03681/11651] crypto: octeon - enable OCTEON SHA1/256/512 module selection Enable user to select OCTEON SHA1/256/512 modules. Signed-off-by: Aaro Koskinen Signed-off-by: Herbert Xu --- crypto/Kconfig | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/crypto/Kconfig b/crypto/Kconfig index 6918aff74f4d..1afb0f66ad43 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -554,6 +554,15 @@ config CRYPTO_SHA512_SSSE3 Extensions version 1 (AVX1), or Advanced Vector Extensions version 2 (AVX2) instructions, when available. +config CRYPTO_SHA1_OCTEON + tristate "SHA1 digest algorithm (OCTEON)" + depends on CPU_CAVIUM_OCTEON + select CRYPTO_SHA1 + select CRYPTO_HASH + help + SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2) implemented + using OCTEON crypto instructions, when available. + config CRYPTO_SHA1_SPARC64 tristate "SHA1 digest algorithm (SPARC64)" depends on SPARC64 @@ -634,6 +643,15 @@ config CRYPTO_SHA256_PPC_SPE SHA224 and SHA256 secure hash standard (DFIPS 180-2) implemented using powerpc SPE SIMD instruction set. +config CRYPTO_SHA256_OCTEON + tristate "SHA224 and SHA256 digest algorithm (OCTEON)" + depends on CPU_CAVIUM_OCTEON + select CRYPTO_SHA256 + select CRYPTO_HASH + help + SHA-256 secure hash standard (DFIPS 180-2) implemented + using OCTEON crypto instructions, when available. + config CRYPTO_SHA256_SPARC64 tristate "SHA224 and SHA256 digest algorithm (SPARC64)" depends on SPARC64 @@ -655,6 +673,15 @@ config CRYPTO_SHA512 This code also includes SHA-384, a 384 bit hash with 192 bits of security against collision attacks. +config CRYPTO_SHA512_OCTEON + tristate "SHA384 and SHA512 digest algorithms (OCTEON)" + depends on CPU_CAVIUM_OCTEON + select CRYPTO_SHA512 + select CRYPTO_HASH + help + SHA-512 secure hash standard (DFIPS 180-2) implemented + using OCTEON crypto instructions, when available. + config CRYPTO_SHA512_SPARC64 tristate "SHA384 and SHA512 digest algorithm (SPARC64)" depends on SPARC64 -- GitLab From 762e45836a047323defe9bdbbac534f0675ff027 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 4 Mar 2015 18:09:26 +0000 Subject: [PATCH 03682/11651] drm/i915: Make WAIT_IOCTL negative timeouts be indefinite again MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes a regression from commit 5ed0bdf21a85d78e04f89f15ccf227562177cbd9 Author: Thomas Gleixner Date: Wed Jul 16 21:05:06 2014 +0000 drm: i915: Use nsec based interfaces that made a negative timeout return immediately rather than the previously defined behaviour of waiting indefinitely. Testcase: igt/gem_wait Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=89494 Signed-off-by: Chris Wilson Cc: Daniel Vetter Cc: Ben Widawsky Cc: Kristian Høgsberg Cc: stable@vger.kernel.org Reviewed-by: Daniel Vetter [Jani: fixed a checkpatch complaint about whitespace.] Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_gem.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index e5daad5f75fb..ac7fe39d38a3 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2936,9 +2936,9 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file) req = obj->last_read_req; /* Do this after OLR check to make sure we make forward progress polling - * on this IOCTL with a timeout <=0 (like busy ioctl) + * on this IOCTL with a timeout == 0 (like busy ioctl) */ - if (args->timeout_ns <= 0) { + if (args->timeout_ns == 0) { ret = -ETIME; goto out; } @@ -2948,7 +2948,8 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file) i915_gem_request_reference(req); mutex_unlock(&dev->struct_mutex); - ret = __i915_wait_request(req, reset_counter, true, &args->timeout_ns, + ret = __i915_wait_request(req, reset_counter, true, + args->timeout_ns > 0 ? &args->timeout_ns : NULL, file->driver_priv); mutex_lock(&dev->struct_mutex); i915_gem_request_unreference(req); -- GitLab From 0cd0caad99a028568dd4a7c1b95777aadf4eb317 Mon Sep 17 00:00:00 2001 From: Mika Kuoppala Date: Fri, 27 Feb 2015 18:11:09 +0200 Subject: [PATCH 03683/11651] drm/i915: Do both mt and gen6 style forcewake reset on ivb probe commit 05a2fb157e44 ("drm/i915: Consolidate forcewake code") failed to take into account that we have used to reset both the gen6 style and the multithreaded style forcewake registers. This is due to fact that ivb can use either, depending on how the bios has set up the machine. Mimic the old semantics before we have determined the correct variety and reset both before the ecobus probe. Cc: Chris Wilson Cc: Huang Ying Signed-off-by: Mika Kuoppala Reviewed-by: Chris Wilson Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_uncore.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index c47a3baa53d5..4e8fb891d4ea 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -1048,8 +1048,14 @@ static void intel_uncore_fw_domains_init(struct drm_device *dev) /* We need to init first for ECOBUS access and then * determine later if we want to reinit, in case of MT access is - * not working + * not working. In this stage we don't know which flavour this + * ivb is, so it is better to reset also the gen6 fw registers + * before the ecobus check. */ + + __raw_i915_write32(dev_priv, FORCEWAKE, 0); + __raw_posting_read(dev_priv, ECOBUS); + fw_domain_init(dev_priv, FW_DOMAIN_ID_RENDER, FORCEWAKE_MT, FORCEWAKE_MT_ACK); -- GitLab From 359f9365d3f8d0d62683344807c986ec7d711b59 Mon Sep 17 00:00:00 2001 From: Hongzhou Yang Date: Mon, 9 Mar 2015 21:54:39 -0700 Subject: [PATCH 03684/11651] arm64: dts: mt8173: Add pinctrl/GPIO/EINT node for mt8173. Add pinctrl, GPIO and EINT node to mt8173.dtsi. Signed-off-by: Hongzhou Yang Signed-off-by: Matthias Brugger --- arch/arm64/boot/dts/mediatek/mt8173-pinfunc.h | 682 ++++++++++++++++++ arch/arm64/boot/dts/mediatek/mt8173.dtsi | 20 + 2 files changed, 702 insertions(+) create mode 100644 arch/arm64/boot/dts/mediatek/mt8173-pinfunc.h diff --git a/arch/arm64/boot/dts/mediatek/mt8173-pinfunc.h b/arch/arm64/boot/dts/mediatek/mt8173-pinfunc.h new file mode 100644 index 000000000000..d2f3809af70e --- /dev/null +++ b/arch/arm64/boot/dts/mediatek/mt8173-pinfunc.h @@ -0,0 +1,682 @@ +/* + * Copyright (c) 2014 MediaTek Inc. + * Author: Hongzhou.Yang + * + * 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. + */ + +#ifndef __DTS_MT8173_PINFUNC_H +#define __DTS_MT8173_PINFUNC_H + +#include + +#define MT8173_PIN_0_EINT0__FUNC_GPIO0 (MTK_PIN_NO(0) | 0) +#define MT8173_PIN_0_EINT0__FUNC_IRDA_PDN (MTK_PIN_NO(0) | 1) +#define MT8173_PIN_0_EINT0__FUNC_I2S1_WS (MTK_PIN_NO(0) | 2) +#define MT8173_PIN_0_EINT0__FUNC_AUD_SPDIF (MTK_PIN_NO(0) | 3) +#define MT8173_PIN_0_EINT0__FUNC_UTXD0 (MTK_PIN_NO(0) | 4) +#define MT8173_PIN_0_EINT0__FUNC_DBG_MON_A_20_ (MTK_PIN_NO(0) | 7) + +#define MT8173_PIN_1_EINT1__FUNC_GPIO1 (MTK_PIN_NO(1) | 0) +#define MT8173_PIN_1_EINT1__FUNC_IRDA_RXD (MTK_PIN_NO(1) | 1) +#define MT8173_PIN_1_EINT1__FUNC_I2S1_BCK (MTK_PIN_NO(1) | 2) +#define MT8173_PIN_1_EINT1__FUNC_SDA5 (MTK_PIN_NO(1) | 3) +#define MT8173_PIN_1_EINT1__FUNC_URXD0 (MTK_PIN_NO(1) | 4) +#define MT8173_PIN_1_EINT1__FUNC_DBG_MON_A_21_ (MTK_PIN_NO(1) | 7) + +#define MT8173_PIN_2_EINT2__FUNC_GPIO2 (MTK_PIN_NO(2) | 0) +#define MT8173_PIN_2_EINT2__FUNC_IRDA_TXD (MTK_PIN_NO(2) | 1) +#define MT8173_PIN_2_EINT2__FUNC_I2S1_MCK (MTK_PIN_NO(2) | 2) +#define MT8173_PIN_2_EINT2__FUNC_SCL5 (MTK_PIN_NO(2) | 3) +#define MT8173_PIN_2_EINT2__FUNC_UTXD3 (MTK_PIN_NO(2) | 4) +#define MT8173_PIN_2_EINT2__FUNC_DBG_MON_A_22_ (MTK_PIN_NO(2) | 7) + +#define MT8173_PIN_3_EINT3__FUNC_GPIO3 (MTK_PIN_NO(3) | 0) +#define MT8173_PIN_3_EINT3__FUNC_DSI1_TE (MTK_PIN_NO(3) | 1) +#define MT8173_PIN_3_EINT3__FUNC_I2S1_DO_1 (MTK_PIN_NO(3) | 2) +#define MT8173_PIN_3_EINT3__FUNC_SDA3 (MTK_PIN_NO(3) | 3) +#define MT8173_PIN_3_EINT3__FUNC_URXD3 (MTK_PIN_NO(3) | 4) +#define MT8173_PIN_3_EINT3__FUNC_DBG_MON_A_23_ (MTK_PIN_NO(3) | 7) + +#define MT8173_PIN_4_EINT4__FUNC_GPIO4 (MTK_PIN_NO(4) | 0) +#define MT8173_PIN_4_EINT4__FUNC_DISP_PWM1 (MTK_PIN_NO(4) | 1) +#define MT8173_PIN_4_EINT4__FUNC_I2S1_DO_2 (MTK_PIN_NO(4) | 2) +#define MT8173_PIN_4_EINT4__FUNC_SCL3 (MTK_PIN_NO(4) | 3) +#define MT8173_PIN_4_EINT4__FUNC_UCTS3 (MTK_PIN_NO(4) | 4) +#define MT8173_PIN_4_EINT4__FUNC_SFWP_B (MTK_PIN_NO(4) | 6) + +#define MT8173_PIN_5_EINT5__FUNC_GPIO5 (MTK_PIN_NO(5) | 0) +#define MT8173_PIN_5_EINT5__FUNC_PCM1_CLK (MTK_PIN_NO(5) | 1) +#define MT8173_PIN_5_EINT5__FUNC_I2S2_WS (MTK_PIN_NO(5) | 2) +#define MT8173_PIN_5_EINT5__FUNC_SPI_CK_3_ (MTK_PIN_NO(5) | 3) +#define MT8173_PIN_5_EINT5__FUNC_URTS3 (MTK_PIN_NO(5) | 4) +#define MT8173_PIN_5_EINT5__FUNC_AP_MD32_JTAG_TMS (MTK_PIN_NO(5) | 5) +#define MT8173_PIN_5_EINT5__FUNC_SFOUT (MTK_PIN_NO(5) | 6) + +#define MT8173_PIN_6_EINT6__FUNC_GPIO6 (MTK_PIN_NO(6) | 0) +#define MT8173_PIN_6_EINT6__FUNC_PCM1_SYNC (MTK_PIN_NO(6) | 1) +#define MT8173_PIN_6_EINT6__FUNC_I2S2_BCK (MTK_PIN_NO(6) | 2) +#define MT8173_PIN_6_EINT6__FUNC_SPI_MI_3_ (MTK_PIN_NO(6) | 3) +#define MT8173_PIN_6_EINT6__FUNC_AP_MD32_JTAG_TCK (MTK_PIN_NO(6) | 5) +#define MT8173_PIN_6_EINT6__FUNC_SFCS0 (MTK_PIN_NO(6) | 6) + +#define MT8173_PIN_7_EINT7__FUNC_GPIO7 (MTK_PIN_NO(7) | 0) +#define MT8173_PIN_7_EINT7__FUNC_PCM1_DI (MTK_PIN_NO(7) | 1) +#define MT8173_PIN_7_EINT7__FUNC_I2S2_DI_1 (MTK_PIN_NO(7) | 2) +#define MT8173_PIN_7_EINT7__FUNC_SPI_MO_3_ (MTK_PIN_NO(7) | 3) +#define MT8173_PIN_7_EINT7__FUNC_AP_MD32_JTAG_TDI (MTK_PIN_NO(7) | 5) +#define MT8173_PIN_7_EINT7__FUNC_SFHOLD (MTK_PIN_NO(7) | 6) + +#define MT8173_PIN_8_EINT8__FUNC_GPIO8 (MTK_PIN_NO(8) | 0) +#define MT8173_PIN_8_EINT8__FUNC_PCM1_DO (MTK_PIN_NO(8) | 1) +#define MT8173_PIN_8_EINT8__FUNC_I2S2_DI_2 (MTK_PIN_NO(8) | 2) +#define MT8173_PIN_8_EINT8__FUNC_SPI_CS_3_ (MTK_PIN_NO(8) | 3) +#define MT8173_PIN_8_EINT8__FUNC_AUD_SPDIF (MTK_PIN_NO(8) | 4) +#define MT8173_PIN_8_EINT8__FUNC_AP_MD32_JTAG_TDO (MTK_PIN_NO(8) | 5) +#define MT8173_PIN_8_EINT8__FUNC_SFIN (MTK_PIN_NO(8) | 6) + +#define MT8173_PIN_9_EINT9__FUNC_GPIO9 (MTK_PIN_NO(9) | 0) +#define MT8173_PIN_9_EINT9__FUNC_USB_DRVVBUS_P0 (MTK_PIN_NO(9) | 1) +#define MT8173_PIN_9_EINT9__FUNC_I2S2_MCK (MTK_PIN_NO(9) | 2) +#define MT8173_PIN_9_EINT9__FUNC_USB_DRVVBUS_P1 (MTK_PIN_NO(9) | 4) +#define MT8173_PIN_9_EINT9__FUNC_AP_MD32_JTAG_TRST (MTK_PIN_NO(9) | 5) +#define MT8173_PIN_9_EINT9__FUNC_SFCK (MTK_PIN_NO(9) | 6) + +#define MT8173_PIN_10_EINT10__FUNC_GPIO10 (MTK_PIN_NO(10) | 0) +#define MT8173_PIN_10_EINT10__FUNC_CLKM0 (MTK_PIN_NO(10) | 1) +#define MT8173_PIN_10_EINT10__FUNC_DSI1_TE (MTK_PIN_NO(10) | 2) +#define MT8173_PIN_10_EINT10__FUNC_DISP_PWM1 (MTK_PIN_NO(10) | 3) +#define MT8173_PIN_10_EINT10__FUNC_PWM4 (MTK_PIN_NO(10) | 4) +#define MT8173_PIN_10_EINT10__FUNC_IRDA_RXD (MTK_PIN_NO(10) | 5) + +#define MT8173_PIN_11_EINT11__FUNC_GPIO11 (MTK_PIN_NO(11) | 0) +#define MT8173_PIN_11_EINT11__FUNC_CLKM1 (MTK_PIN_NO(11) | 1) +#define MT8173_PIN_11_EINT11__FUNC_I2S3_WS (MTK_PIN_NO(11) | 2) +#define MT8173_PIN_11_EINT11__FUNC_USB_DRVVBUS_P0 (MTK_PIN_NO(11) | 3) +#define MT8173_PIN_11_EINT11__FUNC_PWM5 (MTK_PIN_NO(11) | 4) +#define MT8173_PIN_11_EINT11__FUNC_IRDA_TXD (MTK_PIN_NO(11) | 5) +#define MT8173_PIN_11_EINT11__FUNC_USB_DRVVBUS_P1 (MTK_PIN_NO(11) | 6) +#define MT8173_PIN_11_EINT11__FUNC_DBG_MON_B_30_ (MTK_PIN_NO(11) | 7) + +#define MT8173_PIN_12_EINT12__FUNC_GPIO12 (MTK_PIN_NO(12) | 0) +#define MT8173_PIN_12_EINT12__FUNC_CLKM2 (MTK_PIN_NO(12) | 1) +#define MT8173_PIN_12_EINT12__FUNC_I2S3_BCK (MTK_PIN_NO(12) | 2) +#define MT8173_PIN_12_EINT12__FUNC_SRCLKENA0 (MTK_PIN_NO(12) | 3) +#define MT8173_PIN_12_EINT12__FUNC_I2S2_WS (MTK_PIN_NO(12) | 5) +#define MT8173_PIN_12_EINT12__FUNC_DBG_MON_B_32_ (MTK_PIN_NO(12) | 7) + +#define MT8173_PIN_13_EINT13__FUNC_GPIO13 (MTK_PIN_NO(13) | 0) +#define MT8173_PIN_13_EINT13__FUNC_CLKM3 (MTK_PIN_NO(13) | 1) +#define MT8173_PIN_13_EINT13__FUNC_I2S3_MCK (MTK_PIN_NO(13) | 2) +#define MT8173_PIN_13_EINT13__FUNC_SRCLKENA0 (MTK_PIN_NO(13) | 3) +#define MT8173_PIN_13_EINT13__FUNC_I2S2_BCK (MTK_PIN_NO(13) | 5) +#define MT8173_PIN_13_EINT13__FUNC_DBG_MON_A_32_ (MTK_PIN_NO(13) | 7) + +#define MT8173_PIN_14_EINT14__FUNC_GPIO14 (MTK_PIN_NO(14) | 0) +#define MT8173_PIN_14_EINT14__FUNC_CMDAT0 (MTK_PIN_NO(14) | 1) +#define MT8173_PIN_14_EINT14__FUNC_CMCSD0 (MTK_PIN_NO(14) | 2) +#define MT8173_PIN_14_EINT14__FUNC_CLKM2 (MTK_PIN_NO(14) | 4) +#define MT8173_PIN_14_EINT14__FUNC_DBG_MON_B_6_ (MTK_PIN_NO(14) | 7) + +#define MT8173_PIN_15_EINT15__FUNC_GPIO15 (MTK_PIN_NO(15) | 0) +#define MT8173_PIN_15_EINT15__FUNC_CMDAT1 (MTK_PIN_NO(15) | 1) +#define MT8173_PIN_15_EINT15__FUNC_CMCSD1 (MTK_PIN_NO(15) | 2) +#define MT8173_PIN_15_EINT15__FUNC_CMFLASH (MTK_PIN_NO(15) | 3) +#define MT8173_PIN_15_EINT15__FUNC_CLKM3 (MTK_PIN_NO(15) | 4) +#define MT8173_PIN_15_EINT15__FUNC_DBG_MON_B_29_ (MTK_PIN_NO(15) | 7) + +#define MT8173_PIN_16_IDDIG__FUNC_GPIO16 (MTK_PIN_NO(16) | 0) +#define MT8173_PIN_16_IDDIG__FUNC_IDDIG (MTK_PIN_NO(16) | 1) +#define MT8173_PIN_16_IDDIG__FUNC_CMFLASH (MTK_PIN_NO(16) | 2) +#define MT8173_PIN_16_IDDIG__FUNC_PWM5 (MTK_PIN_NO(16) | 4) + +#define MT8173_PIN_17_WATCHDOG__FUNC_GPIO17 (MTK_PIN_NO(17) | 0) +#define MT8173_PIN_17_WATCHDOG__FUNC_WATCHDOG_AO (MTK_PIN_NO(17) | 1) + +#define MT8173_PIN_18_CEC__FUNC_GPIO18 (MTK_PIN_NO(18) | 0) +#define MT8173_PIN_18_CEC__FUNC_CEC (MTK_PIN_NO(18) | 1) + +#define MT8173_PIN_19_HDMISCK__FUNC_GPIO19 (MTK_PIN_NO(19) | 0) +#define MT8173_PIN_19_HDMISCK__FUNC_HDMISCK (MTK_PIN_NO(19) | 1) +#define MT8173_PIN_19_HDMISCK__FUNC_HDCP_SCL (MTK_PIN_NO(19) | 2) + +#define MT8173_PIN_20_HDMISD__FUNC_GPIO20 (MTK_PIN_NO(20) | 0) +#define MT8173_PIN_20_HDMISD__FUNC_HDMISD (MTK_PIN_NO(20) | 1) +#define MT8173_PIN_20_HDMISD__FUNC_HDCP_SDA (MTK_PIN_NO(20) | 2) + +#define MT8173_PIN_21_HTPLG__FUNC_GPIO21 (MTK_PIN_NO(21) | 0) +#define MT8173_PIN_21_HTPLG__FUNC_HTPLG (MTK_PIN_NO(21) | 1) + +#define MT8173_PIN_22_MSDC3_DAT0__FUNC_GPIO22 (MTK_PIN_NO(22) | 0) +#define MT8173_PIN_22_MSDC3_DAT0__FUNC_MSDC3_DAT0 (MTK_PIN_NO(22) | 1) + +#define MT8173_PIN_23_MSDC3_DAT1__FUNC_GPIO23 (MTK_PIN_NO(23) | 0) +#define MT8173_PIN_23_MSDC3_DAT1__FUNC_MSDC3_DAT1 (MTK_PIN_NO(23) | 1) + +#define MT8173_PIN_24_MSDC3_DAT2__FUNC_GPIO24 (MTK_PIN_NO(24) | 0) +#define MT8173_PIN_24_MSDC3_DAT2__FUNC_MSDC3_DAT2 (MTK_PIN_NO(24) | 1) + +#define MT8173_PIN_25_MSDC3_DAT3__FUNC_GPIO25 (MTK_PIN_NO(25) | 0) +#define MT8173_PIN_25_MSDC3_DAT3__FUNC_MSDC3_DAT3 (MTK_PIN_NO(25) | 1) + +#define MT8173_PIN_26_MSDC3_CLK__FUNC_GPIO26 (MTK_PIN_NO(26) | 0) +#define MT8173_PIN_26_MSDC3_CLK__FUNC_MSDC3_CLK (MTK_PIN_NO(26) | 1) + +#define MT8173_PIN_27_MSDC3_CMD__FUNC_GPIO27 (MTK_PIN_NO(27) | 0) +#define MT8173_PIN_27_MSDC3_CMD__FUNC_MSDC3_CMD (MTK_PIN_NO(27) | 1) + +#define MT8173_PIN_28_MSDC3_DSL__FUNC_GPIO28 (MTK_PIN_NO(28) | 0) +#define MT8173_PIN_28_MSDC3_DSL__FUNC_MSDC3_DSL (MTK_PIN_NO(28) | 1) + +#define MT8173_PIN_29_UCTS2__FUNC_GPIO29 (MTK_PIN_NO(29) | 0) +#define MT8173_PIN_29_UCTS2__FUNC_UCTS2 (MTK_PIN_NO(29) | 1) + +#define MT8173_PIN_30_URTS2__FUNC_GPIO30 (MTK_PIN_NO(30) | 0) +#define MT8173_PIN_30_URTS2__FUNC_URTS2 (MTK_PIN_NO(30) | 1) + +#define MT8173_PIN_31_URXD2__FUNC_GPIO31 (MTK_PIN_NO(31) | 0) +#define MT8173_PIN_31_URXD2__FUNC_URXD2 (MTK_PIN_NO(31) | 1) +#define MT8173_PIN_31_URXD2__FUNC_UTXD2 (MTK_PIN_NO(31) | 2) + +#define MT8173_PIN_32_UTXD2__FUNC_GPIO32 (MTK_PIN_NO(32) | 0) +#define MT8173_PIN_32_UTXD2__FUNC_UTXD2 (MTK_PIN_NO(32) | 1) +#define MT8173_PIN_32_UTXD2__FUNC_URXD2 (MTK_PIN_NO(32) | 2) + +#define MT8173_PIN_33_DAICLK__FUNC_GPIO33 (MTK_PIN_NO(33) | 0) +#define MT8173_PIN_33_DAICLK__FUNC_MRG_CLK (MTK_PIN_NO(33) | 1) +#define MT8173_PIN_33_DAICLK__FUNC_PCM0_CLK (MTK_PIN_NO(33) | 2) + +#define MT8173_PIN_34_DAIPCMIN__FUNC_GPIO34 (MTK_PIN_NO(34) | 0) +#define MT8173_PIN_34_DAIPCMIN__FUNC_MRG_DI (MTK_PIN_NO(34) | 1) +#define MT8173_PIN_34_DAIPCMIN__FUNC_PCM0_DI (MTK_PIN_NO(34) | 2) + +#define MT8173_PIN_35_DAIPCMOUT__FUNC_GPIO35 (MTK_PIN_NO(35) | 0) +#define MT8173_PIN_35_DAIPCMOUT__FUNC_MRG_DO (MTK_PIN_NO(35) | 1) +#define MT8173_PIN_35_DAIPCMOUT__FUNC_PCM0_DO (MTK_PIN_NO(35) | 2) + +#define MT8173_PIN_36_DAISYNC__FUNC_GPIO36 (MTK_PIN_NO(36) | 0) +#define MT8173_PIN_36_DAISYNC__FUNC_MRG_SYNC (MTK_PIN_NO(36) | 1) +#define MT8173_PIN_36_DAISYNC__FUNC_PCM0_SYNC (MTK_PIN_NO(36) | 2) + +#define MT8173_PIN_37_EINT16__FUNC_GPIO37 (MTK_PIN_NO(37) | 0) +#define MT8173_PIN_37_EINT16__FUNC_USB_DRVVBUS_P0 (MTK_PIN_NO(37) | 1) +#define MT8173_PIN_37_EINT16__FUNC_USB_DRVVBUS_P1 (MTK_PIN_NO(37) | 2) +#define MT8173_PIN_37_EINT16__FUNC_PWM0 (MTK_PIN_NO(37) | 3) +#define MT8173_PIN_37_EINT16__FUNC_PWM1 (MTK_PIN_NO(37) | 4) +#define MT8173_PIN_37_EINT16__FUNC_PWM2 (MTK_PIN_NO(37) | 5) +#define MT8173_PIN_37_EINT16__FUNC_CLKM0 (MTK_PIN_NO(37) | 6) + +#define MT8173_PIN_38_CONN_RST__FUNC_GPIO38 (MTK_PIN_NO(38) | 0) +#define MT8173_PIN_38_CONN_RST__FUNC_USB_DRVVBUS_P0 (MTK_PIN_NO(38) | 1) +#define MT8173_PIN_38_CONN_RST__FUNC_USB_DRVVBUS_P1 (MTK_PIN_NO(38) | 2) +#define MT8173_PIN_38_CONN_RST__FUNC_CLKM1 (MTK_PIN_NO(38) | 6) + +#define MT8173_PIN_39_CM2MCLK__FUNC_GPIO39 (MTK_PIN_NO(39) | 0) +#define MT8173_PIN_39_CM2MCLK__FUNC_CM2MCLK (MTK_PIN_NO(39) | 1) +#define MT8173_PIN_39_CM2MCLK__FUNC_CMCSD0 (MTK_PIN_NO(39) | 2) +#define MT8173_PIN_39_CM2MCLK__FUNC_DBG_MON_A_17_ (MTK_PIN_NO(39) | 7) + +#define MT8173_PIN_40_CMPCLK__FUNC_GPIO40 (MTK_PIN_NO(40) | 0) +#define MT8173_PIN_40_CMPCLK__FUNC_CMPCLK (MTK_PIN_NO(40) | 1) +#define MT8173_PIN_40_CMPCLK__FUNC_CMCSK (MTK_PIN_NO(40) | 2) +#define MT8173_PIN_40_CMPCLK__FUNC_CMCSD2 (MTK_PIN_NO(40) | 3) +#define MT8173_PIN_40_CMPCLK__FUNC_DBG_MON_A_18_ (MTK_PIN_NO(40) | 7) + +#define MT8173_PIN_41_CMMCLK__FUNC_GPIO41 (MTK_PIN_NO(41) | 0) +#define MT8173_PIN_41_CMMCLK__FUNC_CMMCLK (MTK_PIN_NO(41) | 1) +#define MT8173_PIN_41_CMMCLK__FUNC_DBG_MON_A_19_ (MTK_PIN_NO(41) | 7) + +#define MT8173_PIN_42_DSI_TE__FUNC_GPIO42 (MTK_PIN_NO(42) | 0) +#define MT8173_PIN_42_DSI_TE__FUNC_DSI_TE (MTK_PIN_NO(42) | 1) + +#define MT8173_PIN_43_SDA2__FUNC_GPIO43 (MTK_PIN_NO(43) | 0) +#define MT8173_PIN_43_SDA2__FUNC_SDA2 (MTK_PIN_NO(43) | 1) + +#define MT8173_PIN_44_SCL2__FUNC_GPIO44 (MTK_PIN_NO(44) | 0) +#define MT8173_PIN_44_SCL2__FUNC_SCL2 (MTK_PIN_NO(44) | 1) + +#define MT8173_PIN_45_SDA0__FUNC_GPIO45 (MTK_PIN_NO(45) | 0) +#define MT8173_PIN_45_SDA0__FUNC_SDA0 (MTK_PIN_NO(45) | 1) + +#define MT8173_PIN_46_SCL0__FUNC_GPIO46 (MTK_PIN_NO(46) | 0) +#define MT8173_PIN_46_SCL0__FUNC_SCL0 (MTK_PIN_NO(46) | 1) + +#define MT8173_PIN_47_RDN0_A__FUNC_GPIO47 (MTK_PIN_NO(47) | 0) +#define MT8173_PIN_47_RDN0_A__FUNC_CMDAT2 (MTK_PIN_NO(47) | 1) + +#define MT8173_PIN_48_RDP0_A__FUNC_GPIO48 (MTK_PIN_NO(48) | 0) +#define MT8173_PIN_48_RDP0_A__FUNC_CMDAT3 (MTK_PIN_NO(48) | 1) + +#define MT8173_PIN_49_RDN1_A__FUNC_GPIO49 (MTK_PIN_NO(49) | 0) +#define MT8173_PIN_49_RDN1_A__FUNC_CMDAT4 (MTK_PIN_NO(49) | 1) + +#define MT8173_PIN_50_RDP1_A__FUNC_GPIO50 (MTK_PIN_NO(50) | 0) +#define MT8173_PIN_50_RDP1_A__FUNC_CMDAT5 (MTK_PIN_NO(50) | 1) + +#define MT8173_PIN_51_RCN_A__FUNC_GPIO51 (MTK_PIN_NO(51) | 0) +#define MT8173_PIN_51_RCN_A__FUNC_CMDAT6 (MTK_PIN_NO(51) | 1) + +#define MT8173_PIN_52_RCP_A__FUNC_GPIO52 (MTK_PIN_NO(52) | 0) +#define MT8173_PIN_52_RCP_A__FUNC_CMDAT7 (MTK_PIN_NO(52) | 1) + +#define MT8173_PIN_53_RDN2_A__FUNC_GPIO53 (MTK_PIN_NO(53) | 0) +#define MT8173_PIN_53_RDN2_A__FUNC_CMDAT8 (MTK_PIN_NO(53) | 1) +#define MT8173_PIN_53_RDN2_A__FUNC_CMCSD3 (MTK_PIN_NO(53) | 2) + +#define MT8173_PIN_54_RDP2_A__FUNC_GPIO54 (MTK_PIN_NO(54) | 0) +#define MT8173_PIN_54_RDP2_A__FUNC_CMDAT9 (MTK_PIN_NO(54) | 1) +#define MT8173_PIN_54_RDP2_A__FUNC_CMCSD2 (MTK_PIN_NO(54) | 2) + +#define MT8173_PIN_55_RDN3_A__FUNC_GPIO55 (MTK_PIN_NO(55) | 0) +#define MT8173_PIN_55_RDN3_A__FUNC_CMHSYNC (MTK_PIN_NO(55) | 1) +#define MT8173_PIN_55_RDN3_A__FUNC_CMCSD1 (MTK_PIN_NO(55) | 2) + +#define MT8173_PIN_56_RDP3_A__FUNC_GPIO56 (MTK_PIN_NO(56) | 0) +#define MT8173_PIN_56_RDP3_A__FUNC_CMVSYNC (MTK_PIN_NO(56) | 1) +#define MT8173_PIN_56_RDP3_A__FUNC_CMCSD0 (MTK_PIN_NO(56) | 2) + +#define MT8173_PIN_57_MSDC0_DAT0__FUNC_GPIO57 (MTK_PIN_NO(57) | 0) +#define MT8173_PIN_57_MSDC0_DAT0__FUNC_MSDC0_DAT0 (MTK_PIN_NO(57) | 1) +#define MT8173_PIN_57_MSDC0_DAT0__FUNC_I2S1_WS (MTK_PIN_NO(57) | 2) +#define MT8173_PIN_57_MSDC0_DAT0__FUNC_DBG_MON_B_7_ (MTK_PIN_NO(57) | 7) + +#define MT8173_PIN_58_MSDC0_DAT1__FUNC_GPIO58 (MTK_PIN_NO(58) | 0) +#define MT8173_PIN_58_MSDC0_DAT1__FUNC_MSDC0_DAT1 (MTK_PIN_NO(58) | 1) +#define MT8173_PIN_58_MSDC0_DAT1__FUNC_I2S1_BCK (MTK_PIN_NO(58) | 2) +#define MT8173_PIN_58_MSDC0_DAT1__FUNC_DBG_MON_B_8_ (MTK_PIN_NO(58) | 7) + +#define MT8173_PIN_59_MSDC0_DAT2__FUNC_GPIO59 (MTK_PIN_NO(59) | 0) +#define MT8173_PIN_59_MSDC0_DAT2__FUNC_MSDC0_DAT2 (MTK_PIN_NO(59) | 1) +#define MT8173_PIN_59_MSDC0_DAT2__FUNC_I2S1_MCK (MTK_PIN_NO(59) | 2) +#define MT8173_PIN_59_MSDC0_DAT2__FUNC_DBG_MON_B_9_ (MTK_PIN_NO(59) | 7) + +#define MT8173_PIN_60_MSDC0_DAT3__FUNC_GPIO60 (MTK_PIN_NO(60) | 0) +#define MT8173_PIN_60_MSDC0_DAT3__FUNC_MSDC0_DAT3 (MTK_PIN_NO(60) | 1) +#define MT8173_PIN_60_MSDC0_DAT3__FUNC_I2S1_DO_1 (MTK_PIN_NO(60) | 2) +#define MT8173_PIN_60_MSDC0_DAT3__FUNC_DBG_MON_B_10_ (MTK_PIN_NO(60) | 7) + +#define MT8173_PIN_61_MSDC0_DAT4__FUNC_GPIO61 (MTK_PIN_NO(61) | 0) +#define MT8173_PIN_61_MSDC0_DAT4__FUNC_MSDC0_DAT4 (MTK_PIN_NO(61) | 1) +#define MT8173_PIN_61_MSDC0_DAT4__FUNC_I2S1_DO_2 (MTK_PIN_NO(61) | 2) +#define MT8173_PIN_61_MSDC0_DAT4__FUNC_DBG_MON_B_11_ (MTK_PIN_NO(61) | 7) + +#define MT8173_PIN_62_MSDC0_DAT5__FUNC_GPIO62 (MTK_PIN_NO(62) | 0) +#define MT8173_PIN_62_MSDC0_DAT5__FUNC_MSDC0_DAT5 (MTK_PIN_NO(62) | 1) +#define MT8173_PIN_62_MSDC0_DAT5__FUNC_I2S2_WS (MTK_PIN_NO(62) | 2) +#define MT8173_PIN_62_MSDC0_DAT5__FUNC_DBG_MON_B_12_ (MTK_PIN_NO(62) | 7) + +#define MT8173_PIN_63_MSDC0_DAT6__FUNC_GPIO63 (MTK_PIN_NO(63) | 0) +#define MT8173_PIN_63_MSDC0_DAT6__FUNC_MSDC0_DAT6 (MTK_PIN_NO(63) | 1) +#define MT8173_PIN_63_MSDC0_DAT6__FUNC_I2S2_BCK (MTK_PIN_NO(63) | 2) +#define MT8173_PIN_63_MSDC0_DAT6__FUNC_DBG_MON_B_13_ (MTK_PIN_NO(63) | 7) + +#define MT8173_PIN_64_MSDC0_DAT7__FUNC_GPIO64 (MTK_PIN_NO(64) | 0) +#define MT8173_PIN_64_MSDC0_DAT7__FUNC_MSDC0_DAT7 (MTK_PIN_NO(64) | 1) +#define MT8173_PIN_64_MSDC0_DAT7__FUNC_I2S2_DI_1 (MTK_PIN_NO(64) | 2) +#define MT8173_PIN_64_MSDC0_DAT7__FUNC_DBG_MON_B_14_ (MTK_PIN_NO(64) | 7) + +#define MT8173_PIN_65_MSDC0_CLK__FUNC_GPIO65 (MTK_PIN_NO(65) | 0) +#define MT8173_PIN_65_MSDC0_CLK__FUNC_MSDC0_CLK (MTK_PIN_NO(65) | 1) +#define MT8173_PIN_65_MSDC0_CLK__FUNC_DBG_MON_B_16_ (MTK_PIN_NO(65) | 7) + +#define MT8173_PIN_66_MSDC0_CMD__FUNC_GPIO66 (MTK_PIN_NO(66) | 0) +#define MT8173_PIN_66_MSDC0_CMD__FUNC_MSDC0_CMD (MTK_PIN_NO(66) | 1) +#define MT8173_PIN_66_MSDC0_CMD__FUNC_I2S2_DI_2 (MTK_PIN_NO(66) | 2) +#define MT8173_PIN_66_MSDC0_CMD__FUNC_DBG_MON_B_15_ (MTK_PIN_NO(66) | 7) + +#define MT8173_PIN_67_MSDC0_DSL__FUNC_GPIO67 (MTK_PIN_NO(67) | 0) +#define MT8173_PIN_67_MSDC0_DSL__FUNC_MSDC0_DSL (MTK_PIN_NO(67) | 1) +#define MT8173_PIN_67_MSDC0_DSL__FUNC_DBG_MON_B_17_ (MTK_PIN_NO(67) | 7) + +#define MT8173_PIN_68_MSDC0_RST___FUNC_GPIO68 (MTK_PIN_NO(68) | 0) +#define MT8173_PIN_68_MSDC0_RST___FUNC_MSDC0_RSTB (MTK_PIN_NO(68) | 1) +#define MT8173_PIN_68_MSDC0_RST___FUNC_I2S2_MCK (MTK_PIN_NO(68) | 2) +#define MT8173_PIN_68_MSDC0_RST___FUNC_DBG_MON_B_18_ (MTK_PIN_NO(68) | 7) + +#define MT8173_PIN_69_SPI_CK__FUNC_GPIO69 (MTK_PIN_NO(69) | 0) +#define MT8173_PIN_69_SPI_CK__FUNC_SPI_CK_0_ (MTK_PIN_NO(69) | 1) +#define MT8173_PIN_69_SPI_CK__FUNC_I2S3_DO_1 (MTK_PIN_NO(69) | 2) +#define MT8173_PIN_69_SPI_CK__FUNC_PWM0 (MTK_PIN_NO(69) | 3) +#define MT8173_PIN_69_SPI_CK__FUNC_PWM5 (MTK_PIN_NO(69) | 4) +#define MT8173_PIN_69_SPI_CK__FUNC_I2S2_MCK (MTK_PIN_NO(69) | 5) +#define MT8173_PIN_69_SPI_CK__FUNC_DBG_MON_B_19_ (MTK_PIN_NO(69) | 7) + +#define MT8173_PIN_70_SPI_MI__FUNC_GPIO70 (MTK_PIN_NO(70) | 0) +#define MT8173_PIN_70_SPI_MI__FUNC_SPI_MI_0_ (MTK_PIN_NO(70) | 1) +#define MT8173_PIN_70_SPI_MI__FUNC_I2S3_DO_2 (MTK_PIN_NO(70) | 2) +#define MT8173_PIN_70_SPI_MI__FUNC_PWM1 (MTK_PIN_NO(70) | 3) +#define MT8173_PIN_70_SPI_MI__FUNC_SPI_MO_0_ (MTK_PIN_NO(70) | 4) +#define MT8173_PIN_70_SPI_MI__FUNC_I2S2_DI_1 (MTK_PIN_NO(70) | 5) +#define MT8173_PIN_70_SPI_MI__FUNC_DSI1_TE (MTK_PIN_NO(70) | 6) +#define MT8173_PIN_70_SPI_MI__FUNC_DBG_MON_B_20_ (MTK_PIN_NO(70) | 7) + +#define MT8173_PIN_71_SPI_MO__FUNC_GPIO71 (MTK_PIN_NO(71) | 0) +#define MT8173_PIN_71_SPI_MO__FUNC_SPI_MO_0_ (MTK_PIN_NO(71) | 1) +#define MT8173_PIN_71_SPI_MO__FUNC_I2S3_DO_3 (MTK_PIN_NO(71) | 2) +#define MT8173_PIN_71_SPI_MO__FUNC_PWM2 (MTK_PIN_NO(71) | 3) +#define MT8173_PIN_71_SPI_MO__FUNC_SPI_MI_0_ (MTK_PIN_NO(71) | 4) +#define MT8173_PIN_71_SPI_MO__FUNC_I2S2_DI_2 (MTK_PIN_NO(71) | 5) +#define MT8173_PIN_71_SPI_MO__FUNC_DBG_MON_B_21_ (MTK_PIN_NO(71) | 7) + +#define MT8173_PIN_72_SPI_CS__FUNC_GPIO72 (MTK_PIN_NO(72) | 0) +#define MT8173_PIN_72_SPI_CS__FUNC_SPI_CS_0_ (MTK_PIN_NO(72) | 1) +#define MT8173_PIN_72_SPI_CS__FUNC_I2S3_DO_4 (MTK_PIN_NO(72) | 2) +#define MT8173_PIN_72_SPI_CS__FUNC_PWM3 (MTK_PIN_NO(72) | 3) +#define MT8173_PIN_72_SPI_CS__FUNC_PWM6 (MTK_PIN_NO(72) | 4) +#define MT8173_PIN_72_SPI_CS__FUNC_DISP_PWM1 (MTK_PIN_NO(72) | 5) +#define MT8173_PIN_72_SPI_CS__FUNC_DBG_MON_B_22_ (MTK_PIN_NO(72) | 7) + +#define MT8173_PIN_73_MSDC1_DAT0__FUNC_GPIO73 (MTK_PIN_NO(73) | 0) +#define MT8173_PIN_73_MSDC1_DAT0__FUNC_MSDC1_DAT0 (MTK_PIN_NO(73) | 1) +#define MT8173_PIN_73_MSDC1_DAT0__FUNC_DBG_MON_B_24_ (MTK_PIN_NO(73) | 7) + +#define MT8173_PIN_74_MSDC1_DAT1__FUNC_GPIO74 (MTK_PIN_NO(74) | 0) +#define MT8173_PIN_74_MSDC1_DAT1__FUNC_MSDC1_DAT1 (MTK_PIN_NO(74) | 1) +#define MT8173_PIN_74_MSDC1_DAT1__FUNC_DBG_MON_B_25_ (MTK_PIN_NO(74) | 7) + +#define MT8173_PIN_75_MSDC1_DAT2__FUNC_GPIO75 (MTK_PIN_NO(75) | 0) +#define MT8173_PIN_75_MSDC1_DAT2__FUNC_MSDC1_DAT2 (MTK_PIN_NO(75) | 1) +#define MT8173_PIN_75_MSDC1_DAT2__FUNC_DBG_MON_B_26_ (MTK_PIN_NO(75) | 7) + +#define MT8173_PIN_76_MSDC1_DAT3__FUNC_GPIO76 (MTK_PIN_NO(76) | 0) +#define MT8173_PIN_76_MSDC1_DAT3__FUNC_MSDC1_DAT3 (MTK_PIN_NO(76) | 1) +#define MT8173_PIN_76_MSDC1_DAT3__FUNC_DBG_MON_B_27_ (MTK_PIN_NO(76) | 7) + +#define MT8173_PIN_77_MSDC1_CLK__FUNC_GPIO77 (MTK_PIN_NO(77) | 0) +#define MT8173_PIN_77_MSDC1_CLK__FUNC_MSDC1_CLK (MTK_PIN_NO(77) | 1) +#define MT8173_PIN_77_MSDC1_CLK__FUNC_DBG_MON_B_28_ (MTK_PIN_NO(77) | 7) + +#define MT8173_PIN_78_MSDC1_CMD__FUNC_GPIO78 (MTK_PIN_NO(78) | 0) +#define MT8173_PIN_78_MSDC1_CMD__FUNC_MSDC1_CMD (MTK_PIN_NO(78) | 1) +#define MT8173_PIN_78_MSDC1_CMD__FUNC_DBG_MON_B_23_ (MTK_PIN_NO(78) | 7) + +#define MT8173_PIN_79_PWRAP_SPI0_MI__FUNC_GPIO79 (MTK_PIN_NO(79) | 0) +#define MT8173_PIN_79_PWRAP_SPI0_MI__FUNC_PWRAP_SPIMI (MTK_PIN_NO(79) | 1) +#define MT8173_PIN_79_PWRAP_SPI0_MI__FUNC_PWRAP_SPIMO (MTK_PIN_NO(79) | 2) + +#define MT8173_PIN_80_PWRAP_SPI0_MO__FUNC_GPIO80 (MTK_PIN_NO(80) | 0) +#define MT8173_PIN_80_PWRAP_SPI0_MO__FUNC_PWRAP_SPIMO (MTK_PIN_NO(80) | 1) +#define MT8173_PIN_80_PWRAP_SPI0_MO__FUNC_PWRAP_SPIMI (MTK_PIN_NO(80) | 2) + +#define MT8173_PIN_81_PWRAP_SPI0_CK__FUNC_GPIO81 (MTK_PIN_NO(81) | 0) +#define MT8173_PIN_81_PWRAP_SPI0_CK__FUNC_PWRAP_SPICK (MTK_PIN_NO(81) | 1) + +#define MT8173_PIN_82_PWRAP_SPI0_CSN__FUNC_GPIO82 (MTK_PIN_NO(82) | 0) +#define MT8173_PIN_82_PWRAP_SPI0_CSN__FUNC_PWRAP_SPICS (MTK_PIN_NO(82) | 1) + +#define MT8173_PIN_83_AUD_CLK_MOSI__FUNC_GPIO83 (MTK_PIN_NO(83) | 0) +#define MT8173_PIN_83_AUD_CLK_MOSI__FUNC_AUD_CLK_MOSI (MTK_PIN_NO(83) | 1) + +#define MT8173_PIN_84_AUD_DAT_MISO__FUNC_GPIO84 (MTK_PIN_NO(84) | 0) +#define MT8173_PIN_84_AUD_DAT_MISO__FUNC_AUD_DAT_MISO (MTK_PIN_NO(84) | 1) +#define MT8173_PIN_84_AUD_DAT_MISO__FUNC_AUD_DAT_MOSI (MTK_PIN_NO(84) | 2) + +#define MT8173_PIN_85_AUD_DAT_MOSI__FUNC_GPIO85 (MTK_PIN_NO(85) | 0) +#define MT8173_PIN_85_AUD_DAT_MOSI__FUNC_AUD_DAT_MOSI (MTK_PIN_NO(85) | 1) +#define MT8173_PIN_85_AUD_DAT_MOSI__FUNC_AUD_DAT_MISO (MTK_PIN_NO(85) | 2) + +#define MT8173_PIN_86_RTC32K_CK__FUNC_GPIO86 (MTK_PIN_NO(86) | 0) +#define MT8173_PIN_86_RTC32K_CK__FUNC_RTC32K_CK (MTK_PIN_NO(86) | 1) + +#define MT8173_PIN_87_DISP_PWM0__FUNC_GPIO87 (MTK_PIN_NO(87) | 0) +#define MT8173_PIN_87_DISP_PWM0__FUNC_DISP_PWM0 (MTK_PIN_NO(87) | 1) +#define MT8173_PIN_87_DISP_PWM0__FUNC_DISP_PWM1 (MTK_PIN_NO(87) | 2) +#define MT8173_PIN_87_DISP_PWM0__FUNC_DBG_MON_B_31_ (MTK_PIN_NO(87) | 7) + +#define MT8173_PIN_88_SRCLKENAI__FUNC_GPIO88 (MTK_PIN_NO(88) | 0) +#define MT8173_PIN_88_SRCLKENAI__FUNC_SRCLKENAI (MTK_PIN_NO(88) | 1) + +#define MT8173_PIN_89_SRCLKENAI2__FUNC_GPIO89 (MTK_PIN_NO(89) | 0) +#define MT8173_PIN_89_SRCLKENAI2__FUNC_SRCLKENAI2 (MTK_PIN_NO(89) | 1) + +#define MT8173_PIN_90_SRCLKENA0__FUNC_GPIO90 (MTK_PIN_NO(90) | 0) +#define MT8173_PIN_90_SRCLKENA0__FUNC_SRCLKENA0 (MTK_PIN_NO(90) | 1) + +#define MT8173_PIN_91_SRCLKENA1__FUNC_GPIO91 (MTK_PIN_NO(91) | 0) +#define MT8173_PIN_91_SRCLKENA1__FUNC_SRCLKENA1 (MTK_PIN_NO(91) | 1) + +#define MT8173_PIN_92_PCM_CLK__FUNC_GPIO92 (MTK_PIN_NO(92) | 0) +#define MT8173_PIN_92_PCM_CLK__FUNC_PCM1_CLK (MTK_PIN_NO(92) | 1) +#define MT8173_PIN_92_PCM_CLK__FUNC_I2S0_BCK (MTK_PIN_NO(92) | 2) +#define MT8173_PIN_92_PCM_CLK__FUNC_DBG_MON_A_24_ (MTK_PIN_NO(92) | 7) + +#define MT8173_PIN_93_PCM_SYNC__FUNC_GPIO93 (MTK_PIN_NO(93) | 0) +#define MT8173_PIN_93_PCM_SYNC__FUNC_PCM1_SYNC (MTK_PIN_NO(93) | 1) +#define MT8173_PIN_93_PCM_SYNC__FUNC_I2S0_WS (MTK_PIN_NO(93) | 2) +#define MT8173_PIN_93_PCM_SYNC__FUNC_DBG_MON_A_25_ (MTK_PIN_NO(93) | 7) + +#define MT8173_PIN_94_PCM_RX__FUNC_GPIO94 (MTK_PIN_NO(94) | 0) +#define MT8173_PIN_94_PCM_RX__FUNC_PCM1_DI (MTK_PIN_NO(94) | 1) +#define MT8173_PIN_94_PCM_RX__FUNC_I2S0_DI (MTK_PIN_NO(94) | 2) +#define MT8173_PIN_94_PCM_RX__FUNC_DBG_MON_A_26_ (MTK_PIN_NO(94) | 7) + +#define MT8173_PIN_95_PCM_TX__FUNC_GPIO95 (MTK_PIN_NO(95) | 0) +#define MT8173_PIN_95_PCM_TX__FUNC_PCM1_DO (MTK_PIN_NO(95) | 1) +#define MT8173_PIN_95_PCM_TX__FUNC_I2S0_DO (MTK_PIN_NO(95) | 2) +#define MT8173_PIN_95_PCM_TX__FUNC_DBG_MON_A_27_ (MTK_PIN_NO(95) | 7) + +#define MT8173_PIN_96_URXD1__FUNC_GPIO96 (MTK_PIN_NO(96) | 0) +#define MT8173_PIN_96_URXD1__FUNC_URXD1 (MTK_PIN_NO(96) | 1) +#define MT8173_PIN_96_URXD1__FUNC_UTXD1 (MTK_PIN_NO(96) | 2) +#define MT8173_PIN_96_URXD1__FUNC_DBG_MON_A_28_ (MTK_PIN_NO(96) | 7) + +#define MT8173_PIN_97_UTXD1__FUNC_GPIO97 (MTK_PIN_NO(97) | 0) +#define MT8173_PIN_97_UTXD1__FUNC_UTXD1 (MTK_PIN_NO(97) | 1) +#define MT8173_PIN_97_UTXD1__FUNC_URXD1 (MTK_PIN_NO(97) | 2) +#define MT8173_PIN_97_UTXD1__FUNC_DBG_MON_A_29_ (MTK_PIN_NO(97) | 7) + +#define MT8173_PIN_98_URTS1__FUNC_GPIO98 (MTK_PIN_NO(98) | 0) +#define MT8173_PIN_98_URTS1__FUNC_URTS1 (MTK_PIN_NO(98) | 1) +#define MT8173_PIN_98_URTS1__FUNC_UCTS1 (MTK_PIN_NO(98) | 2) +#define MT8173_PIN_98_URTS1__FUNC_DBG_MON_A_30_ (MTK_PIN_NO(98) | 7) + +#define MT8173_PIN_99_UCTS1__FUNC_GPIO99 (MTK_PIN_NO(99) | 0) +#define MT8173_PIN_99_UCTS1__FUNC_UCTS1 (MTK_PIN_NO(99) | 1) +#define MT8173_PIN_99_UCTS1__FUNC_URTS1 (MTK_PIN_NO(99) | 2) +#define MT8173_PIN_99_UCTS1__FUNC_DBG_MON_A_31_ (MTK_PIN_NO(99) | 7) + +#define MT8173_PIN_100_MSDC2_DAT0__FUNC_GPIO100 (MTK_PIN_NO(100) | 0) +#define MT8173_PIN_100_MSDC2_DAT0__FUNC_MSDC2_DAT0 (MTK_PIN_NO(100) | 1) +#define MT8173_PIN_100_MSDC2_DAT0__FUNC_USB_DRVVBUS_P0 (MTK_PIN_NO(100) | 3) +#define MT8173_PIN_100_MSDC2_DAT0__FUNC_SDA5 (MTK_PIN_NO(100) | 4) +#define MT8173_PIN_100_MSDC2_DAT0__FUNC_USB_DRVVBUS_P1 (MTK_PIN_NO(100) | 5) +#define MT8173_PIN_100_MSDC2_DAT0__FUNC_DBG_MON_B_0_ (MTK_PIN_NO(100) | 7) + +#define MT8173_PIN_101_MSDC2_DAT1__FUNC_GPIO101 (MTK_PIN_NO(101) | 0) +#define MT8173_PIN_101_MSDC2_DAT1__FUNC_MSDC2_DAT1 (MTK_PIN_NO(101) | 1) +#define MT8173_PIN_101_MSDC2_DAT1__FUNC_AUD_SPDIF (MTK_PIN_NO(101) | 3) +#define MT8173_PIN_101_MSDC2_DAT1__FUNC_SCL5 (MTK_PIN_NO(101) | 4) +#define MT8173_PIN_101_MSDC2_DAT1__FUNC_DBG_MON_B_1_ (MTK_PIN_NO(101) | 7) + +#define MT8173_PIN_102_MSDC2_DAT2__FUNC_GPIO102 (MTK_PIN_NO(102) | 0) +#define MT8173_PIN_102_MSDC2_DAT2__FUNC_MSDC2_DAT2 (MTK_PIN_NO(102) | 1) +#define MT8173_PIN_102_MSDC2_DAT2__FUNC_UTXD0 (MTK_PIN_NO(102) | 3) +#define MT8173_PIN_102_MSDC2_DAT2__FUNC_PWM0 (MTK_PIN_NO(102) | 5) +#define MT8173_PIN_102_MSDC2_DAT2__FUNC_SPI_CK_1_ (MTK_PIN_NO(102) | 6) +#define MT8173_PIN_102_MSDC2_DAT2__FUNC_DBG_MON_B_2_ (MTK_PIN_NO(102) | 7) + +#define MT8173_PIN_103_MSDC2_DAT3__FUNC_GPIO103 (MTK_PIN_NO(103) | 0) +#define MT8173_PIN_103_MSDC2_DAT3__FUNC_MSDC2_DAT3 (MTK_PIN_NO(103) | 1) +#define MT8173_PIN_103_MSDC2_DAT3__FUNC_URXD0 (MTK_PIN_NO(103) | 3) +#define MT8173_PIN_103_MSDC2_DAT3__FUNC_PWM1 (MTK_PIN_NO(103) | 5) +#define MT8173_PIN_103_MSDC2_DAT3__FUNC_SPI_MI_1_ (MTK_PIN_NO(103) | 6) +#define MT8173_PIN_103_MSDC2_DAT3__FUNC_DBG_MON_B_3_ (MTK_PIN_NO(103) | 7) + +#define MT8173_PIN_104_MSDC2_CLK__FUNC_GPIO104 (MTK_PIN_NO(104) | 0) +#define MT8173_PIN_104_MSDC2_CLK__FUNC_MSDC2_CLK (MTK_PIN_NO(104) | 1) +#define MT8173_PIN_104_MSDC2_CLK__FUNC_UTXD3 (MTK_PIN_NO(104) | 3) +#define MT8173_PIN_104_MSDC2_CLK__FUNC_SDA3 (MTK_PIN_NO(104) | 4) +#define MT8173_PIN_104_MSDC2_CLK__FUNC_PWM2 (MTK_PIN_NO(104) | 5) +#define MT8173_PIN_104_MSDC2_CLK__FUNC_SPI_MO_1_ (MTK_PIN_NO(104) | 6) +#define MT8173_PIN_104_MSDC2_CLK__FUNC_DBG_MON_B_4_ (MTK_PIN_NO(104) | 7) + +#define MT8173_PIN_105_MSDC2_CMD__FUNC_GPIO105 (MTK_PIN_NO(105) | 0) +#define MT8173_PIN_105_MSDC2_CMD__FUNC_MSDC2_CMD (MTK_PIN_NO(105) | 1) +#define MT8173_PIN_105_MSDC2_CMD__FUNC_URXD3 (MTK_PIN_NO(105) | 3) +#define MT8173_PIN_105_MSDC2_CMD__FUNC_SCL3 (MTK_PIN_NO(105) | 4) +#define MT8173_PIN_105_MSDC2_CMD__FUNC_PWM3 (MTK_PIN_NO(105) | 5) +#define MT8173_PIN_105_MSDC2_CMD__FUNC_SPI_CS_1_ (MTK_PIN_NO(105) | 6) +#define MT8173_PIN_105_MSDC2_CMD__FUNC_DBG_MON_B_5_ (MTK_PIN_NO(105) | 7) + +#define MT8173_PIN_106_SDA3__FUNC_GPIO106 (MTK_PIN_NO(106) | 0) +#define MT8173_PIN_106_SDA3__FUNC_SDA3 (MTK_PIN_NO(106) | 1) + +#define MT8173_PIN_107_SCL3__FUNC_GPIO107 (MTK_PIN_NO(107) | 0) +#define MT8173_PIN_107_SCL3__FUNC_SCL3 (MTK_PIN_NO(107) | 1) + +#define MT8173_PIN_108_JTMS__FUNC_GPIO108 (MTK_PIN_NO(108) | 0) +#define MT8173_PIN_108_JTMS__FUNC_JTMS (MTK_PIN_NO(108) | 1) +#define MT8173_PIN_108_JTMS__FUNC_MFG_JTAG_TMS (MTK_PIN_NO(108) | 2) +#define MT8173_PIN_108_JTMS__FUNC_AP_MD32_JTAG_TMS (MTK_PIN_NO(108) | 5) +#define MT8173_PIN_108_JTMS__FUNC_DFD_TMS (MTK_PIN_NO(108) | 6) + +#define MT8173_PIN_109_JTCK__FUNC_GPIO109 (MTK_PIN_NO(109) | 0) +#define MT8173_PIN_109_JTCK__FUNC_JTCK (MTK_PIN_NO(109) | 1) +#define MT8173_PIN_109_JTCK__FUNC_MFG_JTAG_TCK (MTK_PIN_NO(109) | 2) +#define MT8173_PIN_109_JTCK__FUNC_AP_MD32_JTAG_TCK (MTK_PIN_NO(109) | 5) +#define MT8173_PIN_109_JTCK__FUNC_DFD_TCK (MTK_PIN_NO(109) | 6) + +#define MT8173_PIN_110_JTDI__FUNC_GPIO110 (MTK_PIN_NO(110) | 0) +#define MT8173_PIN_110_JTDI__FUNC_JTDI (MTK_PIN_NO(110) | 1) +#define MT8173_PIN_110_JTDI__FUNC_MFG_JTAG_TDI (MTK_PIN_NO(110) | 2) +#define MT8173_PIN_110_JTDI__FUNC_AP_MD32_JTAG_TDI (MTK_PIN_NO(110) | 5) +#define MT8173_PIN_110_JTDI__FUNC_DFD_TDI (MTK_PIN_NO(110) | 6) + +#define MT8173_PIN_111_JTDO__FUNC_GPIO111 (MTK_PIN_NO(111) | 0) +#define MT8173_PIN_111_JTDO__FUNC_JTDO (MTK_PIN_NO(111) | 1) +#define MT8173_PIN_111_JTDO__FUNC_MFG_JTAG_TDO (MTK_PIN_NO(111) | 2) +#define MT8173_PIN_111_JTDO__FUNC_AP_MD32_JTAG_TDO (MTK_PIN_NO(111) | 5) +#define MT8173_PIN_111_JTDO__FUNC_DFD_TDO (MTK_PIN_NO(111) | 6) + +#define MT8173_PIN_112_JTRST_B__FUNC_GPIO112 (MTK_PIN_NO(112) | 0) +#define MT8173_PIN_112_JTRST_B__FUNC_JTRST_B (MTK_PIN_NO(112) | 1) +#define MT8173_PIN_112_JTRST_B__FUNC_MFG_JTAG_TRSTN (MTK_PIN_NO(112) | 2) +#define MT8173_PIN_112_JTRST_B__FUNC_AP_MD32_JTAG_TRST (MTK_PIN_NO(112) | 5) +#define MT8173_PIN_112_JTRST_B__FUNC_DFD_NTRST (MTK_PIN_NO(112) | 6) + +#define MT8173_PIN_113_URXD0__FUNC_GPIO113 (MTK_PIN_NO(113) | 0) +#define MT8173_PIN_113_URXD0__FUNC_URXD0 (MTK_PIN_NO(113) | 1) +#define MT8173_PIN_113_URXD0__FUNC_UTXD0 (MTK_PIN_NO(113) | 2) +#define MT8173_PIN_113_URXD0__FUNC_I2S2_WS (MTK_PIN_NO(113) | 6) +#define MT8173_PIN_113_URXD0__FUNC_DBG_MON_A_0_ (MTK_PIN_NO(113) | 7) + +#define MT8173_PIN_114_UTXD0__FUNC_GPIO114 (MTK_PIN_NO(114) | 0) +#define MT8173_PIN_114_UTXD0__FUNC_UTXD0 (MTK_PIN_NO(114) | 1) +#define MT8173_PIN_114_UTXD0__FUNC_URXD0 (MTK_PIN_NO(114) | 2) +#define MT8173_PIN_114_UTXD0__FUNC_I2S2_BCK (MTK_PIN_NO(114) | 6) +#define MT8173_PIN_114_UTXD0__FUNC_DBG_MON_A_1_ (MTK_PIN_NO(114) | 7) + +#define MT8173_PIN_115_URTS0__FUNC_GPIO115 (MTK_PIN_NO(115) | 0) +#define MT8173_PIN_115_URTS0__FUNC_URTS0 (MTK_PIN_NO(115) | 1) +#define MT8173_PIN_115_URTS0__FUNC_UCTS0 (MTK_PIN_NO(115) | 2) +#define MT8173_PIN_115_URTS0__FUNC_I2S2_MCK (MTK_PIN_NO(115) | 6) +#define MT8173_PIN_115_URTS0__FUNC_DBG_MON_A_2_ (MTK_PIN_NO(115) | 7) + +#define MT8173_PIN_116_UCTS0__FUNC_GPIO116 (MTK_PIN_NO(116) | 0) +#define MT8173_PIN_116_UCTS0__FUNC_UCTS0 (MTK_PIN_NO(116) | 1) +#define MT8173_PIN_116_UCTS0__FUNC_URTS0 (MTK_PIN_NO(116) | 2) +#define MT8173_PIN_116_UCTS0__FUNC_I2S2_DI_1 (MTK_PIN_NO(116) | 6) +#define MT8173_PIN_116_UCTS0__FUNC_DBG_MON_A_3_ (MTK_PIN_NO(116) | 7) + +#define MT8173_PIN_117_URXD3__FUNC_GPIO117 (MTK_PIN_NO(117) | 0) +#define MT8173_PIN_117_URXD3__FUNC_URXD3 (MTK_PIN_NO(117) | 1) +#define MT8173_PIN_117_URXD3__FUNC_UTXD3 (MTK_PIN_NO(117) | 2) +#define MT8173_PIN_117_URXD3__FUNC_DBG_MON_A_9_ (MTK_PIN_NO(117) | 7) + +#define MT8173_PIN_118_UTXD3__FUNC_GPIO118 (MTK_PIN_NO(118) | 0) +#define MT8173_PIN_118_UTXD3__FUNC_UTXD3 (MTK_PIN_NO(118) | 1) +#define MT8173_PIN_118_UTXD3__FUNC_URXD3 (MTK_PIN_NO(118) | 2) +#define MT8173_PIN_118_UTXD3__FUNC_DBG_MON_A_10_ (MTK_PIN_NO(118) | 7) + +#define MT8173_PIN_119_KPROW0__FUNC_GPIO119 (MTK_PIN_NO(119) | 0) +#define MT8173_PIN_119_KPROW0__FUNC_KROW0 (MTK_PIN_NO(119) | 1) +#define MT8173_PIN_119_KPROW0__FUNC_DBG_MON_A_11_ (MTK_PIN_NO(119) | 7) + +#define MT8173_PIN_120_KPROW1__FUNC_GPIO120 (MTK_PIN_NO(120) | 0) +#define MT8173_PIN_120_KPROW1__FUNC_KROW1 (MTK_PIN_NO(120) | 1) +#define MT8173_PIN_120_KPROW1__FUNC_PWM6 (MTK_PIN_NO(120) | 3) +#define MT8173_PIN_120_KPROW1__FUNC_DBG_MON_A_12_ (MTK_PIN_NO(120) | 7) + +#define MT8173_PIN_121_KPROW2__FUNC_GPIO121 (MTK_PIN_NO(121) | 0) +#define MT8173_PIN_121_KPROW2__FUNC_KROW2 (MTK_PIN_NO(121) | 1) +#define MT8173_PIN_121_KPROW2__FUNC_IRDA_PDN (MTK_PIN_NO(121) | 2) +#define MT8173_PIN_121_KPROW2__FUNC_USB_DRVVBUS_P0 (MTK_PIN_NO(121) | 3) +#define MT8173_PIN_121_KPROW2__FUNC_PWM4 (MTK_PIN_NO(121) | 4) +#define MT8173_PIN_121_KPROW2__FUNC_USB_DRVVBUS_P1 (MTK_PIN_NO(121) | 5) +#define MT8173_PIN_121_KPROW2__FUNC_DBG_MON_A_13_ (MTK_PIN_NO(121) | 7) + +#define MT8173_PIN_122_KPCOL0__FUNC_GPIO122 (MTK_PIN_NO(122) | 0) +#define MT8173_PIN_122_KPCOL0__FUNC_KCOL0 (MTK_PIN_NO(122) | 1) +#define MT8173_PIN_122_KPCOL0__FUNC_DBG_MON_A_14_ (MTK_PIN_NO(122) | 7) + +#define MT8173_PIN_123_KPCOL1__FUNC_GPIO123 (MTK_PIN_NO(123) | 0) +#define MT8173_PIN_123_KPCOL1__FUNC_KCOL1 (MTK_PIN_NO(123) | 1) +#define MT8173_PIN_123_KPCOL1__FUNC_IRDA_RXD (MTK_PIN_NO(123) | 2) +#define MT8173_PIN_123_KPCOL1__FUNC_PWM5 (MTK_PIN_NO(123) | 3) +#define MT8173_PIN_123_KPCOL1__FUNC_DBG_MON_A_15_ (MTK_PIN_NO(123) | 7) + +#define MT8173_PIN_124_KPCOL2__FUNC_GPIO124 (MTK_PIN_NO(124) | 0) +#define MT8173_PIN_124_KPCOL2__FUNC_KCOL2 (MTK_PIN_NO(124) | 1) +#define MT8173_PIN_124_KPCOL2__FUNC_IRDA_TXD (MTK_PIN_NO(124) | 2) +#define MT8173_PIN_124_KPCOL2__FUNC_USB_DRVVBUS_P0 (MTK_PIN_NO(124) | 3) +#define MT8173_PIN_124_KPCOL2__FUNC_PWM3 (MTK_PIN_NO(124) | 4) +#define MT8173_PIN_124_KPCOL2__FUNC_USB_DRVVBUS_P1 (MTK_PIN_NO(124) | 5) +#define MT8173_PIN_124_KPCOL2__FUNC_DBG_MON_A_16_ (MTK_PIN_NO(124) | 7) + +#define MT8173_PIN_125_SDA1__FUNC_GPIO125 (MTK_PIN_NO(125) | 0) +#define MT8173_PIN_125_SDA1__FUNC_SDA1 (MTK_PIN_NO(125) | 1) + +#define MT8173_PIN_126_SCL1__FUNC_GPIO126 (MTK_PIN_NO(126) | 0) +#define MT8173_PIN_126_SCL1__FUNC_SCL1 (MTK_PIN_NO(126) | 1) + +#define MT8173_PIN_127_LCM_RST__FUNC_GPIO127 (MTK_PIN_NO(127) | 0) +#define MT8173_PIN_127_LCM_RST__FUNC_LCM_RST (MTK_PIN_NO(127) | 1) + +#define MT8173_PIN_128_I2S0_LRCK__FUNC_GPIO128 (MTK_PIN_NO(128) | 0) +#define MT8173_PIN_128_I2S0_LRCK__FUNC_I2S0_WS (MTK_PIN_NO(128) | 1) +#define MT8173_PIN_128_I2S0_LRCK__FUNC_I2S1_WS (MTK_PIN_NO(128) | 2) +#define MT8173_PIN_128_I2S0_LRCK__FUNC_I2S2_WS (MTK_PIN_NO(128) | 3) +#define MT8173_PIN_128_I2S0_LRCK__FUNC_SPI_CK_2_ (MTK_PIN_NO(128) | 5) +#define MT8173_PIN_128_I2S0_LRCK__FUNC_DBG_MON_A_4_ (MTK_PIN_NO(128) | 7) + +#define MT8173_PIN_129_I2S0_BCK__FUNC_GPIO129 (MTK_PIN_NO(129) | 0) +#define MT8173_PIN_129_I2S0_BCK__FUNC_I2S0_BCK (MTK_PIN_NO(129) | 1) +#define MT8173_PIN_129_I2S0_BCK__FUNC_I2S1_BCK (MTK_PIN_NO(129) | 2) +#define MT8173_PIN_129_I2S0_BCK__FUNC_I2S2_BCK (MTK_PIN_NO(129) | 3) +#define MT8173_PIN_129_I2S0_BCK__FUNC_SPI_MI_2_ (MTK_PIN_NO(129) | 5) +#define MT8173_PIN_129_I2S0_BCK__FUNC_DBG_MON_A_5_ (MTK_PIN_NO(129) | 7) + +#define MT8173_PIN_130_I2S0_MCK__FUNC_GPIO130 (MTK_PIN_NO(130) | 0) +#define MT8173_PIN_130_I2S0_MCK__FUNC_I2S0_MCK (MTK_PIN_NO(130) | 1) +#define MT8173_PIN_130_I2S0_MCK__FUNC_I2S1_MCK (MTK_PIN_NO(130) | 2) +#define MT8173_PIN_130_I2S0_MCK__FUNC_I2S2_MCK (MTK_PIN_NO(130) | 3) +#define MT8173_PIN_130_I2S0_MCK__FUNC_SPI_MO_2_ (MTK_PIN_NO(130) | 5) +#define MT8173_PIN_130_I2S0_MCK__FUNC_DBG_MON_A_6_ (MTK_PIN_NO(130) | 7) + +#define MT8173_PIN_131_I2S0_DATA0__FUNC_GPIO131 (MTK_PIN_NO(131) | 0) +#define MT8173_PIN_131_I2S0_DATA0__FUNC_I2S0_DO (MTK_PIN_NO(131) | 1) +#define MT8173_PIN_131_I2S0_DATA0__FUNC_I2S1_DO_1 (MTK_PIN_NO(131) | 2) +#define MT8173_PIN_131_I2S0_DATA0__FUNC_I2S2_DI_1 (MTK_PIN_NO(131) | 3) +#define MT8173_PIN_131_I2S0_DATA0__FUNC_SPI_CS_2_ (MTK_PIN_NO(131) | 5) +#define MT8173_PIN_131_I2S0_DATA0__FUNC_DBG_MON_A_7_ (MTK_PIN_NO(131) | 7) + +#define MT8173_PIN_132_I2S0_DATA1__FUNC_GPIO132 (MTK_PIN_NO(132) | 0) +#define MT8173_PIN_132_I2S0_DATA1__FUNC_I2S0_DI (MTK_PIN_NO(132) | 1) +#define MT8173_PIN_132_I2S0_DATA1__FUNC_I2S1_DO_2 (MTK_PIN_NO(132) | 2) +#define MT8173_PIN_132_I2S0_DATA1__FUNC_I2S2_DI_2 (MTK_PIN_NO(132) | 3) +#define MT8173_PIN_132_I2S0_DATA1__FUNC_DBG_MON_A_8_ (MTK_PIN_NO(132) | 7) + +#define MT8173_PIN_133_SDA4__FUNC_GPIO133 (MTK_PIN_NO(133) | 0) +#define MT8173_PIN_133_SDA4__FUNC_SDA4 (MTK_PIN_NO(133) | 1) + +#define MT8173_PIN_134_SCL4__FUNC_GPIO134 (MTK_PIN_NO(134) | 0) +#define MT8173_PIN_134_SCL4__FUNC_SCL4 (MTK_PIN_NO(134) | 1) + +#endif /* __DTS_MT8173_PINFUNC_H */ diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi index 8554ec31dd9e..924fdb6673ff 100644 --- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi @@ -13,6 +13,7 @@ #include #include +#include "mt8173-pinfunc.h" / { compatible = "mediatek,mt8173"; @@ -105,6 +106,25 @@ compatible = "simple-bus"; ranges; + syscfg_pctl_a: syscfg_pctl_a@10005000 { + compatible = "mediatek,mt8173-pctl-a-syscfg", "syscon"; + reg = <0 0x10005000 0 0x1000>; + }; + + pio: pinctrl@0x10005000 { + compatible = "mediatek,mt8173-pinctrl"; + reg = <0 0x1000B000 0 0x1000>; + mediatek,pctl-regmap = <&syscfg_pctl_a>; + pins-are-numbered; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = , + , + ; + }; + sysirq: intpol-controller@10200620 { compatible = "mediatek,mt8173-sysirq", "mediatek,mt6577-sysirq"; -- GitLab From 1b4bd608763e063ea87e20030e05db005e70177f Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 9 Mar 2015 18:54:32 +0100 Subject: [PATCH 03685/11651] ARM: 8309/1: l2c: enforce use of cache-level property Make sure that we can read the "cache-level" property from the L2 cache controller node, and ensure its value is 2. Signed-off-by: Florian Fainelli Signed-off-by: Russell King --- arch/arm/mm/cache-l2x0.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c index c6c7696b8db9..8b933dc43e24 100644 --- a/arch/arm/mm/cache-l2x0.c +++ b/arch/arm/mm/cache-l2x0.c @@ -1648,6 +1648,7 @@ int __init l2x0_of_init(u32 aux_val, u32 aux_mask) struct device_node *np; struct resource res; u32 cache_id, old_aux; + u32 cache_level = 2; np = of_find_matching_node(NULL, l2x0_ids); if (!np) @@ -1680,6 +1681,12 @@ int __init l2x0_of_init(u32 aux_val, u32 aux_mask) if (!of_property_read_bool(np, "cache-unified")) pr_err("L2C: device tree omits to specify unified cache\n"); + if (of_property_read_u32(np, "cache-level", &cache_level)) + pr_err("L2C: device tree omits to specify cache-level\n"); + + if (cache_level != 2) + pr_err("L2C: device tree specifies invalid cache level\n"); + /* Read back current (default) hardware configuration */ if (data->save) data->save(l2x0_base); -- GitLab From 7e476c7dd8d39b03a4dd8447be907d3517579c51 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 10 Mar 2015 13:44:41 +1100 Subject: [PATCH 03686/11651] regulator: fixes for regulator_set_optimum_mode name change Signed-off-by: Stephen Rothwell Signed-off-by: Mark Brown --- drivers/gpu/drm/msm/edp/edp_ctrl.c | 6 +++--- drivers/phy/phy-qcom-ufs.c | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/msm/edp/edp_ctrl.c b/drivers/gpu/drm/msm/edp/edp_ctrl.c index 3e246210c46f..0ec5abdba5c4 100644 --- a/drivers/gpu/drm/msm/edp/edp_ctrl.c +++ b/drivers/gpu/drm/msm/edp/edp_ctrl.c @@ -332,7 +332,7 @@ static int edp_regulator_enable(struct edp_ctrl *ctrl) goto vdda_set_fail; } - ret = regulator_set_optimum_mode(ctrl->vdda_vreg, VDDA_UA_ON_LOAD); + ret = regulator_set_load(ctrl->vdda_vreg, VDDA_UA_ON_LOAD); if (ret < 0) { pr_err("%s: vdda_vreg set regulator mode failed.\n", __func__); goto vdda_set_fail; @@ -356,7 +356,7 @@ static int edp_regulator_enable(struct edp_ctrl *ctrl) lvl_enable_fail: regulator_disable(ctrl->vdda_vreg); vdda_enable_fail: - regulator_set_optimum_mode(ctrl->vdda_vreg, VDDA_UA_OFF_LOAD); + regulator_set_load(ctrl->vdda_vreg, VDDA_UA_OFF_LOAD); vdda_set_fail: return ret; } @@ -365,7 +365,7 @@ static void edp_regulator_disable(struct edp_ctrl *ctrl) { regulator_disable(ctrl->lvl_vreg); regulator_disable(ctrl->vdda_vreg); - regulator_set_optimum_mode(ctrl->vdda_vreg, VDDA_UA_OFF_LOAD); + regulator_set_load(ctrl->vdda_vreg, VDDA_UA_OFF_LOAD); } static int edp_gpio_config(struct edp_ctrl *ctrl) diff --git a/drivers/phy/phy-qcom-ufs.c b/drivers/phy/phy-qcom-ufs.c index 44ee983d57fe..86665e9dc399 100644 --- a/drivers/phy/phy-qcom-ufs.c +++ b/drivers/phy/phy-qcom-ufs.c @@ -346,10 +346,10 @@ int ufs_qcom_phy_cfg_vreg(struct phy *phy, goto out; } uA_load = on ? vreg->max_uA : 0; - ret = regulator_set_optimum_mode(reg, uA_load); + ret = regulator_set_load(reg, uA_load); if (ret >= 0) { /* - * regulator_set_optimum_mode() returns new regulator + * regulator_set_load() returns new regulator * mode upon success. */ ret = 0; -- GitLab From ce991981311e0ae258982b600564226ad6cb24ea Mon Sep 17 00:00:00 2001 From: Yannick Guerrini Date: Mon, 9 Mar 2015 22:13:03 +0100 Subject: [PATCH 03687/11651] ALSA: firewire: Fix trivial typos in comments Change 'propper' to 'proper' Change 'paramters' to 'parameters' Change 'SYT_INTEVAL' to 'SYT_INTERVAL' Change 'aligh'/'alighed' to 'align'/'aligned' Signed-off-by: Yannick Guerrini Signed-off-by: Takashi Iwai --- sound/firewire/amdtp.c | 8 ++++---- sound/firewire/fireworks/fireworks_transaction.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/sound/firewire/amdtp.c b/sound/firewire/amdtp.c index 5cc356db5351..e061355f535f 100644 --- a/sound/firewire/amdtp.c +++ b/sound/firewire/amdtp.c @@ -166,10 +166,10 @@ int amdtp_stream_add_pcm_hw_constraints(struct amdtp_stream *s, * One AMDTP packet can include some frames. In blocking mode, the * number equals to SYT_INTERVAL. So the number is 8, 16 or 32, * depending on its sampling rate. For accurate period interrupt, it's - * preferrable to aligh period/buffer sizes to current SYT_INTERVAL. + * preferrable to align period/buffer sizes to current SYT_INTERVAL. * - * TODO: These constraints can be improved with propper rules. - * Currently apply LCM of SYT_INTEVALs. + * TODO: These constraints can be improved with proper rules. + * Currently apply LCM of SYT_INTERVALs. */ err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 32); @@ -270,7 +270,7 @@ static void amdtp_read_s32(struct amdtp_stream *s, * @s: the AMDTP stream to configure * @format: the format of the ALSA PCM device * - * The sample format must be set after the other paramters (rate/PCM channels/ + * The sample format must be set after the other parameters (rate/PCM channels/ * MIDI) and before the stream is started, and must not be changed while the * stream is running. */ diff --git a/sound/firewire/fireworks/fireworks_transaction.c b/sound/firewire/fireworks/fireworks_transaction.c index 2a85e4209f0b..f550808d1784 100644 --- a/sound/firewire/fireworks/fireworks_transaction.c +++ b/sound/firewire/fireworks/fireworks_transaction.c @@ -13,7 +13,7 @@ * * Transaction substance: * At first, 6 data exist. Following to the data, parameters for each command - * exist. All of the parameters are 32 bit alighed to big endian. + * exist. All of the parameters are 32 bit aligned to big endian. * data[0]: Length of transaction substance * data[1]: Transaction version * data[2]: Sequence number. This is incremented by the device -- GitLab From 739ae3452d0ee199b3cfe5e52214d9ccd8e358ea Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 10 Mar 2015 17:05:33 +0800 Subject: [PATCH 03688/11651] phy: berlin-usb: Set drvdata for phy and use it At the context where we have pointer to struct phy, it's useful to call phy_get_drvdata() to get the address of priv. With this change, we can remove the to_phy_berlin_usb_priv() macro and remove *phy from struct phy_berlin_usb_priv. Signed-off-by: Axel Lin Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/phy-berlin-usb.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/phy/phy-berlin-usb.c b/drivers/phy/phy-berlin-usb.c index 9f7cc7eed292..c6fc95b53083 100644 --- a/drivers/phy/phy-berlin-usb.c +++ b/drivers/phy/phy-berlin-usb.c @@ -103,9 +103,6 @@ #define MODE_TEST_EN BIT(11) #define ANA_TEST_DC_CTRL(x) ((x) << 12) -#define to_phy_berlin_usb_priv(p) \ - container_of((p), struct phy_berlin_usb_priv, phy) - static const u32 phy_berlin_pll_dividers[] = { /* Berlin 2 */ CLK_REF_DIV(0xc) | FEEDBACK_CLK_DIV(0x54), @@ -115,14 +112,13 @@ static const u32 phy_berlin_pll_dividers[] = { struct phy_berlin_usb_priv { void __iomem *base; - struct phy *phy; struct reset_control *rst_ctrl; u32 pll_divider; }; static int phy_berlin_usb_power_on(struct phy *phy) { - struct phy_berlin_usb_priv *priv = dev_get_drvdata(phy->dev.parent); + struct phy_berlin_usb_priv *priv = phy_get_drvdata(phy); reset_control_reset(priv->rst_ctrl); @@ -175,6 +171,7 @@ static int phy_berlin_usb_probe(struct platform_device *pdev) of_match_device(phy_berlin_sata_of_match, &pdev->dev); struct phy_berlin_usb_priv *priv; struct resource *res; + struct phy *phy; struct phy_provider *phy_provider; priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); @@ -192,13 +189,14 @@ static int phy_berlin_usb_probe(struct platform_device *pdev) priv->pll_divider = *((u32 *)match->data); - priv->phy = devm_phy_create(&pdev->dev, NULL, &phy_berlin_usb_ops); - if (IS_ERR(priv->phy)) { + phy = devm_phy_create(&pdev->dev, NULL, &phy_berlin_usb_ops); + if (IS_ERR(phy)) { dev_err(&pdev->dev, "failed to create PHY\n"); - return PTR_ERR(priv->phy); + return PTR_ERR(phy); } platform_set_drvdata(pdev, priv); + phy_set_drvdata(phy, priv); phy_provider = devm_of_phy_provider_register(&pdev->dev, of_phy_simple_xlate); -- GitLab From 17713ce09d95fa79a1bf8f8604ecea9c6e1924aa Mon Sep 17 00:00:00 2001 From: Nicholas Mc Guire Date: Fri, 20 Feb 2015 09:34:01 -0500 Subject: [PATCH 03689/11651] video: fbdev: use msecs_to_jiffies for time conversions This is only an API consolidation and should make things more readable by replacing var * HZ / 1000 by msecs_to_jiffies(var). Signed-off-by: Nicholas Mc Guire Signed-off-by: Tomi Valkeinen --- drivers/video/fbdev/pxafb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/video/fbdev/pxafb.c b/drivers/video/fbdev/pxafb.c index da2431eda2fd..7245611ec963 100644 --- a/drivers/video/fbdev/pxafb.c +++ b/drivers/video/fbdev/pxafb.c @@ -1285,7 +1285,7 @@ static int pxafb_smart_thread(void *arg) mutex_unlock(&fbi->ctrlr_lock); set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(30 * HZ / 1000); + schedule_timeout(msecs_to_jiffies(30)); } pr_debug("%s(): task ending\n", __func__); @@ -1460,7 +1460,7 @@ static void pxafb_disable_controller(struct pxafb_info *fbi) #ifdef CONFIG_FB_PXA_SMARTPANEL if (fbi->lccr0 & LCCR0_LCDT) { wait_for_completion_timeout(&fbi->refresh_done, - 200 * HZ / 1000); + msecs_to_jiffies(200)); return; } #endif @@ -1472,7 +1472,7 @@ static void pxafb_disable_controller(struct pxafb_info *fbi) lcd_writel(fbi, LCCR0, lccr0); lcd_writel(fbi, LCCR0, lccr0 | LCCR0_DIS); - wait_for_completion_timeout(&fbi->disable_done, 200 * HZ / 1000); + wait_for_completion_timeout(&fbi->disable_done, msecs_to_jiffies(200)); /* disable LCD controller clock */ clk_disable_unprepare(fbi->clk); -- GitLab From 7dea97e0379dbb2983a9f009c7cdaeb6bbe4c98e Mon Sep 17 00:00:00 2001 From: Nicholas Mc Guire Date: Thu, 29 Jan 2015 11:24:16 +0100 Subject: [PATCH 03690/11651] hyperv: hyperv_fb: match wait_for_completion_timeout return type The return type of wait_for_completion_timeout is unsigned long not int. This patch fixes up the declarations only. Signed-off-by: Nicholas Mc Guire Reviewed-by: Vitaly Kuznetsov Signed-off-by: Tomi Valkeinen --- drivers/video/fbdev/hyperv_fb.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c index 42543362f163..807ee22ef229 100644 --- a/drivers/video/fbdev/hyperv_fb.c +++ b/drivers/video/fbdev/hyperv_fb.c @@ -415,7 +415,8 @@ static int synthvid_negotiate_ver(struct hv_device *hdev, u32 ver) struct fb_info *info = hv_get_drvdata(hdev); struct hvfb_par *par = info->par; struct synthvid_msg *msg = (struct synthvid_msg *)par->init_buf; - int t, ret = 0; + int ret = 0; + unsigned long t; memset(msg, 0, sizeof(struct synthvid_msg)); msg->vid_hdr.type = SYNTHVID_VERSION_REQUEST; @@ -488,7 +489,8 @@ static int synthvid_send_config(struct hv_device *hdev) struct fb_info *info = hv_get_drvdata(hdev); struct hvfb_par *par = info->par; struct synthvid_msg *msg = (struct synthvid_msg *)par->init_buf; - int t, ret = 0; + int ret = 0; + unsigned long t; /* Send VRAM location */ memset(msg, 0, sizeof(struct synthvid_msg)); -- GitLab From b3924dd7a943613939f8b019690d1f919ece035c Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 25 Feb 2015 16:25:20 +0300 Subject: [PATCH 03691/11651] fbdev: pm3fb: cleanup some confusing indenting This if statement should be pushed out one tab to line up with the rest. Signed-off-by: Dan Carpenter Signed-off-by: Tomi Valkeinen --- drivers/video/fbdev/pm3fb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/video/fbdev/pm3fb.c b/drivers/video/fbdev/pm3fb.c index 4bf3273d0433..77b99ed39ad0 100644 --- a/drivers/video/fbdev/pm3fb.c +++ b/drivers/video/fbdev/pm3fb.c @@ -1479,9 +1479,9 @@ static void pm3fb_remove(struct pci_dev *dev) fb_dealloc_cmap(&info->cmap); #ifdef CONFIG_MTRR - if (par->mtrr_handle >= 0) - mtrr_del(par->mtrr_handle, info->fix.smem_start, - info->fix.smem_len); + if (par->mtrr_handle >= 0) + mtrr_del(par->mtrr_handle, info->fix.smem_start, + info->fix.smem_len); #endif /* CONFIG_MTRR */ iounmap(info->screen_base); release_mem_region(fix->smem_start, fix->smem_len); -- GitLab From 29722cd4ef666705b2eda1c3ba44435488e509eb Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 9 Mar 2015 19:39:21 +0100 Subject: [PATCH 03692/11651] x86/asm/entry/64: Save R11 into pt_regs->flags on SYSCALL64 fastpath Before this patch, R11 was saved in pt_regs->r11. Which looks natural, but requires messy shuffling to/from iret frame whenever ptrace or e.g. sys_iopl() wants to modify flags - because that's how this register is used by SYSCALL/SYSRET. This patch saves R11 in pt_regs->flags, and uses that value for the SYSRET64 instruction. Shuffling is eliminated. FIXUP/RESTORE_TOP_OF_STACK are simplified. stub_iopl is no longer needed: pt_regs->flags needs no fixing up. Testing shows that syscall fast path is ~54.3 ns before and after the patch (on 2.7 GHz Sandy Bridge CPU). Signed-off-by: Denys Vlasenko Cc: Alexei Starovoitov Cc: Andy Lutomirski Cc: Borislav Petkov Cc: Frederic Weisbecker Cc: H. Peter Anvin Cc: Kees Cook Cc: Linus Torvalds Cc: Oleg Nesterov Cc: Steven Rostedt Cc: Will Drewry Link: http://lkml.kernel.org/r/1425926364-9526-2-git-send-email-dvlasenk@redhat.com Signed-off-by: Ingo Molnar --- arch/x86/include/asm/calling.h | 20 ++++++++++++++------ arch/x86/kernel/entry_64.S | 24 +++++++++++------------- 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/arch/x86/include/asm/calling.h b/arch/x86/include/asm/calling.h index f1a962ff7ddf..4b5f7bf2b780 100644 --- a/arch/x86/include/asm/calling.h +++ b/arch/x86/include/asm/calling.h @@ -95,9 +95,11 @@ For 32-bit we have the following conventions - kernel is built with CFI_ADJUST_CFA_OFFSET 15*8+\addskip .endm - .macro SAVE_C_REGS_HELPER offset=0 rax=1 rcx=1 r8plus=1 - .if \r8plus + .macro SAVE_C_REGS_HELPER offset=0 rax=1 rcx=1 r8910=1 r11=1 + .if \r11 movq_cfi r11, 6*8+\offset + .endif + .if \r8910 movq_cfi r10, 7*8+\offset movq_cfi r9, 8*8+\offset movq_cfi r8, 9*8+\offset @@ -113,16 +115,19 @@ For 32-bit we have the following conventions - kernel is built with movq_cfi rdi, 14*8+\offset .endm .macro SAVE_C_REGS offset=0 - SAVE_C_REGS_HELPER \offset, 1, 1, 1 + SAVE_C_REGS_HELPER \offset, 1, 1, 1, 1 .endm .macro SAVE_C_REGS_EXCEPT_RAX_RCX offset=0 - SAVE_C_REGS_HELPER \offset, 0, 0, 1 + SAVE_C_REGS_HELPER \offset, 0, 0, 1, 1 .endm .macro SAVE_C_REGS_EXCEPT_R891011 - SAVE_C_REGS_HELPER 0, 1, 1, 0 + SAVE_C_REGS_HELPER 0, 1, 1, 0, 0 .endm .macro SAVE_C_REGS_EXCEPT_RCX_R891011 - SAVE_C_REGS_HELPER 0, 1, 0, 0 + SAVE_C_REGS_HELPER 0, 1, 0, 0, 0 + .endm + .macro SAVE_C_REGS_EXCEPT_RAX_RCX_R11 + SAVE_C_REGS_HELPER 0, 0, 0, 1, 0 .endm .macro SAVE_EXTRA_REGS offset=0 @@ -179,6 +184,9 @@ For 32-bit we have the following conventions - kernel is built with .macro RESTORE_C_REGS_EXCEPT_R11 RESTORE_C_REGS_HELPER 1,1,0,1,1 .endm + .macro RESTORE_C_REGS_EXCEPT_RCX_R11 + RESTORE_C_REGS_HELPER 1,0,0,1,1 + .endm .macro RESTORE_RSI_RDI RESTORE_C_REGS_HELPER 0,0,0,0,0 .endm diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index 5117a2baefe9..324200aca431 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -121,14 +121,12 @@ ENDPROC(native_usergs_sysret64) #endif /* - * C code is not supposed to know about undefined top of stack. Every time - * a C function with an pt_regs argument is called from the SYSCALL based - * fast path FIXUP_TOP_OF_STACK is needed. + * C code is not supposed to know that the iret frame is not populated. + * Every time a C function with an pt_regs argument is called from + * the SYSCALL based fast path FIXUP_TOP_OF_STACK is needed. * RESTORE_TOP_OF_STACK syncs the syscall state after any possible ptregs * manipulation. */ - - /* %rsp:at FRAMEEND */ .macro FIXUP_TOP_OF_STACK tmp offset=0 movq PER_CPU_VAR(old_rsp),\tmp movq \tmp,RSP+\offset(%rsp) @@ -136,15 +134,13 @@ ENDPROC(native_usergs_sysret64) movq $__USER_CS,CS+\offset(%rsp) movq RIP+\offset(%rsp),\tmp /* get rip */ movq \tmp,RCX+\offset(%rsp) /* copy it to rcx as sysret would do */ - movq R11+\offset(%rsp),\tmp /* get eflags */ - movq \tmp,EFLAGS+\offset(%rsp) + movq EFLAGS+\offset(%rsp),\tmp /* ditto for rflags->r11 */ + movq \tmp,R11+\offset(%rsp) .endm .macro RESTORE_TOP_OF_STACK tmp offset=0 movq RSP+\offset(%rsp),\tmp movq \tmp,PER_CPU_VAR(old_rsp) - movq EFLAGS+\offset(%rsp),\tmp - movq \tmp,R11+\offset(%rsp) .endm /* @@ -257,9 +253,10 @@ GLOBAL(system_call_after_swapgs) */ ENABLE_INTERRUPTS(CLBR_NONE) ALLOC_PT_GPREGS_ON_STACK 8 /* +8: space for orig_ax */ - SAVE_C_REGS_EXCEPT_RAX_RCX + SAVE_C_REGS_EXCEPT_RAX_RCX_R11 movq $-ENOSYS,RAX(%rsp) movq_cfi rax,ORIG_RAX + movq %r11,EFLAGS(%rsp) movq %rcx,RIP(%rsp) CFI_REL_OFFSET rip,RIP testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags+THREAD_INFO(%rsp,RIP) @@ -277,7 +274,7 @@ system_call_fastpath: movq %rax,RAX(%rsp) /* * Syscall return path ending with SYSRET (fast path) - * Has incomplete stack frame and undefined top of stack. + * Has incompletely filled pt_regs, iret frame is also incomplete. */ ret_from_sys_call: testl $_TIF_ALLWORK_MASK,TI_flags+THREAD_INFO(%rsp,RIP) @@ -291,9 +288,10 @@ ret_from_sys_call: * sysretq will re-enable interrupts: */ TRACE_IRQS_ON - RESTORE_C_REGS_EXCEPT_RCX - movq RIP(%rsp),%rcx + RESTORE_C_REGS_EXCEPT_RCX_R11 + movq RIP(%rsp),%rcx CFI_REGISTER rip,rcx + movq EFLAGS(%rsp),%r11 /*CFI_REGISTER rflags,r11*/ movq PER_CPU_VAR(old_rsp), %rsp /* -- GitLab From 616ab249f1e42f6135642183529f910fcedc2642 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 10 Mar 2015 11:45:06 +0100 Subject: [PATCH 03693/11651] x86/asm/entry/64: Remove stub_iopl stub_iopl is no longer needed: pt_regs->flags needs no fixing up after previous change. Remove it. Signed-off-by: Denys Vlasenko Cc: Alexei Starovoitov Cc: Borislav Petkov Cc: Frederic Weisbecker Cc: H. Peter Anvin Cc: Kees Cook Cc: Linus Torvalds Cc: Oleg Nesterov Cc: Steven Rostedt Cc: Will Drewry Link: http://lkml.kernel.org/r/1425984307-2143-1-git-send-email-dvlasenk@redhat.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/entry_64.S | 13 ------------- arch/x86/syscalls/syscall_64.tbl | 2 +- arch/x86/um/sys_call_table_64.c | 2 +- 3 files changed, 2 insertions(+), 15 deletions(-) diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index 324200aca431..703ced057199 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -421,22 +421,9 @@ ENTRY(stub_\func) END(stub_\func) .endm - .macro FIXED_FRAME label,func -ENTRY(\label) - CFI_STARTPROC - DEFAULT_FRAME 0, 8 /* offset 8: return address */ - FIXUP_TOP_OF_STACK %r11, 8 - call \func - RESTORE_TOP_OF_STACK %r11, 8 - ret - CFI_ENDPROC -END(\label) - .endm - FORK_LIKE clone FORK_LIKE fork FORK_LIKE vfork - FIXED_FRAME stub_iopl, sys_iopl ENTRY(stub_execve) CFI_STARTPROC diff --git a/arch/x86/syscalls/syscall_64.tbl b/arch/x86/syscalls/syscall_64.tbl index 8d656fbb57aa..9ef32d5f1b19 100644 --- a/arch/x86/syscalls/syscall_64.tbl +++ b/arch/x86/syscalls/syscall_64.tbl @@ -178,7 +178,7 @@ 169 common reboot sys_reboot 170 common sethostname sys_sethostname 171 common setdomainname sys_setdomainname -172 common iopl stub_iopl +172 common iopl sys_iopl 173 common ioperm sys_ioperm 174 64 create_module 175 common init_module sys_init_module diff --git a/arch/x86/um/sys_call_table_64.c b/arch/x86/um/sys_call_table_64.c index 5cdfa9db2217..a75d8700472a 100644 --- a/arch/x86/um/sys_call_table_64.c +++ b/arch/x86/um/sys_call_table_64.c @@ -16,7 +16,7 @@ */ /* Not going to be implemented by UML, since we have no hardware. */ -#define stub_iopl sys_ni_syscall +#define sys_iopl sys_ni_syscall #define sys_ioperm sys_ni_syscall /* -- GitLab From 263042e4630a85e856b4a8cd72f28dab33ef4741 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 9 Mar 2015 19:39:23 +0100 Subject: [PATCH 03694/11651] x86/asm/entry/64: Save user RSP in pt_regs->sp on SYSCALL64 fastpath Prepare for the removal of 'usersp', by simplifying PER_CPU(old_rsp) usage: - use it only as temp storage - store the userspace stack pointer immediately in pt_regs->sp on syscall entry, instead of using it later, on syscall exit. - change C code to use pt_regs->sp only, instead of PER_CPU(old_rsp) and task->thread.usersp. FIXUP/RESTORE_TOP_OF_STACK are simplified as well. Signed-off-by: Denys Vlasenko Cc: Alexei Starovoitov Cc: Andy Lutomirski Cc: Borislav Petkov Cc: Frederic Weisbecker Cc: H. Peter Anvin Cc: Kees Cook Cc: Linus Torvalds Cc: Oleg Nesterov Cc: Steven Rostedt Cc: Will Drewry Link: http://lkml.kernel.org/r/1425926364-9526-4-git-send-email-dvlasenk@redhat.com Signed-off-by: Ingo Molnar --- arch/x86/include/asm/compat.h | 2 +- arch/x86/include/asm/ptrace.h | 8 ++------ arch/x86/kernel/entry_64.S | 18 +++++++----------- arch/x86/kernel/perf_regs.c | 2 +- arch/x86/kernel/process_64.c | 3 +-- 5 files changed, 12 insertions(+), 21 deletions(-) diff --git a/arch/x86/include/asm/compat.h b/arch/x86/include/asm/compat.h index 59c6c401f79f..acdee09228b3 100644 --- a/arch/x86/include/asm/compat.h +++ b/arch/x86/include/asm/compat.h @@ -301,7 +301,7 @@ static inline void __user *arch_compat_alloc_user_space(long len) sp = task_pt_regs(current)->sp; } else { /* -128 for the x32 ABI redzone */ - sp = this_cpu_read(old_rsp) - 128; + sp = task_pt_regs(current)->sp - 128; } return (void __user *)round_down(sp - len, 16); diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h index 4077d963a1a0..74bb2e0f3030 100644 --- a/arch/x86/include/asm/ptrace.h +++ b/arch/x86/include/asm/ptrace.h @@ -145,12 +145,8 @@ static inline bool user_64bit_mode(struct pt_regs *regs) #endif } -#define current_user_stack_pointer() this_cpu_read(old_rsp) -/* ia32 vs. x32 difference */ -#define compat_user_stack_pointer() \ - (test_thread_flag(TIF_IA32) \ - ? current_pt_regs()->sp \ - : this_cpu_read(old_rsp)) +#define current_user_stack_pointer() current_pt_regs()->sp +#define compat_user_stack_pointer() current_pt_regs()->sp #endif #ifdef CONFIG_X86_32 diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index 703ced057199..d86788c3257b 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -128,8 +128,6 @@ ENDPROC(native_usergs_sysret64) * manipulation. */ .macro FIXUP_TOP_OF_STACK tmp offset=0 - movq PER_CPU_VAR(old_rsp),\tmp - movq \tmp,RSP+\offset(%rsp) movq $__USER_DS,SS+\offset(%rsp) movq $__USER_CS,CS+\offset(%rsp) movq RIP+\offset(%rsp),\tmp /* get rip */ @@ -139,8 +137,7 @@ ENDPROC(native_usergs_sysret64) .endm .macro RESTORE_TOP_OF_STACK tmp offset=0 - movq RSP+\offset(%rsp),\tmp - movq \tmp,PER_CPU_VAR(old_rsp) + /* nothing to do */ .endm /* @@ -222,9 +219,6 @@ ENDPROC(native_usergs_sysret64) * Interrupts are off on entry. * Only called from user space. * - * XXX if we had a free scratch register we could save the RSP into the stack frame - * and report it properly in ps. Unfortunately we haven't. - * * When user can change the frames always force IRET. That is because * it deals with uncanonical addresses better. SYSRET has trouble * with them due to bugs in both AMD and Intel CPUs. @@ -253,11 +247,13 @@ GLOBAL(system_call_after_swapgs) */ ENABLE_INTERRUPTS(CLBR_NONE) ALLOC_PT_GPREGS_ON_STACK 8 /* +8: space for orig_ax */ + movq %rcx,RIP(%rsp) + movq PER_CPU_VAR(old_rsp),%rcx + movq %r11,EFLAGS(%rsp) + movq %rcx,RSP(%rsp) + movq_cfi rax,ORIG_RAX SAVE_C_REGS_EXCEPT_RAX_RCX_R11 movq $-ENOSYS,RAX(%rsp) - movq_cfi rax,ORIG_RAX - movq %r11,EFLAGS(%rsp) - movq %rcx,RIP(%rsp) CFI_REL_OFFSET rip,RIP testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags+THREAD_INFO(%rsp,RIP) jnz tracesys @@ -293,7 +289,7 @@ ret_from_sys_call: CFI_REGISTER rip,rcx movq EFLAGS(%rsp),%r11 /*CFI_REGISTER rflags,r11*/ - movq PER_CPU_VAR(old_rsp), %rsp + movq RSP(%rsp),%rsp /* * 64bit SYSRET restores rip from rcx, * rflags from r11 (but RF and VM bits are forced to 0), diff --git a/arch/x86/kernel/perf_regs.c b/arch/x86/kernel/perf_regs.c index 781861cc5ee8..02a8720414c0 100644 --- a/arch/x86/kernel/perf_regs.c +++ b/arch/x86/kernel/perf_regs.c @@ -177,7 +177,7 @@ void perf_get_regs_user(struct perf_regs *regs_user, * than just blindly copying user_regs. */ regs_user->abi = PERF_SAMPLE_REGS_ABI_64; - regs_user_copy->sp = this_cpu_read(old_rsp); + regs_user_copy->sp = user_regs->sp; regs_user_copy->cs = __USER_CS; regs_user_copy->ss = __USER_DS; regs_user_copy->cx = -1; /* usually contains garbage */ diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 1e393d27d701..e8c124a1f885 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -602,6 +602,5 @@ long sys_arch_prctl(int code, unsigned long addr) unsigned long KSTK_ESP(struct task_struct *task) { - return (test_tsk_thread_flag(task, TIF_IA32)) ? - (task_pt_regs(task)->sp) : ((task)->thread.usersp); + return task_pt_regs(task)->sp; } -- GitLab From e936351a611bca2ebd37634d81d168e6585e3634 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Tue, 10 Mar 2015 14:15:35 +0530 Subject: [PATCH 03695/11651] staging: sm750fb: wrong type for print mention correct format specifier while printing. fixes all the build warnings about incorrect argument type while printing. since this is a framebuffer device and it should follow what the framebuffer layer is suggesting in struct fb_fix_screeninfo at smem_start and mmio_start, so accordingly changed the datatypes of vidmem_start, vidreg_start, vidmem_size and vidreg_size. Signed-off-by: Sudip Mukherjee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sm750fb/sm750.c | 24 ++++++++++++------------ drivers/staging/sm750fb/sm750.h | 8 ++++---- drivers/staging/sm750fb/sm750_hw.c | 4 ++-- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/staging/sm750fb/sm750.c b/drivers/staging/sm750fb/sm750.c index 520c69e3ab74..753869e3686d 100644 --- a/drivers/staging/sm750fb/sm750.c +++ b/drivers/staging/sm750fb/sm750.c @@ -530,20 +530,20 @@ static int lynxfb_ops_mmap(struct fb_info * info, struct vm_area_struct * vma) if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) return -EINVAL; off = vma->vm_pgoff << PAGE_SHIFT; - printk("lynxfb mmap pgoff: %x\n", vma->vm_pgoff); - printk("lynxfb mmap off 1: %x\n", off); + printk("lynxfb mmap pgoff: %lx\n", vma->vm_pgoff); + printk("lynxfb mmap off 1: %lx\n", off); /* frame buffer memory */ start = info->fix.smem_start; len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.smem_len); - printk("lynxfb mmap start 1: %x\n", start); + printk("lynxfb mmap start 1: %lx\n", start); printk("lynxfb mmap len 1: %x\n", len); if (off >= len) { /* memory mapped io */ off -= len; - printk("lynxfb mmap off 2: %x\n", off); + printk("lynxfb mmap off 2: %lx\n", off); if (info->var.accel_flags) { printk("lynxfb mmap accel flags true"); return -EINVAL; @@ -551,28 +551,28 @@ static int lynxfb_ops_mmap(struct fb_info * info, struct vm_area_struct * vma) start = info->fix.mmio_start; len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.mmio_len); - printk("lynxfb mmap start 2: %x\n", start); + printk("lynxfb mmap start 2: %lx\n", start); printk("lynxfb mmap len 2: %x\n", len); } start &= PAGE_MASK; - printk("lynxfb mmap start 3: %x\n", start); - printk("lynxfb mmap vm start: %x\n", vma->vm_start); - printk("lynxfb mmap vm end: %x\n", vma->vm_end); + printk("lynxfb mmap start 3: %lx\n", start); + printk("lynxfb mmap vm start: %lx\n", vma->vm_start); + printk("lynxfb mmap vm end: %lx\n", vma->vm_end); printk("lynxfb mmap len: %x\n", len); - printk("lynxfb mmap off: %x\n", off); + printk("lynxfb mmap off: %lx\n", off); if ((vma->vm_end - vma->vm_start + off) > len) { return -EINVAL; } off += start; - printk("lynxfb mmap off 3: %x\n", off); + printk("lynxfb mmap off 3: %lx\n", off); vma->vm_pgoff = off >> PAGE_SHIFT; /* This is an IO map - tell maydump to skip this VMA */ vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP; vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); fb_pgprotect(file, vma, off); - printk("lynxfb mmap off 4: %x\n", off); - printk("lynxfb mmap pgprot: %x\n", vma->vm_page_prot); + printk("lynxfb mmap off 4: %lx\n", off); + printk("lynxfb mmap pgprot: %lx\n", (unsigned long) pgprot_val(vma->vm_page_prot)); if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, vma->vm_end - vma->vm_start, vma->vm_page_prot)) return -EAGAIN; diff --git a/drivers/staging/sm750fb/sm750.h b/drivers/staging/sm750fb/sm750.h index 711676c58839..d39968c2d5c1 100644 --- a/drivers/staging/sm750fb/sm750.h +++ b/drivers/staging/sm750fb/sm750.h @@ -59,10 +59,10 @@ struct lynx_share{ }mtrr; #endif /* all smi graphic adaptor got below attributes */ - resource_size_t vidmem_start; - resource_size_t vidreg_start; - resource_size_t vidmem_size; - resource_size_t vidreg_size; + unsigned long vidmem_start; + unsigned long vidreg_start; + __u32 vidmem_size; + __u32 vidreg_size; volatile unsigned char __iomem * pvReg; unsigned char __iomem * pvMem; /* locks*/ diff --git a/drivers/staging/sm750fb/sm750_hw.c b/drivers/staging/sm750fb/sm750_hw.c index cd971bd41637..ec2d49959072 100644 --- a/drivers/staging/sm750fb/sm750_hw.c +++ b/drivers/staging/sm750fb/sm750_hw.c @@ -36,7 +36,7 @@ int hw_sm750_map(struct lynx_share* share,struct pci_dev* pdev) share->vidreg_start = pci_resource_start(pdev,1); share->vidreg_size = MB(2); - pr_info("mmio phyAddr = %x\n",share->vidreg_start); + pr_info("mmio phyAddr = %lx\n", share->vidreg_start); /* reserve the vidreg space of smi adaptor * if you do this, u need to add release region code @@ -73,7 +73,7 @@ int hw_sm750_map(struct lynx_share* share,struct pci_dev* pdev) * @hw_sm750_getVMSize function can be safe. * */ share->vidmem_size = hw_sm750_getVMSize(share); - pr_info("video memory phyAddr = %x, size = %d bytes\n", + pr_info("video memory phyAddr = %lx, size = %u bytes\n", share->vidmem_start,share->vidmem_size); /* reserve the vidmem space of smi adaptor */ -- GitLab From 5e4f518959bdf8a4f9c8f80879e4a0f7a95d2cb3 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 13 Feb 2015 14:35:59 +0000 Subject: [PATCH 03696/11651] drm/i915: Prevent TLB error on first execution on SNB Long ago I found that I was getting sporadic errors when booting SNB, with the symptom being that the first batch died with IPEHR != *ACTHD, typically caused by the TLB being invalid. These magically disappeared if I held the forcewake during the entire ring initialisation sequence. (It can probably be shortened to a short critical section, but the whole initialisation is full of register writes and so we would be taking and releasing forcewake almost continually, and so holding it over the entire sequence will probably be a net win!) Note some of the kernels I encounted the issue already had the deferred forcewake release, so it is still relevant. I know that there have been a few other reports with similar failure conditions on SNB, I think such as References: https://bugs.freedesktop.org/show_bug.cgi?id=80913 v2: Wrap i915_gem_init_hw() with its own security blanket as we take that path following resume and reset. Signed-off-by: Chris Wilson Reviewed-by: Daniel Vetter Cc: stable@vger.kernel.org Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_gem.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index ac7fe39d38a3..5b205863b659 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4793,6 +4793,9 @@ i915_gem_init_hw(struct drm_device *dev) if (INTEL_INFO(dev)->gen < 6 && !intel_enable_gtt()) return -EIO; + /* Double layer security blanket, see i915_gem_init() */ + intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); + if (dev_priv->ellc_size) I915_WRITE(HSW_IDICR, I915_READ(HSW_IDICR) | IDIHASHMSK(0xf)); @@ -4825,7 +4828,7 @@ i915_gem_init_hw(struct drm_device *dev) for_each_ring(ring, dev_priv, i) { ret = ring->init_hw(ring); if (ret) - return ret; + goto out; } for (i = 0; i < NUM_L3_SLICES(dev); i++) @@ -4842,9 +4845,11 @@ i915_gem_init_hw(struct drm_device *dev) DRM_ERROR("Context enable failed %d\n", ret); i915_gem_cleanup_ringbuffer(dev); - return ret; + goto out; } +out: + intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); return ret; } @@ -4878,6 +4883,14 @@ int i915_gem_init(struct drm_device *dev) dev_priv->gt.stop_ring = intel_logical_ring_stop; } + /* This is just a security blanket to placate dragons. + * On some systems, we very sporadically observe that the first TLBs + * used by the CS may be stale, despite us poking the TLB reset. If + * we hold the forcewake during initialisation these problems + * just magically go away. + */ + intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); + ret = i915_gem_init_userptr(dev); if (ret) goto out_unlock; @@ -4904,6 +4917,7 @@ int i915_gem_init(struct drm_device *dev) } out_unlock: + intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); mutex_unlock(&dev->struct_mutex); return ret; -- GitLab From 67fdcc96b49455569307e6ba7bba0905cf9d6596 Mon Sep 17 00:00:00 2001 From: Matthias Brugger Date: Fri, 6 Mar 2015 13:52:58 +0100 Subject: [PATCH 03697/11651] ARM: mediatek: enable the pin controller This patch enables the pin controller for Mediatek SoCs. Signed-off-by: Matthias Brugger --- arch/arm/mach-mediatek/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-mediatek/Kconfig b/arch/arm/mach-mediatek/Kconfig index f7e463ca0287..9f59e58da3a4 100644 --- a/arch/arm/mach-mediatek/Kconfig +++ b/arch/arm/mach-mediatek/Kconfig @@ -1,6 +1,7 @@ menuconfig ARCH_MEDIATEK bool "Mediatek MT65xx & MT81xx SoC" if ARCH_MULTI_V7 select ARM_GIC + select PINCTRL select MTK_TIMER help Support for Mediatek MT65xx & MT81xx SoCs -- GitLab From 668f198f40d1cc89c2330c6ad56f3b397b05a0bc Mon Sep 17 00:00:00 2001 From: David Kaplan Date: Fri, 20 Feb 2015 16:02:10 -0600 Subject: [PATCH 03698/11651] KVM: SVM: use kvm_register_write()/read() KVM has nice wrappers to access the register values, clean up a few places that should use them but currently do not. Signed-off-by: David Kaplan [forward port and testing] Signed-off-by: Joel Schopp Acked-by: Borislav Petkov Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/svm.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index cc618c882f90..93dda3ccff03 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -2757,11 +2757,11 @@ static int invlpga_interception(struct vcpu_svm *svm) { struct kvm_vcpu *vcpu = &svm->vcpu; - trace_kvm_invlpga(svm->vmcb->save.rip, vcpu->arch.regs[VCPU_REGS_RCX], - vcpu->arch.regs[VCPU_REGS_RAX]); + trace_kvm_invlpga(svm->vmcb->save.rip, kvm_register_read(&svm->vcpu, VCPU_REGS_RCX), + kvm_register_read(&svm->vcpu, VCPU_REGS_RAX)); /* Let's treat INVLPGA the same as INVLPG (can be optimized!) */ - kvm_mmu_invlpg(vcpu, vcpu->arch.regs[VCPU_REGS_RAX]); + kvm_mmu_invlpg(vcpu, kvm_register_read(&svm->vcpu, VCPU_REGS_RAX)); svm->next_rip = kvm_rip_read(&svm->vcpu) + 3; skip_emulated_instruction(&svm->vcpu); @@ -2770,7 +2770,7 @@ static int invlpga_interception(struct vcpu_svm *svm) static int skinit_interception(struct vcpu_svm *svm) { - trace_kvm_skinit(svm->vmcb->save.rip, svm->vcpu.arch.regs[VCPU_REGS_RAX]); + trace_kvm_skinit(svm->vmcb->save.rip, kvm_register_read(&svm->vcpu, VCPU_REGS_RAX)); kvm_queue_exception(&svm->vcpu, UD_VECTOR); return 1; @@ -3133,7 +3133,7 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data) static int rdmsr_interception(struct vcpu_svm *svm) { - u32 ecx = svm->vcpu.arch.regs[VCPU_REGS_RCX]; + u32 ecx = kvm_register_read(&svm->vcpu, VCPU_REGS_RCX); u64 data; if (svm_get_msr(&svm->vcpu, ecx, &data)) { @@ -3142,8 +3142,8 @@ static int rdmsr_interception(struct vcpu_svm *svm) } else { trace_kvm_msr_read(ecx, data); - svm->vcpu.arch.regs[VCPU_REGS_RAX] = data & 0xffffffff; - svm->vcpu.arch.regs[VCPU_REGS_RDX] = data >> 32; + kvm_register_write(&svm->vcpu, VCPU_REGS_RAX, data & 0xffffffff); + kvm_register_write(&svm->vcpu, VCPU_REGS_RDX, data >> 32); svm->next_rip = kvm_rip_read(&svm->vcpu) + 2; skip_emulated_instruction(&svm->vcpu); } @@ -3246,9 +3246,8 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr) static int wrmsr_interception(struct vcpu_svm *svm) { struct msr_data msr; - u32 ecx = svm->vcpu.arch.regs[VCPU_REGS_RCX]; - u64 data = (svm->vcpu.arch.regs[VCPU_REGS_RAX] & -1u) - | ((u64)(svm->vcpu.arch.regs[VCPU_REGS_RDX] & -1u) << 32); + u32 ecx = kvm_register_read(&svm->vcpu, VCPU_REGS_RCX); + u64 data = kvm_read_edx_eax(&svm->vcpu); msr.data = data; msr.index = ecx; -- GitLab From bfda0e849102108eeedbeb71077859cdc853b7cd Mon Sep 17 00:00:00 2001 From: Kevin Mulvey Date: Fri, 20 Feb 2015 08:21:36 -0500 Subject: [PATCH 03699/11651] KVM: white space formatting in kvm_main.c Better alignment of loop using tabs rather than spaces, this makes checkpatch.pl happier. Signed-off-by: Kevin Mulvey Signed-off-by: Marcelo Tosatti --- virt/kvm/kvm_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index a1093700f3a4..36ab89dfbf62 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -1742,7 +1742,7 @@ int kvm_clear_guest(struct kvm *kvm, gpa_t gpa, unsigned long len) int offset = offset_in_page(gpa); int ret; - while ((seg = next_segment(len, offset)) != 0) { + while ((seg = next_segment(len, offset)) != 0) { ret = kvm_clear_guest_page(kvm, gfn, offset, seg); if (ret < 0) return ret; -- GitLab From ae548c5c806497b3495019f550f93dee03f6c15a Mon Sep 17 00:00:00 2001 From: Kevin Mulvey Date: Fri, 20 Feb 2015 08:21:37 -0500 Subject: [PATCH 03700/11651] KVM: fix checkpatch.pl errors in kvm/irqchip.c Fix whitespace around while Signed-off-by: Kevin Mulvey Signed-off-by: Marcelo Tosatti --- virt/kvm/irqchip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/virt/kvm/irqchip.c b/virt/kvm/irqchip.c index 7f256f31df10..1d56a901e791 100644 --- a/virt/kvm/irqchip.c +++ b/virt/kvm/irqchip.c @@ -105,7 +105,7 @@ int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level, i = kvm_irq_map_gsi(kvm, irq_set, irq); srcu_read_unlock(&kvm->irq_srcu, idx); - while(i--) { + while (i--) { int r; r = irq_set[i].set(&irq_set[i], kvm, irq_source_id, level, line_status); -- GitLab From 5bda6eed2e3626f40f2602a8fed72007f1fafaf8 Mon Sep 17 00:00:00 2001 From: Wincy Van Date: Wed, 24 Dec 2014 11:14:29 +0800 Subject: [PATCH 03701/11651] KVM: ioapic: Record edge-triggered interrupts delivery status This patch fixes the bug discussed in https://www.mail-archive.com/kvm@vger.kernel.org/msg109813.html This patch uses a new field named irr_delivered to record the delivery status of edge-triggered interrupts, and clears the delivered interrupts in kvm_get_ioapic. So it has the same effect of commit 0bc830b05c667218d703f2026ec866c49df974fc ("KVM: ioapic: clear IRR for edge-triggered interrupts at delivery") while avoids the bug of Windows guests. Signed-off-by: Wincy Van Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/ioapic.c | 7 ++++++- arch/x86/kvm/ioapic.h | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/arch/x86/kvm/ioapic.c b/arch/x86/kvm/ioapic.c index b1947e0f3e10..a2e9d961c7fe 100644 --- a/arch/x86/kvm/ioapic.c +++ b/arch/x86/kvm/ioapic.c @@ -206,6 +206,8 @@ static int ioapic_set_irq(struct kvm_ioapic *ioapic, unsigned int irq, old_irr = ioapic->irr; ioapic->irr |= mask; + if (edge) + ioapic->irr_delivered &= ~mask; if ((edge && old_irr == ioapic->irr) || (!edge && entry.fields.remote_irr)) { ret = 0; @@ -349,7 +351,7 @@ static int ioapic_service(struct kvm_ioapic *ioapic, int irq, bool line_status) irqe.shorthand = 0; if (irqe.trig_mode == IOAPIC_EDGE_TRIG) - ioapic->irr &= ~(1 << irq); + ioapic->irr_delivered |= 1 << irq; if (irq == RTC_GSI && line_status) { /* @@ -597,6 +599,7 @@ static void kvm_ioapic_reset(struct kvm_ioapic *ioapic) ioapic->base_address = IOAPIC_DEFAULT_BASE_ADDRESS; ioapic->ioregsel = 0; ioapic->irr = 0; + ioapic->irr_delivered = 0; ioapic->id = 0; memset(ioapic->irq_eoi, 0x00, IOAPIC_NUM_PINS); rtc_irq_eoi_tracking_reset(ioapic); @@ -654,6 +657,7 @@ int kvm_get_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state) spin_lock(&ioapic->lock); memcpy(state, ioapic, sizeof(struct kvm_ioapic_state)); + state->irr &= ~ioapic->irr_delivered; spin_unlock(&ioapic->lock); return 0; } @@ -667,6 +671,7 @@ int kvm_set_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state) spin_lock(&ioapic->lock); memcpy(ioapic, state, sizeof(struct kvm_ioapic_state)); ioapic->irr = 0; + ioapic->irr_delivered = 0; update_handled_vectors(ioapic); kvm_vcpu_request_scan_ioapic(kvm); kvm_ioapic_inject_all(ioapic, state->irr); diff --git a/arch/x86/kvm/ioapic.h b/arch/x86/kvm/ioapic.h index c2e36d934af4..38d8402ea65c 100644 --- a/arch/x86/kvm/ioapic.h +++ b/arch/x86/kvm/ioapic.h @@ -77,6 +77,7 @@ struct kvm_ioapic { struct rtc_status rtc_status; struct delayed_work eoi_inject; u32 irq_eoi[IOAPIC_NUM_PINS]; + u32 irr_delivered; }; #ifdef DEBUG -- GitLab From 0fa9778895635ab3824caf34fd573562dd2b999c Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Fri, 27 Feb 2015 16:50:10 +0100 Subject: [PATCH 03702/11651] KVM: make halt_poll_ns static halt_poll_ns is used only locally. Make it static. Signed-off-by: Christian Borntraeger Signed-off-by: Marcelo Tosatti --- virt/kvm/kvm_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 36ab89dfbf62..b1d6a161eafa 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -66,7 +66,7 @@ MODULE_AUTHOR("Qumranet"); MODULE_LICENSE("GPL"); -unsigned int halt_poll_ns = 0; +static unsigned int halt_poll_ns; module_param(halt_poll_ns, uint, S_IRUGO | S_IWUSR); /* -- GitLab From 548ef28449c0c06f92194c40ff0eaed248cb4b75 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Tue, 24 Feb 2015 21:29:25 +0100 Subject: [PATCH 03703/11651] KVM: Get rid of kvm_kvfree() kvm_kvfree() provides exactly the same functionality as the new common kvfree() function - so let's simply replace the kvm function with the common function. Signed-off-by: Thomas Huth Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/x86.c | 8 ++++---- include/linux/kvm_host.h | 1 - virt/kvm/kvm_main.c | 10 +--------- 3 files changed, 5 insertions(+), 14 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index bd7a70be41b3..c5f7e035e0f1 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -7429,7 +7429,7 @@ void kvm_arch_free_memslot(struct kvm *kvm, struct kvm_memory_slot *free, for (i = 0; i < KVM_NR_PAGE_SIZES; ++i) { if (!dont || free->arch.rmap[i] != dont->arch.rmap[i]) { - kvm_kvfree(free->arch.rmap[i]); + kvfree(free->arch.rmap[i]); free->arch.rmap[i] = NULL; } if (i == 0) @@ -7437,7 +7437,7 @@ void kvm_arch_free_memslot(struct kvm *kvm, struct kvm_memory_slot *free, if (!dont || free->arch.lpage_info[i - 1] != dont->arch.lpage_info[i - 1]) { - kvm_kvfree(free->arch.lpage_info[i - 1]); + kvfree(free->arch.lpage_info[i - 1]); free->arch.lpage_info[i - 1] = NULL; } } @@ -7491,12 +7491,12 @@ int kvm_arch_create_memslot(struct kvm *kvm, struct kvm_memory_slot *slot, out_free: for (i = 0; i < KVM_NR_PAGE_SIZES; ++i) { - kvm_kvfree(slot->arch.rmap[i]); + kvfree(slot->arch.rmap[i]); slot->arch.rmap[i] = NULL; if (i == 0) continue; - kvm_kvfree(slot->arch.lpage_info[i - 1]); + kvfree(slot->arch.lpage_info[i - 1]); slot->arch.lpage_info[i - 1] = NULL; } return -ENOMEM; diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index d12b2104d19b..0f574ebc82f4 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -658,7 +658,6 @@ int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu); int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu); void *kvm_kvzalloc(unsigned long size); -void kvm_kvfree(const void *addr); #ifndef __KVM_HAVE_ARCH_VM_ALLOC static inline struct kvm *kvm_arch_alloc_vm(void) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index b1d6a161eafa..07064dc18f97 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -539,20 +539,12 @@ void *kvm_kvzalloc(unsigned long size) return kzalloc(size, GFP_KERNEL); } -void kvm_kvfree(const void *addr) -{ - if (is_vmalloc_addr(addr)) - vfree(addr); - else - kfree(addr); -} - static void kvm_destroy_dirty_bitmap(struct kvm_memory_slot *memslot) { if (!memslot->dirty_bitmap) return; - kvm_kvfree(memslot->dirty_bitmap); + kvfree(memslot->dirty_bitmap); memslot->dirty_bitmap = NULL; } -- GitLab From 893bdbf16574e781504ea2a767ff8919d1394e52 Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Thu, 26 Feb 2015 14:58:19 +0800 Subject: [PATCH 03704/11651] KVM: Fix WARNINGs for 'sizeof(X)' instead of 'sizeof X' in kvm_main.c There are many WARNINGs like this: WARNING: sizeof tr should be sizeof(tr) + if (copy_from_user(&tr, argp, sizeof tr)) In kvm_main.c many places are using 'sizeof(X)', and the other places are using 'sizeof X', while the kernel recommands to use 'sizeof(X)', so this patch will replace all 'sizeof X' to 'sizeof(X)' to make them consistent and at the same time to reduce the WARNINGs noise when we are checking new patches. Signed-off-by: Xiubo Li Signed-off-by: Marcelo Tosatti --- virt/kvm/kvm_main.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 07064dc18f97..38738c20992e 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -2197,7 +2197,7 @@ out_free1: if (r) goto out; r = -EFAULT; - if (copy_to_user(argp, &mp_state, sizeof mp_state)) + if (copy_to_user(argp, &mp_state, sizeof(mp_state))) goto out; r = 0; break; @@ -2206,7 +2206,7 @@ out_free1: struct kvm_mp_state mp_state; r = -EFAULT; - if (copy_from_user(&mp_state, argp, sizeof mp_state)) + if (copy_from_user(&mp_state, argp, sizeof(mp_state))) goto out; r = kvm_arch_vcpu_ioctl_set_mpstate(vcpu, &mp_state); break; @@ -2215,13 +2215,13 @@ out_free1: struct kvm_translation tr; r = -EFAULT; - if (copy_from_user(&tr, argp, sizeof tr)) + if (copy_from_user(&tr, argp, sizeof(tr))) goto out; r = kvm_arch_vcpu_ioctl_translate(vcpu, &tr); if (r) goto out; r = -EFAULT; - if (copy_to_user(argp, &tr, sizeof tr)) + if (copy_to_user(argp, &tr, sizeof(tr))) goto out; r = 0; break; @@ -2230,7 +2230,7 @@ out_free1: struct kvm_guest_debug dbg; r = -EFAULT; - if (copy_from_user(&dbg, argp, sizeof dbg)) + if (copy_from_user(&dbg, argp, sizeof(dbg))) goto out; r = kvm_arch_vcpu_ioctl_set_guest_debug(vcpu, &dbg); break; @@ -2244,14 +2244,14 @@ out_free1: if (argp) { r = -EFAULT; if (copy_from_user(&kvm_sigmask, argp, - sizeof kvm_sigmask)) + sizeof(kvm_sigmask))) goto out; r = -EINVAL; - if (kvm_sigmask.len != sizeof sigset) + if (kvm_sigmask.len != sizeof(sigset)) goto out; r = -EFAULT; if (copy_from_user(&sigset, sigmask_arg->sigset, - sizeof sigset)) + sizeof(sigset))) goto out; p = &sigset; } @@ -2313,14 +2313,14 @@ static long kvm_vcpu_compat_ioctl(struct file *filp, if (argp) { r = -EFAULT; if (copy_from_user(&kvm_sigmask, argp, - sizeof kvm_sigmask)) + sizeof(kvm_sigmask))) goto out; r = -EINVAL; - if (kvm_sigmask.len != sizeof csigset) + if (kvm_sigmask.len != sizeof(csigset)) goto out; r = -EFAULT; if (copy_from_user(&csigset, sigmask_arg->sigset, - sizeof csigset)) + sizeof(csigset))) goto out; sigset_from_compat(&sigset, &csigset); r = kvm_vcpu_ioctl_set_sigmask(vcpu, &sigset); @@ -2516,7 +2516,7 @@ static long kvm_vm_ioctl(struct file *filp, r = -EFAULT; if (copy_from_user(&kvm_userspace_mem, argp, - sizeof kvm_userspace_mem)) + sizeof(kvm_userspace_mem))) goto out; r = kvm_vm_ioctl_set_memory_region(kvm, &kvm_userspace_mem); @@ -2526,7 +2526,7 @@ static long kvm_vm_ioctl(struct file *filp, struct kvm_dirty_log log; r = -EFAULT; - if (copy_from_user(&log, argp, sizeof log)) + if (copy_from_user(&log, argp, sizeof(log))) goto out; r = kvm_vm_ioctl_get_dirty_log(kvm, &log); break; @@ -2535,7 +2535,7 @@ static long kvm_vm_ioctl(struct file *filp, case KVM_REGISTER_COALESCED_MMIO: { struct kvm_coalesced_mmio_zone zone; r = -EFAULT; - if (copy_from_user(&zone, argp, sizeof zone)) + if (copy_from_user(&zone, argp, sizeof(zone))) goto out; r = kvm_vm_ioctl_register_coalesced_mmio(kvm, &zone); break; @@ -2543,7 +2543,7 @@ static long kvm_vm_ioctl(struct file *filp, case KVM_UNREGISTER_COALESCED_MMIO: { struct kvm_coalesced_mmio_zone zone; r = -EFAULT; - if (copy_from_user(&zone, argp, sizeof zone)) + if (copy_from_user(&zone, argp, sizeof(zone))) goto out; r = kvm_vm_ioctl_unregister_coalesced_mmio(kvm, &zone); break; @@ -2553,7 +2553,7 @@ static long kvm_vm_ioctl(struct file *filp, struct kvm_irqfd data; r = -EFAULT; - if (copy_from_user(&data, argp, sizeof data)) + if (copy_from_user(&data, argp, sizeof(data))) goto out; r = kvm_irqfd(kvm, &data); break; @@ -2562,7 +2562,7 @@ static long kvm_vm_ioctl(struct file *filp, struct kvm_ioeventfd data; r = -EFAULT; - if (copy_from_user(&data, argp, sizeof data)) + if (copy_from_user(&data, argp, sizeof(data))) goto out; r = kvm_ioeventfd(kvm, &data); break; @@ -2583,7 +2583,7 @@ static long kvm_vm_ioctl(struct file *filp, struct kvm_msi msi; r = -EFAULT; - if (copy_from_user(&msi, argp, sizeof msi)) + if (copy_from_user(&msi, argp, sizeof(msi))) goto out; r = kvm_send_userspace_msi(kvm, &msi); break; @@ -2595,7 +2595,7 @@ static long kvm_vm_ioctl(struct file *filp, struct kvm_irq_level irq_event; r = -EFAULT; - if (copy_from_user(&irq_event, argp, sizeof irq_event)) + if (copy_from_user(&irq_event, argp, sizeof(irq_event))) goto out; r = kvm_vm_ioctl_irq_line(kvm, &irq_event, @@ -2605,7 +2605,7 @@ static long kvm_vm_ioctl(struct file *filp, r = -EFAULT; if (ioctl == KVM_IRQ_LINE_STATUS) { - if (copy_to_user(argp, &irq_event, sizeof irq_event)) + if (copy_to_user(argp, &irq_event, sizeof(irq_event))) goto out; } -- GitLab From a642a1756752421e5f6661d951943b53225c03eb Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Thu, 26 Feb 2015 14:58:20 +0800 Subject: [PATCH 03705/11651] KVM: Fix WARNING: labels should not be indented in kvm_main.c WARNING: labels should not be indented + out_free_irq_routing: This patch fixes this WARNING to reduce noise when checking new patches in kvm_main.c. Signed-off-by: Xiubo Li Signed-off-by: Marcelo Tosatti --- virt/kvm/kvm_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 38738c20992e..4146d01319d0 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -2638,7 +2638,7 @@ static long kvm_vm_ioctl(struct file *filp, goto out_free_irq_routing; r = kvm_set_irq_routing(kvm, entries, routing.nr, routing.flags); - out_free_irq_routing: +out_free_irq_routing: vfree(entries); break; } -- GitLab From f4fee93270abbf862aab268111ac1e12934130c4 Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Thu, 26 Feb 2015 14:58:21 +0800 Subject: [PATCH 03706/11651] KVM: Fix ERROR: do not initialise statics to 0 or NULL in kvm_main.c ERROR: do not initialise statics to 0 or NULL +static int kvm_usage_count = 0; The kvm_usage_count will be placed to .bss segment when linking, so not need to set it to 0 here obviously. This patch fixes this ERROR to reduce noise when checking new patches in kvm_main.c. Signed-off-by: Xiubo Li Signed-off-by: Marcelo Tosatti --- virt/kvm/kvm_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 4146d01319d0..7d2c2ac3cb8a 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -80,7 +80,7 @@ static DEFINE_RAW_SPINLOCK(kvm_count_lock); LIST_HEAD(vm_list); static cpumask_var_t cpus_hardware_enabled; -static int kvm_usage_count = 0; +static int kvm_usage_count; static atomic_t hardware_enable_failed; struct kmem_cache *kvm_vcpu_cache; -- GitLab From ee543159d5e0cfa9f3a349ac4e3da01a0ec66c78 Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Thu, 26 Feb 2015 14:58:22 +0800 Subject: [PATCH 03707/11651] KVM: EXPORT_SYMBOL should immediately follow its function WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable +EXPORT_SYMBOL_GPL(gfn_to_page); This patch fixes these warnings to reduce noise when checking new patches in kvm_main.c. Signed-off-by: Xiubo Li Signed-off-by: Marcelo Tosatti --- virt/kvm/kvm_main.c | 1 - 1 file changed, 1 deletion(-) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 7d2c2ac3cb8a..f9ad30727388 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -1473,7 +1473,6 @@ struct page *gfn_to_page(struct kvm *kvm, gfn_t gfn) return kvm_pfn_to_page(pfn); } - EXPORT_SYMBOL_GPL(gfn_to_page); void kvm_release_page_clean(struct page *page) -- GitLab From f95ef0cd0257852198b31ffeb527ef2f72caa1aa Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Thu, 26 Feb 2015 14:58:23 +0800 Subject: [PATCH 03708/11651] KVM: Missing blank line after declarations in kvm_main.c There are many Warnings like this: WARNING: Missing a blank line after declarations + struct kvm_coalesced_mmio_zone zone; + r = -EFAULT; This patch fixes these warnings to reduce noise when checking new patches in kvm_main.c. Signed-off-by: Xiubo Li Signed-off-by: Marcelo Tosatti --- virt/kvm/kvm_main.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index f9ad30727388..ba7fc2e6af01 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -1508,6 +1508,7 @@ void kvm_set_pfn_dirty(pfn_t pfn) { if (!kvm_is_reserved_pfn(pfn)) { struct page *page = pfn_to_page(pfn); + if (!PageReserved(page)) SetPageDirty(page); } @@ -1791,6 +1792,7 @@ void kvm_vcpu_block(struct kvm_vcpu *vcpu) start = cur = ktime_get(); if (halt_poll_ns) { ktime_t stop = ktime_add_ns(ktime_get(), halt_poll_ns); + do { /* * This sets KVM_REQ_UNHALT if an interrupt @@ -2126,6 +2128,7 @@ static long kvm_vcpu_ioctl(struct file *filp, /* The thread running this VCPU changed. */ struct pid *oldpid = vcpu->pid; struct pid *newpid = get_task_pid(current, PIDTYPE_PID); + rcu_assign_pointer(vcpu->pid, newpid); if (oldpid) synchronize_rcu(); @@ -2533,6 +2536,7 @@ static long kvm_vm_ioctl(struct file *filp, #ifdef KVM_COALESCED_MMIO_PAGE_OFFSET case KVM_REGISTER_COALESCED_MMIO: { struct kvm_coalesced_mmio_zone zone; + r = -EFAULT; if (copy_from_user(&zone, argp, sizeof(zone))) goto out; @@ -2541,6 +2545,7 @@ static long kvm_vm_ioctl(struct file *filp, } case KVM_UNREGISTER_COALESCED_MMIO: { struct kvm_coalesced_mmio_zone zone; + r = -EFAULT; if (copy_from_user(&zone, argp, sizeof(zone))) goto out; @@ -3259,6 +3264,7 @@ struct kvm_vcpu *preempt_notifier_to_vcpu(struct preempt_notifier *pn) static void kvm_sched_in(struct preempt_notifier *pn, int cpu) { struct kvm_vcpu *vcpu = preempt_notifier_to_vcpu(pn); + if (vcpu->preempted) vcpu->preempted = false; -- GitLab From b7d409deb9322138d031c2122d1fcba9af9c508c Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Thu, 26 Feb 2015 14:58:24 +0800 Subject: [PATCH 03709/11651] KVM: no space before tabs in kvm_main.c WARNING: please, no space before tabs + * ^I^Ikvm->lock --> kvm->slots_lock --> kvm->irq_lock$ WARNING: please, no space before tabs +^I^I * ^I- gfn_to_hva (kvm_read_guest, gfn_to_pfn)$ WARNING: please, no space before tabs +^I^I * ^I- kvm_is_visible_gfn (mmu_check_roots)$ This patch fixes these warnings to reduce noise when checking new patches in kvm_main.c. Signed-off-by: Xiubo Li Signed-off-by: Marcelo Tosatti --- virt/kvm/kvm_main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index ba7fc2e6af01..8f76c50d1fb4 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -72,7 +72,7 @@ module_param(halt_poll_ns, uint, S_IRUGO | S_IWUSR); /* * Ordering of locks: * - * kvm->lock --> kvm->slots_lock --> kvm->irq_lock + * kvm->lock --> kvm->slots_lock --> kvm->irq_lock */ DEFINE_SPINLOCK(kvm_lock); @@ -880,8 +880,8 @@ int __kvm_set_memory_region(struct kvm *kvm, * or moved, memslot will be created. * * validation of sp->gfn happens in: - * - gfn_to_hva (kvm_read_guest, gfn_to_pfn) - * - kvm_is_visible_gfn (mmu_check_roots) + * - gfn_to_hva (kvm_read_guest, gfn_to_pfn) + * - kvm_is_visible_gfn (mmu_check_roots) */ kvm_arch_flush_shadow_memslot(kvm, slot); -- GitLab From 20e87b72244f922f420d83b0b15b42d17b92acae Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Thu, 26 Feb 2015 14:58:25 +0800 Subject: [PATCH 03710/11651] KVM: Fix indentation in kvm_main.c ERROR: code indent should use tabs where possible + const struct kvm_io_range *r2)$ WARNING: please, no spaces at the start of a line + const struct kvm_io_range *r2)$ This patch fixes this ERROR & WARNING to reduce noise when checking new patches in kvm_main.c. Signed-off-by: Xiubo Li Signed-off-by: Marcelo Tosatti --- virt/kvm/kvm_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 8f76c50d1fb4..e7d1bf8f2366 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -2940,7 +2940,7 @@ static void kvm_io_bus_destroy(struct kvm_io_bus *bus) } static inline int kvm_io_bus_cmp(const struct kvm_io_range *r1, - const struct kvm_io_range *r2) + const struct kvm_io_range *r2) { if (r1->addr < r2->addr) return -1; -- GitLab From 1170adc6dd9e94d3cefb6eefe1f44b308d882515 Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Thu, 26 Feb 2015 14:58:26 +0800 Subject: [PATCH 03711/11651] KVM: Use pr_info/pr_err in kvm_main.c WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ... + printk(KERN_INFO "kvm: exiting hardware virtualization\n"); WARNING: Prefer [subsystem eg: netdev]_err([subsystem]dev, ... then dev_err(dev, ... then pr_err(... to printk(KERN_ERR ... + printk(KERN_ERR "kvm: misc device register failed\n"); Signed-off-by: Xiubo Li Signed-off-by: Marcelo Tosatti --- virt/kvm/kvm_main.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index e7d1bf8f2366..49900fc21f89 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -2817,8 +2817,7 @@ static void hardware_enable_nolock(void *junk) if (r) { cpumask_clear_cpu(cpu, cpus_hardware_enabled); atomic_inc(&hardware_enable_failed); - printk(KERN_INFO "kvm: enabling virtualization on " - "CPU%d failed\n", cpu); + pr_info("kvm: enabling virtualization on CPU%d failed\n", cpu); } } @@ -2894,12 +2893,12 @@ static int kvm_cpu_hotplug(struct notifier_block *notifier, unsigned long val, val &= ~CPU_TASKS_FROZEN; switch (val) { case CPU_DYING: - printk(KERN_INFO "kvm: disabling virtualization on CPU%d\n", + pr_info("kvm: disabling virtualization on CPU%d\n", cpu); hardware_disable(); break; case CPU_STARTING: - printk(KERN_INFO "kvm: enabling virtualization on CPU%d\n", + pr_info("kvm: enabling virtualization on CPU%d\n", cpu); hardware_enable(); break; @@ -2916,7 +2915,7 @@ static int kvm_reboot(struct notifier_block *notifier, unsigned long val, * * And Intel TXT required VMX off for all cpu when system shutdown. */ - printk(KERN_INFO "kvm: exiting hardware virtualization\n"); + pr_info("kvm: exiting hardware virtualization\n"); kvm_rebooting = true; on_each_cpu(hardware_disable_nolock, NULL, 1); return NOTIFY_OK; @@ -3346,7 +3345,7 @@ int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align, r = misc_register(&kvm_dev); if (r) { - printk(KERN_ERR "kvm: misc device register failed\n"); + pr_err("kvm: misc device register failed\n"); goto out_unreg; } @@ -3357,7 +3356,7 @@ int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align, r = kvm_init_debug(); if (r) { - printk(KERN_ERR "kvm: create debugfs files failed\n"); + pr_err("kvm: create debugfs files failed\n"); goto out_undebugfs; } -- GitLab From a03a8dbe20eff6d57aae3147577bf84b52aba4e6 Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Mon, 9 Mar 2015 23:04:15 +0100 Subject: [PATCH 03712/11651] netfilter: fix sparse warnings in reject handling make C=1 CF=-D__CHECK_ENDIAN__ shows following: net/bridge/netfilter/nft_reject_bridge.c:65:50: warning: incorrect type in argument 3 (different base types) net/bridge/netfilter/nft_reject_bridge.c:65:50: expected restricted __be16 [usertype] protocol [..] net/bridge/netfilter/nft_reject_bridge.c:102:37: warning: cast from restricted __be16 net/bridge/netfilter/nft_reject_bridge.c:102:37: warning: incorrect type in argument 1 (different base types) [..] net/bridge/netfilter/nft_reject_bridge.c:121:50: warning: incorrect type in argument 3 (different base types) [..] net/bridge/netfilter/nft_reject_bridge.c:168:52: warning: incorrect type in argument 3 (different base types) [..] net/bridge/netfilter/nft_reject_bridge.c:233:52: warning: incorrect type in argument 3 (different base types) [..] Caused by two (harmless) errors: 1. htons() instead of ntohs() 2. __be16 for protocol in nf_reject_ipXhdr_put API, use u8 instead. Reported-by: kbuild test robot Signed-off-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso --- include/net/netfilter/ipv4/nf_reject.h | 2 +- include/net/netfilter/ipv6/nf_reject.h | 2 +- net/bridge/netfilter/nft_reject_bridge.c | 2 +- net/ipv4/netfilter/nf_reject_ipv4.c | 2 +- net/ipv6/netfilter/nf_reject_ipv6.c | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/net/netfilter/ipv4/nf_reject.h b/include/net/netfilter/ipv4/nf_reject.h index 864127573c32..77862c3645f0 100644 --- a/include/net/netfilter/ipv4/nf_reject.h +++ b/include/net/netfilter/ipv4/nf_reject.h @@ -12,7 +12,7 @@ const struct tcphdr *nf_reject_ip_tcphdr_get(struct sk_buff *oldskb, struct tcphdr *_oth, int hook); struct iphdr *nf_reject_iphdr_put(struct sk_buff *nskb, const struct sk_buff *oldskb, - __be16 protocol, int ttl); + __u8 protocol, int ttl); void nf_reject_ip_tcphdr_put(struct sk_buff *nskb, const struct sk_buff *oldskb, const struct tcphdr *oth); diff --git a/include/net/netfilter/ipv6/nf_reject.h b/include/net/netfilter/ipv6/nf_reject.h index 0ae445d3f217..0ea4fa37db16 100644 --- a/include/net/netfilter/ipv6/nf_reject.h +++ b/include/net/netfilter/ipv6/nf_reject.h @@ -13,7 +13,7 @@ const struct tcphdr *nf_reject_ip6_tcphdr_get(struct sk_buff *oldskb, unsigned int *otcplen, int hook); struct ipv6hdr *nf_reject_ip6hdr_put(struct sk_buff *nskb, const struct sk_buff *oldskb, - __be16 protocol, int hoplimit); + __u8 protocol, int hoplimit); void nf_reject_ip6_tcphdr_put(struct sk_buff *nskb, const struct sk_buff *oldskb, const struct tcphdr *oth, unsigned int otcplen); diff --git a/net/bridge/netfilter/nft_reject_bridge.c b/net/bridge/netfilter/nft_reject_bridge.c index 5c6c96585acd..54a2fdf0f457 100644 --- a/net/bridge/netfilter/nft_reject_bridge.c +++ b/net/bridge/netfilter/nft_reject_bridge.c @@ -99,7 +99,7 @@ static void nft_reject_br_send_v4_unreach(struct sk_buff *oldskb, if (!pskb_may_pull(oldskb, len)) return; - if (pskb_trim_rcsum(oldskb, htons(ip_hdr(oldskb)->tot_len))) + if (pskb_trim_rcsum(oldskb, ntohs(ip_hdr(oldskb)->tot_len))) return; if (ip_hdr(oldskb)->protocol == IPPROTO_TCP || diff --git a/net/ipv4/netfilter/nf_reject_ipv4.c b/net/ipv4/netfilter/nf_reject_ipv4.c index b7405eb7f1ef..c5b794da51a9 100644 --- a/net/ipv4/netfilter/nf_reject_ipv4.c +++ b/net/ipv4/netfilter/nf_reject_ipv4.c @@ -43,7 +43,7 @@ EXPORT_SYMBOL_GPL(nf_reject_ip_tcphdr_get); struct iphdr *nf_reject_iphdr_put(struct sk_buff *nskb, const struct sk_buff *oldskb, - __be16 protocol, int ttl) + __u8 protocol, int ttl) { struct iphdr *niph, *oiph = ip_hdr(oldskb); diff --git a/net/ipv6/netfilter/nf_reject_ipv6.c b/net/ipv6/netfilter/nf_reject_ipv6.c index 68e0bb4db1bf..3afdce03d94e 100644 --- a/net/ipv6/netfilter/nf_reject_ipv6.c +++ b/net/ipv6/netfilter/nf_reject_ipv6.c @@ -65,7 +65,7 @@ EXPORT_SYMBOL_GPL(nf_reject_ip6_tcphdr_get); struct ipv6hdr *nf_reject_ip6hdr_put(struct sk_buff *nskb, const struct sk_buff *oldskb, - __be16 protocol, int hoplimit) + __u8 protocol, int hoplimit) { struct ipv6hdr *ip6h; const struct ipv6hdr *oip6h = ipv6_hdr(oldskb); -- GitLab From 1a4ba64d16a42c1b31d52b671accd7f9103e2626 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Tue, 10 Mar 2015 10:27:18 +0100 Subject: [PATCH 03713/11651] netfilter: bridge: use rcu hook to resolve br_netfilter dependency e5de75b ("netfilter: bridge: move DNAT helper to br_netfilter") results in the following link problem: net/bridge/br_device.c:29: undefined reference to `br_nf_prerouting_finish_bridge` Moreover it creates a hard dependency between br_netfilter and the bridge core, which is what we've been trying to avoid so far. Resolve this problem by using a hook structure so we reduce #ifdef pollution and keep bridge netfilter specific code under br_netfilter.c which was the original intention. Reported-by: Simon Horman Signed-off-by: Pablo Neira Ayuso --- net/bridge/br_device.c | 7 ++++++- net/bridge/br_netfilter.c | 9 +++++++-- net/bridge/br_private.h | 10 +++++----- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index 294cbcc49263..4ff77a16956c 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c @@ -25,6 +25,9 @@ #define COMMON_FEATURES (NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA | \ NETIF_F_GSO_MASK | NETIF_F_HW_CSUM) +const struct nf_br_ops __rcu *nf_br_ops __read_mostly; +EXPORT_SYMBOL_GPL(nf_br_ops); + /* net device transmit always called with BH disabled */ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev) { @@ -33,10 +36,12 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev) struct net_bridge_fdb_entry *dst; struct net_bridge_mdb_entry *mdst; struct pcpu_sw_netstats *brstats = this_cpu_ptr(br->stats); + const struct nf_br_ops *nf_ops; u16 vid = 0; rcu_read_lock(); - if (br_nf_prerouting_finish_bridge(skb)) { + nf_ops = rcu_dereference(nf_br_ops); + if (nf_ops && nf_ops->br_dev_xmit_hook(skb)) { rcu_read_unlock(); return NETDEV_TX_OK; } diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index a8361c7cdf81..b260a97275db 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c @@ -914,7 +914,7 @@ static void br_nf_pre_routing_finish_bridge_slow(struct sk_buff *skb) br_handle_frame_finish(skb); } -int br_nf_prerouting_finish_bridge(struct sk_buff *skb) +static int br_nf_dev_xmit(struct sk_buff *skb) { if (skb->nf_bridge && (skb->nf_bridge->mask & BRNF_BRIDGED_DNAT)) { br_nf_pre_routing_finish_bridge_slow(skb); @@ -922,7 +922,10 @@ int br_nf_prerouting_finish_bridge(struct sk_buff *skb) } return 0; } -EXPORT_SYMBOL_GPL(br_nf_prerouting_finish_bridge); + +static const struct nf_br_ops br_ops = { + .br_dev_xmit_hook = br_nf_dev_xmit, +}; void br_netfilter_enable(void) { @@ -1061,12 +1064,14 @@ static int __init br_netfilter_init(void) return -ENOMEM; } #endif + RCU_INIT_POINTER(nf_br_ops, &br_ops); printk(KERN_NOTICE "Bridge firewalling registered\n"); return 0; } static void __exit br_netfilter_fini(void) { + RCU_INIT_POINTER(nf_br_ops, NULL); nf_unregister_hooks(br_nf_ops, ARRAY_SIZE(br_nf_ops)); #ifdef CONFIG_SYSCTL unregister_net_sysctl_table(brnf_sysctl_header); diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index f0a0438dbd6d..b46fa0c5b8ec 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -763,17 +763,17 @@ static inline int br_vlan_enabled(struct net_bridge *br) } #endif +struct nf_br_ops { + int (*br_dev_xmit_hook)(struct sk_buff *skb); +}; +extern const struct nf_br_ops __rcu *nf_br_ops; + /* br_netfilter.c */ #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) -int br_nf_prerouting_finish_bridge(struct sk_buff *skb); int br_nf_core_init(void); void br_nf_core_fini(void); void br_netfilter_rtable_init(struct net_bridge *); #else -static inline int br_nf_prerouting_finish_bridge(struct sk_buff *skb) -{ - return 0; -} static inline int br_nf_core_init(void) { return 0; } static inline void br_nf_core_fini(void) {} #define br_netfilter_rtable_init(x) -- GitLab From 5b1274efe2a24eb5a85a00cc48c334b1cdfc75aa Mon Sep 17 00:00:00 2001 From: Takashi Sakamoto Date: Tue, 10 Mar 2015 21:58:48 +0900 Subject: [PATCH 03714/11651] Revert "ALSA: dice: fix wrong offsets for Dice interface" This reverts commit 8cdebf71098c07168ef6335e2f1f35d85dbe3049. The reverted commit breaks out-stream functionality of Dice driver. Signed-off-by: Takashi Sakamoto Signed-off-by: Takashi Iwai --- sound/firewire/dice/dice-interface.h | 18 +++++++++--------- sound/firewire/dice/dice-proc.c | 4 ++-- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/sound/firewire/dice/dice-interface.h b/sound/firewire/dice/dice-interface.h index de7602bd69b5..27b044f84c81 100644 --- a/sound/firewire/dice/dice-interface.h +++ b/sound/firewire/dice/dice-interface.h @@ -298,24 +298,24 @@ */ #define RX_ISOCHRONOUS 0x008 +/* + * Index of first quadlet to be interpreted; read/write. If > 0, that many + * quadlets at the beginning of each data block will be ignored, and all the + * audio and MIDI quadlets will follow. + */ +#define RX_SEQ_START 0x00c + /* * The number of audio channels; read-only. There will be one quadlet per * channel. */ -#define RX_NUMBER_AUDIO 0x00c +#define RX_NUMBER_AUDIO 0x010 /* * The number of MIDI ports, 0-8; read-only. If > 0, there will be one * additional quadlet in each data block, following the audio quadlets. */ -#define RX_NUMBER_MIDI 0x010 - -/* - * Index of first quadlet to be interpreted; read/write. If > 0, that many - * quadlets at the beginning of each data block will be ignored, and all the - * audio and MIDI quadlets will follow. - */ -#define RX_SEQ_START 0x014 +#define RX_NUMBER_MIDI 0x014 /* * Names of all audio channels; read-only. Quadlets are byte-swapped. Names diff --git a/sound/firewire/dice/dice-proc.c b/sound/firewire/dice/dice-proc.c index ecfe20fd4de5..f5c1d1bced59 100644 --- a/sound/firewire/dice/dice-proc.c +++ b/sound/firewire/dice/dice-proc.c @@ -99,9 +99,9 @@ static void dice_proc_read(struct snd_info_entry *entry, } tx; struct { u32 iso; + u32 seq_start; u32 number_audio; u32 number_midi; - u32 seq_start; char names[RX_NAMES_SIZE]; u32 ac3_caps; u32 ac3_enable; @@ -204,10 +204,10 @@ static void dice_proc_read(struct snd_info_entry *entry, break; snd_iprintf(buffer, "rx %u:\n", stream); snd_iprintf(buffer, " iso channel: %d\n", (int)buf.rx.iso); + snd_iprintf(buffer, " sequence start: %u\n", buf.rx.seq_start); snd_iprintf(buffer, " audio channels: %u\n", buf.rx.number_audio); snd_iprintf(buffer, " midi ports: %u\n", buf.rx.number_midi); - snd_iprintf(buffer, " sequence start: %u\n", buf.rx.seq_start); if (quadlets >= 68) { dice_proc_fixup_string(buf.rx.names, RX_NAMES_SIZE); snd_iprintf(buffer, " names: %s\n", buf.rx.names); -- GitLab From 59294a01d7037f63fb8bf994af10ce63c618770a Mon Sep 17 00:00:00 2001 From: Takashi Sakamoto Date: Tue, 10 Mar 2015 21:54:35 +0900 Subject: [PATCH 03715/11651] ALSA: firewire-lib: leave unit reference counting completely With previous commit, this module managed to leave the counting to each drivers, but the isochronous resources functionality still increment/decrement the count. This commit purge such codes to leave the responsibility to each drivers. Fix: c6f224dc20ad ('ALSA: firewire-lib: remove reference counting') Signed-off-by: Takashi Sakamoto Signed-off-by: Takashi Iwai --- sound/firewire/iso-resources.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sound/firewire/iso-resources.c b/sound/firewire/iso-resources.c index 5f17b77ee152..f0e4d502d604 100644 --- a/sound/firewire/iso-resources.c +++ b/sound/firewire/iso-resources.c @@ -26,7 +26,7 @@ int fw_iso_resources_init(struct fw_iso_resources *r, struct fw_unit *unit) { r->channels_mask = ~0uLL; - r->unit = fw_unit_get(unit); + r->unit = unit; mutex_init(&r->mutex); r->allocated = false; @@ -42,7 +42,6 @@ void fw_iso_resources_destroy(struct fw_iso_resources *r) { WARN_ON(r->allocated); mutex_destroy(&r->mutex); - fw_unit_put(r->unit); } EXPORT_SYMBOL(fw_iso_resources_destroy); -- GitLab From 4ed56666b7fc98c750a23b5263350b75e742b534 Mon Sep 17 00:00:00 2001 From: Takashi Sakamoto Date: Tue, 10 Mar 2015 22:13:30 +0900 Subject: [PATCH 03716/11651] ALSA: core: use precomputed table to check userspace control params The parameters can be decided in compile time. This commit adds precomputed table to reduce calculating time. Signed-off-by: Takashi Sakamoto Signed-off-by: Takashi Iwai --- sound/core/control.c | 60 +++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 32 deletions(-) diff --git a/sound/core/control.c b/sound/core/control.c index 35324a8e83c8..0b85cbc27e4d 100644 --- a/sound/core/control.c +++ b/sound/core/control.c @@ -1161,6 +1161,23 @@ static void snd_ctl_elem_user_free(struct snd_kcontrol *kcontrol) static int snd_ctl_elem_add(struct snd_ctl_file *file, struct snd_ctl_elem_info *info, int replace) { + /* The capacity of struct snd_ctl_elem_value.value.*/ + static const unsigned int value_sizes[] = { + [SNDRV_CTL_ELEM_TYPE_BOOLEAN] = sizeof(long), + [SNDRV_CTL_ELEM_TYPE_INTEGER] = sizeof(long), + [SNDRV_CTL_ELEM_TYPE_ENUMERATED] = sizeof(unsigned int), + [SNDRV_CTL_ELEM_TYPE_BYTES] = sizeof(unsigned char), + [SNDRV_CTL_ELEM_TYPE_IEC958] = sizeof(struct snd_aes_iec958), + [SNDRV_CTL_ELEM_TYPE_INTEGER64] = sizeof(long long), + }; + static const unsigned int max_value_counts[] = { + [SNDRV_CTL_ELEM_TYPE_BOOLEAN] = 128, + [SNDRV_CTL_ELEM_TYPE_INTEGER] = 128, + [SNDRV_CTL_ELEM_TYPE_ENUMERATED] = 128, + [SNDRV_CTL_ELEM_TYPE_BYTES] = 512, + [SNDRV_CTL_ELEM_TYPE_IEC958] = 1, + [SNDRV_CTL_ELEM_TYPE_INTEGER64] = 64, + }; struct snd_card *card = file->card; struct snd_kcontrol kctl, *_kctl; unsigned int access; @@ -1168,8 +1185,6 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file, struct user_element *ue; int idx, err; - if (info->count < 1) - return -EINVAL; access = info->access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE : (info->access & (SNDRV_CTL_ELEM_ACCESS_READWRITE| SNDRV_CTL_ELEM_ACCESS_INACTIVE| @@ -1201,37 +1216,18 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file, kctl.tlv.c = snd_ctl_elem_user_tlv; access |= SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK; } - switch (info->type) { - case SNDRV_CTL_ELEM_TYPE_BOOLEAN: - case SNDRV_CTL_ELEM_TYPE_INTEGER: - private_size = sizeof(long); - if (info->count > 128) - return -EINVAL; - break; - case SNDRV_CTL_ELEM_TYPE_INTEGER64: - private_size = sizeof(long long); - if (info->count > 64) - return -EINVAL; - break; - case SNDRV_CTL_ELEM_TYPE_ENUMERATED: - private_size = sizeof(unsigned int); - if (info->count > 128 || info->value.enumerated.items == 0) - return -EINVAL; - break; - case SNDRV_CTL_ELEM_TYPE_BYTES: - private_size = sizeof(unsigned char); - if (info->count > 512) - return -EINVAL; - break; - case SNDRV_CTL_ELEM_TYPE_IEC958: - private_size = sizeof(struct snd_aes_iec958); - if (info->count != 1) - return -EINVAL; - break; - default: + + if (info->type < SNDRV_CTL_ELEM_TYPE_BOOLEAN || + info->type > SNDRV_CTL_ELEM_TYPE_INTEGER64) return -EINVAL; - } - private_size *= info->count; + if (info->type == SNDRV_CTL_ELEM_TYPE_ENUMERATED && + info->value.enumerated.items == 0) + return -EINVAL; + if (info->count < 1 || + info->count > max_value_counts[info->type]) + return -EINVAL; + + private_size = value_sizes[info->type] * info->count; ue = kzalloc(sizeof(struct user_element) + private_size, GFP_KERNEL); if (ue == NULL) return -ENOMEM; -- GitLab From 2225e79b9b0370bc179f44756bee809b5e7b4d06 Mon Sep 17 00:00:00 2001 From: Takashi Sakamoto Date: Tue, 10 Mar 2015 22:13:31 +0900 Subject: [PATCH 03717/11651] ALSA: core: reduce stack usage related to snd_ctl_new() The callers of snd_ctl_new() need to have 'struct snd_kcontrol' data, and pass the data as template. Then, the function allocates the structure data again and copy from the template. This is a waste of resources. Especially, the callers use large stack for the template. This commit removes a need of template for the function, thus, changes the prototype of snd_ctl_new(). Furthermore, this commit changes the code of callers, snd_ctl_new1() and snd_ctl_elem_add() for better shape. Signed-off-by: Takashi Sakamoto Signed-off-by: Takashi Iwai --- sound/core/control.c | 213 ++++++++++++++++++++++++++----------------- 1 file changed, 130 insertions(+), 83 deletions(-) diff --git a/sound/core/control.c b/sound/core/control.c index 0b85cbc27e4d..e1d8e0c816f0 100644 --- a/sound/core/control.c +++ b/sound/core/control.c @@ -192,36 +192,43 @@ void snd_ctl_notify(struct snd_card *card, unsigned int mask, EXPORT_SYMBOL(snd_ctl_notify); /** - * snd_ctl_new - create a control instance from the template - * @control: the control template - * @access: the default control access + * snd_ctl_new - create a new control instance with some elements + * @kctl: the pointer to store new control instance + * @count: the number of elements in this control + * @access: the default access flags for elements in this control + * @file: given when locking these elements * - * Allocates a new struct snd_kcontrol instance and copies the given template - * to the new instance. It does not copy volatile data (access). + * Allocates a memory object for a new control instance. The instance has + * elements as many as the given number (@count). Each element has given + * access permissions (@access). Each element is locked when @file is given. * - * Return: The pointer of the new instance, or %NULL on failure. + * Return: 0 on success, error code on failure */ -static struct snd_kcontrol *snd_ctl_new(struct snd_kcontrol *control, - unsigned int access) +static int snd_ctl_new(struct snd_kcontrol **kctl, unsigned int count, + unsigned int access, struct snd_ctl_file *file) { - struct snd_kcontrol *kctl; + unsigned int size; unsigned int idx; - if (snd_BUG_ON(!control || !control->count)) - return NULL; + if (count == 0 || count > MAX_CONTROL_COUNT) + return -EINVAL; - if (control->count > MAX_CONTROL_COUNT) - return NULL; + size = sizeof(struct snd_kcontrol); + size += sizeof(struct snd_kcontrol_volatile) * count; - kctl = kzalloc(sizeof(*kctl) + sizeof(struct snd_kcontrol_volatile) * control->count, GFP_KERNEL); - if (kctl == NULL) { + *kctl = kzalloc(size, GFP_KERNEL); + if (*kctl == NULL) { pr_err("ALSA: Cannot allocate control instance\n"); - return NULL; + return -ENOMEM; } - *kctl = *control; - for (idx = 0; idx < kctl->count; idx++) - kctl->vd[idx].access = access; - return kctl; + + for (idx = 0; idx < count; idx++) { + (*kctl)->vd[idx].access = access; + (*kctl)->vd[idx].owner = file; + } + (*kctl)->count = count; + + return 0; } /** @@ -238,37 +245,53 @@ static struct snd_kcontrol *snd_ctl_new(struct snd_kcontrol *control, struct snd_kcontrol *snd_ctl_new1(const struct snd_kcontrol_new *ncontrol, void *private_data) { - struct snd_kcontrol kctl; + struct snd_kcontrol *kctl; + unsigned int count; unsigned int access; + int err; if (snd_BUG_ON(!ncontrol || !ncontrol->info)) return NULL; - memset(&kctl, 0, sizeof(kctl)); - kctl.id.iface = ncontrol->iface; - kctl.id.device = ncontrol->device; - kctl.id.subdevice = ncontrol->subdevice; + + count = ncontrol->count; + if (count == 0) + count = 1; + + access = ncontrol->access; + if (access == 0) + access = SNDRV_CTL_ELEM_ACCESS_READWRITE; + access &= (SNDRV_CTL_ELEM_ACCESS_READWRITE | + SNDRV_CTL_ELEM_ACCESS_VOLATILE | + SNDRV_CTL_ELEM_ACCESS_INACTIVE | + SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE | + SNDRV_CTL_ELEM_ACCESS_TLV_COMMAND | + SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK); + + err = snd_ctl_new(&kctl, count, access, NULL); + if (err < 0) + return NULL; + + /* The 'numid' member is decided when calling snd_ctl_add(). */ + kctl->id.iface = ncontrol->iface; + kctl->id.device = ncontrol->device; + kctl->id.subdevice = ncontrol->subdevice; if (ncontrol->name) { - strlcpy(kctl.id.name, ncontrol->name, sizeof(kctl.id.name)); - if (strcmp(ncontrol->name, kctl.id.name) != 0) + strlcpy(kctl->id.name, ncontrol->name, sizeof(kctl->id.name)); + if (strcmp(ncontrol->name, kctl->id.name) != 0) pr_warn("ALSA: Control name '%s' truncated to '%s'\n", - ncontrol->name, kctl.id.name); + ncontrol->name, kctl->id.name); } - kctl.id.index = ncontrol->index; - kctl.count = ncontrol->count ? ncontrol->count : 1; - access = ncontrol->access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE : - (ncontrol->access & (SNDRV_CTL_ELEM_ACCESS_READWRITE| - SNDRV_CTL_ELEM_ACCESS_VOLATILE| - SNDRV_CTL_ELEM_ACCESS_INACTIVE| - SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE| - SNDRV_CTL_ELEM_ACCESS_TLV_COMMAND| - SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK)); - kctl.info = ncontrol->info; - kctl.get = ncontrol->get; - kctl.put = ncontrol->put; - kctl.tlv.p = ncontrol->tlv.p; - kctl.private_value = ncontrol->private_value; - kctl.private_data = private_data; - return snd_ctl_new(&kctl, access); + kctl->id.index = ncontrol->index; + + kctl->info = ncontrol->info; + kctl->get = ncontrol->get; + kctl->put = ncontrol->put; + kctl->tlv.p = ncontrol->tlv.p; + + kctl->private_value = ncontrol->private_value; + kctl->private_data = private_data; + + return kctl; } EXPORT_SYMBOL(snd_ctl_new1); @@ -1179,44 +1202,48 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file, [SNDRV_CTL_ELEM_TYPE_INTEGER64] = 64, }; struct snd_card *card = file->card; - struct snd_kcontrol kctl, *_kctl; + struct snd_kcontrol *kctl; + unsigned int count; unsigned int access; long private_size; struct user_element *ue; - int idx, err; - - access = info->access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE : - (info->access & (SNDRV_CTL_ELEM_ACCESS_READWRITE| - SNDRV_CTL_ELEM_ACCESS_INACTIVE| - SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE)); - info->id.numid = 0; - memset(&kctl, 0, sizeof(kctl)); + int err; + /* Delete a control to replace them if needed. */ if (replace) { + info->id.numid = 0; err = snd_ctl_remove_user_ctl(file, &info->id); if (err) return err; } - if (card->user_ctl_count >= MAX_USER_CONTROLS) + /* + * The number of userspace controls are counted control by control, + * not element by element. + */ + if (card->user_ctl_count + 1 > MAX_USER_CONTROLS) return -ENOMEM; - memcpy(&kctl.id, &info->id, sizeof(info->id)); - kctl.count = info->owner ? info->owner : 1; - access |= SNDRV_CTL_ELEM_ACCESS_USER; - if (info->type == SNDRV_CTL_ELEM_TYPE_ENUMERATED) - kctl.info = snd_ctl_elem_user_enum_info; - else - kctl.info = snd_ctl_elem_user_info; - if (access & SNDRV_CTL_ELEM_ACCESS_READ) - kctl.get = snd_ctl_elem_user_get; - if (access & SNDRV_CTL_ELEM_ACCESS_WRITE) - kctl.put = snd_ctl_elem_user_put; - if (access & SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE) { - kctl.tlv.c = snd_ctl_elem_user_tlv; + /* Check the number of elements for this userspace control. */ + count = info->owner; + if (count == 0) + count = 1; + + /* Arrange access permissions if needed. */ + access = info->access; + if (access == 0) + access = SNDRV_CTL_ELEM_ACCESS_READWRITE; + access &= (SNDRV_CTL_ELEM_ACCESS_READWRITE | + SNDRV_CTL_ELEM_ACCESS_INACTIVE | + SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE); + if (access & SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE) access |= SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK; - } + access |= SNDRV_CTL_ELEM_ACCESS_USER; + /* + * Check information and calculate the size of data specific to + * this userspace control. + */ if (info->type < SNDRV_CTL_ELEM_TYPE_BOOLEAN || info->type > SNDRV_CTL_ELEM_TYPE_INTEGER64) return -EINVAL; @@ -1226,11 +1253,27 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file, if (info->count < 1 || info->count > max_value_counts[info->type]) return -EINVAL; - private_size = value_sizes[info->type] * info->count; - ue = kzalloc(sizeof(struct user_element) + private_size, GFP_KERNEL); - if (ue == NULL) + + /* + * Keep memory object for this userspace control. After passing this + * code block, the instance should be freed by snd_ctl_free_one(). + * + * Note that these elements in this control are locked. + */ + err = snd_ctl_new(&kctl, count, access, file); + if (err < 0) + return err; + kctl->private_data = kzalloc(sizeof(struct user_element) + private_size, + GFP_KERNEL); + if (kctl->private_data == NULL) { + kfree(kctl); return -ENOMEM; + } + kctl->private_free = snd_ctl_elem_user_free; + + /* Set private data for this userspace control. */ + ue = (struct user_element *)kctl->private_data; ue->card = card; ue->info = *info; ue->info.access = 0; @@ -1239,21 +1282,25 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file, if (ue->info.type == SNDRV_CTL_ELEM_TYPE_ENUMERATED) { err = snd_ctl_elem_init_enum_names(ue); if (err < 0) { - kfree(ue); + snd_ctl_free_one(kctl); return err; } } - kctl.private_free = snd_ctl_elem_user_free; - _kctl = snd_ctl_new(&kctl, access); - if (_kctl == NULL) { - kfree(ue->priv_data); - kfree(ue); - return -ENOMEM; - } - _kctl->private_data = ue; - for (idx = 0; idx < _kctl->count; idx++) - _kctl->vd[idx].owner = file; - err = snd_ctl_add(card, _kctl); + + /* Set callback functions. */ + if (info->type == SNDRV_CTL_ELEM_TYPE_ENUMERATED) + kctl->info = snd_ctl_elem_user_enum_info; + else + kctl->info = snd_ctl_elem_user_info; + if (access & SNDRV_CTL_ELEM_ACCESS_READ) + kctl->get = snd_ctl_elem_user_get; + if (access & SNDRV_CTL_ELEM_ACCESS_WRITE) + kctl->put = snd_ctl_elem_user_put; + if (access & SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE) + kctl->tlv.c = snd_ctl_elem_user_tlv; + + /* This function manage to free the instance on failure. */ + err = snd_ctl_add(card, kctl); if (err < 0) return err; -- GitLab From 8d98a0673f761f9b7be51a293ca9142ec0c037ca Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 10 Mar 2015 15:39:55 +0100 Subject: [PATCH 03718/11651] ALSA: seq_oss: Drop superfluous error/debug messages after malloc failures The kernel memory allocators already report the errors when the requested allocation fails, thus we don't need to warn it again in each caller side. Signed-off-by: Takashi Iwai --- sound/core/seq/oss/seq_oss_init.c | 4 +--- sound/core/seq/oss/seq_oss_midi.c | 5 ++--- sound/core/seq/oss/seq_oss_readq.c | 9 ++++----- sound/core/seq/oss/seq_oss_synth.c | 6 ++---- 4 files changed, 9 insertions(+), 15 deletions(-) diff --git a/sound/core/seq/oss/seq_oss_init.c b/sound/core/seq/oss/seq_oss_init.c index b0e32e161dd1..2de3feff70d0 100644 --- a/sound/core/seq/oss/seq_oss_init.c +++ b/sound/core/seq/oss/seq_oss_init.c @@ -188,10 +188,8 @@ snd_seq_oss_open(struct file *file, int level) struct seq_oss_devinfo *dp; dp = kzalloc(sizeof(*dp), GFP_KERNEL); - if (!dp) { - pr_err("ALSA: seq_oss: can't malloc device info\n"); + if (!dp) return -ENOMEM; - } dp->cseq = system_client; dp->port = -1; diff --git a/sound/core/seq/oss/seq_oss_midi.c b/sound/core/seq/oss/seq_oss_midi.c index e79cc44b1394..96e8395ae586 100644 --- a/sound/core/seq/oss/seq_oss_midi.c +++ b/sound/core/seq/oss/seq_oss_midi.c @@ -173,10 +173,9 @@ snd_seq_oss_midi_check_new_port(struct snd_seq_port_info *pinfo) /* * allocate midi info record */ - if ((mdev = kzalloc(sizeof(*mdev), GFP_KERNEL)) == NULL) { - pr_err("ALSA: seq_oss: can't malloc midi info\n"); + mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); + if (!mdev) return -ENOMEM; - } /* copy the port information */ mdev->client = pinfo->addr.client; diff --git a/sound/core/seq/oss/seq_oss_readq.c b/sound/core/seq/oss/seq_oss_readq.c index 654d17a5023c..c080c73cea04 100644 --- a/sound/core/seq/oss/seq_oss_readq.c +++ b/sound/core/seq/oss/seq_oss_readq.c @@ -47,13 +47,12 @@ snd_seq_oss_readq_new(struct seq_oss_devinfo *dp, int maxlen) { struct seq_oss_readq *q; - if ((q = kzalloc(sizeof(*q), GFP_KERNEL)) == NULL) { - pr_err("ALSA: seq_oss: can't malloc read queue\n"); + q = kzalloc(sizeof(*q), GFP_KERNEL); + if (!q) return NULL; - } - if ((q->q = kcalloc(maxlen, sizeof(union evrec), GFP_KERNEL)) == NULL) { - pr_err("ALSA: seq_oss: can't malloc read queue buffer\n"); + q->q = kcalloc(maxlen, sizeof(union evrec), GFP_KERNEL); + if (!q->q) { kfree(q); return NULL; } diff --git a/sound/core/seq/oss/seq_oss_synth.c b/sound/core/seq/oss/seq_oss_synth.c index 835edc80f918..48e4fe1b68ab 100644 --- a/sound/core/seq/oss/seq_oss_synth.c +++ b/sound/core/seq/oss/seq_oss_synth.c @@ -106,10 +106,9 @@ snd_seq_oss_synth_probe(struct device *_dev) struct snd_seq_oss_reg *reg = SNDRV_SEQ_DEVICE_ARGPTR(dev); unsigned long flags; - if ((rec = kzalloc(sizeof(*rec), GFP_KERNEL)) == NULL) { - pr_err("ALSA: seq_oss: can't malloc synth info\n"); + rec = kzalloc(sizeof(*rec), GFP_KERNEL); + if (!rec) return -ENOMEM; - } rec->seq_device = -1; rec->synth_type = reg->type; rec->synth_subtype = reg->subtype; @@ -249,7 +248,6 @@ snd_seq_oss_synth_setup(struct seq_oss_devinfo *dp) if (info->nr_voices > 0) { info->ch = kcalloc(info->nr_voices, sizeof(struct seq_oss_chinfo), GFP_KERNEL); if (!info->ch) { - pr_err("ALSA: seq_oss: Cannot malloc voices\n"); rec->oper.close(&info->arg); module_put(rec->oper.owner); snd_use_lock_free(&rec->use_lock); -- GitLab From 24db8bbaa3fcfaf0c2faccbff5864b58088ac1f6 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 10 Mar 2015 15:41:18 +0100 Subject: [PATCH 03719/11651] ALSA: seq: Drop superfluous error/debug messages after malloc failures The kernel memory allocators already report the errors when the requested allocation fails, thus we don't need to warn it again in each caller side. Signed-off-by: Takashi Iwai --- sound/core/seq/seq_fifo.c | 4 +--- sound/core/seq/seq_memory.c | 8 ++------ sound/core/seq/seq_ports.c | 4 +--- sound/core/seq/seq_prioq.c | 4 +--- sound/core/seq/seq_queue.c | 4 +--- sound/core/seq/seq_timer.c | 4 +--- 6 files changed, 7 insertions(+), 21 deletions(-) diff --git a/sound/core/seq/seq_fifo.c b/sound/core/seq/seq_fifo.c index 53a403e17c5b..1d5acbe0c08b 100644 --- a/sound/core/seq/seq_fifo.c +++ b/sound/core/seq/seq_fifo.c @@ -33,10 +33,8 @@ struct snd_seq_fifo *snd_seq_fifo_new(int poolsize) struct snd_seq_fifo *f; f = kzalloc(sizeof(*f), GFP_KERNEL); - if (f == NULL) { - pr_debug("ALSA: seq: malloc failed for snd_seq_fifo_new() \n"); + if (!f) return NULL; - } f->pool = snd_seq_pool_new(poolsize); if (f->pool == NULL) { diff --git a/sound/core/seq/seq_memory.c b/sound/core/seq/seq_memory.c index ba8e4a64e13e..801076687bb1 100644 --- a/sound/core/seq/seq_memory.c +++ b/sound/core/seq/seq_memory.c @@ -387,10 +387,8 @@ int snd_seq_pool_init(struct snd_seq_pool *pool) return 0; pool->ptr = vmalloc(sizeof(struct snd_seq_event_cell) * pool->size); - if (pool->ptr == NULL) { - pr_debug("ALSA: seq: malloc for sequencer events failed\n"); + if (!pool->ptr) return -ENOMEM; - } /* add new cells to the free cell list */ spin_lock_irqsave(&pool->lock, flags); @@ -463,10 +461,8 @@ struct snd_seq_pool *snd_seq_pool_new(int poolsize) /* create pool block */ pool = kzalloc(sizeof(*pool), GFP_KERNEL); - if (pool == NULL) { - pr_debug("ALSA: seq: malloc failed for pool\n"); + if (!pool) return NULL; - } spin_lock_init(&pool->lock); pool->ptr = NULL; pool->free = NULL; diff --git a/sound/core/seq/seq_ports.c b/sound/core/seq/seq_ports.c index 46ff593f618d..55170a20ae72 100644 --- a/sound/core/seq/seq_ports.c +++ b/sound/core/seq/seq_ports.c @@ -141,10 +141,8 @@ struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client, /* create a new port */ new_port = kzalloc(sizeof(*new_port), GFP_KERNEL); - if (! new_port) { - pr_debug("ALSA: seq: malloc failed for registering client port\n"); + if (!new_port) return NULL; /* failure, out of memory */ - } /* init port data */ new_port->addr.client = client->number; new_port->addr.port = -1; diff --git a/sound/core/seq/seq_prioq.c b/sound/core/seq/seq_prioq.c index 021b02bc9330..bc1c8488fc2a 100644 --- a/sound/core/seq/seq_prioq.c +++ b/sound/core/seq/seq_prioq.c @@ -59,10 +59,8 @@ struct snd_seq_prioq *snd_seq_prioq_new(void) struct snd_seq_prioq *f; f = kzalloc(sizeof(*f), GFP_KERNEL); - if (f == NULL) { - pr_debug("ALSA: seq: malloc failed for snd_seq_prioq_new()\n"); + if (!f) return NULL; - } spin_lock_init(&f->lock); f->head = NULL; diff --git a/sound/core/seq/seq_queue.c b/sound/core/seq/seq_queue.c index aad4878cee55..a0cda38205b9 100644 --- a/sound/core/seq/seq_queue.c +++ b/sound/core/seq/seq_queue.c @@ -111,10 +111,8 @@ static struct snd_seq_queue *queue_new(int owner, int locked) struct snd_seq_queue *q; q = kzalloc(sizeof(*q), GFP_KERNEL); - if (q == NULL) { - pr_debug("ALSA: seq: malloc failed for snd_seq_queue_new()\n"); + if (!q) return NULL; - } spin_lock_init(&q->owner_lock); spin_lock_init(&q->check_lock); diff --git a/sound/core/seq/seq_timer.c b/sound/core/seq/seq_timer.c index e73605393eee..186f1611103c 100644 --- a/sound/core/seq/seq_timer.c +++ b/sound/core/seq/seq_timer.c @@ -56,10 +56,8 @@ struct snd_seq_timer *snd_seq_timer_new(void) struct snd_seq_timer *tmr; tmr = kzalloc(sizeof(*tmr), GFP_KERNEL); - if (tmr == NULL) { - pr_debug("ALSA: seq: malloc failed for snd_seq_timer_new() \n"); + if (!tmr) return NULL; - } spin_lock_init(&tmr->lock); /* reset setup to defaults */ -- GitLab From ec0e9937aaa8b0a4b0633711c4d70d622acd9a7f Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 10 Mar 2015 15:42:14 +0100 Subject: [PATCH 03720/11651] ALSA: core: Drop superfluous error/debug messages after malloc failures The kernel memory allocators already report the errors when the requested allocation fails, thus we don't need to warn it again in each caller side. Signed-off-by: Takashi Iwai --- sound/core/control.c | 4 +--- sound/core/device.c | 4 +--- sound/core/hwdep.c | 4 +--- sound/core/oss/mixer_oss.c | 4 +--- sound/core/oss/pcm_oss.c | 1 - sound/core/pcm.c | 13 +++---------- sound/core/rawmidi.c | 8 ++------ sound/core/timer.c | 4 +--- 8 files changed, 10 insertions(+), 32 deletions(-) diff --git a/sound/core/control.c b/sound/core/control.c index e1d8e0c816f0..833b223a363a 100644 --- a/sound/core/control.c +++ b/sound/core/control.c @@ -217,10 +217,8 @@ static int snd_ctl_new(struct snd_kcontrol **kctl, unsigned int count, size += sizeof(struct snd_kcontrol_volatile) * count; *kctl = kzalloc(size, GFP_KERNEL); - if (*kctl == NULL) { - pr_err("ALSA: Cannot allocate control instance\n"); + if (!*kctl) return -ENOMEM; - } for (idx = 0; idx < count; idx++) { (*kctl)->vd[idx].access = access; diff --git a/sound/core/device.c b/sound/core/device.c index 41bec3075ae5..c1a845b42a8b 100644 --- a/sound/core/device.c +++ b/sound/core/device.c @@ -50,10 +50,8 @@ int snd_device_new(struct snd_card *card, enum snd_device_type type, if (snd_BUG_ON(!card || !device_data || !ops)) return -ENXIO; dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (dev == NULL) { - dev_err(card->dev, "Cannot allocate device, type=%d\n", type); + if (!dev) return -ENOMEM; - } INIT_LIST_HEAD(&dev->list); dev->card = card; dev->type = type; diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c index 84244a5143cf..51692c8a39ea 100644 --- a/sound/core/hwdep.c +++ b/sound/core/hwdep.c @@ -378,10 +378,8 @@ int snd_hwdep_new(struct snd_card *card, char *id, int device, if (rhwdep) *rhwdep = NULL; hwdep = kzalloc(sizeof(*hwdep), GFP_KERNEL); - if (hwdep == NULL) { - dev_err(card->dev, "hwdep: cannot allocate\n"); + if (!hwdep) return -ENOMEM; - } init_waitqueue_head(&hwdep->open_wait); mutex_init(&hwdep->open_mutex); diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c index 5e6349f00ecd..056f8e274851 100644 --- a/sound/core/oss/mixer_oss.c +++ b/sound/core/oss/mixer_oss.c @@ -1212,10 +1212,8 @@ static void snd_mixer_oss_proc_write(struct snd_info_entry *entry, /* not changed */ goto __unlock; tbl = kmalloc(sizeof(*tbl), GFP_KERNEL); - if (! tbl) { - pr_err("ALSA: mixer_oss: no memory\n"); + if (!tbl) goto __unlock; - } tbl->oss_id = ch; tbl->name = kstrdup(str, GFP_KERNEL); if (! tbl->name) { diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c index 80423a4ccab6..58550cc93f28 100644 --- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c @@ -854,7 +854,6 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream) params = kmalloc(sizeof(*params), GFP_KERNEL); sparams = kmalloc(sizeof(*sparams), GFP_KERNEL); if (!sw_params || !params || !sparams) { - pcm_dbg(substream->pcm, "No memory\n"); err = -ENOMEM; goto failure; } diff --git a/sound/core/pcm.c b/sound/core/pcm.c index e9b87465c73d..b25bcf5b8644 100644 --- a/sound/core/pcm.c +++ b/sound/core/pcm.c @@ -343,11 +343,8 @@ static void snd_pcm_proc_info_read(struct snd_pcm_substream *substream, return; info = kmalloc(sizeof(*info), GFP_KERNEL); - if (! info) { - pcm_dbg(substream->pcm, - "snd_pcm_proc_info_read: cannot malloc\n"); + if (!info) return; - } err = snd_pcm_info(substream, info); if (err < 0) { @@ -717,10 +714,8 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count) prev = NULL; for (idx = 0, prev = NULL; idx < substream_count; idx++) { substream = kzalloc(sizeof(*substream), GFP_KERNEL); - if (substream == NULL) { - pcm_err(pcm, "Cannot allocate PCM substream\n"); + if (!substream) return -ENOMEM; - } substream->pcm = pcm; substream->pstr = pstr; substream->number = idx; @@ -774,10 +769,8 @@ static int _snd_pcm_new(struct snd_card *card, const char *id, int device, if (rpcm) *rpcm = NULL; pcm = kzalloc(sizeof(*pcm), GFP_KERNEL); - if (pcm == NULL) { - dev_err(card->dev, "Cannot allocate PCM\n"); + if (!pcm) return -ENOMEM; - } pcm->card = card; pcm->device = device; pcm->internal = internal; diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c index b5a748596fc4..a7759846fbaa 100644 --- a/sound/core/rawmidi.c +++ b/sound/core/rawmidi.c @@ -1429,10 +1429,8 @@ static int snd_rawmidi_alloc_substreams(struct snd_rawmidi *rmidi, for (idx = 0; idx < count; idx++) { substream = kzalloc(sizeof(*substream), GFP_KERNEL); - if (substream == NULL) { - rmidi_err(rmidi, "rawmidi: cannot allocate substream\n"); + if (!substream) return -ENOMEM; - } substream->stream = direction; substream->number = idx; substream->rmidi = rmidi; @@ -1479,10 +1477,8 @@ int snd_rawmidi_new(struct snd_card *card, char *id, int device, if (rrawmidi) *rrawmidi = NULL; rmidi = kzalloc(sizeof(*rmidi), GFP_KERNEL); - if (rmidi == NULL) { - dev_err(card->dev, "rawmidi: cannot allocate\n"); + if (!rmidi) return -ENOMEM; - } rmidi->card = card; rmidi->device = device; mutex_init(&rmidi->open_mutex); diff --git a/sound/core/timer.c b/sound/core/timer.c index 490b489d713d..a9a1a047c521 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -774,10 +774,8 @@ int snd_timer_new(struct snd_card *card, char *id, struct snd_timer_id *tid, if (rtimer) *rtimer = NULL; timer = kzalloc(sizeof(*timer), GFP_KERNEL); - if (timer == NULL) { - pr_err("ALSA: timer: cannot allocate\n"); + if (!timer) return -ENOMEM; - } timer->tmr_class = tid->dev_class; timer->card = card; timer->tmr_device = tid->device; -- GitLab From c97df7c2c0692ebed4eff9abaf61a8e12cc250ed Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Tue, 10 Mar 2015 14:15:36 +0530 Subject: [PATCH 03721/11651] staging: sm750fb: remove pragma optimize remove use of #pragma optimize which will usually be ignored by the compiler. Signed-off-by: Sudip Mukherjee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sm750fb/ddk750_swi2c.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/staging/sm750fb/ddk750_swi2c.c b/drivers/staging/sm750fb/ddk750_swi2c.c index b53407bb2042..cae6b9bc6472 100644 --- a/drivers/staging/sm750fb/ddk750_swi2c.c +++ b/drivers/staging/sm750fb/ddk750_swi2c.c @@ -217,8 +217,6 @@ static unsigned char swI2CReadSDA(void) return 0; } -#pragma optimize( "", off ) - /* * This function sends ACK signal */ @@ -356,7 +354,6 @@ unsigned char swI2CReadByte(unsigned char ack) return data; } -#pragma optimize( "", on ) /* * This function initializes GPIO port for SW I2C communication. -- GitLab From 62fa8e1014f0ca6abd4ec0e9cfcaeb6e6601bbb6 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Tue, 10 Mar 2015 14:15:37 +0530 Subject: [PATCH 03722/11651] staging: sm750fb: correctly define SM750LE_REVISION_ID check if it is already defined before defining SM750LE_REVISION_ID again and at the same time mention correct data type. Signed-off-by: Sudip Mukherjee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sm750fb/ddk750_chip.h | 4 +++- drivers/staging/sm750fb/sm750_hw.c | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/staging/sm750fb/ddk750_chip.h b/drivers/staging/sm750fb/ddk750_chip.h index 1c7887512b69..d761b722556f 100644 --- a/drivers/staging/sm750fb/ddk750_chip.h +++ b/drivers/staging/sm750fb/ddk750_chip.h @@ -1,7 +1,9 @@ #ifndef DDK750_CHIP_H__ #define DDK750_CHIP_H__ #define DEFAULT_INPUT_CLOCK 14318181 /* Default reference clock */ -#define SM750LE_REVISION_ID (char)0xfe +#ifndef SM750LE_REVISION_ID +#define SM750LE_REVISION_ID ((unsigned char)0xfe) +#endif /* This is all the chips recognized by this library */ typedef enum _logical_chip_type_t diff --git a/drivers/staging/sm750fb/sm750_hw.c b/drivers/staging/sm750fb/sm750_hw.c index ec2d49959072..a2b7fe219594 100644 --- a/drivers/staging/sm750fb/sm750_hw.c +++ b/drivers/staging/sm750fb/sm750_hw.c @@ -277,7 +277,7 @@ int hw_sm750_crtc_checkMode(struct lynxfb_crtc* crtc,struct fb_var_screeninfo* v case 16: break; case 32: - if(share->revid == (unsigned char)SM750LE_REVISION_ID){ + if (share->revid == SM750LE_REVISION_ID) { pr_debug("750le do not support 32bpp\n"); return -EINVAL; } -- GitLab From 848f2fce7b2713d853eaa7f32b31bb9ffe89e2ce Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Tue, 10 Mar 2015 14:15:38 +0530 Subject: [PATCH 03723/11651] staging: sm750fb: fix undeclared function kbuild test robot reported that for microblaze-allyesconfig chan_to_field() and lynxfb_ops_set_par() were not defined. These two functions were defined under CONFIG_PM, so for any archtecture if CONFIG_PM is not defined we will have this error. while moving the lynxfb_suspend() function some very obvious checkpatch errors, like space after comma, space after if, space before opening brace, were taken care of. Reported-by: kbuild test robot Signed-off-by: Sudip Mukherjee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sm750fb/sm750.c | 110 +++++++++++++++----------------- 1 file changed, 53 insertions(+), 57 deletions(-) diff --git a/drivers/staging/sm750fb/sm750.c b/drivers/staging/sm750fb/sm750.c index 753869e3686d..476dc5c02dc2 100644 --- a/drivers/staging/sm750fb/sm750.c +++ b/drivers/staging/sm750fb/sm750.c @@ -303,62 +303,6 @@ static int lynxfb_ops_pan_display(struct fb_var_screeninfo *var, return ret; } - - - -#ifdef CONFIG_PM -static int lynxfb_suspend(struct pci_dev * pdev,pm_message_t mesg) -{ - struct fb_info * info; - struct lynx_share * share; - int ret; - - - if(mesg.event == pdev->dev.power.power_state.event) - return 0; - - ret = 0; - share = pci_get_drvdata(pdev); - switch (mesg.event) { - case PM_EVENT_FREEZE: - case PM_EVENT_PRETHAW: - pdev->dev.power.power_state = mesg; - return 0; - } - - console_lock(); - if (mesg.event & PM_EVENT_SLEEP) { - info = share->fbinfo[0]; - if(info) - fb_set_suspend(info, 1);/* 1 means do suspend*/ - - info = share->fbinfo[1]; - if(info) - fb_set_suspend(info, 1);/* 1 means do suspend*/ - - ret = pci_save_state(pdev); - if(ret){ - pr_err("error:%d occured in pci_save_state\n",ret); - return ret; - } - - /* set chip to sleep mode */ - if(share->suspend) - (*share->suspend)(share); - - pci_disable_device(pdev); - ret = pci_set_power_state(pdev,pci_choose_state(pdev,mesg)); - if(ret){ - pr_err("error:%d occured in pci_set_power_state\n",ret); - return ret; - } - } - - pdev->dev.power.power_state = mesg; - console_unlock(); - return ret; -} - static int lynxfb_ops_set_par(struct fb_info * info) { struct lynxfb_par * par; @@ -369,7 +313,6 @@ static int lynxfb_ops_set_par(struct fb_info * info) struct fb_fix_screeninfo * fix; int ret; unsigned int line_length; - if(!info) return -EINVAL; @@ -441,6 +384,7 @@ static int lynxfb_ops_set_par(struct fb_info * info) ret = output->proc_setMode(output,var,fix); return ret; } + static inline unsigned int chan_to_field(unsigned int chan,struct fb_bitfield * bf) { chan &= 0xffff; @@ -448,6 +392,58 @@ static inline unsigned int chan_to_field(unsigned int chan,struct fb_bitfield * return chan << bf->offset; } +#ifdef CONFIG_PM +static int lynxfb_suspend(struct pci_dev *pdev, pm_message_t mesg) +{ + struct fb_info *info; + struct lynx_share *share; + int ret; + + if (mesg.event == pdev->dev.power.power_state.event) + return 0; + + ret = 0; + share = pci_get_drvdata(pdev); + switch (mesg.event) { + case PM_EVENT_FREEZE: + case PM_EVENT_PRETHAW: + pdev->dev.power.power_state = mesg; + return 0; + } + + console_lock(); + if (mesg.event & PM_EVENT_SLEEP) { + info = share->fbinfo[0]; + if (info) + /* 1 means do suspend*/ + fb_set_suspend(info, 1); + info = share->fbinfo[1]; + if (info) + /* 1 means do suspend*/ + fb_set_suspend(info, 1); + + ret = pci_save_state(pdev); + if (ret) { + pr_err("error:%d occurred in pci_save_state\n", ret); + return ret; + } + + /* set chip to sleep mode*/ + if (share->suspend) + (*share->suspend)(share); + + pci_disable_device(pdev); + ret = pci_set_power_state(pdev, pci_choose_state(pdev, mesg)); + if (ret) { + pr_err("error:%d occurred in pci_set_power_state\n", ret); + return ret; + } + } + + pdev->dev.power.power_state = mesg; + console_unlock(); + return ret; +} static int lynxfb_resume(struct pci_dev* pdev) { -- GitLab From 5c7784b9d64027145ce4dee2b488c8c11af732cc Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Tue, 10 Mar 2015 14:15:39 +0530 Subject: [PATCH 03724/11651] staging: sm750fb: fix build failure for powerpc-allyesconfig build failed with an error of g_option undeclared. we will get this error on all architecture if MODULE is not defined. fixed the declaration of g_option. Reported-by: Stephen Rothwell Signed-off-by: Sudip Mukherjee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sm750fb/sm750.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/sm750fb/sm750.c b/drivers/staging/sm750fb/sm750.c index 476dc5c02dc2..8c260ee5597d 100644 --- a/drivers/staging/sm750fb/sm750.c +++ b/drivers/staging/sm750fb/sm750.c @@ -54,9 +54,7 @@ static const char * g_fbmode[] = {NULL,NULL}; static const char * g_def_fbmode = "800x600-16@60"; static char * g_settings = NULL; static int g_dualview = 0; -#ifdef MODULE static char * g_option = NULL; -#endif /* if not use spin_lock,system will die if user load driver * and immediatly unload driver frequently (dual)*/ -- GitLab From 2fa645cb2703d9b3786d850db815414dfeefa51d Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sun, 1 Mar 2015 12:21:22 -0500 Subject: [PATCH 03725/11651] of: Fix premature bootconsole disable with 'stdout-path' Support for devicetree serial consoles via 'stdout-path' causes bootconsoles to be disabled when the vt dummy console loads, since there is no preferred console (the preferred console is not added until the device is probed). Ensure there is at least a preferred console, even if never matched. Requires: "console: Fix console name size mismatch" Cc: Andrew Morton Signed-off-by: Peter Hurley Signed-off-by: Rob Herring --- drivers/of/base.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/of/base.c b/drivers/of/base.c index 0a8aeb8523fe..3b1aa08bf5f3 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -1886,8 +1886,10 @@ void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align)) name = of_get_property(of_chosen, "linux,stdout-path", NULL); if (IS_ENABLED(CONFIG_PPC) && !name) name = of_get_property(of_aliases, "stdout", NULL); - if (name) + if (name) { of_stdout = of_find_node_opts_by_path(name, &of_stdout_options); + add_preferred_console("stdout-path", 0, NULL); + } } if (!of_aliases) -- GitLab From 20aa4d8ae8d2ada8f959364ebc096b8841245456 Mon Sep 17 00:00:00 2001 From: Chunyan Zhang Date: Fri, 16 Jan 2015 18:00:07 +0800 Subject: [PATCH 03726/11651] Documentation: DT: Renamed of-serial.txt to 8250.txt The file of-serial.txt was only for 8250 compatible UART implementations, so renamed it to 8250.txt to avoid confusing other persons. This is suggested by Arnd, see: http://lists.infradead.org/pipermail/linux-arm-kernel/2014-September/291455.html Signed-off-by: Chunyan Zhang Acked-by: Mark Rutland Signed-off-by: Rob Herring --- .../devicetree/bindings/serial/{of-serial.txt => 8250.txt} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Documentation/devicetree/bindings/serial/{of-serial.txt => 8250.txt} (100%) diff --git a/Documentation/devicetree/bindings/serial/of-serial.txt b/Documentation/devicetree/bindings/serial/8250.txt similarity index 100% rename from Documentation/devicetree/bindings/serial/of-serial.txt rename to Documentation/devicetree/bindings/serial/8250.txt -- GitLab From d3a891652adb82e1973348c703a597cb54e41dea Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 3 Mar 2015 10:04:45 -0300 Subject: [PATCH 03727/11651] of/overlay: Remove unused variable Commit 3e7f7626fd49a ("of/overlay: Do not generate duplicate nodes") removed the only use of the 'grandchild' variable, which leads to the following build warning: drivers/of/overlay.c: In function 'of_overlay_apply_single_device_node': drivers/of/overlay.c:89:31: warning: unused variable 'grandchild' [-Wunused-variable] struct device_node *tchild, *grandchild; ^ Remove this unused variable. Signed-off-by: Fabio Estevam Signed-off-by: Rob Herring --- drivers/of/overlay.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c index 406664801cb5..dee9270ba547 100644 --- a/drivers/of/overlay.c +++ b/drivers/of/overlay.c @@ -86,7 +86,7 @@ static int of_overlay_apply_single_device_node(struct of_overlay *ov, struct device_node *target, struct device_node *child) { const char *cname; - struct device_node *tchild, *grandchild; + struct device_node *tchild; int ret = 0; cname = kbasename(child->full_name); -- GitLab From 4252de39d644d05d0e5f3a19ab6dd056944e64e4 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 4 Mar 2015 20:49:47 +0100 Subject: [PATCH 03728/11651] of: unittest: fix I2C dependency The unittest fails to link if I2C or I2C_MUX is a loadable module: drivers/built-in.o: In function `selftest_i2c_mux_remove': unittest.c:(.text+0xb0ce4): undefined reference to `i2c_del_mux_adapter' This changes the newly added IS_ENABLED() checks to use IS_BUILTIN() instead, which evaluates to false if the other driver is a module. Reported-by: Chen Gang Signed-off-by: Arnd Bergmann Fixes: d5e75500ca401 ("of: unitest: Add I2C overlay unit tests.") Signed-off-by: Rob Herring --- drivers/of/unittest.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index 0cf9a236d438..eaef89e8358b 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -979,7 +979,7 @@ static int of_path_platform_device_exists(const char *path) return pdev != NULL; } -#if IS_ENABLED(CONFIG_I2C) +#if IS_BUILTIN(CONFIG_I2C) /* get the i2c client device instantiated at the path */ static struct i2c_client *of_path_to_i2c_client(const char *path) @@ -1445,7 +1445,7 @@ static void of_selftest_overlay_11(void) return; } -#if IS_ENABLED(CONFIG_I2C) && IS_ENABLED(CONFIG_OF_OVERLAY) +#if IS_BUILTIN(CONFIG_I2C) && IS_ENABLED(CONFIG_OF_OVERLAY) struct selftest_i2c_bus_data { struct platform_device *pdev; @@ -1584,7 +1584,7 @@ static struct i2c_driver selftest_i2c_dev_driver = { .id_table = selftest_i2c_dev_id, }; -#if IS_ENABLED(CONFIG_I2C_MUX) +#if IS_BUILTIN(CONFIG_I2C_MUX) struct selftest_i2c_mux_data { int nchans; @@ -1695,7 +1695,7 @@ static int of_selftest_overlay_i2c_init(void) "could not register selftest i2c bus driver\n")) return ret; -#if IS_ENABLED(CONFIG_I2C_MUX) +#if IS_BUILTIN(CONFIG_I2C_MUX) ret = i2c_add_driver(&selftest_i2c_mux_driver); if (selftest(ret == 0, "could not register selftest i2c mux driver\n")) @@ -1707,7 +1707,7 @@ static int of_selftest_overlay_i2c_init(void) static void of_selftest_overlay_i2c_cleanup(void) { -#if IS_ENABLED(CONFIG_I2C_MUX) +#if IS_BUILTIN(CONFIG_I2C_MUX) i2c_del_driver(&selftest_i2c_mux_driver); #endif platform_driver_unregister(&selftest_i2c_bus_driver); @@ -1814,7 +1814,7 @@ static void __init of_selftest_overlay(void) of_selftest_overlay_10(); of_selftest_overlay_11(); -#if IS_ENABLED(CONFIG_I2C) +#if IS_BUILTIN(CONFIG_I2C) if (selftest(of_selftest_overlay_i2c_init() == 0, "i2c init failed\n")) goto out; -- GitLab From d1e9fa98387549a24633fb6b00a26edb34382488 Mon Sep 17 00:00:00 2001 From: Matt Porter Date: Thu, 5 Mar 2015 10:53:11 -0500 Subject: [PATCH 03729/11651] dt: submitting-patches: clarify that DT maintainers are to be cced on bindings The exact steps provided for submitting binding patches can be read as requiring the bindings to be sent only to the devicetree@vger.kernel.org list. Since the DT maintainers would like to be Cced on any binding submissions, make this requirement explicit in step 2. Signed-off-by: Matt Porter Signed-off-by: Rob Herring --- Documentation/devicetree/bindings/submitting-patches.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/submitting-patches.txt b/Documentation/devicetree/bindings/submitting-patches.txt index 56742bc70218..7d44eae7ab0b 100644 --- a/Documentation/devicetree/bindings/submitting-patches.txt +++ b/Documentation/devicetree/bindings/submitting-patches.txt @@ -12,6 +12,9 @@ I. For patch submitters devicetree@vger.kernel.org + and Cc: the DT maintainers. Use scripts/get_maintainer.pl to identify + all of the DT maintainers. + 3) The Documentation/ portion of the patch should come in the series before the code implementing the binding. -- GitLab From dc6a9453eb253658df8740d4d872c6323daf4f0d Mon Sep 17 00:00:00 2001 From: Wang Long Date: Mon, 2 Mar 2015 06:49:21 +0000 Subject: [PATCH 03730/11651] of/unittest: remove the duplicate of_changeset_init Remove the duplicate of_changeset_init. In of_selftest_changeset testcase, the "struct of_changeset chgset" is initialized twice, but only once is enough. so, drop the first initializtion code. Signed-off-by: Wang Long Signed-off-by: Rob Herring --- drivers/of/unittest.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index eaef89e8358b..ee99028447ad 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -478,7 +478,6 @@ static void __init of_selftest_changeset(void) struct device_node *n1, *n2, *n21, *nremove, *parent, *np; struct of_changeset chgset; - of_changeset_init(&chgset); n1 = __of_node_dup(NULL, "/testcase-data/changeset/n1"); selftest(n1, "testcase setup failure\n"); n2 = __of_node_dup(NULL, "/testcase-data/changeset/n2"); -- GitLab From 649022e08e4798ffb6e9b11c56ee6b2c62465d11 Mon Sep 17 00:00:00 2001 From: Wang Long Date: Tue, 3 Mar 2015 03:50:38 +0000 Subject: [PATCH 03731/11651] of/unittest: Fix the wrong expected value in of_selftest_property_string This patch fix the wrong expected value of of_property_match_string in of_selftest_property_string. Signed-off-by: Wang Long Signed-off-by: Rob Herring --- drivers/of/unittest.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index ee99028447ad..ac1a834f828f 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -378,9 +378,9 @@ static void __init of_selftest_property_string(void) rc = of_property_match_string(np, "phandle-list-names", "first"); selftest(rc == 0, "first expected:0 got:%i\n", rc); rc = of_property_match_string(np, "phandle-list-names", "second"); - selftest(rc == 1, "second expected:0 got:%i\n", rc); + selftest(rc == 1, "second expected:1 got:%i\n", rc); rc = of_property_match_string(np, "phandle-list-names", "third"); - selftest(rc == 2, "third expected:0 got:%i\n", rc); + selftest(rc == 2, "third expected:2 got:%i\n", rc); rc = of_property_match_string(np, "phandle-list-names", "fourth"); selftest(rc == -ENODATA, "unmatched string; rc=%i\n", rc); rc = of_property_match_string(np, "missing-property", "blah"); -- GitLab From 106937e8ccdcf0f4b95fbf0fe9abd42766cade33 Mon Sep 17 00:00:00 2001 From: Leif Lindholm Date: Fri, 6 Mar 2015 16:52:53 +0000 Subject: [PATCH 03732/11651] of: fix handling of '/' in options for of_find_node_by_path() Ensure proper handling of paths with appended options (after ':'), where those options may contain a '/'. Fixes: 7914a7c5651a ("of: support passing console options with stdout-path") Reported-by: Peter Hurley Signed-off-by: Leif Lindholm Cc: # 3.19 Signed-off-by: Rob Herring --- drivers/of/base.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/drivers/of/base.c b/drivers/of/base.c index 3b1aa08bf5f3..adb8764861c0 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -714,16 +714,17 @@ static struct device_node *__of_find_node_by_path(struct device_node *parent, const char *path) { struct device_node *child; - int len = strchrnul(path, '/') - path; - int term; + int len; + const char *end; + end = strchr(path, ':'); + if (!end) + end = strchrnul(path, '/'); + + len = end - path; if (!len) return NULL; - term = strchrnul(path, ':') - path; - if (term < len) - len = term; - __for_each_child_of_node(parent, child) { const char *name = strrchr(child->full_name, '/'); if (WARN(!name, "malformed device_node %s\n", child->full_name)) @@ -768,8 +769,12 @@ struct device_node *of_find_node_opts_by_path(const char *path, const char **opt /* The path could begin with an alias */ if (*path != '/') { - char *p = strchrnul(path, '/'); - int len = separator ? separator - path : p - path; + int len; + const char *p = separator; + + if (!p) + p = strchrnul(path, '/'); + len = p - path; /* of_aliases must not be NULL */ if (!of_aliases) @@ -794,6 +799,8 @@ struct device_node *of_find_node_opts_by_path(const char *path, const char **opt path++; /* Increment past '/' delimiter */ np = __of_find_node_by_path(np, path); path = strchrnul(path, '/'); + if (separator && separator < path) + break; } raw_spin_unlock_irqrestore(&devtree_lock, flags); return np; -- GitLab From 8cbba1ab1ae15b3a5d96caa526eac607f80bda23 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Fri, 6 Mar 2015 13:59:59 -0500 Subject: [PATCH 03733/11651] of: unittest: Add options string testcase variants Add testcase variants with '/' in the options string to test for scan beyond end path name terminated by ':'. Signed-off-by: Peter Hurley Signed-off-by: Rob Herring --- drivers/of/unittest.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index ac1a834f828f..aba8946cac46 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -92,6 +92,11 @@ static void __init of_selftest_find_node_by_name(void) "option path test failed\n"); of_node_put(np); + np = of_find_node_opts_by_path("/testcase-data:test/option", &options); + selftest(np && !strcmp("test/option", options), + "option path test, subcase #1 failed\n"); + of_node_put(np); + np = of_find_node_opts_by_path("/testcase-data:testoption", NULL); selftest(np, "NULL option path test failed\n"); of_node_put(np); @@ -102,6 +107,12 @@ static void __init of_selftest_find_node_by_name(void) "option alias path test failed\n"); of_node_put(np); + np = of_find_node_opts_by_path("testcase-alias:test/alias/option", + &options); + selftest(np && !strcmp("test/alias/option", options), + "option alias path test, subcase #1 failed\n"); + of_node_put(np); + np = of_find_node_opts_by_path("testcase-alias:testaliasoption", NULL); selftest(np, "NULL option alias path test failed\n"); of_node_put(np); -- GitLab From e6a4e5d50b3eea42220e50d64006fe5baacf654c Mon Sep 17 00:00:00 2001 From: Ray Jui Date: Mon, 9 Mar 2015 13:44:58 -0700 Subject: [PATCH 03734/11651] ARM: dts: enable IOMUX for Broadcom Cygnus This enables the IOMUX support for Broadcom Cygnus SoC Signed-off-by: Ray Jui Tested-by: Dmitry Torokhov Acked-by: Linus Walleij Signed-off-by: Florian Fainelli --- arch/arm/boot/dts/bcm-cygnus.dtsi | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm/boot/dts/bcm-cygnus.dtsi b/arch/arm/boot/dts/bcm-cygnus.dtsi index ff5fb6ab0b97..1cbae6a052f1 100644 --- a/arch/arm/boot/dts/bcm-cygnus.dtsi +++ b/arch/arm/boot/dts/bcm-cygnus.dtsi @@ -54,6 +54,12 @@ /include/ "bcm-cygnus-clock.dtsi" + pinctrl: pinctrl@0x0301d0c8 { + compatible = "brcm,cygnus-pinmux"; + reg = <0x0301d0c8 0x30>, + <0x0301d24c 0x2c>; + }; + amba { #address-cells = <1>; #size-cells = <1>; -- GitLab From 5fa4b29c71b204b7258a8130020d574e033f4015 Mon Sep 17 00:00:00 2001 From: Ray Jui Date: Mon, 9 Mar 2015 13:45:01 -0700 Subject: [PATCH 03735/11651] ARM: dts: enable GPIO for Broadcom Cygnus This enables all 3 GPIO controllers including the ASIU GPIO, the chipcommonG GPIO, and the ALWAYS-ON GPIO, for Broadcom Cygnus SoC Signed-off-by: Ray Jui Reviewed-by: Scott Branden Tested-by: Dmitry Torokhov Acked-by: Linus Walleij Signed-off-by: Florian Fainelli --- arch/arm/boot/dts/bcm-cygnus.dtsi | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/arch/arm/boot/dts/bcm-cygnus.dtsi b/arch/arm/boot/dts/bcm-cygnus.dtsi index 1cbae6a052f1..63b7fed73614 100644 --- a/arch/arm/boot/dts/bcm-cygnus.dtsi +++ b/arch/arm/boot/dts/bcm-cygnus.dtsi @@ -60,6 +60,36 @@ <0x0301d24c 0x2c>; }; + gpio_crmu: gpio@03024800 { + compatible = "brcm,cygnus-crmu-gpio"; + reg = <0x03024800 0x50>, + <0x03024008 0x18>; + #gpio-cells = <2>; + gpio-controller; + }; + + gpio_ccm: gpio@1800a000 { + compatible = "brcm,cygnus-ccm-gpio"; + reg = <0x1800a000 0x50>, + <0x0301d164 0x20>; + #gpio-cells = <2>; + gpio-controller; + interrupts = ; + interrupt-controller; + }; + + gpio_asiu: gpio@180a5000 { + compatible = "brcm,cygnus-asiu-gpio"; + reg = <0x180a5000 0x668>; + #gpio-cells = <2>; + gpio-controller; + + pinmux = <&pinctrl>; + + interrupt-controller; + interrupts = ; + }; + amba { #address-cells = <1>; #size-cells = <1>; -- GitLab From 90c6e608e737e387e88aa789c7b4e1f6dfdc4822 Mon Sep 17 00:00:00 2001 From: Ray Jui Date: Mon, 9 Mar 2015 13:45:02 -0700 Subject: [PATCH 03736/11651] ARM: dts: cygnus: enable GPIO based hook detection This enables GPIO based phone hook detection for Broadcom BCM911360 phone factor board (bcm911360_entphn) Signed-off-by: Ray Jui Acked-by: Linus Walleij Signed-off-by: Florian Fainelli --- arch/arm/boot/dts/bcm911360_entphn.dts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/arch/arm/boot/dts/bcm911360_entphn.dts b/arch/arm/boot/dts/bcm911360_entphn.dts index d2ee95280548..7db484323fd6 100644 --- a/arch/arm/boot/dts/bcm911360_entphn.dts +++ b/arch/arm/boot/dts/bcm911360_entphn.dts @@ -33,6 +33,7 @@ /dts-v1/; #include "bcm-cygnus.dtsi" +#include "dt-bindings/input/input.h" / { model = "Cygnus Enterprise Phone (BCM911360_ENTPHN)"; @@ -50,4 +51,16 @@ uart3: serial@18023000 { status = "okay"; }; + + gpio_keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + + hook { + label = "HOOK"; + linux,code = ; + gpios = <&gpio_asiu 48 0>; + }; + }; }; -- GitLab From 3855634deb051bbce155d149bca05b99a3528d5d Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Tue, 10 Mar 2015 04:56:53 +0100 Subject: [PATCH 03737/11651] drivers: atm: nicstar: remove ifdef'd out skb destructors remove dead code. Signed-off-by: Florian Westphal Signed-off-by: David S. Miller --- drivers/atm/nicstar.c | 90 ------------------------------------------- 1 file changed, 90 deletions(-) diff --git a/drivers/atm/nicstar.c b/drivers/atm/nicstar.c index b7e1cc0a97c8..ddc4ceb85fc5 100644 --- a/drivers/atm/nicstar.c +++ b/drivers/atm/nicstar.c @@ -73,9 +73,6 @@ #undef GENERAL_DEBUG #undef EXTRA_DEBUG -#undef NS_USE_DESTRUCTORS /* For now keep this undefined unless you know - you're going to use only raw ATM */ - /* Do not touch these */ #ifdef TX_DEBUG @@ -138,11 +135,6 @@ static void process_tsq(ns_dev * card); static void drain_scq(ns_dev * card, scq_info * scq, int pos); static void process_rsq(ns_dev * card); static void dequeue_rx(ns_dev * card, ns_rsqe * rsqe); -#ifdef NS_USE_DESTRUCTORS -static void ns_sb_destructor(struct sk_buff *sb); -static void ns_lb_destructor(struct sk_buff *lb); -static void ns_hb_destructor(struct sk_buff *hb); -#endif /* NS_USE_DESTRUCTORS */ static void recycle_rx_buf(ns_dev * card, struct sk_buff *skb); static void recycle_iovec_rx_bufs(ns_dev * card, struct iovec *iov, int count); static void recycle_iov_buf(ns_dev * card, struct sk_buff *iovb); @@ -2169,9 +2161,6 @@ static void dequeue_rx(ns_dev * card, ns_rsqe * rsqe) } else { skb_put(skb, len); dequeue_sm_buf(card, skb); -#ifdef NS_USE_DESTRUCTORS - skb->destructor = ns_sb_destructor; -#endif /* NS_USE_DESTRUCTORS */ ATM_SKB(skb)->vcc = vcc; __net_timestamp(skb); vcc->push(vcc, skb); @@ -2190,9 +2179,6 @@ static void dequeue_rx(ns_dev * card, ns_rsqe * rsqe) } else { skb_put(sb, len); dequeue_sm_buf(card, sb); -#ifdef NS_USE_DESTRUCTORS - sb->destructor = ns_sb_destructor; -#endif /* NS_USE_DESTRUCTORS */ ATM_SKB(sb)->vcc = vcc; __net_timestamp(sb); vcc->push(vcc, sb); @@ -2208,9 +2194,6 @@ static void dequeue_rx(ns_dev * card, ns_rsqe * rsqe) atomic_inc(&vcc->stats->rx_drop); } else { dequeue_lg_buf(card, skb); -#ifdef NS_USE_DESTRUCTORS - skb->destructor = ns_lb_destructor; -#endif /* NS_USE_DESTRUCTORS */ skb_push(skb, NS_SMBUFSIZE); skb_copy_from_linear_data(sb, skb->data, NS_SMBUFSIZE); @@ -2322,9 +2305,6 @@ static void dequeue_rx(ns_dev * card, ns_rsqe * rsqe) card->index); #endif /* EXTRA_DEBUG */ ATM_SKB(hb)->vcc = vcc; -#ifdef NS_USE_DESTRUCTORS - hb->destructor = ns_hb_destructor; -#endif /* NS_USE_DESTRUCTORS */ __net_timestamp(hb); vcc->push(vcc, hb); atomic_inc(&vcc->stats->rx); @@ -2337,68 +2317,6 @@ static void dequeue_rx(ns_dev * card, ns_rsqe * rsqe) } -#ifdef NS_USE_DESTRUCTORS - -static void ns_sb_destructor(struct sk_buff *sb) -{ - ns_dev *card; - u32 stat; - - card = (ns_dev *) ATM_SKB(sb)->vcc->dev->dev_data; - stat = readl(card->membase + STAT); - card->sbfqc = ns_stat_sfbqc_get(stat); - card->lbfqc = ns_stat_lfbqc_get(stat); - - do { - sb = __dev_alloc_skb(NS_SMSKBSIZE, GFP_KERNEL); - if (sb == NULL) - break; - NS_PRV_BUFTYPE(sb) = BUF_SM; - skb_queue_tail(&card->sbpool.queue, sb); - skb_reserve(sb, NS_AAL0_HEADER); - push_rxbufs(card, sb); - } while (card->sbfqc < card->sbnr.min); -} - -static void ns_lb_destructor(struct sk_buff *lb) -{ - ns_dev *card; - u32 stat; - - card = (ns_dev *) ATM_SKB(lb)->vcc->dev->dev_data; - stat = readl(card->membase + STAT); - card->sbfqc = ns_stat_sfbqc_get(stat); - card->lbfqc = ns_stat_lfbqc_get(stat); - - do { - lb = __dev_alloc_skb(NS_LGSKBSIZE, GFP_KERNEL); - if (lb == NULL) - break; - NS_PRV_BUFTYPE(lb) = BUF_LG; - skb_queue_tail(&card->lbpool.queue, lb); - skb_reserve(lb, NS_SMBUFSIZE); - push_rxbufs(card, lb); - } while (card->lbfqc < card->lbnr.min); -} - -static void ns_hb_destructor(struct sk_buff *hb) -{ - ns_dev *card; - - card = (ns_dev *) ATM_SKB(hb)->vcc->dev->dev_data; - - while (card->hbpool.count < card->hbnr.init) { - hb = __dev_alloc_skb(NS_HBUFSIZE, GFP_KERNEL); - if (hb == NULL) - break; - NS_PRV_BUFTYPE(hb) = BUF_NONE; - skb_queue_tail(&card->hbpool.queue, hb); - card->hbpool.count++; - } -} - -#endif /* NS_USE_DESTRUCTORS */ - static void recycle_rx_buf(ns_dev * card, struct sk_buff *skb) { if (unlikely(NS_PRV_BUFTYPE(skb) == BUF_NONE)) { @@ -2427,9 +2345,6 @@ static void recycle_iov_buf(ns_dev * card, struct sk_buff *iovb) static void dequeue_sm_buf(ns_dev * card, struct sk_buff *sb) { skb_unlink(sb, &card->sbpool.queue); -#ifdef NS_USE_DESTRUCTORS - if (card->sbfqc < card->sbnr.min) -#else if (card->sbfqc < card->sbnr.init) { struct sk_buff *new_sb; if ((new_sb = dev_alloc_skb(NS_SMSKBSIZE)) != NULL) { @@ -2440,7 +2355,6 @@ static void dequeue_sm_buf(ns_dev * card, struct sk_buff *sb) } } if (card->sbfqc < card->sbnr.init) -#endif /* NS_USE_DESTRUCTORS */ { struct sk_buff *new_sb; if ((new_sb = dev_alloc_skb(NS_SMSKBSIZE)) != NULL) { @@ -2455,9 +2369,6 @@ static void dequeue_sm_buf(ns_dev * card, struct sk_buff *sb) static void dequeue_lg_buf(ns_dev * card, struct sk_buff *lb) { skb_unlink(lb, &card->lbpool.queue); -#ifdef NS_USE_DESTRUCTORS - if (card->lbfqc < card->lbnr.min) -#else if (card->lbfqc < card->lbnr.init) { struct sk_buff *new_lb; if ((new_lb = dev_alloc_skb(NS_LGSKBSIZE)) != NULL) { @@ -2468,7 +2379,6 @@ static void dequeue_lg_buf(ns_dev * card, struct sk_buff *lb) } } if (card->lbfqc < card->lbnr.init) -#endif /* NS_USE_DESTRUCTORS */ { struct sk_buff *new_lb; if ((new_lb = dev_alloc_skb(NS_LGSKBSIZE)) != NULL) { -- GitLab From af5cbc9822f6bbe399925760a4d5ee82c21f258c Mon Sep 17 00:00:00 2001 From: Nimrod Andy Date: Tue, 10 Mar 2015 19:09:41 +0800 Subject: [PATCH 03738/11651] net: fec: fix receive VLAN CTAG HW acceleration issue The current driver support receive VLAN CTAG HW acceleration feature (NETIF_F_HW_VLAN_CTAG_RX) through software simulation. There calls the api .skb_copy_to_linear_data_offset() to skip the VLAN tag, but there have overlap between the two memory data point range. The patch just fix the issue. V2: Michael Grzeschik suggest to use memmove() instead of skb_copy_to_linear_data_offset(). Reported-by: Michael Grzeschik Fixes: 1b7bde6d659d ("net: fec: implement rx_copybreak to improve rx performance") Signed-off-by: Fugang Duan Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/fec_main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index 99492b7e3713..787db5026191 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -1479,8 +1479,7 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id) vlan_packet_rcvd = true; - skb_copy_to_linear_data_offset(skb, VLAN_HLEN, - data, (2 * ETH_ALEN)); + memmove(skb->data + VLAN_HLEN, data, ETH_ALEN * 2); skb_pull(skb, VLAN_HLEN); } -- GitLab From e3d50738e59af9e58f569e54ff8af1840bea906c Mon Sep 17 00:00:00 2001 From: Hariprasad Shenai Date: Tue, 10 Mar 2015 17:44:52 +0530 Subject: [PATCH 03739/11651] cxgb4: fix coccinelle warnings Commit 16e47624e76b43db ("cxgb4: Add new scheme to update T4/T5 firmware") introduced below coccinelle warning. >> drivers/net/ethernet/chelsio/cxgb4/t4_hw.c:994:2-8: Replace memcpy with struct assignment Reported-by: Fengguang Wu Signed-off-by: Hariprasad Shenai Signed-off-by: David S. Miller --- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index 853c38997c82..1abdfa123c6c 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -1120,7 +1120,7 @@ int t4_prep_fw(struct adapter *adap, struct fw_info *fw_info, } /* Installed successfully, update the cached header too. */ - memcpy(card_fw, fs_fw, sizeof(*card_fw)); + *card_fw = *fs_fw; card_fw_usable = 1; *reset = 0; /* already reset as part of load_fw */ } -- GitLab From 491da2a477077357c8206a601559e2ea58f224db Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 10 Mar 2015 07:15:52 -0700 Subject: [PATCH 03740/11651] net: constify sock_diag_check_cookie() sock_diag_check_cookie() second parameter is constant Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/linux/sock_diag.h | 2 +- net/core/sock_diag.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/sock_diag.h b/include/linux/sock_diag.h index 46cca4c06848..b5ad7d35a636 100644 --- a/include/linux/sock_diag.h +++ b/include/linux/sock_diag.h @@ -19,7 +19,7 @@ void sock_diag_unregister(const struct sock_diag_handler *h); void sock_diag_register_inet_compat(int (*fn)(struct sk_buff *skb, struct nlmsghdr *nlh)); void sock_diag_unregister_inet_compat(int (*fn)(struct sk_buff *skb, struct nlmsghdr *nlh)); -int sock_diag_check_cookie(void *sk, __u32 *cookie); +int sock_diag_check_cookie(void *sk, const __u32 *cookie); void sock_diag_save_cookie(void *sk, __u32 *cookie); int sock_diag_put_meminfo(struct sock *sk, struct sk_buff *skb, int attr); diff --git a/net/core/sock_diag.c b/net/core/sock_diag.c index ad704c757bb4..96e70ee05a8d 100644 --- a/net/core/sock_diag.c +++ b/net/core/sock_diag.c @@ -13,7 +13,7 @@ static const struct sock_diag_handler *sock_diag_handlers[AF_MAX]; static int (*inet_rcv_compat)(struct sk_buff *skb, struct nlmsghdr *nlh); static DEFINE_MUTEX(sock_diag_table_mutex); -int sock_diag_check_cookie(void *sk, __u32 *cookie) +int sock_diag_check_cookie(void *sk, const __u32 *cookie) { if ((cookie[0] != INET_DIAG_NOCOOKIE || cookie[1] != INET_DIAG_NOCOOKIE) && -- GitLab From e31c5e0e486226e0808a2e90a7af40daa084ed09 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 10 Mar 2015 07:15:53 -0700 Subject: [PATCH 03741/11651] inet_diag: cleanups Remove all inline keywords, add some const, and cleanup style. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/inet_diag.c | 144 +++++++++++++++++++++---------------------- 1 file changed, 71 insertions(+), 73 deletions(-) diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index 0c974d3499ed..cd261f6e3abb 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c @@ -38,8 +38,8 @@ static const struct inet_diag_handler **inet_diag_table; struct inet_diag_entry { - __be32 *saddr; - __be32 *daddr; + const __be32 *saddr; + const __be32 *daddr; u16 sport; u16 dport; u16 family; @@ -65,28 +65,27 @@ static const struct inet_diag_handler *inet_diag_lock_handler(int proto) return inet_diag_table[proto]; } -static inline void inet_diag_unlock_handler( - const struct inet_diag_handler *handler) +static void inet_diag_unlock_handler(const struct inet_diag_handler *handler) { mutex_unlock(&inet_diag_table_mutex); } int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk, - struct sk_buff *skb, struct inet_diag_req_v2 *req, - struct user_namespace *user_ns, - u32 portid, u32 seq, u16 nlmsg_flags, - const struct nlmsghdr *unlh) + struct sk_buff *skb, struct inet_diag_req_v2 *req, + struct user_namespace *user_ns, + u32 portid, u32 seq, u16 nlmsg_flags, + const struct nlmsghdr *unlh) { const struct inet_sock *inet = inet_sk(sk); + const struct inet_diag_handler *handler; + int ext = req->idiag_ext; struct inet_diag_msg *r; struct nlmsghdr *nlh; struct nlattr *attr; void *info = NULL; - const struct inet_diag_handler *handler; - int ext = req->idiag_ext; handler = inet_diag_table[req->sdiag_protocol]; - BUG_ON(handler == NULL); + BUG_ON(!handler); nlh = nlmsg_put(skb, portid, seq, unlh->nlmsg_type, sizeof(*r), nlmsg_flags); @@ -125,7 +124,6 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk, #if IS_ENABLED(CONFIG_IPV6) if (r->idiag_family == AF_INET6) { - *(struct in6_addr *)r->id.idiag_src = sk->sk_v6_rcv_saddr; *(struct in6_addr *)r->id.idiag_dst = sk->sk_v6_daddr; @@ -155,7 +153,7 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk, if (sock_diag_put_meminfo(sk, skb, INET_DIAG_SKMEMINFO)) goto errout; - if (icsk == NULL) { + if (!icsk) { handler->idiag_get_info(sk, r, NULL); goto out; } @@ -213,23 +211,25 @@ errout: EXPORT_SYMBOL_GPL(inet_sk_diag_fill); static int inet_csk_diag_fill(struct sock *sk, - struct sk_buff *skb, struct inet_diag_req_v2 *req, + struct sk_buff *skb, + struct inet_diag_req_v2 *req, struct user_namespace *user_ns, u32 portid, u32 seq, u16 nlmsg_flags, const struct nlmsghdr *unlh) { - return inet_sk_diag_fill(sk, inet_csk(sk), - skb, req, user_ns, portid, seq, nlmsg_flags, unlh); + return inet_sk_diag_fill(sk, inet_csk(sk), skb, req, + user_ns, portid, seq, nlmsg_flags, unlh); } static int inet_twsk_diag_fill(struct inet_timewait_sock *tw, - struct sk_buff *skb, struct inet_diag_req_v2 *req, + struct sk_buff *skb, + struct inet_diag_req_v2 *req, u32 portid, u32 seq, u16 nlmsg_flags, const struct nlmsghdr *unlh) { - s32 tmo; struct inet_diag_msg *r; struct nlmsghdr *nlh; + s32 tmo; nlh = nlmsg_put(skb, portid, seq, unlh->nlmsg_type, sizeof(*r), nlmsg_flags); @@ -290,36 +290,35 @@ static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, nlmsg_flags, unlh); } -int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *in_skb, - const struct nlmsghdr *nlh, struct inet_diag_req_v2 *req) +int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, + struct sk_buff *in_skb, + const struct nlmsghdr *nlh, + struct inet_diag_req_v2 *req) { - int err; - struct sock *sk; - struct sk_buff *rep; struct net *net = sock_net(in_skb->sk); + struct sk_buff *rep; + struct sock *sk; + int err; err = -EINVAL; - if (req->sdiag_family == AF_INET) { + if (req->sdiag_family == AF_INET) sk = inet_lookup(net, hashinfo, req->id.idiag_dst[0], req->id.idiag_dport, req->id.idiag_src[0], req->id.idiag_sport, req->id.idiag_if); - } #if IS_ENABLED(CONFIG_IPV6) - else if (req->sdiag_family == AF_INET6) { + else if (req->sdiag_family == AF_INET6) sk = inet6_lookup(net, hashinfo, (struct in6_addr *)req->id.idiag_dst, req->id.idiag_dport, (struct in6_addr *)req->id.idiag_src, req->id.idiag_sport, req->id.idiag_if); - } #endif - else { + else goto out_nosk; - } err = -ENOENT; - if (sk == NULL) + if (!sk) goto out_nosk; err = sock_diag_check_cookie(sk, req->id.idiag_cookie); @@ -400,9 +399,8 @@ static int bitstring_match(const __be32 *a1, const __be32 *a2, int bits) return 1; } - static int inet_diag_bc_run(const struct nlattr *_bc, - const struct inet_diag_entry *entry) + const struct inet_diag_entry *entry) { const void *bc = nla_data(_bc); int len = nla_len(_bc); @@ -434,10 +432,10 @@ static int inet_diag_bc_run(const struct nlattr *_bc, break; case INET_DIAG_BC_S_COND: case INET_DIAG_BC_D_COND: { - struct inet_diag_hostcond *cond; - __be32 *addr; + const struct inet_diag_hostcond *cond; + const __be32 *addr; - cond = (struct inet_diag_hostcond *)(op + 1); + cond = (const struct inet_diag_hostcond *)(op + 1); if (cond->port != -1 && cond->port != (op->code == INET_DIAG_BC_S_COND ? entry->sport : entry->dport)) { @@ -488,16 +486,15 @@ static int inet_diag_bc_run(const struct nlattr *_bc, int inet_diag_bc_sk(const struct nlattr *bc, struct sock *sk) { - struct inet_diag_entry entry; struct inet_sock *inet = inet_sk(sk); + struct inet_diag_entry entry; - if (bc == NULL) + if (!bc) return 1; entry.family = sk->sk_family; #if IS_ENABLED(CONFIG_IPV6) if (entry.family == AF_INET6) { - entry.saddr = sk->sk_v6_rcv_saddr.s6_addr32; entry.daddr = sk->sk_v6_daddr.s6_addr32; } else @@ -535,8 +532,8 @@ static int valid_cc(const void *bc, int len, int cc) static bool valid_hostcond(const struct inet_diag_bc_op *op, int len, int *min_len) { - int addr_len; struct inet_diag_hostcond *cond; + int addr_len; /* Check hostcond space. */ *min_len += sizeof(struct inet_diag_hostcond); @@ -570,8 +567,8 @@ static bool valid_hostcond(const struct inet_diag_bc_op *op, int len, } /* Validate a port comparison operator. */ -static inline bool valid_port_comparison(const struct inet_diag_bc_op *op, - int len, int *min_len) +static bool valid_port_comparison(const struct inet_diag_bc_op *op, + int len, int *min_len) { /* Port comparisons put the port in a follow-on inet_diag_bc_op. */ *min_len += sizeof(struct inet_diag_bc_op); @@ -586,10 +583,9 @@ static int inet_diag_bc_audit(const void *bytecode, int bytecode_len) int len = bytecode_len; while (len > 0) { - const struct inet_diag_bc_op *op = bc; int min_len = sizeof(struct inet_diag_bc_op); + const struct inet_diag_bc_op *op = bc; -//printk("BC: %d %d %d {%d} / %d\n", op->code, op->yes, op->no, op[1].no, len); switch (op->code) { case INET_DIAG_BC_S_COND: case INET_DIAG_BC_D_COND: @@ -687,11 +683,11 @@ static int inet_twsk_diag_dump(struct sock *sk, /* Get the IPv4, IPv6, or IPv4-mapped-IPv6 local and remote addresses * from a request_sock. For IPv4-mapped-IPv6 we must map IPv4 to IPv6. */ -static inline void inet_diag_req_addrs(const struct sock *sk, - const struct request_sock *req, - struct inet_diag_entry *entry) +static void inet_diag_req_addrs(const struct sock *sk, + const struct request_sock *req, + struct inet_diag_entry *entry) { - struct inet_request_sock *ireq = inet_rsk(req); + const struct inet_request_sock *ireq = inet_rsk(req); #if IS_ENABLED(CONFIG_IPV6) if (sk->sk_family == AF_INET6) { @@ -761,6 +757,7 @@ static int inet_diag_fill_req(struct sk_buff *skb, struct sock *sk, #if IS_ENABLED(CONFIG_IPV6) if (r->idiag_family == AF_INET6) { struct inet_diag_entry entry; + inet_diag_req_addrs(sk, req, &entry); memcpy(r->id.idiag_src, entry.saddr, sizeof(struct in6_addr)); memcpy(r->id.idiag_dst, entry.daddr, sizeof(struct in6_addr)); @@ -776,12 +773,11 @@ static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk, struct inet_diag_req_v2 *r, const struct nlattr *bc) { - struct inet_diag_entry entry; struct inet_connection_sock *icsk = inet_csk(sk); - struct listen_sock *lopt; struct inet_sock *inet = inet_sk(sk); - int j, s_j; - int reqnum, s_reqnum; + struct inet_diag_entry entry; + int j, s_j, reqnum, s_reqnum; + struct listen_sock *lopt; int err = 0; s_j = cb->args[3]; @@ -798,7 +794,7 @@ static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk, if (!lopt || !lopt->qlen) goto out; - if (bc != NULL) { + if (bc) { entry.sport = inet->inet_num; entry.userlocks = sk->sk_userlocks; } @@ -825,9 +821,9 @@ static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk, } err = inet_diag_fill_req(skb, sk, req, - sk_user_ns(NETLINK_CB(cb->skb).sk), - NETLINK_CB(cb->skb).portid, - cb->nlh->nlmsg_seq, cb->nlh); + sk_user_ns(NETLINK_CB(cb->skb).sk), + NETLINK_CB(cb->skb).portid, + cb->nlh->nlmsg_seq, cb->nlh); if (err < 0) { cb->args[3] = j + 1; cb->args[4] = reqnum; @@ -845,11 +841,11 @@ out: } void inet_diag_dump_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *skb, - struct netlink_callback *cb, struct inet_diag_req_v2 *r, struct nlattr *bc) + struct netlink_callback *cb, + struct inet_diag_req_v2 *r, struct nlattr *bc) { - int i, num; - int s_i, s_num; struct net *net = sock_net(skb->sk); + int i, num, s_i, s_num; s_i = cb->args[1]; s_num = num = cb->args[2]; @@ -859,9 +855,9 @@ void inet_diag_dump_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *skb, goto skip_listen_ht; for (i = s_i; i < INET_LHTABLE_SIZE; i++) { - struct sock *sk; - struct hlist_nulls_node *node; struct inet_listen_hashbucket *ilb; + struct hlist_nulls_node *node; + struct sock *sk; num = 0; ilb = &hashinfo->listening_hash[i]; @@ -878,7 +874,7 @@ void inet_diag_dump_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *skb, } if (r->sdiag_family != AF_UNSPEC && - sk->sk_family != r->sdiag_family) + sk->sk_family != r->sdiag_family) goto next_listen; if (r->id.idiag_sport != inet->inet_sport && @@ -926,8 +922,8 @@ skip_listen_ht: for (i = s_i; i <= hashinfo->ehash_mask; i++) { struct inet_ehash_bucket *head = &hashinfo->ehash[i]; spinlock_t *lock = inet_ehash_lockp(hashinfo, i); - struct sock *sk; struct hlist_nulls_node *node; + struct sock *sk; num = 0; @@ -939,8 +935,7 @@ skip_listen_ht: spin_lock_bh(lock); sk_nulls_for_each(sk, node, &head->chain) { - int res; - int state; + int state, res; if (!net_eq(sock_net(sk), net)) continue; @@ -983,7 +978,8 @@ out: EXPORT_SYMBOL_GPL(inet_diag_dump_icsk); static int __inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb, - struct inet_diag_req_v2 *r, struct nlattr *bc) + struct inet_diag_req_v2 *r, + struct nlattr *bc) { const struct inet_diag_handler *handler; int err = 0; @@ -1000,8 +996,8 @@ static int __inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb, static int inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb) { - struct nlattr *bc = NULL; int hdrlen = sizeof(struct inet_diag_req_v2); + struct nlattr *bc = NULL; if (nlmsg_attrlen(cb->nlh, hdrlen)) bc = nlmsg_find_attr(cb->nlh, hdrlen, INET_DIAG_REQ_BYTECODE); @@ -1009,7 +1005,7 @@ static int inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb) return __inet_diag_dump(skb, cb, nlmsg_data(cb->nlh), bc); } -static inline int inet_diag_type2proto(int type) +static int inet_diag_type2proto(int type) { switch (type) { case TCPDIAG_GETSOCK: @@ -1021,12 +1017,13 @@ static inline int inet_diag_type2proto(int type) } } -static int inet_diag_dump_compat(struct sk_buff *skb, struct netlink_callback *cb) +static int inet_diag_dump_compat(struct sk_buff *skb, + struct netlink_callback *cb) { struct inet_diag_req *rc = nlmsg_data(cb->nlh); + int hdrlen = sizeof(struct inet_diag_req); struct inet_diag_req_v2 req; struct nlattr *bc = NULL; - int hdrlen = sizeof(struct inet_diag_req); req.sdiag_family = AF_UNSPEC; /* compatibility */ req.sdiag_protocol = inet_diag_type2proto(cb->nlh->nlmsg_type); @@ -1041,7 +1038,7 @@ static int inet_diag_dump_compat(struct sk_buff *skb, struct netlink_callback *c } static int inet_diag_get_exact_compat(struct sk_buff *in_skb, - const struct nlmsghdr *nlh) + const struct nlmsghdr *nlh) { struct inet_diag_req *rc = nlmsg_data(nlh); struct inet_diag_req_v2 req; @@ -1070,7 +1067,7 @@ static int inet_diag_rcv_msg_compat(struct sk_buff *skb, struct nlmsghdr *nlh) attr = nlmsg_find_attr(nlh, hdrlen, INET_DIAG_REQ_BYTECODE); - if (attr == NULL || + if (!attr || nla_len(attr) < sizeof(struct inet_diag_bc_op) || inet_diag_bc_audit(nla_data(attr), nla_len(attr))) return -EINVAL; @@ -1097,9 +1094,10 @@ static int inet_diag_handler_dump(struct sk_buff *skb, struct nlmsghdr *h) if (h->nlmsg_flags & NLM_F_DUMP) { if (nlmsg_attrlen(h, hdrlen)) { struct nlattr *attr; + attr = nlmsg_find_attr(h, hdrlen, INET_DIAG_REQ_BYTECODE); - if (attr == NULL || + if (!attr || nla_len(attr) < sizeof(struct inet_diag_bc_op) || inet_diag_bc_audit(nla_data(attr), nla_len(attr))) return -EINVAL; @@ -1135,7 +1133,7 @@ int inet_diag_register(const struct inet_diag_handler *h) mutex_lock(&inet_diag_table_mutex); err = -EEXIST; - if (inet_diag_table[type] == NULL) { + if (!inet_diag_table[type]) { inet_diag_table[type] = h; err = 0; } -- GitLab From 34160ea3f9c96b5ae71a11459f9b9f6c298b8930 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 10 Mar 2015 07:15:54 -0700 Subject: [PATCH 03742/11651] inet_diag: add const to inet_diag_req_v2 diag dumpers should not modify the request. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/linux/inet_diag.h | 43 ++++++++++++++++++++------------------- net/dccp/diag.c | 7 ++++--- net/ipv4/inet_diag.c | 22 ++++++++++---------- net/ipv4/tcp_diag.c | 4 ++-- net/ipv4/udp_diag.c | 22 ++++++++++++-------- 5 files changed, 52 insertions(+), 46 deletions(-) diff --git a/include/linux/inet_diag.h b/include/linux/inet_diag.h index 46da02410a09..ac48b10c9395 100644 --- a/include/linux/inet_diag.h +++ b/include/linux/inet_diag.h @@ -11,33 +11,34 @@ struct sk_buff; struct netlink_callback; struct inet_diag_handler { - void (*dump)(struct sk_buff *skb, - struct netlink_callback *cb, - struct inet_diag_req_v2 *r, - struct nlattr *bc); - - int (*dump_one)(struct sk_buff *in_skb, - const struct nlmsghdr *nlh, - struct inet_diag_req_v2 *req); - - void (*idiag_get_info)(struct sock *sk, - struct inet_diag_msg *r, - void *info); - __u16 idiag_type; + void (*dump)(struct sk_buff *skb, + struct netlink_callback *cb, + const struct inet_diag_req_v2 *r, + struct nlattr *bc); + + int (*dump_one)(struct sk_buff *in_skb, + const struct nlmsghdr *nlh, + const struct inet_diag_req_v2 *req); + + void (*idiag_get_info)(struct sock *sk, + struct inet_diag_msg *r, + void *info); + __u16 idiag_type; }; struct inet_connection_sock; int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk, - struct sk_buff *skb, struct inet_diag_req_v2 *req, - struct user_namespace *user_ns, - u32 pid, u32 seq, u16 nlmsg_flags, - const struct nlmsghdr *unlh); + struct sk_buff *skb, const struct inet_diag_req_v2 *req, + struct user_namespace *user_ns, + u32 pid, u32 seq, u16 nlmsg_flags, + const struct nlmsghdr *unlh); void inet_diag_dump_icsk(struct inet_hashinfo *h, struct sk_buff *skb, - struct netlink_callback *cb, struct inet_diag_req_v2 *r, - struct nlattr *bc); + struct netlink_callback *cb, + const struct inet_diag_req_v2 *r, + struct nlattr *bc); int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, - struct sk_buff *in_skb, const struct nlmsghdr *nlh, - struct inet_diag_req_v2 *req); + struct sk_buff *in_skb, const struct nlmsghdr *nlh, + const struct inet_diag_req_v2 *req); int inet_diag_bc_sk(const struct nlattr *_bc, struct sock *sk); diff --git a/net/dccp/diag.c b/net/dccp/diag.c index 028fc43aacbd..5a45f8de5d99 100644 --- a/net/dccp/diag.c +++ b/net/dccp/diag.c @@ -49,13 +49,14 @@ static void dccp_diag_get_info(struct sock *sk, struct inet_diag_msg *r, } static void dccp_diag_dump(struct sk_buff *skb, struct netlink_callback *cb, - struct inet_diag_req_v2 *r, struct nlattr *bc) + const struct inet_diag_req_v2 *r, struct nlattr *bc) { inet_diag_dump_icsk(&dccp_hashinfo, skb, cb, r, bc); } -static int dccp_diag_dump_one(struct sk_buff *in_skb, const struct nlmsghdr *nlh, - struct inet_diag_req_v2 *req) +static int dccp_diag_dump_one(struct sk_buff *in_skb, + const struct nlmsghdr *nlh, + const struct inet_diag_req_v2 *req) { return inet_diag_dump_one_icsk(&dccp_hashinfo, in_skb, nlh, req); } diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index cd261f6e3abb..ac3bfb458afd 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c @@ -71,7 +71,7 @@ static void inet_diag_unlock_handler(const struct inet_diag_handler *handler) } int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk, - struct sk_buff *skb, struct inet_diag_req_v2 *req, + struct sk_buff *skb, const struct inet_diag_req_v2 *req, struct user_namespace *user_ns, u32 portid, u32 seq, u16 nlmsg_flags, const struct nlmsghdr *unlh) @@ -212,7 +212,7 @@ EXPORT_SYMBOL_GPL(inet_sk_diag_fill); static int inet_csk_diag_fill(struct sock *sk, struct sk_buff *skb, - struct inet_diag_req_v2 *req, + const struct inet_diag_req_v2 *req, struct user_namespace *user_ns, u32 portid, u32 seq, u16 nlmsg_flags, const struct nlmsghdr *unlh) @@ -223,7 +223,7 @@ static int inet_csk_diag_fill(struct sock *sk, static int inet_twsk_diag_fill(struct inet_timewait_sock *tw, struct sk_buff *skb, - struct inet_diag_req_v2 *req, + const struct inet_diag_req_v2 *req, u32 portid, u32 seq, u16 nlmsg_flags, const struct nlmsghdr *unlh) { @@ -277,7 +277,7 @@ static int inet_twsk_diag_fill(struct inet_timewait_sock *tw, } static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, - struct inet_diag_req_v2 *r, + const struct inet_diag_req_v2 *r, struct user_namespace *user_ns, u32 portid, u32 seq, u16 nlmsg_flags, const struct nlmsghdr *unlh) @@ -293,7 +293,7 @@ static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *in_skb, const struct nlmsghdr *nlh, - struct inet_diag_req_v2 *req) + const struct inet_diag_req_v2 *req) { struct net *net = sock_net(in_skb->sk); struct sk_buff *rep; @@ -358,7 +358,7 @@ EXPORT_SYMBOL_GPL(inet_diag_dump_one_icsk); static int inet_diag_get_exact(struct sk_buff *in_skb, const struct nlmsghdr *nlh, - struct inet_diag_req_v2 *req) + const struct inet_diag_req_v2 *req) { const struct inet_diag_handler *handler; int err; @@ -626,7 +626,7 @@ static int inet_diag_bc_audit(const void *bytecode, int bytecode_len) static int inet_csk_diag_dump(struct sock *sk, struct sk_buff *skb, struct netlink_callback *cb, - struct inet_diag_req_v2 *r, + const struct inet_diag_req_v2 *r, const struct nlattr *bc) { if (!inet_diag_bc_sk(bc, sk)) @@ -667,7 +667,7 @@ static void twsk_build_assert(void) static int inet_twsk_diag_dump(struct sock *sk, struct sk_buff *skb, struct netlink_callback *cb, - struct inet_diag_req_v2 *r, + const struct inet_diag_req_v2 *r, const struct nlattr *bc) { twsk_build_assert(); @@ -770,7 +770,7 @@ static int inet_diag_fill_req(struct sk_buff *skb, struct sock *sk, static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk, struct netlink_callback *cb, - struct inet_diag_req_v2 *r, + const struct inet_diag_req_v2 *r, const struct nlattr *bc) { struct inet_connection_sock *icsk = inet_csk(sk); @@ -842,7 +842,7 @@ out: void inet_diag_dump_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *skb, struct netlink_callback *cb, - struct inet_diag_req_v2 *r, struct nlattr *bc) + const struct inet_diag_req_v2 *r, struct nlattr *bc) { struct net *net = sock_net(skb->sk); int i, num, s_i, s_num; @@ -978,7 +978,7 @@ out: EXPORT_SYMBOL_GPL(inet_diag_dump_icsk); static int __inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb, - struct inet_diag_req_v2 *r, + const struct inet_diag_req_v2 *r, struct nlattr *bc) { const struct inet_diag_handler *handler; diff --git a/net/ipv4/tcp_diag.c b/net/ipv4/tcp_diag.c index 0d73f9ddb55b..86dc119a3815 100644 --- a/net/ipv4/tcp_diag.c +++ b/net/ipv4/tcp_diag.c @@ -34,13 +34,13 @@ static void tcp_diag_get_info(struct sock *sk, struct inet_diag_msg *r, } static void tcp_diag_dump(struct sk_buff *skb, struct netlink_callback *cb, - struct inet_diag_req_v2 *r, struct nlattr *bc) + const struct inet_diag_req_v2 *r, struct nlattr *bc) { inet_diag_dump_icsk(&tcp_hashinfo, skb, cb, r, bc); } static int tcp_diag_dump_one(struct sk_buff *in_skb, const struct nlmsghdr *nlh, - struct inet_diag_req_v2 *req) + const struct inet_diag_req_v2 *req) { return inet_diag_dump_one_icsk(&tcp_hashinfo, in_skb, nlh, req); } diff --git a/net/ipv4/udp_diag.c b/net/ipv4/udp_diag.c index 4a000f1dd757..2dbfc1f1f7b3 100644 --- a/net/ipv4/udp_diag.c +++ b/net/ipv4/udp_diag.c @@ -18,8 +18,9 @@ #include static int sk_diag_dump(struct sock *sk, struct sk_buff *skb, - struct netlink_callback *cb, struct inet_diag_req_v2 *req, - struct nlattr *bc) + struct netlink_callback *cb, + const struct inet_diag_req_v2 *req, + struct nlattr *bc) { if (!inet_diag_bc_sk(bc, sk)) return 0; @@ -31,7 +32,8 @@ static int sk_diag_dump(struct sock *sk, struct sk_buff *skb, } static int udp_dump_one(struct udp_table *tbl, struct sk_buff *in_skb, - const struct nlmsghdr *nlh, struct inet_diag_req_v2 *req) + const struct nlmsghdr *nlh, + const struct inet_diag_req_v2 *req) { int err = -EINVAL; struct sock *sk; @@ -90,8 +92,9 @@ out_nosk: return err; } -static void udp_dump(struct udp_table *table, struct sk_buff *skb, struct netlink_callback *cb, - struct inet_diag_req_v2 *r, struct nlattr *bc) +static void udp_dump(struct udp_table *table, struct sk_buff *skb, + struct netlink_callback *cb, + const struct inet_diag_req_v2 *r, struct nlattr *bc) { int num, s_num, slot, s_slot; struct net *net = sock_net(skb->sk); @@ -144,13 +147,13 @@ done: } static void udp_diag_dump(struct sk_buff *skb, struct netlink_callback *cb, - struct inet_diag_req_v2 *r, struct nlattr *bc) + const struct inet_diag_req_v2 *r, struct nlattr *bc) { udp_dump(&udp_table, skb, cb, r, bc); } static int udp_diag_dump_one(struct sk_buff *in_skb, const struct nlmsghdr *nlh, - struct inet_diag_req_v2 *req) + const struct inet_diag_req_v2 *req) { return udp_dump_one(&udp_table, in_skb, nlh, req); } @@ -170,13 +173,14 @@ static const struct inet_diag_handler udp_diag_handler = { }; static void udplite_diag_dump(struct sk_buff *skb, struct netlink_callback *cb, - struct inet_diag_req_v2 *r, struct nlattr *bc) + const struct inet_diag_req_v2 *r, + struct nlattr *bc) { udp_dump(&udplite_table, skb, cb, r, bc); } static int udplite_diag_dump_one(struct sk_buff *in_skb, const struct nlmsghdr *nlh, - struct inet_diag_req_v2 *req) + const struct inet_diag_req_v2 *req) { return udp_dump_one(&udplite_table, in_skb, nlh, req); } -- GitLab From 406ef2a67bd0bb13d77d5e5d700e36a2caea09ae Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Tue, 10 Mar 2015 20:14:27 +0200 Subject: [PATCH 03743/11651] Bluetooth: Make Fast Connectable available while powered off To maximize the usability of the Fast Connectable feature we should make it possible to set (or unset) it at any given moment. This means removing the dependency on the 'connectable' setting as well as the 'powered' setting. The former makes also sense since page scan may get enabled through add_device even if 'connectable' is false. To keep the setting available over power cycles its flag also needs to be removed from the flags that are cleared upon HCI_Reset. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- include/net/bluetooth/hci.h | 2 +- net/bluetooth/mgmt.c | 30 ++++++++++++------------------ 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index 8e54f825153c..f76f45ae76c3 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -231,7 +231,7 @@ enum { * or the HCI device is closed. */ #define HCI_PERSISTENT_MASK (BIT(HCI_LE_SCAN) | BIT(HCI_PERIODIC_INQ) | \ - BIT(HCI_FAST_CONNECTABLE) | BIT(HCI_LE_ADV)) + BIT(HCI_LE_ADV)) /* HCI timeouts */ #define HCI_DISCONN_TIMEOUT msecs_to_jiffies(2000) /* 2 seconds */ diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index d769b428b630..49b8e09ffe67 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -1968,15 +1968,6 @@ static int set_connectable(struct sock *sk, struct hci_dev *hdev, void *data, } no_scan_update: - /* If we're going from non-connectable to connectable or - * vice-versa when fast connectable is enabled ensure that fast - * connectable gets disabled. write_fast_connectable won't do - * anything if the page scan parameters are already what they - * should be. - */ - if (cp->val || test_bit(HCI_FAST_CONNECTABLE, &hdev->dev_flags)) - write_fast_connectable(&req, false); - /* Update the advertising parameters if necessary */ if (test_bit(HCI_ADVERTISING, &hdev->dev_flags)) enable_advertising(&req); @@ -4660,14 +4651,6 @@ static int set_fast_connectable(struct sock *sk, struct hci_dev *hdev, return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE, MGMT_STATUS_INVALID_PARAMS); - if (!hdev_is_powered(hdev)) - return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE, - MGMT_STATUS_NOT_POWERED); - - if (!test_bit(HCI_CONNECTABLE, &hdev->dev_flags)) - return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE, - MGMT_STATUS_REJECTED); - hci_dev_lock(hdev); if (mgmt_pending_find(MGMT_OP_SET_FAST_CONNECTABLE, hdev)) { @@ -4682,6 +4665,14 @@ static int set_fast_connectable(struct sock *sk, struct hci_dev *hdev, goto unlock; } + if (!hdev_is_powered(hdev)) { + change_bit(HCI_FAST_CONNECTABLE, &hdev->dev_flags); + err = send_settings_rsp(sk, MGMT_OP_SET_FAST_CONNECTABLE, + hdev); + new_settings(hdev, sk); + goto unlock; + } + cmd = mgmt_pending_add(sk, MGMT_OP_SET_FAST_CONNECTABLE, hdev, data, len); if (!cmd) { @@ -6481,7 +6472,10 @@ static int powered_update_hci(struct hci_dev *hdev) sizeof(link_sec), &link_sec); if (lmp_bredr_capable(hdev)) { - write_fast_connectable(&req, false); + if (test_bit(HCI_FAST_CONNECTABLE, &hdev->dev_flags)) + write_fast_connectable(&req, true); + else + write_fast_connectable(&req, false); __hci_update_page_scan(&req); update_class(&req); update_name(&req); -- GitLab From 8bf1268f48ad9bf5d6401b4db913e6d85b0863f6 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 10 Mar 2015 16:41:35 +0000 Subject: [PATCH 03744/11651] ARM: dma-api: fix off-by-one error in __dma_supported() When validating the mask against the amount of memory we have available (so that we can trap 32-bit DMA addresses with >32-bits memory), we had not taken account of the fact that max_pfn is the maximum PFN number plus one that would be in the system. There are several references in the code which bear this out: mm/page_owner.c: for (; pfn < max_pfn; pfn++) { } arch/x86/kernel/setup.c: high_memory = (void *)__va(max_pfn * PAGE_SIZE - 1) Signed-off-by: Russell King --- arch/arm/mm/dma-mapping.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 170a116d1b29..c27447653903 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -171,7 +171,7 @@ static int __dma_supported(struct device *dev, u64 mask, bool warn) */ if (sizeof(mask) != sizeof(dma_addr_t) && mask > (dma_addr_t)~0 && - dma_to_pfn(dev, ~0) < max_pfn) { + dma_to_pfn(dev, ~0) < max_pfn - 1) { if (warn) { dev_warn(dev, "Coherent DMA mask %#llx is larger than dma_addr_t allows\n", mask); -- GitLab From 6d021b724481fbb908eb29384898deb9f00dfe70 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 10 Mar 2015 19:40:55 +0000 Subject: [PATCH 03745/11651] ARM: dump pgd, pmd and pte states on unhandled data abort faults It can be useful to dump the page table entries when an unhandled data abort fault occurs. This can aid debugging of these situations, for example, a STREX instruction causing an external abort on non-linefetch fault, as has been reported recently. Signed-off-by: Russell King --- arch/arm/mm/fault.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index a982dc3190df..6333d9c17875 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c @@ -552,6 +552,7 @@ do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs) pr_alert("Unhandled fault: %s (0x%03x) at 0x%08lx\n", inf->name, fsr, addr); + show_pte(current->mm, addr); info.si_signo = inf->sig; info.si_errno = 0; -- GitLab From 4933b29bd4e007a0544c97ea47fa0a091c5fec53 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Tue, 10 Mar 2015 22:46:52 +0530 Subject: [PATCH 03746/11651] staging: sm750fb: remove unused functions removed the functions which were not used anywhere. it has been build tested also confirmed with git grep that there is no other reference of these functions. Signed-off-by: Sudip Mukherjee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sm750fb/ddk750_display.c | 11 ---- drivers/staging/sm750fb/ddk750_swi2c.c | 8 --- drivers/staging/sm750fb/sm750.c | 65 ------------------------ 3 files changed, 84 deletions(-) diff --git a/drivers/staging/sm750fb/ddk750_display.c b/drivers/staging/sm750fb/ddk750_display.c index 57192e5b4730..a282a9492cc0 100644 --- a/drivers/staging/sm750fb/ddk750_display.c +++ b/drivers/staging/sm750fb/ddk750_display.c @@ -201,17 +201,6 @@ static void waitNextVerticalSync(int ctrl,int delay) } } -static void swPanelPowerSequence_sm750le(int disp,int delay) -{ - unsigned int reg; - reg = PEEK32(DISPLAY_CONTROL_750LE); - if(disp) - reg |= 0xf; - else - reg &= ~0xf; - POKE32(DISPLAY_CONTROL_750LE,reg); -} - static void swPanelPowerSequence(int disp,int delay) { unsigned int reg; diff --git a/drivers/staging/sm750fb/ddk750_swi2c.c b/drivers/staging/sm750fb/ddk750_swi2c.c index cae6b9bc6472..1249759eb347 100644 --- a/drivers/staging/sm750fb/ddk750_swi2c.c +++ b/drivers/staging/sm750fb/ddk750_swi2c.c @@ -79,14 +79,6 @@ static unsigned long g_i2cDataGPIOMuxReg = GPIO_MUX; static unsigned long g_i2cDataGPIODataReg = GPIO_DATA; static unsigned long g_i2cDataGPIODataDirReg = GPIO_DATA_DIRECTION; -static unsigned char peekIO(unsigned short port,unsigned short index) -{ -#if defined(__i386__) || defined( __x86_64__) - outb_p(index,port); - return inb_p(port+1); -#endif -} - /* * This function puts a delay between command */ diff --git a/drivers/staging/sm750fb/sm750.c b/drivers/staging/sm750fb/sm750.c index 8c260ee5597d..87029b61ce83 100644 --- a/drivers/staging/sm750fb/sm750.c +++ b/drivers/staging/sm750fb/sm750.c @@ -510,69 +510,6 @@ static int lynxfb_resume(struct pci_dev* pdev) } #endif -static int lynxfb_ops_mmap(struct fb_info * info, struct vm_area_struct * vma) -{ - unsigned long off; - unsigned long start; - u32 len; - struct file *file; - - file = vma->vm_file; - - if (!info) - return -ENODEV; - if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) - return -EINVAL; - off = vma->vm_pgoff << PAGE_SHIFT; - printk("lynxfb mmap pgoff: %lx\n", vma->vm_pgoff); - printk("lynxfb mmap off 1: %lx\n", off); - - /* frame buffer memory */ - start = info->fix.smem_start; - len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.smem_len); - - printk("lynxfb mmap start 1: %lx\n", start); - printk("lynxfb mmap len 1: %x\n", len); - - if (off >= len) { - /* memory mapped io */ - off -= len; - printk("lynxfb mmap off 2: %lx\n", off); - if (info->var.accel_flags) { - printk("lynxfb mmap accel flags true"); - return -EINVAL; - } - start = info->fix.mmio_start; - len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.mmio_len); - - printk("lynxfb mmap start 2: %lx\n", start); - printk("lynxfb mmap len 2: %x\n", len); - } - start &= PAGE_MASK; - printk("lynxfb mmap start 3: %lx\n", start); - printk("lynxfb mmap vm start: %lx\n", vma->vm_start); - printk("lynxfb mmap vm end: %lx\n", vma->vm_end); - printk("lynxfb mmap len: %x\n", len); - printk("lynxfb mmap off: %lx\n", off); - if ((vma->vm_end - vma->vm_start + off) > len) - { - return -EINVAL; - } - off += start; - printk("lynxfb mmap off 3: %lx\n", off); - vma->vm_pgoff = off >> PAGE_SHIFT; - /* This is an IO map - tell maydump to skip this VMA */ - vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP; - vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); - fb_pgprotect(file, vma, off); - printk("lynxfb mmap off 4: %lx\n", off); - printk("lynxfb mmap pgprot: %lx\n", (unsigned long) pgprot_val(vma->vm_page_prot)); - if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, - vma->vm_end - vma->vm_start, vma->vm_page_prot)) - return -EAGAIN; - return 0; -} - static int lynxfb_ops_check_var(struct fb_var_screeninfo* var,struct fb_info* info) { struct lynxfb_par * par; @@ -824,8 +761,6 @@ static struct fb_ops lynxfb_ops={ .fb_set_par = lynxfb_ops_set_par, .fb_setcolreg = lynxfb_ops_setcolreg, .fb_blank = lynxfb_ops_blank, - /*.fb_mmap = lynxfb_ops_mmap,*/ - /* will be hooked by hardware */ .fb_fillrect = cfb_fillrect, .fb_imageblit = cfb_imageblit, .fb_copyarea = cfb_copyarea, -- GitLab From 041d3a42e7d823e89b593d47338d6840b38cbcd3 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Tue, 10 Mar 2015 22:46:53 +0530 Subject: [PATCH 03747/11651] staging: sm750fb: remove unused variables removed some variables which were only declared but were never used. Signed-off-by: Sudip Mukherjee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sm750fb/sm750_cursor.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/sm750fb/sm750_cursor.c b/drivers/staging/sm750fb/sm750_cursor.c index 480615cb6650..fca441e9c2dd 100644 --- a/drivers/staging/sm750fb/sm750_cursor.c +++ b/drivers/staging/sm750fb/sm750_cursor.c @@ -99,7 +99,6 @@ void hw_cursor_setData(struct lynx_cursor * cursor, u8 color,mask,opr; u16 data; u16 * pbuffer,*pstart; - static ulong odd = 0; /* in byte*/ pitch = cursor->w >> 3; @@ -188,7 +187,7 @@ void hw_cursor_setData2(struct lynx_cursor * cursor, u16 rop,const u8* pcol,const u8* pmsk) { int i,j,count,pitch,offset; - u8 color,mask,opr; + u8 color, mask; u16 data; u16 * pbuffer,*pstart; -- GitLab From 54a1a05fe270f87e755732a47f693de870d0ffec Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Tue, 10 Mar 2015 22:46:54 +0530 Subject: [PATCH 03748/11651] staging: sm750fb: correct function return hw_cursor_setData2() is a function with void return type but it was returning an integer. Signed-off-by: Sudip Mukherjee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sm750fb/sm750_cursor.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/sm750fb/sm750_cursor.c b/drivers/staging/sm750fb/sm750_cursor.c index fca441e9c2dd..6cceef107c37 100644 --- a/drivers/staging/sm750fb/sm750_cursor.c +++ b/drivers/staging/sm750fb/sm750_cursor.c @@ -248,6 +248,4 @@ void hw_cursor_setData2(struct lynx_cursor * cursor, } } - return 0; - } -- GitLab From 06a1bf813607ceb836d2b4b7c415a187253ea4ad Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Tue, 10 Mar 2015 22:46:56 +0530 Subject: [PATCH 03749/11651] staging: sm750fb: fix mixed declarations we were getting build warning about mixed declaration. the variable is now declared at the beginning of the block. Signed-off-by: Sudip Mukherjee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sm750fb/sm750.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/sm750fb/sm750.c b/drivers/staging/sm750fb/sm750.c index 87029b61ce83..021b863dda95 100644 --- a/drivers/staging/sm750fb/sm750.c +++ b/drivers/staging/sm750fb/sm750.c @@ -1175,6 +1175,7 @@ ALLOC_FB: else { struct lynxfb_par * par; + int errno; pr_info("framebuffer #%d alloc okay\n",fbidx); share->fbinfo[fbidx] = info[fbidx]; par = info[fbidx]->par; @@ -1191,7 +1192,7 @@ ALLOC_FB: /* register frame buffer*/ pr_info("Ready to register framebuffer #%d.\n",fbidx); - int errno = register_framebuffer(info[fbidx]); + errno = register_framebuffer(info[fbidx]); if (errno < 0) { pr_err("Failed to register fb_info #%d. err %d\n",fbidx, errno); if(fbidx == 0) -- GitLab From 0fa96e39279988bde14cb6cf6cd0440185f2dae4 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Tue, 10 Mar 2015 22:46:57 +0530 Subject: [PATCH 03750/11651] staging: sm750fb: correct integer comparison fixed the build warning about comparison of pointer and integer. end of string was being compared to NULL. Signed-off-by: Sudip Mukherjee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sm750fb/sm750.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/sm750fb/sm750.c b/drivers/staging/sm750fb/sm750.c index 021b863dda95..5532a28e6030 100644 --- a/drivers/staging/sm750fb/sm750.c +++ b/drivers/staging/sm750fb/sm750.c @@ -1000,7 +1000,7 @@ static void sm750fb_setup(struct lynx_share * share,char * src) goto NO_PARAM; } - while((opt = strsep(&src,":")) != NULL && *opt != NULL){ + while((opt = strsep(&src,":")) != NULL && *opt != 0){ pr_err("opt=%s\n",opt); pr_err("src=%s\n",src); -- GitLab From 7768eed8bf1d2e5eefa38c573f15f737a9824052 Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Tue, 10 Mar 2015 19:03:46 +0100 Subject: [PATCH 03751/11651] net: add comment for sock_efree() usage Signed-off-by: Oliver Hartkopp Acked-by: Alexander Duyck Signed-off-by: David S. Miller --- net/core/sock.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/net/core/sock.c b/net/core/sock.c index 93c8b20c91e4..78e89eb7eb70 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -1655,6 +1655,10 @@ void sock_rfree(struct sk_buff *skb) } EXPORT_SYMBOL(sock_rfree); +/* + * Buffer destructor for skbs that are not used directly in read or write + * path, e.g. for error handler skbs. Automatically called from kfree_skb. + */ void sock_efree(struct sk_buff *skb) { sock_put(skb->sk); -- GitLab From 2bf4c1d483d911cda5dd385527194d23e5cea73d Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 10 Mar 2015 12:39:03 +0100 Subject: [PATCH 03752/11651] ASoC: adav80x: Fix wrong value references for boolean kctl The correct values referred by a boolean control are value.integer.value[], not value.enumerated.item[]. The former is long while the latter is int, so it's even incompatible on 64bit architectures. Signed-off-by: Takashi Iwai Acked-by: Lars-Peter Clausen Signed-off-by: Mark Brown Cc: --- sound/soc/codecs/adav80x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/adav80x.c b/sound/soc/codecs/adav80x.c index b67480f1b1aa..4373ada95648 100644 --- a/sound/soc/codecs/adav80x.c +++ b/sound/soc/codecs/adav80x.c @@ -317,7 +317,7 @@ static int adav80x_put_deemph(struct snd_kcontrol *kcontrol, { struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); - unsigned int deemph = ucontrol->value.enumerated.item[0]; + unsigned int deemph = ucontrol->value.integer.value[0]; if (deemph > 1) return -EINVAL; @@ -333,7 +333,7 @@ static int adav80x_get_deemph(struct snd_kcontrol *kcontrol, struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); - ucontrol->value.enumerated.item[0] = adav80x->deemph; + ucontrol->value.integer.value[0] = adav80x->deemph; return 0; }; -- GitLab From a99e334da16ce81163db0e47ec22469a79a91b72 Mon Sep 17 00:00:00 2001 From: Madhusudhanan Ravindran Date: Tue, 10 Mar 2015 23:07:39 +0530 Subject: [PATCH 03753/11651] staging: sm750fb: Use kzalloc rather than kmalloc followed by memset with 0 The semantic patch that makes this change is available in scriptcoccinelle/api/alloc/kzalloc-simple.cocci. Signed-off-by: Madhusudhanan Ravindran Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sm750fb/sm750.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/sm750fb/sm750.c b/drivers/staging/sm750fb/sm750.c index 5532a28e6030..aa0888c232b9 100644 --- a/drivers/staging/sm750fb/sm750.c +++ b/drivers/staging/sm750fb/sm750.c @@ -1278,11 +1278,10 @@ static int __init lynxfb_setup(char * options) pr_info("options:%s\n",options); len = strlen(options) + 1; - g_settings = kmalloc(len,GFP_KERNEL); + g_settings = kzalloc(len, GFP_KERNEL); if(!g_settings) return -ENOMEM; - memset(g_settings,0,len); tmp = g_settings; /* Notes: -- GitLab From f8b0dced35e60a857e893648308e056915ffed4a Mon Sep 17 00:00:00 2001 From: Lorenzo Stoakes Date: Tue, 10 Mar 2015 15:25:47 +0000 Subject: [PATCH 03754/11651] staging: sm750fb: Cleanup the type of mmio750 This patch assigns the more appropriate void* type to the mmio750 variable eliminating an unnecessary volatile qualifier in the process. Additionally it updates parameter types as necessary where those parameters interact with mmio750, removes unnecessary casts and updates the type of the lynx_share->pvReg field which is passed to the ddk750_set_mmio method. As a consequence, this patch fixes the following sparse warning:- drivers/staging/sm750fb/ddk750_help.c:12:17: warning: incorrect type in assignment (different address spaces) Signed-off-by: Lorenzo Stoakes Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sm750fb/ddk750_chip.h | 4 +++- drivers/staging/sm750fb/ddk750_help.c | 4 ++-- drivers/staging/sm750fb/ddk750_help.h | 10 +++++----- drivers/staging/sm750fb/sm750.h | 2 +- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/drivers/staging/sm750fb/ddk750_chip.h b/drivers/staging/sm750fb/ddk750_chip.h index d761b722556f..04cb0d559245 100644 --- a/drivers/staging/sm750fb/ddk750_chip.h +++ b/drivers/staging/sm750fb/ddk750_chip.h @@ -5,6 +5,8 @@ #define SM750LE_REVISION_ID ((unsigned char)0xfe) #endif +#include + /* This is all the chips recognized by this library */ typedef enum _logical_chip_type_t { @@ -72,7 +74,7 @@ logical_chip_type_t getChipType(void); unsigned int calcPllValue(unsigned int request,pll_value_t *pll); unsigned int calcPllValue2(unsigned int,pll_value_t *); unsigned int formatPllReg(pll_value_t *pPLL); -void ddk750_set_mmio(volatile unsigned char *,unsigned short,char); +void ddk750_set_mmio(void __iomem *,unsigned short,char); unsigned int ddk750_getVMSize(void); int ddk750_initHw(initchip_param_t *); unsigned int getPllValue(clock_type_t clockType, pll_value_t *pPLL); diff --git a/drivers/staging/sm750fb/ddk750_help.c b/drivers/staging/sm750fb/ddk750_help.c index cc00d2b32436..c68ff3b5751a 100644 --- a/drivers/staging/sm750fb/ddk750_help.c +++ b/drivers/staging/sm750fb/ddk750_help.c @@ -2,12 +2,12 @@ //#include "ddk750_chip.h" #include "ddk750_help.h" -volatile unsigned char __iomem * mmio750 = NULL; +void __iomem * mmio750 = NULL; char revId750 = 0; unsigned short devId750 = 0; /* after driver mapped io registers, use this function first */ -void ddk750_set_mmio(volatile unsigned char * addr,unsigned short devId,char revId) +void ddk750_set_mmio(void __iomem * addr,unsigned short devId,char revId) { mmio750 = addr; devId750 = devId; diff --git a/drivers/staging/sm750fb/ddk750_help.h b/drivers/staging/sm750fb/ddk750_help.h index 4fc93b5d41c7..07c8264fac95 100644 --- a/drivers/staging/sm750fb/ddk750_help.h +++ b/drivers/staging/sm750fb/ddk750_help.h @@ -12,14 +12,14 @@ #if 0 /* if 718 big endian turned on,be aware that don't use this driver for general use,only for ppc big-endian */ #warning "big endian on target cpu and enable nature big endian support of 718 capability !" -#define PEEK32(addr) __raw_readl((void __iomem *)(mmio750)+(addr)) -#define POKE32(addr,data) __raw_writel((data),(void __iomem*)(mmio750)+(addr)) +#define PEEK32(addr) __raw_readl(mmio750 + addr) +#define POKE32(addr,data) __raw_writel(data, mmio750 + addr) #else /* software control endianess */ -#define PEEK32(addr) readl((addr)+mmio750) -#define POKE32(addr,data) writel((data),(addr)+mmio750) +#define PEEK32(addr) readl(addr + mmio750) +#define POKE32(addr,data) writel(data, addr + mmio750) #endif -extern volatile unsigned char __iomem * mmio750; +extern void __iomem * mmio750; extern char revId750; extern unsigned short devId750; #else diff --git a/drivers/staging/sm750fb/sm750.h b/drivers/staging/sm750fb/sm750.h index d39968c2d5c1..53611163fe91 100644 --- a/drivers/staging/sm750fb/sm750.h +++ b/drivers/staging/sm750fb/sm750.h @@ -63,7 +63,7 @@ struct lynx_share{ unsigned long vidreg_start; __u32 vidmem_size; __u32 vidreg_size; - volatile unsigned char __iomem * pvReg; + void __iomem * pvReg; unsigned char __iomem * pvMem; /* locks*/ spinlock_t slock; -- GitLab From 3ec320dd5c9465fbed3c84dd14ed3941ce757823 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 10 Mar 2015 11:25:41 -0700 Subject: [PATCH 03755/11651] fib_trie: Correctly handle case of key == 0 in leaf_walk_rcu In the case of a trie that had no tnodes with a key of 0 the initial look-up would fail resulting in an out-of-bounds cindex on the first tnode. This resulted in an entire trie being skipped. In order resolve this I have updated the cindex logic in the initial look-up so that if the key is zero we will always traverse the child zero path. Fixes: 8be33e95 ("fib_trie: Fib walk rcu should take a tnode and key instead of a trie and a leaf") Reported-by: Sabrina Dubroca Signed-off-by: Alexander Duyck Tested-by: Sabrina Dubroca Signed-off-by: David S. Miller --- net/ipv4/fib_trie.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index fcfa9825a816..44cab1d41463 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -1530,7 +1530,7 @@ static struct key_vector *leaf_walk_rcu(struct key_vector **tn, t_key key) do { /* record parent and next child index */ pn = n; - cindex = get_index(key, pn); + cindex = key ? get_index(key, pn) : 0; if (cindex >> pn->bits) break; -- GitLab From 08641d9b7bf915144a57a736b42642e13eb1167f Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 10 Mar 2015 12:39:04 +0100 Subject: [PATCH 03756/11651] ASoC: ak4641: Fix wrong value references for boolean kctl The correct values referred by a boolean control are value.integer.value[], not value.enumerated.item[]. The former is long while the latter is int, so it's even incompatible on 64bit architectures. Signed-off-by: Takashi Iwai Signed-off-by: Mark Brown Cc: --- sound/soc/codecs/ak4641.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/ak4641.c b/sound/soc/codecs/ak4641.c index 70861c7b1631..81b54a270bd8 100644 --- a/sound/soc/codecs/ak4641.c +++ b/sound/soc/codecs/ak4641.c @@ -76,7 +76,7 @@ static int ak4641_put_deemph(struct snd_kcontrol *kcontrol, { struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec); - int deemph = ucontrol->value.enumerated.item[0]; + int deemph = ucontrol->value.integer.value[0]; if (deemph > 1) return -EINVAL; @@ -92,7 +92,7 @@ static int ak4641_get_deemph(struct snd_kcontrol *kcontrol, struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec); - ucontrol->value.enumerated.item[0] = ak4641->deemph; + ucontrol->value.integer.value[0] = ak4641->deemph; return 0; }; -- GitLab From e8371aa0fecb73fb8a4b2e0296b025b11e7d6229 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 10 Mar 2015 12:39:05 +0100 Subject: [PATCH 03757/11651] ASoC: cs4271: Fix wrong value references for boolean kctl The correct values referred by a boolean control are value.integer.value[], not value.enumerated.item[]. The former is long while the latter is int, so it's even incompatible on 64bit architectures. Signed-off-by: Takashi Iwai Acked-by: Paul Handrigan Signed-off-by: Mark Brown Cc: --- sound/soc/codecs/cs4271.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c index 79a4efcb894c..7d3a6accaf9a 100644 --- a/sound/soc/codecs/cs4271.c +++ b/sound/soc/codecs/cs4271.c @@ -286,7 +286,7 @@ static int cs4271_get_deemph(struct snd_kcontrol *kcontrol, struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec); - ucontrol->value.enumerated.item[0] = cs4271->deemph; + ucontrol->value.integer.value[0] = cs4271->deemph; return 0; } @@ -296,7 +296,7 @@ static int cs4271_put_deemph(struct snd_kcontrol *kcontrol, struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec); - cs4271->deemph = ucontrol->value.enumerated.item[0]; + cs4271->deemph = ucontrol->value.integer.value[0]; return cs4271_set_deemph(codec); } -- GitLab From d223b0e7fcfecc23380e7de45eb6a0e7b328c17c Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 10 Mar 2015 12:39:06 +0100 Subject: [PATCH 03758/11651] ASoC: es8238: Fix wrong value references for boolean kctl The correct values referred by a boolean control are value.integer.value[], not value.enumerated.item[]. The former is long while the latter is int, so it's even incompatible on 64bit architectures. Signed-off-by: Takashi Iwai Signed-off-by: Mark Brown Cc: --- sound/soc/codecs/es8328.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/es8328.c b/sound/soc/codecs/es8328.c index f27325155ace..c5f35a07e8e4 100644 --- a/sound/soc/codecs/es8328.c +++ b/sound/soc/codecs/es8328.c @@ -120,7 +120,7 @@ static int es8328_get_deemph(struct snd_kcontrol *kcontrol, struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec); - ucontrol->value.enumerated.item[0] = es8328->deemph; + ucontrol->value.integer.value[0] = es8328->deemph; return 0; } @@ -129,7 +129,7 @@ static int es8328_put_deemph(struct snd_kcontrol *kcontrol, { struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec); - int deemph = ucontrol->value.enumerated.item[0]; + int deemph = ucontrol->value.integer.value[0]; int ret; if (deemph > 1) -- GitLab From d7f58db49d9ad92bdb12d21fdc2308b76bc2ed38 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 10 Mar 2015 12:39:07 +0100 Subject: [PATCH 03759/11651] ASoC: pcm1681: Fix wrong value references for boolean kctl The correct values referred by a boolean control are value.integer.value[], not value.enumerated.item[]. The former is long while the latter is int, so it's even incompatible on 64bit architectures. Signed-off-by: Takashi Iwai Signed-off-by: Mark Brown Cc: --- sound/soc/codecs/pcm1681.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/pcm1681.c b/sound/soc/codecs/pcm1681.c index a722a023c262..477e13d30971 100644 --- a/sound/soc/codecs/pcm1681.c +++ b/sound/soc/codecs/pcm1681.c @@ -118,7 +118,7 @@ static int pcm1681_get_deemph(struct snd_kcontrol *kcontrol, struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct pcm1681_private *priv = snd_soc_codec_get_drvdata(codec); - ucontrol->value.enumerated.item[0] = priv->deemph; + ucontrol->value.integer.value[0] = priv->deemph; return 0; } @@ -129,7 +129,7 @@ static int pcm1681_put_deemph(struct snd_kcontrol *kcontrol, struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct pcm1681_private *priv = snd_soc_codec_get_drvdata(codec); - priv->deemph = ucontrol->value.enumerated.item[0]; + priv->deemph = ucontrol->value.integer.value[0]; return pcm1681_set_deemph(codec); } -- GitLab From 4c523ef61160b7d478371ddc9f48c8ce0a00d675 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 10 Mar 2015 12:39:08 +0100 Subject: [PATCH 03760/11651] ASoC: tas5086: Fix wrong value references for boolean kctl The correct values referred by a boolean control are value.integer.value[], not value.enumerated.item[]. The former is long while the latter is int, so it's even incompatible on 64bit architectures. Signed-off-by: Takashi Iwai Signed-off-by: Mark Brown Cc: --- sound/soc/codecs/tas5086.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/tas5086.c b/sound/soc/codecs/tas5086.c index 249ef5c4c762..32942bed34b1 100644 --- a/sound/soc/codecs/tas5086.c +++ b/sound/soc/codecs/tas5086.c @@ -281,7 +281,7 @@ static int tas5086_get_deemph(struct snd_kcontrol *kcontrol, struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec); - ucontrol->value.enumerated.item[0] = priv->deemph; + ucontrol->value.integer.value[0] = priv->deemph; return 0; } @@ -292,7 +292,7 @@ static int tas5086_put_deemph(struct snd_kcontrol *kcontrol, struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec); - priv->deemph = ucontrol->value.enumerated.item[0]; + priv->deemph = ucontrol->value.integer.value[0]; return tas5086_set_deemph(codec); } -- GitLab From 00a14c2968e3d55817e0fa35c78106ca840537bf Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 10 Mar 2015 12:39:09 +0100 Subject: [PATCH 03761/11651] ASoC: wm2000: Fix wrong value references for boolean kctl The correct values referred by a boolean control are value.integer.value[], not value.enumerated.item[]. The former is long while the latter is int, so it's even incompatible on 64bit architectures. Signed-off-by: Takashi Iwai Acked-by: Charles Keepax Signed-off-by: Mark Brown Cc: --- sound/soc/codecs/wm2000.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c index 8d9de49a5052..21d5402e343f 100644 --- a/sound/soc/codecs/wm2000.c +++ b/sound/soc/codecs/wm2000.c @@ -610,7 +610,7 @@ static int wm2000_anc_mode_get(struct snd_kcontrol *kcontrol, struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); - ucontrol->value.enumerated.item[0] = wm2000->anc_active; + ucontrol->value.integer.value[0] = wm2000->anc_active; return 0; } @@ -620,7 +620,7 @@ static int wm2000_anc_mode_put(struct snd_kcontrol *kcontrol, { struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); - int anc_active = ucontrol->value.enumerated.item[0]; + int anc_active = ucontrol->value.integer.value[0]; int ret; if (anc_active > 1) @@ -643,7 +643,7 @@ static int wm2000_speaker_get(struct snd_kcontrol *kcontrol, struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); - ucontrol->value.enumerated.item[0] = wm2000->spk_ena; + ucontrol->value.integer.value[0] = wm2000->spk_ena; return 0; } @@ -653,7 +653,7 @@ static int wm2000_speaker_put(struct snd_kcontrol *kcontrol, { struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); - int val = ucontrol->value.enumerated.item[0]; + int val = ucontrol->value.integer.value[0]; int ret; if (val > 1) -- GitLab From bd14016fbf31aa199026f1e2358eab695f374eb1 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 10 Mar 2015 12:39:10 +0100 Subject: [PATCH 03762/11651] ASoC: wm8731: Fix wrong value references for boolean kctl The correct values referred by a boolean control are value.integer.value[], not value.enumerated.item[]. The former is long while the latter is int, so it's even incompatible on 64bit architectures. Signed-off-by: Takashi Iwai Acked-by: Charles Keepax Signed-off-by: Mark Brown Cc: --- sound/soc/codecs/wm8731.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index 098c143f44d6..c6d10533e2bd 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c @@ -125,7 +125,7 @@ static int wm8731_get_deemph(struct snd_kcontrol *kcontrol, struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); - ucontrol->value.enumerated.item[0] = wm8731->deemph; + ucontrol->value.integer.value[0] = wm8731->deemph; return 0; } @@ -135,7 +135,7 @@ static int wm8731_put_deemph(struct snd_kcontrol *kcontrol, { struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); - int deemph = ucontrol->value.enumerated.item[0]; + int deemph = ucontrol->value.integer.value[0]; int ret = 0; if (deemph > 1) -- GitLab From 24cc883c1fd16df34211ae41624aa6d3cd906693 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 10 Mar 2015 12:39:11 +0100 Subject: [PATCH 03763/11651] ASoC: wm8903: Fix wrong value references for boolean kctl The correct values referred by a boolean control are value.integer.value[], not value.enumerated.item[]. The former is long while the latter is int, so it's even incompatible on 64bit architectures. Signed-off-by: Takashi Iwai Acked-by: Charles Keepax Signed-off-by: Mark Brown Cc: --- sound/soc/codecs/wm8903.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index dde462c082be..04b04f8e147c 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c @@ -442,7 +442,7 @@ static int wm8903_get_deemph(struct snd_kcontrol *kcontrol, struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); - ucontrol->value.enumerated.item[0] = wm8903->deemph; + ucontrol->value.integer.value[0] = wm8903->deemph; return 0; } @@ -452,7 +452,7 @@ static int wm8903_put_deemph(struct snd_kcontrol *kcontrol, { struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); - int deemph = ucontrol->value.enumerated.item[0]; + int deemph = ucontrol->value.integer.value[0]; int ret = 0; if (deemph > 1) -- GitLab From eaddf6fd959074f6a6e71deffe079c71eef35da6 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 10 Mar 2015 12:39:12 +0100 Subject: [PATCH 03764/11651] ASoC: wm8904: Fix wrong value references for boolean kctl The correct values referred by a boolean control are value.integer.value[], not value.enumerated.item[]. The former is long while the latter is int, so it's even incompatible on 64bit architectures. Signed-off-by: Takashi Iwai Acked-by: Charles Keepax Signed-off-by: Mark Brown Cc: --- sound/soc/codecs/wm8904.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index d3b3f57668cc..215e93c1ddf0 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c @@ -525,7 +525,7 @@ static int wm8904_get_deemph(struct snd_kcontrol *kcontrol, struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); - ucontrol->value.enumerated.item[0] = wm8904->deemph; + ucontrol->value.integer.value[0] = wm8904->deemph; return 0; } @@ -534,7 +534,7 @@ static int wm8904_put_deemph(struct snd_kcontrol *kcontrol, { struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); - int deemph = ucontrol->value.enumerated.item[0]; + int deemph = ucontrol->value.integer.value[0]; if (deemph > 1) return -EINVAL; -- GitLab From 07892b10356f17717abdc578acbef72db86c880e Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 10 Mar 2015 12:39:13 +0100 Subject: [PATCH 03765/11651] ASoC: wm8955: Fix wrong value references for boolean kctl The correct values referred by a boolean control are value.integer.value[], not value.enumerated.item[]. The former is long while the latter is int, so it's even incompatible on 64bit architectures. Signed-off-by: Takashi Iwai Acked-by: Charles Keepax Signed-off-by: Mark Brown Cc: --- sound/soc/codecs/wm8955.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c index 1ab2d462afad..00bec915d652 100644 --- a/sound/soc/codecs/wm8955.c +++ b/sound/soc/codecs/wm8955.c @@ -393,7 +393,7 @@ static int wm8955_get_deemph(struct snd_kcontrol *kcontrol, struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec); - ucontrol->value.enumerated.item[0] = wm8955->deemph; + ucontrol->value.integer.value[0] = wm8955->deemph; return 0; } @@ -402,7 +402,7 @@ static int wm8955_put_deemph(struct snd_kcontrol *kcontrol, { struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec); - int deemph = ucontrol->value.enumerated.item[0]; + int deemph = ucontrol->value.integer.value[0]; if (deemph > 1) return -EINVAL; -- GitLab From b4a18c8b1af15ebfa9054a3d2aef7b0a7e6f2a05 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 10 Mar 2015 12:39:14 +0100 Subject: [PATCH 03766/11651] ASoC: wm8960: Fix wrong value references for boolean kctl The correct values referred by a boolean control are value.integer.value[], not value.enumerated.item[]. The former is long while the latter is int, so it's even incompatible on 64bit architectures. Signed-off-by: Takashi Iwai Acked-by: Charles Keepax Signed-off-by: Mark Brown Cc: --- sound/soc/codecs/wm8960.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c index cf8fecf97f2c..3035d9856415 100644 --- a/sound/soc/codecs/wm8960.c +++ b/sound/soc/codecs/wm8960.c @@ -184,7 +184,7 @@ static int wm8960_get_deemph(struct snd_kcontrol *kcontrol, struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); - ucontrol->value.enumerated.item[0] = wm8960->deemph; + ucontrol->value.integer.value[0] = wm8960->deemph; return 0; } @@ -193,7 +193,7 @@ static int wm8960_put_deemph(struct snd_kcontrol *kcontrol, { struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); - int deemph = ucontrol->value.enumerated.item[0]; + int deemph = ucontrol->value.integer.value[0]; if (deemph > 1) return -EINVAL; -- GitLab From 4b0b669b86a963f71feaa1a694e881832fdf4f86 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 10 Mar 2015 12:39:15 +0100 Subject: [PATCH 03767/11651] ASoC: wm9712: Fix wrong value references for boolean kctl The correct values referred by a boolean control are value.integer.value[], not value.enumerated.item[]. The former is long while the latter is int, so it's even incompatible on 64bit architectures. Signed-off-by: Takashi Iwai Acked-by: Charles Keepax Signed-off-by: Mark Brown Cc: --- sound/soc/codecs/wm9712.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index 9517571e820d..98c9525bd751 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c @@ -180,7 +180,7 @@ static int wm9712_hp_mixer_put(struct snd_kcontrol *kcontrol, struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol); struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm); struct wm9712_priv *wm9712 = snd_soc_codec_get_drvdata(codec); - unsigned int val = ucontrol->value.enumerated.item[0]; + unsigned int val = ucontrol->value.integer.value[0]; struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; unsigned int mixer, mask, shift, old; @@ -193,7 +193,7 @@ static int wm9712_hp_mixer_put(struct snd_kcontrol *kcontrol, mutex_lock(&wm9712->lock); old = wm9712->hp_mixer[mixer]; - if (ucontrol->value.enumerated.item[0]) + if (ucontrol->value.integer.value[0]) wm9712->hp_mixer[mixer] |= mask; else wm9712->hp_mixer[mixer] &= ~mask; @@ -231,7 +231,7 @@ static int wm9712_hp_mixer_get(struct snd_kcontrol *kcontrol, mixer = mc->shift >> 8; shift = mc->shift & 0xff; - ucontrol->value.enumerated.item[0] = + ucontrol->value.integer.value[0] = (wm9712->hp_mixer[mixer] >> shift) & 1; return 0; -- GitLab From 87a8b286e2f63c048a586dc677140d4a5b5808aa Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 10 Mar 2015 12:39:16 +0100 Subject: [PATCH 03768/11651] ASoC: wm9713: Fix wrong value references for boolean kctl The correct values referred by a boolean control are value.integer.value[], not value.enumerated.item[]. The former is long while the latter is int, so it's even incompatible on 64bit architectures. Signed-off-by: Takashi Iwai Acked-by: Charles Keepax Signed-off-by: Mark Brown Cc: --- sound/soc/codecs/wm9713.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index 68222917b396..79552953e1bd 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c @@ -255,7 +255,7 @@ static int wm9713_hp_mixer_put(struct snd_kcontrol *kcontrol, struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol); struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm); struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec); - unsigned int val = ucontrol->value.enumerated.item[0]; + unsigned int val = ucontrol->value.integer.value[0]; struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; unsigned int mixer, mask, shift, old; @@ -268,7 +268,7 @@ static int wm9713_hp_mixer_put(struct snd_kcontrol *kcontrol, mutex_lock(&wm9713->lock); old = wm9713->hp_mixer[mixer]; - if (ucontrol->value.enumerated.item[0]) + if (ucontrol->value.integer.value[0]) wm9713->hp_mixer[mixer] |= mask; else wm9713->hp_mixer[mixer] &= ~mask; @@ -306,7 +306,7 @@ static int wm9713_hp_mixer_get(struct snd_kcontrol *kcontrol, mixer = mc->shift >> 8; shift = mc->shift & 0xff; - ucontrol->value.enumerated.item[0] = + ucontrol->value.integer.value[0] = (wm9713->hp_mixer[mixer] >> shift) & 1; return 0; -- GitLab From 3009de604831e6dd908c39c05fd063bd668edb0e Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 10 Mar 2015 21:20:52 +0100 Subject: [PATCH 03769/11651] Staging: sm750fb: fix build warning with proc_panDisplay Change the options to the proc_panDisplay function pointer to match the function pointer that we want to assign to it, in order to remove the build warning. Cc: Sudip Mukherjee Cc: Teddy Wang Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/staging/sm750fb/sm750.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/staging/sm750fb/sm750.h b/drivers/staging/sm750fb/sm750.h index 53611163fe91..efe999acbe46 100644 --- a/drivers/staging/sm750fb/sm750.h +++ b/drivers/staging/sm750fb/sm750.h @@ -120,8 +120,9 @@ struct lynxfb_crtc{ int(*proc_setColReg)(struct lynxfb_crtc*,ushort,ushort,ushort,ushort); void (*clear)(struct lynxfb_crtc*); /* pan display */ - int(*proc_panDisplay)(struct lynxfb_crtc*, struct fb_var_screeninfo*, - struct fb_info*); + int (*proc_panDisplay)(struct lynxfb_crtc *, + const struct fb_var_screeninfo *, + const struct fb_info *); /* cursor information */ struct lynx_cursor cursor; }; -- GitLab From bf2fbc2a12b42a1d3fd38b1da24cd4250df4f3ab Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 10 Mar 2015 21:29:38 +0100 Subject: [PATCH 03770/11651] Staging: sm750fb: fix build warning with lynx_accel Change the return value of lynx_accel to be void, to fix the build warning, and due to the fact that the function can't seem to fail at all, and no one cares if it does or not. Cc: Sudip Mukherjee Cc: Teddy Wang Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/staging/sm750fb/sm750.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/sm750fb/sm750.h b/drivers/staging/sm750fb/sm750.h index efe999acbe46..0847d2bd95c8 100644 --- a/drivers/staging/sm750fb/sm750.h +++ b/drivers/staging/sm750fb/sm750.h @@ -23,7 +23,7 @@ struct lynx_accel{ volatile unsigned char __iomem * dpPortBase; /* function fointers */ - int (*de_init)(struct lynx_accel *); + void (*de_init)(struct lynx_accel *); int (*de_wait)(void);/* see if hardware ready to work */ -- GitLab From 25140ce627f43df1d425d591ac3d360b48ae24e1 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sat, 21 Feb 2015 18:53:37 -0800 Subject: [PATCH 03771/11651] usb: gadget: udc: pxa27x_udc: Remove use of seq_printf return value The seq_printf return value, because it's frequently misused, will eventually be converted to void. See: commit 1f33c41c03da ("seq_file: Rename seq_overflow() to seq_has_overflowed() and make public") While there, simplify the error handler logic by returning immediately and remove the unnecessary labels. Tested-by: Robert Jarzmik Signed-off-by: Joe Perches Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/pxa27x_udc.c | 132 +++++++++++++--------------- 1 file changed, 60 insertions(+), 72 deletions(-) diff --git a/drivers/usb/gadget/udc/pxa27x_udc.c b/drivers/usb/gadget/udc/pxa27x_udc.c index 6a855fc9bd84..486f7546de8c 100644 --- a/drivers/usb/gadget/udc/pxa27x_udc.c +++ b/drivers/usb/gadget/udc/pxa27x_udc.c @@ -93,50 +93,46 @@ static void handle_ep(struct pxa_ep *ep); static int state_dbg_show(struct seq_file *s, void *p) { struct pxa_udc *udc = s->private; - int pos = 0, ret; u32 tmp; - ret = -ENODEV; if (!udc->driver) - goto out; + return -ENODEV; /* basic device status */ - pos += seq_printf(s, DRIVER_DESC "\n" - "%s version: %s\nGadget driver: %s\n", - driver_name, DRIVER_VERSION, - udc->driver ? udc->driver->driver.name : "(none)"); + seq_printf(s, DRIVER_DESC "\n" + "%s version: %s\n" + "Gadget driver: %s\n", + driver_name, DRIVER_VERSION, + udc->driver ? udc->driver->driver.name : "(none)"); tmp = udc_readl(udc, UDCCR); - pos += seq_printf(s, - "udccr=0x%0x(%s%s%s%s%s%s%s%s%s%s), " - "con=%d,inter=%d,altinter=%d\n", tmp, - (tmp & UDCCR_OEN) ? " oen":"", - (tmp & UDCCR_AALTHNP) ? " aalthnp":"", - (tmp & UDCCR_AHNP) ? " rem" : "", - (tmp & UDCCR_BHNP) ? " rstir" : "", - (tmp & UDCCR_DWRE) ? " dwre" : "", - (tmp & UDCCR_SMAC) ? " smac" : "", - (tmp & UDCCR_EMCE) ? " emce" : "", - (tmp & UDCCR_UDR) ? " udr" : "", - (tmp & UDCCR_UDA) ? " uda" : "", - (tmp & UDCCR_UDE) ? " ude" : "", - (tmp & UDCCR_ACN) >> UDCCR_ACN_S, - (tmp & UDCCR_AIN) >> UDCCR_AIN_S, - (tmp & UDCCR_AAISN) >> UDCCR_AAISN_S); + seq_printf(s, + "udccr=0x%0x(%s%s%s%s%s%s%s%s%s%s), con=%d,inter=%d,altinter=%d\n", + tmp, + (tmp & UDCCR_OEN) ? " oen":"", + (tmp & UDCCR_AALTHNP) ? " aalthnp":"", + (tmp & UDCCR_AHNP) ? " rem" : "", + (tmp & UDCCR_BHNP) ? " rstir" : "", + (tmp & UDCCR_DWRE) ? " dwre" : "", + (tmp & UDCCR_SMAC) ? " smac" : "", + (tmp & UDCCR_EMCE) ? " emce" : "", + (tmp & UDCCR_UDR) ? " udr" : "", + (tmp & UDCCR_UDA) ? " uda" : "", + (tmp & UDCCR_UDE) ? " ude" : "", + (tmp & UDCCR_ACN) >> UDCCR_ACN_S, + (tmp & UDCCR_AIN) >> UDCCR_AIN_S, + (tmp & UDCCR_AAISN) >> UDCCR_AAISN_S); /* registers for device and ep0 */ - pos += seq_printf(s, "udcicr0=0x%08x udcicr1=0x%08x\n", - udc_readl(udc, UDCICR0), udc_readl(udc, UDCICR1)); - pos += seq_printf(s, "udcisr0=0x%08x udcisr1=0x%08x\n", - udc_readl(udc, UDCISR0), udc_readl(udc, UDCISR1)); - pos += seq_printf(s, "udcfnr=%d\n", udc_readl(udc, UDCFNR)); - pos += seq_printf(s, "irqs: reset=%lu, suspend=%lu, resume=%lu, " - "reconfig=%lu\n", - udc->stats.irqs_reset, udc->stats.irqs_suspend, - udc->stats.irqs_resume, udc->stats.irqs_reconfig); - - ret = 0; -out: - return ret; + seq_printf(s, "udcicr0=0x%08x udcicr1=0x%08x\n", + udc_readl(udc, UDCICR0), udc_readl(udc, UDCICR1)); + seq_printf(s, "udcisr0=0x%08x udcisr1=0x%08x\n", + udc_readl(udc, UDCISR0), udc_readl(udc, UDCISR1)); + seq_printf(s, "udcfnr=%d\n", udc_readl(udc, UDCFNR)); + seq_printf(s, "irqs: reset=%lu, suspend=%lu, resume=%lu, reconfig=%lu\n", + udc->stats.irqs_reset, udc->stats.irqs_suspend, + udc->stats.irqs_resume, udc->stats.irqs_reconfig); + + return 0; } static int queues_dbg_show(struct seq_file *s, void *p) @@ -144,75 +140,67 @@ static int queues_dbg_show(struct seq_file *s, void *p) struct pxa_udc *udc = s->private; struct pxa_ep *ep; struct pxa27x_request *req; - int pos = 0, i, maxpkt, ret; + int i, maxpkt; - ret = -ENODEV; if (!udc->driver) - goto out; + return -ENODEV; /* dump endpoint queues */ for (i = 0; i < NR_PXA_ENDPOINTS; i++) { ep = &udc->pxa_ep[i]; maxpkt = ep->fifo_size; - pos += seq_printf(s, "%-12s max_pkt=%d %s\n", - EPNAME(ep), maxpkt, "pio"); + seq_printf(s, "%-12s max_pkt=%d %s\n", + EPNAME(ep), maxpkt, "pio"); if (list_empty(&ep->queue)) { - pos += seq_printf(s, "\t(nothing queued)\n"); + seq_puts(s, "\t(nothing queued)\n"); continue; } list_for_each_entry(req, &ep->queue, queue) { - pos += seq_printf(s, "\treq %p len %d/%d buf %p\n", - &req->req, req->req.actual, - req->req.length, req->req.buf); + seq_printf(s, "\treq %p len %d/%d buf %p\n", + &req->req, req->req.actual, + req->req.length, req->req.buf); } } - ret = 0; -out: - return ret; + return 0; } static int eps_dbg_show(struct seq_file *s, void *p) { struct pxa_udc *udc = s->private; struct pxa_ep *ep; - int pos = 0, i, ret; + int i; u32 tmp; - ret = -ENODEV; if (!udc->driver) - goto out; + return -ENODEV; ep = &udc->pxa_ep[0]; tmp = udc_ep_readl(ep, UDCCSR); - pos += seq_printf(s, "udccsr0=0x%03x(%s%s%s%s%s%s%s)\n", tmp, - (tmp & UDCCSR0_SA) ? " sa" : "", - (tmp & UDCCSR0_RNE) ? " rne" : "", - (tmp & UDCCSR0_FST) ? " fst" : "", - (tmp & UDCCSR0_SST) ? " sst" : "", - (tmp & UDCCSR0_DME) ? " dme" : "", - (tmp & UDCCSR0_IPR) ? " ipr" : "", - (tmp & UDCCSR0_OPC) ? " opc" : ""); + seq_printf(s, "udccsr0=0x%03x(%s%s%s%s%s%s%s)\n", + tmp, + (tmp & UDCCSR0_SA) ? " sa" : "", + (tmp & UDCCSR0_RNE) ? " rne" : "", + (tmp & UDCCSR0_FST) ? " fst" : "", + (tmp & UDCCSR0_SST) ? " sst" : "", + (tmp & UDCCSR0_DME) ? " dme" : "", + (tmp & UDCCSR0_IPR) ? " ipr" : "", + (tmp & UDCCSR0_OPC) ? " opc" : ""); for (i = 0; i < NR_PXA_ENDPOINTS; i++) { ep = &udc->pxa_ep[i]; tmp = i? udc_ep_readl(ep, UDCCR) : udc_readl(udc, UDCCR); - pos += seq_printf(s, "%-12s: " - "IN %lu(%lu reqs), OUT %lu(%lu reqs), " - "irqs=%lu, udccr=0x%08x, udccsr=0x%03x, " - "udcbcr=%d\n", - EPNAME(ep), - ep->stats.in_bytes, ep->stats.in_ops, - ep->stats.out_bytes, ep->stats.out_ops, - ep->stats.irqs, - tmp, udc_ep_readl(ep, UDCCSR), - udc_ep_readl(ep, UDCBCR)); + seq_printf(s, "%-12s: IN %lu(%lu reqs), OUT %lu(%lu reqs), irqs=%lu, udccr=0x%08x, udccsr=0x%03x, udcbcr=%d\n", + EPNAME(ep), + ep->stats.in_bytes, ep->stats.in_ops, + ep->stats.out_bytes, ep->stats.out_ops, + ep->stats.irqs, + tmp, udc_ep_readl(ep, UDCCSR), + udc_ep_readl(ep, UDCBCR)); } - ret = 0; -out: - return ret; + return 0; } static int eps_dbg_open(struct inode *inode, struct file *file) -- GitLab From adf9c3c85615f41c08559086e0d9ecdc6cc9db71 Mon Sep 17 00:00:00 2001 From: Joseph Kogut Date: Mon, 16 Feb 2015 19:32:46 -0700 Subject: [PATCH 03772/11651] usb: move definition of PCI_VENDOR_ID_SYNOPSYS to linux/pci_ids.h Removed FIXME from usb/dwc3/dwc3-pci.c by moving definition of PCI_VENDOR_ID_SYNOPSYS shared with usb/dwc2 to linux/pci_ids.h. Signed-off-by: Joseph Kogut Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/pci.c | 1 - drivers/usb/dwc3/dwc3-pci.c | 2 -- include/linux/pci_ids.h | 2 ++ 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/usb/dwc2/pci.c b/drivers/usb/dwc2/pci.c index a4e724b0a62e..6646adb1fb17 100644 --- a/drivers/usb/dwc2/pci.c +++ b/drivers/usb/dwc2/pci.c @@ -54,7 +54,6 @@ #include "core.h" #include "hcd.h" -#define PCI_VENDOR_ID_SYNOPSYS 0x16c3 #define PCI_PRODUCT_ID_HAPS_HSOTG 0xabc0 static const char dwc2_driver_name[] = "dwc2"; diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index 8d950569d557..b773fb53d6a7 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -24,8 +24,6 @@ #include "platform_data.h" -/* FIXME define these in */ -#define PCI_VENDOR_ID_SYNOPSYS 0x16c3 #define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3 0xabcd #define PCI_DEVICE_ID_INTEL_BYT 0x0f37 #define PCI_DEVICE_ID_INTEL_MRFLD 0x119e diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index e63c02a93f6b..38cff8f6716d 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2315,6 +2315,8 @@ #define PCI_VENDOR_ID_CENATEK 0x16CA #define PCI_DEVICE_ID_CENATEK_IDE 0x0001 +#define PCI_VENDOR_ID_SYNOPSYS 0x16c3 + #define PCI_VENDOR_ID_VITESSE 0x1725 #define PCI_DEVICE_ID_VITESSE_VSC7174 0x7174 -- GitLab From ab7580c1479f9cc9d6a70a5184687a4d807fc612 Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Thu, 26 Feb 2015 11:47:57 +0000 Subject: [PATCH 03773/11651] usb: isp1760: add peripheral/device controller chip id As per the SAF1761 data sheet[0], the DcChipID register represents the hardware version number (0001h) and the chip ID (1582h) for the Peripheral Controller. However as per the ISP1761 data sheet[1], the DcChipID register represents the hardware version number (0015h) and the chip ID (8210h) for the Peripheral Controller. This patch adds support for both the chip ID values. [0] http://www.nxp.com/documents/data_sheet/SAF1761.pdf [1] http://pdf.datasheetcatalog.com/datasheets2/74/742102_1.pdf Cc: Felipe Balbi Cc: Laurent Pinchart Signed-off-by: Sudeep Holla Acked-by: Laurent Pinchart Signed-off-by: Felipe Balbi --- drivers/usb/isp1760/isp1760-udc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/isp1760/isp1760-udc.c b/drivers/usb/isp1760/isp1760-udc.c index 9612d7990565..6d618b3fab07 100644 --- a/drivers/usb/isp1760/isp1760-udc.c +++ b/drivers/usb/isp1760/isp1760-udc.c @@ -1411,7 +1411,7 @@ static int isp1760_udc_init(struct isp1760_udc *udc) return -ENODEV; } - if (chipid != 0x00011582) { + if (chipid != 0x00011582 && chipid != 0x00158210) { dev_err(udc->isp->dev, "udc: invalid chip ID 0x%08x\n", chipid); return -ENODEV; } -- GitLab From 896f7ea37f53666a72080d0958213d12ae59deaa Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 25 Feb 2015 14:03:23 -0600 Subject: [PATCH 03774/11651] usb: musb: core: remove unnecessary logical comparison devctl & MUSB_DEVCTL_HM represents a single bit, just check for the bit, there's really no need to compare the result against 0. Tested-by: Bin Liu Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index e59ae7395ba8..8066dbab1045 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -879,7 +879,7 @@ b_host: */ if (int_usb & MUSB_INTR_RESET) { handled = IRQ_HANDLED; - if ((devctl & MUSB_DEVCTL_HM) != 0) { + if (devctl & MUSB_DEVCTL_HM) { /* * Looks like non-HS BABBLE can be ignored, but * HS BABBLE is an error condition. For HS the solution -- GitLab From d57a27711939dcb289b3d17ac48fca99f0fd245d Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 25 Feb 2015 14:05:15 -0600 Subject: [PATCH 03775/11651] usb: musb: core: add missing curly braces no functional changes, clean up only. Tested-by: Bin Liu Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 8066dbab1045..21ab26636631 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -887,9 +887,9 @@ b_host: * caused BABBLE. When HS BABBLE happens we can only * stop the session. */ - if (devctl & (MUSB_DEVCTL_FSDEV | MUSB_DEVCTL_LSDEV)) + if (devctl & (MUSB_DEVCTL_FSDEV | MUSB_DEVCTL_LSDEV)) { dev_dbg(musb->controller, "BABBLE devctl: %02x\n", devctl); - else { + } else { ERR("Stopping host session -- babble\n"); musb_writeb(musb->mregs, MUSB_DEVCTL, 0); } -- GitLab From 28378d5ed5ca1221479d2f94c3b346691834822f Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 26 Feb 2015 10:54:27 -0600 Subject: [PATCH 03776/11651] usb: musb: core: fix highspeed check FSDEV is set for both HIGH and FULL speeds, the correct HIGHSPEED check is done through power register's HSMODE bit. Tested-by: Bin Liu Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 21ab26636631..cf7b10e5963e 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -880,16 +880,23 @@ b_host: if (int_usb & MUSB_INTR_RESET) { handled = IRQ_HANDLED; if (devctl & MUSB_DEVCTL_HM) { + u8 power = musb_readl(musb->mregs, MUSB_POWER); + /* * Looks like non-HS BABBLE can be ignored, but - * HS BABBLE is an error condition. For HS the solution - * is to avoid babble in the first place and fix what - * caused BABBLE. When HS BABBLE happens we can only - * stop the session. + * HS BABBLE is an error condition. + * + * For HS the solution is to avoid babble in the first + * place and fix what caused BABBLE. + * + * When HS BABBLE happens what we can depends on which + * platform MUSB is running, because some platforms + * implemented proprietary means for 'recovering' from + * Babble conditions. One such platform is AM335x. In + * most cases, however, the only thing we can do is drop + * the session. */ - if (devctl & (MUSB_DEVCTL_FSDEV | MUSB_DEVCTL_LSDEV)) { - dev_dbg(musb->controller, "BABBLE devctl: %02x\n", devctl); - } else { + if (power & MUSB_POWER_HSMODE) { ERR("Stopping host session -- babble\n"); musb_writeb(musb->mregs, MUSB_DEVCTL, 0); } -- GitLab From d0cddae7926f39e8fd488f62496cfebf7a5e757d Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 26 Feb 2015 10:55:13 -0600 Subject: [PATCH 03777/11651] usb: musb: dsps: return error code if reset fails if reset fails, we should return a *negative* error code, not a positive value. Tested-by: Bin Liu Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_dsps.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index a900c9877195..af614f49cd98 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -652,7 +652,7 @@ static int dsps_musb_reset(struct musb *musb) session_restart = 1; } - return !session_restart; + return session_restart ? 0 : -EPIPE; } static struct musb_platform_ops dsps_ops = { -- GitLab From d0fc0a20b5b7babe0fe1552204bd52505a4f93dd Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 25 Feb 2015 14:07:52 -0600 Subject: [PATCH 03778/11651] usb: musb: core: move babble recovery inside babble check There was already a proper place where we were checking for babble interrupts, move babble recovery there. Tested-by: Bin Liu Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index cf7b10e5963e..9ea02d4cc2c2 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -899,6 +899,12 @@ b_host: if (power & MUSB_POWER_HSMODE) { ERR("Stopping host session -- babble\n"); musb_writeb(musb->mregs, MUSB_DEVCTL, 0); + + if (is_host_active(musb)) { + musb_generic_disable(musb); + schedule_delayed_work(&musb->recover_work, + msecs_to_jiffies(100)); + } } } else { dev_dbg(musb->controller, "BUS RESET as %s\n", @@ -938,13 +944,6 @@ b_host: } } - /* handle babble condition */ - if (int_usb & MUSB_INTR_BABBLE && is_host_active(musb)) { - musb_generic_disable(musb); - schedule_delayed_work(&musb->recover_work, - msecs_to_jiffies(100)); - } - #if 0 /* REVISIT ... this would be for multiplexing periodic endpoints, or * supporting transfer phasing to prevent exceeding ISO bandwidth -- GitLab From 0acff6b83106ef699f17828caea6545bcc716f14 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 25 Feb 2015 14:14:15 -0600 Subject: [PATCH 03779/11651] usb: musb: core: break long line no functional changes, clean up only. Tested-by: Bin Liu Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 9ea02d4cc2c2..b5dfe83dce76 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -534,7 +534,8 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, */ if (int_usb & MUSB_INTR_RESUME) { handled = IRQ_HANDLED; - dev_dbg(musb->controller, "RESUME (%s)\n", usb_otg_state_string(musb->xceiv->otg->state)); + dev_dbg(musb->controller, "RESUME (%s)\n", + usb_otg_state_string(musb->xceiv->otg->state)); if (devctl & MUSB_DEVCTL_HM) { void __iomem *mbase = musb->mregs; -- GitLab From 46571889ec435f1bf29d9094f062948b26630723 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 25 Feb 2015 14:30:55 -0600 Subject: [PATCH 03780/11651] usb: musb: core: remove unnecessary reg access from resume IRQ when musb is operating as host and a remote wakeup fires up, a resume interrupt will be raised. At that point SUSPENDM bit is automatically cleared and RESUME bit is automatically set. Remove those two from IRQ handler. Tested-by: Bin Liu Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.c | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index b5dfe83dce76..3fb7d6e032f1 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -538,27 +538,12 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, usb_otg_state_string(musb->xceiv->otg->state)); if (devctl & MUSB_DEVCTL_HM) { - void __iomem *mbase = musb->mregs; - u8 power; - switch (musb->xceiv->otg->state) { case OTG_STATE_A_SUSPEND: /* remote wakeup? later, GetPortStatus * will stop RESUME signaling */ - power = musb_readb(musb->mregs, MUSB_POWER); - if (power & MUSB_POWER_SUSPENDM) { - /* spurious */ - musb->int_usb &= ~MUSB_INTR_SUSPEND; - dev_dbg(musb->controller, "Spurious SUSPENDM\n"); - break; - } - - power &= ~MUSB_POWER_SUSPENDM; - musb_writeb(mbase, MUSB_POWER, - power | MUSB_POWER_RESUME); - musb->port1_status |= (USB_PORT_STAT_C_SUSPEND << 16) | MUSB_PORT_STAT_RESUME; -- GitLab From b2c7361bd07f94e6280507a20e0541870d5d7a1a Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 25 Feb 2015 14:48:50 -0600 Subject: [PATCH 03781/11651] usb: musb: core: there is no connect interrupt in peripheral mode MUSB does not generate a connect IRQ when working in peripheral mode. Tested-by: Bin Liu Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 3fb7d6e032f1..7ac69799a1db 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -761,10 +761,6 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, musb->ep0_stage = MUSB_EP0_START; - /* flush endpoints when transitioning from Device Mode */ - if (is_peripheral_active(musb)) { - /* REVISIT HNP; just force disconnect */ - } musb->intrtxe = musb->epmask; musb_writew(musb->mregs, MUSB_INTRTXE, musb->intrtxe); musb->intrrxe = musb->epmask & 0xfffe; -- GitLab From 52b9e6eb07f739207bd7d4257fdfbb24592d096a Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 25 Feb 2015 16:04:39 -0600 Subject: [PATCH 03782/11651] usb: musb: dsps: remove babble check from dsps irq handler musb->int_usb already contains the correct information for musb-core to handle babble. In fact, this very check was just causing a nonsensical babble interrupt storm. With this I can get test.sh to run and, even though all tests fail with timeout, that's still better than locking up the system due to IRQ storm. Also, if I remove g_zero and load g_mass_storage, then everything works fine again. Tested-by: Bin Liu Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.c | 2 +- drivers/usb/musb/musb_dsps.c | 22 ---------------------- 2 files changed, 1 insertion(+), 23 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 7ac69799a1db..d7730c7e7938 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -879,7 +879,7 @@ b_host: * the session. */ if (power & MUSB_POWER_HSMODE) { - ERR("Stopping host session -- babble\n"); + dev_err(musb->controller, "Babble\n"); musb_writeb(musb->mregs, MUSB_DEVCTL, 0); if (is_host_active(musb)) { diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index af614f49cd98..8f96e79dd069 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -330,28 +330,6 @@ static irqreturn_t dsps_interrupt(int irq, void *hci) dev_dbg(musb->controller, "usbintr (%x) epintr(%x)\n", usbintr, epintr); - /* - * DRVVBUS IRQs are the only proxy we have (a very poor one!) for - * DSPS IP's missing ID change IRQ. We need an ID change IRQ to - * switch appropriately between halves of the OTG state machine. - * Managing DEVCTL.SESSION per Mentor docs requires that we know its - * value but DEVCTL.BDEVICE is invalid without DEVCTL.SESSION set. - * Also, DRVVBUS pulses for SRP (but not at 5V) ... - */ - if (is_host_active(musb) && usbintr & MUSB_INTR_BABBLE) { - pr_info("CAUTION: musb: Babble Interrupt Occurred\n"); - - /* - * When a babble condition occurs, the musb controller removes - * the session and is no longer in host mode. Hence, all - * devices connected to its root hub get disconnected. - * - * Hand this error down to the musb core isr, so it can - * recover. - */ - musb->int_usb = MUSB_INTR_BABBLE | MUSB_INTR_DISCONNECT; - musb->int_tx = musb->int_rx = 0; - } if (usbintr & ((1 << wrp->drvvbus) << wrp->usb_shift)) { int drvvbus = dsps_readl(reg_base, wrp->status); -- GitLab From f860f0b1ea76b9f15d24db8fa98823eb15273afb Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 26 Feb 2015 11:01:03 -0600 Subject: [PATCH 03783/11651] usb: musb: dsps: check for the single bit We want to check if that particular bit is set. It could very well be that bootloader (or romcode) has fiddled with MUSB before us which could leave other bits set in this register. Tested-by: Bin Liu Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_dsps.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 8f96e79dd069..e210b75fb6f2 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -475,7 +475,7 @@ static int dsps_musb_init(struct musb *musb) * logic enabled. */ val = dsps_readb(musb->mregs, MUSB_BABBLE_CTL); - if (val == MUSB_BABBLE_RCV_DISABLE) { + if (val & MUSB_BABBLE_RCV_DISABLE) { glue->sw_babble_enabled = true; val |= MUSB_BABBLE_SW_SESSION_CTRL; dsps_writeb(musb->mregs, MUSB_BABBLE_CTL, val); -- GitLab From a67cab72b87c7bb970bec8bc060a8946c5dfa1c5 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 26 Feb 2015 11:09:20 -0600 Subject: [PATCH 03784/11651] usb: musb: core: controller drops session automatically Whenever babble happens, MUSB controller will drop session automatically. The only case where it won't drop the session, is when we're running on AM335x and SW_SESSION_CTRL bit has been set. In that case, controller will not touch session bit so SW has a chance to recover from babble condition. Tested-by: Bin Liu Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index d7730c7e7938..b86e975cba2b 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -880,7 +880,6 @@ b_host: */ if (power & MUSB_POWER_HSMODE) { dev_err(musb->controller, "Babble\n"); - musb_writeb(musb->mregs, MUSB_DEVCTL, 0); if (is_host_active(musb)) { musb_generic_disable(musb); -- GitLab From 3709ffca6485bd1b03b1fe2d9eb384dcf5db87a6 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 26 Feb 2015 11:11:33 -0600 Subject: [PATCH 03785/11651] usb: musb: dsps: add dsps_ prefix to sw_babble_control this makes it easier to filter function traces. No functional changes. Tested-by: Bin Liu Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_dsps.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index e210b75fb6f2..85ebfa2c3858 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -549,7 +549,7 @@ static int dsps_musb_set_mode(struct musb *musb, u8 mode) return 0; } -static bool sw_babble_control(struct musb *musb) +static bool dsps_sw_babble_control(struct musb *musb) { u8 babble_ctl; bool session_restart = false; @@ -608,7 +608,7 @@ static int dsps_musb_reset(struct musb *musb) int session_restart = 0, error; if (glue->sw_babble_enabled) - session_restart = sw_babble_control(musb); + session_restart = dsps_sw_babble_control(musb); /* * In case of new silicon version babble condition can be recovered * without resetting the MUSB. But for older silicon versions, MUSB -- GitLab From e1eb3eb8b02c5be35ea1fedccc6c9c6d2c9b0165 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 26 Feb 2015 11:26:09 -0600 Subject: [PATCH 03786/11651] usb: musb: core: refactor IRQ enable/disable to separate functions sometimes we want to just mask/unmask interrupts without touching devctl register. For those cases, let's introduce musb_enable_interrupts and musb_disable_interrupts() Tested-by: Bin Liu Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.c | 37 +++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index b86e975cba2b..8ae24266f1a8 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -507,7 +507,9 @@ void musb_hnp_stop(struct musb *musb) musb->port1_status &= ~(USB_PORT_STAT_C_CONNECTION << 16); } +static void musb_disable_interrupts(struct musb *musb); static void musb_generic_disable(struct musb *musb); + /* * Interrupt Service Routine to record USB "global" interrupts. * Since these do not happen often and signify things of @@ -977,7 +979,7 @@ b_host: /*-------------------------------------------------------------------------*/ -static void musb_generic_disable(struct musb *musb) +static void musb_disable_interrupts(struct musb *musb) { void __iomem *mbase = musb->mregs; u16 temp; @@ -989,16 +991,35 @@ static void musb_generic_disable(struct musb *musb) musb->intrrxe = 0; musb_writew(mbase, MUSB_INTRRXE, 0); - /* off */ - musb_writeb(mbase, MUSB_DEVCTL, 0); - /* flush pending interrupts */ temp = musb_readb(mbase, MUSB_INTRUSB); temp = musb_readw(mbase, MUSB_INTRTX); temp = musb_readw(mbase, MUSB_INTRRX); +} + +static void musb_enable_interrupts(struct musb *musb) +{ + void __iomem *regs = musb->mregs; + + /* Set INT enable registers, enable interrupts */ + musb->intrtxe = musb->epmask; + musb_writew(regs, MUSB_INTRTXE, musb->intrtxe); + musb->intrrxe = musb->epmask & 0xfffe; + musb_writew(regs, MUSB_INTRRXE, musb->intrrxe); + musb_writeb(regs, MUSB_INTRUSBE, 0xf7); } +static void musb_generic_disable(struct musb *musb) +{ + void __iomem *mbase = musb->mregs; + + musb_disable_interrupts(musb); + + /* off */ + musb_writeb(mbase, MUSB_DEVCTL, 0); +} + /* * Program the HDRC to start (enable interrupts, dma, etc.). */ @@ -1009,13 +1030,7 @@ void musb_start(struct musb *musb) dev_dbg(musb->controller, "<== devctl %02x\n", devctl); - /* Set INT enable registers, enable interrupts */ - musb->intrtxe = musb->epmask; - musb_writew(regs, MUSB_INTRTXE, musb->intrtxe); - musb->intrrxe = musb->epmask & 0xfffe; - musb_writew(regs, MUSB_INTRRXE, musb->intrrxe); - musb_writeb(regs, MUSB_INTRUSBE, 0xf7); - + musb_enable_interrupts(musb); musb_writeb(regs, MUSB_TESTMODE, 0); /* put into basic highspeed mode and start session */ -- GitLab From ba7ee8bb313c4a55066c4da30292aeb9abac82d8 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 26 Feb 2015 11:31:49 -0600 Subject: [PATCH 03787/11651] usb: musb: don't touch devctl from babble recovery We do *not* want to touch devctl at all when trying to recover from babble. All we want to do is mask IRQs until we're done without our babble recovery, at which point we will unmask IRQs. Tested-by: Bin Liu Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 8ae24266f1a8..a4e524cb8416 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -884,7 +884,7 @@ b_host: dev_err(musb->controller, "Babble\n"); if (is_host_active(musb)) { - musb_generic_disable(musb); + musb_disable_interrupts(musb); schedule_delayed_work(&musb->recover_work, msecs_to_jiffies(100)); } @@ -1838,8 +1838,10 @@ static void musb_recover_work(struct work_struct *data) int status, ret; ret = musb_platform_reset(musb); - if (ret) + if (ret) { + musb_enable_interrupts(musb); return; + } usb_phy_vbus_off(musb->xceiv); usleep_range(100, 200); -- GitLab From d5fa3e9f7398adf337f03fa3257d5e9b214078ee Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 26 Feb 2015 11:35:13 -0600 Subject: [PATCH 03788/11651] usb: musb: core: decrease delayed_work time When babble IRQ happens, we need to wait only 5.3us (320 cycles of 60MHz clock), we will give it some slack and schedule our work a 10 usecs into the future. Tested-by: Bin Liu Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index a4e524cb8416..96d71fa2ae85 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -886,7 +886,7 @@ b_host: if (is_host_active(musb)) { musb_disable_interrupts(musb); schedule_delayed_work(&musb->recover_work, - msecs_to_jiffies(100)); + usecs_to_jiffies(10)); } } } else { -- GitLab From 011d0dd5400b84e593eecfc4a17fcfb6c0c5ac60 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 26 Feb 2015 14:00:52 -0600 Subject: [PATCH 03789/11651] usb: musb: dsps: do not reset musb on babble All we have to do is, really, drop session bit and let the session restart. Big thanks goes to Bin Liu for inspiring this work. Tested-by: Bin Liu Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_dsps.c | 23 ++--------------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 85ebfa2c3858..a159de1225f3 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -604,31 +604,12 @@ static int dsps_musb_reset(struct musb *musb) { struct device *dev = musb->controller; struct dsps_glue *glue = dev_get_drvdata(dev->parent); - const struct dsps_musb_wrapper *wrp = glue->wrp; - int session_restart = 0, error; + int session_restart = 0; if (glue->sw_babble_enabled) session_restart = dsps_sw_babble_control(musb); - /* - * In case of new silicon version babble condition can be recovered - * without resetting the MUSB. But for older silicon versions, MUSB - * reset is needed - */ - if (session_restart || !glue->sw_babble_enabled) { - dev_info(musb->controller, "Restarting MUSB to recover from Babble\n"); - dsps_writel(musb->ctrl_base, wrp->control, (1 << wrp->reset)); - usleep_range(100, 200); - usb_phy_shutdown(musb->xceiv); - error = phy_power_off(musb->phy); - if (error) - dev_err(dev, "phy shutdown failed: %i\n", error); - usleep_range(100, 200); - usb_phy_init(musb->xceiv); - error = phy_power_on(musb->phy); - if (error) - dev_err(dev, "phy powerup failed: %i\n", error); + else session_restart = 1; - } return session_restart ? 0 : -EPIPE; } -- GitLab From b4dc38fd45b63e3da2bc98db5d283a15a637a2fa Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 26 Feb 2015 14:02:35 -0600 Subject: [PATCH 03790/11651] usb: musb: core: simplify musb_recover_work() we're not resetting musb at all, just restarting the session. This means we don't need to touch PHYs or VBUS or anything like that. Just make sure session bit is reenabled after MUSB dropped it. while at that, make sure to tell usbcore that we're dropping the session and, thus, disconnecting the device. Tested-by: Bin Liu Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 96d71fa2ae85..979bc2b0550f 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1835,7 +1835,8 @@ static void musb_irq_work(struct work_struct *data) static void musb_recover_work(struct work_struct *data) { struct musb *musb = container_of(data, struct musb, recover_work.work); - int status, ret; + int ret; + u8 devctl; ret = musb_platform_reset(musb); if (ret) { @@ -1843,23 +1844,25 @@ static void musb_recover_work(struct work_struct *data) return; } - usb_phy_vbus_off(musb->xceiv); - usleep_range(100, 200); + /* drop session bit */ + devctl = musb_readb(musb->mregs, MUSB_DEVCTL); + devctl &= ~MUSB_DEVCTL_SESSION; + musb_writeb(musb->mregs, MUSB_DEVCTL, devctl); - usb_phy_vbus_on(musb->xceiv); - usleep_range(100, 200); + /* tell usbcore about it */ + musb_root_disconnect(musb); /* * When a babble condition occurs, the musb controller * removes the session bit and the endpoint config is lost. */ if (musb->dyn_fifo) - status = ep_config_from_table(musb); + ret = ep_config_from_table(musb); else - status = ep_config_from_hw(musb); + ret = ep_config_from_hw(musb); - /* start the session again */ - if (status == 0) + /* restart session */ + if (ret == 0) musb_start(musb); } -- GitLab From b28a6432405ca95b3da25630d79d2463c754a79c Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 26 Feb 2015 14:20:58 -0600 Subject: [PATCH 03791/11651] usb: musb: rename ->reset() to ->recover() recover is a much better name than reset, considering we don't really reset the IP, just run platform-specific babble recovery algorithm. while at that, also fix a typo in comment and add kdoc for recover memeber of platform_ops. Tested-by: Bin Liu Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.c | 2 +- drivers/usb/musb/musb_core.h | 13 +++++++------ drivers/usb/musb/musb_dsps.c | 4 ++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 979bc2b0550f..bf9746287d7c 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1838,7 +1838,7 @@ static void musb_recover_work(struct work_struct *data) int ret; u8 devctl; - ret = musb_platform_reset(musb); + ret = musb_platform_recover(musb); if (ret) { musb_enable_interrupts(musb); return; diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index 5e65958f7915..1e03c7ec82e4 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h @@ -160,7 +160,8 @@ struct musb_io; * @init: turns on clocks, sets up platform-specific registers, etc * @exit: undoes @init * @set_mode: forcefully changes operating mode - * @try_ilde: tries to idle the IP + * @try_idle: tries to idle the IP + * @recover: platform-specific babble recovery * @vbus_status: returns vbus status if possible * @set_vbus: forces vbus status * @adjust_channel_params: pre check for standard dma channel_program func @@ -196,7 +197,7 @@ struct musb_platform_ops { void (*write_fifo)(struct musb_hw_ep *hw_ep, u16 len, const u8 *buf); int (*set_mode)(struct musb *musb, u8 mode); void (*try_idle)(struct musb *musb, unsigned long timeout); - int (*reset)(struct musb *musb); + int (*recover)(struct musb *musb); int (*vbus_status)(struct musb *musb); void (*set_vbus)(struct musb *musb, int on); @@ -558,12 +559,12 @@ static inline void musb_platform_try_idle(struct musb *musb, musb->ops->try_idle(musb, timeout); } -static inline int musb_platform_reset(struct musb *musb) +static inline int musb_platform_recover(struct musb *musb) { - if (!musb->ops->reset) - return -EINVAL; + if (!musb->ops->recover) + return 0; - return musb->ops->reset(musb); + return musb->ops->recover(musb); } static inline int musb_platform_get_vbus_status(struct musb *musb) diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index a159de1225f3..30eb6ac29b81 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -600,7 +600,7 @@ static bool dsps_sw_babble_control(struct musb *musb) return session_restart; } -static int dsps_musb_reset(struct musb *musb) +static int dsps_musb_recover(struct musb *musb) { struct device *dev = musb->controller; struct dsps_glue *glue = dev_get_drvdata(dev->parent); @@ -624,7 +624,7 @@ static struct musb_platform_ops dsps_ops = { .try_idle = dsps_musb_try_idle, .set_mode = dsps_musb_set_mode, - .reset = dsps_musb_reset, + .recover = dsps_musb_recover, }; static u64 musb_dmamask = DMA_BIT_MASK(32); -- GitLab From 83b8f5b8c07c8cbad8c14c7b8767e7219a6c1813 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 26 Feb 2015 14:27:12 -0600 Subject: [PATCH 03792/11651] usb: musb: core: drop recover_work that's not needed anymore. Everything that we call is irq-safe, so we might as well not have a delayed work for babble recovery. Tested-by: Bin Liu Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.c | 17 +++++++++-------- drivers/usb/musb/musb_core.h | 1 - 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index bf9746287d7c..b410af6b0510 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -509,6 +509,7 @@ void musb_hnp_stop(struct musb *musb) static void musb_disable_interrupts(struct musb *musb); static void musb_generic_disable(struct musb *musb); +static void musb_recover_from_babble(struct musb *musb); /* * Interrupt Service Routine to record USB "global" interrupts. @@ -885,8 +886,7 @@ b_host: if (is_host_active(musb)) { musb_disable_interrupts(musb); - schedule_delayed_work(&musb->recover_work, - usecs_to_jiffies(10)); + musb_recover_from_babble(musb); } } } else { @@ -1831,13 +1831,17 @@ static void musb_irq_work(struct work_struct *data) } } -/* Recover from babble interrupt conditions */ -static void musb_recover_work(struct work_struct *data) +static void musb_recover_from_babble(struct musb *musb) { - struct musb *musb = container_of(data, struct musb, recover_work.work); int ret; u8 devctl; + /* + * wait at least 320 cycles of 60MHz clock. That's 5.3us, we will give + * it some slack and wait for 10us. + */ + udelay(10); + ret = musb_platform_recover(musb); if (ret) { musb_enable_interrupts(musb); @@ -2098,7 +2102,6 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) /* Init IRQ workqueue before request_irq */ INIT_WORK(&musb->irq_work, musb_irq_work); - INIT_DELAYED_WORK(&musb->recover_work, musb_recover_work); INIT_DELAYED_WORK(&musb->deassert_reset_work, musb_deassert_reset); INIT_DELAYED_WORK(&musb->finish_resume_work, musb_host_finish_resume); @@ -2194,7 +2197,6 @@ fail4: fail3: cancel_work_sync(&musb->irq_work); - cancel_delayed_work_sync(&musb->recover_work); cancel_delayed_work_sync(&musb->finish_resume_work); cancel_delayed_work_sync(&musb->deassert_reset_work); if (musb->dma_controller) @@ -2260,7 +2262,6 @@ static int musb_remove(struct platform_device *pdev) dma_controller_destroy(musb->dma_controller); cancel_work_sync(&musb->irq_work); - cancel_delayed_work_sync(&musb->recover_work); cancel_delayed_work_sync(&musb->finish_resume_work); cancel_delayed_work_sync(&musb->deassert_reset_work); musb_free(musb); diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index 1e03c7ec82e4..3877249a8b2d 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h @@ -301,7 +301,6 @@ struct musb { irqreturn_t (*isr)(int, void *); struct work_struct irq_work; - struct delayed_work recover_work; struct delayed_work deassert_reset_work; struct delayed_work finish_resume_work; u16 hwvers; -- GitLab From 06753fe115c517b715616ef7ef4f56b1b46ecc69 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 26 Feb 2015 14:33:41 -0600 Subject: [PATCH 03793/11651] usb: musb: core: remove unnecessary forward declaration no functional changes, cleanup only. Tested-by: Bin Liu Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index b410af6b0510..ecf2219ebc78 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -508,7 +508,6 @@ void musb_hnp_stop(struct musb *musb) } static void musb_disable_interrupts(struct musb *musb); -static void musb_generic_disable(struct musb *musb); static void musb_recover_from_babble(struct musb *musb); /* -- GitLab From 0244336f812583299291e18b69a75be5674e819f Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 26 Feb 2015 14:42:19 -0600 Subject: [PATCH 03794/11651] usb: musb: core: disable irqs inside babble recovery There's no point is splitting those anymore. We're now also able to drop another forward declaration. Tested-by: Bin Liu Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index ecf2219ebc78..3916e73abf7d 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -507,7 +507,6 @@ void musb_hnp_stop(struct musb *musb) musb->port1_status &= ~(USB_PORT_STAT_C_CONNECTION << 16); } -static void musb_disable_interrupts(struct musb *musb); static void musb_recover_from_babble(struct musb *musb); /* @@ -883,10 +882,8 @@ b_host: if (power & MUSB_POWER_HSMODE) { dev_err(musb->controller, "Babble\n"); - if (is_host_active(musb)) { - musb_disable_interrupts(musb); + if (is_host_active(musb)) musb_recover_from_babble(musb); - } } } else { dev_dbg(musb->controller, "BUS RESET as %s\n", @@ -1835,6 +1832,8 @@ static void musb_recover_from_babble(struct musb *musb) int ret; u8 devctl; + musb_disable_interrupts(musb); + /* * wait at least 320 cycles of 60MHz clock. That's 5.3us, we will give * it some slack and wait for 10us. -- GitLab From 34754dec8ab83799a0a37f2a7ada8ce1e53d174b Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 26 Feb 2015 14:43:57 -0600 Subject: [PATCH 03795/11651] usb: musb: core: always try to recover from babble we can also have babble conditions with LS/FS and we also want to recover in that case. Because of that we will drop the check of HSMODE and always try to run babble recovery. Suggested-by: Bin Liu Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.c | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 3916e73abf7d..a48b5a9c6c47 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -863,28 +863,18 @@ b_host: if (int_usb & MUSB_INTR_RESET) { handled = IRQ_HANDLED; if (devctl & MUSB_DEVCTL_HM) { - u8 power = musb_readl(musb->mregs, MUSB_POWER); - /* - * Looks like non-HS BABBLE can be ignored, but - * HS BABBLE is an error condition. - * - * For HS the solution is to avoid babble in the first - * place and fix what caused BABBLE. - * - * When HS BABBLE happens what we can depends on which + * When BABBLE happens what we can depends on which * platform MUSB is running, because some platforms * implemented proprietary means for 'recovering' from * Babble conditions. One such platform is AM335x. In - * most cases, however, the only thing we can do is drop - * the session. + * most cases, however, the only thing we can do is + * drop the session. */ - if (power & MUSB_POWER_HSMODE) { - dev_err(musb->controller, "Babble\n"); + dev_err(musb->controller, "Babble\n"); - if (is_host_active(musb)) - musb_recover_from_babble(musb); - } + if (is_host_active(musb)) + musb_recover_from_babble(musb); } else { dev_dbg(musb->controller, "BUS RESET as %s\n", usb_otg_state_string(musb->xceiv->otg->state)); -- GitLab From a285f40d80d440853ac908017d6d949ae2a7f88e Mon Sep 17 00:00:00 2001 From: Mian Yousaf Kaukab Date: Mon, 2 Feb 2015 10:55:23 +0100 Subject: [PATCH 03796/11651] usb: gadget: net2280: use ep_autoconfig compatible names in advance mode Each struct usb_ep added for net2280 can be used in either direction. Whereas, each struct usb_ep for usb3380 has fixed direction. Use ep_autoconf compatible names so that endpoint with correct direction can be selected. Name sequence is due to the logic in usb_reinit_338x() in ne[] and ep_reg_addr[]. Signed-off-by: Mian Yousaf Kaukab Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/net2280.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/udc/net2280.c b/drivers/usb/gadget/udc/net2280.c index d2c0bf65e345..b7024dcce83a 100644 --- a/drivers/usb/gadget/udc/net2280.c +++ b/drivers/usb/gadget/udc/net2280.c @@ -80,6 +80,13 @@ static const char *const ep_name[] = { "ep-e", "ep-f", "ep-g", "ep-h", }; +/* Endpoint names for usb3380 advance mode */ +static const char *const ep_name_adv[] = { + ep0name, + "ep1in", "ep2out", "ep3in", "ep4out", + "ep1out", "ep2in", "ep3out", "ep4in", +}; + /* mode 0 == ep-{a,b,c,d} 1K fifo each * mode 1 == ep-{a,b} 2K fifo each, ep-{c,d} unavailable * mode 2 == ep-a 2K fifo, ep-{b,c} 1K each, ep-d unavailable @@ -1977,7 +1984,7 @@ static void usb_reinit_338x(struct net2280 *dev) for (i = 0; i < dev->n_ep; i++) { struct net2280_ep *ep = &dev->ep[i]; - ep->ep.name = ep_name[i]; + ep->ep.name = dev->enhanced_mode ? ep_name_adv[i] : ep_name[i]; ep->dev = dev; ep->num = i; -- GitLab From fb2a85dd933c2793f5aabeb84af8b3bc00c0c968 Mon Sep 17 00:00:00 2001 From: Mian Yousaf Kaukab Date: Mon, 2 Feb 2015 10:55:24 +0100 Subject: [PATCH 03797/11651] usb: gadget: net2280: remove fiforegs as it is unused Remove fiforegs from struct net2280 and net2280_ep as it is unused. By the way, ep->fiforegs = &dev->fiforegs[i] assignment is incorrect. It should be ep->fiforegs = &dev->fiforegs[ne[i]], but it doesn't matter now. Signed-off-by: Mian Yousaf Kaukab Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/net2280.c | 4 ---- drivers/usb/gadget/udc/net2280.h | 2 -- 2 files changed, 6 deletions(-) diff --git a/drivers/usb/gadget/udc/net2280.c b/drivers/usb/gadget/udc/net2280.c index b7024dcce83a..d51430f26ecf 100644 --- a/drivers/usb/gadget/udc/net2280.c +++ b/drivers/usb/gadget/udc/net2280.c @@ -1996,11 +1996,9 @@ static void usb_reinit_338x(struct net2280 *dev) ep->regs = (struct net2280_ep_regs __iomem *) (((void __iomem *)&dev->epregs[ne[i]]) + ep_reg_addr[i]); - ep->fiforegs = &dev->fiforegs[i]; } else { ep->cfg = &dev->epregs[i]; ep->regs = &dev->epregs[i]; - ep->fiforegs = &dev->fiforegs[i]; } ep->fifo_size = (i != 0) ? 2048 : 512; @@ -3380,8 +3378,6 @@ static int net2280_probe(struct pci_dev *pdev, const struct pci_device_id *id) u32 usbstat; dev->usb_ext = (struct usb338x_usb_ext_regs __iomem *) (base + 0x00b4); - dev->fiforegs = (struct usb338x_fifo_regs __iomem *) - (base + 0x0500); dev->llregs = (struct usb338x_ll_regs __iomem *) (base + 0x0700); dev->ll_lfps_regs = (struct usb338x_ll_lfps_regs __iomem *) diff --git a/drivers/usb/gadget/udc/net2280.h b/drivers/usb/gadget/udc/net2280.h index ac8d5a20a378..4dff60d34f73 100644 --- a/drivers/usb/gadget/udc/net2280.h +++ b/drivers/usb/gadget/udc/net2280.h @@ -96,7 +96,6 @@ struct net2280_ep { struct net2280_ep_regs __iomem *regs; struct net2280_dma_regs __iomem *dma; struct net2280_dma *dummy; - struct usb338x_fifo_regs __iomem *fiforegs; dma_addr_t td_dma; /* of dummy */ struct net2280 *dev; unsigned long irqs; @@ -181,7 +180,6 @@ struct net2280 { struct net2280_dma_regs __iomem *dma; struct net2280_dep_regs __iomem *dep; struct net2280_ep_regs __iomem *epregs; - struct usb338x_fifo_regs __iomem *fiforegs; struct usb338x_ll_regs __iomem *llregs; struct usb338x_ll_lfps_regs __iomem *ll_lfps_regs; struct usb338x_ll_tsn_regs __iomem *ll_tsn_regs; -- GitLab From 9ceafcc2b3ad48ad2ef42608f1505ecad515d144 Mon Sep 17 00:00:00 2001 From: Mian Yousaf Kaukab Date: Mon, 2 Feb 2015 10:55:25 +0100 Subject: [PATCH 03798/11651] usb: gadget: net2280: print error in ep_ops error paths Hopefully, these prints will help localize the problems faster. [ balbi@ti.com: removed 2 unnecessary OOM error messages ] Signed-off-by: Mian Yousaf Kaukab Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/net2280.c | 166 ++++++++++++++++++++++--------- 1 file changed, 119 insertions(+), 47 deletions(-) diff --git a/drivers/usb/gadget/udc/net2280.c b/drivers/usb/gadget/udc/net2280.c index d51430f26ecf..5a8f6b6f7c8d 100644 --- a/drivers/usb/gadget/udc/net2280.c +++ b/drivers/usb/gadget/udc/net2280.c @@ -145,31 +145,44 @@ net2280_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) u32 max, tmp; unsigned long flags; static const u32 ep_key[9] = { 1, 0, 1, 0, 1, 1, 0, 1, 0 }; + int ret = 0; ep = container_of(_ep, struct net2280_ep, ep); if (!_ep || !desc || ep->desc || _ep->name == ep0name || - desc->bDescriptorType != USB_DT_ENDPOINT) + desc->bDescriptorType != USB_DT_ENDPOINT) { + pr_err("%s: failed at line=%d\n", __func__, __LINE__); return -EINVAL; + } dev = ep->dev; - if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) - return -ESHUTDOWN; + if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) { + ret = -ESHUTDOWN; + goto print_err; + } /* erratum 0119 workaround ties up an endpoint number */ - if ((desc->bEndpointAddress & 0x0f) == EP_DONTUSE) - return -EDOM; + if ((desc->bEndpointAddress & 0x0f) == EP_DONTUSE) { + ret = -EDOM; + goto print_err; + } if (dev->quirks & PLX_SUPERSPEED) { - if ((desc->bEndpointAddress & 0x0f) >= 0x0c) - return -EDOM; + if ((desc->bEndpointAddress & 0x0f) >= 0x0c) { + ret = -EDOM; + goto print_err; + } ep->is_in = !!usb_endpoint_dir_in(desc); - if (dev->enhanced_mode && ep->is_in && ep_key[ep->num]) - return -EINVAL; + if (dev->enhanced_mode && ep->is_in && ep_key[ep->num]) { + ret = -EINVAL; + goto print_err; + } } /* sanity check ep-e/ep-f since their fifos are small */ max = usb_endpoint_maxp(desc) & 0x1fff; - if (ep->num > 4 && max > 64 && (dev->quirks & PLX_LEGACY)) - return -ERANGE; + if (ep->num > 4 && max > 64 && (dev->quirks & PLX_LEGACY)) { + ret = -ERANGE; + goto print_err; + } spin_lock_irqsave(&dev->lock, flags); _ep->maxpacket = max & 0x7ff; @@ -199,7 +212,8 @@ net2280_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) (dev->gadget.speed == USB_SPEED_HIGH && max != 512) || (dev->gadget.speed == USB_SPEED_FULL && max > 64)) { spin_unlock_irqrestore(&dev->lock, flags); - return -ERANGE; + ret = -ERANGE; + goto print_err; } } ep->is_iso = (tmp == USB_ENDPOINT_XFER_ISOC); @@ -278,7 +292,11 @@ net2280_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) /* pci writes may still be posted */ spin_unlock_irqrestore(&dev->lock, flags); - return 0; + return ret; + +print_err: + dev_err(&ep->dev->pdev->dev, "%s: error=%d\n", __func__, ret); + return ret; } static int handshake(u32 __iomem *ptr, u32 mask, u32 done, int usec) @@ -433,9 +451,10 @@ static int net2280_disable(struct usb_ep *_ep) unsigned long flags; ep = container_of(_ep, struct net2280_ep, ep); - if (!_ep || !ep->desc || _ep->name == ep0name) + if (!_ep || !ep->desc || _ep->name == ep0name) { + pr_err("%s: Invalid ep=%p or ep->desc\n", __func__, _ep); return -EINVAL; - + } spin_lock_irqsave(&ep->dev->lock, flags); nuke(ep); @@ -465,8 +484,10 @@ static struct usb_request struct net2280_ep *ep; struct net2280_request *req; - if (!_ep) + if (!_ep) { + pr_err("%s: Invalid ep\n", __func__); return NULL; + } ep = container_of(_ep, struct net2280_ep, ep); req = kzalloc(sizeof(*req), gfp_flags); @@ -498,8 +519,11 @@ static void net2280_free_request(struct usb_ep *_ep, struct usb_request *_req) struct net2280_request *req; ep = container_of(_ep, struct net2280_ep, ep); - if (!_ep || !_req) + if (!_ep || !_req) { + dev_err(&ep->dev->pdev->dev, "%s: Inavlid ep=%p or req=%p\n", + __func__, _ep, _req); return; + } req = container_of(_req, struct net2280_request, req); WARN_ON(!list_empty(&req->queue)); @@ -903,35 +927,44 @@ net2280_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) struct net2280_ep *ep; struct net2280 *dev; unsigned long flags; + int ret = 0; /* we always require a cpu-view buffer, so that we can * always use pio (as fallback or whatever). */ - req = container_of(_req, struct net2280_request, req); - if (!_req || !_req->complete || !_req->buf || - !list_empty(&req->queue)) - return -EINVAL; - if (_req->length > (~0 & DMA_BYTE_COUNT_MASK)) - return -EDOM; ep = container_of(_ep, struct net2280_ep, ep); - if (!_ep || (!ep->desc && ep->num != 0)) + if (!_ep || (!ep->desc && ep->num != 0)) { + pr_err("%s: Invalid ep=%p or ep->desc\n", __func__, _ep); return -EINVAL; + } + req = container_of(_req, struct net2280_request, req); + if (!_req || !_req->complete || !_req->buf || + !list_empty(&req->queue)) { + ret = -EINVAL; + goto print_err; + } + if (_req->length > (~0 & DMA_BYTE_COUNT_MASK)) { + ret = -EDOM; + goto print_err; + } dev = ep->dev; - if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) - return -ESHUTDOWN; + if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) { + ret = -ESHUTDOWN; + goto print_err; + } /* FIXME implement PIO fallback for ZLPs with DMA */ - if (ep->dma && _req->length == 0) - return -EOPNOTSUPP; + if (ep->dma && _req->length == 0) { + ret = -EOPNOTSUPP; + goto print_err; + } /* set up dma mapping in case the caller didn't */ if (ep->dma) { - int ret; - ret = usb_gadget_map_request(&dev->gadget, _req, ep->is_in); if (ret) - return ret; + goto print_err; } ep_vdbg(dev, "%s queue req %p, len %d buf %p\n", @@ -1020,7 +1053,11 @@ done: spin_unlock_irqrestore(&dev->lock, flags); /* pci writes may still be posted */ - return 0; + return ret; + +print_err: + dev_err(&ep->dev->pdev->dev, "%s: error=%d\n", __func__, ret); + return ret; } static inline void @@ -1141,8 +1178,11 @@ static int net2280_dequeue(struct usb_ep *_ep, struct usb_request *_req) int stopped; ep = container_of(_ep, struct net2280_ep, ep); - if (!_ep || (!ep->desc && ep->num != 0) || !_req) + if (!_ep || (!ep->desc && ep->num != 0) || !_req) { + pr_err("%s: Invalid ep=%p or ep->desc or req=%p\n", + __func__, _ep, _req); return -EINVAL; + } spin_lock_irqsave(&ep->dev->lock, flags); stopped = ep->stopped; @@ -1164,6 +1204,8 @@ static int net2280_dequeue(struct usb_ep *_ep, struct usb_request *_req) } if (&req->req != _req) { spin_unlock_irqrestore(&ep->dev->lock, flags); + dev_err(&ep->dev->pdev->dev, "%s: Request mismatch\n", + __func__); return -EINVAL; } @@ -1221,20 +1263,28 @@ net2280_set_halt_and_wedge(struct usb_ep *_ep, int value, int wedged) int retval = 0; ep = container_of(_ep, struct net2280_ep, ep); - if (!_ep || (!ep->desc && ep->num != 0)) + if (!_ep || (!ep->desc && ep->num != 0)) { + pr_err("%s: Invalid ep=%p or ep->desc\n", __func__, _ep); return -EINVAL; - if (!ep->dev->driver || ep->dev->gadget.speed == USB_SPEED_UNKNOWN) - return -ESHUTDOWN; + } + if (!ep->dev->driver || ep->dev->gadget.speed == USB_SPEED_UNKNOWN) { + retval = -ESHUTDOWN; + goto print_err; + } if (ep->desc /* not ep0 */ && (ep->desc->bmAttributes & 0x03) - == USB_ENDPOINT_XFER_ISOC) - return -EINVAL; + == USB_ENDPOINT_XFER_ISOC) { + retval = -EINVAL; + goto print_err; + } spin_lock_irqsave(&ep->dev->lock, flags); - if (!list_empty(&ep->queue)) + if (!list_empty(&ep->queue)) { retval = -EAGAIN; - else if (ep->is_in && value && net2280_fifo_status(_ep) != 0) + goto print_unlock; + } else if (ep->is_in && value && net2280_fifo_status(_ep) != 0) { retval = -EAGAIN; - else { + goto print_unlock; + } else { ep_vdbg(ep->dev, "%s %s %s\n", _ep->name, value ? "set" : "clear", wedged ? "wedge" : "halt"); @@ -1258,6 +1308,12 @@ net2280_set_halt_and_wedge(struct usb_ep *_ep, int value, int wedged) spin_unlock_irqrestore(&ep->dev->lock, flags); return retval; + +print_unlock: + spin_unlock_irqrestore(&ep->dev->lock, flags); +print_err: + dev_err(&ep->dev->pdev->dev, "%s: error=%d\n", __func__, retval); + return retval; } static int net2280_set_halt(struct usb_ep *_ep, int value) @@ -1267,8 +1323,10 @@ static int net2280_set_halt(struct usb_ep *_ep, int value) static int net2280_set_wedge(struct usb_ep *_ep) { - if (!_ep || _ep->name == ep0name) + if (!_ep || _ep->name == ep0name) { + pr_err("%s: Invalid ep=%p or ep0\n", __func__, _ep); return -EINVAL; + } return net2280_set_halt_and_wedge(_ep, 1, 1); } @@ -1278,14 +1336,22 @@ static int net2280_fifo_status(struct usb_ep *_ep) u32 avail; ep = container_of(_ep, struct net2280_ep, ep); - if (!_ep || (!ep->desc && ep->num != 0)) + if (!_ep || (!ep->desc && ep->num != 0)) { + pr_err("%s: Invalid ep=%p or ep->desc\n", __func__, _ep); return -ENODEV; - if (!ep->dev->driver || ep->dev->gadget.speed == USB_SPEED_UNKNOWN) + } + if (!ep->dev->driver || ep->dev->gadget.speed == USB_SPEED_UNKNOWN) { + dev_err(&ep->dev->pdev->dev, + "%s: Invalid driver=%p or speed=%d\n", + __func__, ep->dev->driver, ep->dev->gadget.speed); return -ESHUTDOWN; + } avail = readl(&ep->regs->ep_avail) & (BIT(12) - 1); - if (avail > ep->fifo_size) + if (avail > ep->fifo_size) { + dev_err(&ep->dev->pdev->dev, "%s: Fifo overflow\n", __func__); return -EOVERFLOW; + } if (ep->is_in) avail = ep->fifo_size - avail; return avail; @@ -1296,10 +1362,16 @@ static void net2280_fifo_flush(struct usb_ep *_ep) struct net2280_ep *ep; ep = container_of(_ep, struct net2280_ep, ep); - if (!_ep || (!ep->desc && ep->num != 0)) + if (!_ep || (!ep->desc && ep->num != 0)) { + pr_err("%s: Invalid ep=%p or ep->desc\n", __func__, _ep); return; - if (!ep->dev->driver || ep->dev->gadget.speed == USB_SPEED_UNKNOWN) + } + if (!ep->dev->driver || ep->dev->gadget.speed == USB_SPEED_UNKNOWN) { + dev_err(&ep->dev->pdev->dev, + "%s: Invalid driver=%p or speed=%d\n", + __func__, ep->dev->driver, ep->dev->gadget.speed); return; + } writel(BIT(FIFO_FLUSH), &ep->regs->ep_stat); (void) readl(&ep->regs->ep_rsp); -- GitLab From 12366ef1942128d9bd8baa77e7eb4010b18fd676 Mon Sep 17 00:00:00 2001 From: Mian Yousaf Kaukab Date: Mon, 2 Feb 2015 10:55:26 +0100 Subject: [PATCH 03799/11651] usb: gadget: net2280: don't connect from udc_start net2280_start can be called with pullup disabled. Don't set softconnect flag in it. Let net2280_pullup handle the connection part. Signed-off-by: Mian Yousaf Kaukab Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/net2280.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/usb/gadget/udc/net2280.c b/drivers/usb/gadget/udc/net2280.c index 5a8f6b6f7c8d..5041e218a302 100644 --- a/drivers/usb/gadget/udc/net2280.c +++ b/drivers/usb/gadget/udc/net2280.c @@ -2263,7 +2263,6 @@ static int net2280_start(struct usb_gadget *_gadget, dev->ep[i].irqs = 0; /* hook up the driver ... */ - dev->softconnect = 1; driver->driver.bus = NULL; dev->driver = driver; -- GitLab From ccf5fb698155ee289b9257b0f1d6be3c7900ba0a Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 27 Feb 2015 09:44:51 -0600 Subject: [PATCH 03800/11651] usb: gadget: net2280: silence sparse warning Silence the following warning: drivers/usb/gadget/udc/net2280.c:3176:33: warning: context imbalance in 'handle_stat1_irqs' - unexpected unlock Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/net2280.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/gadget/udc/net2280.c b/drivers/usb/gadget/udc/net2280.c index 5041e218a302..9871b90195ad 100644 --- a/drivers/usb/gadget/udc/net2280.c +++ b/drivers/usb/gadget/udc/net2280.c @@ -3128,6 +3128,8 @@ next_endpoints: BIT(PCI_RETRY_ABORT_INTERRUPT)) static void handle_stat1_irqs(struct net2280 *dev, u32 stat) +__releases(dev->lock) +__acquires(dev->lock) { struct net2280_ep *ep; u32 tmp, num, mask, scratch; -- GitLab From 1b61625f8b5d87caf9633d7dbfbaf1ea8270036d Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 27 Feb 2015 13:19:39 -0600 Subject: [PATCH 03801/11651] usb: musb: cppi41: decrease indentation level no functional changes, clean up only. Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_cppi41.c | 88 +++++++++++++++++----------------- 1 file changed, 45 insertions(+), 43 deletions(-) diff --git a/drivers/usb/musb/musb_cppi41.c b/drivers/usb/musb/musb_cppi41.c index be84562d021b..73ac9835485d 100644 --- a/drivers/usb/musb/musb_cppi41.c +++ b/drivers/usb/musb/musb_cppi41.c @@ -225,10 +225,12 @@ static void cppi41_dma_callback(void *private_data) struct dma_channel *channel = private_data; struct cppi41_dma_channel *cppi41_channel = channel->private_data; struct musb_hw_ep *hw_ep = cppi41_channel->hw_ep; + struct cppi41_dma_controller *controller; struct musb *musb = hw_ep->musb; unsigned long flags; struct dma_tx_state txstate; u32 transferred; + int is_hs = 0; bool empty; spin_lock_irqsave(&musb->lock, flags); @@ -251,58 +253,58 @@ static void cppi41_dma_callback(void *private_data) empty = musb_is_tx_fifo_empty(hw_ep); if (empty) { cppi41_trans_done(cppi41_channel); - } else { - struct cppi41_dma_controller *controller; - int is_hs = 0; - /* - * On AM335x it has been observed that the TX interrupt fires - * too early that means the TXFIFO is not yet empty but the DMA - * engine says that it is done with the transfer. We don't - * receive a FIFO empty interrupt so the only thing we can do is - * to poll for the bit. On HS it usually takes 2us, on FS around - * 110us - 150us depending on the transfer size. - * We spin on HS (no longer than than 25us and setup a timer on - * FS to check for the bit and complete the transfer. - */ - controller = cppi41_channel->controller; + goto out; + } - if (is_host_active(musb)) { - if (musb->port1_status & USB_PORT_STAT_HIGH_SPEED) - is_hs = 1; - } else { - if (musb->g.speed == USB_SPEED_HIGH) - is_hs = 1; - } - if (is_hs) { - unsigned wait = 25; - - do { - empty = musb_is_tx_fifo_empty(hw_ep); - if (empty) - break; - wait--; - if (!wait) - break; - udelay(1); - } while (1); + /* + * On AM335x it has been observed that the TX interrupt fires + * too early that means the TXFIFO is not yet empty but the DMA + * engine says that it is done with the transfer. We don't + * receive a FIFO empty interrupt so the only thing we can do is + * to poll for the bit. On HS it usually takes 2us, on FS around + * 110us - 150us depending on the transfer size. + * We spin on HS (no longer than than 25us and setup a timer on + * FS to check for the bit and complete the transfer. + */ + controller = cppi41_channel->controller; + + if (is_host_active(musb)) { + if (musb->port1_status & USB_PORT_STAT_HIGH_SPEED) + is_hs = 1; + } else { + if (musb->g.speed == USB_SPEED_HIGH) + is_hs = 1; + } + if (is_hs) { + unsigned wait = 25; + do { empty = musb_is_tx_fifo_empty(hw_ep); - if (empty) { - cppi41_trans_done(cppi41_channel); - goto out; - } + if (empty) + break; + wait--; + if (!wait) + break; + udelay(1); + } while (1); + + empty = musb_is_tx_fifo_empty(hw_ep); + if (empty) { + cppi41_trans_done(cppi41_channel); + goto out; } - list_add_tail(&cppi41_channel->tx_check, - &controller->early_tx_list); - if (!hrtimer_is_queued(&controller->early_tx)) { - unsigned long usecs = cppi41_channel->total_len / 10; + } + list_add_tail(&cppi41_channel->tx_check, + &controller->early_tx_list); + if (!hrtimer_is_queued(&controller->early_tx)) { + unsigned long usecs = cppi41_channel->total_len / 10; - hrtimer_start_range_ns(&controller->early_tx, + hrtimer_start_range_ns(&controller->early_tx, ktime_set(0, usecs * NSEC_PER_USEC), 20 * NSEC_PER_USEC, HRTIMER_MODE_REL); - } } + out: spin_unlock_irqrestore(&musb->lock, flags); } -- GitLab From af63429cf046210d7313805b579dd779d10ad1c0 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 27 Feb 2015 13:21:14 -0600 Subject: [PATCH 03802/11651] usb: musb: cppi41: exit early when tx fifo is empty as soon as we find out tx fifo is empty, there's no need to break out of the loop just to have another branch to complete the transfer. We can just complete transfer and exit early. Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_cppi41.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/usb/musb/musb_cppi41.c b/drivers/usb/musb/musb_cppi41.c index 73ac9835485d..4407f30d0b86 100644 --- a/drivers/usb/musb/musb_cppi41.c +++ b/drivers/usb/musb/musb_cppi41.c @@ -280,19 +280,15 @@ static void cppi41_dma_callback(void *private_data) do { empty = musb_is_tx_fifo_empty(hw_ep); - if (empty) - break; + if (empty) { + cppi41_trans_done(cppi41_channel); + goto out; + } wait--; if (!wait) break; udelay(1); } while (1); - - empty = musb_is_tx_fifo_empty(hw_ep); - if (empty) { - cppi41_trans_done(cppi41_channel); - goto out; - } } list_add_tail(&cppi41_channel->tx_check, &controller->early_tx_list); -- GitLab From 043f5b75dd2b1fbd45d5f367d50e5ae5b4afa955 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 27 Feb 2015 13:22:27 -0600 Subject: [PATCH 03803/11651] usb: musb: cppi41: do not call udelay() according to comment in code, HS completion will happen pretty fast, instead of using udelay(), let's just busy loop and drop a cpu_relax() where udelay() was. Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_cppi41.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/musb/musb_cppi41.c b/drivers/usb/musb/musb_cppi41.c index 4407f30d0b86..9dc45a4a9fa8 100644 --- a/drivers/usb/musb/musb_cppi41.c +++ b/drivers/usb/musb/musb_cppi41.c @@ -287,7 +287,7 @@ static void cppi41_dma_callback(void *private_data) wait--; if (!wait) break; - udelay(1); + cpu_relax(); } while (1); } list_add_tail(&cppi41_channel->tx_check, -- GitLab From 9e204d885a6d0ae3696284bacd86e2b94dd936c8 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 27 Feb 2015 19:02:41 -0600 Subject: [PATCH 03804/11651] usb: musb: dsps: use msecs_to_jiffies instead when polling, we were using n * HZ (where n is an integer in seconds), however HZ isn't always correct if we're using cpufreq. A better way is to use msecs_to_jiffies(n) (where n is now an integer in miliseconds). while at that, also rename poll_seconds to poll_timeout and change its type to unsigned int. Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_dsps.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 30eb6ac29b81..9271450ebacd 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -119,7 +119,7 @@ struct dsps_musb_wrapper { unsigned iddig:5; unsigned iddig_mux:5; /* miscellaneous stuff */ - u8 poll_seconds; + unsigned poll_timeout; }; /* @@ -285,7 +285,8 @@ static void otg_timer(unsigned long _musb) } if (!(devctl & MUSB_DEVCTL_SESSION) && !skip_session) dsps_writeb(mregs, MUSB_DEVCTL, MUSB_DEVCTL_SESSION); - mod_timer(&glue->timer, jiffies + wrp->poll_seconds * HZ); + mod_timer(&glue->timer, jiffies + + msecs_to_jiffies(wrp->poll_timeout)); break; case OTG_STATE_A_WAIT_VFALL: musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE; @@ -352,8 +353,8 @@ static irqreturn_t dsps_interrupt(int irq, void *hci) */ musb->int_usb &= ~MUSB_INTR_VBUSERROR; musb->xceiv->otg->state = OTG_STATE_A_WAIT_VFALL; - mod_timer(&glue->timer, - jiffies + wrp->poll_seconds * HZ); + mod_timer(&glue->timer, jiffies + + msecs_to_jiffies(wrp->poll_timeout)); WARNING("VBUS error workaround (delay coming)\n"); } else if (drvvbus) { MUSB_HST_MODE(musb); @@ -382,7 +383,8 @@ static irqreturn_t dsps_interrupt(int irq, void *hci) /* Poll for ID change in OTG port mode */ if (musb->xceiv->otg->state == OTG_STATE_B_IDLE && musb->port_mode == MUSB_PORT_MODE_DUAL_ROLE) - mod_timer(&glue->timer, jiffies + wrp->poll_seconds * HZ); + mod_timer(&glue->timer, jiffies + + msecs_to_jiffies(wrp->poll_timeout)); out: spin_unlock_irqrestore(&musb->lock, flags); @@ -832,7 +834,7 @@ static const struct dsps_musb_wrapper am33xx_driver_data = { .rxep_shift = 16, .rxep_mask = 0xfffe, .rxep_bitmap = (0xfffe << 16), - .poll_seconds = 2, + .poll_timeout = 2000, /* ms */ }; static const struct of_device_id musb_dsps_of_match[] = { @@ -888,7 +890,8 @@ static int dsps_resume(struct device *dev) dsps_writel(mbase, wrp->rx_mode, glue->context.rx_mode); if (musb->xceiv->otg->state == OTG_STATE_B_IDLE && musb->port_mode == MUSB_PORT_MODE_DUAL_ROLE) - mod_timer(&glue->timer, jiffies + wrp->poll_seconds * HZ); + mod_timer(&glue->timer, jiffies + + msecs_to_jiffies(wrp->poll_timeout)); return 0; } -- GitLab From ad78c918602cb7cce0fab5d5813213853a6f351d Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 27 Feb 2015 19:07:49 -0600 Subject: [PATCH 03805/11651] usb: musb: dsps: just start polling already there's no need to fake an IRQ, just check if VBUS is valid already. Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_dsps.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 9271450ebacd..baa757ba1353 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -225,9 +225,8 @@ static void dsps_musb_enable(struct musb *musb) dsps_writel(reg_base, wrp->epintr_set, epmask); dsps_writel(reg_base, wrp->coreintr_set, coremask); - /* Force the DRVVBUS IRQ so we can start polling for ID change. */ - dsps_writel(reg_base, wrp->coreintr_set, - (1 << wrp->drvvbus) << wrp->usb_shift); + /* start polling for ID change. */ + mod_timer(&glue->timer, jiffies + msecs_to_jiffies(wrp->poll_timeout)); dsps_musb_try_idle(musb, 0); } -- GitLab From eac68e8f979b82d257eea0a4bbcda7b169d330bf Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Mon, 9 Mar 2015 15:06:12 +0100 Subject: [PATCH 03806/11651] usb: dwc3: make LPM configurable in DT This patch removes "Enable USB3 LPM Capability" option from Kconfig and adds snps,usb3_lpm_capable devicetree property instead of it. USB3 LPM (Link Power Management) capability is hardware property, and it's platform dependent, so if our hardware supports this feature, we want rather to configure it in devicetree than having it as Kconfig option. Signed-off-by: Robert Baldyga Signed-off-by: Felipe Balbi --- Documentation/devicetree/bindings/usb/dwc3.txt | 1 + drivers/usb/dwc3/Kconfig | 7 ------- drivers/usb/dwc3/core.c | 3 +++ drivers/usb/dwc3/core.h | 2 ++ drivers/usb/dwc3/host.c | 4 +--- drivers/usb/dwc3/platform_data.h | 1 + 6 files changed, 8 insertions(+), 10 deletions(-) diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt index cd7f0454e13a..5cc364309edb 100644 --- a/Documentation/devicetree/bindings/usb/dwc3.txt +++ b/Documentation/devicetree/bindings/usb/dwc3.txt @@ -14,6 +14,7 @@ Optional properties: - phys: from the *Generic PHY* bindings - phy-names: from the *Generic PHY* bindings - tx-fifo-resize: determines if the FIFO *has* to be reallocated. + - snps,usb3_lpm_capable: determines if platform is USB3 LPM capable - snps,disable_scramble_quirk: true when SW should disable data scrambling. Only really useful for FPGA builds. - snps,has-lpm-erratum: true when DWC3 was configured with LPM Erratum enabled diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig index edbf9c85af7e..827c4f80379f 100644 --- a/drivers/usb/dwc3/Kconfig +++ b/drivers/usb/dwc3/Kconfig @@ -104,11 +104,4 @@ config USB_DWC3_DEBUG help Say Y here to enable debugging messages on DWC3 Driver. -config DWC3_HOST_USB3_LPM_ENABLE - bool "Enable USB3 LPM Capability" - depends on USB_DWC3_HOST=y || USB_DWC3_DUAL_ROLE=y - default n - help - Select this when you want to enable USB3 LPM with dwc3 xhci host. - endif diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index cd59e919e27e..2bbab3d86fff 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -804,6 +804,8 @@ static int dwc3_probe(struct platform_device *pdev) "snps,is-utmi-l1-suspend"); of_property_read_u8(node, "snps,hird-threshold", &hird_threshold); + dwc->usb3_lpm_capable = of_property_read_bool(node, + "snps,usb3_lpm_capable"); dwc->needs_fifo_resize = of_property_read_bool(node, "tx-fifo-resize"); @@ -844,6 +846,7 @@ static int dwc3_probe(struct platform_device *pdev) hird_threshold = pdata->hird_threshold; dwc->needs_fifo_resize = pdata->tx_fifo_resize; + dwc->usb3_lpm_capable = pdata->usb3_lpm_capable; dwc->dr_mode = pdata->dr_mode; dwc->disable_scramble_quirk = pdata->disable_scramble_quirk; diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index d201910b892f..fdab715a0631 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -689,6 +689,7 @@ struct dwc3_scratchpad_array { * @setup_packet_pending: true when there's a Setup Packet in FIFO. Workaround * @start_config_issued: true when StartConfig command has been issued * @three_stage_setup: set if we perform a three phase setup + * @usb3_lpm_capable: set if hadrware supports Link Power Management * @disable_scramble_quirk: set if we enable the disable scramble quirk * @u2exit_lfps_quirk: set if we enable u2exit lfps quirk * @u2ss_inp3_quirk: set if we enable P3 OK for U2/SS Inactive quirk @@ -812,6 +813,7 @@ struct dwc3 { unsigned setup_packet_pending:1; unsigned start_config_issued:1; unsigned three_stage_setup:1; + unsigned usb3_lpm_capable:1; unsigned disable_scramble_quirk:1; unsigned u2exit_lfps_quirk:1; diff --git a/drivers/usb/dwc3/host.c b/drivers/usb/dwc3/host.c index 12bfd3c5405e..c679f63783ae 100644 --- a/drivers/usb/dwc3/host.c +++ b/drivers/usb/dwc3/host.c @@ -49,9 +49,7 @@ int dwc3_host_init(struct dwc3 *dwc) memset(&pdata, 0, sizeof(pdata)); -#ifdef CONFIG_DWC3_HOST_USB3_LPM_ENABLE - pdata.usb3_lpm_capable = 1; -#endif + pdata.usb3_lpm_capable = dwc->usb3_lpm_capable; ret = platform_device_add_data(xhci, &pdata, sizeof(pdata)); if (ret) { diff --git a/drivers/usb/dwc3/platform_data.h b/drivers/usb/dwc3/platform_data.h index a3a3b6d5668c..a2bd464be828 100644 --- a/drivers/usb/dwc3/platform_data.h +++ b/drivers/usb/dwc3/platform_data.h @@ -24,6 +24,7 @@ struct dwc3_platform_data { enum usb_device_speed maximum_speed; enum usb_dr_mode dr_mode; bool tx_fifo_resize; + bool usb3_lpm_capable; unsigned is_utmi_l1_suspend:1; u8 hird_threshold; -- GitLab From 232c0102e84b7fce634c8902a5fa30ca2b3342ac Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Tue, 3 Mar 2015 10:52:04 +0100 Subject: [PATCH 03807/11651] usb: gadget: composite: don't try standard handling for non-standard requests If a non-standard request is processed and its parameters just happen to match those of some standard request, the logic of composite_setup() can be fooled, so don't even try any switch cases, just go to the proper place where unknown requests are handled. Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/composite.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 13adfd1a3f54..9fb92310fb2b 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -1472,6 +1472,13 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) req->length = 0; gadget->ep0->driver_data = cdev; + /* + * Don't let non-standard requests match any of the cases below + * by accident. + */ + if ((ctrl->bRequestType & USB_TYPE_MASK) != USB_TYPE_STANDARD) + goto unknown; + switch (ctrl->bRequest) { /* we handle all standard USB descriptors */ -- GitLab From eb132ccbdec5df46e29c9814adf76075ce83576b Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Tue, 3 Mar 2015 10:52:05 +0100 Subject: [PATCH 03808/11651] usb: gadget: printer: enqueue printer's response for setup request Function-specific setup requests should be handled in such a way, that apart from filling in the data buffer, the requests are also actually enqueued: if function-specific setup is called from composte_setup(), the "usb_ep_queue()" block of code in composite_setup() is skipped. The printer function lacks this part and it results in e.g. get device id requests failing: the host expects some response, the device prepares it but does not equeue it for sending to the host, so the host finally asserts timeout. This patch adds enqueueing the prepared responses. Cc: # v3.4+ Fixes: 2e87edf49227: "usb: gadget: make g_printer use composite" Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/legacy/printer.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index 90545980542f..6385c198c134 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -1031,6 +1031,15 @@ unknown: break; } /* host either stalls (value < 0) or reports success */ + if (value >= 0) { + req->length = value; + req->zero = value < wLength; + value = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC); + if (value < 0) { + ERROR(dev, "%s:%d Error!\n", __func__, __LINE__); + req->status = 0; + } + } return value; } -- GitLab From 050f571264154b2f5b4c3c4c1581ab365064ff28 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Tue, 3 Mar 2015 10:52:06 +0100 Subject: [PATCH 03809/11651] usb: gadget: printer: remove unused and empty printer_unbind The unbind() method is optional is usb_composite_driver. In this particular driver the method does nothing so it can be removed. Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/legacy/printer.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index 6385c198c134..21ea317d2a43 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -1288,11 +1288,6 @@ fail: return status; } -static int printer_unbind(struct usb_composite_dev *cdev) -{ - return 0; -} - static int __init printer_bind(struct usb_composite_dev *cdev) { int ret; @@ -1317,7 +1312,6 @@ static __refdata struct usb_composite_driver printer_driver = { .strings = dev_strings, .max_speed = USB_SPEED_SUPER, .bind = printer_bind, - .unbind = printer_unbind, }; static int __init -- GitLab From c69b8186945c10d245586e9f9703486e9574170c Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Tue, 3 Mar 2015 10:52:07 +0100 Subject: [PATCH 03810/11651] usb: gadget: printer: eliminate random pointer dereference struct printer_dev contains 3 list heads: tx_reqs, rx_reqs and rx_buffers. There is just one instance of this structure in the driver and it is file static, and as such initialized with all zeros. If device_create() or cdev_add() fails then "goto fail" branch is taken, which results in printer_cfg_unbind() call. The latter checks if tx_reqs, rx_reqs and rx_buffers lists are empty. The check for emptiness is in fact a check whether the "next" member of struct list_head points to the head of the list. But the heads of the lists in question have not been initialized yet and, as mentioned above, contain all zeros, so list_empty() returns false and respective "while" loop body starts executing. Here, container_of() just subtracts the offset of a struct usb_request member from an address of this same member, which results in a value somewhere near 0 or 0xfff...ff. And the argument to list_del() dereferences such a pointer which causes a disaster. This patch moves respective INIT_LIST_HEAD() invocations to a point before "goto fail" branch can be taken. Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/legacy/printer.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index 21ea317d2a43..12247d3fe768 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -1190,6 +1190,9 @@ static int __init printer_bind_config(struct usb_configuration *c) dev->function.unbind = printer_func_unbind; dev->function.set_alt = printer_func_set_alt; dev->function.disable = printer_func_disable; + INIT_LIST_HEAD(&dev->tx_reqs); + INIT_LIST_HEAD(&dev->rx_reqs); + INIT_LIST_HEAD(&dev->rx_buffers); status = usb_add_function(c, &dev->function); if (status) @@ -1233,11 +1236,8 @@ static int __init printer_bind_config(struct usb_configuration *c) spin_lock_init(&dev->lock); mutex_init(&dev->lock_printer_io); - INIT_LIST_HEAD(&dev->tx_reqs); INIT_LIST_HEAD(&dev->tx_reqs_active); - INIT_LIST_HEAD(&dev->rx_reqs); INIT_LIST_HEAD(&dev->rx_reqs_active); - INIT_LIST_HEAD(&dev->rx_buffers); init_waitqueue_head(&dev->rx_wait); init_waitqueue_head(&dev->tx_wait); init_waitqueue_head(&dev->tx_flush_wait); -- GitLab From f5bda0034fba942adf5555246e248ddb66c76052 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Tue, 3 Mar 2015 10:52:08 +0100 Subject: [PATCH 03811/11651] usb: gadget: printer: revert usb_add_function() effect in error recovery Whenever the "goto fail" branch is taken, the effect of usb_add_function() should be reverted. Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/legacy/printer.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index 12247d3fe768..eb02a6b8da08 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -1285,6 +1285,7 @@ static int __init printer_bind_config(struct usb_configuration *c) fail: printer_cfg_unbind(c); + usb_remove_function(c, &dev->function); return status; } -- GitLab From 44b316525986252bb95d356419fc9e75f0532112 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Tue, 3 Mar 2015 10:52:09 +0100 Subject: [PATCH 03812/11651] usb: gadget: printer: add missing error handling If cdev_add() in printer_bind_config() fails, care is taken to reverse the effects of initializations completed until the fail happens. But if printer_req_alloc() fails, it is just one of the two lists that is cleaned up while the effects of cdev_add() and device_create() are not reverted. This patch changes error handling so that at least as much cleanup is done as when a failure happens before printer_req_alloc() invocations. Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/legacy/printer.c | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index eb02a6b8da08..bbcd6aa9abd1 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -1249,31 +1249,18 @@ static int __init printer_bind_config(struct usb_configuration *c) dev->current_rx_bytes = 0; dev->current_rx_buf = NULL; + status = -ENOMEM; for (i = 0; i < QLEN; i++) { req = printer_req_alloc(dev->in_ep, USB_BUFSIZE, GFP_KERNEL); - if (!req) { - while (!list_empty(&dev->tx_reqs)) { - req = container_of(dev->tx_reqs.next, - struct usb_request, list); - list_del(&req->list); - printer_req_free(dev->in_ep, req); - } - return -ENOMEM; - } + if (!req) + goto fail; list_add(&req->list, &dev->tx_reqs); } for (i = 0; i < QLEN; i++) { req = printer_req_alloc(dev->out_ep, USB_BUFSIZE, GFP_KERNEL); - if (!req) { - while (!list_empty(&dev->rx_reqs)) { - req = container_of(dev->rx_reqs.next, - struct usb_request, list); - list_del(&req->list); - printer_req_free(dev->out_ep, req); - } - return -ENOMEM; - } + if (!req) + goto fail; list_add(&req->list, &dev->rx_reqs); } -- GitLab From 44eccced2b9aafd1eced9fb4821f26b6dff26a25 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Tue, 3 Mar 2015 10:52:10 +0100 Subject: [PATCH 03813/11651] usb: gadget: printer: eliminate pdev member of struct printer_dev The pdev member of struct printer_dev is not used outside printer_bind_config(), so it can just as well be a local variable there. Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/legacy/printer.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index bbcd6aa9abd1..a9c3e5782462 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -83,7 +83,6 @@ struct printer_dev { u8 printer_status; u8 reset_printer; struct cdev printer_cdev; - struct device *pdev; u8 printer_cdev_open; wait_queue_head_t wait; struct usb_function function; @@ -1175,6 +1174,7 @@ static int __init printer_bind_config(struct usb_configuration *c) { struct usb_gadget *gadget = c->cdev->gadget; struct printer_dev *dev; + struct device *pdev; int status = -ENOMEM; size_t len; u32 i; @@ -1199,11 +1199,11 @@ static int __init printer_bind_config(struct usb_configuration *c) return status; /* Setup the sysfs files for the printer gadget. */ - dev->pdev = device_create(usb_gadget_class, NULL, g_printer_devno, + pdev = device_create(usb_gadget_class, NULL, g_printer_devno, NULL, "g_printer"); - if (IS_ERR(dev->pdev)) { + if (IS_ERR(pdev)) { ERROR(dev, "Failed to create device: g_printer\n"); - status = PTR_ERR(dev->pdev); + status = PTR_ERR(pdev); goto fail; } -- GitLab From 406be2ccbadb5652f5894078d0e025d90683b3e9 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Tue, 3 Mar 2015 10:52:11 +0100 Subject: [PATCH 03814/11651] usb: gadget: printer: follow the naming convention for usb_add_config callback Legacy gadgets, before converting them to the new function framework, used to use the name _do_config() for usb_add_config()'s callback. This patch changes the name so that it is easier to follow the convention. Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/legacy/printer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index a9c3e5782462..c86583317431 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -1170,7 +1170,7 @@ static struct usb_configuration printer_cfg_driver = { .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, }; -static int __init printer_bind_config(struct usb_configuration *c) +static int __init printer_do_config(struct usb_configuration *c) { struct usb_gadget *gadget = c->cdev->gadget; struct printer_dev *dev; @@ -1287,7 +1287,7 @@ static int __init printer_bind(struct usb_composite_dev *cdev) device_desc.iProduct = strings[USB_GADGET_PRODUCT_IDX].id; device_desc.iSerialNumber = strings[USB_GADGET_SERIAL_IDX].id; - ret = usb_add_config(cdev, &printer_cfg_driver, printer_bind_config); + ret = usb_add_config(cdev, &printer_cfg_driver, printer_do_config); if (ret) return ret; usb_composite_overwrite_options(cdev, &coverwrite); -- GitLab From ae2dd0de57a3f6b12e30e5552033a492d6d206f7 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Tue, 3 Mar 2015 10:52:12 +0100 Subject: [PATCH 03815/11651] usb: gadget: printer: standardize printer_do_config Follow the convention of distributing source code between _do_config() and _bind_config(). Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/legacy/printer.c | 39 ++++++++++++++++++----------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index c86583317431..494cd8a5aca4 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -1170,7 +1170,8 @@ static struct usb_configuration printer_cfg_driver = { .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, }; -static int __init printer_do_config(struct usb_configuration *c) +static int f_printer_bind_config(struct usb_configuration *c, char *pnp_str, + unsigned q_len) { struct usb_gadget *gadget = c->cdev->gadget; struct printer_dev *dev; @@ -1180,8 +1181,6 @@ static int __init printer_do_config(struct usb_configuration *c) u32 i; struct usb_request *req; - usb_ep_autoconfig_reset(gadget); - dev = &usb_printer_gadget; dev->function.name = shortname; @@ -1219,21 +1218,13 @@ static int __init printer_do_config(struct usb_configuration *c) goto fail; } - if (iPNPstring) - strlcpy(&pnp_string[2], iPNPstring, (sizeof pnp_string)-2); + if (pnp_str) + strlcpy(&pnp_string[2], pnp_str, sizeof(pnp_string) - 2); len = strlen(pnp_string); pnp_string[0] = (len >> 8) & 0xFF; pnp_string[1] = len & 0xFF; - usb_gadget_set_selfpowered(gadget); - - if (gadget_is_otg(gadget)) { - otg_descriptor.bmAttributes |= USB_OTG_HNP; - printer_cfg_driver.descriptors = otg_desc; - printer_cfg_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP; - } - spin_lock_init(&dev->lock); mutex_init(&dev->lock_printer_io); INIT_LIST_HEAD(&dev->tx_reqs_active); @@ -1250,14 +1241,14 @@ static int __init printer_do_config(struct usb_configuration *c) dev->current_rx_buf = NULL; status = -ENOMEM; - for (i = 0; i < QLEN; i++) { + for (i = 0; i < q_len; i++) { req = printer_req_alloc(dev->in_ep, USB_BUFSIZE, GFP_KERNEL); if (!req) goto fail; list_add(&req->list, &dev->tx_reqs); } - for (i = 0; i < QLEN; i++) { + for (i = 0; i < q_len; i++) { req = printer_req_alloc(dev->out_ep, USB_BUFSIZE, GFP_KERNEL); if (!req) goto fail; @@ -1276,6 +1267,24 @@ fail: return status; } +static int __init printer_do_config(struct usb_configuration *c) +{ + struct usb_gadget *gadget = c->cdev->gadget; + + usb_ep_autoconfig_reset(gadget); + + usb_gadget_set_selfpowered(gadget); + + if (gadget_is_otg(gadget)) { + otg_descriptor.bmAttributes |= USB_OTG_HNP; + printer_cfg_driver.descriptors = otg_desc; + printer_cfg_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP; + } + + return f_printer_bind_config(c, iPNPstring, QLEN); + +} + static int __init printer_bind(struct usb_composite_dev *cdev) { int ret; -- GitLab From 4504b5a0b22e26a7213d9e08706303a790f5a400 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Tue, 3 Mar 2015 10:52:13 +0100 Subject: [PATCH 03816/11651] usb: gadget: printer: move function-related bind code to function's bind In order to factor out a reusable f_printer.c, the code related to the function should be placed in functions related to the function. Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/legacy/printer.c | 114 ++++++++++++++++------------ 1 file changed, 66 insertions(+), 48 deletions(-) diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index 494cd8a5aca4..c8570441a303 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -85,6 +85,7 @@ struct printer_dev { struct cdev printer_cdev; u8 printer_cdev_open; wait_queue_head_t wait; + unsigned q_len; struct usb_function function; }; @@ -1045,18 +1046,25 @@ unknown: static int __init printer_func_bind(struct usb_configuration *c, struct usb_function *f) { + struct usb_gadget *gadget = c->cdev->gadget; struct printer_dev *dev = container_of(f, struct printer_dev, function); + struct device *pdev; struct usb_composite_dev *cdev = c->cdev; struct usb_ep *in_ep; struct usb_ep *out_ep = NULL; + struct usb_request *req; int id; int ret; + u32 i; id = usb_interface_id(c, f); if (id < 0) return id; intf_desc.bInterfaceNumber = id; + /* finish hookup to lower layer ... */ + dev->gadget = gadget; + /* all we really need is bulk IN/OUT */ in_ep = usb_ep_autoconfig(cdev->gadget, &fs_ep_in_desc); if (!in_ep) { @@ -1085,7 +1093,64 @@ autoconf_fail: dev->in_ep = in_ep; dev->out_ep = out_ep; + + ret = -ENOMEM; + for (i = 0; i < dev->q_len; i++) { + req = printer_req_alloc(dev->in_ep, USB_BUFSIZE, GFP_KERNEL); + if (!req) + goto fail_tx_reqs; + list_add(&req->list, &dev->tx_reqs); + } + + for (i = 0; i < dev->q_len; i++) { + req = printer_req_alloc(dev->out_ep, USB_BUFSIZE, GFP_KERNEL); + if (!req) + goto fail_rx_reqs; + list_add(&req->list, &dev->rx_reqs); + } + + /* Setup the sysfs files for the printer gadget. */ + pdev = device_create(usb_gadget_class, NULL, g_printer_devno, + NULL, "g_printer"); + if (IS_ERR(pdev)) { + ERROR(dev, "Failed to create device: g_printer\n"); + ret = PTR_ERR(pdev); + goto fail_rx_reqs; + } + + /* + * Register a character device as an interface to a user mode + * program that handles the printer specific functionality. + */ + cdev_init(&dev->printer_cdev, &printer_io_operations); + dev->printer_cdev.owner = THIS_MODULE; + ret = cdev_add(&dev->printer_cdev, g_printer_devno, 1); + if (ret) { + ERROR(dev, "Failed to open char device\n"); + goto fail_cdev_add; + } + return 0; + +fail_cdev_add: + device_destroy(usb_gadget_class, g_printer_devno); + +fail_rx_reqs: + while (!list_empty(&dev->rx_reqs)) { + req = container_of(dev->rx_reqs.next, struct usb_request, list); + list_del(&req->list); + printer_req_free(dev->out_ep, req); + } + +fail_tx_reqs: + while (!list_empty(&dev->tx_reqs)) { + req = container_of(dev->tx_reqs.next, struct usb_request, list); + list_del(&req->list); + printer_req_free(dev->in_ep, req); + } + + return ret; + } static void printer_func_unbind(struct usb_configuration *c, @@ -1173,13 +1238,9 @@ static struct usb_configuration printer_cfg_driver = { static int f_printer_bind_config(struct usb_configuration *c, char *pnp_str, unsigned q_len) { - struct usb_gadget *gadget = c->cdev->gadget; struct printer_dev *dev; - struct device *pdev; int status = -ENOMEM; size_t len; - u32 i; - struct usb_request *req; dev = &usb_printer_gadget; @@ -1193,31 +1254,11 @@ static int f_printer_bind_config(struct usb_configuration *c, char *pnp_str, INIT_LIST_HEAD(&dev->rx_reqs); INIT_LIST_HEAD(&dev->rx_buffers); + dev->q_len = q_len; status = usb_add_function(c, &dev->function); if (status) return status; - /* Setup the sysfs files for the printer gadget. */ - pdev = device_create(usb_gadget_class, NULL, g_printer_devno, - NULL, "g_printer"); - if (IS_ERR(pdev)) { - ERROR(dev, "Failed to create device: g_printer\n"); - status = PTR_ERR(pdev); - goto fail; - } - - /* - * Register a character device as an interface to a user mode - * program that handles the printer specific functionality. - */ - cdev_init(&dev->printer_cdev, &printer_io_operations); - dev->printer_cdev.owner = THIS_MODULE; - status = cdev_add(&dev->printer_cdev, g_printer_devno, 1); - if (status) { - ERROR(dev, "Failed to open char device\n"); - goto fail; - } - if (pnp_str) strlcpy(&pnp_string[2], pnp_str, sizeof(pnp_string) - 2); @@ -1240,31 +1281,8 @@ static int f_printer_bind_config(struct usb_configuration *c, char *pnp_str, dev->current_rx_bytes = 0; dev->current_rx_buf = NULL; - status = -ENOMEM; - for (i = 0; i < q_len; i++) { - req = printer_req_alloc(dev->in_ep, USB_BUFSIZE, GFP_KERNEL); - if (!req) - goto fail; - list_add(&req->list, &dev->tx_reqs); - } - - for (i = 0; i < q_len; i++) { - req = printer_req_alloc(dev->out_ep, USB_BUFSIZE, GFP_KERNEL); - if (!req) - goto fail; - list_add(&req->list, &dev->rx_reqs); - } - - /* finish hookup to lower layer ... */ - dev->gadget = gadget; - INFO(dev, "%s, version: " DRIVER_VERSION "\n", driver_desc); return 0; - -fail: - printer_cfg_unbind(c); - usb_remove_function(c, &dev->function); - return status; } static int __init printer_do_config(struct usb_configuration *c) -- GitLab From cee5cbff8d80ec2d10fe8070f229e95cc42443bf Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Tue, 3 Mar 2015 10:52:14 +0100 Subject: [PATCH 03817/11651] usb: gadget: printer: call usb_add_function() last Conversion to the new function interface requires splitting a _bind_config() function into two parts: allocation of container_of struct usb_function and invocation of usb_add_function(). This patch moves the latter to the end of the f_printer_bind_config() in order to enable conversion to the new interface. Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/legacy/printer.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index c8570441a303..5dbb93a91512 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -1254,11 +1254,6 @@ static int f_printer_bind_config(struct usb_configuration *c, char *pnp_str, INIT_LIST_HEAD(&dev->rx_reqs); INIT_LIST_HEAD(&dev->rx_buffers); - dev->q_len = q_len; - status = usb_add_function(c, &dev->function); - if (status) - return status; - if (pnp_str) strlcpy(&pnp_string[2], pnp_str, sizeof(pnp_string) - 2); @@ -1280,7 +1275,11 @@ static int f_printer_bind_config(struct usb_configuration *c, char *pnp_str, dev->current_rx_req = NULL; dev->current_rx_bytes = 0; dev->current_rx_buf = NULL; + dev->q_len = q_len; + status = usb_add_function(c, &dev->function); + if (status) + return status; INFO(dev, "%s, version: " DRIVER_VERSION "\n", driver_desc); return 0; } -- GitLab From 991cd26249e775c07347ab4d62adfbc3284e7704 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Tue, 3 Mar 2015 10:52:15 +0100 Subject: [PATCH 03818/11651] usb: gadget: printer: move function-related unbind code to function's unbind In order to factor out a reusable f_printer.c, the code related to the function should be placed in functions related to the function. printer_cfg_unbind() becomes empty, so it is removed. Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/legacy/printer.c | 58 +++++++++++++---------------- 1 file changed, 25 insertions(+), 33 deletions(-) diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index 5dbb93a91512..84e6cdd72137 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -1155,44 +1155,12 @@ fail_tx_reqs: static void printer_func_unbind(struct usb_configuration *c, struct usb_function *f) -{ - usb_free_all_descriptors(f); -} - -static int printer_func_set_alt(struct usb_function *f, - unsigned intf, unsigned alt) -{ - struct printer_dev *dev = container_of(f, struct printer_dev, function); - int ret = -ENOTSUPP; - - if (!alt) - ret = set_interface(dev, intf); - - return ret; -} - -static void printer_func_disable(struct usb_function *f) -{ - struct printer_dev *dev = container_of(f, struct printer_dev, function); - unsigned long flags; - - DBG(dev, "%s\n", __func__); - - spin_lock_irqsave(&dev->lock, flags); - printer_reset_interface(dev); - spin_unlock_irqrestore(&dev->lock, flags); -} - -static void printer_cfg_unbind(struct usb_configuration *c) { struct printer_dev *dev; struct usb_request *req; dev = &usb_printer_gadget; - DBG(dev, "%s\n", __func__); - - /* Remove sysfs files */ device_destroy(usb_gadget_class, g_printer_devno); /* Remove Character Device */ @@ -1226,11 +1194,35 @@ static void printer_cfg_unbind(struct usb_configuration *c) list_del(&req->list); printer_req_free(dev->out_ep, req); } + usb_free_all_descriptors(f); +} + +static int printer_func_set_alt(struct usb_function *f, + unsigned intf, unsigned alt) +{ + struct printer_dev *dev = container_of(f, struct printer_dev, function); + int ret = -ENOTSUPP; + + if (!alt) + ret = set_interface(dev, intf); + + return ret; +} + +static void printer_func_disable(struct usb_function *f) +{ + struct printer_dev *dev = container_of(f, struct printer_dev, function); + unsigned long flags; + + DBG(dev, "%s\n", __func__); + + spin_lock_irqsave(&dev->lock, flags); + printer_reset_interface(dev); + spin_unlock_irqrestore(&dev->lock, flags); } static struct usb_configuration printer_cfg_driver = { .label = "printer", - .unbind = printer_cfg_unbind, .bConfigurationValue = 1, .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, }; -- GitLab From 085617a1eb865c2987c05652bf82d35f500ac4b4 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Tue, 3 Mar 2015 10:52:16 +0100 Subject: [PATCH 03819/11651] usb: gadget: printer: define pnp string buffer length Avoid using magic numbers. Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/legacy/printer.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index 84e6cdd72137..db5e2f0681c7 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -276,9 +276,11 @@ static inline struct usb_endpoint_descriptor *ep_desc(struct usb_gadget *gadget, /* descriptors that are built on-demand */ +#define PNP_STRING_LEN 1024 + static char product_desc [40] = DRIVER_DESC; static char serial_num [40] = "1"; -static char pnp_string [1024] = +static char pnp_string[PNP_STRING_LEN] = "XXMFG:linux;MDL:g_printer;CLS:PRINTER;SN:1;"; /* static strings, in UTF-8 */ @@ -1247,7 +1249,7 @@ static int f_printer_bind_config(struct usb_configuration *c, char *pnp_str, INIT_LIST_HEAD(&dev->rx_buffers); if (pnp_str) - strlcpy(&pnp_string[2], pnp_str, sizeof(pnp_string) - 2); + strlcpy(&pnp_string[2], pnp_str, PNP_STRING_LEN - 2); len = strlen(pnp_string); pnp_string[0] = (len >> 8) & 0xFF; -- GitLab From 5a84e6f608598dd691c0024eab50fffb96aca43b Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Tue, 3 Mar 2015 10:52:17 +0100 Subject: [PATCH 03820/11651] usb: gadget: printer: don't access file global pnp_string in function's code In order to factor out a reusable f_printer, the function's code should not use file global variables related to legacy printer gadget's implementation. Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/legacy/printer.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index db5e2f0681c7..42c46da6f59f 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -86,6 +86,7 @@ struct printer_dev { u8 printer_cdev_open; wait_queue_head_t wait; unsigned q_len; + char *pnp_string; /* We don't own memory! */ struct usb_function function; }; @@ -994,10 +995,10 @@ static int printer_func_setup(struct usb_function *f, if ((wIndex>>8) != dev->interface) break; - value = (pnp_string[0]<<8)|pnp_string[1]; - memcpy(req->buf, pnp_string, value); + value = (dev->pnp_string[0] << 8) | dev->pnp_string[1]; + memcpy(req->buf, dev->pnp_string, value); DBG(dev, "1284 PNP String: %x %s\n", value, - &pnp_string[2]); + &dev->pnp_string[2]); break; case 1: /* Get Port Status */ @@ -1230,13 +1231,14 @@ static struct usb_configuration printer_cfg_driver = { }; static int f_printer_bind_config(struct usb_configuration *c, char *pnp_str, - unsigned q_len) + char *pnp_string, unsigned q_len) { struct printer_dev *dev; int status = -ENOMEM; size_t len; dev = &usb_printer_gadget; + dev->pnp_string = pnp_string; dev->function.name = shortname; dev->function.bind = printer_func_bind; @@ -1249,7 +1251,7 @@ static int f_printer_bind_config(struct usb_configuration *c, char *pnp_str, INIT_LIST_HEAD(&dev->rx_buffers); if (pnp_str) - strlcpy(&pnp_string[2], pnp_str, PNP_STRING_LEN - 2); + strlcpy(&dev->pnp_string[2], pnp_str, PNP_STRING_LEN - 2); len = strlen(pnp_string); pnp_string[0] = (len >> 8) & 0xFF; @@ -1292,7 +1294,7 @@ static int __init printer_do_config(struct usb_configuration *c) printer_cfg_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP; } - return f_printer_bind_config(c, iPNPstring, QLEN); + return f_printer_bind_config(c, iPNPstring, pnp_string, QLEN); } -- GitLab From d82cd82edb98d727c6a0804a6e271e3081559404 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Tue, 3 Mar 2015 10:52:18 +0100 Subject: [PATCH 03821/11651] usb: gadget: printer: add setup and cleanup functions Factor out gprinter_setup() and gprinter_cleanup() so that it is easy to change the place they are called from. Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/legacy/printer.c | 46 +++++++++++++++++++---------- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index 42c46da6f59f..83cea9a5c75e 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -1298,6 +1298,34 @@ static int __init printer_do_config(struct usb_configuration *c) } +static int gprinter_setup(void) +{ + int status; + + usb_gadget_class = class_create(THIS_MODULE, "usb_printer_gadget"); + if (IS_ERR(usb_gadget_class)) { + status = PTR_ERR(usb_gadget_class); + pr_err("unable to create usb_gadget class %d\n", status); + return status; + } + + status = alloc_chrdev_region(&g_printer_devno, 0, 1, + "USB printer gadget"); + if (status) { + pr_err("alloc_chrdev_region %d\n", status); + class_destroy(usb_gadget_class); + } + + return status; +} + +/* must be called with struct printer_dev's lock_printer_io held */ +static void gprinter_cleanup(void) +{ + unregister_chrdev_region(g_printer_devno, 1); + class_destroy(usb_gadget_class); +} + static int __init printer_bind(struct usb_composite_dev *cdev) { int ret; @@ -1329,20 +1357,9 @@ init(void) { int status; - usb_gadget_class = class_create(THIS_MODULE, "usb_printer_gadget"); - if (IS_ERR(usb_gadget_class)) { - status = PTR_ERR(usb_gadget_class); - pr_err("unable to create usb_gadget class %d\n", status); - return status; - } - - status = alloc_chrdev_region(&g_printer_devno, 0, 1, - "USB printer gadget"); - if (status) { - pr_err("alloc_chrdev_region %d\n", status); - class_destroy(usb_gadget_class); + status = gprinter_setup(); + if (status) return status; - } status = usb_composite_probe(&printer_driver); if (status) { @@ -1360,8 +1377,7 @@ cleanup(void) { mutex_lock(&usb_printer_gadget.lock_printer_io); usb_composite_unregister(&printer_driver); - unregister_chrdev_region(g_printer_devno, 1); - class_destroy(usb_gadget_class); + gprinter_cleanup(); mutex_unlock(&usb_printer_gadget.lock_printer_io); } module_exit(cleanup); -- GitLab From a844715d2fc44adc2da17f90b34cc0d0c1e81596 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Tue, 3 Mar 2015 10:52:19 +0100 Subject: [PATCH 03822/11651] usb: gadget: printer: call gprinter_setup() from gadget's bind Call gprinter_setup() from gadget's bind instead of module's init. Call gprinter_cleaup() corerspondingly. This detaches printer function's logic from legacy printer gadget's implementation. Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/legacy/printer.c | 35 +++++++++++++++-------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index 83cea9a5c75e..b7889b1f7afa 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -1330,45 +1330,47 @@ static int __init printer_bind(struct usb_composite_dev *cdev) { int ret; + ret = gprinter_setup(); + if (ret) + return ret; + ret = usb_string_ids_tab(cdev, strings); - if (ret < 0) + if (ret < 0) { + gprinter_cleanup(); return ret; + } device_desc.iManufacturer = strings[USB_GADGET_MANUFACTURER_IDX].id; device_desc.iProduct = strings[USB_GADGET_PRODUCT_IDX].id; device_desc.iSerialNumber = strings[USB_GADGET_SERIAL_IDX].id; ret = usb_add_config(cdev, &printer_cfg_driver, printer_do_config); - if (ret) + if (ret) { + gprinter_cleanup(); return ret; + } usb_composite_overwrite_options(cdev, &coverwrite); return ret; } +static int __exit printer_unbind(struct usb_composite_dev *cdev) +{ + gprinter_cleanup(); + return 0; +} + static __refdata struct usb_composite_driver printer_driver = { .name = shortname, .dev = &device_desc, .strings = dev_strings, .max_speed = USB_SPEED_SUPER, .bind = printer_bind, + .unbind = printer_unbind, }; static int __init init(void) { - int status; - - status = gprinter_setup(); - if (status) - return status; - - status = usb_composite_probe(&printer_driver); - if (status) { - class_destroy(usb_gadget_class); - unregister_chrdev_region(g_printer_devno, 1); - pr_err("usb_gadget_probe_driver %x\n", status); - } - - return status; + return usb_composite_probe(&printer_driver); } module_init(init); @@ -1377,7 +1379,6 @@ cleanup(void) { mutex_lock(&usb_printer_gadget.lock_printer_io); usb_composite_unregister(&printer_driver); - gprinter_cleanup(); mutex_unlock(&usb_printer_gadget.lock_printer_io); } module_exit(cleanup); -- GitLab From dec81cf1dcaac5b91de7cd32c96aadcb94840c7f Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Tue, 3 Mar 2015 10:52:20 +0100 Subject: [PATCH 03823/11651] usb: gadget: printer: eliminate file global printer_mutex The mutex is a legacy after semi-automatic Big Kernel Lock removal. printer_open() does its own locking, so no need to duplicate it. Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/legacy/printer.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index b7889b1f7afa..3206ebcdd7a6 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -48,7 +48,6 @@ USB_GADGET_COMPOSITE_OPTIONS(); #define DRIVER_DESC "Printer Gadget" #define DRIVER_VERSION "2007 OCT 06" -static DEFINE_MUTEX(printer_mutex); static const char shortname [] = "printer"; static const char driver_desc [] = DRIVER_DESC; @@ -420,7 +419,6 @@ printer_open(struct inode *inode, struct file *fd) unsigned long flags; int ret = -EBUSY; - mutex_lock(&printer_mutex); dev = container_of(inode->i_cdev, struct printer_dev, printer_cdev); spin_lock_irqsave(&dev->lock, flags); @@ -436,7 +434,6 @@ printer_open(struct inode *inode, struct file *fd) spin_unlock_irqrestore(&dev->lock, flags); DBG(dev, "printer_open returned %x\n", ret); - mutex_unlock(&printer_mutex); return ret; } -- GitLab From 8fe20f661f3cfbb6778368eb3c73f8a6438ac640 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Tue, 3 Mar 2015 10:52:21 +0100 Subject: [PATCH 03824/11651] usb: gadget: printer: don't access file global usb_printer_gadget in function's code The printer_dev can be recovered from printer_func_unbind() function's parameters. Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/legacy/printer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index 3206ebcdd7a6..806475c19934 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -1159,7 +1159,7 @@ static void printer_func_unbind(struct usb_configuration *c, struct printer_dev *dev; struct usb_request *req; - dev = &usb_printer_gadget; + dev = container_of(f, struct printer_dev, function); device_destroy(usb_gadget_class, g_printer_devno); -- GitLab From 143d53e10ecfeee7245341aa9c50515b5680ffd4 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Tue, 3 Mar 2015 10:52:22 +0100 Subject: [PATCH 03825/11651] usb: gadget: printer: add container_of helper for printer_dev 5 uses of container_of() in the same context justify wrapping it in a static inline function. Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/legacy/printer.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index 806475c19934..955847fe8092 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -89,6 +89,11 @@ struct printer_dev { struct usb_function function; }; +static inline struct printer_dev *func_to_printer(struct usb_function *f) +{ + return container_of(f, struct printer_dev, function); +} + static struct printer_dev usb_printer_gadget; /*-------------------------------------------------------------------------*/ @@ -973,7 +978,7 @@ static void printer_soft_reset(struct printer_dev *dev) static int printer_func_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) { - struct printer_dev *dev = container_of(f, struct printer_dev, function); + struct printer_dev *dev = func_to_printer(f); struct usb_composite_dev *cdev = f->config->cdev; struct usb_request *req = cdev->req; int value = -EOPNOTSUPP; @@ -1047,7 +1052,7 @@ static int __init printer_func_bind(struct usb_configuration *c, struct usb_function *f) { struct usb_gadget *gadget = c->cdev->gadget; - struct printer_dev *dev = container_of(f, struct printer_dev, function); + struct printer_dev *dev = func_to_printer(f); struct device *pdev; struct usb_composite_dev *cdev = c->cdev; struct usb_ep *in_ep; @@ -1159,7 +1164,7 @@ static void printer_func_unbind(struct usb_configuration *c, struct printer_dev *dev; struct usb_request *req; - dev = container_of(f, struct printer_dev, function); + dev = func_to_printer(f); device_destroy(usb_gadget_class, g_printer_devno); @@ -1200,7 +1205,7 @@ static void printer_func_unbind(struct usb_configuration *c, static int printer_func_set_alt(struct usb_function *f, unsigned intf, unsigned alt) { - struct printer_dev *dev = container_of(f, struct printer_dev, function); + struct printer_dev *dev = func_to_printer(f); int ret = -ENOTSUPP; if (!alt) @@ -1211,7 +1216,7 @@ static int printer_func_set_alt(struct usb_function *f, static void printer_func_disable(struct usb_function *f) { - struct printer_dev *dev = container_of(f, struct printer_dev, function); + struct printer_dev *dev = func_to_printer(f); unsigned long flags; DBG(dev, "%s\n", __func__); -- GitLab From f563d230903210acc2336af58e422216b68ded76 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Tue, 3 Mar 2015 10:52:23 +0100 Subject: [PATCH 03826/11651] usb: gadget: composite: add req_match method to usb_function Non-standard requests can encode the actual interface number in a non-standard way. For example composite_setup() assumes that it is w_index && 0xFF, but the printer function encodes the interface number in a context-dependet way (either w_index or w_index >> 8). This can lead to such requests being directed to wrong functions. This patch adds req_match() method to usb_function. Its purpose is to verify that a given request can be handled by a given function. If any function within a configuration provides the method and it returns true, then it is assumed that the right function is found. If a function uses req_match(), it should try as hard as possible to determine if the request is meant for it. If no functions in a configuration provide req_match or none of them returns true, then fall back to the usual approach. Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/composite.c | 6 +++++- include/linux/usb/composite.h | 3 +++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 9fb92310fb2b..4d25e11b1f72 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -1758,6 +1758,10 @@ unknown: * take such requests too, if that's ever needed: to work * in config 0, etc. */ + list_for_each_entry(f, &cdev->config->functions, list) + if (f->req_match && f->req_match(f, ctrl)) + goto try_fun_setup; + f = NULL; switch (ctrl->bRequestType & USB_RECIP_MASK) { case USB_RECIP_INTERFACE: if (!cdev->config || intf >= MAX_CONFIG_INTERFACES) @@ -1775,7 +1779,7 @@ unknown: f = NULL; break; } - +try_fun_setup: if (f && f->setup) value = f->setup(f, ctrl); else { diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h index 3d87defcc527..2511469a9904 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h @@ -148,6 +148,7 @@ struct usb_os_desc_table { * @disable: (REQUIRED) Indicates the function should be disabled. Reasons * include host resetting or reconfiguring the gadget, and disconnection. * @setup: Used for interface-specific control requests. + * @req_match: Tests if a given class request can be handled by this function. * @suspend: Notifies functions when the host stops sending USB traffic. * @resume: Notifies functions when the host restarts USB traffic. * @get_status: Returns function status as a reply to @@ -213,6 +214,8 @@ struct usb_function { void (*disable)(struct usb_function *); int (*setup)(struct usb_function *, const struct usb_ctrlrequest *); + bool (*req_match)(struct usb_function *, + const struct usb_ctrlrequest *); void (*suspend)(struct usb_function *); void (*resume)(struct usb_function *); -- GitLab From d7239f4c6daeb7a987a0e6f37a3ea24b37f7c208 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Tue, 3 Mar 2015 10:52:24 +0100 Subject: [PATCH 03827/11651] usb: gadget: printer: name class specific requests Avoid using magic numbers. Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/legacy/printer.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index 955847fe8092..78f515413e3b 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -47,6 +47,9 @@ USB_GADGET_COMPOSITE_OPTIONS(); #define DRIVER_DESC "Printer Gadget" #define DRIVER_VERSION "2007 OCT 06" +#define GET_DEVICE_ID 0 +#define GET_PORT_STATUS 1 +#define SOFT_RESET 2 static const char shortname [] = "printer"; static const char driver_desc [] = DRIVER_DESC; @@ -992,7 +995,7 @@ static int printer_func_setup(struct usb_function *f, switch (ctrl->bRequestType&USB_TYPE_MASK) { case USB_TYPE_CLASS: switch (ctrl->bRequest) { - case 0: /* Get the IEEE-1284 PNP String */ + case GET_DEVICE_ID: /* Get the IEEE-1284 PNP String */ /* Only one printer interface is supported. */ if ((wIndex>>8) != dev->interface) break; @@ -1003,7 +1006,7 @@ static int printer_func_setup(struct usb_function *f, &dev->pnp_string[2]); break; - case 1: /* Get Port Status */ + case GET_PORT_STATUS: /* Get Port Status */ /* Only one printer interface is supported. */ if (wIndex != dev->interface) break; @@ -1012,7 +1015,7 @@ static int printer_func_setup(struct usb_function *f, value = min(wLength, (u16) 1); break; - case 2: /* Soft Reset */ + case SOFT_RESET: /* Soft Reset */ /* Only one printer interface is supported. */ if (wIndex != dev->interface) break; -- GitLab From 636bc0ed271d996e18365345e9c00fc712edc610 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Tue, 3 Mar 2015 10:52:25 +0100 Subject: [PATCH 03828/11651] usb: gadget: printer: add req_match for printer function Verify that a given usb_ctrlrequest is meant for printer function. The following parts of the request are tested: - bmRequestType:Data transfer direction - bmRequestType:Type - bmRequestType:Recipient - bRequest - wValue for bRequest 1 and 2 - wLength Additionally, the request is considered meant for this function iff the decoded interface number matches dev->interface. Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/legacy/printer.c | 36 +++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index 78f515413e3b..c059af1aa454 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -974,6 +974,41 @@ static void printer_soft_reset(struct printer_dev *dev) /*-------------------------------------------------------------------------*/ +static bool gprinter_req_match(struct usb_function *f, + const struct usb_ctrlrequest *ctrl) +{ + struct printer_dev *dev = func_to_printer(f); + u16 w_index = le16_to_cpu(ctrl->wIndex); + u16 w_value = le16_to_cpu(ctrl->wValue); + u16 w_length = le16_to_cpu(ctrl->wLength); + + if ((ctrl->bRequestType & USB_RECIP_MASK) != USB_RECIP_INTERFACE || + (ctrl->bRequestType & USB_TYPE_MASK) != USB_TYPE_CLASS) + return false; + + switch (ctrl->bRequest) { + case GET_DEVICE_ID: + w_index >>= 8; + if (w_length <= PNP_STRING_LEN && + (USB_DIR_IN & ctrl->bRequestType)) + break; + return false; + case GET_PORT_STATUS: + if (!w_value && w_length == 1 && + (USB_DIR_IN & ctrl->bRequestType)) + break; + return false; + case SOFT_RESET: + if (!w_value && !w_length && + (USB_DIR_OUT & ctrl->bRequestType)) + break; + /* fall through */ + default: + return false; + } + return w_index == dev->interface; +} + /* * The setup() callback implements all the ep0 functionality that's not * handled lower down. @@ -1251,6 +1286,7 @@ static int f_printer_bind_config(struct usb_configuration *c, char *pnp_str, dev->function.unbind = printer_func_unbind; dev->function.set_alt = printer_func_set_alt; dev->function.disable = printer_func_disable; + dev->function.req_match = gprinter_req_match; INIT_LIST_HEAD(&dev->tx_reqs); INIT_LIST_HEAD(&dev->rx_reqs); INIT_LIST_HEAD(&dev->rx_buffers); -- GitLab From 6dd8c2e69521ec9d7b23a741294702f844353f1a Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Tue, 3 Mar 2015 10:52:26 +0100 Subject: [PATCH 03829/11651] usb: gadget: printer: allocate printer_dev instances dynamically With all the obstacles removed it is possible to allow more than one instance of the printer function. Since the function requires allocating character device region, a maximum number of allowed instances is defined. Such an approach is used in f_acm and in f_hid. With multiple instances it does not make sense to depend on a lock_printer_io member of a dynamically allocated (and destroyed) struct printer_dev to clean up after all instances of the printer function. Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/legacy/printer.c | 62 +++++++++++++++++++---------- 1 file changed, 40 insertions(+), 22 deletions(-) diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index c059af1aa454..d1f85f81975f 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -51,11 +51,12 @@ USB_GADGET_COMPOSITE_OPTIONS(); #define GET_PORT_STATUS 1 #define SOFT_RESET 2 +#define PRINTER_MINORS 4 + static const char shortname [] = "printer"; static const char driver_desc [] = DRIVER_DESC; -static dev_t g_printer_devno; - +static int major, minors; static struct class *usb_gadget_class; /*-------------------------------------------------------------------------*/ @@ -84,6 +85,7 @@ struct printer_dev { u8 *current_rx_buf; u8 printer_status; u8 reset_printer; + int minor; struct cdev printer_cdev; u8 printer_cdev_open; wait_queue_head_t wait; @@ -97,8 +99,6 @@ static inline struct printer_dev *func_to_printer(struct usb_function *f) return container_of(f, struct printer_dev, function); } -static struct printer_dev usb_printer_gadget; - /*-------------------------------------------------------------------------*/ /* DO NOT REUSE THESE IDs with a protocol-incompatible driver!! Ever!! @@ -1096,6 +1096,7 @@ static int __init printer_func_bind(struct usb_configuration *c, struct usb_ep *in_ep; struct usb_ep *out_ep = NULL; struct usb_request *req; + dev_t devt; int id; int ret; u32 i; @@ -1153,8 +1154,9 @@ autoconf_fail: } /* Setup the sysfs files for the printer gadget. */ - pdev = device_create(usb_gadget_class, NULL, g_printer_devno, - NULL, "g_printer"); + devt = MKDEV(major, dev->minor); + pdev = device_create(usb_gadget_class, NULL, devt, + NULL, "g_printer%d", dev->minor); if (IS_ERR(pdev)) { ERROR(dev, "Failed to create device: g_printer\n"); ret = PTR_ERR(pdev); @@ -1167,7 +1169,7 @@ autoconf_fail: */ cdev_init(&dev->printer_cdev, &printer_io_operations); dev->printer_cdev.owner = THIS_MODULE; - ret = cdev_add(&dev->printer_cdev, g_printer_devno, 1); + ret = cdev_add(&dev->printer_cdev, devt, 1); if (ret) { ERROR(dev, "Failed to open char device\n"); goto fail_cdev_add; @@ -1176,7 +1178,7 @@ autoconf_fail: return 0; fail_cdev_add: - device_destroy(usb_gadget_class, g_printer_devno); + device_destroy(usb_gadget_class, devt); fail_rx_reqs: while (!list_empty(&dev->rx_reqs)) { @@ -1204,7 +1206,7 @@ static void printer_func_unbind(struct usb_configuration *c, dev = func_to_printer(f); - device_destroy(usb_gadget_class, g_printer_devno); + device_destroy(usb_gadget_class, MKDEV(major, dev->minor)); /* Remove Character Device */ cdev_del(&dev->printer_cdev); @@ -1238,6 +1240,7 @@ static void printer_func_unbind(struct usb_configuration *c, printer_req_free(dev->out_ep, req); } usb_free_all_descriptors(f); + kfree(dev); } static int printer_func_set_alt(struct usb_function *f, @@ -1271,14 +1274,21 @@ static struct usb_configuration printer_cfg_driver = { }; static int f_printer_bind_config(struct usb_configuration *c, char *pnp_str, - char *pnp_string, unsigned q_len) + char *pnp_string, unsigned q_len, int minor) { struct printer_dev *dev; int status = -ENOMEM; size_t len; - dev = &usb_printer_gadget; + if (minor >= minors) + return -ENOENT; + + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) + return -ENOMEM; + dev->pnp_string = pnp_string; + dev->minor = minor; dev->function.name = shortname; dev->function.bind = printer_func_bind; @@ -1315,8 +1325,10 @@ static int f_printer_bind_config(struct usb_configuration *c, char *pnp_str, dev->q_len = q_len; status = usb_add_function(c, &dev->function); - if (status) + if (status) { + kfree(dev); return status; + } INFO(dev, "%s, version: " DRIVER_VERSION "\n", driver_desc); return 0; } @@ -1335,43 +1347,51 @@ static int __init printer_do_config(struct usb_configuration *c) printer_cfg_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP; } - return f_printer_bind_config(c, iPNPstring, pnp_string, QLEN); - + return f_printer_bind_config(c, iPNPstring, pnp_string, QLEN, 0); } -static int gprinter_setup(void) +static int gprinter_setup(int count) { int status; + dev_t devt; usb_gadget_class = class_create(THIS_MODULE, "usb_printer_gadget"); if (IS_ERR(usb_gadget_class)) { status = PTR_ERR(usb_gadget_class); + usb_gadget_class = NULL; pr_err("unable to create usb_gadget class %d\n", status); return status; } - status = alloc_chrdev_region(&g_printer_devno, 0, 1, - "USB printer gadget"); + status = alloc_chrdev_region(&devt, 0, count, "USB printer gadget"); if (status) { pr_err("alloc_chrdev_region %d\n", status); class_destroy(usb_gadget_class); + usb_gadget_class = NULL; + return status; } + major = MAJOR(devt); + minors = count; + return status; } -/* must be called with struct printer_dev's lock_printer_io held */ static void gprinter_cleanup(void) { - unregister_chrdev_region(g_printer_devno, 1); + if (major) { + unregister_chrdev_region(MKDEV(major, 0), minors); + major = minors = 0; + } class_destroy(usb_gadget_class); + usb_gadget_class = NULL; } static int __init printer_bind(struct usb_composite_dev *cdev) { int ret; - ret = gprinter_setup(); + ret = gprinter_setup(PRINTER_MINORS); if (ret) return ret; @@ -1418,9 +1438,7 @@ module_init(init); static void __exit cleanup(void) { - mutex_lock(&usb_printer_gadget.lock_printer_io); usb_composite_unregister(&printer_driver); - mutex_unlock(&usb_printer_gadget.lock_printer_io); } module_exit(cleanup); -- GitLab From b185f01a9ab7af586133be2555298e960237359b Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Tue, 3 Mar 2015 10:52:27 +0100 Subject: [PATCH 03830/11651] usb: gadget: printer: factor out f_printer The legacy printer gadget now contains both a reusable printer function and legacy gadget proper implementations interwoven, but logically separate. This patch factors out a reusable f_printer. Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_printer.c | 1279 +++++++++++++++++++++++ drivers/usb/gadget/legacy/printer.c | 1255 +--------------------- 2 files changed, 1285 insertions(+), 1249 deletions(-) create mode 100644 drivers/usb/gadget/function/f_printer.c diff --git a/drivers/usb/gadget/function/f_printer.c b/drivers/usb/gadget/function/f_printer.c new file mode 100644 index 000000000000..0847972b9686 --- /dev/null +++ b/drivers/usb/gadget/function/f_printer.c @@ -0,0 +1,1279 @@ +/* + * f_printer.c - USB printer function driver + * + * Copied from drivers/usb/gadget/legacy/printer.c, + * which was: + * + * printer.c -- Printer gadget driver + * + * Copyright (C) 2003-2005 David Brownell + * Copyright (C) 2006 Craig W. Nadler + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define PNP_STRING_LEN 1024 +#define PRINTER_MINORS 4 +#define GET_DEVICE_ID 0 +#define GET_PORT_STATUS 1 +#define SOFT_RESET 2 + +static int major, minors; +static struct class *usb_gadget_class; + +/*-------------------------------------------------------------------------*/ + +struct printer_dev { + spinlock_t lock; /* lock this structure */ + /* lock buffer lists during read/write calls */ + struct mutex lock_printer_io; + struct usb_gadget *gadget; + s8 interface; + struct usb_ep *in_ep, *out_ep; + + struct list_head rx_reqs; /* List of free RX structs */ + struct list_head rx_reqs_active; /* List of Active RX xfers */ + struct list_head rx_buffers; /* List of completed xfers */ + /* wait until there is data to be read. */ + wait_queue_head_t rx_wait; + struct list_head tx_reqs; /* List of free TX structs */ + struct list_head tx_reqs_active; /* List of Active TX xfers */ + /* Wait until there are write buffers available to use. */ + wait_queue_head_t tx_wait; + /* Wait until all write buffers have been sent. */ + wait_queue_head_t tx_flush_wait; + struct usb_request *current_rx_req; + size_t current_rx_bytes; + u8 *current_rx_buf; + u8 printer_status; + u8 reset_printer; + int minor; + struct cdev printer_cdev; + u8 printer_cdev_open; + wait_queue_head_t wait; + unsigned q_len; + char *pnp_string; /* We don't own memory! */ + struct usb_function function; +}; + +static inline struct printer_dev *func_to_printer(struct usb_function *f) +{ + return container_of(f, struct printer_dev, function); +} + +/*-------------------------------------------------------------------------*/ + +/* + * DESCRIPTORS ... most are static, but strings and (full) configuration + * descriptors are built on demand. + */ + +/* holds our biggest descriptor */ +#define USB_DESC_BUFSIZE 256 +#define USB_BUFSIZE 8192 + +static struct usb_interface_descriptor intf_desc = { + .bLength = sizeof(intf_desc), + .bDescriptorType = USB_DT_INTERFACE, + .bNumEndpoints = 2, + .bInterfaceClass = USB_CLASS_PRINTER, + .bInterfaceSubClass = 1, /* Printer Sub-Class */ + .bInterfaceProtocol = 2, /* Bi-Directional */ + .iInterface = 0 +}; + +static struct usb_endpoint_descriptor fs_ep_in_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = USB_DIR_IN, + .bmAttributes = USB_ENDPOINT_XFER_BULK +}; + +static struct usb_endpoint_descriptor fs_ep_out_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = USB_DIR_OUT, + .bmAttributes = USB_ENDPOINT_XFER_BULK +}; + +static struct usb_descriptor_header *fs_printer_function[] = { + (struct usb_descriptor_header *) &intf_desc, + (struct usb_descriptor_header *) &fs_ep_in_desc, + (struct usb_descriptor_header *) &fs_ep_out_desc, + NULL +}; + +/* + * usb 2.0 devices need to expose both high speed and full speed + * descriptors, unless they only run at full speed. + */ + +static struct usb_endpoint_descriptor hs_ep_in_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = cpu_to_le16(512) +}; + +static struct usb_endpoint_descriptor hs_ep_out_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = cpu_to_le16(512) +}; + +static struct usb_qualifier_descriptor dev_qualifier = { + .bLength = sizeof(dev_qualifier), + .bDescriptorType = USB_DT_DEVICE_QUALIFIER, + .bcdUSB = cpu_to_le16(0x0200), + .bDeviceClass = USB_CLASS_PRINTER, + .bNumConfigurations = 1 +}; + +static struct usb_descriptor_header *hs_printer_function[] = { + (struct usb_descriptor_header *) &intf_desc, + (struct usb_descriptor_header *) &hs_ep_in_desc, + (struct usb_descriptor_header *) &hs_ep_out_desc, + NULL +}; + +/* + * Added endpoint descriptors for 3.0 devices + */ + +static struct usb_endpoint_descriptor ss_ep_in_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = cpu_to_le16(1024), +}; + +static struct usb_ss_ep_comp_descriptor ss_ep_in_comp_desc = { + .bLength = sizeof(ss_ep_in_comp_desc), + .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, +}; + +static struct usb_endpoint_descriptor ss_ep_out_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = cpu_to_le16(1024), +}; + +static struct usb_ss_ep_comp_descriptor ss_ep_out_comp_desc = { + .bLength = sizeof(ss_ep_out_comp_desc), + .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, +}; + +static struct usb_descriptor_header *ss_printer_function[] = { + (struct usb_descriptor_header *) &intf_desc, + (struct usb_descriptor_header *) &ss_ep_in_desc, + (struct usb_descriptor_header *) &ss_ep_in_comp_desc, + (struct usb_descriptor_header *) &ss_ep_out_desc, + (struct usb_descriptor_header *) &ss_ep_out_comp_desc, + NULL +}; + +/* maxpacket and other transfer characteristics vary by speed. */ +static inline struct usb_endpoint_descriptor *ep_desc(struct usb_gadget *gadget, + struct usb_endpoint_descriptor *fs, + struct usb_endpoint_descriptor *hs, + struct usb_endpoint_descriptor *ss) +{ + switch (gadget->speed) { + case USB_SPEED_SUPER: + return ss; + case USB_SPEED_HIGH: + return hs; + default: + return fs; + } +} + +/*-------------------------------------------------------------------------*/ + +static struct usb_request * +printer_req_alloc(struct usb_ep *ep, unsigned len, gfp_t gfp_flags) +{ + struct usb_request *req; + + req = usb_ep_alloc_request(ep, gfp_flags); + + if (req != NULL) { + req->length = len; + req->buf = kmalloc(len, gfp_flags); + if (req->buf == NULL) { + usb_ep_free_request(ep, req); + return NULL; + } + } + + return req; +} + +static void +printer_req_free(struct usb_ep *ep, struct usb_request *req) +{ + if (ep != NULL && req != NULL) { + kfree(req->buf); + usb_ep_free_request(ep, req); + } +} + +/*-------------------------------------------------------------------------*/ + +static void rx_complete(struct usb_ep *ep, struct usb_request *req) +{ + struct printer_dev *dev = ep->driver_data; + int status = req->status; + unsigned long flags; + + spin_lock_irqsave(&dev->lock, flags); + + list_del_init(&req->list); /* Remode from Active List */ + + switch (status) { + + /* normal completion */ + case 0: + if (req->actual > 0) { + list_add_tail(&req->list, &dev->rx_buffers); + DBG(dev, "G_Printer : rx length %d\n", req->actual); + } else { + list_add(&req->list, &dev->rx_reqs); + } + break; + + /* software-driven interface shutdown */ + case -ECONNRESET: /* unlink */ + case -ESHUTDOWN: /* disconnect etc */ + VDBG(dev, "rx shutdown, code %d\n", status); + list_add(&req->list, &dev->rx_reqs); + break; + + /* for hardware automagic (such as pxa) */ + case -ECONNABORTED: /* endpoint reset */ + DBG(dev, "rx %s reset\n", ep->name); + list_add(&req->list, &dev->rx_reqs); + break; + + /* data overrun */ + case -EOVERFLOW: + /* FALLTHROUGH */ + + default: + DBG(dev, "rx status %d\n", status); + list_add(&req->list, &dev->rx_reqs); + break; + } + + wake_up_interruptible(&dev->rx_wait); + spin_unlock_irqrestore(&dev->lock, flags); +} + +static void tx_complete(struct usb_ep *ep, struct usb_request *req) +{ + struct printer_dev *dev = ep->driver_data; + + switch (req->status) { + default: + VDBG(dev, "tx err %d\n", req->status); + /* FALLTHROUGH */ + case -ECONNRESET: /* unlink */ + case -ESHUTDOWN: /* disconnect etc */ + break; + case 0: + break; + } + + spin_lock(&dev->lock); + /* Take the request struct off the active list and put it on the + * free list. + */ + list_del_init(&req->list); + list_add(&req->list, &dev->tx_reqs); + wake_up_interruptible(&dev->tx_wait); + if (likely(list_empty(&dev->tx_reqs_active))) + wake_up_interruptible(&dev->tx_flush_wait); + + spin_unlock(&dev->lock); +} + +/*-------------------------------------------------------------------------*/ + +static int +printer_open(struct inode *inode, struct file *fd) +{ + struct printer_dev *dev; + unsigned long flags; + int ret = -EBUSY; + + dev = container_of(inode->i_cdev, struct printer_dev, printer_cdev); + + spin_lock_irqsave(&dev->lock, flags); + + if (!dev->printer_cdev_open) { + dev->printer_cdev_open = 1; + fd->private_data = dev; + ret = 0; + /* Change the printer status to show that it's on-line. */ + dev->printer_status |= PRINTER_SELECTED; + } + + spin_unlock_irqrestore(&dev->lock, flags); + + DBG(dev, "printer_open returned %x\n", ret); + return ret; +} + +static int +printer_close(struct inode *inode, struct file *fd) +{ + struct printer_dev *dev = fd->private_data; + unsigned long flags; + + spin_lock_irqsave(&dev->lock, flags); + dev->printer_cdev_open = 0; + fd->private_data = NULL; + /* Change printer status to show that the printer is off-line. */ + dev->printer_status &= ~PRINTER_SELECTED; + spin_unlock_irqrestore(&dev->lock, flags); + + DBG(dev, "printer_close\n"); + + return 0; +} + +/* This function must be called with interrupts turned off. */ +static void +setup_rx_reqs(struct printer_dev *dev) +{ + struct usb_request *req; + + while (likely(!list_empty(&dev->rx_reqs))) { + int error; + + req = container_of(dev->rx_reqs.next, + struct usb_request, list); + list_del_init(&req->list); + + /* The USB Host sends us whatever amount of data it wants to + * so we always set the length field to the full USB_BUFSIZE. + * If the amount of data is more than the read() caller asked + * for it will be stored in the request buffer until it is + * asked for by read(). + */ + req->length = USB_BUFSIZE; + req->complete = rx_complete; + + /* here, we unlock, and only unlock, to avoid deadlock. */ + spin_unlock(&dev->lock); + error = usb_ep_queue(dev->out_ep, req, GFP_ATOMIC); + spin_lock(&dev->lock); + if (error) { + DBG(dev, "rx submit --> %d\n", error); + list_add(&req->list, &dev->rx_reqs); + break; + } + /* if the req is empty, then add it into dev->rx_reqs_active. */ + else if (list_empty(&req->list)) + list_add(&req->list, &dev->rx_reqs_active); + } +} + +static ssize_t +printer_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr) +{ + struct printer_dev *dev = fd->private_data; + unsigned long flags; + size_t size; + size_t bytes_copied; + struct usb_request *req; + /* This is a pointer to the current USB rx request. */ + struct usb_request *current_rx_req; + /* This is the number of bytes in the current rx buffer. */ + size_t current_rx_bytes; + /* This is a pointer to the current rx buffer. */ + u8 *current_rx_buf; + + if (len == 0) + return -EINVAL; + + DBG(dev, "printer_read trying to read %d bytes\n", (int)len); + + mutex_lock(&dev->lock_printer_io); + spin_lock_irqsave(&dev->lock, flags); + + /* We will use this flag later to check if a printer reset happened + * after we turn interrupts back on. + */ + dev->reset_printer = 0; + + setup_rx_reqs(dev); + + bytes_copied = 0; + current_rx_req = dev->current_rx_req; + current_rx_bytes = dev->current_rx_bytes; + current_rx_buf = dev->current_rx_buf; + dev->current_rx_req = NULL; + dev->current_rx_bytes = 0; + dev->current_rx_buf = NULL; + + /* Check if there is any data in the read buffers. Please note that + * current_rx_bytes is the number of bytes in the current rx buffer. + * If it is zero then check if there are any other rx_buffers that + * are on the completed list. We are only out of data if all rx + * buffers are empty. + */ + if ((current_rx_bytes == 0) && + (likely(list_empty(&dev->rx_buffers)))) { + /* Turn interrupts back on before sleeping. */ + spin_unlock_irqrestore(&dev->lock, flags); + + /* + * If no data is available check if this is a NON-Blocking + * call or not. + */ + if (fd->f_flags & (O_NONBLOCK|O_NDELAY)) { + mutex_unlock(&dev->lock_printer_io); + return -EAGAIN; + } + + /* Sleep until data is available */ + wait_event_interruptible(dev->rx_wait, + (likely(!list_empty(&dev->rx_buffers)))); + spin_lock_irqsave(&dev->lock, flags); + } + + /* We have data to return then copy it to the caller's buffer.*/ + while ((current_rx_bytes || likely(!list_empty(&dev->rx_buffers))) + && len) { + if (current_rx_bytes == 0) { + req = container_of(dev->rx_buffers.next, + struct usb_request, list); + list_del_init(&req->list); + + if (req->actual && req->buf) { + current_rx_req = req; + current_rx_bytes = req->actual; + current_rx_buf = req->buf; + } else { + list_add(&req->list, &dev->rx_reqs); + continue; + } + } + + /* Don't leave irqs off while doing memory copies */ + spin_unlock_irqrestore(&dev->lock, flags); + + if (len > current_rx_bytes) + size = current_rx_bytes; + else + size = len; + + size -= copy_to_user(buf, current_rx_buf, size); + bytes_copied += size; + len -= size; + buf += size; + + spin_lock_irqsave(&dev->lock, flags); + + /* We've disconnected or reset so return. */ + if (dev->reset_printer) { + list_add(¤t_rx_req->list, &dev->rx_reqs); + spin_unlock_irqrestore(&dev->lock, flags); + mutex_unlock(&dev->lock_printer_io); + return -EAGAIN; + } + + /* If we not returning all the data left in this RX request + * buffer then adjust the amount of data left in the buffer. + * Othewise if we are done with this RX request buffer then + * requeue it to get any incoming data from the USB host. + */ + if (size < current_rx_bytes) { + current_rx_bytes -= size; + current_rx_buf += size; + } else { + list_add(¤t_rx_req->list, &dev->rx_reqs); + current_rx_bytes = 0; + current_rx_buf = NULL; + current_rx_req = NULL; + } + } + + dev->current_rx_req = current_rx_req; + dev->current_rx_bytes = current_rx_bytes; + dev->current_rx_buf = current_rx_buf; + + spin_unlock_irqrestore(&dev->lock, flags); + mutex_unlock(&dev->lock_printer_io); + + DBG(dev, "printer_read returned %d bytes\n", (int)bytes_copied); + + if (bytes_copied) + return bytes_copied; + else + return -EAGAIN; +} + +static ssize_t +printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr) +{ + struct printer_dev *dev = fd->private_data; + unsigned long flags; + size_t size; /* Amount of data in a TX request. */ + size_t bytes_copied = 0; + struct usb_request *req; + + DBG(dev, "printer_write trying to send %d bytes\n", (int)len); + + if (len == 0) + return -EINVAL; + + mutex_lock(&dev->lock_printer_io); + spin_lock_irqsave(&dev->lock, flags); + + /* Check if a printer reset happens while we have interrupts on */ + dev->reset_printer = 0; + + /* Check if there is any available write buffers */ + if (likely(list_empty(&dev->tx_reqs))) { + /* Turn interrupts back on before sleeping. */ + spin_unlock_irqrestore(&dev->lock, flags); + + /* + * If write buffers are available check if this is + * a NON-Blocking call or not. + */ + if (fd->f_flags & (O_NONBLOCK|O_NDELAY)) { + mutex_unlock(&dev->lock_printer_io); + return -EAGAIN; + } + + /* Sleep until a write buffer is available */ + wait_event_interruptible(dev->tx_wait, + (likely(!list_empty(&dev->tx_reqs)))); + spin_lock_irqsave(&dev->lock, flags); + } + + while (likely(!list_empty(&dev->tx_reqs)) && len) { + + if (len > USB_BUFSIZE) + size = USB_BUFSIZE; + else + size = len; + + req = container_of(dev->tx_reqs.next, struct usb_request, + list); + list_del_init(&req->list); + + req->complete = tx_complete; + req->length = size; + + /* Check if we need to send a zero length packet. */ + if (len > size) + /* They will be more TX requests so no yet. */ + req->zero = 0; + else + /* If the data amount is not a multiple of the + * maxpacket size then send a zero length packet. + */ + req->zero = ((len % dev->in_ep->maxpacket) == 0); + + /* Don't leave irqs off while doing memory copies */ + spin_unlock_irqrestore(&dev->lock, flags); + + if (copy_from_user(req->buf, buf, size)) { + list_add(&req->list, &dev->tx_reqs); + mutex_unlock(&dev->lock_printer_io); + return bytes_copied; + } + + bytes_copied += size; + len -= size; + buf += size; + + spin_lock_irqsave(&dev->lock, flags); + + /* We've disconnected or reset so free the req and buffer */ + if (dev->reset_printer) { + list_add(&req->list, &dev->tx_reqs); + spin_unlock_irqrestore(&dev->lock, flags); + mutex_unlock(&dev->lock_printer_io); + return -EAGAIN; + } + + if (usb_ep_queue(dev->in_ep, req, GFP_ATOMIC)) { + list_add(&req->list, &dev->tx_reqs); + spin_unlock_irqrestore(&dev->lock, flags); + mutex_unlock(&dev->lock_printer_io); + return -EAGAIN; + } + + list_add(&req->list, &dev->tx_reqs_active); + + } + + spin_unlock_irqrestore(&dev->lock, flags); + mutex_unlock(&dev->lock_printer_io); + + DBG(dev, "printer_write sent %d bytes\n", (int)bytes_copied); + + if (bytes_copied) + return bytes_copied; + else + return -EAGAIN; +} + +static int +printer_fsync(struct file *fd, loff_t start, loff_t end, int datasync) +{ + struct printer_dev *dev = fd->private_data; + struct inode *inode = file_inode(fd); + unsigned long flags; + int tx_list_empty; + + mutex_lock(&inode->i_mutex); + spin_lock_irqsave(&dev->lock, flags); + tx_list_empty = (likely(list_empty(&dev->tx_reqs))); + spin_unlock_irqrestore(&dev->lock, flags); + + if (!tx_list_empty) { + /* Sleep until all data has been sent */ + wait_event_interruptible(dev->tx_flush_wait, + (likely(list_empty(&dev->tx_reqs_active)))); + } + mutex_unlock(&inode->i_mutex); + + return 0; +} + +static unsigned int +printer_poll(struct file *fd, poll_table *wait) +{ + struct printer_dev *dev = fd->private_data; + unsigned long flags; + int status = 0; + + mutex_lock(&dev->lock_printer_io); + spin_lock_irqsave(&dev->lock, flags); + setup_rx_reqs(dev); + spin_unlock_irqrestore(&dev->lock, flags); + mutex_unlock(&dev->lock_printer_io); + + poll_wait(fd, &dev->rx_wait, wait); + poll_wait(fd, &dev->tx_wait, wait); + + spin_lock_irqsave(&dev->lock, flags); + if (likely(!list_empty(&dev->tx_reqs))) + status |= POLLOUT | POLLWRNORM; + + if (likely(dev->current_rx_bytes) || + likely(!list_empty(&dev->rx_buffers))) + status |= POLLIN | POLLRDNORM; + + spin_unlock_irqrestore(&dev->lock, flags); + + return status; +} + +static long +printer_ioctl(struct file *fd, unsigned int code, unsigned long arg) +{ + struct printer_dev *dev = fd->private_data; + unsigned long flags; + int status = 0; + + DBG(dev, "printer_ioctl: cmd=0x%4.4x, arg=%lu\n", code, arg); + + /* handle ioctls */ + + spin_lock_irqsave(&dev->lock, flags); + + switch (code) { + case GADGET_GET_PRINTER_STATUS: + status = (int)dev->printer_status; + break; + case GADGET_SET_PRINTER_STATUS: + dev->printer_status = (u8)arg; + break; + default: + /* could not handle ioctl */ + DBG(dev, "printer_ioctl: ERROR cmd=0x%4.4xis not supported\n", + code); + status = -ENOTTY; + } + + spin_unlock_irqrestore(&dev->lock, flags); + + return status; +} + +/* used after endpoint configuration */ +static const struct file_operations printer_io_operations = { + .owner = THIS_MODULE, + .open = printer_open, + .read = printer_read, + .write = printer_write, + .fsync = printer_fsync, + .poll = printer_poll, + .unlocked_ioctl = printer_ioctl, + .release = printer_close, + .llseek = noop_llseek, +}; + +/*-------------------------------------------------------------------------*/ + +static int +set_printer_interface(struct printer_dev *dev) +{ + int result = 0; + + dev->in_ep->desc = ep_desc(dev->gadget, &fs_ep_in_desc, &hs_ep_in_desc, + &ss_ep_in_desc); + dev->in_ep->driver_data = dev; + + dev->out_ep->desc = ep_desc(dev->gadget, &fs_ep_out_desc, + &hs_ep_out_desc, &ss_ep_out_desc); + dev->out_ep->driver_data = dev; + + result = usb_ep_enable(dev->in_ep); + if (result != 0) { + DBG(dev, "enable %s --> %d\n", dev->in_ep->name, result); + goto done; + } + + result = usb_ep_enable(dev->out_ep); + if (result != 0) { + DBG(dev, "enable %s --> %d\n", dev->in_ep->name, result); + goto done; + } + +done: + /* on error, disable any endpoints */ + if (result != 0) { + (void) usb_ep_disable(dev->in_ep); + (void) usb_ep_disable(dev->out_ep); + dev->in_ep->desc = NULL; + dev->out_ep->desc = NULL; + } + + /* caller is responsible for cleanup on error */ + return result; +} + +static void printer_reset_interface(struct printer_dev *dev) +{ + if (dev->interface < 0) + return; + + DBG(dev, "%s\n", __func__); + + if (dev->in_ep->desc) + usb_ep_disable(dev->in_ep); + + if (dev->out_ep->desc) + usb_ep_disable(dev->out_ep); + + dev->in_ep->desc = NULL; + dev->out_ep->desc = NULL; + dev->interface = -1; +} + +/* Change our operational Interface. */ +static int set_interface(struct printer_dev *dev, unsigned number) +{ + int result = 0; + + /* Free the current interface */ + printer_reset_interface(dev); + + result = set_printer_interface(dev); + if (result) + printer_reset_interface(dev); + else + dev->interface = number; + + if (!result) + INFO(dev, "Using interface %x\n", number); + + return result; +} + +static void printer_soft_reset(struct printer_dev *dev) +{ + struct usb_request *req; + + INFO(dev, "Received Printer Reset Request\n"); + + if (usb_ep_disable(dev->in_ep)) + DBG(dev, "Failed to disable USB in_ep\n"); + if (usb_ep_disable(dev->out_ep)) + DBG(dev, "Failed to disable USB out_ep\n"); + + if (dev->current_rx_req != NULL) { + list_add(&dev->current_rx_req->list, &dev->rx_reqs); + dev->current_rx_req = NULL; + } + dev->current_rx_bytes = 0; + dev->current_rx_buf = NULL; + dev->reset_printer = 1; + + while (likely(!(list_empty(&dev->rx_buffers)))) { + req = container_of(dev->rx_buffers.next, struct usb_request, + list); + list_del_init(&req->list); + list_add(&req->list, &dev->rx_reqs); + } + + while (likely(!(list_empty(&dev->rx_reqs_active)))) { + req = container_of(dev->rx_buffers.next, struct usb_request, + list); + list_del_init(&req->list); + list_add(&req->list, &dev->rx_reqs); + } + + while (likely(!(list_empty(&dev->tx_reqs_active)))) { + req = container_of(dev->tx_reqs_active.next, + struct usb_request, list); + list_del_init(&req->list); + list_add(&req->list, &dev->tx_reqs); + } + + if (usb_ep_enable(dev->in_ep)) + DBG(dev, "Failed to enable USB in_ep\n"); + if (usb_ep_enable(dev->out_ep)) + DBG(dev, "Failed to enable USB out_ep\n"); + + wake_up_interruptible(&dev->rx_wait); + wake_up_interruptible(&dev->tx_wait); + wake_up_interruptible(&dev->tx_flush_wait); +} + +/*-------------------------------------------------------------------------*/ + +static bool gprinter_req_match(struct usb_function *f, + const struct usb_ctrlrequest *ctrl) +{ + struct printer_dev *dev = func_to_printer(f); + u16 w_index = le16_to_cpu(ctrl->wIndex); + u16 w_value = le16_to_cpu(ctrl->wValue); + u16 w_length = le16_to_cpu(ctrl->wLength); + + if ((ctrl->bRequestType & USB_RECIP_MASK) != USB_RECIP_INTERFACE || + (ctrl->bRequestType & USB_TYPE_MASK) != USB_TYPE_CLASS) + return false; + + switch (ctrl->bRequest) { + case GET_DEVICE_ID: + w_index >>= 8; + if (w_length <= PNP_STRING_LEN && + (USB_DIR_IN & ctrl->bRequestType)) + break; + return false; + case GET_PORT_STATUS: + if (!w_value && w_length == 1 && + (USB_DIR_IN & ctrl->bRequestType)) + break; + return false; + case SOFT_RESET: + if (!w_value && !w_length && + (USB_DIR_OUT & ctrl->bRequestType)) + break; + /* fall through */ + default: + return false; + } + return w_index == dev->interface; +} + +/* + * The setup() callback implements all the ep0 functionality that's not + * handled lower down. + */ +static int printer_func_setup(struct usb_function *f, + const struct usb_ctrlrequest *ctrl) +{ + struct printer_dev *dev = func_to_printer(f); + struct usb_composite_dev *cdev = f->config->cdev; + struct usb_request *req = cdev->req; + int value = -EOPNOTSUPP; + u16 wIndex = le16_to_cpu(ctrl->wIndex); + u16 wValue = le16_to_cpu(ctrl->wValue); + u16 wLength = le16_to_cpu(ctrl->wLength); + + DBG(dev, "ctrl req%02x.%02x v%04x i%04x l%d\n", + ctrl->bRequestType, ctrl->bRequest, wValue, wIndex, wLength); + + switch (ctrl->bRequestType&USB_TYPE_MASK) { + case USB_TYPE_CLASS: + switch (ctrl->bRequest) { + case GET_DEVICE_ID: /* Get the IEEE-1284 PNP String */ + /* Only one printer interface is supported. */ + if ((wIndex>>8) != dev->interface) + break; + + value = (dev->pnp_string[0] << 8) | dev->pnp_string[1]; + memcpy(req->buf, dev->pnp_string, value); + DBG(dev, "1284 PNP String: %x %s\n", value, + &dev->pnp_string[2]); + break; + + case GET_PORT_STATUS: /* Get Port Status */ + /* Only one printer interface is supported. */ + if (wIndex != dev->interface) + break; + + *(u8 *)req->buf = dev->printer_status; + value = min_t(u16, wLength, 1); + break; + + case SOFT_RESET: /* Soft Reset */ + /* Only one printer interface is supported. */ + if (wIndex != dev->interface) + break; + + printer_soft_reset(dev); + + value = 0; + break; + + default: + goto unknown; + } + break; + + default: +unknown: + VDBG(dev, + "unknown ctrl req%02x.%02x v%04x i%04x l%d\n", + ctrl->bRequestType, ctrl->bRequest, + wValue, wIndex, wLength); + break; + } + /* host either stalls (value < 0) or reports success */ + if (value >= 0) { + req->length = value; + req->zero = value < wLength; + value = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC); + if (value < 0) { + ERROR(dev, "%s:%d Error!\n", __func__, __LINE__); + req->status = 0; + } + } + return value; +} + +static int __init printer_func_bind(struct usb_configuration *c, + struct usb_function *f) +{ + struct usb_gadget *gadget = c->cdev->gadget; + struct printer_dev *dev = func_to_printer(f); + struct device *pdev; + struct usb_composite_dev *cdev = c->cdev; + struct usb_ep *in_ep; + struct usb_ep *out_ep = NULL; + struct usb_request *req; + dev_t devt; + int id; + int ret; + u32 i; + + id = usb_interface_id(c, f); + if (id < 0) + return id; + intf_desc.bInterfaceNumber = id; + + /* finish hookup to lower layer ... */ + dev->gadget = gadget; + + /* all we really need is bulk IN/OUT */ + in_ep = usb_ep_autoconfig(cdev->gadget, &fs_ep_in_desc); + if (!in_ep) { +autoconf_fail: + dev_err(&cdev->gadget->dev, "can't autoconfigure on %s\n", + cdev->gadget->name); + return -ENODEV; + } + in_ep->driver_data = in_ep; /* claim */ + + out_ep = usb_ep_autoconfig(cdev->gadget, &fs_ep_out_desc); + if (!out_ep) + goto autoconf_fail; + out_ep->driver_data = out_ep; /* claim */ + + /* assumes that all endpoints are dual-speed */ + hs_ep_in_desc.bEndpointAddress = fs_ep_in_desc.bEndpointAddress; + hs_ep_out_desc.bEndpointAddress = fs_ep_out_desc.bEndpointAddress; + ss_ep_in_desc.bEndpointAddress = fs_ep_in_desc.bEndpointAddress; + ss_ep_out_desc.bEndpointAddress = fs_ep_out_desc.bEndpointAddress; + + ret = usb_assign_descriptors(f, fs_printer_function, + hs_printer_function, ss_printer_function); + if (ret) + return ret; + + dev->in_ep = in_ep; + dev->out_ep = out_ep; + + ret = -ENOMEM; + for (i = 0; i < dev->q_len; i++) { + req = printer_req_alloc(dev->in_ep, USB_BUFSIZE, GFP_KERNEL); + if (!req) + goto fail_tx_reqs; + list_add(&req->list, &dev->tx_reqs); + } + + for (i = 0; i < dev->q_len; i++) { + req = printer_req_alloc(dev->out_ep, USB_BUFSIZE, GFP_KERNEL); + if (!req) + goto fail_rx_reqs; + list_add(&req->list, &dev->rx_reqs); + } + + /* Setup the sysfs files for the printer gadget. */ + devt = MKDEV(major, dev->minor); + pdev = device_create(usb_gadget_class, NULL, devt, + NULL, "g_printer%d", dev->minor); + if (IS_ERR(pdev)) { + ERROR(dev, "Failed to create device: g_printer\n"); + ret = PTR_ERR(pdev); + goto fail_rx_reqs; + } + + /* + * Register a character device as an interface to a user mode + * program that handles the printer specific functionality. + */ + cdev_init(&dev->printer_cdev, &printer_io_operations); + dev->printer_cdev.owner = THIS_MODULE; + ret = cdev_add(&dev->printer_cdev, devt, 1); + if (ret) { + ERROR(dev, "Failed to open char device\n"); + goto fail_cdev_add; + } + + return 0; + +fail_cdev_add: + device_destroy(usb_gadget_class, devt); + +fail_rx_reqs: + while (!list_empty(&dev->rx_reqs)) { + req = container_of(dev->rx_reqs.next, struct usb_request, list); + list_del(&req->list); + printer_req_free(dev->out_ep, req); + } + +fail_tx_reqs: + while (!list_empty(&dev->tx_reqs)) { + req = container_of(dev->tx_reqs.next, struct usb_request, list); + list_del(&req->list); + printer_req_free(dev->in_ep, req); + } + + return ret; + +} + +static void printer_func_unbind(struct usb_configuration *c, + struct usb_function *f) +{ + struct printer_dev *dev; + struct usb_request *req; + + dev = func_to_printer(f); + + device_destroy(usb_gadget_class, MKDEV(major, dev->minor)); + + /* Remove Character Device */ + cdev_del(&dev->printer_cdev); + + /* we must already have been disconnected ... no i/o may be active */ + WARN_ON(!list_empty(&dev->tx_reqs_active)); + WARN_ON(!list_empty(&dev->rx_reqs_active)); + + /* Free all memory for this driver. */ + while (!list_empty(&dev->tx_reqs)) { + req = container_of(dev->tx_reqs.next, struct usb_request, + list); + list_del(&req->list); + printer_req_free(dev->in_ep, req); + } + + if (dev->current_rx_req != NULL) + printer_req_free(dev->out_ep, dev->current_rx_req); + + while (!list_empty(&dev->rx_reqs)) { + req = container_of(dev->rx_reqs.next, + struct usb_request, list); + list_del(&req->list); + printer_req_free(dev->out_ep, req); + } + + while (!list_empty(&dev->rx_buffers)) { + req = container_of(dev->rx_buffers.next, + struct usb_request, list); + list_del(&req->list); + printer_req_free(dev->out_ep, req); + } + usb_free_all_descriptors(f); + kfree(dev); +} + +static int printer_func_set_alt(struct usb_function *f, + unsigned intf, unsigned alt) +{ + struct printer_dev *dev = func_to_printer(f); + int ret = -ENOTSUPP; + + if (!alt) + ret = set_interface(dev, intf); + + return ret; +} + +static void printer_func_disable(struct usb_function *f) +{ + struct printer_dev *dev = func_to_printer(f); + unsigned long flags; + + DBG(dev, "%s\n", __func__); + + spin_lock_irqsave(&dev->lock, flags); + printer_reset_interface(dev); + spin_unlock_irqrestore(&dev->lock, flags); +} + +static int f_printer_bind_config(struct usb_configuration *c, char *pnp_str, + char *pnp_string, unsigned q_len, int minor) +{ + struct printer_dev *dev; + int status = -ENOMEM; + size_t len; + + if (minor >= minors) + return -ENOENT; + + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) + return -ENOMEM; + + dev->pnp_string = pnp_string; + dev->minor = minor; + + dev->function.name = shortname; + dev->function.bind = printer_func_bind; + dev->function.setup = printer_func_setup; + dev->function.unbind = printer_func_unbind; + dev->function.set_alt = printer_func_set_alt; + dev->function.disable = printer_func_disable; + dev->function.req_match = gprinter_req_match; + INIT_LIST_HEAD(&dev->tx_reqs); + INIT_LIST_HEAD(&dev->rx_reqs); + INIT_LIST_HEAD(&dev->rx_buffers); + + if (pnp_str) + strlcpy(&dev->pnp_string[2], pnp_str, PNP_STRING_LEN - 2); + + len = strlen(pnp_string); + pnp_string[0] = (len >> 8) & 0xFF; + pnp_string[1] = len & 0xFF; + + spin_lock_init(&dev->lock); + mutex_init(&dev->lock_printer_io); + INIT_LIST_HEAD(&dev->tx_reqs_active); + INIT_LIST_HEAD(&dev->rx_reqs_active); + init_waitqueue_head(&dev->rx_wait); + init_waitqueue_head(&dev->tx_wait); + init_waitqueue_head(&dev->tx_flush_wait); + + dev->interface = -1; + dev->printer_cdev_open = 0; + dev->printer_status = PRINTER_NOT_ERROR; + dev->current_rx_req = NULL; + dev->current_rx_bytes = 0; + dev->current_rx_buf = NULL; + dev->q_len = q_len; + + status = usb_add_function(c, &dev->function); + if (status) { + kfree(dev); + return status; + } + + INFO(dev, "%s, version: " DRIVER_VERSION "\n", driver_desc); + return 0; +} + +static int gprinter_setup(int count) +{ + int status; + dev_t devt; + + usb_gadget_class = class_create(THIS_MODULE, "usb_printer_gadget"); + if (IS_ERR(usb_gadget_class)) { + status = PTR_ERR(usb_gadget_class); + usb_gadget_class = NULL; + pr_err("unable to create usb_gadget class %d\n", status); + return status; + } + + status = alloc_chrdev_region(&devt, 0, count, "USB printer gadget"); + if (status) { + pr_err("alloc_chrdev_region %d\n", status); + class_destroy(usb_gadget_class); + usb_gadget_class = NULL; + return status; + } + + major = MAJOR(devt); + minors = count; + + return status; +} + +static void gprinter_cleanup(void) +{ + if (major) { + unregister_chrdev_region(MKDEV(major, 0), minors); + major = minors = 0; + } + class_destroy(usb_gadget_class); + usb_gadget_class = NULL; +} diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index d1f85f81975f..4d926d08df02 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -12,29 +12,7 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - #include -#include -#include -#include -#include #include #include @@ -46,58 +24,16 @@ USB_GADGET_COMPOSITE_OPTIONS(); #define DRIVER_DESC "Printer Gadget" -#define DRIVER_VERSION "2007 OCT 06" -#define GET_DEVICE_ID 0 -#define GET_PORT_STATUS 1 -#define SOFT_RESET 2 - -#define PRINTER_MINORS 4 +#define DRIVER_VERSION "2015 FEB 17" static const char shortname [] = "printer"; static const char driver_desc [] = DRIVER_DESC; -static int major, minors; -static struct class *usb_gadget_class; - -/*-------------------------------------------------------------------------*/ - -struct printer_dev { - spinlock_t lock; /* lock this structure */ - /* lock buffer lists during read/write calls */ - struct mutex lock_printer_io; - struct usb_gadget *gadget; - s8 interface; - struct usb_ep *in_ep, *out_ep; - - struct list_head rx_reqs; /* List of free RX structs */ - struct list_head rx_reqs_active; /* List of Active RX xfers */ - struct list_head rx_buffers; /* List of completed xfers */ - /* wait until there is data to be read. */ - wait_queue_head_t rx_wait; - struct list_head tx_reqs; /* List of free TX structs */ - struct list_head tx_reqs_active; /* List of Active TX xfers */ - /* Wait until there are write buffers available to use. */ - wait_queue_head_t tx_wait; - /* Wait until all write buffers have been sent. */ - wait_queue_head_t tx_flush_wait; - struct usb_request *current_rx_req; - size_t current_rx_bytes; - u8 *current_rx_buf; - u8 printer_status; - u8 reset_printer; - int minor; - struct cdev printer_cdev; - u8 printer_cdev_open; - wait_queue_head_t wait; - unsigned q_len; - char *pnp_string; /* We don't own memory! */ - struct usb_function function; -}; - -static inline struct printer_dev *func_to_printer(struct usb_function *f) -{ - return container_of(f, struct printer_dev, function); -} +/* + * This will be changed when f_printer is converted + * to the new function interface. + */ +#include "f_printer.c" /*-------------------------------------------------------------------------*/ @@ -135,10 +71,6 @@ module_param(qlen, uint, S_IRUGO|S_IWUSR); * descriptors are built on demand. */ -/* holds our biggest descriptor */ -#define USB_DESC_BUFSIZE 256 -#define USB_BUFSIZE 8192 - static struct usb_device_descriptor device_desc = { .bLength = sizeof device_desc, .bDescriptorType = USB_DT_DEVICE, @@ -151,108 +83,6 @@ static struct usb_device_descriptor device_desc = { .bNumConfigurations = 1 }; -static struct usb_interface_descriptor intf_desc = { - .bLength = sizeof intf_desc, - .bDescriptorType = USB_DT_INTERFACE, - .bNumEndpoints = 2, - .bInterfaceClass = USB_CLASS_PRINTER, - .bInterfaceSubClass = 1, /* Printer Sub-Class */ - .bInterfaceProtocol = 2, /* Bi-Directional */ - .iInterface = 0 -}; - -static struct usb_endpoint_descriptor fs_ep_in_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_BULK -}; - -static struct usb_endpoint_descriptor fs_ep_out_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_OUT, - .bmAttributes = USB_ENDPOINT_XFER_BULK -}; - -static struct usb_descriptor_header *fs_printer_function[] = { - (struct usb_descriptor_header *) &intf_desc, - (struct usb_descriptor_header *) &fs_ep_in_desc, - (struct usb_descriptor_header *) &fs_ep_out_desc, - NULL -}; - -/* - * usb 2.0 devices need to expose both high speed and full speed - * descriptors, unless they only run at full speed. - */ - -static struct usb_endpoint_descriptor hs_ep_in_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = cpu_to_le16(512) -}; - -static struct usb_endpoint_descriptor hs_ep_out_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = cpu_to_le16(512) -}; - -static struct usb_qualifier_descriptor dev_qualifier = { - .bLength = sizeof dev_qualifier, - .bDescriptorType = USB_DT_DEVICE_QUALIFIER, - .bcdUSB = cpu_to_le16(0x0200), - .bDeviceClass = USB_CLASS_PRINTER, - .bNumConfigurations = 1 -}; - -static struct usb_descriptor_header *hs_printer_function[] = { - (struct usb_descriptor_header *) &intf_desc, - (struct usb_descriptor_header *) &hs_ep_in_desc, - (struct usb_descriptor_header *) &hs_ep_out_desc, - NULL -}; - -/* - * Added endpoint descriptors for 3.0 devices - */ - -static struct usb_endpoint_descriptor ss_ep_in_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = cpu_to_le16(1024), -}; - -static struct usb_ss_ep_comp_descriptor ss_ep_in_comp_desc = { - .bLength = sizeof(ss_ep_in_comp_desc), - .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, -}; - -static struct usb_endpoint_descriptor ss_ep_out_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = cpu_to_le16(1024), -}; - -static struct usb_ss_ep_comp_descriptor ss_ep_out_comp_desc = { - .bLength = sizeof(ss_ep_out_comp_desc), - .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, -}; - -static struct usb_descriptor_header *ss_printer_function[] = { - (struct usb_descriptor_header *) &intf_desc, - (struct usb_descriptor_header *) &ss_ep_in_desc, - (struct usb_descriptor_header *) &ss_ep_in_comp_desc, - (struct usb_descriptor_header *) &ss_ep_out_desc, - (struct usb_descriptor_header *) &ss_ep_out_comp_desc, - NULL -}; - static struct usb_otg_descriptor otg_descriptor = { .bLength = sizeof otg_descriptor, .bDescriptorType = USB_DT_OTG, @@ -264,28 +94,10 @@ static const struct usb_descriptor_header *otg_desc[] = { NULL, }; -/* maxpacket and other transfer characteristics vary by speed. */ -static inline struct usb_endpoint_descriptor *ep_desc(struct usb_gadget *gadget, - struct usb_endpoint_descriptor *fs, - struct usb_endpoint_descriptor *hs, - struct usb_endpoint_descriptor *ss) -{ - switch (gadget->speed) { - case USB_SPEED_SUPER: - return ss; - case USB_SPEED_HIGH: - return hs; - default: - return fs; - } -} - /*-------------------------------------------------------------------------*/ /* descriptors that are built on-demand */ -#define PNP_STRING_LEN 1024 - static char product_desc [40] = DRIVER_DESC; static char serial_num [40] = "1"; static char pnp_string[PNP_STRING_LEN] = @@ -309,1030 +121,12 @@ static struct usb_gadget_strings *dev_strings[] = { NULL, }; -/*-------------------------------------------------------------------------*/ - -static struct usb_request * -printer_req_alloc(struct usb_ep *ep, unsigned len, gfp_t gfp_flags) -{ - struct usb_request *req; - - req = usb_ep_alloc_request(ep, gfp_flags); - - if (req != NULL) { - req->length = len; - req->buf = kmalloc(len, gfp_flags); - if (req->buf == NULL) { - usb_ep_free_request(ep, req); - return NULL; - } - } - - return req; -} - -static void -printer_req_free(struct usb_ep *ep, struct usb_request *req) -{ - if (ep != NULL && req != NULL) { - kfree(req->buf); - usb_ep_free_request(ep, req); - } -} - -/*-------------------------------------------------------------------------*/ - -static void rx_complete(struct usb_ep *ep, struct usb_request *req) -{ - struct printer_dev *dev = ep->driver_data; - int status = req->status; - unsigned long flags; - - spin_lock_irqsave(&dev->lock, flags); - - list_del_init(&req->list); /* Remode from Active List */ - - switch (status) { - - /* normal completion */ - case 0: - if (req->actual > 0) { - list_add_tail(&req->list, &dev->rx_buffers); - DBG(dev, "G_Printer : rx length %d\n", req->actual); - } else { - list_add(&req->list, &dev->rx_reqs); - } - break; - - /* software-driven interface shutdown */ - case -ECONNRESET: /* unlink */ - case -ESHUTDOWN: /* disconnect etc */ - VDBG(dev, "rx shutdown, code %d\n", status); - list_add(&req->list, &dev->rx_reqs); - break; - - /* for hardware automagic (such as pxa) */ - case -ECONNABORTED: /* endpoint reset */ - DBG(dev, "rx %s reset\n", ep->name); - list_add(&req->list, &dev->rx_reqs); - break; - - /* data overrun */ - case -EOVERFLOW: - /* FALLTHROUGH */ - - default: - DBG(dev, "rx status %d\n", status); - list_add(&req->list, &dev->rx_reqs); - break; - } - - wake_up_interruptible(&dev->rx_wait); - spin_unlock_irqrestore(&dev->lock, flags); -} - -static void tx_complete(struct usb_ep *ep, struct usb_request *req) -{ - struct printer_dev *dev = ep->driver_data; - - switch (req->status) { - default: - VDBG(dev, "tx err %d\n", req->status); - /* FALLTHROUGH */ - case -ECONNRESET: /* unlink */ - case -ESHUTDOWN: /* disconnect etc */ - break; - case 0: - break; - } - - spin_lock(&dev->lock); - /* Take the request struct off the active list and put it on the - * free list. - */ - list_del_init(&req->list); - list_add(&req->list, &dev->tx_reqs); - wake_up_interruptible(&dev->tx_wait); - if (likely(list_empty(&dev->tx_reqs_active))) - wake_up_interruptible(&dev->tx_flush_wait); - - spin_unlock(&dev->lock); -} - -/*-------------------------------------------------------------------------*/ - -static int -printer_open(struct inode *inode, struct file *fd) -{ - struct printer_dev *dev; - unsigned long flags; - int ret = -EBUSY; - - dev = container_of(inode->i_cdev, struct printer_dev, printer_cdev); - - spin_lock_irqsave(&dev->lock, flags); - - if (!dev->printer_cdev_open) { - dev->printer_cdev_open = 1; - fd->private_data = dev; - ret = 0; - /* Change the printer status to show that it's on-line. */ - dev->printer_status |= PRINTER_SELECTED; - } - - spin_unlock_irqrestore(&dev->lock, flags); - - DBG(dev, "printer_open returned %x\n", ret); - return ret; -} - -static int -printer_close(struct inode *inode, struct file *fd) -{ - struct printer_dev *dev = fd->private_data; - unsigned long flags; - - spin_lock_irqsave(&dev->lock, flags); - dev->printer_cdev_open = 0; - fd->private_data = NULL; - /* Change printer status to show that the printer is off-line. */ - dev->printer_status &= ~PRINTER_SELECTED; - spin_unlock_irqrestore(&dev->lock, flags); - - DBG(dev, "printer_close\n"); - - return 0; -} - -/* This function must be called with interrupts turned off. */ -static void -setup_rx_reqs(struct printer_dev *dev) -{ - struct usb_request *req; - - while (likely(!list_empty(&dev->rx_reqs))) { - int error; - - req = container_of(dev->rx_reqs.next, - struct usb_request, list); - list_del_init(&req->list); - - /* The USB Host sends us whatever amount of data it wants to - * so we always set the length field to the full USB_BUFSIZE. - * If the amount of data is more than the read() caller asked - * for it will be stored in the request buffer until it is - * asked for by read(). - */ - req->length = USB_BUFSIZE; - req->complete = rx_complete; - - /* here, we unlock, and only unlock, to avoid deadlock. */ - spin_unlock(&dev->lock); - error = usb_ep_queue(dev->out_ep, req, GFP_ATOMIC); - spin_lock(&dev->lock); - if (error) { - DBG(dev, "rx submit --> %d\n", error); - list_add(&req->list, &dev->rx_reqs); - break; - } - /* if the req is empty, then add it into dev->rx_reqs_active. */ - else if (list_empty(&req->list)) { - list_add(&req->list, &dev->rx_reqs_active); - } - } -} - -static ssize_t -printer_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr) -{ - struct printer_dev *dev = fd->private_data; - unsigned long flags; - size_t size; - size_t bytes_copied; - struct usb_request *req; - /* This is a pointer to the current USB rx request. */ - struct usb_request *current_rx_req; - /* This is the number of bytes in the current rx buffer. */ - size_t current_rx_bytes; - /* This is a pointer to the current rx buffer. */ - u8 *current_rx_buf; - - if (len == 0) - return -EINVAL; - - DBG(dev, "printer_read trying to read %d bytes\n", (int)len); - - mutex_lock(&dev->lock_printer_io); - spin_lock_irqsave(&dev->lock, flags); - - /* We will use this flag later to check if a printer reset happened - * after we turn interrupts back on. - */ - dev->reset_printer = 0; - - setup_rx_reqs(dev); - - bytes_copied = 0; - current_rx_req = dev->current_rx_req; - current_rx_bytes = dev->current_rx_bytes; - current_rx_buf = dev->current_rx_buf; - dev->current_rx_req = NULL; - dev->current_rx_bytes = 0; - dev->current_rx_buf = NULL; - - /* Check if there is any data in the read buffers. Please note that - * current_rx_bytes is the number of bytes in the current rx buffer. - * If it is zero then check if there are any other rx_buffers that - * are on the completed list. We are only out of data if all rx - * buffers are empty. - */ - if ((current_rx_bytes == 0) && - (likely(list_empty(&dev->rx_buffers)))) { - /* Turn interrupts back on before sleeping. */ - spin_unlock_irqrestore(&dev->lock, flags); - - /* - * If no data is available check if this is a NON-Blocking - * call or not. - */ - if (fd->f_flags & (O_NONBLOCK|O_NDELAY)) { - mutex_unlock(&dev->lock_printer_io); - return -EAGAIN; - } - - /* Sleep until data is available */ - wait_event_interruptible(dev->rx_wait, - (likely(!list_empty(&dev->rx_buffers)))); - spin_lock_irqsave(&dev->lock, flags); - } - - /* We have data to return then copy it to the caller's buffer.*/ - while ((current_rx_bytes || likely(!list_empty(&dev->rx_buffers))) - && len) { - if (current_rx_bytes == 0) { - req = container_of(dev->rx_buffers.next, - struct usb_request, list); - list_del_init(&req->list); - - if (req->actual && req->buf) { - current_rx_req = req; - current_rx_bytes = req->actual; - current_rx_buf = req->buf; - } else { - list_add(&req->list, &dev->rx_reqs); - continue; - } - } - - /* Don't leave irqs off while doing memory copies */ - spin_unlock_irqrestore(&dev->lock, flags); - - if (len > current_rx_bytes) - size = current_rx_bytes; - else - size = len; - - size -= copy_to_user(buf, current_rx_buf, size); - bytes_copied += size; - len -= size; - buf += size; - - spin_lock_irqsave(&dev->lock, flags); - - /* We've disconnected or reset so return. */ - if (dev->reset_printer) { - list_add(¤t_rx_req->list, &dev->rx_reqs); - spin_unlock_irqrestore(&dev->lock, flags); - mutex_unlock(&dev->lock_printer_io); - return -EAGAIN; - } - - /* If we not returning all the data left in this RX request - * buffer then adjust the amount of data left in the buffer. - * Othewise if we are done with this RX request buffer then - * requeue it to get any incoming data from the USB host. - */ - if (size < current_rx_bytes) { - current_rx_bytes -= size; - current_rx_buf += size; - } else { - list_add(¤t_rx_req->list, &dev->rx_reqs); - current_rx_bytes = 0; - current_rx_buf = NULL; - current_rx_req = NULL; - } - } - - dev->current_rx_req = current_rx_req; - dev->current_rx_bytes = current_rx_bytes; - dev->current_rx_buf = current_rx_buf; - - spin_unlock_irqrestore(&dev->lock, flags); - mutex_unlock(&dev->lock_printer_io); - - DBG(dev, "printer_read returned %d bytes\n", (int)bytes_copied); - - if (bytes_copied) - return bytes_copied; - else - return -EAGAIN; -} - -static ssize_t -printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr) -{ - struct printer_dev *dev = fd->private_data; - unsigned long flags; - size_t size; /* Amount of data in a TX request. */ - size_t bytes_copied = 0; - struct usb_request *req; - - DBG(dev, "printer_write trying to send %d bytes\n", (int)len); - - if (len == 0) - return -EINVAL; - - mutex_lock(&dev->lock_printer_io); - spin_lock_irqsave(&dev->lock, flags); - - /* Check if a printer reset happens while we have interrupts on */ - dev->reset_printer = 0; - - /* Check if there is any available write buffers */ - if (likely(list_empty(&dev->tx_reqs))) { - /* Turn interrupts back on before sleeping. */ - spin_unlock_irqrestore(&dev->lock, flags); - - /* - * If write buffers are available check if this is - * a NON-Blocking call or not. - */ - if (fd->f_flags & (O_NONBLOCK|O_NDELAY)) { - mutex_unlock(&dev->lock_printer_io); - return -EAGAIN; - } - - /* Sleep until a write buffer is available */ - wait_event_interruptible(dev->tx_wait, - (likely(!list_empty(&dev->tx_reqs)))); - spin_lock_irqsave(&dev->lock, flags); - } - - while (likely(!list_empty(&dev->tx_reqs)) && len) { - - if (len > USB_BUFSIZE) - size = USB_BUFSIZE; - else - size = len; - - req = container_of(dev->tx_reqs.next, struct usb_request, - list); - list_del_init(&req->list); - - req->complete = tx_complete; - req->length = size; - - /* Check if we need to send a zero length packet. */ - if (len > size) - /* They will be more TX requests so no yet. */ - req->zero = 0; - else - /* If the data amount is not a multple of the - * maxpacket size then send a zero length packet. - */ - req->zero = ((len % dev->in_ep->maxpacket) == 0); - - /* Don't leave irqs off while doing memory copies */ - spin_unlock_irqrestore(&dev->lock, flags); - - if (copy_from_user(req->buf, buf, size)) { - list_add(&req->list, &dev->tx_reqs); - mutex_unlock(&dev->lock_printer_io); - return bytes_copied; - } - - bytes_copied += size; - len -= size; - buf += size; - - spin_lock_irqsave(&dev->lock, flags); - - /* We've disconnected or reset so free the req and buffer */ - if (dev->reset_printer) { - list_add(&req->list, &dev->tx_reqs); - spin_unlock_irqrestore(&dev->lock, flags); - mutex_unlock(&dev->lock_printer_io); - return -EAGAIN; - } - - if (usb_ep_queue(dev->in_ep, req, GFP_ATOMIC)) { - list_add(&req->list, &dev->tx_reqs); - spin_unlock_irqrestore(&dev->lock, flags); - mutex_unlock(&dev->lock_printer_io); - return -EAGAIN; - } - - list_add(&req->list, &dev->tx_reqs_active); - - } - - spin_unlock_irqrestore(&dev->lock, flags); - mutex_unlock(&dev->lock_printer_io); - - DBG(dev, "printer_write sent %d bytes\n", (int)bytes_copied); - - if (bytes_copied) { - return bytes_copied; - } else { - return -EAGAIN; - } -} - -static int -printer_fsync(struct file *fd, loff_t start, loff_t end, int datasync) -{ - struct printer_dev *dev = fd->private_data; - struct inode *inode = file_inode(fd); - unsigned long flags; - int tx_list_empty; - - mutex_lock(&inode->i_mutex); - spin_lock_irqsave(&dev->lock, flags); - tx_list_empty = (likely(list_empty(&dev->tx_reqs))); - spin_unlock_irqrestore(&dev->lock, flags); - - if (!tx_list_empty) { - /* Sleep until all data has been sent */ - wait_event_interruptible(dev->tx_flush_wait, - (likely(list_empty(&dev->tx_reqs_active)))); - } - mutex_unlock(&inode->i_mutex); - - return 0; -} - -static unsigned int -printer_poll(struct file *fd, poll_table *wait) -{ - struct printer_dev *dev = fd->private_data; - unsigned long flags; - int status = 0; - - mutex_lock(&dev->lock_printer_io); - spin_lock_irqsave(&dev->lock, flags); - setup_rx_reqs(dev); - spin_unlock_irqrestore(&dev->lock, flags); - mutex_unlock(&dev->lock_printer_io); - - poll_wait(fd, &dev->rx_wait, wait); - poll_wait(fd, &dev->tx_wait, wait); - - spin_lock_irqsave(&dev->lock, flags); - if (likely(!list_empty(&dev->tx_reqs))) - status |= POLLOUT | POLLWRNORM; - - if (likely(dev->current_rx_bytes) || - likely(!list_empty(&dev->rx_buffers))) - status |= POLLIN | POLLRDNORM; - - spin_unlock_irqrestore(&dev->lock, flags); - - return status; -} - -static long -printer_ioctl(struct file *fd, unsigned int code, unsigned long arg) -{ - struct printer_dev *dev = fd->private_data; - unsigned long flags; - int status = 0; - - DBG(dev, "printer_ioctl: cmd=0x%4.4x, arg=%lu\n", code, arg); - - /* handle ioctls */ - - spin_lock_irqsave(&dev->lock, flags); - - switch (code) { - case GADGET_GET_PRINTER_STATUS: - status = (int)dev->printer_status; - break; - case GADGET_SET_PRINTER_STATUS: - dev->printer_status = (u8)arg; - break; - default: - /* could not handle ioctl */ - DBG(dev, "printer_ioctl: ERROR cmd=0x%4.4xis not supported\n", - code); - status = -ENOTTY; - } - - spin_unlock_irqrestore(&dev->lock, flags); - - return status; -} - -/* used after endpoint configuration */ -static const struct file_operations printer_io_operations = { - .owner = THIS_MODULE, - .open = printer_open, - .read = printer_read, - .write = printer_write, - .fsync = printer_fsync, - .poll = printer_poll, - .unlocked_ioctl = printer_ioctl, - .release = printer_close, - .llseek = noop_llseek, -}; - -/*-------------------------------------------------------------------------*/ - -static int -set_printer_interface(struct printer_dev *dev) -{ - int result = 0; - - dev->in_ep->desc = ep_desc(dev->gadget, &fs_ep_in_desc, &hs_ep_in_desc, - &ss_ep_in_desc); - dev->in_ep->driver_data = dev; - - dev->out_ep->desc = ep_desc(dev->gadget, &fs_ep_out_desc, - &hs_ep_out_desc, &ss_ep_out_desc); - dev->out_ep->driver_data = dev; - - result = usb_ep_enable(dev->in_ep); - if (result != 0) { - DBG(dev, "enable %s --> %d\n", dev->in_ep->name, result); - goto done; - } - - result = usb_ep_enable(dev->out_ep); - if (result != 0) { - DBG(dev, "enable %s --> %d\n", dev->in_ep->name, result); - goto done; - } - -done: - /* on error, disable any endpoints */ - if (result != 0) { - (void) usb_ep_disable(dev->in_ep); - (void) usb_ep_disable(dev->out_ep); - dev->in_ep->desc = NULL; - dev->out_ep->desc = NULL; - } - - /* caller is responsible for cleanup on error */ - return result; -} - -static void printer_reset_interface(struct printer_dev *dev) -{ - if (dev->interface < 0) - return; - - DBG(dev, "%s\n", __func__); - - if (dev->in_ep->desc) - usb_ep_disable(dev->in_ep); - - if (dev->out_ep->desc) - usb_ep_disable(dev->out_ep); - - dev->in_ep->desc = NULL; - dev->out_ep->desc = NULL; - dev->interface = -1; -} - -/* Change our operational Interface. */ -static int set_interface(struct printer_dev *dev, unsigned number) -{ - int result = 0; - - /* Free the current interface */ - printer_reset_interface(dev); - - result = set_printer_interface(dev); - if (result) - printer_reset_interface(dev); - else - dev->interface = number; - - if (!result) - INFO(dev, "Using interface %x\n", number); - - return result; -} - -static void printer_soft_reset(struct printer_dev *dev) -{ - struct usb_request *req; - - INFO(dev, "Received Printer Reset Request\n"); - - if (usb_ep_disable(dev->in_ep)) - DBG(dev, "Failed to disable USB in_ep\n"); - if (usb_ep_disable(dev->out_ep)) - DBG(dev, "Failed to disable USB out_ep\n"); - - if (dev->current_rx_req != NULL) { - list_add(&dev->current_rx_req->list, &dev->rx_reqs); - dev->current_rx_req = NULL; - } - dev->current_rx_bytes = 0; - dev->current_rx_buf = NULL; - dev->reset_printer = 1; - - while (likely(!(list_empty(&dev->rx_buffers)))) { - req = container_of(dev->rx_buffers.next, struct usb_request, - list); - list_del_init(&req->list); - list_add(&req->list, &dev->rx_reqs); - } - - while (likely(!(list_empty(&dev->rx_reqs_active)))) { - req = container_of(dev->rx_buffers.next, struct usb_request, - list); - list_del_init(&req->list); - list_add(&req->list, &dev->rx_reqs); - } - - while (likely(!(list_empty(&dev->tx_reqs_active)))) { - req = container_of(dev->tx_reqs_active.next, - struct usb_request, list); - list_del_init(&req->list); - list_add(&req->list, &dev->tx_reqs); - } - - if (usb_ep_enable(dev->in_ep)) - DBG(dev, "Failed to enable USB in_ep\n"); - if (usb_ep_enable(dev->out_ep)) - DBG(dev, "Failed to enable USB out_ep\n"); - - wake_up_interruptible(&dev->rx_wait); - wake_up_interruptible(&dev->tx_wait); - wake_up_interruptible(&dev->tx_flush_wait); -} - -/*-------------------------------------------------------------------------*/ - -static bool gprinter_req_match(struct usb_function *f, - const struct usb_ctrlrequest *ctrl) -{ - struct printer_dev *dev = func_to_printer(f); - u16 w_index = le16_to_cpu(ctrl->wIndex); - u16 w_value = le16_to_cpu(ctrl->wValue); - u16 w_length = le16_to_cpu(ctrl->wLength); - - if ((ctrl->bRequestType & USB_RECIP_MASK) != USB_RECIP_INTERFACE || - (ctrl->bRequestType & USB_TYPE_MASK) != USB_TYPE_CLASS) - return false; - - switch (ctrl->bRequest) { - case GET_DEVICE_ID: - w_index >>= 8; - if (w_length <= PNP_STRING_LEN && - (USB_DIR_IN & ctrl->bRequestType)) - break; - return false; - case GET_PORT_STATUS: - if (!w_value && w_length == 1 && - (USB_DIR_IN & ctrl->bRequestType)) - break; - return false; - case SOFT_RESET: - if (!w_value && !w_length && - (USB_DIR_OUT & ctrl->bRequestType)) - break; - /* fall through */ - default: - return false; - } - return w_index == dev->interface; -} - -/* - * The setup() callback implements all the ep0 functionality that's not - * handled lower down. - */ -static int printer_func_setup(struct usb_function *f, - const struct usb_ctrlrequest *ctrl) -{ - struct printer_dev *dev = func_to_printer(f); - struct usb_composite_dev *cdev = f->config->cdev; - struct usb_request *req = cdev->req; - int value = -EOPNOTSUPP; - u16 wIndex = le16_to_cpu(ctrl->wIndex); - u16 wValue = le16_to_cpu(ctrl->wValue); - u16 wLength = le16_to_cpu(ctrl->wLength); - - DBG(dev, "ctrl req%02x.%02x v%04x i%04x l%d\n", - ctrl->bRequestType, ctrl->bRequest, wValue, wIndex, wLength); - - switch (ctrl->bRequestType&USB_TYPE_MASK) { - case USB_TYPE_CLASS: - switch (ctrl->bRequest) { - case GET_DEVICE_ID: /* Get the IEEE-1284 PNP String */ - /* Only one printer interface is supported. */ - if ((wIndex>>8) != dev->interface) - break; - - value = (dev->pnp_string[0] << 8) | dev->pnp_string[1]; - memcpy(req->buf, dev->pnp_string, value); - DBG(dev, "1284 PNP String: %x %s\n", value, - &dev->pnp_string[2]); - break; - - case GET_PORT_STATUS: /* Get Port Status */ - /* Only one printer interface is supported. */ - if (wIndex != dev->interface) - break; - - *(u8 *)req->buf = dev->printer_status; - value = min(wLength, (u16) 1); - break; - - case SOFT_RESET: /* Soft Reset */ - /* Only one printer interface is supported. */ - if (wIndex != dev->interface) - break; - - printer_soft_reset(dev); - - value = 0; - break; - - default: - goto unknown; - } - break; - - default: -unknown: - VDBG(dev, - "unknown ctrl req%02x.%02x v%04x i%04x l%d\n", - ctrl->bRequestType, ctrl->bRequest, - wValue, wIndex, wLength); - break; - } - /* host either stalls (value < 0) or reports success */ - if (value >= 0) { - req->length = value; - req->zero = value < wLength; - value = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC); - if (value < 0) { - ERROR(dev, "%s:%d Error!\n", __func__, __LINE__); - req->status = 0; - } - } - return value; -} - -static int __init printer_func_bind(struct usb_configuration *c, - struct usb_function *f) -{ - struct usb_gadget *gadget = c->cdev->gadget; - struct printer_dev *dev = func_to_printer(f); - struct device *pdev; - struct usb_composite_dev *cdev = c->cdev; - struct usb_ep *in_ep; - struct usb_ep *out_ep = NULL; - struct usb_request *req; - dev_t devt; - int id; - int ret; - u32 i; - - id = usb_interface_id(c, f); - if (id < 0) - return id; - intf_desc.bInterfaceNumber = id; - - /* finish hookup to lower layer ... */ - dev->gadget = gadget; - - /* all we really need is bulk IN/OUT */ - in_ep = usb_ep_autoconfig(cdev->gadget, &fs_ep_in_desc); - if (!in_ep) { -autoconf_fail: - dev_err(&cdev->gadget->dev, "can't autoconfigure on %s\n", - cdev->gadget->name); - return -ENODEV; - } - in_ep->driver_data = in_ep; /* claim */ - - out_ep = usb_ep_autoconfig(cdev->gadget, &fs_ep_out_desc); - if (!out_ep) - goto autoconf_fail; - out_ep->driver_data = out_ep; /* claim */ - - /* assumes that all endpoints are dual-speed */ - hs_ep_in_desc.bEndpointAddress = fs_ep_in_desc.bEndpointAddress; - hs_ep_out_desc.bEndpointAddress = fs_ep_out_desc.bEndpointAddress; - ss_ep_in_desc.bEndpointAddress = fs_ep_in_desc.bEndpointAddress; - ss_ep_out_desc.bEndpointAddress = fs_ep_out_desc.bEndpointAddress; - - ret = usb_assign_descriptors(f, fs_printer_function, - hs_printer_function, ss_printer_function); - if (ret) - return ret; - - dev->in_ep = in_ep; - dev->out_ep = out_ep; - - ret = -ENOMEM; - for (i = 0; i < dev->q_len; i++) { - req = printer_req_alloc(dev->in_ep, USB_BUFSIZE, GFP_KERNEL); - if (!req) - goto fail_tx_reqs; - list_add(&req->list, &dev->tx_reqs); - } - - for (i = 0; i < dev->q_len; i++) { - req = printer_req_alloc(dev->out_ep, USB_BUFSIZE, GFP_KERNEL); - if (!req) - goto fail_rx_reqs; - list_add(&req->list, &dev->rx_reqs); - } - - /* Setup the sysfs files for the printer gadget. */ - devt = MKDEV(major, dev->minor); - pdev = device_create(usb_gadget_class, NULL, devt, - NULL, "g_printer%d", dev->minor); - if (IS_ERR(pdev)) { - ERROR(dev, "Failed to create device: g_printer\n"); - ret = PTR_ERR(pdev); - goto fail_rx_reqs; - } - - /* - * Register a character device as an interface to a user mode - * program that handles the printer specific functionality. - */ - cdev_init(&dev->printer_cdev, &printer_io_operations); - dev->printer_cdev.owner = THIS_MODULE; - ret = cdev_add(&dev->printer_cdev, devt, 1); - if (ret) { - ERROR(dev, "Failed to open char device\n"); - goto fail_cdev_add; - } - - return 0; - -fail_cdev_add: - device_destroy(usb_gadget_class, devt); - -fail_rx_reqs: - while (!list_empty(&dev->rx_reqs)) { - req = container_of(dev->rx_reqs.next, struct usb_request, list); - list_del(&req->list); - printer_req_free(dev->out_ep, req); - } - -fail_tx_reqs: - while (!list_empty(&dev->tx_reqs)) { - req = container_of(dev->tx_reqs.next, struct usb_request, list); - list_del(&req->list); - printer_req_free(dev->in_ep, req); - } - - return ret; - -} - -static void printer_func_unbind(struct usb_configuration *c, - struct usb_function *f) -{ - struct printer_dev *dev; - struct usb_request *req; - - dev = func_to_printer(f); - - device_destroy(usb_gadget_class, MKDEV(major, dev->minor)); - - /* Remove Character Device */ - cdev_del(&dev->printer_cdev); - - /* we must already have been disconnected ... no i/o may be active */ - WARN_ON(!list_empty(&dev->tx_reqs_active)); - WARN_ON(!list_empty(&dev->rx_reqs_active)); - - /* Free all memory for this driver. */ - while (!list_empty(&dev->tx_reqs)) { - req = container_of(dev->tx_reqs.next, struct usb_request, - list); - list_del(&req->list); - printer_req_free(dev->in_ep, req); - } - - if (dev->current_rx_req != NULL) - printer_req_free(dev->out_ep, dev->current_rx_req); - - while (!list_empty(&dev->rx_reqs)) { - req = container_of(dev->rx_reqs.next, - struct usb_request, list); - list_del(&req->list); - printer_req_free(dev->out_ep, req); - } - - while (!list_empty(&dev->rx_buffers)) { - req = container_of(dev->rx_buffers.next, - struct usb_request, list); - list_del(&req->list); - printer_req_free(dev->out_ep, req); - } - usb_free_all_descriptors(f); - kfree(dev); -} - -static int printer_func_set_alt(struct usb_function *f, - unsigned intf, unsigned alt) -{ - struct printer_dev *dev = func_to_printer(f); - int ret = -ENOTSUPP; - - if (!alt) - ret = set_interface(dev, intf); - - return ret; -} - -static void printer_func_disable(struct usb_function *f) -{ - struct printer_dev *dev = func_to_printer(f); - unsigned long flags; - - DBG(dev, "%s\n", __func__); - - spin_lock_irqsave(&dev->lock, flags); - printer_reset_interface(dev); - spin_unlock_irqrestore(&dev->lock, flags); -} - static struct usb_configuration printer_cfg_driver = { .label = "printer", .bConfigurationValue = 1, .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, }; -static int f_printer_bind_config(struct usb_configuration *c, char *pnp_str, - char *pnp_string, unsigned q_len, int minor) -{ - struct printer_dev *dev; - int status = -ENOMEM; - size_t len; - - if (minor >= minors) - return -ENOENT; - - dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) - return -ENOMEM; - - dev->pnp_string = pnp_string; - dev->minor = minor; - - dev->function.name = shortname; - dev->function.bind = printer_func_bind; - dev->function.setup = printer_func_setup; - dev->function.unbind = printer_func_unbind; - dev->function.set_alt = printer_func_set_alt; - dev->function.disable = printer_func_disable; - dev->function.req_match = gprinter_req_match; - INIT_LIST_HEAD(&dev->tx_reqs); - INIT_LIST_HEAD(&dev->rx_reqs); - INIT_LIST_HEAD(&dev->rx_buffers); - - if (pnp_str) - strlcpy(&dev->pnp_string[2], pnp_str, PNP_STRING_LEN - 2); - - len = strlen(pnp_string); - pnp_string[0] = (len >> 8) & 0xFF; - pnp_string[1] = len & 0xFF; - - spin_lock_init(&dev->lock); - mutex_init(&dev->lock_printer_io); - INIT_LIST_HEAD(&dev->tx_reqs_active); - INIT_LIST_HEAD(&dev->rx_reqs_active); - init_waitqueue_head(&dev->rx_wait); - init_waitqueue_head(&dev->tx_wait); - init_waitqueue_head(&dev->tx_flush_wait); - - dev->interface = -1; - dev->printer_cdev_open = 0; - dev->printer_status = PRINTER_NOT_ERROR; - dev->current_rx_req = NULL; - dev->current_rx_bytes = 0; - dev->current_rx_buf = NULL; - dev->q_len = q_len; - - status = usb_add_function(c, &dev->function); - if (status) { - kfree(dev); - return status; - } - INFO(dev, "%s, version: " DRIVER_VERSION "\n", driver_desc); - return 0; -} - static int __init printer_do_config(struct usb_configuration *c) { struct usb_gadget *gadget = c->cdev->gadget; @@ -1350,43 +144,6 @@ static int __init printer_do_config(struct usb_configuration *c) return f_printer_bind_config(c, iPNPstring, pnp_string, QLEN, 0); } -static int gprinter_setup(int count) -{ - int status; - dev_t devt; - - usb_gadget_class = class_create(THIS_MODULE, "usb_printer_gadget"); - if (IS_ERR(usb_gadget_class)) { - status = PTR_ERR(usb_gadget_class); - usb_gadget_class = NULL; - pr_err("unable to create usb_gadget class %d\n", status); - return status; - } - - status = alloc_chrdev_region(&devt, 0, count, "USB printer gadget"); - if (status) { - pr_err("alloc_chrdev_region %d\n", status); - class_destroy(usb_gadget_class); - usb_gadget_class = NULL; - return status; - } - - major = MAJOR(devt); - minors = count; - - return status; -} - -static void gprinter_cleanup(void) -{ - if (major) { - unregister_chrdev_region(MKDEV(major, 0), minors); - major = minors = 0; - } - class_destroy(usb_gadget_class); - usb_gadget_class = NULL; -} - static int __init printer_bind(struct usb_composite_dev *cdev) { int ret; -- GitLab From b26394bd567e5ebe57ec4dee7fe6cd14023c96e9 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Tue, 3 Mar 2015 10:52:28 +0100 Subject: [PATCH 03831/11651] usb: gadget: f_printer: convert to new function interface with backward compatibility In order to add configfs support, a usb function must be converted to use the new interface. This patch converts the function to the new interface and provides backward compatiblity layer, which can be removed after all its users are converted to use the new interface. Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/Kconfig | 3 + drivers/usb/gadget/function/Makefile | 2 + drivers/usb/gadget/function/f_printer.c | 185 +++++++++++++++++++++++- drivers/usb/gadget/function/u_printer.h | 30 ++++ drivers/usb/gadget/legacy/printer.c | 1 + 5 files changed, 220 insertions(+), 1 deletion(-) create mode 100644 drivers/usb/gadget/function/u_printer.h diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index b454d05be583..9d507cf98f94 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -196,6 +196,9 @@ config USB_F_MIDI config USB_F_HID tristate +config USB_F_PRINTER + tristate + choice tristate "USB Gadget Drivers" default USB_ETH diff --git a/drivers/usb/gadget/function/Makefile b/drivers/usb/gadget/function/Makefile index f71b1aaa0edf..bd7def576955 100644 --- a/drivers/usb/gadget/function/Makefile +++ b/drivers/usb/gadget/function/Makefile @@ -42,3 +42,5 @@ usb_f_midi-y := f_midi.o obj-$(CONFIG_USB_F_MIDI) += usb_f_midi.o usb_f_hid-y := f_hid.o obj-$(CONFIG_USB_F_HID) += usb_f_hid.o +usb_f_printer-y := f_printer.o +obj-$(CONFIG_USB_F_PRINTER) += usb_f_printer.o diff --git a/drivers/usb/gadget/function/f_printer.c b/drivers/usb/gadget/function/f_printer.c index 0847972b9686..93f4d4e61fef 100644 --- a/drivers/usb/gadget/function/f_printer.c +++ b/drivers/usb/gadget/function/f_printer.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -46,6 +47,8 @@ #include #include +#include "u_printer.h" + #define PNP_STRING_LEN 1024 #define PRINTER_MINORS 4 #define GET_DEVICE_ID 0 @@ -54,6 +57,10 @@ static int major, minors; static struct class *usb_gadget_class; +#ifndef USBF_PRINTER_INCLUDED +static DEFINE_IDA(printer_ida); +static DEFINE_MUTEX(printer_ida_lock); /* protects access do printer_ida */ +#endif /*-------------------------------------------------------------------------*/ @@ -999,7 +1006,7 @@ unknown: return value; } -static int __init printer_func_bind(struct usb_configuration *c, +static int printer_func_bind(struct usb_configuration *c, struct usb_function *f) { struct usb_gadget *gadget = c->cdev->gadget; @@ -1111,6 +1118,7 @@ fail_tx_reqs: } +#ifdef USBF_PRINTER_INCLUDED static void printer_func_unbind(struct usb_configuration *c, struct usb_function *f) { @@ -1155,6 +1163,7 @@ static void printer_func_unbind(struct usb_configuration *c, usb_free_all_descriptors(f); kfree(dev); } +#endif static int printer_func_set_alt(struct usb_function *f, unsigned intf, unsigned alt) @@ -1180,6 +1189,7 @@ static void printer_func_disable(struct usb_function *f) spin_unlock_irqrestore(&dev->lock, flags); } +#ifdef USBF_PRINTER_INCLUDED static int f_printer_bind_config(struct usb_configuration *c, char *pnp_str, char *pnp_string, unsigned q_len, int minor) { @@ -1240,6 +1250,179 @@ static int f_printer_bind_config(struct usb_configuration *c, char *pnp_str, INFO(dev, "%s, version: " DRIVER_VERSION "\n", driver_desc); return 0; } +#else +static inline int gprinter_get_minor(void) +{ + return ida_simple_get(&printer_ida, 0, 0, GFP_KERNEL); +} + +static inline void gprinter_put_minor(int minor) +{ + ida_simple_remove(&printer_ida, minor); +} + +static int gprinter_setup(int); +static void gprinter_cleanup(void); + +static void gprinter_free_inst(struct usb_function_instance *f) +{ + struct f_printer_opts *opts; + + opts = container_of(f, struct f_printer_opts, func_inst); + + mutex_lock(&printer_ida_lock); + + gprinter_put_minor(opts->minor); + if (idr_is_empty(&printer_ida.idr)) + gprinter_cleanup(); + + mutex_unlock(&printer_ida_lock); + + kfree(opts); +} + +static struct usb_function_instance *gprinter_alloc_inst(void) +{ + struct f_printer_opts *opts; + struct usb_function_instance *ret; + int status = 0; + + opts = kzalloc(sizeof(*opts), GFP_KERNEL); + if (!opts) + return ERR_PTR(-ENOMEM); + + opts->func_inst.free_func_inst = gprinter_free_inst; + ret = &opts->func_inst; + + mutex_lock(&printer_ida_lock); + + if (idr_is_empty(&printer_ida.idr)) { + status = gprinter_setup(PRINTER_MINORS); + if (status) { + ret = ERR_PTR(status); + kfree(opts); + goto unlock; + } + } + + opts->minor = gprinter_get_minor(); + if (opts->minor < 0) { + ret = ERR_PTR(opts->minor); + kfree(opts); + if (idr_is_empty(&printer_ida.idr)) + gprinter_cleanup(); + } + +unlock: + mutex_unlock(&printer_ida_lock); + return ret; +} + +static void gprinter_free(struct usb_function *f) +{ + struct printer_dev *dev = func_to_printer(f); + + kfree(dev); +} + +static void printer_func_unbind(struct usb_configuration *c, + struct usb_function *f) +{ + struct printer_dev *dev; + struct usb_request *req; + + dev = func_to_printer(f); + + device_destroy(usb_gadget_class, MKDEV(major, dev->minor)); + + /* Remove Character Device */ + cdev_del(&dev->printer_cdev); + + /* we must already have been disconnected ... no i/o may be active */ + WARN_ON(!list_empty(&dev->tx_reqs_active)); + WARN_ON(!list_empty(&dev->rx_reqs_active)); + + /* Free all memory for this driver. */ + while (!list_empty(&dev->tx_reqs)) { + req = container_of(dev->tx_reqs.next, struct usb_request, + list); + list_del(&req->list); + printer_req_free(dev->in_ep, req); + } + + if (dev->current_rx_req != NULL) + printer_req_free(dev->out_ep, dev->current_rx_req); + + while (!list_empty(&dev->rx_reqs)) { + req = container_of(dev->rx_reqs.next, + struct usb_request, list); + list_del(&req->list); + printer_req_free(dev->out_ep, req); + } + + while (!list_empty(&dev->rx_buffers)) { + req = container_of(dev->rx_buffers.next, + struct usb_request, list); + list_del(&req->list); + printer_req_free(dev->out_ep, req); + } + usb_free_all_descriptors(f); +} + +static struct usb_function *gprinter_alloc(struct usb_function_instance *fi) +{ + struct printer_dev *dev; + struct f_printer_opts *opts; + + opts = container_of(fi, struct f_printer_opts, func_inst); + + if (opts->minor >= minors) + return ERR_PTR(-ENOENT); + + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) + return ERR_PTR(-ENOMEM); + + dev->minor = opts->minor; + dev->pnp_string = opts->pnp_string; + dev->q_len = opts->q_len; + + dev->function.name = "printer"; + dev->function.bind = printer_func_bind; + dev->function.setup = printer_func_setup; + dev->function.unbind = printer_func_unbind; + dev->function.set_alt = printer_func_set_alt; + dev->function.disable = printer_func_disable; + dev->function.req_match = gprinter_req_match; + dev->function.free_func = gprinter_free; + + INIT_LIST_HEAD(&dev->tx_reqs); + INIT_LIST_HEAD(&dev->rx_reqs); + INIT_LIST_HEAD(&dev->rx_buffers); + INIT_LIST_HEAD(&dev->tx_reqs_active); + INIT_LIST_HEAD(&dev->rx_reqs_active); + + spin_lock_init(&dev->lock); + mutex_init(&dev->lock_printer_io); + init_waitqueue_head(&dev->rx_wait); + init_waitqueue_head(&dev->tx_wait); + init_waitqueue_head(&dev->tx_flush_wait); + + dev->interface = -1; + dev->printer_cdev_open = 0; + dev->printer_status = PRINTER_NOT_ERROR; + dev->current_rx_req = NULL; + dev->current_rx_bytes = 0; + dev->current_rx_buf = NULL; + + return &dev->function; +} + +DECLARE_USB_FUNCTION_INIT(printer, gprinter_alloc_inst, gprinter_alloc); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Craig Nadler"); + +#endif static int gprinter_setup(int count) { diff --git a/drivers/usb/gadget/function/u_printer.h b/drivers/usb/gadget/function/u_printer.h new file mode 100644 index 000000000000..b2338cacdfe4 --- /dev/null +++ b/drivers/usb/gadget/function/u_printer.h @@ -0,0 +1,30 @@ +/* + * u_printer.h + * + * Utility definitions for the printer function + * + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Author: Andrzej Pietrasiewicz + * + * 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. + */ + +#ifndef U_PRINTER_H +#define U_PRINTER_H + +#include + +#define PNP_STRING_LEN 1024 + +struct f_printer_opts { + struct usb_function_instance func_inst; + int minor; + char pnp_string[PNP_STRING_LEN]; + unsigned q_len; +}; + +#endif /* U_PRINTER_H */ diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index 4d926d08df02..770b5041323e 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -33,6 +33,7 @@ static const char driver_desc [] = DRIVER_DESC; * This will be changed when f_printer is converted * to the new function interface. */ +#define USBF_PRINTER_INCLUDED #include "f_printer.c" /*-------------------------------------------------------------------------*/ -- GitLab From 69504f808d6770940f1404b6f6f43c50cfe0be72 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Tue, 3 Mar 2015 10:52:29 +0100 Subject: [PATCH 03832/11651] usb: gadget: printer: convert to new interface of f_printer The goal is to remove the old function interface, so its (only) user must be converted to the new interface. Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/legacy/Kconfig | 1 + drivers/usb/gadget/legacy/printer.c | 50 +++++++++++++++++++++-------- 2 files changed, 37 insertions(+), 14 deletions(-) diff --git a/drivers/usb/gadget/legacy/Kconfig b/drivers/usb/gadget/legacy/Kconfig index 113c87e22117..d5a7102de696 100644 --- a/drivers/usb/gadget/legacy/Kconfig +++ b/drivers/usb/gadget/legacy/Kconfig @@ -301,6 +301,7 @@ config USB_MIDI_GADGET config USB_G_PRINTER tristate "Printer Gadget" select USB_LIBCOMPOSITE + select USB_F_PRINTER help The Printer Gadget channels data between the USB host and a userspace program driving the print engine. The user space diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index 770b5041323e..a8050f8cbe11 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -29,12 +29,7 @@ USB_GADGET_COMPOSITE_OPTIONS(); static const char shortname [] = "printer"; static const char driver_desc [] = DRIVER_DESC; -/* - * This will be changed when f_printer is converted - * to the new function interface. - */ -#define USBF_PRINTER_INCLUDED -#include "f_printer.c" +#include "u_printer.h" /*-------------------------------------------------------------------------*/ @@ -65,6 +60,9 @@ module_param(qlen, uint, S_IRUGO|S_IWUSR); #define QLEN qlen +static struct usb_function_instance *fi_printer; +static struct usb_function *f_printer; + /*-------------------------------------------------------------------------*/ /* @@ -131,6 +129,7 @@ static struct usb_configuration printer_cfg_driver = { static int __init printer_do_config(struct usb_configuration *c) { struct usb_gadget *gadget = c->cdev->gadget; + int status = 0; usb_ep_autoconfig_reset(gadget); @@ -142,20 +141,41 @@ static int __init printer_do_config(struct usb_configuration *c) printer_cfg_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP; } - return f_printer_bind_config(c, iPNPstring, pnp_string, QLEN, 0); + f_printer = usb_get_function(fi_printer); + if (IS_ERR(f_printer)) + return PTR_ERR(f_printer); + + status = usb_add_function(c, f_printer); + if (status < 0) + usb_put_function(f_printer); + + return status; } static int __init printer_bind(struct usb_composite_dev *cdev) { - int ret; + struct f_printer_opts *opts; + int ret, len; - ret = gprinter_setup(PRINTER_MINORS); - if (ret) - return ret; + fi_printer = usb_get_function_instance("printer"); + if (IS_ERR(fi_printer)) + return PTR_ERR(fi_printer); + + if (iPNPstring) + strlcpy(&pnp_string[2], iPNPstring, PNP_STRING_LEN - 2); + + len = strlen(pnp_string); + pnp_string[0] = (len >> 8) & 0xFF; + pnp_string[1] = len & 0xFF; + + opts = container_of(fi_printer, struct f_printer_opts, func_inst); + opts->minor = 0; + memcpy(opts->pnp_string, pnp_string, PNP_STRING_LEN); + opts->q_len = QLEN; ret = usb_string_ids_tab(cdev, strings); if (ret < 0) { - gprinter_cleanup(); + usb_put_function_instance(fi_printer); return ret; } device_desc.iManufacturer = strings[USB_GADGET_MANUFACTURER_IDX].id; @@ -164,7 +184,7 @@ static int __init printer_bind(struct usb_composite_dev *cdev) ret = usb_add_config(cdev, &printer_cfg_driver, printer_do_config); if (ret) { - gprinter_cleanup(); + usb_put_function_instance(fi_printer); return ret; } usb_composite_overwrite_options(cdev, &coverwrite); @@ -173,7 +193,9 @@ static int __init printer_bind(struct usb_composite_dev *cdev) static int __exit printer_unbind(struct usb_composite_dev *cdev) { - gprinter_cleanup(); + usb_put_function(f_printer); + usb_put_function_instance(fi_printer); + return 0; } -- GitLab From d85dc4824c5793f4b71225d7ba5b50e737045830 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Tue, 3 Mar 2015 10:52:30 +0100 Subject: [PATCH 03833/11651] usb: gadget: f_printer: remove compatibility layer There are no old interface users left, so it can be removed. Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_printer.c | 113 ------------------------ 1 file changed, 113 deletions(-) diff --git a/drivers/usb/gadget/function/f_printer.c b/drivers/usb/gadget/function/f_printer.c index 93f4d4e61fef..7afe17d76f17 100644 --- a/drivers/usb/gadget/function/f_printer.c +++ b/drivers/usb/gadget/function/f_printer.c @@ -57,10 +57,8 @@ static int major, minors; static struct class *usb_gadget_class; -#ifndef USBF_PRINTER_INCLUDED static DEFINE_IDA(printer_ida); static DEFINE_MUTEX(printer_ida_lock); /* protects access do printer_ida */ -#endif /*-------------------------------------------------------------------------*/ @@ -1118,53 +1116,6 @@ fail_tx_reqs: } -#ifdef USBF_PRINTER_INCLUDED -static void printer_func_unbind(struct usb_configuration *c, - struct usb_function *f) -{ - struct printer_dev *dev; - struct usb_request *req; - - dev = func_to_printer(f); - - device_destroy(usb_gadget_class, MKDEV(major, dev->minor)); - - /* Remove Character Device */ - cdev_del(&dev->printer_cdev); - - /* we must already have been disconnected ... no i/o may be active */ - WARN_ON(!list_empty(&dev->tx_reqs_active)); - WARN_ON(!list_empty(&dev->rx_reqs_active)); - - /* Free all memory for this driver. */ - while (!list_empty(&dev->tx_reqs)) { - req = container_of(dev->tx_reqs.next, struct usb_request, - list); - list_del(&req->list); - printer_req_free(dev->in_ep, req); - } - - if (dev->current_rx_req != NULL) - printer_req_free(dev->out_ep, dev->current_rx_req); - - while (!list_empty(&dev->rx_reqs)) { - req = container_of(dev->rx_reqs.next, - struct usb_request, list); - list_del(&req->list); - printer_req_free(dev->out_ep, req); - } - - while (!list_empty(&dev->rx_buffers)) { - req = container_of(dev->rx_buffers.next, - struct usb_request, list); - list_del(&req->list); - printer_req_free(dev->out_ep, req); - } - usb_free_all_descriptors(f); - kfree(dev); -} -#endif - static int printer_func_set_alt(struct usb_function *f, unsigned intf, unsigned alt) { @@ -1189,68 +1140,6 @@ static void printer_func_disable(struct usb_function *f) spin_unlock_irqrestore(&dev->lock, flags); } -#ifdef USBF_PRINTER_INCLUDED -static int f_printer_bind_config(struct usb_configuration *c, char *pnp_str, - char *pnp_string, unsigned q_len, int minor) -{ - struct printer_dev *dev; - int status = -ENOMEM; - size_t len; - - if (minor >= minors) - return -ENOENT; - - dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) - return -ENOMEM; - - dev->pnp_string = pnp_string; - dev->minor = minor; - - dev->function.name = shortname; - dev->function.bind = printer_func_bind; - dev->function.setup = printer_func_setup; - dev->function.unbind = printer_func_unbind; - dev->function.set_alt = printer_func_set_alt; - dev->function.disable = printer_func_disable; - dev->function.req_match = gprinter_req_match; - INIT_LIST_HEAD(&dev->tx_reqs); - INIT_LIST_HEAD(&dev->rx_reqs); - INIT_LIST_HEAD(&dev->rx_buffers); - - if (pnp_str) - strlcpy(&dev->pnp_string[2], pnp_str, PNP_STRING_LEN - 2); - - len = strlen(pnp_string); - pnp_string[0] = (len >> 8) & 0xFF; - pnp_string[1] = len & 0xFF; - - spin_lock_init(&dev->lock); - mutex_init(&dev->lock_printer_io); - INIT_LIST_HEAD(&dev->tx_reqs_active); - INIT_LIST_HEAD(&dev->rx_reqs_active); - init_waitqueue_head(&dev->rx_wait); - init_waitqueue_head(&dev->tx_wait); - init_waitqueue_head(&dev->tx_flush_wait); - - dev->interface = -1; - dev->printer_cdev_open = 0; - dev->printer_status = PRINTER_NOT_ERROR; - dev->current_rx_req = NULL; - dev->current_rx_bytes = 0; - dev->current_rx_buf = NULL; - dev->q_len = q_len; - - status = usb_add_function(c, &dev->function); - if (status) { - kfree(dev); - return status; - } - - INFO(dev, "%s, version: " DRIVER_VERSION "\n", driver_desc); - return 0; -} -#else static inline int gprinter_get_minor(void) { return ida_simple_get(&printer_ida, 0, 0, GFP_KERNEL); @@ -1422,8 +1311,6 @@ DECLARE_USB_FUNCTION_INIT(printer, gprinter_alloc_inst, gprinter_alloc); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Craig Nadler"); -#endif - static int gprinter_setup(int count) { int status; -- GitLab From a2a8e48a94c78c72b5dd1e4c8d190c5c54aca7a4 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Tue, 3 Mar 2015 10:52:31 +0100 Subject: [PATCH 03834/11651] usb: gadget: printer: use module_usb_composite_driver helper macro Substitute some boilerplate code with a dedicated macro. Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/legacy/printer.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index a8050f8cbe11..d5b6ee725a2a 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -208,19 +208,7 @@ static __refdata struct usb_composite_driver printer_driver = { .unbind = printer_unbind, }; -static int __init -init(void) -{ - return usb_composite_probe(&printer_driver); -} -module_init(init); - -static void __exit -cleanup(void) -{ - usb_composite_unregister(&printer_driver); -} -module_exit(cleanup); +module_usb_composite_driver(printer_driver); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_AUTHOR("Craig Nadler"); -- GitLab From ee1cd515e889d222f5a7397fead0a9db1214edea Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Tue, 3 Mar 2015 10:52:32 +0100 Subject: [PATCH 03835/11651] usb: gadget: printer: add configfs support Add support for configfs interface so that f_printer can be used as a component of usb gadgets composed with it. Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- .../ABI/testing/configfs-usb-gadget-printer | 9 ++ Documentation/usb/gadget-testing.txt | 47 +++++++ drivers/usb/gadget/Kconfig | 13 ++ drivers/usb/gadget/function/f_printer.c | 130 +++++++++++++++++- drivers/usb/gadget/function/u_printer.h | 7 + 5 files changed, 204 insertions(+), 2 deletions(-) create mode 100644 Documentation/ABI/testing/configfs-usb-gadget-printer diff --git a/Documentation/ABI/testing/configfs-usb-gadget-printer b/Documentation/ABI/testing/configfs-usb-gadget-printer new file mode 100644 index 000000000000..6b0714e3c605 --- /dev/null +++ b/Documentation/ABI/testing/configfs-usb-gadget-printer @@ -0,0 +1,9 @@ +What: /config/usb-gadget/gadget/functions/printer.name +Date: Apr 2015 +KernelVersion: 4.1 +Description: + The attributes: + + pnp_string - Data to be passed to the host in pnp string + q_len - Number of requests per endpoint + diff --git a/Documentation/usb/gadget-testing.txt b/Documentation/usb/gadget-testing.txt index 076ac7ba7f93..f45b2bf4b41d 100644 --- a/Documentation/usb/gadget-testing.txt +++ b/Documentation/usb/gadget-testing.txt @@ -19,6 +19,7 @@ provided by gadgets. 16. UAC1 function 17. UAC2 function 18. UVC function +19. PRINTER function 1. ACM function @@ -726,3 +727,49 @@ with these patches: http://www.spinics.net/lists/linux-usb/msg99220.html host: luvcview -f yuv + +19. PRINTER function +==================== + +The function is provided by usb_f_printer.ko module. + +Function-specific configfs interface +------------------------------------ + +The function name to use when creating the function directory is "printer". +The printer function provides these attributes in its function directory: + + pnp_string - Data to be passed to the host in pnp string + q_len - Number of requests per endpoint + +Testing the PRINTER function +---------------------------- + +The most basic testing: + +device: run the gadget +# ls -l /devices/virtual/usb_printer_gadget/ + +should show g_printer. + +If udev is active, then /dev/g_printer should appear automatically. + +host: + +If udev is active, then e.g. /dev/usb/lp0 should appear. + +host->device transmission: + +device: +# cat /dev/g_printer +host: +# cat > /dev/usb/lp0 + +device->host transmission: + +# cat > /dev/g_printer +host: +# cat /dev/usb/lp0 + +More advanced testing can be done with the prn_example +described in Documentation/usb/gadget-printer.txt. diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 9d507cf98f94..3bb0e67fded2 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -437,6 +437,19 @@ config USB_CONFIGFS_F_UVC device. It provides a userspace API to process UVC control requests and stream video data to the host. +config USB_CONFIGFS_F_PRINTER + bool "Printer function" + select USB_F_PRINTER + help + The Printer function channels data between the USB host and a + userspace program driving the print engine. The user space + program reads and writes the device file /dev/g_printer to + receive or send printer data. It can use ioctl calls to + the device file to get or set printer status. + + For more information, see Documentation/usb/gadget_printer.txt + which includes sample code for accessing the device file. + source "drivers/usb/gadget/legacy/Kconfig" endchoice diff --git a/drivers/usb/gadget/function/f_printer.c b/drivers/usb/gadget/function/f_printer.c index 7afe17d76f17..757fcf070013 100644 --- a/drivers/usb/gadget/function/f_printer.c +++ b/drivers/usb/gadget/function/f_printer.c @@ -1140,6 +1140,117 @@ static void printer_func_disable(struct usb_function *f) spin_unlock_irqrestore(&dev->lock, flags); } +static inline struct f_printer_opts +*to_f_printer_opts(struct config_item *item) +{ + return container_of(to_config_group(item), struct f_printer_opts, + func_inst.group); +} + +CONFIGFS_ATTR_STRUCT(f_printer_opts); +CONFIGFS_ATTR_OPS(f_printer_opts); + +static void printer_attr_release(struct config_item *item) +{ + struct f_printer_opts *opts = to_f_printer_opts(item); + + usb_put_function_instance(&opts->func_inst); +} + +static struct configfs_item_operations printer_item_ops = { + .release = printer_attr_release, + .show_attribute = f_printer_opts_attr_show, + .store_attribute = f_printer_opts_attr_store, +}; + +static ssize_t f_printer_opts_pnp_string_show(struct f_printer_opts *opts, + char *page) +{ + int result; + + mutex_lock(&opts->lock); + result = strlcpy(page, opts->pnp_string + 2, PNP_STRING_LEN - 2); + mutex_unlock(&opts->lock); + + return result; +} + +static ssize_t f_printer_opts_pnp_string_store(struct f_printer_opts *opts, + const char *page, size_t len) +{ + int result, l; + + mutex_lock(&opts->lock); + result = strlcpy(opts->pnp_string + 2, page, PNP_STRING_LEN - 2); + l = strlen(opts->pnp_string + 2) + 2; + opts->pnp_string[0] = (l >> 8) & 0xFF; + opts->pnp_string[1] = l & 0xFF; + mutex_unlock(&opts->lock); + + return result; +} + +static struct f_printer_opts_attribute f_printer_opts_pnp_string = + __CONFIGFS_ATTR(pnp_string, S_IRUGO | S_IWUSR, + f_printer_opts_pnp_string_show, + f_printer_opts_pnp_string_store); + +static ssize_t f_printer_opts_q_len_show(struct f_printer_opts *opts, + char *page) +{ + int result; + + mutex_lock(&opts->lock); + result = sprintf(page, "%d\n", opts->q_len); + mutex_unlock(&opts->lock); + + return result; +} + +static ssize_t f_printer_opts_q_len_store(struct f_printer_opts *opts, + const char *page, size_t len) +{ + int ret; + u16 num; + + mutex_lock(&opts->lock); + if (opts->refcnt) { + ret = -EBUSY; + goto end; + } + + ret = kstrtou16(page, 0, &num); + if (ret) + goto end; + + if (num > 65535) { + ret = -EINVAL; + goto end; + } + + opts->q_len = (unsigned)num; + ret = len; +end: + mutex_unlock(&opts->lock); + return ret; +} + +static struct f_printer_opts_attribute f_printer_opts_q_len = + __CONFIGFS_ATTR(q_len, S_IRUGO | S_IWUSR, f_printer_opts_q_len_show, + f_printer_opts_q_len_store); + +static struct configfs_attribute *printer_attrs[] = { + &f_printer_opts_pnp_string.attr, + &f_printer_opts_q_len.attr, + NULL, +}; + +static struct config_item_type printer_func_type = { + .ct_item_ops = &printer_item_ops, + .ct_attrs = printer_attrs, + .ct_owner = THIS_MODULE, +}; + static inline int gprinter_get_minor(void) { return ida_simple_get(&printer_ida, 0, 0, GFP_KERNEL); @@ -1180,6 +1291,7 @@ static struct usb_function_instance *gprinter_alloc_inst(void) if (!opts) return ERR_PTR(-ENOMEM); + mutex_init(&opts->lock); opts->func_inst.free_func_inst = gprinter_free_inst; ret = &opts->func_inst; @@ -1201,6 +1313,8 @@ static struct usb_function_instance *gprinter_alloc_inst(void) if (idr_is_empty(&printer_ida.idr)) gprinter_cleanup(); } + config_group_init_type_name(&opts->func_inst.group, "", + &printer_func_type); unlock: mutex_unlock(&printer_ida_lock); @@ -1210,8 +1324,13 @@ unlock: static void gprinter_free(struct usb_function *f) { struct printer_dev *dev = func_to_printer(f); + struct f_printer_opts *opts; + opts = container_of(f->fi, struct f_printer_opts, func_inst); kfree(dev); + mutex_lock(&opts->lock); + --opts->refcnt; + mutex_unlock(&opts->lock); } static void printer_func_unbind(struct usb_configuration *c, @@ -1265,16 +1384,23 @@ static struct usb_function *gprinter_alloc(struct usb_function_instance *fi) opts = container_of(fi, struct f_printer_opts, func_inst); - if (opts->minor >= minors) + mutex_lock(&opts->lock); + if (opts->minor >= minors) { + mutex_unlock(&opts->lock); return ERR_PTR(-ENOENT); + } dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) + if (!dev) { + mutex_unlock(&opts->lock); return ERR_PTR(-ENOMEM); + } + ++opts->refcnt; dev->minor = opts->minor; dev->pnp_string = opts->pnp_string; dev->q_len = opts->q_len; + mutex_unlock(&opts->lock); dev->function.name = "printer"; dev->function.bind = printer_func_bind; diff --git a/drivers/usb/gadget/function/u_printer.h b/drivers/usb/gadget/function/u_printer.h index b2338cacdfe4..0e2c49d4274e 100644 --- a/drivers/usb/gadget/function/u_printer.h +++ b/drivers/usb/gadget/function/u_printer.h @@ -25,6 +25,13 @@ struct f_printer_opts { int minor; char pnp_string[PNP_STRING_LEN]; unsigned q_len; + + /* + * Protect the data from concurrent access by read/write + * and create symlink/remove symlink + */ + struct mutex lock; + int refcnt; }; #endif /* U_PRINTER_H */ -- GitLab From 8d0c38a3f2a6bb70e952f127ed817fc7a08db52c Mon Sep 17 00:00:00 2001 From: Jin Yao Date: Tue, 10 Mar 2015 09:05:38 +0800 Subject: [PATCH 03836/11651] ASoC: Intel: move sysclk source setting to platform_clock_control for balance. A playback noise happens after suspend/resume on Braswell. The issue is due to the codec PLL and codec ASRC are not enabled correctly due to the incorrect sysclk setting after resume. This patch resets the sysclk source setting in platform clock control widget handler. Signed-off-by: Bard Liao Signed-off-by: Jin Yao Signed-off-by: Mark Brown --- sound/soc/intel/cht_bsw_rt5672.c | 40 ++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/sound/soc/intel/cht_bsw_rt5672.c b/sound/soc/intel/cht_bsw_rt5672.c index bc8dcacd5e6a..279df4c43de1 100644 --- a/sound/soc/intel/cht_bsw_rt5672.c +++ b/sound/soc/intel/cht_bsw_rt5672.c @@ -50,6 +50,7 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w, struct snd_soc_dapm_context *dapm = w->dapm; struct snd_soc_card *card = dapm->card; struct snd_soc_dai *codec_dai; + int ret; codec_dai = cht_get_codec_dai(card); if (!codec_dai) { @@ -57,17 +58,31 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w, return -EIO; } - if (!SND_SOC_DAPM_EVENT_OFF(event)) - return 0; - - /* Set codec sysclk source to its internal clock because codec PLL will - * be off when idle and MCLK will also be off by ACPI when codec is - * runtime suspended. Codec needs clock for jack detection and button - * press. - */ - snd_soc_dai_set_sysclk(codec_dai, RT5670_SCLK_S_RCCLK, - 0, SND_SOC_CLOCK_IN); - + if (SND_SOC_DAPM_EVENT_ON(event)) { + /* set codec PLL source to the 19.2MHz platform clock (MCLK) */ + ret = snd_soc_dai_set_pll(codec_dai, 0, RT5670_PLL1_S_MCLK, + CHT_PLAT_CLK_3_HZ, 48000 * 512); + if (ret < 0) { + dev_err(card->dev, "can't set codec pll: %d\n", ret); + return ret; + } + + /* set codec sysclk source to PLL */ + ret = snd_soc_dai_set_sysclk(codec_dai, RT5670_SCLK_S_PLL1, + 48000 * 512, SND_SOC_CLOCK_IN); + if (ret < 0) { + dev_err(card->dev, "can't set codec sysclk: %d\n", ret); + return ret; + } + } else { + /* Set codec sysclk source to its internal clock because codec + * PLL will be off when idle and MCLK will also be off by ACPI + * when codec is runtime suspended. Codec needs clock for jack + * detection and button press. + */ + snd_soc_dai_set_sysclk(codec_dai, RT5670_SCLK_S_RCCLK, + 48000 * 512, SND_SOC_CLOCK_IN); + } return 0; } @@ -77,7 +92,8 @@ static const struct snd_soc_dapm_widget cht_dapm_widgets[] = { SND_SOC_DAPM_MIC("Int Mic", NULL), SND_SOC_DAPM_SPK("Ext Spk", NULL), SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0, - platform_clock_control, SND_SOC_DAPM_POST_PMD), + platform_clock_control, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), }; static const struct snd_soc_dapm_route cht_audio_map[] = { -- GitLab From 55e76b38986a61259f3079afd0f9a865651a34fe Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Tue, 10 Mar 2015 22:34:40 +0200 Subject: [PATCH 03837/11651] Bluetooth: Add 'Already Paired' error for Pair Device command To make the behavior predictable when attempting to pair with a device for which we already have a Link Key or Long Term Key, this patch adds a new 'Already Paired' error which gets sent in such a scenario. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- include/net/bluetooth/hci_core.h | 2 ++ include/net/bluetooth/mgmt.h | 1 + net/bluetooth/hci_core.c | 27 +++++++++++++++++++++++++++ net/bluetooth/mgmt.c | 7 +++++++ 4 files changed, 37 insertions(+) diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index afc641c5e55c..5cc5a192359d 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -967,6 +967,8 @@ struct smp_irk *hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type); void hci_smp_irks_clear(struct hci_dev *hdev); +bool hci_bdaddr_is_paired(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type); + void hci_remote_oob_data_clear(struct hci_dev *hdev); struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type); diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h index 0c737e4b8f57..5bf6af9cee78 100644 --- a/include/net/bluetooth/mgmt.h +++ b/include/net/bluetooth/mgmt.h @@ -43,6 +43,7 @@ #define MGMT_STATUS_CANCELLED 0x10 #define MGMT_STATUS_INVALID_INDEX 0x11 #define MGMT_STATUS_RFKILLED 0x12 +#define MGMT_STATUS_ALREADY_PAIRED 0x13 struct mgmt_hdr { __le16 opcode; diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index bba4c344c6e0..a35d8441187a 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -2516,6 +2516,33 @@ void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type) } } +bool hci_bdaddr_is_paired(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) +{ + struct smp_ltk *k; + u8 addr_type; + + if (type == BDADDR_BREDR) { + if (hci_find_link_key(hdev, bdaddr)) + return true; + return false; + } + + /* Convert to HCI addr type which struct smp_ltk uses */ + if (type == BDADDR_LE_PUBLIC) + addr_type = ADDR_LE_DEV_PUBLIC; + else + addr_type = ADDR_LE_DEV_RANDOM; + + rcu_read_lock(); + list_for_each_entry_rcu(k, &hdev->long_term_keys, list) { + if (k->bdaddr_type == addr_type && !bacmp(bdaddr, &k->bdaddr)) + return true; + } + rcu_read_unlock(); + + return false; +} + /* HCI command timer function */ static void hci_cmd_timeout(struct work_struct *work) { diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 49b8e09ffe67..600636c00d34 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -3245,6 +3245,13 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data, goto unlock; } + if (hci_bdaddr_is_paired(hdev, &cp->addr.bdaddr, cp->addr.type)) { + err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_PAIR_DEVICE, + MGMT_STATUS_ALREADY_PAIRED, &rp, + sizeof(rp)); + goto unlock; + } + sec_level = BT_SECURITY_MEDIUM; auth_type = HCI_AT_DEDICATED_BONDING; -- GitLab From 509d612b2fc4b66a58f1af762ac69829ed11c0ce Mon Sep 17 00:00:00 2001 From: Yunzhi Li Date: Fri, 6 Mar 2015 15:17:10 +0800 Subject: [PATCH 03838/11651] usb: dwc2: host: fix dwc2 disconnect bug When dwc2 controller detects a disconnect interrupt, dwc2_hcd_disconnect() should be called immediately to do clean-up jobs and set port_connect_status_change flag to notify usb hub driver disconnect status. Tested-by: Vincent Palatin Acked-by: John Youn Signed-off-by: Yunzhi Li Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/core_intr.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c index 02e3e2d4ea56..6cf047878dba 100644 --- a/drivers/usb/dwc2/core_intr.c +++ b/drivers/usb/dwc2/core_intr.c @@ -377,6 +377,9 @@ static void dwc2_handle_disconnect_intr(struct dwc2_hsotg *hsotg) dwc2_is_host_mode(hsotg) ? "Host" : "Device", dwc2_op_state_str(hsotg)); + if (hsotg->op_state == OTG_STATE_A_HOST) + dwc2_hcd_disconnect(hsotg); + /* Change to L3 (OFF) state */ hsotg->lx_state = DWC2_L3; -- GitLab From b78ce7ed54093e5e63d4f5d7cbdc3f7d42ebbd5c Mon Sep 17 00:00:00 2001 From: Adrian Remonda Date: Tue, 10 Mar 2015 16:12:30 -0400 Subject: [PATCH 03839/11651] spi: spidev_test: Cleaned hexadecimal dump Signed-off-by: Adrian Remonda Signed-off-by: Mark Brown --- Documentation/spi/spidev_test.c | 35 +++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/Documentation/spi/spidev_test.c b/Documentation/spi/spidev_test.c index 3a2f9d59edab..9cb09184a3d6 100644 --- a/Documentation/spi/spidev_test.c +++ b/Documentation/spi/spidev_test.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -35,6 +36,33 @@ static uint8_t bits = 8; static uint32_t speed = 500000; static uint16_t delay; +static void hex_dump(const void *src, size_t length, size_t line_size, char *prefix) +{ + int i = 0; + const unsigned char *address = src; + const unsigned char *line = address; + unsigned char c; + + printf("%s | ", prefix); + while (length-- > 0) { + printf("%02X ", *address++); + if (!(++i % line_size) || (length == 0 && i % line_size)) { + if (length == 0) { + while (i++ % line_size) + printf("__ "); + } + printf(" | "); /* right close */ + while (line < address) { + c = *line++; + printf("%c", (c < 33 || c == 255) ? 0x2E : c); + } + printf("\n"); + if (length > 0) + printf("%s | ", prefix); + } + } +} + static void transfer(int fd) { int ret; @@ -76,12 +104,7 @@ static void transfer(int fd) if (ret < 1) pabort("can't send spi message"); - for (ret = 0; ret < ARRAY_SIZE(tx); ret++) { - if (!(ret % 6)) - puts(""); - printf("%.2X ", rx[ret]); - } - puts(""); + hex_dump(rx, ARRAY_SIZE(rx), 32, "RX"); } static void print_usage(const char *prog) -- GitLab From 31a5c5a72b90e074bd2377ada2bdfd506801ed72 Mon Sep 17 00:00:00 2001 From: Adrian Remonda Date: Tue, 10 Mar 2015 16:12:31 -0400 Subject: [PATCH 03840/11651] spi: spidev_test: Added verbose output Signed-off-by: Adrian Remonda Signed-off-by: Mark Brown --- Documentation/spi/spidev_test.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Documentation/spi/spidev_test.c b/Documentation/spi/spidev_test.c index 9cb09184a3d6..4b6a3803638b 100644 --- a/Documentation/spi/spidev_test.c +++ b/Documentation/spi/spidev_test.c @@ -35,6 +35,7 @@ static uint32_t mode; static uint8_t bits = 8; static uint32_t speed = 500000; static uint16_t delay; +static int verbose; static void hex_dump(const void *src, size_t length, size_t line_size, char *prefix) { @@ -104,6 +105,8 @@ static void transfer(int fd) if (ret < 1) pabort("can't send spi message"); + if (verbose) + hex_dump(tx, ARRAY_SIZE(tx), 32, "TX"); hex_dump(rx, ARRAY_SIZE(rx), 32, "RX"); } @@ -120,6 +123,7 @@ static void print_usage(const char *prog) " -L --lsb least significant bit first\n" " -C --cs-high chip select active high\n" " -3 --3wire SI/SO signals shared\n" + " -v --verbose Verbose (show tx buffer)\n" " -N --no-cs no chip select\n" " -R --ready slave pulls low to pause\n" " -2 --dual dual transfer\n" @@ -144,12 +148,13 @@ static void parse_opts(int argc, char *argv[]) { "no-cs", 0, 0, 'N' }, { "ready", 0, 0, 'R' }, { "dual", 0, 0, '2' }, + { "verbose", 0, 0, 'v' }, { "quad", 0, 0, '4' }, { NULL, 0, 0, 0 }, }; int c; - c = getopt_long(argc, argv, "D:s:d:b:lHOLC3NR24", lopts, NULL); + c = getopt_long(argc, argv, "D:s:d:b:lHOLC3NR24:v", lopts, NULL); if (c == -1) break; @@ -188,6 +193,9 @@ static void parse_opts(int argc, char *argv[]) case 'N': mode |= SPI_NO_CS; break; + case 'v': + verbose = 1; + break; case 'R': mode |= SPI_READY; break; -- GitLab From 30061915be6e3a2c2a4bc4f22a229d4eb7b7cc65 Mon Sep 17 00:00:00 2001 From: Adrian Remonda Date: Tue, 10 Mar 2015 16:12:32 -0400 Subject: [PATCH 03841/11651] spi: spidev_test: Added input buffer from the terminal Signed-off-by: Adrian Remonda Signed-off-by: Mark Brown --- Documentation/spi/spidev_test.c | 76 ++++++++++++++++++++++++++------- 1 file changed, 60 insertions(+), 16 deletions(-) diff --git a/Documentation/spi/spidev_test.c b/Documentation/spi/spidev_test.c index 4b6a3803638b..94f574b0fdb2 100644 --- a/Documentation/spi/spidev_test.c +++ b/Documentation/spi/spidev_test.c @@ -37,6 +37,18 @@ static uint32_t speed = 500000; static uint16_t delay; static int verbose; +uint8_t default_tx[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x95, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF0, 0x0D, +}; + +uint8_t default_rx[ARRAY_SIZE(default_tx)] = {0, }; +char *input_tx; + static void hex_dump(const void *src, size_t length, size_t line_size, char *prefix) { int i = 0; @@ -64,23 +76,38 @@ static void hex_dump(const void *src, size_t length, size_t line_size, char *pre } } -static void transfer(int fd) +/* + * Unescape - process hexadecimal escape character + * converts shell input "\x23" -> 0x23 + */ +int unespcape(char *_dst, char *_src, size_t len) +{ + int ret = 0; + char *src = _src; + char *dst = _dst; + unsigned int ch; + + while (*src) { + if (*src == '\\' && *(src+1) == 'x') { + sscanf(src + 2, "%2x", &ch); + src += 4; + *dst++ = (unsigned char)ch; + } else { + *dst++ = *src++; + } + ret++; + } + return ret; +} + +static void transfer(int fd, uint8_t const *tx, uint8_t const *rx, size_t len) { int ret; - uint8_t tx[] = { - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0x40, 0x00, 0x00, 0x00, 0x00, 0x95, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xDE, 0xAD, 0xBE, 0xEF, 0xBA, 0xAD, - 0xF0, 0x0D, - }; - uint8_t rx[ARRAY_SIZE(tx)] = {0, }; + struct spi_ioc_transfer tr = { .tx_buf = (unsigned long)tx, .rx_buf = (unsigned long)rx, - .len = ARRAY_SIZE(tx), + .len = len, .delay_usecs = delay, .speed_hz = speed, .bits_per_word = bits, @@ -106,8 +133,8 @@ static void transfer(int fd) pabort("can't send spi message"); if (verbose) - hex_dump(tx, ARRAY_SIZE(tx), 32, "TX"); - hex_dump(rx, ARRAY_SIZE(rx), 32, "RX"); + hex_dump(tx, len, 32, "TX"); + hex_dump(rx, len, 32, "RX"); } static void print_usage(const char *prog) @@ -124,6 +151,7 @@ static void print_usage(const char *prog) " -C --cs-high chip select active high\n" " -3 --3wire SI/SO signals shared\n" " -v --verbose Verbose (show tx buffer)\n" + " -p Send data (e.g. \"1234\\xde\\xad\")\n" " -N --no-cs no chip select\n" " -R --ready slave pulls low to pause\n" " -2 --dual dual transfer\n" @@ -154,7 +182,7 @@ static void parse_opts(int argc, char *argv[]) }; int c; - c = getopt_long(argc, argv, "D:s:d:b:lHOLC3NR24:v", lopts, NULL); + c = getopt_long(argc, argv, "D:s:d:b:lHOLC3NR24p:v", lopts, NULL); if (c == -1) break; @@ -199,6 +227,9 @@ static void parse_opts(int argc, char *argv[]) case 'R': mode |= SPI_READY; break; + case 'p': + input_tx = optarg; + break; case '2': mode |= SPI_TX_DUAL; break; @@ -222,6 +253,9 @@ int main(int argc, char *argv[]) { int ret = 0; int fd; + uint8_t *tx; + uint8_t *rx; + int size; parse_opts(argc, argv); @@ -266,7 +300,17 @@ int main(int argc, char *argv[]) printf("bits per word: %d\n", bits); printf("max speed: %d Hz (%d KHz)\n", speed, speed/1000); - transfer(fd); + if (input_tx) { + size = strlen(input_tx+1); + tx = malloc(size); + rx = malloc(size); + size = unespcape((char *)tx, input_tx, size); + transfer(fd, tx, rx, size); + free(rx); + free(tx); + } else { + transfer(fd, default_tx, default_rx, sizeof(default_tx)); + } close(fd); -- GitLab From 7c6f3fdc488296ea00ded8024dcfd7de13d2ca67 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 10 Mar 2015 22:03:01 +0100 Subject: [PATCH 03842/11651] Staging: sm750fb: fix hw_imageblit parameters Fix up hw_imageblit() so that the function paramaters match up with what the driver expects them to be when using it as a function pointer. Cc: Sudip Mukherjee Cc: Teddy Wang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sm750fb/sm750_accel.c | 29 +++++++++++++-------------- drivers/staging/sm750fb/sm750_accel.h | 29 +++++++++++++-------------- 2 files changed, 28 insertions(+), 30 deletions(-) diff --git a/drivers/staging/sm750fb/sm750_accel.c b/drivers/staging/sm750fb/sm750_accel.c index ee211deb9975..6521c3b3bcdc 100644 --- a/drivers/staging/sm750fb/sm750_accel.c +++ b/drivers/staging/sm750fb/sm750_accel.c @@ -395,21 +395,20 @@ static unsigned int deGetTransparency(struct lynx_accel * accel) return de_ctrl; } -int hw_imageblit( -struct lynx_accel * accel, -unsigned char *pSrcbuf, /* pointer to start of source buffer in system memory */ -int srcDelta, /* Pitch value (in bytes) of the source buffer, +ive means top down and -ive mean button up */ -unsigned int startBit, /* Mono data can start at any bit in a byte, this value should be 0 to 7 */ -unsigned int dBase, /* Address of destination: offset in frame buffer */ -unsigned int dPitch, /* Pitch value of destination surface in BYTE */ -unsigned int bytePerPixel, /* Color depth of destination surface */ -unsigned int dx, -unsigned int dy, /* Starting coordinate of destination surface */ -unsigned int width, -unsigned int height, /* width and height of rectange in pixel value */ -unsigned int fColor, /* Foreground color (corresponding to a 1 in the monochrome data */ -unsigned int bColor, /* Background color (corresponding to a 0 in the monochrome data */ -unsigned int rop2) /* ROP value */ +int hw_imageblit(struct lynx_accel *accel, + const char *pSrcbuf, /* pointer to start of source buffer in system memory */ + u32 srcDelta, /* Pitch value (in bytes) of the source buffer, +ive means top down and -ive mean button up */ + u32 startBit, /* Mono data can start at any bit in a byte, this value should be 0 to 7 */ + u32 dBase, /* Address of destination: offset in frame buffer */ + u32 dPitch, /* Pitch value of destination surface in BYTE */ + u32 bytePerPixel, /* Color depth of destination surface */ + u32 dx, + u32 dy, /* Starting coordinate of destination surface */ + u32 width, + u32 height, /* width and height of rectange in pixel value */ + u32 fColor, /* Foreground color (corresponding to a 1 in the monochrome data */ + u32 bColor, /* Background color (corresponding to a 0 in the monochrome data */ + u32 rop2) /* ROP value */ { unsigned int ulBytesPerScan; unsigned int ul4BytesPerScan; diff --git a/drivers/staging/sm750fb/sm750_accel.h b/drivers/staging/sm750fb/sm750_accel.h index 575f4a7e38d4..3ee0bd89257b 100644 --- a/drivers/staging/sm750fb/sm750_accel.h +++ b/drivers/staging/sm750fb/sm750_accel.h @@ -258,19 +258,18 @@ unsigned int width, unsigned int height, /* width and height of rectangle in pixel value */ unsigned int rop2); -int hw_imageblit( -struct lynx_accel * accel, -unsigned char *pSrcbuf, /* pointer to start of source buffer in system memory */ -int srcDelta, /* Pitch value (in bytes) of the source buffer, +ive means top down and -ive mean button up */ -unsigned int startBit, /* Mono data can start at any bit in a byte, this value should be 0 to 7 */ -unsigned int dBase, /* Address of destination: offset in frame buffer */ -unsigned int dPitch, /* Pitch value of destination surface in BYTE */ -unsigned int bytePerPixel, /* Color depth of destination surface */ -unsigned int dx, -unsigned int dy, /* Starting coordinate of destination surface */ -unsigned int width, -unsigned int height, /* width and height of rectange in pixel value */ -unsigned int fColor, /* Foreground color (corresponding to a 1 in the monochrome data */ -unsigned int bColor, /* Background color (corresponding to a 0 in the monochrome data */ -unsigned int rop2); +int hw_imageblit(struct lynx_accel *accel, + const char *pSrcbuf, /* pointer to start of source buffer in system memory */ + u32 srcDelta, /* Pitch value (in bytes) of the source buffer, +ive means top down and -ive mean button up */ + u32 startBit, /* Mono data can start at any bit in a byte, this value should be 0 to 7 */ + u32 dBase, /* Address of destination: offset in frame buffer */ + u32 dPitch, /* Pitch value of destination surface in BYTE */ + u32 bytePerPixel, /* Color depth of destination surface */ + u32 dx, + u32 dy, /* Starting coordinate of destination surface */ + u32 width, + u32 height, /* width and height of rectange in pixel value */ + u32 fColor, /* Foreground color (corresponding to a 1 in the monochrome data */ + u32 bColor, /* Background color (corresponding to a 0 in the monochrome data */ + u32 rop2); #endif -- GitLab From e74ac550298ec4635cc32e99f966568a808fd370 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 10 Mar 2015 22:08:38 +0100 Subject: [PATCH 03843/11651] Staging: sm750fb: provide error path for hw_sm750le_setBLANK() This provides a default path for the switch statement in hw_sm750le_setBLANK() so that the compiler will not correctly complain about undefined values being sent to the hardware. Instead, properly error out if the blank command is unknown by the driver. Cc: Sudip Mukherjee Cc: Teddy Wang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sm750fb/sm750_hw.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/staging/sm750fb/sm750_hw.c b/drivers/staging/sm750fb/sm750_hw.c index a2b7fe219594..c44a50b0c489 100644 --- a/drivers/staging/sm750fb/sm750_hw.c +++ b/drivers/staging/sm750fb/sm750_hw.c @@ -472,6 +472,8 @@ int hw_sm750le_setBLANK(struct lynxfb_output * output,int blank){ dpms = CRT_DISPLAY_CTRL_DPMS_3; crtdb = CRT_DISPLAY_CTRL_BLANK_ON; break; + default: + return -EINVAL; } if(output->paths & sm750_crt){ -- GitLab From d0f347d62814ec0f599a05c61c5619d5e999e4ae Mon Sep 17 00:00:00 2001 From: David Dueck Date: Sun, 8 Feb 2015 16:29:30 +0100 Subject: [PATCH 03844/11651] usb: phy: am335x-control: check return value of bus_find_device This fixes a potential null pointer dereference. Cc: # v3.16+ Fixes: d4332013919a ("driver core: dev_get_drvdata: Don't check for NULL dev") Acked-by: Sebastian Andrzej Siewior Signed-off-by: David Dueck Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-am335x-control.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/phy/phy-am335x-control.c b/drivers/usb/phy/phy-am335x-control.c index 403fab772724..7b3035ff9434 100644 --- a/drivers/usb/phy/phy-am335x-control.c +++ b/drivers/usb/phy/phy-am335x-control.c @@ -126,6 +126,9 @@ struct phy_control *am335x_get_phy_control(struct device *dev) return NULL; dev = bus_find_device(&platform_bus_type, NULL, node, match); + if (!dev) + return NULL; + ctrl_usb = dev_get_drvdata(dev); if (!ctrl_usb) return NULL; -- GitLab From 416377ea392823e8ea1f8a10477e7d08a9bb715e Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 10 Mar 2015 18:33:49 -0400 Subject: [PATCH 03845/11651] macb: Fix merge error. The code removed by commit 421d9df0628b ("net/macb: merge at91_ether driver into macb driver") should be removed in the merge resolution as well. Signed-off-by: David S. Miller --- drivers/net/ethernet/cadence/macb.c | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c index f032e2a245b0..f00be585f661 100644 --- a/drivers/net/ethernet/cadence/macb.c +++ b/drivers/net/ethernet/cadence/macb.c @@ -2131,24 +2131,8 @@ static const struct net_device_ops macb_netdev_ops = { */ static void macb_configure_caps(struct macb *bp) { - const struct of_device_id *match; - const struct macb_config *config; u32 dcfg; - if (bp->pdev->dev.of_node) { - match = of_match_node(macb_dt_ids, bp->pdev->dev.of_node); - if (match && match->data) { - config = match->data; - - bp->caps = config->caps; - /* - * As we have access to the matching node, configure - * DMA burst length as well - */ - bp->dma_burst_length = config->dma_burst_length; - } - } - if (MACB_BFEXT(IDNUM, macb_readl(bp, MID)) == 0x2) bp->caps |= MACB_CAPS_MACB_IS_GEM; -- GitLab From ddb4b9a1328ea89733133e86cf1972d23891abfc Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 10 Mar 2015 14:39:34 -0700 Subject: [PATCH 03846/11651] fib_trie: Address possible NULL pointer dereference in resize If the inflate call failed it would return NULL. As a result tp would be set to NULL and cause use to trigger a NULL pointer dereference in should_halve if the inflate failed on the first attempt. In order to prevent this we should decrement max_work before we actually attempt to inflate as this will force us to exit before attempting to halve a node we should have inflated. In order to keep things symmetric between inflate and halve I went ahead and also moved the decrement of max_work for the halve case as well so we take care of that before we actually attempt to halve the tnode. Fixes: 88bae714 ("fib_trie: Add key vector to root, return parent key_vector in resize") Reported-by: Dan Carpenter Signed-off-by: Alexander Duyck Signed-off-by: David S. Miller --- net/ipv4/fib_trie.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 44cab1d41463..83290beaf7cf 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -830,7 +830,7 @@ static struct key_vector *resize(struct trie *t, struct key_vector *tn) /* Double as long as the resulting node has a number of * nonempty nodes that are above the threshold. */ - while (should_inflate(tp, tn) && max_work) { + while (should_inflate(tp, tn) && max_work--) { tp = inflate(t, tn); if (!tp) { #ifdef CONFIG_IP_FIB_TRIE_STATS @@ -839,7 +839,6 @@ static struct key_vector *resize(struct trie *t, struct key_vector *tn) break; } - max_work--; tn = get_child(tp, cindex); } @@ -850,7 +849,7 @@ static struct key_vector *resize(struct trie *t, struct key_vector *tn) /* Halve as long as the number of empty children in this * node is above threshold. */ - while (should_halve(tp, tn) && max_work) { + while (should_halve(tp, tn) && max_work--) { tp = halve(t, tn); if (!tp) { #ifdef CONFIG_IP_FIB_TRIE_STATS @@ -859,7 +858,6 @@ static struct key_vector *resize(struct trie *t, struct key_vector *tn) break; } - max_work--; tn = get_child(tp, cindex); } -- GitLab From 169bf9121b19dd6029e0a354d33513f61bfbe3d3 Mon Sep 17 00:00:00 2001 From: Jon Paul Maloy Date: Tue, 10 Mar 2015 12:23:34 -0400 Subject: [PATCH 03847/11651] tipc: ensure that idle links are deleted when a bearer is disabled commit afaa3f65f65fda2e7b190aac7e2a75d9a2a77cb6 (tipc: purge links when bearer is disabled) was an attempt to resolve a problem that turned out to have a more profound reason. When we disable a bearer, we delete all its pertaining links if there is no other bearer to perform failover to, or if the module is shutting down. In case there are dual bearers, we wait with deleting links until the failover procedure is finished. However, this misses the case when a link on the removed bearer was already down, so that there will be no failover procedure to finish the link delete. This causes confusion if a new bearer is added to replace the removed one, and also entails a small memory leak. This commit takes the current state of the link into account when deciding when to delete it, and also reverses the above-mentioned commit. Reviewed-by: Erik Hugne Signed-off-by: Jon Maloy Signed-off-by: David S. Miller --- net/tipc/bearer.c | 2 +- net/tipc/link.c | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index 840db89e4283..3613e72e858e 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c @@ -747,7 +747,7 @@ int tipc_nl_bearer_disable(struct sk_buff *skb, struct genl_info *info) return -EINVAL; } - bearer_disable(net, bearer, true); + bearer_disable(net, bearer, false); rtnl_unlock(); return 0; diff --git a/net/tipc/link.c b/net/tipc/link.c index 14f09b3cb87c..98609fdfb06a 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -344,6 +344,7 @@ void tipc_link_delete_list(struct net *net, unsigned int bearer_id, struct tipc_net *tn = net_generic(net, tipc_net_id); struct tipc_link *link; struct tipc_node *node; + bool del_link; rcu_read_lock(); list_for_each_entry_rcu(node, &tn->node_list, list) { @@ -353,12 +354,13 @@ void tipc_link_delete_list(struct net *net, unsigned int bearer_id, tipc_node_unlock(node); continue; } + del_link = !tipc_link_is_up(link) && !link->exp_msg_count; tipc_link_reset(link); if (del_timer(&link->timer)) tipc_link_put(link); link->flags |= LINK_STOPPED; /* Delete link now, or when failover is finished: */ - if (shutting_down || !tipc_node_is_up(node)) + if (shutting_down || !tipc_node_is_up(node) || del_link) tipc_link_delete(link); tipc_node_unlock(node); } -- GitLab From 5cb56059c94ddfaf92567a1c6443deec8363ae1c Mon Sep 17 00:00:00 2001 From: Joel Schopp Date: Mon, 2 Mar 2015 13:43:31 -0600 Subject: [PATCH 03848/11651] kvm: x86: make kvm_emulate_* consistant MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently kvm_emulate() skips the instruction but kvm_emulate_* sometimes don't. The end reult is the caller ends up doing the skip themselves. Let's make them consistant. Signed-off-by: Joel Schopp Reviewed-by: Radim Krčmář Signed-off-by: Marcelo Tosatti --- arch/x86/include/asm/kvm_host.h | 1 + arch/x86/kvm/svm.c | 2 -- arch/x86/kvm/vmx.c | 9 +++------ arch/x86/kvm/x86.c | 23 ++++++++++++++++++++--- 4 files changed, 24 insertions(+), 11 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index a236e39cc385..bf5a1606ccd5 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -933,6 +933,7 @@ struct x86_emulate_ctxt; int kvm_fast_pio_out(struct kvm_vcpu *vcpu, int size, unsigned short port); void kvm_emulate_cpuid(struct kvm_vcpu *vcpu); int kvm_emulate_halt(struct kvm_vcpu *vcpu); +int kvm_vcpu_halt(struct kvm_vcpu *vcpu); int kvm_emulate_wbinvd(struct kvm_vcpu *vcpu); void kvm_get_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg); diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 93dda3ccff03..16d6e5ca4c03 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -1929,14 +1929,12 @@ static int nop_on_interception(struct vcpu_svm *svm) static int halt_interception(struct vcpu_svm *svm) { svm->next_rip = kvm_rip_read(&svm->vcpu) + 1; - skip_emulated_instruction(&svm->vcpu); return kvm_emulate_halt(&svm->vcpu); } static int vmmcall_interception(struct vcpu_svm *svm) { svm->next_rip = kvm_rip_read(&svm->vcpu) + 3; - skip_emulated_instruction(&svm->vcpu); kvm_emulate_hypercall(&svm->vcpu); return 1; } diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index f7b20b417a3a..fbd949909628 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -5000,7 +5000,7 @@ static int handle_rmode_exception(struct kvm_vcpu *vcpu, if (emulate_instruction(vcpu, 0) == EMULATE_DONE) { if (vcpu->arch.halt_request) { vcpu->arch.halt_request = 0; - return kvm_emulate_halt(vcpu); + return kvm_vcpu_halt(vcpu); } return 1; } @@ -5527,13 +5527,11 @@ static int handle_interrupt_window(struct kvm_vcpu *vcpu) static int handle_halt(struct kvm_vcpu *vcpu) { - skip_emulated_instruction(vcpu); return kvm_emulate_halt(vcpu); } static int handle_vmcall(struct kvm_vcpu *vcpu) { - skip_emulated_instruction(vcpu); kvm_emulate_hypercall(vcpu); return 1; } @@ -5564,7 +5562,6 @@ static int handle_rdpmc(struct kvm_vcpu *vcpu) static int handle_wbinvd(struct kvm_vcpu *vcpu) { - skip_emulated_instruction(vcpu); kvm_emulate_wbinvd(vcpu); return 1; } @@ -5903,7 +5900,7 @@ static int handle_invalid_guest_state(struct kvm_vcpu *vcpu) if (vcpu->arch.halt_request) { vcpu->arch.halt_request = 0; - ret = kvm_emulate_halt(vcpu); + ret = kvm_vcpu_halt(vcpu); goto out; } @@ -9518,7 +9515,7 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch) vmcs12->launch_state = 1; if (vmcs12->guest_activity_state == GUEST_ACTIVITY_HLT) - return kvm_emulate_halt(vcpu); + return kvm_vcpu_halt(vcpu); vmx->nested.nested_run_pending = 1; diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index c5f7e035e0f1..d1a1feaa522b 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -4706,7 +4706,7 @@ static void emulator_invlpg(struct x86_emulate_ctxt *ctxt, ulong address) kvm_mmu_invlpg(emul_to_vcpu(ctxt), address); } -int kvm_emulate_wbinvd(struct kvm_vcpu *vcpu) +int kvm_emulate_wbinvd_noskip(struct kvm_vcpu *vcpu) { if (!need_emulate_wbinvd(vcpu)) return X86EMUL_CONTINUE; @@ -4723,11 +4723,19 @@ int kvm_emulate_wbinvd(struct kvm_vcpu *vcpu) wbinvd(); return X86EMUL_CONTINUE; } + +int kvm_emulate_wbinvd(struct kvm_vcpu *vcpu) +{ + kvm_x86_ops->skip_emulated_instruction(vcpu); + return kvm_emulate_wbinvd_noskip(vcpu); +} EXPORT_SYMBOL_GPL(kvm_emulate_wbinvd); + + static void emulator_wbinvd(struct x86_emulate_ctxt *ctxt) { - kvm_emulate_wbinvd(emul_to_vcpu(ctxt)); + kvm_emulate_wbinvd_noskip(emul_to_vcpu(ctxt)); } int emulator_get_dr(struct x86_emulate_ctxt *ctxt, int dr, unsigned long *dest) @@ -5817,7 +5825,7 @@ void kvm_arch_exit(void) free_percpu(shared_msrs); } -int kvm_emulate_halt(struct kvm_vcpu *vcpu) +int kvm_vcpu_halt(struct kvm_vcpu *vcpu) { ++vcpu->stat.halt_exits; if (irqchip_in_kernel(vcpu->kvm)) { @@ -5828,6 +5836,13 @@ int kvm_emulate_halt(struct kvm_vcpu *vcpu) return 0; } } +EXPORT_SYMBOL_GPL(kvm_vcpu_halt); + +int kvm_emulate_halt(struct kvm_vcpu *vcpu) +{ + kvm_x86_ops->skip_emulated_instruction(vcpu); + return kvm_vcpu_halt(vcpu); +} EXPORT_SYMBOL_GPL(kvm_emulate_halt); int kvm_hv_hypercall(struct kvm_vcpu *vcpu) @@ -5912,6 +5927,8 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu) unsigned long nr, a0, a1, a2, a3, ret; int op_64_bit, r = 1; + kvm_x86_ops->skip_emulated_instruction(vcpu); + if (kvm_hv_hypercall_enabled(vcpu->kvm)) return kvm_hv_hypercall(vcpu); -- GitLab From dab429a798a8ab3377136e09dda55ea75a41648d Mon Sep 17 00:00:00 2001 From: David Kaplan Date: Mon, 2 Mar 2015 13:43:37 -0600 Subject: [PATCH 03849/11651] kvm: svm: make wbinvd faster MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit No need to re-decode WBINVD since we know what it is from the intercept. Signed-off-by: David Kaplan [extracted from larger unlrelated patch, forward ported, tested,style cleanup] Signed-off-by: Joel Schopp Reviewed-by: Radim Krčmář Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/svm.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 16d6e5ca4c03..8f665851724f 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -2774,6 +2774,12 @@ static int skinit_interception(struct vcpu_svm *svm) return 1; } +static int wbinvd_interception(struct vcpu_svm *svm) +{ + kvm_emulate_wbinvd(&svm->vcpu); + return 1; +} + static int xsetbv_interception(struct vcpu_svm *svm) { u64 new_bv = kvm_read_edx_eax(&svm->vcpu); @@ -3373,7 +3379,7 @@ static int (*const svm_exit_handlers[])(struct vcpu_svm *svm) = { [SVM_EXIT_STGI] = stgi_interception, [SVM_EXIT_CLGI] = clgi_interception, [SVM_EXIT_SKINIT] = skinit_interception, - [SVM_EXIT_WBINVD] = emulate_on_interception, + [SVM_EXIT_WBINVD] = wbinvd_interception, [SVM_EXIT_MONITOR] = monitor_interception, [SVM_EXIT_MWAIT] = mwait_interception, [SVM_EXIT_XSETBV] = xsetbv_interception, -- GitLab From dc9be0fac70a2ad86e31a81372bb0bdfb6945353 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 5 Mar 2015 11:54:46 +0100 Subject: [PATCH 03850/11651] kvm: move advertising of KVM_CAP_IRQFD to common code POWER supports irqfds but forgot to advertise them. Some userspace does not check for the capability, but others check it---thus they work on x86 and s390 but not POWER. To avoid that other architectures in the future make the same mistake, let common code handle KVM_CAP_IRQFD the same way as KVM_CAP_IRQFD_RESAMPLE. Reported-and-tested-by: Greg Kurz Cc: stable@vger.kernel.org Fixes: 297e21053a52f060944e9f0de4c64fad9bcd72fc Signed-off-by: Paolo Bonzini Signed-off-by: Marcelo Tosatti --- arch/s390/kvm/kvm-s390.c | 1 - arch/x86/kvm/x86.c | 1 - virt/kvm/kvm_main.c | 1 + 3 files changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index f6579cfde2df..19e17bd7aec0 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -165,7 +165,6 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) case KVM_CAP_ONE_REG: case KVM_CAP_ENABLE_CAP: case KVM_CAP_S390_CSS_SUPPORT: - case KVM_CAP_IRQFD: case KVM_CAP_IOEVENTFD: case KVM_CAP_DEVICE_CTRL: case KVM_CAP_ENABLE_CAP_VM: diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index bd7a70be41b3..32bf19ef3115 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -2744,7 +2744,6 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) case KVM_CAP_USER_NMI: case KVM_CAP_REINJECT_CONTROL: case KVM_CAP_IRQ_INJECT_STATUS: - case KVM_CAP_IRQFD: case KVM_CAP_IOEVENTFD: case KVM_CAP_IOEVENTFD_NO_LENGTH: case KVM_CAP_PIT2: diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index a1093700f3a4..a2214d9609bd 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -2492,6 +2492,7 @@ static long kvm_vm_ioctl_check_extension_generic(struct kvm *kvm, long arg) case KVM_CAP_SIGNAL_MSI: #endif #ifdef CONFIG_HAVE_KVM_IRQFD + case KVM_CAP_IRQFD: case KVM_CAP_IRQFD_RESAMPLE: #endif case KVM_CAP_CHECK_EXTENSION_VM: -- GitLab From 46a158f2ce965940f68ccb07ac8127e1091bebe8 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 10 Mar 2015 01:39:01 +0000 Subject: [PATCH 03851/11651] ARM: shmobile: r8a7790: add reg-names for sound Rensas R-Car sound driver supports reg-names. Let's use it. Signed-off-by: Kuninori Morimoto Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7790.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi index b3202526b62c..2041ec7cdd04 100644 --- a/arch/arm/boot/dts/r8a7790.dtsi +++ b/arch/arm/boot/dts/r8a7790.dtsi @@ -1461,6 +1461,8 @@ <0 0xec5a0000 0 0x100>, /* ADG */ <0 0xec540000 0 0x1000>, /* SSIU */ <0 0xec541000 0 0x1280>; /* SSI */ + reg-names = "scu", "adg", "ssiu", "ssi"; + clocks = <&mstp10_clks R8A7790_CLK_SSI_ALL>, <&mstp10_clks R8A7790_CLK_SSI9>, <&mstp10_clks R8A7790_CLK_SSI8>, <&mstp10_clks R8A7790_CLK_SSI7>, <&mstp10_clks R8A7790_CLK_SSI6>, -- GitLab From d88a6a2a2184b0f58c42dfda77fdda87ab28b6aa Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 10 Mar 2015 01:39:18 +0000 Subject: [PATCH 03852/11651] ARM: shmobile: r8a7791: add reg-names for sound Rensas R-Car sound driver supports reg-names. Let's use it. Signed-off-by: Kuninori Morimoto Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7791.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi index e899f79253fe..8631e023751e 100644 --- a/arch/arm/boot/dts/r8a7791.dtsi +++ b/arch/arm/boot/dts/r8a7791.dtsi @@ -1504,6 +1504,8 @@ <0 0xec5a0000 0 0x100>, /* ADG */ <0 0xec540000 0 0x1000>, /* SSIU */ <0 0xec541000 0 0x1280>; /* SSI */ + reg-names = "scu", "adg", "ssiu", "ssi"; + clocks = <&mstp10_clks R8A7791_CLK_SSI_ALL>, <&mstp10_clks R8A7791_CLK_SSI9>, <&mstp10_clks R8A7791_CLK_SSI8>, <&mstp10_clks R8A7791_CLK_SSI7>, <&mstp10_clks R8A7791_CLK_SSI6>, -- GitLab From 0c60267702244b8a6e62743a8e13a07823efbf6d Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 10 Mar 2015 01:39:39 +0000 Subject: [PATCH 03853/11651] ARM: shmobile: r8a7790: enable Audio DMAC peri peri via sound driver Audio DMAC peri peri is no longer DMAEngine. it is supported by sound driver. this patch enable it. Signed-off-by: Kuninori Morimoto Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7790.dtsi | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi index 2041ec7cdd04..48d11e0ee088 100644 --- a/arch/arm/boot/dts/r8a7790.dtsi +++ b/arch/arm/boot/dts/r8a7790.dtsi @@ -370,13 +370,6 @@ dma-channels = <13>; }; - audmapp: dma-controller@ec740000 { - compatible = "renesas,rcar-audmapp"; - #dma-cells = <1>; - - reg = <0 0xec740000 0 0x200>; - }; - i2c0: i2c@e6508000 { #address-cells = <1>; #size-cells = <0>; @@ -1460,8 +1453,9 @@ reg = <0 0xec500000 0 0x1000>, /* SCU */ <0 0xec5a0000 0 0x100>, /* ADG */ <0 0xec540000 0 0x1000>, /* SSIU */ - <0 0xec541000 0 0x1280>; /* SSI */ - reg-names = "scu", "adg", "ssiu", "ssi"; + <0 0xec541000 0 0x1280>, /* SSI */ + <0 0xec740000 0 0x200>; /* Audio DMAC peri peri*/ + reg-names = "scu", "adg", "ssiu", "ssi", "audmapp"; clocks = <&mstp10_clks R8A7790_CLK_SSI_ALL>, <&mstp10_clks R8A7790_CLK_SSI9>, <&mstp10_clks R8A7790_CLK_SSI8>, -- GitLab From d73a5013ed61bc605374f72ce879a358feba7f3e Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 10 Mar 2015 01:39:55 +0000 Subject: [PATCH 03854/11651] ARM: shmobile: r8a7791: enable Audio DMAC peri peri via sound driver Audio DMAC peri peri is no longer DMAEngine. it is supported by sound driver. this patch enable it. Signed-off-by: Kuninori Morimoto Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7791.dtsi | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi index 8631e023751e..a697b94525b6 100644 --- a/arch/arm/boot/dts/r8a7791.dtsi +++ b/arch/arm/boot/dts/r8a7791.dtsi @@ -357,13 +357,6 @@ dma-channels = <13>; }; - audmapp: dma-controller@ec740000 { - compatible = "renesas,rcar-audmapp"; - #dma-cells = <1>; - - reg = <0 0xec740000 0 0x200>; - }; - /* The memory map in the User's Manual maps the cores to bus numbers */ i2c0: i2c@e6508000 { #address-cells = <1>; @@ -1503,8 +1496,9 @@ reg = <0 0xec500000 0 0x1000>, /* SCU */ <0 0xec5a0000 0 0x100>, /* ADG */ <0 0xec540000 0 0x1000>, /* SSIU */ - <0 0xec541000 0 0x1280>; /* SSI */ - reg-names = "scu", "adg", "ssiu", "ssi"; + <0 0xec541000 0 0x1280>, /* SSI */ + <0 0xec740000 0 0x200>; /* Audio DMAC peri peri*/ + reg-names = "scu", "adg", "ssiu", "ssi", "audmapp"; clocks = <&mstp10_clks R8A7791_CLK_SSI_ALL>, <&mstp10_clks R8A7791_CLK_SSI9>, <&mstp10_clks R8A7791_CLK_SSI8>, -- GitLab From 118a509374f7791feee309946abccf2ce5609f16 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 10 Mar 2015 01:40:13 +0000 Subject: [PATCH 03855/11651] ARM: shmobile: r8a7790: sound enables Audio DMAC entry on DTSI This patch adds Audio DMAC (= rcar-dmac) entry for sound Signed-off-by: Kuninori Morimoto Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7790.dtsi | 130 +++++++++++++++++++++++++++------ 1 file changed, 108 insertions(+), 22 deletions(-) diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi index 48d11e0ee088..4bb2f4c17321 100644 --- a/arch/arm/boot/dts/r8a7790.dtsi +++ b/arch/arm/boot/dts/r8a7790.dtsi @@ -1481,34 +1481,120 @@ status = "disabled"; rcar_sound,dvc { - dvc0: dvc@0 { }; - dvc1: dvc@1 { }; + dvc0: dvc@0 { + dmas = <&audma0 0xbc>; + dma-names = "tx"; + }; + dvc1: dvc@1 { + dmas = <&audma0 0xbe>; + dma-names = "tx"; + }; }; rcar_sound,src { - src0: src@0 { interrupts = <0 352 IRQ_TYPE_LEVEL_HIGH>; }; - src1: src@1 { interrupts = <0 353 IRQ_TYPE_LEVEL_HIGH>; }; - src2: src@2 { interrupts = <0 354 IRQ_TYPE_LEVEL_HIGH>; }; - src3: src@3 { interrupts = <0 355 IRQ_TYPE_LEVEL_HIGH>; }; - src4: src@4 { interrupts = <0 356 IRQ_TYPE_LEVEL_HIGH>; }; - src5: src@5 { interrupts = <0 357 IRQ_TYPE_LEVEL_HIGH>; }; - src6: src@6 { interrupts = <0 358 IRQ_TYPE_LEVEL_HIGH>; }; - src7: src@7 { interrupts = <0 359 IRQ_TYPE_LEVEL_HIGH>; }; - src8: src@8 { interrupts = <0 360 IRQ_TYPE_LEVEL_HIGH>; }; - src9: src@9 { interrupts = <0 361 IRQ_TYPE_LEVEL_HIGH>; }; + src0: src@0 { + interrupts = <0 352 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x85>, <&audma1 0x9a>; + dma-names = "rx", "tx"; + }; + src1: src@1 { + interrupts = <0 353 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x87>, <&audma1 0x9c>; + dma-names = "rx", "tx"; + }; + src2: src@2 { + interrupts = <0 354 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x89>, <&audma1 0x9e>; + dma-names = "rx", "tx"; + }; + src3: src@3 { + interrupts = <0 355 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x8b>, <&audma1 0xa0>; + dma-names = "rx", "tx"; + }; + src4: src@4 { + interrupts = <0 356 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x8d>, <&audma1 0xb0>; + dma-names = "rx", "tx"; + }; + src5: src@5 { + interrupts = <0 357 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x8f>, <&audma1 0xb2>; + dma-names = "rx", "tx"; + }; + src6: src@6 { + interrupts = <0 358 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x91>, <&audma1 0xb4>; + dma-names = "rx", "tx"; + }; + src7: src@7 { + interrupts = <0 359 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x93>, <&audma1 0xb6>; + dma-names = "rx", "tx"; + }; + src8: src@8 { + interrupts = <0 360 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x95>, <&audma1 0xb8>; + dma-names = "rx", "tx"; + }; + src9: src@9 { + interrupts = <0 361 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x97>, <&audma1 0xba>; + dma-names = "rx", "tx"; + }; }; rcar_sound,ssi { - ssi0: ssi@0 { interrupts = <0 370 IRQ_TYPE_LEVEL_HIGH>; }; - ssi1: ssi@1 { interrupts = <0 371 IRQ_TYPE_LEVEL_HIGH>; }; - ssi2: ssi@2 { interrupts = <0 372 IRQ_TYPE_LEVEL_HIGH>; }; - ssi3: ssi@3 { interrupts = <0 373 IRQ_TYPE_LEVEL_HIGH>; }; - ssi4: ssi@4 { interrupts = <0 374 IRQ_TYPE_LEVEL_HIGH>; }; - ssi5: ssi@5 { interrupts = <0 375 IRQ_TYPE_LEVEL_HIGH>; }; - ssi6: ssi@6 { interrupts = <0 376 IRQ_TYPE_LEVEL_HIGH>; }; - ssi7: ssi@7 { interrupts = <0 377 IRQ_TYPE_LEVEL_HIGH>; }; - ssi8: ssi@8 { interrupts = <0 378 IRQ_TYPE_LEVEL_HIGH>; }; - ssi9: ssi@9 { interrupts = <0 379 IRQ_TYPE_LEVEL_HIGH>; }; + ssi0: ssi@0 { + interrupts = <0 370 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x01>, <&audma1 0x02>, <&audma0 0x15>, <&audma1 0x16>; + dma-names = "rx", "tx", "rxu", "txu"; + }; + ssi1: ssi@1 { + interrupts = <0 371 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x03>, <&audma1 0x04>, <&audma0 0x49>, <&audma1 0x4a>; + dma-names = "rx", "tx", "rxu", "txu"; + }; + ssi2: ssi@2 { + interrupts = <0 372 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x05>, <&audma1 0x06>, <&audma0 0x63>, <&audma1 0x64>; + dma-names = "rx", "tx", "rxu", "txu"; + }; + ssi3: ssi@3 { + interrupts = <0 373 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x07>, <&audma1 0x08>, <&audma0 0x6f>, <&audma1 0x70>; + dma-names = "rx", "tx", "rxu", "txu"; + }; + ssi4: ssi@4 { + interrupts = <0 374 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x09>, <&audma1 0x0a>, <&audma0 0x71>, <&audma1 0x72>; + dma-names = "rx", "tx", "rxu", "txu"; + }; + ssi5: ssi@5 { + interrupts = <0 375 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x0b>, <&audma1 0x0c>, <&audma0 0x73>, <&audma1 0x74>; + dma-names = "rx", "tx", "rxu", "txu"; + }; + ssi6: ssi@6 { + interrupts = <0 376 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x0d>, <&audma1 0x0e>, <&audma0 0x75>, <&audma1 0x76>; + dma-names = "rx", "tx", "rxu", "txu"; + }; + ssi7: ssi@7 { + interrupts = <0 377 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x0f>, <&audma1 0x10>, <&audma0 0x79>, <&audma1 0x7a>; + dma-names = "rx", "tx", "rxu", "txu"; + }; + ssi8: ssi@8 { + interrupts = <0 378 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x11>, <&audma1 0x12>, <&audma0 0x7b>, <&audma1 0x7c>; + dma-names = "rx", "tx", "rxu", "txu"; + }; + ssi9: ssi@9 { + interrupts = <0 379 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x13>, <&audma1 0x14>, <&audma0 0x7d>, <&audma1 0x7e>; + dma-names = "rx", "tx", "rxu", "txu"; + }; }; }; -- GitLab From 63573339e7698503bfeaef3bb0c444ffc98e45a0 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 10 Mar 2015 01:40:27 +0000 Subject: [PATCH 03856/11651] ARM: shmobile: r8a7791: sound enables Audio DMAC entry on DTSI This patch adds Audio DMAC (= rcar-dmac) entry for sound Signed-off-by: Kuninori Morimoto Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7791.dtsi | 130 +++++++++++++++++++++++++++------ 1 file changed, 108 insertions(+), 22 deletions(-) diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi index a697b94525b6..4696062f6dde 100644 --- a/arch/arm/boot/dts/r8a7791.dtsi +++ b/arch/arm/boot/dts/r8a7791.dtsi @@ -1524,34 +1524,120 @@ status = "disabled"; rcar_sound,dvc { - dvc0: dvc@0 { }; - dvc1: dvc@1 { }; + dvc0: dvc@0 { + dmas = <&audma0 0xbc>; + dma-names = "tx"; + }; + dvc1: dvc@1 { + dmas = <&audma0 0xbe>; + dma-names = "tx"; + }; }; rcar_sound,src { - src0: src@0 { interrupts = <0 352 IRQ_TYPE_LEVEL_HIGH>; }; - src1: src@1 { interrupts = <0 353 IRQ_TYPE_LEVEL_HIGH>; }; - src2: src@2 { interrupts = <0 354 IRQ_TYPE_LEVEL_HIGH>; }; - src3: src@3 { interrupts = <0 355 IRQ_TYPE_LEVEL_HIGH>; }; - src4: src@4 { interrupts = <0 356 IRQ_TYPE_LEVEL_HIGH>; }; - src5: src@5 { interrupts = <0 357 IRQ_TYPE_LEVEL_HIGH>; }; - src6: src@6 { interrupts = <0 358 IRQ_TYPE_LEVEL_HIGH>; }; - src7: src@7 { interrupts = <0 359 IRQ_TYPE_LEVEL_HIGH>; }; - src8: src@8 { interrupts = <0 360 IRQ_TYPE_LEVEL_HIGH>; }; - src9: src@9 { interrupts = <0 361 IRQ_TYPE_LEVEL_HIGH>; }; + src0: src@0 { + interrupts = <0 352 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x85>, <&audma1 0x9a>; + dma-names = "rx", "tx"; + }; + src1: src@1 { + interrupts = <0 353 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x87>, <&audma1 0x9c>; + dma-names = "rx", "tx"; + }; + src2: src@2 { + interrupts = <0 354 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x89>, <&audma1 0x9e>; + dma-names = "rx", "tx"; + }; + src3: src@3 { + interrupts = <0 355 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x8b>, <&audma1 0xa0>; + dma-names = "rx", "tx"; + }; + src4: src@4 { + interrupts = <0 356 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x8d>, <&audma1 0xb0>; + dma-names = "rx", "tx"; + }; + src5: src@5 { + interrupts = <0 357 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x8f>, <&audma1 0xb2>; + dma-names = "rx", "tx"; + }; + src6: src@6 { + interrupts = <0 358 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x91>, <&audma1 0xb4>; + dma-names = "rx", "tx"; + }; + src7: src@7 { + interrupts = <0 359 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x93>, <&audma1 0xb6>; + dma-names = "rx", "tx"; + }; + src8: src@8 { + interrupts = <0 360 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x95>, <&audma1 0xb8>; + dma-names = "rx", "tx"; + }; + src9: src@9 { + interrupts = <0 361 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x97>, <&audma1 0xba>; + dma-names = "rx", "tx"; + }; }; rcar_sound,ssi { - ssi0: ssi@0 { interrupts = <0 370 IRQ_TYPE_LEVEL_HIGH>; }; - ssi1: ssi@1 { interrupts = <0 371 IRQ_TYPE_LEVEL_HIGH>; }; - ssi2: ssi@2 { interrupts = <0 372 IRQ_TYPE_LEVEL_HIGH>; }; - ssi3: ssi@3 { interrupts = <0 373 IRQ_TYPE_LEVEL_HIGH>; }; - ssi4: ssi@4 { interrupts = <0 374 IRQ_TYPE_LEVEL_HIGH>; }; - ssi5: ssi@5 { interrupts = <0 375 IRQ_TYPE_LEVEL_HIGH>; }; - ssi6: ssi@6 { interrupts = <0 376 IRQ_TYPE_LEVEL_HIGH>; }; - ssi7: ssi@7 { interrupts = <0 377 IRQ_TYPE_LEVEL_HIGH>; }; - ssi8: ssi@8 { interrupts = <0 378 IRQ_TYPE_LEVEL_HIGH>; }; - ssi9: ssi@9 { interrupts = <0 379 IRQ_TYPE_LEVEL_HIGH>; }; + ssi0: ssi@0 { + interrupts = <0 370 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x01>, <&audma1 0x02>, <&audma0 0x15>, <&audma1 0x16>; + dma-names = "rx", "tx", "rxu", "txu"; + }; + ssi1: ssi@1 { + interrupts = <0 371 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x03>, <&audma1 0x04>, <&audma0 0x49>, <&audma1 0x4a>; + dma-names = "rx", "tx", "rxu", "txu"; + }; + ssi2: ssi@2 { + interrupts = <0 372 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x05>, <&audma1 0x06>, <&audma0 0x63>, <&audma1 0x64>; + dma-names = "rx", "tx", "rxu", "txu"; + }; + ssi3: ssi@3 { + interrupts = <0 373 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x07>, <&audma1 0x08>, <&audma0 0x6f>, <&audma1 0x70>; + dma-names = "rx", "tx", "rxu", "txu"; + }; + ssi4: ssi@4 { + interrupts = <0 374 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x09>, <&audma1 0x0a>, <&audma0 0x71>, <&audma1 0x72>; + dma-names = "rx", "tx", "rxu", "txu"; + }; + ssi5: ssi@5 { + interrupts = <0 375 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x0b>, <&audma1 0x0c>, <&audma0 0x73>, <&audma1 0x74>; + dma-names = "rx", "tx", "rxu", "txu"; + }; + ssi6: ssi@6 { + interrupts = <0 376 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x0d>, <&audma1 0x0e>, <&audma0 0x75>, <&audma1 0x76>; + dma-names = "rx", "tx", "rxu", "txu"; + }; + ssi7: ssi@7 { + interrupts = <0 377 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x0f>, <&audma1 0x10>, <&audma0 0x79>, <&audma1 0x7a>; + dma-names = "rx", "tx", "rxu", "txu"; + }; + ssi8: ssi@8 { + interrupts = <0 378 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x11>, <&audma1 0x12>, <&audma0 0x7b>, <&audma1 0x7c>; + dma-names = "rx", "tx", "rxu", "txu"; + }; + ssi9: ssi@9 { + interrupts = <0 379 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x13>, <&audma1 0x14>, <&audma0 0x7d>, <&audma1 0x7e>; + dma-names = "rx", "tx", "rxu", "txu"; + }; }; }; }; -- GitLab From 663fbb52159cca6ffb049cb15b9f9d1cd7ad7d8a Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 9 Mar 2015 20:50:40 +0100 Subject: [PATCH 03857/11651] ARM: shmobile: R-Car Gen2: Add da9063/da9210 regulator quirk The r8a7790/lager and r8a7791/koelsch development boards have da9063 and da9210 regulators. Both regulators have their interrupt request lines tied to the same interrupt pin (IRQ2) on the SoC. After cold boot or da9063-induced restart, both the da9063 and da9210 seem to assert their interrupt request lines. Hence as soon as one driver requests this irq, it gets stuck in an interrupt storm, as it only manages to deassert its own interrupt request line, and the other driver hasn't installed an interrupt handler yet. To handle this, install a quirk that masks the interrupts in both the da9063 and da9210. This quirk has to run after the i2c master driver has been initialized, but before the i2c slave drivers are initialized. As it depends on i2c, select I2C if one of the affected platforms is enabled in the kernel config. On koelsch, the following happens: - Cold boot or reboot using the da9063 restart handler: IRQ2 is asserted, installing da9063/da9210 regulator quirk ... i2c i2c-6: regulator_quirk_notify: 1, IRQC_MONITOR = 0x3fb i2c 6-0058: regulator_quirk_notify: 1, IRQC_MONITOR = 0x3fb i2c 6-0058: Detected da9063 i2c 6-0058: Masking da9063 interrupt sources i2c 6-0068: regulator_quirk_notify: 1, IRQC_MONITOR = 0x3fb i2c 6-0068: Detected da9210 i2c 6-0068: Masking da9210 interrupt sources i2c 6-0068: IRQ2 is not asserted, removing quirk - Warm boot (reset button): rcar_gen2_regulator_quirk: IRQ2 is not asserted, not installing quirk Signed-off-by: Geert Uytterhoeven Tested-by: Wolfram Sang Reviewed-by: Mark Brown Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/Kconfig | 2 + arch/arm/mach-shmobile/Makefile | 2 + .../mach-shmobile/regulator-quirk-rcar-gen2.c | 147 ++++++++++++++++++ 3 files changed, 151 insertions(+) create mode 100644 arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig index 2f36c85eec4b..347b6a58fc3e 100644 --- a/arch/arm/mach-shmobile/Kconfig +++ b/arch/arm/mach-shmobile/Kconfig @@ -69,10 +69,12 @@ config ARCH_R8A7779 config ARCH_R8A7790 bool "R-Car H2 (R8A77900)" select ARCH_RCAR_GEN2 + select I2C config ARCH_R8A7791 bool "R-Car M2-W (R8A77910)" select ARCH_RCAR_GEN2 + select I2C config ARCH_R8A7794 bool "R-Car E2 (R8A77940)" diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile index d53996e6da97..fb9ef904f4b5 100644 --- a/arch/arm/mach-shmobile/Makefile +++ b/arch/arm/mach-shmobile/Makefile @@ -35,6 +35,8 @@ cpu-y := platsmp.o headsmp.o # Shared SoC family objects obj-$(CONFIG_ARCH_RCAR_GEN2) += setup-rcar-gen2.o platsmp-apmu.o $(cpu-y) CFLAGS_setup-rcar-gen2.o += -march=armv7-a +obj-$(CONFIG_ARCH_R8A7790) += regulator-quirk-rcar-gen2.o +obj-$(CONFIG_ARCH_R8A7791) += regulator-quirk-rcar-gen2.o # SMP objects smp-y := $(cpu-y) diff --git a/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c b/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c new file mode 100644 index 000000000000..384e6e934b87 --- /dev/null +++ b/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c @@ -0,0 +1,147 @@ +/* + * R-Car Generation 2 da9063/da9210 regulator quirk + * + * The r8a7790/lager and r8a7791/koelsch development boards have da9063 and + * da9210 regulators. Both regulators have their interrupt request lines tied + * to the same interrupt pin (IRQ2) on the SoC. + * + * After cold boot or da9063-induced restart, both the da9063 and da9210 seem + * to assert their interrupt request lines. Hence as soon as one driver + * requests this irq, it gets stuck in an interrupt storm, as it only manages + * to deassert its own interrupt request line, and the other driver hasn't + * installed an interrupt handler yet. + * + * To handle this, install a quirk that masks the interrupts in both the + * da9063 and da9210. This quirk has to run after the i2c master driver has + * been initialized, but before the i2c slave drivers are initialized. + * + * Copyright (C) 2015 Glider bvba + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * 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 +#include +#include +#include +#include +#include +#include + + +#define IRQC_BASE 0xe61c0000 +#define IRQC_MONITOR 0x104 /* IRQn Signal Level Monitor Register */ + +#define REGULATOR_IRQ_MASK BIT(2) /* IRQ2, active low */ + +static void __iomem *irqc; + +static const u8 da9063_mask_regs[] = { + DA9063_REG_IRQ_MASK_A, + DA9063_REG_IRQ_MASK_B, + DA9063_REG_IRQ_MASK_C, + DA9063_REG_IRQ_MASK_D, +}; + +/* DA9210 System Control and Event Registers */ +#define DA9210_REG_MASK_A 0x54 +#define DA9210_REG_MASK_B 0x55 + +static const u8 da9210_mask_regs[] = { + DA9210_REG_MASK_A, + DA9210_REG_MASK_B, +}; + +static void da9xxx_mask_irqs(struct i2c_client *client, const u8 regs[], + unsigned int nregs) +{ + unsigned int i; + + dev_info(&client->dev, "Masking %s interrupt sources\n", client->name); + + for (i = 0; i < nregs; i++) { + int error = i2c_smbus_write_byte_data(client, regs[i], ~0); + if (error) { + dev_err(&client->dev, "i2c error %d\n", error); + return; + } + } +} + +static int regulator_quirk_notify(struct notifier_block *nb, + unsigned long action, void *data) +{ + struct device *dev = data; + struct i2c_client *client; + u32 mon; + + mon = ioread32(irqc + IRQC_MONITOR); + dev_dbg(dev, "%s: %ld, IRQC_MONITOR = 0x%x\n", __func__, action, mon); + if (mon & REGULATOR_IRQ_MASK) + goto remove; + + if (action != BUS_NOTIFY_ADD_DEVICE || dev->type == &i2c_adapter_type) + return 0; + + client = to_i2c_client(dev); + dev_dbg(dev, "Detected %s\n", client->name); + + if ((client->addr == 0x58 && !strcmp(client->name, "da9063"))) + da9xxx_mask_irqs(client, da9063_mask_regs, + ARRAY_SIZE(da9063_mask_regs)); + else if (client->addr == 0x68 && !strcmp(client->name, "da9210")) + da9xxx_mask_irqs(client, da9210_mask_regs, + ARRAY_SIZE(da9210_mask_regs)); + + mon = ioread32(irqc + IRQC_MONITOR); + if (mon & REGULATOR_IRQ_MASK) + goto remove; + + return 0; + +remove: + dev_info(dev, "IRQ2 is not asserted, removing quirk\n"); + + bus_unregister_notifier(&i2c_bus_type, nb); + iounmap(irqc); + return 0; +} + +static struct notifier_block regulator_quirk_nb = { + .notifier_call = regulator_quirk_notify +}; + +static int __init rcar_gen2_regulator_quirk(void) +{ + u32 mon; + + if (!of_machine_is_compatible("renesas,koelsch") && + !of_machine_is_compatible("renesas,lager")) + return -ENODEV; + + irqc = ioremap(IRQC_BASE, PAGE_SIZE); + if (!irqc) + return -ENOMEM; + + mon = ioread32(irqc + IRQC_MONITOR); + if (mon & REGULATOR_IRQ_MASK) { + pr_debug("%s: IRQ2 is not asserted, not installing quirk\n", + __func__); + iounmap(irqc); + return 0; + } + + pr_info("IRQ2 is asserted, installing da9063/da9210 regulator quirk\n"); + + bus_register_notifier(&i2c_bus_type, ®ulator_quirk_nb); + return 0; +} + +arch_initcall(rcar_gen2_regulator_quirk); -- GitLab From 4be7338df39037266da832f6598557cc4ca3de10 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 9 Mar 2015 21:06:54 +0100 Subject: [PATCH 03858/11651] ARM: shmobile: koelsch dts: Add da9210 regulator interrupt The da9210 regulator is connected to IRQ2. Reflect this in its device node, so the driver can use it when it gains interrupt support. Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7791-koelsch.dts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/boot/dts/r8a7791-koelsch.dts b/arch/arm/boot/dts/r8a7791-koelsch.dts index a3c27807f6c5..213a643c27ae 100644 --- a/arch/arm/boot/dts/r8a7791-koelsch.dts +++ b/arch/arm/boot/dts/r8a7791-koelsch.dts @@ -520,6 +520,8 @@ vdd_dvfs: regulator@68 { compatible = "dlg,da9210"; reg = <0x68>; + interrupt-parent = <&irqc0>; + interrupts = <2 IRQ_TYPE_LEVEL_LOW>; regulator-min-microvolt = <1000000>; regulator-max-microvolt = <1000000>; -- GitLab From a6b422664597d7b9ca6cf441bc48cfe1a707cd3a Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 9 Mar 2015 21:06:55 +0100 Subject: [PATCH 03859/11651] ARM: shmobile: koelsch: Add da9063 PMIC device node for system restart Add a device node for the da9063 PMIC, with subnodes for rtc and wdt. Regulator support is not yet included. This allows the system to be restarted when the watchdog timer times out, or when a system restart is requested. Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7791-koelsch.dts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/arch/arm/boot/dts/r8a7791-koelsch.dts b/arch/arm/boot/dts/r8a7791-koelsch.dts index 213a643c27ae..b2dcf640d583 100644 --- a/arch/arm/boot/dts/r8a7791-koelsch.dts +++ b/arch/arm/boot/dts/r8a7791-koelsch.dts @@ -517,6 +517,22 @@ status = "okay"; clock-frequency = <100000>; + pmic@58 { + compatible = "dlg,da9063"; + reg = <0x58>; + interrupt-parent = <&irqc0>; + interrupts = <2 IRQ_TYPE_LEVEL_LOW>; + interrupt-controller; + + rtc { + compatible = "dlg,da9063-rtc"; + }; + + wdt { + compatible = "dlg,da9063-watchdog"; + }; + }; + vdd_dvfs: regulator@68 { compatible = "dlg,da9210"; reg = <0x68>; -- GitLab From ceb7747993adcc40581629e4abb0d9ea7853e857 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 9 Mar 2015 21:06:56 +0100 Subject: [PATCH 03860/11651] ARM: shmobile: lager dts: Add da9210 regulator interrupt The da9210 regulator is connected to IRQ2. Reflect this in its device node, so the driver can use it when it gains interrupt support. Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7790-lager.dts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/boot/dts/r8a7790-lager.dts b/arch/arm/boot/dts/r8a7790-lager.dts index 0c3b6783b72a..e2f47464f023 100644 --- a/arch/arm/boot/dts/r8a7790-lager.dts +++ b/arch/arm/boot/dts/r8a7790-lager.dts @@ -516,6 +516,8 @@ vdd_dvfs: regulator@68 { compatible = "dlg,da9210"; reg = <0x68>; + interrupt-parent = <&irqc0>; + interrupts = <2 IRQ_TYPE_LEVEL_LOW>; regulator-min-microvolt = <1000000>; regulator-max-microvolt = <1000000>; -- GitLab From 46dd8a809effdc7ebe6ec760e3e421d5ac2a40f1 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 9 Mar 2015 21:06:57 +0100 Subject: [PATCH 03861/11651] ARM: shmobile: lager: Add da9063 PMIC device node for system restart Add a device node for the da9063 PMIC, with subnodes for rtc and wdt. Regulator support is not yet included. This allows the system to be restarted when the watchdog timer times out, or when a system restart is requested. Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7790-lager.dts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/arch/arm/boot/dts/r8a7790-lager.dts b/arch/arm/boot/dts/r8a7790-lager.dts index e2f47464f023..2a0f895c48d0 100644 --- a/arch/arm/boot/dts/r8a7790-lager.dts +++ b/arch/arm/boot/dts/r8a7790-lager.dts @@ -513,6 +513,22 @@ pinctrl-0 = <&iic3_pins>; status = "okay"; + pmic@58 { + compatible = "dlg,da9063"; + reg = <0x58>; + interrupt-parent = <&irqc0>; + interrupts = <2 IRQ_TYPE_LEVEL_LOW>; + interrupt-controller; + + rtc { + compatible = "dlg,da9063-rtc"; + }; + + wdt { + compatible = "dlg,da9063-watchdog"; + }; + }; + vdd_dvfs: regulator@68 { compatible = "dlg,da9210"; reg = <0x68>; -- GitLab From 58e4a668be82362c32577ef08e06c8a292e3a457 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Mon, 23 Feb 2015 18:40:11 +0100 Subject: [PATCH 03862/11651] Documentation: Add device tree bindings for Freescale i.MX GPC The i.MX6 contains a power controller that controls power gating and sequencing for the SoC's power domains. Signed-off-by: Philipp Zabel Signed-off-by: Shawn Guo --- .../devicetree/bindings/power/fsl,imx-gpc.txt | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 Documentation/devicetree/bindings/power/fsl,imx-gpc.txt diff --git a/Documentation/devicetree/bindings/power/fsl,imx-gpc.txt b/Documentation/devicetree/bindings/power/fsl,imx-gpc.txt new file mode 100644 index 000000000000..65cc0345747d --- /dev/null +++ b/Documentation/devicetree/bindings/power/fsl,imx-gpc.txt @@ -0,0 +1,59 @@ +Freescale i.MX General Power Controller +======================================= + +The i.MX6Q General Power Control (GPC) block contains DVFS load tracking +counters and Power Gating Control (PGC) for the CPU and PU (GPU/VPU) power +domains. + +Required properties: +- compatible: Should be "fsl,imx6q-gpc" or "fsl,imx6sl-gpc" +- reg: should be register base and length as documented in the + datasheet +- interrupts: Should contain GPC interrupt request 1 +- pu-supply: Link to the LDO regulator powering the PU power domain +- clocks: Clock phandles to devices in the PU power domain that need + to be enabled during domain power-up for reset propagation. +- #power-domain-cells: Should be 1, see below: + +The gpc node is a power-controller as documented by the generic power domain +bindings in Documentation/devicetree/bindings/power/power_domain.txt. + +Example: + + gpc: gpc@020dc000 { + compatible = "fsl,imx6q-gpc"; + reg = <0x020dc000 0x4000>; + interrupts = <0 89 IRQ_TYPE_LEVEL_HIGH>, + <0 90 IRQ_TYPE_LEVEL_HIGH>; + pu-supply = <®_pu>; + clocks = <&clks IMX6QDL_CLK_GPU3D_CORE>, + <&clks IMX6QDL_CLK_GPU3D_SHADER>, + <&clks IMX6QDL_CLK_GPU2D_CORE>, + <&clks IMX6QDL_CLK_GPU2D_AXI>, + <&clks IMX6QDL_CLK_OPENVG_AXI>, + <&clks IMX6QDL_CLK_VPU_AXI>; + #power-domain-cells = <1>; + }; + + +Specifying power domain for IP modules +====================================== + +IP cores belonging to a power domain should contain a 'power-domains' property +that is a phandle pointing to the gpc device node and a DOMAIN_INDEX specifying +the power domain the device belongs to. + +Example of a device that is part of the PU power domain: + + vpu: vpu@02040000 { + reg = <0x02040000 0x3c000>; + /* ... */ + power-domains = <&gpc 1>; + /* ... */ + }; + +The following DOMAIN_INDEX values are valid for i.MX6Q: +ARM_DOMAIN 0 +PU_DOMAIN 1 +The following additional DOMAIN_INDEX value is valid for i.MX6SL: +DISPLAY_DOMAIN 2 -- GitLab From 00eb60a8b4f7a4aa00fd8abd68c2dc7aec55df19 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Mon, 23 Feb 2015 18:40:12 +0100 Subject: [PATCH 03863/11651] ARM: imx6: gpc: Add PU power domain for GPU/VPU When generic pm domain support is enabled, the PGC can be used to completely gate power to the PU power domain containing GPU3D, GPU2D, and VPU cores. This code triggers the PGC powerdown sequence to disable the GPU/VPU isolation cells and gate power and then disables the PU regulator. To reenable, the reverse powerup sequence is triggered after the PU regulator is enabled again. The GPU and VPU devices in the PU power domain temporarily need to be clocked during powerup, so that the reset machinery can work. [Avoid explicit regulator enabling in probe, unless !PM] Signed-off-by: Markus Pargmann Signed-off-by: Philipp Zabel Signed-off-by: Shawn Guo --- arch/arm/mach-imx/Kconfig | 1 + arch/arm/mach-imx/gpc.c | 213 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 214 insertions(+) diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index b8d3ccdfe127..178f0d001011 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -50,6 +50,7 @@ config HAVE_IMX_ANATOP config HAVE_IMX_GPC bool + select PM_GENERIC_DOMAINS if PM config HAVE_IMX_MMDC bool diff --git a/arch/arm/mach-imx/gpc.c b/arch/arm/mach-imx/gpc.c index 745caa18ab2c..029f59ce2712 100644 --- a/arch/arm/mach-imx/gpc.c +++ b/arch/arm/mach-imx/gpc.c @@ -10,15 +10,25 @@ * http://www.gnu.org/copyleft/gpl.html */ +#include +#include #include #include #include #include #include +#include +#include +#include #include #include "common.h" +#include "hardware.h" +#define GPC_CNTR 0x000 #define GPC_IMR1 0x008 +#define GPC_PGC_GPU_PDN 0x260 +#define GPC_PGC_GPU_PUPSCR 0x264 +#define GPC_PGC_GPU_PDNSCR 0x268 #define GPC_PGC_CPU_PDN 0x2a0 #define GPC_PGC_CPU_PUPSCR 0x2a4 #define GPC_PGC_CPU_PDNSCR 0x2a8 @@ -27,6 +37,18 @@ #define IMR_NUM 4 +#define GPU_VPU_PUP_REQ BIT(1) +#define GPU_VPU_PDN_REQ BIT(0) + +#define GPC_CLK_MAX 6 + +struct pu_domain { + struct generic_pm_domain base; + struct regulator *reg; + struct clk *clk[GPC_CLK_MAX]; + int num_clks; +}; + static void __iomem *gpc_base; static u32 gpc_wake_irqs[IMR_NUM]; static u32 gpc_saved_imrs[IMR_NUM]; @@ -170,3 +192,194 @@ void __init imx_gpc_init(void) gic_arch_extn.irq_unmask = imx_gpc_irq_unmask; gic_arch_extn.irq_set_wake = imx_gpc_irq_set_wake; } + +#ifdef CONFIG_PM_GENERIC_DOMAINS + +static void _imx6q_pm_pu_power_off(struct generic_pm_domain *genpd) +{ + int iso, iso2sw; + u32 val; + + /* Read ISO and ISO2SW power down delays */ + val = readl_relaxed(gpc_base + GPC_PGC_GPU_PDNSCR); + iso = val & 0x3f; + iso2sw = (val >> 8) & 0x3f; + + /* Gate off PU domain when GPU/VPU when powered down */ + writel_relaxed(0x1, gpc_base + GPC_PGC_GPU_PDN); + + /* Request GPC to power down GPU/VPU */ + val = readl_relaxed(gpc_base + GPC_CNTR); + val |= GPU_VPU_PDN_REQ; + writel_relaxed(val, gpc_base + GPC_CNTR); + + /* Wait ISO + ISO2SW IPG clock cycles */ + ndelay((iso + iso2sw) * 1000 / 66); +} + +static int imx6q_pm_pu_power_off(struct generic_pm_domain *genpd) +{ + struct pu_domain *pu = container_of(genpd, struct pu_domain, base); + + _imx6q_pm_pu_power_off(genpd); + + if (pu->reg) + regulator_disable(pu->reg); + + return 0; +} + +static int imx6q_pm_pu_power_on(struct generic_pm_domain *genpd) +{ + struct pu_domain *pu = container_of(genpd, struct pu_domain, base); + int i, ret, sw, sw2iso; + u32 val; + + if (pu->reg) + ret = regulator_enable(pu->reg); + if (pu->reg && ret) { + pr_err("%s: failed to enable regulator: %d\n", __func__, ret); + return ret; + } + + /* Enable reset clocks for all devices in the PU domain */ + for (i = 0; i < pu->num_clks; i++) + clk_prepare_enable(pu->clk[i]); + + /* Gate off PU domain when GPU/VPU when powered down */ + writel_relaxed(0x1, gpc_base + GPC_PGC_GPU_PDN); + + /* Read ISO and ISO2SW power down delays */ + val = readl_relaxed(gpc_base + GPC_PGC_GPU_PUPSCR); + sw = val & 0x3f; + sw2iso = (val >> 8) & 0x3f; + + /* Request GPC to power up GPU/VPU */ + val = readl_relaxed(gpc_base + GPC_CNTR); + val |= GPU_VPU_PUP_REQ; + writel_relaxed(val, gpc_base + GPC_CNTR); + + /* Wait ISO + ISO2SW IPG clock cycles */ + ndelay((sw + sw2iso) * 1000 / 66); + + /* Disable reset clocks for all devices in the PU domain */ + for (i = 0; i < pu->num_clks; i++) + clk_disable_unprepare(pu->clk[i]); + + return 0; +} + +static struct generic_pm_domain imx6q_arm_domain = { + .name = "ARM", +}; + +static struct pu_domain imx6q_pu_domain = { + .base = { + .name = "PU", + .power_off = imx6q_pm_pu_power_off, + .power_on = imx6q_pm_pu_power_on, + .power_off_latency_ns = 25000, + .power_on_latency_ns = 2000000, + }, +}; + +static struct generic_pm_domain imx6sl_display_domain = { + .name = "DISPLAY", +}; + +static struct generic_pm_domain *imx_gpc_domains[] = { + &imx6q_arm_domain, + &imx6q_pu_domain.base, + &imx6sl_display_domain, +}; + +static struct genpd_onecell_data imx_gpc_onecell_data = { + .domains = imx_gpc_domains, + .num_domains = ARRAY_SIZE(imx_gpc_domains), +}; + +static int imx_gpc_genpd_init(struct device *dev, struct regulator *pu_reg) +{ + struct clk *clk; + bool is_off; + int i; + + imx6q_pu_domain.reg = pu_reg; + + for (i = 0; ; i++) { + clk = of_clk_get(dev->of_node, i); + if (IS_ERR(clk)) + break; + if (i >= GPC_CLK_MAX) { + dev_err(dev, "more than %d clocks\n", GPC_CLK_MAX); + goto clk_err; + } + imx6q_pu_domain.clk[i] = clk; + } + imx6q_pu_domain.num_clks = i; + + is_off = IS_ENABLED(CONFIG_PM); + if (is_off) { + _imx6q_pm_pu_power_off(&imx6q_pu_domain.base); + } else { + /* + * Enable power if compiled without CONFIG_PM in case the + * bootloader disabled it. + */ + imx6q_pm_pu_power_on(&imx6q_pu_domain.base); + } + + pm_genpd_init(&imx6q_pu_domain.base, NULL, is_off); + return of_genpd_add_provider_onecell(dev->of_node, + &imx_gpc_onecell_data); + +clk_err: + while (i--) + clk_put(imx6q_pu_domain.clk[i]); + return -EINVAL; +} + +#else +static inline int imx_gpc_genpd_init(struct device *dev, struct regulator *reg) +{ + return 0; +} +#endif /* CONFIG_PM_GENERIC_DOMAINS */ + +static int imx_gpc_probe(struct platform_device *pdev) +{ + struct regulator *pu_reg; + int ret; + + pu_reg = devm_regulator_get_optional(&pdev->dev, "pu"); + if (PTR_ERR(pu_reg) == -ENODEV) + pu_reg = NULL; + if (IS_ERR(pu_reg)) { + ret = PTR_ERR(pu_reg); + dev_err(&pdev->dev, "failed to get pu regulator: %d\n", ret); + return ret; + } + + return imx_gpc_genpd_init(&pdev->dev, pu_reg); +} + +static const struct of_device_id imx_gpc_dt_ids[] = { + { .compatible = "fsl,imx6q-gpc" }, + { .compatible = "fsl,imx6sl-gpc" }, + { } +}; + +static struct platform_driver imx_gpc_driver = { + .driver = { + .name = "imx-gpc", + .owner = THIS_MODULE, + .of_match_table = imx_gpc_dt_ids, + }, + .probe = imx_gpc_probe, +}; + +static int __init imx_pgc_init(void) +{ + return platform_driver_register(&imx_gpc_driver); +} +subsys_initcall(imx_pgc_init); -- GitLab From 40f737791d4dab26bf23a6331609c604142228bd Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Fri, 6 Mar 2015 16:04:20 +0800 Subject: [PATCH 03864/11651] ARM: imx6qdl-sabresd: set swbst_reg as vbus's parent reg USB vbus 5V is from PMIC SWBST, so set swbst_reg as vbus's parent reg, it fixed a bug that the voltage of vbus is incorrect due to swbst_reg is disabled after boots up. Cc: stable@vger.kernel.org Signed-off-by: Peter Chen Signed-off-by: Shawn Guo --- arch/arm/boot/dts/imx6qdl-sabresd.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/boot/dts/imx6qdl-sabresd.dtsi b/arch/arm/boot/dts/imx6qdl-sabresd.dtsi index f1cd2147421d..a626e6dd8022 100644 --- a/arch/arm/boot/dts/imx6qdl-sabresd.dtsi +++ b/arch/arm/boot/dts/imx6qdl-sabresd.dtsi @@ -35,6 +35,7 @@ regulator-max-microvolt = <5000000>; gpio = <&gpio3 22 0>; enable-active-high; + vin-supply = <&swbst_reg>; }; reg_usb_h1_vbus: regulator@1 { @@ -45,6 +46,7 @@ regulator-max-microvolt = <5000000>; gpio = <&gpio1 29 0>; enable-active-high; + vin-supply = <&swbst_reg>; }; reg_audio: regulator@2 { -- GitLab From 2de9dd0391a74e80922c1bc95a78cedf85bcdc9e Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Fri, 6 Mar 2015 16:04:21 +0800 Subject: [PATCH 03865/11651] ARM: imx6sl-evk: set swbst_reg as vbus's parent reg USB vbus 5V is from PMIC SWBST, so set swbst_reg as vbus's parent reg, it fixed a bug that the voltage of vbus is incorrect due to swbst_reg is disabled after boots up. Cc: stable@vger.kernel.org Signed-off-by: Peter Chen Signed-off-by: Shawn Guo --- arch/arm/boot/dts/imx6sl-evk.dts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/boot/dts/imx6sl-evk.dts b/arch/arm/boot/dts/imx6sl-evk.dts index fda4932faefd..945887d3fdb3 100644 --- a/arch/arm/boot/dts/imx6sl-evk.dts +++ b/arch/arm/boot/dts/imx6sl-evk.dts @@ -52,6 +52,7 @@ regulator-max-microvolt = <5000000>; gpio = <&gpio4 0 0>; enable-active-high; + vin-supply = <&swbst_reg>; }; reg_usb_otg2_vbus: regulator@1 { @@ -62,6 +63,7 @@ regulator-max-microvolt = <5000000>; gpio = <&gpio4 2 0>; enable-active-high; + vin-supply = <&swbst_reg>; }; reg_aud3v: regulator@2 { -- GitLab From 3877942b0c7f36c82b2f05e84776b2dfe1afb784 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 10 Mar 2015 22:40:02 -0300 Subject: [PATCH 03866/11651] ARM: imx25: Remove eukrea mx25 board files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit eukrea mx25 is well supported in device tree, so let's get rid of its board files. Cc: Eric Bénard Signed-off-by: Fabio Estevam Signed-off-by: Shawn Guo --- arch/arm/mach-imx/Kconfig | 34 -- arch/arm/mach-imx/Makefile | 2 - .../arm/mach-imx/eukrea_mbimxsd25-baseboard.c | 310 ------------------ arch/arm/mach-imx/mach-eukrea_cpuimx25.c | 172 ---------- 4 files changed, 518 deletions(-) delete mode 100644 arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c delete mode 100644 arch/arm/mach-imx/mach-eukrea_cpuimx25.c diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 247a465eb203..6eec6253d94d 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -149,40 +149,6 @@ config MACH_MX21ADS Include support for MX21ADS platform. This includes specific configurations for the board and its peripherals. -comment "MX25 platforms:" - -config MACH_EUKREA_CPUIMX25SD - bool "Support Eukrea CPUIMX25 Platform" - select IMX_HAVE_PLATFORM_FLEXCAN - select IMX_HAVE_PLATFORM_FSL_USB2_UDC - select IMX_HAVE_PLATFORM_IMX2_WDT - select IMX_HAVE_PLATFORM_IMXDI_RTC - select IMX_HAVE_PLATFORM_IMX_FB - select IMX_HAVE_PLATFORM_IMX_I2C - select IMX_HAVE_PLATFORM_IMX_UART - select IMX_HAVE_PLATFORM_MXC_EHCI - select IMX_HAVE_PLATFORM_MXC_NAND - select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX - select USB_ULPI_VIEWPORT if USB_ULPI - select SOC_IMX25 - -choice - prompt "Baseboard" - depends on MACH_EUKREA_CPUIMX25SD - default MACH_EUKREA_MBIMXSD25_BASEBOARD - -config MACH_EUKREA_MBIMXSD25_BASEBOARD - bool "Eukrea MBIMXSD development board" - select IMX_HAVE_PLATFORM_GPIO_KEYS - select IMX_HAVE_PLATFORM_IMX_SSI - select IMX_HAVE_PLATFORM_SPI_IMX - select LEDS_GPIO_REGISTER - help - This adds board specific devices that can be found on Eukrea's - MBIMXSD evaluation board. - -endchoice - config MACH_IMX25_DT bool "Support i.MX25 platforms from device tree" select SOC_IMX25 diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index e92ede9b1ad1..724b7fbe417b 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -49,8 +49,6 @@ obj-$(CONFIG_MACH_IMX1_DT) += imx1-dt.o obj-$(CONFIG_MACH_MX21ADS) += mach-mx21ads.o # i.MX25 based machines -obj-$(CONFIG_MACH_EUKREA_CPUIMX25SD) += mach-eukrea_cpuimx25.o -obj-$(CONFIG_MACH_EUKREA_MBIMXSD25_BASEBOARD) += eukrea_mbimxsd25-baseboard.o obj-$(CONFIG_MACH_IMX25_DT) += imx25-dt.o # i.MX27 based machines diff --git a/arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c b/arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c deleted file mode 100644 index 10e53818e003..000000000000 --- a/arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c +++ /dev/null @@ -1,310 +0,0 @@ -/* - * Copyright (C) 2010 Eric Benard - eric@eukrea.com - * - * Based on pcm970-baseboard.c which is : - * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * 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 Street, Fifth Floor, Boston, - * MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include