* Re: [PATCH 1/1] Staging: hv: mousevsc: Move the mouse driver out of staging
From: Dmitry Torokhov @ 2011-10-23 7:24 UTC (permalink / raw)
To: K. Y. Srinivasan
Cc: gregkh, linux-kernel, devel, virtualization, linux-input,
Haiyang Zhang, Jiri Kosina
In-Reply-To: <1318658907-16698-1-git-send-email-kys@microsoft.com>
Hi K. Y.,
On Fri, Oct 14, 2011 at 11:08:27PM -0700, K. Y. Srinivasan wrote:
> In preparation for moving the mouse driver out of staging, seek community
> review of the mouse driver code.
>
Because it is a HID driver it should go through Jiri Kosina's tree
(CCed). Still, a few comments below.
> Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
> Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
> ---
> drivers/hid/Kconfig | 6 +
> drivers/hid/Makefile | 1 +
> drivers/hid/hv_mouse.c | 599 +++++++++++++++++++++++++++++++++++++++++
> drivers/staging/hv/Kconfig | 6 -
> drivers/staging/hv/Makefile | 1 -
> drivers/staging/hv/hv_mouse.c | 599 -----------------------------------------
> 6 files changed, 606 insertions(+), 606 deletions(-)
> create mode 100644 drivers/hid/hv_mouse.c
> delete mode 100644 drivers/staging/hv/hv_mouse.c
>
> diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
> index 1130a89..f8b98b8 100644
> --- a/drivers/hid/Kconfig
> +++ b/drivers/hid/Kconfig
> @@ -613,6 +613,12 @@ config HID_ZYDACRON
> ---help---
> Support for Zydacron remote control.
>
> +config HYPERV_MOUSE
> + tristate "Microsoft Hyper-V mouse driver"
> + depends on HYPERV
> + help
> + Select this option to enable the Hyper-V mouse driver.
> +
> endmenu
>
> endif # HID_SUPPORT
> diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
> index 0a0a38e..436ac2e 100644
> --- a/drivers/hid/Makefile
> +++ b/drivers/hid/Makefile
> @@ -76,6 +76,7 @@ obj-$(CONFIG_HID_ZYDACRON) += hid-zydacron.o
> obj-$(CONFIG_HID_WACOM) += hid-wacom.o
> obj-$(CONFIG_HID_WALTOP) += hid-waltop.o
> obj-$(CONFIG_HID_WIIMOTE) += hid-wiimote.o
> +obj-$(CONFIG_HYPERV_MOUSE) += hv_mouse.o
>
> obj-$(CONFIG_USB_HID) += usbhid/
> obj-$(CONFIG_USB_MOUSE) += usbhid/
> diff --git a/drivers/hid/hv_mouse.c b/drivers/hid/hv_mouse.c
> new file mode 100644
> index 0000000..ccd39c7
> --- /dev/null
> +++ b/drivers/hid/hv_mouse.c
> @@ -0,0 +1,599 @@
> +/*
> + * Copyright (c) 2009, Citrix Systems, Inc.
> + * Copyright (c) 2010, Microsoft Corporation.
> + * Copyright (c) 2011, Novell Inc.
> + *
> + * 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 <linux/init.h>
> +#include <linux/module.h>
> +#include <linux/delay.h>
> +#include <linux/device.h>
> +#include <linux/workqueue.h>
Is this really needed?
> +#include <linux/sched.h>
You probably want completion.h instead.
> +#include <linux/wait.h>
> +#include <linux/input.h>
> +#include <linux/hid.h>
> +#include <linux/hiddev.h>
> +#include <linux/hyperv.h>
> +
> +
> +struct hv_input_dev_info {
> + unsigned int size;
> + unsigned short vendor;
> + unsigned short product;
> + unsigned short version;
> + unsigned short reserved[11];
> +};
> +
> +/* The maximum size of a synthetic input message. */
> +#define SYNTHHID_MAX_INPUT_REPORT_SIZE 16
> +
> +/*
> + * Current version
> + *
> + * History:
> + * Beta, RC < 2008/1/22 1,0
> + * RC > 2008/1/22 2,0
> + */
> +#define SYNTHHID_INPUT_VERSION_MAJOR 2
> +#define SYNTHHID_INPUT_VERSION_MINOR 0
> +#define SYNTHHID_INPUT_VERSION (SYNTHHID_INPUT_VERSION_MINOR | \
> + (SYNTHHID_INPUT_VERSION_MAJOR << 16))
> +
> +
> +#pragma pack(push, 1)
> +/*
> + * Message types in the synthetic input protocol
> + */
> +enum synthhid_msg_type {
> + SYNTH_HID_PROTOCOL_REQUEST,
> + SYNTH_HID_PROTOCOL_RESPONSE,
> + SYNTH_HID_INITIAL_DEVICE_INFO,
> + SYNTH_HID_INITIAL_DEVICE_INFO_ACK,
> + SYNTH_HID_INPUT_REPORT,
> + SYNTH_HID_MAX
> +};
> +
> +/*
> + * Basic message structures.
> + */
> +struct synthhid_msg_hdr {
> + enum synthhid_msg_type type;
> + u32 size;
> +};
> +
> +struct synthhid_msg {
> + struct synthhid_msg_hdr header;
> + char data[1]; /* Enclosed message */
> +};
> +
> +union synthhid_version {
> + struct {
> + u16 minor_version;
> + u16 major_version;
> + };
> + u32 version;
> +};
> +
> +/*
> + * Protocol messages
> + */
> +struct synthhid_protocol_request {
> + struct synthhid_msg_hdr header;
> + union synthhid_version version_requested;
> +};
> +
> +struct synthhid_protocol_response {
> + struct synthhid_msg_hdr header;
> + union synthhid_version version_requested;
> + unsigned char approved;
> +};
> +
> +struct synthhid_device_info {
> + struct synthhid_msg_hdr header;
> + struct hv_input_dev_info hid_dev_info;
> + struct hid_descriptor hid_descriptor;
> +};
> +
> +struct synthhid_device_info_ack {
> + struct synthhid_msg_hdr header;
> + unsigned char reserved;
> +};
> +
> +struct synthhid_input_report {
> + struct synthhid_msg_hdr header;
> + char buffer[1];
> +};
> +
> +#pragma pack(pop)
> +
> +#define INPUTVSC_SEND_RING_BUFFER_SIZE (10*PAGE_SIZE)
> +#define INPUTVSC_RECV_RING_BUFFER_SIZE (10*PAGE_SIZE)
> +
> +#define NBITS(x) (((x)/BITS_PER_LONG)+1)
> +
> +enum pipe_prot_msg_type {
> + PIPE_MESSAGE_INVALID,
> + PIPE_MESSAGE_DATA,
> + PIPE_MESSAGE_MAXIMUM
> +};
> +
> +
> +struct pipe_prt_msg {
> + enum pipe_prot_msg_type type;
> + u32 size;
> + char data[1];
> +};
> +
> +struct mousevsc_prt_msg {
> + enum pipe_prot_msg_type type;
> + u32 size;
> + union {
> + struct synthhid_protocol_request request;
> + struct synthhid_protocol_response response;
> + struct synthhid_device_info_ack ack;
> + };
> +};
> +
> +/*
> + * Represents an mousevsc device
> + */
> +struct mousevsc_dev {
> + struct hv_device *device;
> + unsigned char init_complete;
> + struct mousevsc_prt_msg protocol_req;
> + struct mousevsc_prt_msg protocol_resp;
> + /* Synchronize the request/response if needed */
> + struct completion wait_event;
> + int dev_info_status;
> +
> + struct hid_descriptor *hid_desc;
> + unsigned char *report_desc;
> + u32 report_desc_size;
> + struct hv_input_dev_info hid_dev_info;
> + int connected;
bool?
> + struct hid_device *hid_device;
> +};
> +
> +
> +static struct mousevsc_dev *alloc_input_device(struct hv_device *device)
> +{
> + struct mousevsc_dev *input_dev;
> +
> + input_dev = kzalloc(sizeof(struct mousevsc_dev), GFP_KERNEL);
> +
This blank line is extra.
> + if (!input_dev)
> + return NULL;
> +
> + input_dev->device = device;
> + hv_set_drvdata(device, input_dev);
> + init_completion(&input_dev->wait_event);
> +
> + return input_dev;
> +}
> +
> +static void free_input_device(struct mousevsc_dev *device)
> +{
> + kfree(device->hid_desc);
> + kfree(device->report_desc);
> + hv_set_drvdata(device->device, NULL);
> + kfree(device);
> +}
> +
> +
> +static void mousevsc_on_receive_device_info(struct mousevsc_dev *input_device,
> + struct synthhid_device_info *device_info)
> +{
> + int ret = 0;
> + struct hid_descriptor *desc;
> + struct mousevsc_prt_msg ack;
> +
> + /* Assume success for now */
> + input_device->dev_info_status = 0;
> +
> + memcpy(&input_device->hid_dev_info, &device_info->hid_dev_info,
> + sizeof(struct hv_input_dev_info));
> +
> + desc = &device_info->hid_descriptor;
> + WARN_ON(desc->bLength == 0);
> +
> + input_device->hid_desc = kzalloc(desc->bLength, GFP_ATOMIC);
> +
> + if (!input_device->hid_desc)
> + goto cleanup;
> +
> + memcpy(input_device->hid_desc, desc, desc->bLength);
> +
> + input_device->report_desc_size = desc->desc[0].wDescriptorLength;
> + if (input_device->report_desc_size == 0)
> + goto cleanup;
> + input_device->report_desc = kzalloc(input_device->report_desc_size,
> + GFP_ATOMIC);
> +
> + if (!input_device->report_desc)
> + goto cleanup;
> +
> + memcpy(input_device->report_desc,
> + ((unsigned char *)desc) + desc->bLength,
> + desc->desc[0].wDescriptorLength);
> +
> + /* Send the ack */
> + memset(&ack, 0, sizeof(struct mousevsc_prt_msg));
> +
> + ack.type = PIPE_MESSAGE_DATA;
> + ack.size = sizeof(struct synthhid_device_info_ack);
> +
> + ack.ack.header.type = SYNTH_HID_INITIAL_DEVICE_INFO_ACK;
> + ack.ack.header.size = 1;
> + ack.ack.reserved = 0;
That looks like a constant structure...
> +
> + ret = vmbus_sendpacket(input_device->device->channel,
> + &ack,
> + sizeof(struct pipe_prt_msg) - sizeof(unsigned char) +
> + sizeof(struct synthhid_device_info_ack),
> + (unsigned long)&ack,
> + VM_PKT_DATA_INBAND,
> + VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
> + if (ret != 0)
> + goto cleanup;
> +
> + complete(&input_device->wait_event);
> +
> + return;
> +
> +cleanup:
> + kfree(input_device->hid_desc);
> + input_device->hid_desc = NULL;
> +
> + kfree(input_device->report_desc);
> + input_device->report_desc = NULL;
> +
> + input_device->dev_info_status = -1;
> + complete(&input_device->wait_event);
> +}
> +
> +static void mousevsc_on_receive(struct hv_device *device,
> + struct vmpacket_descriptor *packet)
> +{
> + struct pipe_prt_msg *pipe_msg;
> + struct synthhid_msg *hid_msg;
> + struct mousevsc_dev *input_dev = hv_get_drvdata(device);
> + struct synthhid_input_report *input_report;
> +
> + pipe_msg = (struct pipe_prt_msg *)((unsigned long)packet +
> + (packet->offset8 << 3));
> +
> + if (pipe_msg->type != PIPE_MESSAGE_DATA)
> + return;
> +
> + hid_msg = (struct synthhid_msg *)&pipe_msg->data[0];
> +
> + switch (hid_msg->header.type) {
> + case SYNTH_HID_PROTOCOL_RESPONSE:
> + memcpy(&input_dev->protocol_resp, pipe_msg,
> + pipe_msg->size + sizeof(struct pipe_prt_msg) -
> + sizeof(unsigned char));
> + complete(&input_dev->wait_event);
> + break;
> +
> + case SYNTH_HID_INITIAL_DEVICE_INFO:
> + WARN_ON(pipe_msg->size < sizeof(struct hv_input_dev_info));
> +
> + /*
> + * Parse out the device info into device attr,
> + * hid desc and report desc
> + */
> + mousevsc_on_receive_device_info(input_dev,
> + (struct synthhid_device_info *)&pipe_msg->data[0]);
> + break;
> + case SYNTH_HID_INPUT_REPORT:
> + input_report =
> + (struct synthhid_input_report *)&pipe_msg->data[0];
> + if (!input_dev->init_complete)
> + break;
> + hid_input_report(input_dev->hid_device,
> + HID_INPUT_REPORT, input_report->buffer,
> + input_report->header.size, 1);
> + break;
> + default:
> + pr_err("unsupported hid msg type - type %d len %d",
> + hid_msg->header.type, hid_msg->header.size);
> + break;
> + }
> +
> +}
> +
> +static void mousevsc_on_channel_callback(void *context)
> +{
> + const int packetSize = 0x100;
> + int ret = 0;
> + struct hv_device *device = (struct hv_device *)context;
No need to cast.
> +
> + u32 bytes_recvd;
> + u64 req_id;
> + unsigned char packet[0x100];
Hmm, 100 bytes on stack... and are we in interrupt context by any
chance?
> + struct vmpacket_descriptor *desc;
> + unsigned char *buffer = packet;
> + int bufferlen = packetSize;
> +
> +
> + do {
> + ret = vmbus_recvpacket_raw(device->channel, buffer,
> + bufferlen, &bytes_recvd, &req_id);
> +
> + if (ret == 0) {
> + if (bytes_recvd > 0) {
> + desc = (struct vmpacket_descriptor *)buffer;
> +
> + switch (desc->type) {
> + case VM_PKT_COMP:
> + break;
> +
> + case VM_PKT_DATA_INBAND:
> + mousevsc_on_receive(
> + device, desc);
> + break;
> +
> + default:
> + pr_err("unhandled packet type %d, tid %llx len %d\n",
> + desc->type,
> + req_id,
> + bytes_recvd);
> + break;
> + }
> +
> + /* reset */
> + if (bufferlen > packetSize) {
> + kfree(buffer);
> +
> + buffer = packet;
> + bufferlen = packetSize;
> + }
> + } else {
> + if (bufferlen > packetSize) {
> + kfree(buffer);
> +
> + buffer = packet;
> + bufferlen = packetSize;
> + }
> + break;
> + }
> + } else if (ret == -ENOBUFS) {
> + /* Handle large packet */
> + bufferlen = bytes_recvd;
> + buffer = kzalloc(bytes_recvd, GFP_ATOMIC);
> +
What happens if we receive even larger amount of data after allocating
the buffer?
> + if (buffer == NULL) {
> + buffer = packet;
> + bufferlen = packetSize;
> + break;
> + }
> + }
> + } while (1);
So we can be looping indefinitely here as long as other side keeps
sending data?
> +
> + return;
No naked returns please.
> +}
> +
> +static int mousevsc_connect_to_vsp(struct hv_device *device)
> +{
> + int ret = 0;
> + int t;
> + struct mousevsc_dev *input_dev = hv_get_drvdata(device);
> + struct mousevsc_prt_msg *request;
> + struct mousevsc_prt_msg *response;
> +
> +
> + request = &input_dev->protocol_req;
> +
> + memset(request, 0, sizeof(struct mousevsc_prt_msg));
> +
> + request->type = PIPE_MESSAGE_DATA;
> + request->size = sizeof(struct synthhid_protocol_request);
> +
> + request->request.header.type = SYNTH_HID_PROTOCOL_REQUEST;
> + request->request.header.size = sizeof(unsigned int);
> + request->request.version_requested.version = SYNTHHID_INPUT_VERSION;
> +
> +
> + ret = vmbus_sendpacket(device->channel, request,
> + sizeof(struct pipe_prt_msg) -
> + sizeof(unsigned char) +
> + sizeof(struct synthhid_protocol_request),
> + (unsigned long)request,
> + VM_PKT_DATA_INBAND,
> + VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
> + if (ret != 0)
> + goto cleanup;
> +
> + t = wait_for_completion_timeout(&input_dev->wait_event, 5*HZ);
> + if (t == 0) {
> + ret = -ETIMEDOUT;
> + goto cleanup;
> + }
> +
> + response = &input_dev->protocol_resp;
> +
> + if (!response->response.approved) {
> + pr_err("synthhid protocol request failed (version %d)",
> + SYNTHHID_INPUT_VERSION);
> + ret = -ENODEV;
> + goto cleanup;
> + }
> +
> + t = wait_for_completion_timeout(&input_dev->wait_event, 5*HZ);
We just completed the wait for this completion, why are we waiting on
the same completion again?
> + if (t == 0) {
> + ret = -ETIMEDOUT;
> + goto cleanup;
> + }
> +
> + /*
> + * We should have gotten the device attr, hid desc and report
> + * desc at this point
> + */
> + if (input_dev->dev_info_status)
> + ret = -ENOMEM;
-ENOMEM seems wrong.
> +
> +cleanup:
> +
> + return ret;
> +}
> +
> +static int mousevsc_hid_open(struct hid_device *hid)
> +{
> + return 0;
> +}
> +
> +static void mousevsc_hid_close(struct hid_device *hid)
> +{
> +}
> +
> +static struct hid_ll_driver mousevsc_ll_driver = {
> + .open = mousevsc_hid_open,
> + .close = mousevsc_hid_close,
> +};
> +
> +static struct hid_driver mousevsc_hid_driver;
> +
> +static void reportdesc_callback(struct hv_device *dev, void *packet, u32 len)
> +{
This is called from mousevsc_on_device_add() which is part of device
probe. Why it is split into separate function with bizzare arguments is
beyond me.
> + struct hid_device *hid_dev;
> + struct mousevsc_dev *input_device = hv_get_drvdata(dev);
> +
> + hid_dev = hid_allocate_device();
> + if (IS_ERR(hid_dev))
> + return;
This is not very helpful.
> +
> + hid_dev->ll_driver = &mousevsc_ll_driver;
> + hid_dev->driver = &mousevsc_hid_driver;
> +
> + if (hid_parse_report(hid_dev, packet, len))
> + return;
Neither is this.
> +
> + hid_dev->bus = BUS_VIRTUAL;
> + hid_dev->vendor = input_device->hid_dev_info.vendor;
> + hid_dev->product = input_device->hid_dev_info.product;
> + hid_dev->version = input_device->hid_dev_info.version;
> +
> + sprintf(hid_dev->name, "%s", "Microsoft Vmbus HID-compliant Mouse");
> +
> + if (!hidinput_connect(hid_dev, 0)) {
> + hid_dev->claimed |= HID_CLAIMED_INPUT;
Why do you force hidinput claim? Let the normal rules do it.
> +
> + input_device->connected = 1;
input_device->connected = true;
> +
> + }
> +
> + input_device->hid_device = hid_dev;
This assignment is probably too late.
> +}
> +
> +static int mousevsc_on_device_add(struct hv_device *device)
The only caller of this is mousevsc_probe() so why do you have it>
> +{
> + int ret = 0;
> + struct mousevsc_dev *input_dev;
> +
> + input_dev = alloc_input_device(device);
> +
> + if (!input_dev)
> + return -ENOMEM;
> +
> + input_dev->init_complete = false;
> +
> + ret = vmbus_open(device->channel,
> + INPUTVSC_SEND_RING_BUFFER_SIZE,
> + INPUTVSC_RECV_RING_BUFFER_SIZE,
> + NULL,
> + 0,
> + mousevsc_on_channel_callback,
> + device
> + );
> +
> + if (ret != 0) {
> + free_input_device(input_dev);
> + return ret;
> + }
> +
> +
> + ret = mousevsc_connect_to_vsp(device);
> +
> + if (ret != 0) {
> + vmbus_close(device->channel);
> + free_input_device(input_dev);
> + return ret;
> + }
> +
> +
> + /* workaround SA-167 */
> + if (input_dev->report_desc[14] == 0x25)
> + input_dev->report_desc[14] = 0x29;
> +
> + reportdesc_callback(device, input_dev->report_desc,
> + input_dev->report_desc_size);
> +
> + input_dev->init_complete = true;
> +
> + return ret;
> +}
> +
> +static int mousevsc_probe(struct hv_device *dev,
> + const struct hv_vmbus_device_id *dev_id)
> +{
> +
> + return mousevsc_on_device_add(dev);
> +
> +}
> +
> +static int mousevsc_remove(struct hv_device *dev)
> +{
> + struct mousevsc_dev *input_dev = hv_get_drvdata(dev);
> +
> + vmbus_close(dev->channel);
> +
> + if (input_dev->connected) {
> + hidinput_disconnect(input_dev->hid_device);
> + input_dev->connected = 0;
> + hid_destroy_device(input_dev->hid_device);
hid_destroy_device() should disconnect registered handlers for you; you
do not need to do that manually.
> + }
> +
> + free_input_device(input_dev);
Calling it input device is terribly confusing to me. I'd also freed it
inline (and used gotos to unwind errors in probe()).
> +
> + return 0;
> +}
> +
> +static const struct hv_vmbus_device_id id_table[] = {
> + /* Mouse guid */
> + { VMBUS_DEVICE(0x9E, 0xB6, 0xA8, 0xCF, 0x4A, 0x5B, 0xc0, 0x4c,
> + 0xB9, 0x8B, 0x8B, 0xA1, 0xA1, 0xF3, 0xF9, 0x5A) },
> + { },
> +};
> +
> +MODULE_DEVICE_TABLE(vmbus, id_table);
> +
> +static struct hv_driver mousevsc_drv = {
> + .name = "mousevsc",
> + .id_table = id_table,
> + .probe = mousevsc_probe,
> + .remove = mousevsc_remove,
> +};
> +
> +static int __init mousevsc_init(void)
> +{
> + return vmbus_driver_register(&mousevsc_drv);
> +}
> +
> +static void __exit mousevsc_exit(void)
> +{
> + vmbus_driver_unregister(&mousevsc_drv);
> +}
> +
> +MODULE_LICENSE("GPL");
> +MODULE_VERSION(HV_DRV_VERSION);
> +module_init(mousevsc_init);
> +module_exit(mousevsc_exit);
Thanks.
--
Dmitry
^ permalink raw reply
* [PULL] drm-intel-next
From: Keith Packard @ 2011-10-23 7:27 UTC (permalink / raw)
To: Dave Airlie; +Cc: linux-kernel, dri-devel, Intel drivers
[-- Attachment #1: Type: text/plain, Size: 6710 bytes --]
Here's a pile of new code for the 3.2 series.
Overview:
* 3 pipe support for IVB.
* eDP fixes for SNB
* Interrupt race condition fixes
* Switch from MI_FLUSH to PIPECONTROL
* VT-d work-around for ILK
The following changes since commit 0ac225e56997ef89f46eb51b02799a685b78f214:
Merge branch 'drm-intel-fixes' into drm-intel-next (2011-09-28 14:44:38 -0700)
are available in the git repository at:
git://people.freedesktop.org/~keithp/linux drm-intel-next
Adam Jackson (8):
drm/i915: Remove "i2c_speed" nonsense from child device table
drm/i915: Fix multifunction SDVO detection
drm/i915: Rename intel_sdvo_hdmi_sink_detect
drm/i915: Remove redundant bit shifting from intel_gmbus_set_speed
drm/i915/dp: Fix the math in intel_dp_link_required
drm/i915/dp: Remove eDP special cases from bandwidth checks
drm/i915/dp: Introduce is_cpu_edp()
drm/i915/dp: Fix eDP on PCH DP on CPT/PPT
Andi Kleen (1):
i915: Move i915_read/write out of line
Ben Widawsky (3):
drm/i915: Remove early exit on i915_gpu_idle
drm/i915: ILK + VT-d workaround
drm: Add Panel Self Refresh DP addresses
Chris Wilson (1):
drm/i915: Defend against userspace creating a gem object with size==0
Daniel Vetter (7):
drm/i915: close PM interrupt masking races in the irq handler
drm/i915: close PM interrupt masking races in the rps work func
drm/i915: properly cancel rps_work on module unload v2
drm/i915: fix swizzling on gen6+
drm/i915: simplify swapin/out swizzle checking a bit
io-mapping: ensure io_mapping_map_atomic _is_ atomic
drm/i915: drop KM_USER0 argument to k(un)map_atomic
David Woodhouse (2):
intel-iommu: Workaround IOTLB hang on Ironlake GPU
intel-iommu: Export a flag indicating that the IOMMU is used for iGFX.
Jesse Barnes (19):
drm/i915: Use PIPE_CONTROL for flushing on gen6+.
drm/i915: always set FDI composite sync bit
drm/i915: PLL macro cleanup and pipe assertion check
drm/i915: support 3 pipes on IVB+
drm/i915: split refclk code out of ironlake_crtc_mode_set
drm/i915: use transcoder select bits on VGA and HDMI on CPT
drm/i915: fix PCH PLL assertion check for 3 pipes
drm/i915: add PLL sharing support to handle 3 pipes
drm/i915: fix debug output for 3 pipe configs
drm/i915: fix IVB cursor support
drm/i915: fix transcoder PLL select masking
drm/i915: export a CPT mode set verification function
drm/i915: set watermarks for third pipe on IVB
drm/i915: if transcoder disable fails, say which
drm/i915: remove transcoder PLL mashing from mode_set per specs
drm/i915: read full receiver capability field during DP hot plug
drm/i915: add DP test request handling
drm/i915: fix ILK+ infoframe support
drm/i915: use correct SPD type value
Keith Packard (30):
drm/i915: broken copyright encoding in intel_bios.c
drm/i915: Use DRM_DEBUG_KMS for all messages in intel_bios.c
drv/i915: Pull display_clock_mode out of VBT table
drm/i915: Document a few more BDB_GENERAL_FEATURES bits from PCH BIOS
drm/i915: Allow SSC parameter to override VBT value
drm/i915: Fix PCH SSC reference clock settings
drm/i915: Use CK505 as non-SSC source where available
drm/i915: All PCH refclks are 120MHz
drm/i915: Initialize PCH refclks at modeset init time
drm/i915: Enable digital port hotplug on PCH systems
drm/i915: Shut down PCH interrupts during irq_uninstall
drm/i915: Only use VBT panel mode on eDP if no EDID is found
drm/i915: Check eDP power when doing aux channel communications
drm/i915: Unlock PCH_PP_CONTROL always
drm/i915: Check for eDP inside edp panel on/off funcs
drm/i915: Turn force VDD back off when panel running in intel_dp_dpms
drm/i915: Ensure panel is on during DPMS off
drm/i915: Delay DP i2c initialization until panel power timings are computed
drm/i915: Wrap DP EDID fetch functions to enable eDP panel power
drm/i915: Enable eDP panel power during I2C initialization sequence
drm/i915: Ensure eDP powered up during DP_SET_POWER operation in dp_prepare
drm/i915: Correct eDP panel power sequencing delay computations
drm/i915: Move eDP panel fixed mode from dev_priv to intel_dp
drm/i915: edp_panel_on does not need to return a bool
drm/i915: Create helper functions to determine eDP power state
drm/i915: Disable eDP VDD in a delayed work proc instead of synchronously
drm/i915: Restrict ILK-specific eDP power hack to ILK
drm/i915: No need to wait for eDP power off delay if panel is on
Merge branch 'edp-training-fixes' into drm-intel-next
Merge branch 'fix-pch-refclk' into foo
Kenneth Graunke (2):
drm/i915: Remove implied length of 2 from GFX_OP_PIPE_CONTROL #define.
drm/i915: Rename PIPE_CONTROL bit defines to be less terse.
Takashi Iwai (1):
drm/i915/panel: Always record the backlight level again (but cleverly)
drivers/char/agp/intel-gtt.c | 28 ++
drivers/gpu/drm/i915/i915_dma.c | 4 +-
drivers/gpu/drm/i915/i915_drv.c | 47 +++-
drivers/gpu/drm/i915/i915_drv.h | 31 +--
drivers/gpu/drm/i915/i915_gem.c | 16 +-
drivers/gpu/drm/i915/i915_gem_debug.c | 6 +-
drivers/gpu/drm/i915/i915_gem_gtt.c | 30 ++
drivers/gpu/drm/i915/i915_gem_tiling.c | 15 +-
drivers/gpu/drm/i915/i915_irq.c | 36 ++-
drivers/gpu/drm/i915/i915_reg.h | 65 +++-
drivers/gpu/drm/i915/intel_bios.c | 19 +-
drivers/gpu/drm/i915/intel_bios.h | 20 +-
drivers/gpu/drm/i915/intel_crt.c | 18 +-
drivers/gpu/drm/i915/intel_display.c | 409 +++++++++++++++------
drivers/gpu/drm/i915/intel_dp.c | 588 +++++++++++++++++++++++--------
drivers/gpu/drm/i915/intel_drv.h | 7 +-
drivers/gpu/drm/i915/intel_hdmi.c | 30 +-
drivers/gpu/drm/i915/intel_i2c.c | 8 +-
drivers/gpu/drm/i915/intel_lvds.c | 8 +-
drivers/gpu/drm/i915/intel_panel.c | 21 +-
drivers/gpu/drm/i915/intel_ringbuffer.c | 150 +++++++-
drivers/gpu/drm/i915/intel_sdvo.c | 21 +-
drivers/iommu/intel-iommu.c | 31 +-
include/drm/drm_dp_helper.h | 61 ++++
include/drm/intel-gtt.h | 2 +
include/linux/io-mapping.h | 4 +
26 files changed, 1244 insertions(+), 431 deletions(-)
--
keith.packard@intel.com
[-- Attachment #2: Type: application/pgp-signature, Size: 827 bytes --]
^ permalink raw reply
* Re: [22/27] VFS: Fix automount for negative autofs dentries
From: Linus Torvalds @ 2011-10-23 7:35 UTC (permalink / raw)
To: Greg KH
Cc: linux-kernel, stable, stable-review, akpm, alan, David Howells,
Ian Kent, Al Viro, Chuck Ebbert, Miklos Szeredi, Trond Myklebust
In-Reply-To: <20111023062540.684446582@pistachio.kroah.org>
This one is debatable.
I think it also wants
- commit 0ec26fd0698285b31248e34bf1abb022c00f23d6 (with
LOOKUP_PARENT->LOOKUP_CONTINUE too)
- commit d94c177beeb4469cd4f6e83354ab0223353e98ed (to get the few
other cases right too)
anything else I missed?
Linus
On Sun, Oct 23, 2011 at 9:24 AM, Greg KH <gregkh@suse.de> wrote:
> 3.0-stable review patch. If anyone has any objections, please let us know.
>
> ------------------
>
> From: David Howells <dhowells@redhat.com>
>
> commit 5a30d8a2b8ddd5102c440c7e5a7c8e1fd729c818 upstream.
> [ backport for 3.0.x: LOOKUP_PARENT => LOOKUP_CONTINUE by Chuck Ebbert
> <cebbert@redhat.com> ]
>
> Autofs may set the DCACHE_NEED_AUTOMOUNT flag on negative dentries. These
> need attention from the automounter daemon regardless of the LOOKUP_FOLLOW flag.
>
> Signed-off-by: David Howells <dhowells@redhat.com>
> Acked-by: Ian Kent <raven@themaw.net>
> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
> Cc: Chuck Ebbert <cebbert@redhat.com>
> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
>
> ---
> fs/namei.c | 24 +++++++++++++++---------
> 1 file changed, 15 insertions(+), 9 deletions(-)
>
> --- a/fs/namei.c
> +++ b/fs/namei.c
> @@ -779,19 +779,25 @@ static int follow_automount(struct path
> if ((flags & LOOKUP_NO_AUTOMOUNT) && !(flags & LOOKUP_CONTINUE))
> return -EISDIR; /* we actually want to stop here */
>
> - /* We want to mount if someone is trying to open/create a file of any
> - * type under the mountpoint, wants to traverse through the mountpoint
> - * or wants to open the mounted directory.
> - *
> + /*
> * We don't want to mount if someone's just doing a stat and they've
> * set AT_SYMLINK_NOFOLLOW - unless they're stat'ing a directory and
> * appended a '/' to the name.
> */
> - if (!(flags & LOOKUP_FOLLOW) &&
> - !(flags & (LOOKUP_CONTINUE | LOOKUP_DIRECTORY |
> - LOOKUP_OPEN | LOOKUP_CREATE)))
> - return -EISDIR;
> -
> + if (!(flags & LOOKUP_FOLLOW)) {
> + /* We do, however, want to mount if someone wants to open or
> + * create a file of any type under the mountpoint, wants to
> + * traverse through the mountpoint or wants to open the mounted
> + * directory.
> + * Also, autofs may mark negative dentries as being automount
> + * points. These will need the attentions of the daemon to
> + * instantiate them before they can be used.
> + */
> + if (!(flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY |
> + LOOKUP_OPEN | LOOKUP_CREATE)) &&
> + path->dentry->d_inode)
> + return -EISDIR;
> + }
> current->total_link_count++;
> if (current->total_link_count >= 40)
> return -ELOOP;
>
>
>
^ permalink raw reply
* RE: vmenter/exit
From: Zhang, Xiantao @ 2011-10-23 7:36 UTC (permalink / raw)
To: kvm-ia64
In-Reply-To: <CALKntY0BvJLg-T44gScUhjyX_K6fPUbwsPd_anUSB3GjiNVE8A@mail.gmail.com>
This list is for kvm ia64 not for x86_64, and maybe you need to send a detailed question to kvm@vger.kernel.org. Thanks!
Xiantao
-----Original Message-----
From: kvm-ia64-owner@vger.kernel.org [mailto:kvm-ia64-owner@vger.kernel.org] On Behalf Of Xin Tong
Sent: Sunday, October 23, 2011 1:01 AM
To: kvm-ia64@vger.kernel.org
Subject: vmenter/exit
I would like to know the latest numbers on vmeter/exit for x86_64
Thanks
Xin
--
To unsubscribe from this list: send the line "unsubscribe kvm-ia64" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [Qemu-devel] [Spice-devel] Possible SPICE/QEMU deadlock on fast client reconnect
From: Yonit Halperin @ 2011-10-23 7:37 UTC (permalink / raw)
To: Daniel P. Berrange; +Cc: spice-devel, qemu-devel
In-Reply-To: <20111021152627.GF23627@redhat.com>
Hi,
Sounds like https://bugzilla.redhat.com/show_bug.cgi?id=746950 and
https://bugs.freedesktop.org/show_bug.cgi?id=41858
Alon's patch:
http://lists.freedesktop.org/archives/spice-devel/2011-September
/005369.html
Should solve it.
Cheers,
Yonit.
On 10/21/2011 05:26 PM, Daniel P. Berrange wrote:
> In testing my patches for 'add_client' support with SPICE, I noticed
> deadlock in the QEMU/SPICE code. It only happens if I close a SPICE
> client and then immediately reconnect within about 1 second. If I
> wait a couple of seconds before reconnecting the SPICE client I don't
> see the deadlock.
>
> I'm using QEMU& SPICE git master, and GDB has this to say
>
> (gdb) thread apply all bt
>
> Thread 3 (Thread 0x7f269e142700 (LWP 17233)):
> #0 pthread_cond_wait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:165
> #1 0x00000000004e80e9 in qemu_cond_wait (cond=<optimized out>, mutex=<optimized out>)
> at qemu-thread-posix.c:113
> #2 0x0000000000556469 in qemu_kvm_wait_io_event (env=<optimized out>)
> at /home/berrange/src/virt/qemu/cpus.c:626
> #3 qemu_kvm_cpu_thread_fn (arg=0x29217a0) at /home/berrange/src/virt/qemu/cpus.c:661
> #4 0x0000003a83207b31 in start_thread (arg=0x7f269e142700) at pthread_create.c:305
> #5 0x0000003a82edfd2d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:115
>
> Thread 2 (Thread 0x7f26822fc700 (LWP 17234)):
> #0 __lll_lock_wait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:140
> #1 0x0000003a83209ad6 in _L_lock_752 () from /lib64/libpthread.so.0
> #2 0x0000003a832099d7 in __pthread_mutex_lock (mutex=0x1182f60) at pthread_mutex_lock.c:65
> #3 0x00000000004e7ec9 in qemu_mutex_lock (mutex=<optimized out>) at qemu-thread-posix.c:54
> #4 0x0000000000507df5 in channel_event (event=3, info=0x2a3c610) at ui/spice-core.c:234
> #5 0x00007f269f77be87 in reds_stream_free (s=0x2a3c590) at reds.c:4073
> #6 0x00007f269f75b64f in red_channel_client_disconnect (rcc=0x7f267c069ec0) at red_channel.c:961
> #7 0x00007f269f75a131 in red_peer_handle_incoming (handler=0x7f267c06a5a0, stream=0x2a3c590)
> at red_channel.c:150
> #8 red_channel_client_receive (rcc=0x7f267c069ec0) at red_channel.c:158
> #9 0x00007f269f761fbc in handle_channel_events (in_listener=0x7f267c06a5f8, events=<optimized out>)
> at red_worker.c:9566
> #10 0x00007f269f776672 in red_worker_main (arg=<optimized out>) at red_worker.c:10813
> #11 0x0000003a83207b31 in start_thread (arg=0x7f26822fc700) at pthread_create.c:305
> #12 0x0000003a82edfd2d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:115
>
> Thread 1 (Thread 0x7f269f72e9c0 (LWP 17232)):
> #0 0x0000003a8320e01d in read () at ../sysdeps/unix/syscall-template.S:82
> #1 0x00007f269f75daaa in receive_data (n=4, in_buf=0x7fffe7a5a02c, fd=18) at red_worker.h:150
> #2 read_message (message=0x7fffe7a5a02c, fd=18) at red_worker.h:163
> #3 red_dispatcher_disconnect_cursor_peer (rcc=0x7f267c0c0f60) at red_dispatcher.c:157
> #4 0x00007f269f75c20d in red_client_destroy (client=0x2a35400) at red_channel.c:1189
> #5 0x00007f269f778335 in reds_client_disconnect (client=0x2a35400) at reds.c:624
> ---Type<return> to continue, or q<return> to quit---
> #6 0x00007f269f75a131 in red_peer_handle_incoming (handler=0x2a35b50, stream=0x2b037d0) at red_channel.c:150
> #7 red_channel_client_receive (rcc=0x2a35470) at red_channel.c:158
> #8 0x00007f269f75b1e8 in red_channel_client_event (fd=<optimized out>, event=<optimized out>,
> data=<optimized out>) at red_channel.c:774
> #9 0x000000000045e561 in fd_trampoline (chan=<optimized out>, cond=<optimized out>, opaque=<optimized out>)
> at iohandler.c:97
> #10 0x0000003a84e427ed in g_main_dispatch (context=0x27fc510) at gmain.c:2441
> #11 g_main_context_dispatch (context=0x27fc510) at gmain.c:3014
> #12 0x00000000004c3da3 in glib_select_poll (err=false, xfds=0x7fffe7a5a2e0, wfds=0x7fffe7a5a260, rfds=
> 0x7fffe7a5a1e0) at /home/berrange/src/virt/qemu/vl.c:1495
> #13 main_loop_wait (nonblocking=<optimized out>) at /home/berrange/src/virt/qemu/vl.c:1541
> #14 0x000000000040fdd1 in main_loop () at /home/berrange/src/virt/qemu/vl.c:1570
> #15 main (argc=<optimized out>, argv=<optimized out>, envp=<optimized out>)
> at /home/berrange/src/virt/qemu/vl.c:3563
> (gdb)
>
>
^ permalink raw reply
* Re: Linux 3.1-rc10
From: Linus Torvalds @ 2011-10-23 7:42 UTC (permalink / raw)
To: Dave Airlie; +Cc: Valdis.Kletnieks, Linux Kernel Mailing List
In-Reply-To: <CAPM=9tympvK8O3NC20CFG-2TutozHUKZTird7MpNUQi5BY=sww@mail.gmail.com>
On Sun, Oct 23, 2011 at 9:16 AM, Dave Airlie <airlied@gmail.com> wrote:
>
> Are you going to accept pull requests from non-k.org remotes?
For something like freedesktop.org, I have no trouble at all. It's the
totally anonymous trees that I don't want to worry about - they've
been ok for the later part of the -rc stage, when the commits are few
and small and I can just verify that it all looks ok, but for big
changes I definitely want more of a trustworthy source.
Oh, but make sure your pull requests are valid. Look at the pull
requests you've been sending me: they have things like "~/" in them,
which probably works for you, but does *not* work for me. You need to
make it "~airlied/" or whatever. Again, fixing things like that up is
fine when I only have a few small pull requests, but it's a major pain
in the rear during the chaos that is the merge window.
Thanks,
Linus
^ permalink raw reply
* how stable are snapshots at the block level?
From: Mathijs Kwik @ 2011-10-23 7:45 UTC (permalink / raw)
To: linux-btrfs
Hi all,
I'm currently doing backups by doing a btrfs snapshot, then rsync the
snapshot to my backup location.
As I have a lot of small files and quite some changes between
snapshots, this process is taking more and more time.
I looked at "btrfs find-new", which is promissing, but I need
something to track deletes and modifications too.
Also, while this will help the initial comparison phase, most time is
still spent on the syncing itself, as a lot of overhead is caused by
the tiny files.
After finding some discussion about it here:
http://www.backupcentral.com/phpBB2/two-way-mirrors-of-external-mailing-lists-3/backuppc-21/using-rsync-for-blockdevice-level-synchronisation-of-backupp-100438
I found that the official rsync-patches tarball includes the patch
that allows syncing full block devices.
After the initial backup, I found that this indeed speeds up my backups a lot.
Ofcourse this is meant for syncing unmounted filesystems (or other
things that are "stable" at the block level, like LVM snapshot
volumes).
I tested backing up a live btrfs filesystem by making a btrfs
snapshot, and this (very simple, non-thorough) turned out to work ok.
My root subvolume contains the "current" subvolume (which I mount) and
several backup subvolumes.
Ofcourse I understand that the "current" subvolume on the backup
destination is broken/inconsistent, as I change it during the rsync
run. But when I mounted the backup disk and compared the subvolumes
using normal file-by-file rsync, they were identical.
Can someone with knowledge about the on-disk structure please
confirm/reject that subvolumes (created before starting rsync on the
block device) should be safe and never move by themselves? Or was I
just lucky?
Are there any things that might break the backup when performed during rsync?
Like creating/deleting other subvolumes, probably defrag isn't a good
idea either :)
Or any incompatible mount options (compression, space_cache, ssd)
Thanks for any comments on this.
Mathijs
^ permalink raw reply
* [PATCH] NFC: update to NCI spec 1.0 draft 18
From: ilanelias78 @ 2011-10-23 7:46 UTC (permalink / raw)
To: aloisio.almeida, lauro.venancio, samuel, linville
Cc: linux-wireless, Ilan Elias
From: Ilan Elias <ilane@ti.com>
Signed-off-by: Ilan Elias <ilane@ti.com>
---
include/net/nfc/nci.h | 208 ++++++++++++++++++++++---------------------
include/net/nfc/nci_core.h | 13 +--
net/nfc/nci/core.c | 17 ++--
net/nfc/nci/data.c | 5 +-
net/nfc/nci/lib.c | 8 +--
net/nfc/nci/ntf.c | 152 +++++++++++++++++++-------------
net/nfc/nci/rsp.c | 149 ++++++++++++++-----------------
7 files changed, 281 insertions(+), 271 deletions(-)
diff --git a/include/net/nfc/nci.h b/include/net/nfc/nci.h
index 39b85bc..e4a2632 100644
--- a/include/net/nfc/nci.h
+++ b/include/net/nfc/nci.h
@@ -33,47 +33,49 @@
#define NCI_MAX_NUM_RF_CONFIGS 10
#define NCI_MAX_NUM_CONN 10
-/* NCI Status Codes */
-#define NCI_STATUS_OK 0x00
-#define NCI_STATUS_REJECTED 0x01
-#define NCI_STATUS_MESSAGE_CORRUPTED 0x02
-#define NCI_STATUS_BUFFER_FULL 0x03
-#define NCI_STATUS_FAILED 0x04
-#define NCI_STATUS_NOT_INITIALIZED 0x05
-#define NCI_STATUS_SYNTAX_ERROR 0x06
-#define NCI_STATUS_SEMANTIC_ERROR 0x07
-#define NCI_STATUS_UNKNOWN_GID 0x08
-#define NCI_STATUS_UNKNOWN_OID 0x09
-#define NCI_STATUS_INVALID_PARAM 0x0a
-#define NCI_STATUS_MESSAGE_SIZE_EXCEEDED 0x0b
-/* Discovery Specific Status Codes */
-#define NCI_STATUS_DISCOVERY_ALREADY_STARTED 0xa0
-#define NCI_STATUS_DISCOVERY_TARGET_ACTIVATION_FAILED 0xa1
+/* Generic Status Codes */
+#define NCI_STATUS_OK 0x00
+#define NCI_STATUS_REJECTED 0x01
+#define NCI_STATUS_RF_FRAME_CORRUPTED 0x02
+#define NCI_STATUS_FAILED 0x03
+#define NCI_STATUS_NOT_INITIALIZED 0x04
+#define NCI_STATUS_SYNTAX_ERROR 0x05
+#define NCI_STATUS_SEMANTIC_ERROR 0x06
+#define NCI_STATUS_UNKNOWN_GID 0x07
+#define NCI_STATUS_UNKNOWN_OID 0x08
+#define NCI_STATUS_INVALID_PARAM 0x09
+#define NCI_STATUS_MESSAGE_SIZE_EXCEEDED 0x0a
+/* RF Discovery Specific Status Codes */
+#define NCI_STATUS_DISCOVERY_ALREADY_STARTED 0xa0
+#define NCI_STATUS_DISCOVERY_TARGET_ACTIVATION_FAILED 0xa1
+#define NCI_STATUS_DISCOVERY_TEAR_DOWN 0xa2
/* RF Interface Specific Status Codes */
-#define NCI_STATUS_RF_TRANSMISSION_ERROR 0xb0
-#define NCI_STATUS_RF_PROTOCOL_ERROR 0xb1
-#define NCI_STATUS_RF_TIMEOUT_ERROR 0xb2
-#define NCI_STATUS_RF_LINK_LOSS_ERROR 0xb3
+#define NCI_STATUS_RF_TRANSMISSION_ERROR 0xb0
+#define NCI_STATUS_RF_PROTOCOL_ERROR 0xb1
+#define NCI_STATUS_RF_TIMEOUT_ERROR 0xb2
/* NFCEE Interface Specific Status Codes */
-#define NCI_STATUS_MAX_ACTIVE_NFCEE_INTERFACES_REACHED 0xc0
-#define NCI_STATUS_NFCEE_INTERFACE_ACTIVATION_FAILED 0xc1
-#define NCI_STATUS_NFCEE_TRANSMISSION_ERROR 0xc2
-#define NCI_STATUS_NFCEE_PROTOCOL_ERROR 0xc3
+#define NCI_STATUS_MAX_ACTIVE_NFCEE_INTERFACES_REACHED 0xc0
+#define NCI_STATUS_NFCEE_INTERFACE_ACTIVATION_FAILED 0xc1
+#define NCI_STATUS_NFCEE_TRANSMISSION_ERROR 0xc2
+#define NCI_STATUS_NFCEE_PROTOCOL_ERROR 0xc3
#define NCI_STATUS_NFCEE_TIMEOUT_ERROR 0xc4
-/* NCI RF Technology and Mode */
-#define NCI_NFC_A_PASSIVE_POLL_MODE 0x00
-#define NCI_NFC_B_PASSIVE_POLL_MODE 0x01
-#define NCI_NFC_F_PASSIVE_POLL_MODE 0x02
-#define NCI_NFC_A_ACTIVE_POLL_MODE 0x03
-#define NCI_NFC_F_ACTIVE_POLL_MODE 0x05
-#define NCI_NFC_A_PASSIVE_LISTEN_MODE 0x80
-#define NCI_NFC_B_PASSIVE_LISTEN_MODE 0x81
-#define NCI_NFC_F_PASSIVE_LISTEN_MODE 0x82
-#define NCI_NFC_A_ACTIVE_LISTEN_MODE 0x83
-#define NCI_NFC_F_ACTIVE_LISTEN_MODE 0x85
-
-/* NCI RF Protocols */
+/* RF Technologies */
+#define NCI_NFC_RF_TECHNOLOGY_A 0x00
+#define NCI_NFC_RF_TECHNOLOGY_B 0x01
+#define NCI_NFC_RF_TECHNOLOGY_F 0x02
+#define NCI_NFC_RF_TECHNOLOGY_15693 0x03
+
+/* Bit Rates */
+#define NCI_NFC_BIT_RATE_106 0x00
+#define NCI_NFC_BIT_RATE_212 0x01
+#define NCI_NFC_BIT_RATE_424 0x02
+#define NCI_NFC_BIT_RATE_848 0x03
+#define NCI_NFC_BIT_RATE_1696 0x04
+#define NCI_NFC_BIT_RATE_3392 0x05
+#define NCI_NFC_BIT_RATE_6784 0x06
+
+/* RF Protocols */
#define NCI_RF_PROTOCOL_UNKNOWN 0x00
#define NCI_RF_PROTOCOL_T1T 0x01
#define NCI_RF_PROTOCOL_T2T 0x02
@@ -81,38 +83,54 @@
#define NCI_RF_PROTOCOL_ISO_DEP 0x04
#define NCI_RF_PROTOCOL_NFC_DEP 0x05
-/* NCI RF Interfaces */
-#define NCI_RF_INTERFACE_RFU 0x00
-#define NCI_RF_INTERFACE_FRAME 0x01
-#define NCI_RF_INTERFACE_ISO_DEP 0x02
-#define NCI_RF_INTERFACE_NFC_DEP 0x03
+/* RF Interfaces */
+#define NCI_RF_INTERFACE_NFCEE_DIRECT 0x00
+#define NCI_RF_INTERFACE_FRAME 0x01
+#define NCI_RF_INTERFACE_ISO_DEP 0x02
+#define NCI_RF_INTERFACE_NFC_DEP 0x03
-/* NCI RF_DISCOVER_MAP_CMD modes */
+/* Reset types */
+#define NCI_RESET_TYPE_KEEP_CONFIG 0x00
+#define NCI_RESET_TYPE_RESET_CONFIG 0x01
+
+/* Static RF connection ID */
+#define NCI_STATIC_RF_CONN_ID 0x00
+
+/* RF_DISCOVER_MAP_CMD modes */
#define NCI_DISC_MAP_MODE_POLL 0x01
#define NCI_DISC_MAP_MODE_LISTEN 0x02
#define NCI_DISC_MAP_MODE_BOTH 0x03
-/* NCI Discovery Types */
+/* Discovery Types */
#define NCI_DISCOVERY_TYPE_POLL_A_PASSIVE 0x00
-#define NCI_DISCOVERY_TYPE_POLL_B_PASSIVE 0x01
-#define NCI_DISCOVERY_TYPE_POLL_F_PASSIVE 0x02
-#define NCI_DISCOVERY_TYPE_POLL_A_ACTIVE 0x03
-#define NCI_DISCOVERY_TYPE_POLL_F_ACTIVE 0x05
-#define NCI_DISCOVERY_TYPE_WAKEUP_A_PASSIVE 0x06
-#define NCI_DISCOVERY_TYPE_WAKEUP_B_PASSIVE 0x07
-#define NCI_DISCOVERY_TYPE_WAKEUP_A_ACTIVE 0x09
-#define NCI_DISCOVERY_TYPE_LISTEN_A_PASSIVE 0x80
-#define NCI_DISCOVERY_TYPE_LISTEN_B_PASSIVE 0x81
-#define NCI_DISCOVERY_TYPE_LISTEN_F_PASSIVE 0x82
-#define NCI_DISCOVERY_TYPE_LISTEN_A_ACTIVE 0x83
-#define NCI_DISCOVERY_TYPE_LISTEN_F_ACTIVE 0x85
-
-/* NCI Deactivation Type */
-#define NCI_DEACTIVATE_TYPE_IDLE_MODE 0x00
-#define NCI_DEACTIVATE_TYPE_SLEEP_MODE 0x01
-#define NCI_DEACTIVATE_TYPE_SLEEP_AF_MODE 0x02
-#define NCI_DEACTIVATE_TYPE_RF_LINK_LOSS 0x03
-#define NCI_DEACTIVATE_TYPE_DISCOVERY_ERROR 0x04
+#define NCI_DISCOVERY_TYPE_POLL_B_PASSIVE 0x01
+#define NCI_DISCOVERY_TYPE_POLL_F_PASSIVE 0x02
+#define NCI_DISCOVERY_TYPE_POLL_A_ACTIVE 0x03
+#define NCI_DISCOVERY_TYPE_POLL_F_ACTIVE 0x05
+#define NCI_DISCOVERY_TYPE_WAKEUP_A_ACTIVE 0x09
+#define NCI_DISCOVERY_TYPE_LISTEN_A_PASSIVE 0x80
+#define NCI_DISCOVERY_TYPE_LISTEN_B_PASSIVE 0x81
+#define NCI_DISCOVERY_TYPE_LISTEN_F_PASSIVE 0x82
+#define NCI_DISCOVERY_TYPE_LISTEN_A_ACTIVE 0x83
+#define NCI_DISCOVERY_TYPE_LISTEN_F_ACTIVE 0x85
+
+/* RF Technology and Mode */
+#define NCI_NFC_A_PASSIVE_POLL_MODE 0x00
+#define NCI_NFC_B_PASSIVE_POLL_MODE 0x01
+#define NCI_NFC_F_PASSIVE_POLL_MODE 0x02
+#define NCI_NFC_A_ACTIVE_POLL_MODE 0x03
+#define NCI_NFC_F_ACTIVE_POLL_MODE 0x05
+#define NCI_NFC_A_PASSIVE_LISTEN_MODE 0x80
+#define NCI_NFC_B_PASSIVE_LISTEN_MODE 0x81
+#define NCI_NFC_F_PASSIVE_LISTEN_MODE 0x82
+#define NCI_NFC_A_ACTIVE_LISTEN_MODE 0x83
+#define NCI_NFC_F_ACTIVE_LISTEN_MODE 0x85
+
+/* Deactivation Type */
+#define NCI_DEACTIVATE_TYPE_IDLE_MODE 0x00
+#define NCI_DEACTIVATE_TYPE_SLEEP_MODE 0x01
+#define NCI_DEACTIVATE_TYPE_SLEEP_AF_MODE 0x02
+#define NCI_DEACTIVATE_TYPE_DISCOVERY 0x03
/* Message Type (MT) */
#define NCI_MT_DATA_PKT 0x00
@@ -144,10 +162,10 @@
#define nci_conn_id(hdr) (__u8)(((hdr)[0])&0x0f)
/* GID values */
-#define NCI_GID_CORE 0x0
-#define NCI_GID_RF_MGMT 0x1
-#define NCI_GID_NFCEE_MGMT 0x2
-#define NCI_GID_PROPRIETARY 0xf
+#define NCI_GID_CORE 0x0
+#define NCI_GID_RF_MGMT 0x1
+#define NCI_GID_NFCEE_MGMT 0x2
+#define NCI_GID_PROPRIETARY 0xf
/* ---- NCI Packet structures ---- */
#define NCI_CTRL_HDR_SIZE 3
@@ -169,18 +187,11 @@ struct nci_data_hdr {
/* ----- NCI Commands ---- */
/* ------------------------ */
#define NCI_OP_CORE_RESET_CMD nci_opcode_pack(NCI_GID_CORE, 0x00)
-
-#define NCI_OP_CORE_INIT_CMD nci_opcode_pack(NCI_GID_CORE, 0x01)
-
-#define NCI_OP_CORE_SET_CONFIG_CMD nci_opcode_pack(NCI_GID_CORE, 0x02)
-
-#define NCI_OP_CORE_CONN_CREATE_CMD nci_opcode_pack(NCI_GID_CORE, 0x04)
-struct nci_core_conn_create_cmd {
- __u8 target_handle;
- __u8 num_target_specific_params;
+struct nci_core_reset_cmd {
+ __u8 reset_type;
} __packed;
-#define NCI_OP_CORE_CONN_CLOSE_CMD nci_opcode_pack(NCI_GID_CORE, 0x06)
+#define NCI_OP_CORE_INIT_CMD nci_opcode_pack(NCI_GID_CORE, 0x01)
#define NCI_OP_RF_DISCOVER_MAP_CMD nci_opcode_pack(NCI_GID_RF_MGMT, 0x00)
struct disc_map_config {
@@ -218,6 +229,7 @@ struct nci_rf_deactivate_cmd {
struct nci_core_reset_rsp {
__u8 status;
__u8 nci_ver;
+ __u8 config_status;
} __packed;
#define NCI_OP_CORE_INIT_RSP nci_opcode_pack(NCI_GID_CORE, 0x01)
@@ -232,24 +244,14 @@ struct nci_core_init_rsp_1 {
struct nci_core_init_rsp_2 {
__u8 max_logical_connections;
__le16 max_routing_table_size;
- __u8 max_control_packet_payload_length;
- __le16 rf_sending_buffer_size;
- __le16 rf_receiving_buffer_size;
- __le16 manufacturer_id;
-} __packed;
-
-#define NCI_OP_CORE_SET_CONFIG_RSP nci_opcode_pack(NCI_GID_CORE, 0x02)
-
-#define NCI_OP_CORE_CONN_CREATE_RSP nci_opcode_pack(NCI_GID_CORE, 0x04)
-struct nci_core_conn_create_rsp {
- __u8 status;
- __u8 max_pkt_payload_size;
+ __u8 max_control_pkt_payload_len;
+ __le16 max_size_for_large_params;
+ __u8 max_data_pkt_payload_size;
__u8 initial_num_credits;
- __u8 conn_id;
+ __u8 manufacturer_id;
+ __le32 manufacturer_specific_info;
} __packed;
-#define NCI_OP_CORE_CONN_CLOSE_RSP nci_opcode_pack(NCI_GID_CORE, 0x06)
-
#define NCI_OP_RF_DISCOVER_MAP_RSP nci_opcode_pack(NCI_GID_RF_MGMT, 0x00)
#define NCI_OP_RF_DISCOVER_RSP nci_opcode_pack(NCI_GID_RF_MGMT, 0x03)
@@ -270,12 +272,7 @@ struct nci_core_conn_credit_ntf {
struct conn_credit_entry conn_entries[NCI_MAX_NUM_CONN];
} __packed;
-#define NCI_OP_RF_FIELD_INFO_NTF nci_opcode_pack(NCI_GID_CORE, 0x08)
-struct nci_rf_field_info_ntf {
- __u8 rf_field_status;
-} __packed;
-
-#define NCI_OP_RF_ACTIVATE_NTF nci_opcode_pack(NCI_GID_RF_MGMT, 0x05)
+#define NCI_OP_RF_INTF_ACTIVATED_NTF nci_opcode_pack(NCI_GID_RF_MGMT, 0x05)
struct rf_tech_specific_params_nfca_poll {
__u16 sens_res;
__u8 nfcid1_len; /* 0, 4, 7, or 10 Bytes */
@@ -289,17 +286,20 @@ struct activation_params_nfca_poll_iso_dep {
__u8 rats_res[20];
};
-struct nci_rf_activate_ntf {
- __u8 target_handle;
+struct nci_rf_intf_activated_ntf {
+ __u8 rf_discovery_id;
+ __u8 rf_interface_type;
__u8 rf_protocol;
- __u8 rf_tech_and_mode;
+ __u8 activation_rf_tech_and_mode;
__u8 rf_tech_specific_params_len;
union {
struct rf_tech_specific_params_nfca_poll nfca_poll;
} rf_tech_specific_params;
- __u8 rf_interface_type;
+ __u8 data_exchange_rf_tech_and_mode;
+ __u8 data_exchange_tx_bit_rate;
+ __u8 data_exchange_rx_bit_rate;
__u8 activation_params_len;
union {
@@ -309,5 +309,9 @@ struct nci_rf_activate_ntf {
} __packed;
#define NCI_OP_RF_DEACTIVATE_NTF nci_opcode_pack(NCI_GID_RF_MGMT, 0x06)
+struct nci_rf_deactivate_ntf {
+ __u8 type;
+ __u8 reason;
+} __packed;
#endif /* __NCI_H */
diff --git a/include/net/nfc/nci_core.h b/include/net/nfc/nci_core.h
index b8b4bbd..77b7c9e 100644
--- a/include/net/nfc/nci_core.h
+++ b/include/net/nfc/nci_core.h
@@ -109,15 +109,12 @@ struct nci_dev {
[NCI_MAX_SUPPORTED_RF_INTERFACES];
__u8 max_logical_connections;
__u16 max_routing_table_size;
- __u8 max_control_packet_payload_length;
- __u16 rf_sending_buffer_size;
- __u16 rf_receiving_buffer_size;
- __u16 manufacturer_id;
-
- /* received during NCI_OP_CORE_CONN_CREATE_RSP for static conn 0 */
- __u8 max_pkt_payload_size;
+ __u8 max_control_pkt_payload_len;
+ __u16 max_size_for_large_params;
+ __u8 max_data_pkt_payload_size;
__u8 initial_num_credits;
- __u8 conn_id;
+ __u8 manufacturer_id;
+ __u32 manufacturer_specific_info;
/* stored during nci_data_exchange */
data_exchange_cb_t data_exchange_cb;
diff --git a/net/nfc/nci/core.c b/net/nfc/nci/core.c
index 4047e29..056cd37 100644
--- a/net/nfc/nci/core.c
+++ b/net/nfc/nci/core.c
@@ -125,7 +125,10 @@ static inline int nci_request(struct nci_dev *ndev,
static void nci_reset_req(struct nci_dev *ndev, unsigned long opt)
{
- nci_send_cmd(ndev, NCI_OP_CORE_RESET_CMD, 0, NULL);
+ struct nci_core_reset_cmd cmd;
+
+ cmd.reset_type = NCI_RESET_TYPE_RESET_CONFIG;
+ nci_send_cmd(ndev, NCI_OP_CORE_RESET_CMD, 1, &cmd);
}
static void nci_init_req(struct nci_dev *ndev, unsigned long opt)
@@ -135,17 +138,11 @@ static void nci_init_req(struct nci_dev *ndev, unsigned long opt)
static void nci_init_complete_req(struct nci_dev *ndev, unsigned long opt)
{
- struct nci_core_conn_create_cmd conn_cmd;
struct nci_rf_disc_map_cmd cmd;
struct disc_map_config *cfg = cmd.mapping_configs;
__u8 *num = &cmd.num_mapping_configs;
int i;
- /* create static rf connection */
- conn_cmd.target_handle = 0;
- conn_cmd.num_target_specific_params = 0;
- nci_send_cmd(ndev, NCI_OP_CORE_CONN_CREATE_CMD, 2, &conn_cmd);
-
/* set rf mapping configurations */
*num = 0;
@@ -469,7 +466,7 @@ static int nci_data_exchange(struct nfc_dev *nfc_dev, __u32 target_idx,
ndev->data_exchange_cb = cb;
ndev->data_exchange_cb_context = cb_context;
- rc = nci_send_data(ndev, ndev->conn_id, skb);
+ rc = nci_send_data(ndev, NCI_STATIC_RF_CONN_ID, skb);
if (rc)
clear_bit(NCI_DATA_EXCHANGE, &ndev->flags);
@@ -725,7 +722,9 @@ static void nci_tx_work(struct work_struct *work)
if (!skb)
return;
- atomic_dec(&ndev->credits_cnt);
+ /* Check if data flow control is used */
+ if (atomic_read(&ndev->credits_cnt) != 0xff)
+ atomic_dec(&ndev->credits_cnt);
nfc_dbg("NCI TX: MT=data, PBF=%d, conn_id=%d, plen=%d",
nci_pbf(skb->data),
diff --git a/net/nfc/nci/data.c b/net/nfc/nci/data.c
index e5ed90f..511fb96 100644
--- a/net/nfc/nci/data.c
+++ b/net/nfc/nci/data.c
@@ -95,7 +95,8 @@ static int nci_queue_tx_data_frags(struct nci_dev *ndev,
__skb_queue_head_init(&frags_q);
while (total_len) {
- frag_len = min_t(int, total_len, ndev->max_pkt_payload_size);
+ frag_len =
+ min_t(int, total_len, ndev->max_data_pkt_payload_size);
skb_frag = nci_skb_alloc(ndev,
(NCI_DATA_HDR_SIZE + frag_len),
@@ -151,7 +152,7 @@ int nci_send_data(struct nci_dev *ndev, __u8 conn_id, struct sk_buff *skb)
nfc_dbg("entry, conn_id 0x%x, plen %d", conn_id, skb->len);
/* check if the packet need to be fragmented */
- if (skb->len <= ndev->max_pkt_payload_size) {
+ if (skb->len <= ndev->max_data_pkt_payload_size) {
/* no need to fragment packet */
nci_push_data_hdr(ndev, conn_id, skb, NCI_PBF_LAST);
diff --git a/net/nfc/nci/lib.c b/net/nfc/nci/lib.c
index b19dc2f..e99adcf 100644
--- a/net/nfc/nci/lib.c
+++ b/net/nfc/nci/lib.c
@@ -42,12 +42,9 @@ int nci_to_errno(__u8 code)
case NCI_STATUS_REJECTED:
return -EBUSY;
- case NCI_STATUS_MESSAGE_CORRUPTED:
+ case NCI_STATUS_RF_FRAME_CORRUPTED:
return -EBADMSG;
- case NCI_STATUS_BUFFER_FULL:
- return -ENOBUFS;
-
case NCI_STATUS_NOT_INITIALIZED:
return -EHOSTDOWN;
@@ -80,9 +77,6 @@ int nci_to_errno(__u8 code)
case NCI_STATUS_NFCEE_TIMEOUT_ERROR:
return -ETIMEDOUT;
- case NCI_STATUS_RF_LINK_LOSS_ERROR:
- return -ENOLINK;
-
case NCI_STATUS_MAX_ACTIVE_NFCEE_INTERFACES_REACHED:
return -EDQUOT;
diff --git a/net/nfc/nci/ntf.c b/net/nfc/nci/ntf.c
index 96633f5..770dfc8 100644
--- a/net/nfc/nci/ntf.c
+++ b/net/nfc/nci/ntf.c
@@ -54,7 +54,7 @@ static void nci_core_conn_credits_ntf_packet(struct nci_dev *ndev,
ntf->conn_entries[i].conn_id,
ntf->conn_entries[i].credits);
- if (ntf->conn_entries[i].conn_id == ndev->conn_id) {
+ if (ntf->conn_entries[i].conn_id == NCI_STATIC_RF_CONN_ID) {
/* found static rf connection */
atomic_add(ntf->conn_entries[i].credits,
&ndev->credits_cnt);
@@ -66,22 +66,12 @@ static void nci_core_conn_credits_ntf_packet(struct nci_dev *ndev,
queue_work(ndev->tx_wq, &ndev->tx_work);
}
-static void nci_rf_field_info_ntf_packet(struct nci_dev *ndev,
- struct sk_buff *skb)
-{
- struct nci_rf_field_info_ntf *ntf = (void *) skb->data;
-
- nfc_dbg("entry, rf_field_status %d", ntf->rf_field_status);
-}
-
-static int nci_rf_activate_nfca_passive_poll(struct nci_dev *ndev,
- struct nci_rf_activate_ntf *ntf, __u8 *data)
+static __u8 *nci_extract_rf_params_nfca_passive_poll(struct nci_dev *ndev,
+ struct nci_rf_intf_activated_ntf *ntf, __u8 *data)
{
struct rf_tech_specific_params_nfca_poll *nfca_poll;
- struct activation_params_nfca_poll_iso_dep *nfca_poll_iso_dep;
nfca_poll = &ntf->rf_tech_specific_params.nfca_poll;
- nfca_poll_iso_dep = &ntf->activation_params.nfca_poll_iso_dep;
nfca_poll->sens_res = __le16_to_cpu(*((__u16 *)data));
data += 2;
@@ -100,32 +90,32 @@ static int nci_rf_activate_nfca_passive_poll(struct nci_dev *ndev,
if (nfca_poll->sel_res_len != 0)
nfca_poll->sel_res = *data++;
- ntf->rf_interface_type = *data++;
- ntf->activation_params_len = *data++;
-
- nfc_dbg("sel_res_len %d, sel_res 0x%x, rf_interface_type %d, activation_params_len %d",
+ nfc_dbg("sel_res_len %d, sel_res 0x%x",
nfca_poll->sel_res_len,
- nfca_poll->sel_res,
- ntf->rf_interface_type,
- ntf->activation_params_len);
-
- switch (ntf->rf_interface_type) {
- case NCI_RF_INTERFACE_ISO_DEP:
- nfca_poll_iso_dep->rats_res_len = *data++;
- if (nfca_poll_iso_dep->rats_res_len > 0) {
- memcpy(nfca_poll_iso_dep->rats_res,
+ nfca_poll->sel_res);
+
+ return data;
+}
+
+static int nci_extract_activation_params_iso_dep(struct nci_dev *ndev,
+ struct nci_rf_intf_activated_ntf *ntf, __u8 *data)
+{
+ struct activation_params_nfca_poll_iso_dep *nfca_poll;
+
+ switch (ntf->activation_rf_tech_and_mode) {
+ case NCI_NFC_A_PASSIVE_POLL_MODE:
+ nfca_poll = &ntf->activation_params.nfca_poll_iso_dep;
+ nfca_poll->rats_res_len = *data++;
+ if (nfca_poll->rats_res_len > 0) {
+ memcpy(nfca_poll->rats_res,
data,
- nfca_poll_iso_dep->rats_res_len);
+ nfca_poll->rats_res_len);
}
break;
- case NCI_RF_INTERFACE_FRAME:
- /* no activation params */
- break;
-
default:
- nfc_err("unsupported rf_interface_type 0x%x",
- ntf->rf_interface_type);
+ nfc_err("unsupported activation_rf_tech_and_mode 0x%x",
+ ntf->activation_rf_tech_and_mode);
return -EPROTO;
}
@@ -133,7 +123,7 @@ static int nci_rf_activate_nfca_passive_poll(struct nci_dev *ndev,
}
static void nci_target_found(struct nci_dev *ndev,
- struct nci_rf_activate_ntf *ntf)
+ struct nci_rf_intf_activated_ntf *ntf)
{
struct nfc_target nfc_tgt;
@@ -141,6 +131,8 @@ static void nci_target_found(struct nci_dev *ndev,
nfc_tgt.supported_protocols = NFC_PROTO_MIFARE_MASK;
else if (ntf->rf_protocol == NCI_RF_PROTOCOL_ISO_DEP) /* 4A */
nfc_tgt.supported_protocols = NFC_PROTO_ISO14443_MASK;
+ else
+ nfc_tgt.supported_protocols = 0;
nfc_tgt.sens_res = ntf->rf_tech_specific_params.nfca_poll.sens_res;
nfc_tgt.sel_res = ntf->rf_tech_specific_params.nfca_poll.sel_res;
@@ -158,49 +150,86 @@ static void nci_target_found(struct nci_dev *ndev,
nfc_targets_found(ndev->nfc_dev, &nfc_tgt, 1);
}
-static void nci_rf_activate_ntf_packet(struct nci_dev *ndev,
- struct sk_buff *skb)
+static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev,
+ struct sk_buff *skb)
{
- struct nci_rf_activate_ntf ntf;
+ struct nci_rf_intf_activated_ntf ntf;
__u8 *data = skb->data;
- int rc = -1;
+ int err = 0;
clear_bit(NCI_DISCOVERY, &ndev->flags);
set_bit(NCI_POLL_ACTIVE, &ndev->flags);
- ntf.target_handle = *data++;
+ ntf.rf_discovery_id = *data++;
+ ntf.rf_interface_type = *data++;
ntf.rf_protocol = *data++;
- ntf.rf_tech_and_mode = *data++;
+ ntf.activation_rf_tech_and_mode = *data++;
ntf.rf_tech_specific_params_len = *data++;
- nfc_dbg("target_handle %d, rf_protocol 0x%x, rf_tech_and_mode 0x%x, rf_tech_specific_params_len %d",
- ntf.target_handle,
- ntf.rf_protocol,
- ntf.rf_tech_and_mode,
+ nfc_dbg("rf_discovery_id %d", ntf.rf_discovery_id);
+ nfc_dbg("rf_interface_type 0x%x", ntf.rf_interface_type);
+ nfc_dbg("rf_protocol 0x%x", ntf.rf_protocol);
+ nfc_dbg("activation_rf_tech_and_mode 0x%x",
+ ntf.activation_rf_tech_and_mode);
+ nfc_dbg("rf_tech_specific_params_len %d",
ntf.rf_tech_specific_params_len);
- switch (ntf.rf_tech_and_mode) {
- case NCI_NFC_A_PASSIVE_POLL_MODE:
- rc = nci_rf_activate_nfca_passive_poll(ndev, &ntf,
- data);
- break;
+ if (ntf.rf_tech_specific_params_len > 0) {
+ switch (ntf.activation_rf_tech_and_mode) {
+ case NCI_NFC_A_PASSIVE_POLL_MODE:
+ data = nci_extract_rf_params_nfca_passive_poll(ndev,
+ &ntf, data);
+ break;
+
+ default:
+ nfc_err("unsupported activation_rf_tech_and_mode 0x%x",
+ ntf.activation_rf_tech_and_mode);
+ return;
+ }
+ }
- default:
- nfc_err("unsupported rf_tech_and_mode 0x%x",
- ntf.rf_tech_and_mode);
- return;
+ ntf.data_exchange_rf_tech_and_mode = *data++;
+ ntf.data_exchange_tx_bit_rate = *data++;
+ ntf.data_exchange_rx_bit_rate = *data++;
+ ntf.activation_params_len = *data++;
+
+ nfc_dbg("data_exchange_rf_tech_and_mode 0x%x",
+ ntf.data_exchange_rf_tech_and_mode);
+ nfc_dbg("data_exchange_tx_bit_rate 0x%x",
+ ntf.data_exchange_tx_bit_rate);
+ nfc_dbg("data_exchange_rx_bit_rate 0x%x",
+ ntf.data_exchange_rx_bit_rate);
+ nfc_dbg("activation_params_len %d",
+ ntf.activation_params_len);
+
+ if (ntf.activation_params_len > 0) {
+ switch (ntf.rf_interface_type) {
+ case NCI_RF_INTERFACE_ISO_DEP:
+ err = nci_extract_activation_params_iso_dep(ndev,
+ &ntf, data);
+ break;
+
+ case NCI_RF_INTERFACE_FRAME:
+ /* no activation params */
+ break;
+
+ default:
+ nfc_err("unsupported rf_interface_type 0x%x",
+ ntf.rf_interface_type);
+ return;
+ }
}
- if (!rc)
+ if (!err)
nci_target_found(ndev, &ntf);
}
static void nci_rf_deactivate_ntf_packet(struct nci_dev *ndev,
struct sk_buff *skb)
{
- __u8 type = skb->data[0];
+ struct nci_rf_deactivate_ntf *ntf = (void *) skb->data;
- nfc_dbg("entry, type 0x%x", type);
+ nfc_dbg("entry, type 0x%x, reason 0x%x", ntf->type, ntf->reason);
clear_bit(NCI_POLL_ACTIVE, &ndev->flags);
ndev->target_active_prot = 0;
@@ -214,6 +243,9 @@ static void nci_rf_deactivate_ntf_packet(struct nci_dev *ndev,
ndev->rx_data_reassembly = 0;
}
+ /* set the available credits to initial value */
+ atomic_set(&ndev->credits_cnt, ndev->initial_num_credits);
+
/* complete the data exchange transaction, if exists */
if (test_bit(NCI_DATA_EXCHANGE, &ndev->flags))
nci_data_exchange_complete(ndev, NULL, -EIO);
@@ -237,12 +269,8 @@ void nci_ntf_packet(struct nci_dev *ndev, struct sk_buff *skb)
nci_core_conn_credits_ntf_packet(ndev, skb);
break;
- case NCI_OP_RF_FIELD_INFO_NTF:
- nci_rf_field_info_ntf_packet(ndev, skb);
- break;
-
- case NCI_OP_RF_ACTIVATE_NTF:
- nci_rf_activate_ntf_packet(ndev, skb);
+ case NCI_OP_RF_INTF_ACTIVATED_NTF:
+ nci_rf_intf_activated_ntf_packet(ndev, skb);
break;
case NCI_OP_RF_DEACTIVATE_NTF:
diff --git a/net/nfc/nci/rsp.c b/net/nfc/nci/rsp.c
index 0403d4c..1d2a1ce 100644
--- a/net/nfc/nci/rsp.c
+++ b/net/nfc/nci/rsp.c
@@ -42,10 +42,11 @@ static void nci_core_reset_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb)
nfc_dbg("entry, status 0x%x", rsp->status);
- if (rsp->status == NCI_STATUS_OK)
+ if (rsp->status == NCI_STATUS_OK) {
ndev->nci_ver = rsp->nci_ver;
-
- nfc_dbg("nci_ver 0x%x", ndev->nci_ver);
+ nfc_dbg("nci_ver 0x%x, config_status 0x%x",
+ rsp->nci_ver, rsp->config_status);
+ }
nci_req_complete(ndev, rsp->status);
}
@@ -57,86 +58,76 @@ static void nci_core_init_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb)
nfc_dbg("entry, status 0x%x", rsp_1->status);
- if (rsp_1->status != NCI_STATUS_OK)
- return;
-
- ndev->nfcc_features = __le32_to_cpu(rsp_1->nfcc_features);
- ndev->num_supported_rf_interfaces = rsp_1->num_supported_rf_interfaces;
-
- if (ndev->num_supported_rf_interfaces >
- NCI_MAX_SUPPORTED_RF_INTERFACES) {
+ if (rsp_1->status == NCI_STATUS_OK) {
+ ndev->nfcc_features = __le32_to_cpu(rsp_1->nfcc_features);
ndev->num_supported_rf_interfaces =
- NCI_MAX_SUPPORTED_RF_INTERFACES;
+ rsp_1->num_supported_rf_interfaces;
+
+ if (ndev->num_supported_rf_interfaces >
+ NCI_MAX_SUPPORTED_RF_INTERFACES) {
+ ndev->num_supported_rf_interfaces =
+ NCI_MAX_SUPPORTED_RF_INTERFACES;
+ }
+
+ memcpy(ndev->supported_rf_interfaces,
+ rsp_1->supported_rf_interfaces,
+ ndev->num_supported_rf_interfaces);
+
+ rsp_2 =
+ (void *) (skb->data + 6 + rsp_1->num_supported_rf_interfaces);
+
+ ndev->max_logical_connections =
+ rsp_2->max_logical_connections;
+ ndev->max_routing_table_size =
+ __le16_to_cpu(rsp_2->max_routing_table_size);
+ ndev->max_control_pkt_payload_len =
+ rsp_2->max_control_pkt_payload_len;
+ ndev->max_size_for_large_params =
+ __le16_to_cpu(rsp_2->max_size_for_large_params);
+ ndev->max_data_pkt_payload_size =
+ rsp_2->max_data_pkt_payload_size;
+ ndev->initial_num_credits =
+ rsp_2->initial_num_credits;
+ ndev->manufacturer_id =
+ rsp_2->manufacturer_id;
+ ndev->manufacturer_specific_info =
+ __le32_to_cpu(rsp_2->manufacturer_specific_info);
+
+ atomic_set(&ndev->credits_cnt, ndev->initial_num_credits);
+
+ nfc_dbg("nfcc_features 0x%x",
+ ndev->nfcc_features);
+ nfc_dbg("num_supported_rf_interfaces %d",
+ ndev->num_supported_rf_interfaces);
+ nfc_dbg("supported_rf_interfaces[0] 0x%x",
+ ndev->supported_rf_interfaces[0]);
+ nfc_dbg("supported_rf_interfaces[1] 0x%x",
+ ndev->supported_rf_interfaces[1]);
+ nfc_dbg("supported_rf_interfaces[2] 0x%x",
+ ndev->supported_rf_interfaces[2]);
+ nfc_dbg("supported_rf_interfaces[3] 0x%x",
+ ndev->supported_rf_interfaces[3]);
+ nfc_dbg("max_logical_connections %d",
+ ndev->max_logical_connections);
+ nfc_dbg("max_routing_table_size %d",
+ ndev->max_routing_table_size);
+ nfc_dbg("max_control_pkt_payload_len %d",
+ ndev->max_control_pkt_payload_len);
+ nfc_dbg("max_size_for_large_params %d",
+ ndev->max_size_for_large_params);
+ nfc_dbg("max_data_pkt_payload_size %d",
+ ndev->max_data_pkt_payload_size);
+ nfc_dbg("initial_num_credits %d",
+ ndev->initial_num_credits);
+ nfc_dbg("manufacturer_id 0x%x",
+ ndev->manufacturer_id);
+ nfc_dbg("manufacturer_specific_info 0x%x",
+ ndev->manufacturer_specific_info);
}
- memcpy(ndev->supported_rf_interfaces,
- rsp_1->supported_rf_interfaces,
- ndev->num_supported_rf_interfaces);
-
- rsp_2 = (void *) (skb->data + 6 + ndev->num_supported_rf_interfaces);
-
- ndev->max_logical_connections =
- rsp_2->max_logical_connections;
- ndev->max_routing_table_size =
- __le16_to_cpu(rsp_2->max_routing_table_size);
- ndev->max_control_packet_payload_length =
- rsp_2->max_control_packet_payload_length;
- ndev->rf_sending_buffer_size =
- __le16_to_cpu(rsp_2->rf_sending_buffer_size);
- ndev->rf_receiving_buffer_size =
- __le16_to_cpu(rsp_2->rf_receiving_buffer_size);
- ndev->manufacturer_id =
- __le16_to_cpu(rsp_2->manufacturer_id);
-
- nfc_dbg("nfcc_features 0x%x",
- ndev->nfcc_features);
- nfc_dbg("num_supported_rf_interfaces %d",
- ndev->num_supported_rf_interfaces);
- nfc_dbg("supported_rf_interfaces[0] 0x%x",
- ndev->supported_rf_interfaces[0]);
- nfc_dbg("supported_rf_interfaces[1] 0x%x",
- ndev->supported_rf_interfaces[1]);
- nfc_dbg("supported_rf_interfaces[2] 0x%x",
- ndev->supported_rf_interfaces[2]);
- nfc_dbg("supported_rf_interfaces[3] 0x%x",
- ndev->supported_rf_interfaces[3]);
- nfc_dbg("max_logical_connections %d",
- ndev->max_logical_connections);
- nfc_dbg("max_routing_table_size %d",
- ndev->max_routing_table_size);
- nfc_dbg("max_control_packet_payload_length %d",
- ndev->max_control_packet_payload_length);
- nfc_dbg("rf_sending_buffer_size %d",
- ndev->rf_sending_buffer_size);
- nfc_dbg("rf_receiving_buffer_size %d",
- ndev->rf_receiving_buffer_size);
- nfc_dbg("manufacturer_id 0x%x",
- ndev->manufacturer_id);
-
nci_req_complete(ndev, rsp_1->status);
}
-static void nci_core_conn_create_rsp_packet(struct nci_dev *ndev,
- struct sk_buff *skb)
-{
- struct nci_core_conn_create_rsp *rsp = (void *) skb->data;
-
- nfc_dbg("entry, status 0x%x", rsp->status);
-
- if (rsp->status != NCI_STATUS_OK)
- return;
-
- ndev->max_pkt_payload_size = rsp->max_pkt_payload_size;
- ndev->initial_num_credits = rsp->initial_num_credits;
- ndev->conn_id = rsp->conn_id;
-
- atomic_set(&ndev->credits_cnt, ndev->initial_num_credits);
-
- nfc_dbg("max_pkt_payload_size %d", ndev->max_pkt_payload_size);
- nfc_dbg("initial_num_credits %d", ndev->initial_num_credits);
- nfc_dbg("conn_id %d", ndev->conn_id);
-}
-
static void nci_rf_disc_map_rsp_packet(struct nci_dev *ndev,
struct sk_buff *skb)
{
@@ -196,10 +187,6 @@ void nci_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb)
nci_core_init_rsp_packet(ndev, skb);
break;
- case NCI_OP_CORE_CONN_CREATE_RSP:
- nci_core_conn_create_rsp_packet(ndev, skb);
- break;
-
case NCI_OP_RF_DISCOVER_MAP_RSP:
nci_rf_disc_map_rsp_packet(ndev, skb);
break;
--
1.7.0.4
^ permalink raw reply related
* Re: Use of _hint() functions and older machines
From: Randell Jesup @ 2011-10-23 7:46 UTC (permalink / raw)
To: Colin Guthrie; +Cc: ALSA Development Mailing List, Randell Jesup
In-Reply-To: <4EA305B7.6050001@colin.guthr.ie>
On 10/22/2011 2:04 PM, Colin Guthrie wrote:
> 'Twas brillig, and Randell Jesup at 21/10/11 04:28 did gyre and gimble:
>> [ I initially posted this to the -users list, but it may be more
>> appropriate here ]
>>
>> At Mozilla, we're in the process of adding support for WebRTC
>> (http://webrtc.org/), which is being standardized by the IETF (their
>> part is 'rtcweb'), and the W3C. This adds real-time audio and video
>> (and data) communication to browsers, peer-to-peer over encrypted channels.
>>
>> We have a sound library that can load either Pulse or Alsa. However,
>> for Alsa, it wants to look at snd_device_name_hint() and also
>> _get_hint() and _free_hint(). It lazy-binds to libasound, so it will
>> dlopen() it and then dlsym() all the symbols it uses; if any fail it
>> unloads the lib and says it's not there. It uses the hint functions to
>> build a device list, for example for presenting to the user.
>>
>> I have two problems:
>>
>> 1) Firefox is build on machines configured with I believe Centos5, and
>> I'm told the machines run Alsa 1.0.12, while the hints() functions were
>> added in 1.0.14 (released June 2007). Right now I can't build release
>> or 'try' builds on the build servers because of this.
>
> Are you sure? CentOS 5 is fairly new and on a box I have access to:
>
> [csuk@shake ~]$ cat /etc/redhat-release
> CentOS release 5.5 (Final)
> [csuk@shake ~]$ rpm -q alsa-lib
> alsa-lib-1.0.17-1.el5
>
>
> So I guess it's likely CentOS 4? Even still updating alsa-lib to 1.0.14
> should be pretty trivial and safe. Or do you not have any control at all
> over the version used?
In general no, I do not have any control. These are the 'hive' of build
and 'try' servers used at Mozilla; they run a "least-common-denominator"
set of packages so that we don't accidentally introduce a dependency on
a newer version. With 400+ million users, we need to be careful about
this. (I don't know how many of those are Linux, but it's still a
substantial number.)
Also, the point here is we need to package a binary that will operate on
the minimum configuration we support. 10.1.14 was released initially
just over 4 years ago; I don't know when it got into distro releases,
but one would assume that would have occurred over the next 6 months to
a year, so users who installed more than 3-4 years ago might have
versions before .14, depending on if they installed updates.
>> 2) We'd like to run on older machines if possible, and official release
>> builds are made on those servers. On older machines, _hint() aren't
>> available, so even if I make them optional to dlsym-loading, I would
>> need some other method to get the information I assume using older,
>> now-deprecated-or-gone interfaces.
>
> Not sure, but I suspect strongly that you should simply not worry about
> this too much. While it's nice to give a good experience to everyone,
> people with systems 4 years old have got to expect a degree of
> degradation over a more recent install.
I understand, and I can try to make an argument for bumping the minimum
configuration required - and that might fly. But I need to know what
the alternative is to even make the argument for bumping.
Thanks for the reply!
--
Randell Jesup
randell-ietf@jesup.org
^ permalink raw reply
* [PATCH 3/3] sandbox: simplify linker script
From: Jean-Christophe PLAGNIOL-VILLARD @ 2011-10-23 7:48 UTC (permalink / raw)
To: barebox
In-Reply-To: <1319356101-4521-1-git-send-email-plagnioj@jcrosoft.com>
let the linker to provide the basic linker script
just insert the commands and initcalls before the .rodata section
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
arch/sandbox/Makefile | 8 +-
arch/sandbox/board/Makefile | 3 -
arch/sandbox/board/barebox.lds.S | 245 +++-----------------------------------
3 files changed, 17 insertions(+), 239 deletions(-)
rewrite arch/sandbox/board/barebox.lds.S (99%)
diff --git a/arch/sandbox/Makefile b/arch/sandbox/Makefile
index 860ed1c..ed1194c 100644
--- a/arch/sandbox/Makefile
+++ b/arch/sandbox/Makefile
@@ -38,23 +38,17 @@ SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
-e s/ppc.*/powerpc/ -e s/mips.*/mips/ )
ifeq ($(SUBARCH),x86_64)
-ELF_ARCH := i386:x86-64
-ELF_FORMAT := elf64-x86-64
ELF_CLASS := ELFCLASS64
endif
ifeq ($(SUBARCH),i386)
-ELF_ARCH := $(SUBARCH)
-ELF_FORMAT := elf32-$(SUBARCH)
ELF_CLASS := ELFCLASS32
endif
ifeq ($(SUBARCH),powerpc)
-ELF_ARCH := powerpc
-ELF_FORMAT := elf32-powerpc
ELF_CLASS := ELFCLASS32
endif
CPPFLAGS += -DELF_CLASS="$(ELF_CLASS)"
-export ELF_FORMAT ELF_ARCH SUBARCH ELF_CLASS
+export ELF_CLASS
archprepare: maketools
diff --git a/arch/sandbox/board/Makefile b/arch/sandbox/board/Makefile
index 8abe5dd..266c3a3 100644
--- a/arch/sandbox/board/Makefile
+++ b/arch/sandbox/board/Makefile
@@ -3,7 +3,4 @@ obj-y += clock.o
obj-y += hostfile.o
obj-y += console.o
-CPPFLAGS_barebox.lds = -U$(SUBARCH) -DELF_ARCH=$(ELF_ARCH) \
- -DELF_FORMAT="$(ELF_FORMAT)"
extra-y += barebox.lds
-
diff --git a/arch/sandbox/board/barebox.lds.S b/arch/sandbox/board/barebox.lds.S
dissimilarity index 99%
index 53e9f60..76975ee 100644
--- a/arch/sandbox/board/barebox.lds.S
+++ b/arch/sandbox/board/barebox.lds.S
@@ -1,229 +1,16 @@
-#include <asm-generic/barebox.lds.h>
-
-OUTPUT_FORMAT(ELF_FORMAT)
-OUTPUT_ARCH(ELF_ARCH)
-ENTRY(_start)
-
-SECTIONS
-{
- /* Read-only sections, merged into text segment: */
- PROVIDE (__executable_start = 0x400000); . = 0x400000 + SIZEOF_HEADERS;
- .interp : { *(.interp) }
- .hash : { *(.hash) }
- .gnu.hash : { *(.gnu.hash) }
- .dynsym : { *(.dynsym) }
- .dynstr : { *(.dynstr) }
- .gnu.version : { *(.gnu.version) }
- .gnu.version_d : { *(.gnu.version_d) }
- .gnu.version_r : { *(.gnu.version_r) }
- .rel.dyn :
- {
- *(.rel.init)
- *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)
- *(.rel.fini)
- *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)
- *(.rel.data.rel.ro* .rel.gnu.linkonce.d.rel.ro.*)
- *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)
- *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*)
- *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*)
- *(.rel.ctors)
- *(.rel.dtors)
- *(.rel.got)
- *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)
- *(.rel.ldata .rel.ldata.* .rel.gnu.linkonce.l.*)
- *(.rel.lbss .rel.lbss.* .rel.gnu.linkonce.lb.*)
- *(.rel.lrodata .rel.lrodata.* .rel.gnu.linkonce.lr.*)
- }
- .rela.dyn :
- {
- *(.rela.init)
- *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
- *(.rela.fini)
- *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
- *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
- *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
- *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
- *(.rela.ctors)
- *(.rela.dtors)
- *(.rela.got)
- *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
- *(.rela.ldata .rela.ldata.* .rela.gnu.linkonce.l.*)
- *(.rela.lbss .rela.lbss.* .rela.gnu.linkonce.lb.*)
- *(.rela.lrodata .rela.lrodata.* .rela.gnu.linkonce.lr.*)
- }
- .rel.plt : { *(.rel.plt) }
- .rela.plt : { *(.rela.plt) }
- .init :
- {
- KEEP (*(.init))
- } =0x90909090
- .plt : { *(.plt) }
- .text :
- {
- *(.text .stub .text.* .gnu.linkonce.t.*)
- KEEP (*(.text.*personality*))
- /* .gnu.warning sections are handled specially by elf32.em. */
- *(.gnu.warning)
- } =0x90909090
- .fini :
- {
- KEEP (*(.fini))
- } =0x90909090
-
- . = ALIGN(64);
- __barebox_initcalls_start = .;
- __barebox_initcalls : { INITCALLS }
- __barebox_initcalls_end = .;
- . = ALIGN(64);
- __barebox_cmd_start = .;
- __barebox_cmd : { BAREBOX_CMDS }
- __barebox_cmd_end = .;
-
- PROVIDE (__etext = .);
- PROVIDE (_etext = .);
- PROVIDE (etext = .);
- .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
- .rodata1 : { *(.rodata1) }
- .eh_frame_hdr : { *(.eh_frame_hdr) }
- .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) }
- .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }
- /* Adjust the address for the data segment. We want to adjust up to
- the same address within the page on the next page up. */
- . = ALIGN (CONSTANT (MAXPAGESIZE)) - ((CONSTANT (MAXPAGESIZE) - .) & (CONSTANT (MAXPAGESIZE) - 1)); . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
- /* Exception handling */
- .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) }
- .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
- /* Thread Local Storage sections */
- .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
- .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
- .preinit_array :
- {
- PROVIDE_HIDDEN (__preinit_array_start = .);
- KEEP (*(.preinit_array))
- PROVIDE_HIDDEN (__preinit_array_end = .);
- }
- .init_array :
- {
- PROVIDE_HIDDEN (__init_array_start = .);
- KEEP (*(SORT(.init_array.*)))
- KEEP (*(.init_array))
- PROVIDE_HIDDEN (__init_array_end = .);
- }
- .fini_array :
- {
- PROVIDE_HIDDEN (__fini_array_start = .);
- KEEP (*(.fini_array))
- KEEP (*(SORT(.fini_array.*)))
- PROVIDE_HIDDEN (__fini_array_end = .);
- }
- .ctors :
- {
- /* gcc uses crtbegin.o to find the start of
- the constructors, so we make sure it is
- first. Because this is a wildcard, it
- doesn't matter if the user does not
- actually link against crtbegin.o; the
- linker won't look for a file to match a
- wildcard. The wildcard also means that it
- doesn't matter which directory crtbegin.o
- is in. */
- KEEP (*crtbegin.o(.ctors))
- KEEP (*crtbegin?.o(.ctors))
- /* We don't want to include the .ctor section from
- the crtend.o file until after the sorted ctors.
- The .ctor section from the crtend file contains the
- end of ctors marker and it must be last */
- KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
- KEEP (*(SORT(.ctors.*)))
- KEEP (*(.ctors))
- }
- .dtors :
- {
- KEEP (*crtbegin.o(.dtors))
- KEEP (*crtbegin?.o(.dtors))
- KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
- KEEP (*(SORT(.dtors.*)))
- KEEP (*(.dtors))
- }
- .jcr : { KEEP (*(.jcr)) }
- .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*) }
- .dynamic : { *(.dynamic) }
- .got : { *(.got) }
- . = DATA_SEGMENT_RELRO_END (24, .);
- .got.plt : { *(.got.plt) }
- .data :
- {
- *(.data .data.* .gnu.linkonce.d.*)
- KEEP (*(.gnu.linkonce.d.*personality*))
- SORT(CONSTRUCTORS)
- }
- .data1 : { *(.data1) }
- _edata = .; PROVIDE (edata = .);
- __bss_start = .;
- .bss :
- {
- *(.dynbss)
- *(.bss .bss.* .gnu.linkonce.b.*)
- *(COMMON)
- /* Align here to ensure that the .bss section occupies space up to
- _end. Align after .bss to ensure correct alignment even if the
- .bss section disappears because there are no input sections.
- FIXME: Why do we need it? When there is no .bss section, we don't
- pad the .data section. */
- . = ALIGN(. != 0 ? 64 / 8 : 1);
- }
- .lbss :
- {
- *(.dynlbss)
- *(.lbss .lbss.* .gnu.linkonce.lb.*)
- *(LARGE_COMMON)
- }
- . = ALIGN(64 / 8);
- .lrodata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) :
- {
- *(.lrodata .lrodata.* .gnu.linkonce.lr.*)
- }
- .ldata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) :
- {
- *(.ldata .ldata.* .gnu.linkonce.l.*)
- . = ALIGN(. != 0 ? 64 / 8 : 1);
- }
- . = ALIGN(64 / 8);
- _end = .; PROVIDE (end = .);
- . = DATA_SEGMENT_END (.);
- /* Stabs debugging sections. */
- .stab 0 : { *(.stab) }
- .stabstr 0 : { *(.stabstr) }
- .stab.excl 0 : { *(.stab.excl) }
- .stab.exclstr 0 : { *(.stab.exclstr) }
- .stab.index 0 : { *(.stab.index) }
- .stab.indexstr 0 : { *(.stab.indexstr) }
- .comment 0 : { *(.comment) }
- /* DWARF debug sections.
- Symbols in the DWARF debugging sections are relative to the beginning
- of the section so we begin them at 0. */
- /* DWARF 1 */
- .debug 0 : { *(.debug) }
- .line 0 : { *(.line) }
- /* GNU DWARF 1 extensions */
- .debug_srcinfo 0 : { *(.debug_srcinfo) }
- .debug_sfnames 0 : { *(.debug_sfnames) }
- /* DWARF 1.1 and DWARF 2 */
- .debug_aranges 0 : { *(.debug_aranges) }
- .debug_pubnames 0 : { *(.debug_pubnames) }
- /* DWARF 2 */
- .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
- .debug_abbrev 0 : { *(.debug_abbrev) }
- .debug_line 0 : { *(.debug_line) }
- .debug_frame 0 : { *(.debug_frame) }
- .debug_str 0 : { *(.debug_str) }
- .debug_loc 0 : { *(.debug_loc) }
- .debug_macinfo 0 : { *(.debug_macinfo) }
- /* SGI/MIPS DWARF 2 extensions */
- .debug_weaknames 0 : { *(.debug_weaknames) }
- .debug_funcnames 0 : { *(.debug_funcnames) }
- .debug_typenames 0 : { *(.debug_typenames) }
- .debug_varnames 0 : { *(.debug_varnames) }
- /DISCARD/ : { *(.note.GNU-stack) }
-}
-
+#include <asm-generic/barebox.lds.h>
+
+SECTIONS
+{
+ . = ALIGN(64);
+ __barebox_initcalls_start = .;
+ __barebox_initcalls : { INITCALLS }
+ __barebox_initcalls_end = .;
+
+ . = ALIGN(64);
+ __barebox_cmd_start = .;
+ __barebox_cmd : { BAREBOX_CMDS }
+ __barebox_cmd_end = .;
+}
+
+INSERT BEFORE .rodata;
--
1.7.7
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply related
* [PATCH 1/3] sandbox: move __SANDBOX__ to Makefile
From: Jean-Christophe PLAGNIOL-VILLARD @ 2011-10-23 7:48 UTC (permalink / raw)
To: barebox
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
arch/sandbox/Makefile | 2 +-
arch/sandbox/board/config.h | 2 --
2 files changed, 1 insertions(+), 3 deletions(-)
diff --git a/arch/sandbox/Makefile b/arch/sandbox/Makefile
index 4ca17ed..860ed1c 100644
--- a/arch/sandbox/Makefile
+++ b/arch/sandbox/Makefile
@@ -1,5 +1,5 @@
-CPPFLAGS += -fno-strict-aliasing
+CPPFLAGS += -D__SANDBOX__ -fno-strict-aliasing
machine-y := sandbox
diff --git a/arch/sandbox/board/config.h b/arch/sandbox/board/config.h
index c96d762..ca15136 100644
--- a/arch/sandbox/board/config.h
+++ b/arch/sandbox/board/config.h
@@ -1,6 +1,4 @@
#ifndef __CONFIG_H
#define __CONFIG_H
-#define __SANDBOX__
-
#endif /* __CONFIG_H */
--
1.7.7
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply related
* [PATCH 2/3] sandbox: remove duplicate barebox.lds.S
From: Jean-Christophe PLAGNIOL-VILLARD @ 2011-10-23 7:48 UTC (permalink / raw)
To: barebox
In-Reply-To: <1319356101-4521-1-git-send-email-plagnioj@jcrosoft.com>
today we have the same linker script in board and lib
and only the board linker script is used
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
arch/sandbox/lib/Makefile | 4 -
arch/sandbox/lib/barebox.lds.S | 229 ----------------------------------------
2 files changed, 0 insertions(+), 233 deletions(-)
delete mode 100644 arch/sandbox/lib/Makefile
delete mode 100644 arch/sandbox/lib/barebox.lds.S
diff --git a/arch/sandbox/lib/Makefile b/arch/sandbox/lib/Makefile
deleted file mode 100644
index 854aa43..0000000
--- a/arch/sandbox/lib/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-CPPFLAGS_barebox.lds = -U$(SUBARCH) -DELF_ARCH=$(ELF_ARCH) \
- -DELF_FORMAT="$(ELF_FORMAT)"
-
-extra-y += barebox.lds
diff --git a/arch/sandbox/lib/barebox.lds.S b/arch/sandbox/lib/barebox.lds.S
deleted file mode 100644
index 53e9f60..0000000
--- a/arch/sandbox/lib/barebox.lds.S
+++ /dev/null
@@ -1,229 +0,0 @@
-#include <asm-generic/barebox.lds.h>
-
-OUTPUT_FORMAT(ELF_FORMAT)
-OUTPUT_ARCH(ELF_ARCH)
-ENTRY(_start)
-
-SECTIONS
-{
- /* Read-only sections, merged into text segment: */
- PROVIDE (__executable_start = 0x400000); . = 0x400000 + SIZEOF_HEADERS;
- .interp : { *(.interp) }
- .hash : { *(.hash) }
- .gnu.hash : { *(.gnu.hash) }
- .dynsym : { *(.dynsym) }
- .dynstr : { *(.dynstr) }
- .gnu.version : { *(.gnu.version) }
- .gnu.version_d : { *(.gnu.version_d) }
- .gnu.version_r : { *(.gnu.version_r) }
- .rel.dyn :
- {
- *(.rel.init)
- *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)
- *(.rel.fini)
- *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)
- *(.rel.data.rel.ro* .rel.gnu.linkonce.d.rel.ro.*)
- *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)
- *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*)
- *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*)
- *(.rel.ctors)
- *(.rel.dtors)
- *(.rel.got)
- *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)
- *(.rel.ldata .rel.ldata.* .rel.gnu.linkonce.l.*)
- *(.rel.lbss .rel.lbss.* .rel.gnu.linkonce.lb.*)
- *(.rel.lrodata .rel.lrodata.* .rel.gnu.linkonce.lr.*)
- }
- .rela.dyn :
- {
- *(.rela.init)
- *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
- *(.rela.fini)
- *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
- *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
- *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
- *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
- *(.rela.ctors)
- *(.rela.dtors)
- *(.rela.got)
- *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
- *(.rela.ldata .rela.ldata.* .rela.gnu.linkonce.l.*)
- *(.rela.lbss .rela.lbss.* .rela.gnu.linkonce.lb.*)
- *(.rela.lrodata .rela.lrodata.* .rela.gnu.linkonce.lr.*)
- }
- .rel.plt : { *(.rel.plt) }
- .rela.plt : { *(.rela.plt) }
- .init :
- {
- KEEP (*(.init))
- } =0x90909090
- .plt : { *(.plt) }
- .text :
- {
- *(.text .stub .text.* .gnu.linkonce.t.*)
- KEEP (*(.text.*personality*))
- /* .gnu.warning sections are handled specially by elf32.em. */
- *(.gnu.warning)
- } =0x90909090
- .fini :
- {
- KEEP (*(.fini))
- } =0x90909090
-
- . = ALIGN(64);
- __barebox_initcalls_start = .;
- __barebox_initcalls : { INITCALLS }
- __barebox_initcalls_end = .;
- . = ALIGN(64);
- __barebox_cmd_start = .;
- __barebox_cmd : { BAREBOX_CMDS }
- __barebox_cmd_end = .;
-
- PROVIDE (__etext = .);
- PROVIDE (_etext = .);
- PROVIDE (etext = .);
- .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
- .rodata1 : { *(.rodata1) }
- .eh_frame_hdr : { *(.eh_frame_hdr) }
- .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) }
- .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }
- /* Adjust the address for the data segment. We want to adjust up to
- the same address within the page on the next page up. */
- . = ALIGN (CONSTANT (MAXPAGESIZE)) - ((CONSTANT (MAXPAGESIZE) - .) & (CONSTANT (MAXPAGESIZE) - 1)); . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
- /* Exception handling */
- .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) }
- .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
- /* Thread Local Storage sections */
- .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
- .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
- .preinit_array :
- {
- PROVIDE_HIDDEN (__preinit_array_start = .);
- KEEP (*(.preinit_array))
- PROVIDE_HIDDEN (__preinit_array_end = .);
- }
- .init_array :
- {
- PROVIDE_HIDDEN (__init_array_start = .);
- KEEP (*(SORT(.init_array.*)))
- KEEP (*(.init_array))
- PROVIDE_HIDDEN (__init_array_end = .);
- }
- .fini_array :
- {
- PROVIDE_HIDDEN (__fini_array_start = .);
- KEEP (*(.fini_array))
- KEEP (*(SORT(.fini_array.*)))
- PROVIDE_HIDDEN (__fini_array_end = .);
- }
- .ctors :
- {
- /* gcc uses crtbegin.o to find the start of
- the constructors, so we make sure it is
- first. Because this is a wildcard, it
- doesn't matter if the user does not
- actually link against crtbegin.o; the
- linker won't look for a file to match a
- wildcard. The wildcard also means that it
- doesn't matter which directory crtbegin.o
- is in. */
- KEEP (*crtbegin.o(.ctors))
- KEEP (*crtbegin?.o(.ctors))
- /* We don't want to include the .ctor section from
- the crtend.o file until after the sorted ctors.
- The .ctor section from the crtend file contains the
- end of ctors marker and it must be last */
- KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
- KEEP (*(SORT(.ctors.*)))
- KEEP (*(.ctors))
- }
- .dtors :
- {
- KEEP (*crtbegin.o(.dtors))
- KEEP (*crtbegin?.o(.dtors))
- KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
- KEEP (*(SORT(.dtors.*)))
- KEEP (*(.dtors))
- }
- .jcr : { KEEP (*(.jcr)) }
- .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*) }
- .dynamic : { *(.dynamic) }
- .got : { *(.got) }
- . = DATA_SEGMENT_RELRO_END (24, .);
- .got.plt : { *(.got.plt) }
- .data :
- {
- *(.data .data.* .gnu.linkonce.d.*)
- KEEP (*(.gnu.linkonce.d.*personality*))
- SORT(CONSTRUCTORS)
- }
- .data1 : { *(.data1) }
- _edata = .; PROVIDE (edata = .);
- __bss_start = .;
- .bss :
- {
- *(.dynbss)
- *(.bss .bss.* .gnu.linkonce.b.*)
- *(COMMON)
- /* Align here to ensure that the .bss section occupies space up to
- _end. Align after .bss to ensure correct alignment even if the
- .bss section disappears because there are no input sections.
- FIXME: Why do we need it? When there is no .bss section, we don't
- pad the .data section. */
- . = ALIGN(. != 0 ? 64 / 8 : 1);
- }
- .lbss :
- {
- *(.dynlbss)
- *(.lbss .lbss.* .gnu.linkonce.lb.*)
- *(LARGE_COMMON)
- }
- . = ALIGN(64 / 8);
- .lrodata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) :
- {
- *(.lrodata .lrodata.* .gnu.linkonce.lr.*)
- }
- .ldata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) :
- {
- *(.ldata .ldata.* .gnu.linkonce.l.*)
- . = ALIGN(. != 0 ? 64 / 8 : 1);
- }
- . = ALIGN(64 / 8);
- _end = .; PROVIDE (end = .);
- . = DATA_SEGMENT_END (.);
- /* Stabs debugging sections. */
- .stab 0 : { *(.stab) }
- .stabstr 0 : { *(.stabstr) }
- .stab.excl 0 : { *(.stab.excl) }
- .stab.exclstr 0 : { *(.stab.exclstr) }
- .stab.index 0 : { *(.stab.index) }
- .stab.indexstr 0 : { *(.stab.indexstr) }
- .comment 0 : { *(.comment) }
- /* DWARF debug sections.
- Symbols in the DWARF debugging sections are relative to the beginning
- of the section so we begin them at 0. */
- /* DWARF 1 */
- .debug 0 : { *(.debug) }
- .line 0 : { *(.line) }
- /* GNU DWARF 1 extensions */
- .debug_srcinfo 0 : { *(.debug_srcinfo) }
- .debug_sfnames 0 : { *(.debug_sfnames) }
- /* DWARF 1.1 and DWARF 2 */
- .debug_aranges 0 : { *(.debug_aranges) }
- .debug_pubnames 0 : { *(.debug_pubnames) }
- /* DWARF 2 */
- .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
- .debug_abbrev 0 : { *(.debug_abbrev) }
- .debug_line 0 : { *(.debug_line) }
- .debug_frame 0 : { *(.debug_frame) }
- .debug_str 0 : { *(.debug_str) }
- .debug_loc 0 : { *(.debug_loc) }
- .debug_macinfo 0 : { *(.debug_macinfo) }
- /* SGI/MIPS DWARF 2 extensions */
- .debug_weaknames 0 : { *(.debug_weaknames) }
- .debug_funcnames 0 : { *(.debug_funcnames) }
- .debug_typenames 0 : { *(.debug_typenames) }
- .debug_varnames 0 : { *(.debug_varnames) }
- /DISCARD/ : { *(.note.GNU-stack) }
-}
-
--
1.7.7
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply related
* Re: [PATCH 3/3] sandbox: simplify linker script
From: Jean-Christophe PLAGNIOL-VILLARD @ 2011-10-23 7:32 UTC (permalink / raw)
To: barebox
In-Reply-To: <1319356101-4521-3-git-send-email-plagnioj@jcrosoft.com>
On 15:48 Sun 23 Oct , Jean-Christophe PLAGNIOL-VILLARD wrote:
> let the linker to provide the basic linker script
>
> just insert the commands and initcalls before the .rodata section
>
> Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
> ---
this was do to fix ARM host support as the basic lds is different
a second set will be to drop the SUBARCH stuff and use the compiler macro to
detect the ELFCLASS as done in linux
Best Regards,
J.
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply
* [PATCH] ipv4: fix ipsec forward performance regression
From: Yan, Zheng @ 2011-10-23 7:58 UTC (permalink / raw)
To: netdev@vger.kernel.org, davem@davemloft.net,
eric.dumazet@gmail.com, Kim Phillips
There is bug in commit 5e2b61f(ipv4: Remove flowi from struct rtable).
It makes xfrm4_fill_dst() modify wrong data structure.
Signed-off-by: Zheng Yan <zheng.z.yan@intel.com>
---
net/ipv4/xfrm4_policy.c | 14 +++++++-------
1 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index fc5368a..a0b4c5d 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -79,13 +79,13 @@ static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
struct rtable *rt = (struct rtable *)xdst->route;
const struct flowi4 *fl4 = &fl->u.ip4;
- rt->rt_key_dst = fl4->daddr;
- rt->rt_key_src = fl4->saddr;
- rt->rt_key_tos = fl4->flowi4_tos;
- rt->rt_route_iif = fl4->flowi4_iif;
- rt->rt_iif = fl4->flowi4_iif;
- rt->rt_oif = fl4->flowi4_oif;
- rt->rt_mark = fl4->flowi4_mark;
+ xdst->u.rt.rt_key_dst = fl4->daddr;
+ xdst->u.rt.rt_key_src = fl4->saddr;
+ xdst->u.rt.rt_key_tos = fl4->flowi4_tos;
+ xdst->u.rt.rt_route_iif = fl4->flowi4_iif;
+ xdst->u.rt.rt_iif = fl4->flowi4_iif;
+ xdst->u.rt.rt_oif = fl4->flowi4_oif;
+ xdst->u.rt.rt_mark = fl4->flowi4_mark;
xdst->u.dst.dev = dev;
dev_hold(dev);
--
1.7.4.4
^ permalink raw reply related
* Re: [systemd-devel] systemd kills mdmon if it was started manually by user
From: Dan Williams @ 2011-10-23 8:00 UTC (permalink / raw)
To: Lennart Poettering
Cc: Andrey Borzenkov, Tomasz Torcz, systemd-devel, linux-raid,
NeilBrown
In-Reply-To: <20110208172822.GC21847@tango.0pointer.de>
On Tue, Feb 8, 2011 at 9:28 AM, Lennart Poettering
<lennart@poettering.net> wrote:
> On Tue, 08.02.11 16:54, Andrey Borzenkov (arvidjaar@mail.ru) wrote:
>
>> >> a) mdmon is perfectly capable of restarting, it is already used to
>> >> take over mdmon launched in initrd. The problem is to know when to
>> >> restart - i.e. when respective libraries are changed. This is a job
>> >> for package management in distribution. It is already employed for
>> >> glibc, systemd and some others and can just as well be employed for
>> >> mdmon. And this is totally unrelated to systemd :)
>> >
>> > Really, you are sying there is a synchronous way to make mdmon reexec
>> > itself? How does that work?
>> >
>>
>> I am not sure whether it qualifies as synchronous, but "mdmon
>> --takeover" will kill any existing mdmon for this and start monitoring
>> itself.
>
> I wonder if this is really fully synchronous, i.e. that a) there is no
> point in time where mdmon is not running during this restart and b) the
> mdmom --takeover command returns when the new daemon is fully up, and
> not right-away.
>
>> > Well, the root file systems cannot be unmounted, only remounted.
>> >
>> > So, is there a way to invoke mdmon so that it flushes all metadata
>> > changes to disk and immediately terminates then this should be all we
>> > need for a clean solution. We'd then shutdown the normal instances of
>> > mdmon down like any other daemon and simply invoke this metadata
>> > flushing command as part of late shutdown.
>>
>>
>> Hmm ... it looks like you just need to
>>
>> start mdmon
>> do mdadm --wait-clean
>>
>> After this you can kill mdmon again (assuming decide is no more in
>> use).
>
>
> Well, it would be nice if the md utils would offer something doing this
> without spawning multiple processes and killing them again.
>
/me wonders why his raid5 resyncs every boot on Fedora 15 and has
found this old thread.
I'm tempted to:
1/ teach ignore_proc() to scan for pid files in /dev/md/ (MDMON_DIR on Fedora)
2/ arrange for mdadm --wait-clean --scan to be called after all
filesytems have been mounted read only
...but a few things strike me. This does not seem to be what was
being proposed above. Systemd does not treat dm devices like a
service and takes care to shut them down explicitly (but in that case
there is an api that it can call). Is it time for a libmd.so, so
systemd can invoke the "--wait-clean --scan" process itself? Probably
simpler to just SIGTERM mdmon and wait for it.
--
Dan
^ permalink raw reply
* bitbake eating more than 6GB ram while parsing recipes
From: Martin Jansa @ 2011-10-23 7:57 UTC (permalink / raw)
To: Patches and discussions about the oe-core layer
[-- Attachment #1: Type: text/plain, Size: 1623 bytes --]
Hi,
I know this was reported a while ago and I had this issue for few days
with 4 GB RAM on my workstation it was hard to do anything when bitbake
was parsing and today I've "resolved" it by removing cache.
first I've tried to remove
#PARALLEL_MAKE="-j3"
#BB_NUMBER_THREADS = "2"
from my local.conf and it didn't help I still had 6 bitbake processes
4 eating ~ 1GB ad 2 with ~ 512MB. So I've removed tmp/cache except
bb_persist_data.sqlite3:
OE om-gta02@shr ~/shr-core $ du -hs tmp/cache/*
35M tmp/cache/bb_codeparser.dat
0 tmp/cache/bb_codeparser.dat.lock.13293
0 tmp/cache/bb_codeparser.dat.lock.13294
0 tmp/cache/bb_codeparser.dat.lock.13295
0 tmp/cache/bb_codeparser.dat.lock.15708
0 tmp/cache/bb_codeparser.dat.lock.16878
0 tmp/cache/bb_codeparser.dat.lock.16879
0 tmp/cache/bb_codeparser.dat.lock.16880
0 tmp/cache/bb_codeparser.dat.lock.25605
68K tmp/cache/bb_persist_data.sqlite3
87M tmp/cache/default-eglibc
OE om-gta02@shr ~/shr-core $ rm -rf tmp/cache/bb_codeparser.dat*
OE om-gta02@shr ~/shr-core $ du -hs tmp/cache/default-eglibc/*
13M tmp/cache/default-eglibc/nokia900
13M tmp/cache/default-eglibc/om-gta02
13M tmp/cache/default-eglibc/palmpre
13M tmp/cache/default-eglibc/qemuarm
13M tmp/cache/default-eglibc/qemux86
13M tmp/cache/default-eglibc/qemux86-64
13M tmp/cache/default-eglibc/spitz
OE om-gta02@shr ~/shr-core $ rm -rf tmp/cache/default-eglibc/
and now it's sane again and memory used is < 2GB.
Regards,
--
Martin 'JaMa' Jansa jabber: Martin.Jansa@gmail.com
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 205 bytes --]
^ permalink raw reply
* [PATCH 0/3] mfd: S5M series initial release
From: Sangbeom Kim @ 2011-10-23 8:07 UTC (permalink / raw)
To: 'Samuel Ortiz'
Cc: 'Mark Brown', linux-kernel, 'Sangbeom Kim'
Samsung is developing various multi function devices.
Currently, 3 devices are announced by samsung.
S5M8767 has pmic and rtc and battery charger.
S5M8763 has pmic, rtc, Li-ion battery charger
S5M8751 has pmic, codec, battery charger, backlight controller.
All devices are designed for mobile applications.
Sequentially, All driver will be posted.
This is initial version for MFD of S5M series.
The other driver will be submitted separately.
Sangbeom
*Currently, My git server has some problem.
So, I can't use git send-email.
This patch are sent by outlook.
^ permalink raw reply
* [PATCH 1/3] mfd: Add S5M core driver
From: Sangbeom Kim @ 2011-10-23 8:07 UTC (permalink / raw)
To: 'Samuel Ortiz'
Cc: linux-kernel, 'Mark Brown', 'Sangbeom Kim'
S5M series are pmic including mutiple functions.
It can support PMIC, RTC, Battery charger, codec.
This patch implement core driver for s5m series.
Signed-off-by: Sangbeom Kim <sbkim73@samsung.com>
---
drivers/mfd/s5m-core.c | 235 +++++++++++++++++++++++++
include/linux/mfd/s5m87xx/s5m-core.h | 313
++++++++++++++++++++++++++++++++++
include/linux/mfd/s5m87xx/s5m-pmic.h | 141 +++++++++++++++
include/linux/mfd/s5m87xx/s5m-rtc.h | 69 ++++++++
4 files changed, 758 insertions(+), 0 deletions(-)
create mode 100644 drivers/mfd/s5m-core.c
create mode 100644 include/linux/mfd/s5m87xx/s5m-core.h
create mode 100644 include/linux/mfd/s5m87xx/s5m-pmic.h
create mode 100644 include/linux/mfd/s5m87xx/s5m-rtc.h
diff --git a/drivers/mfd/s5m-core.c b/drivers/mfd/s5m-core.c
new file mode 100644
index 0000000..6dac3a1
--- /dev/null
+++ b/drivers/mfd/s5m-core.c
@@ -0,0 +1,235 @@
+/*
+ * s5m-core.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd
+ * http://www.samsung.com
+ *
+ * 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 <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/pm_runtime.h>
+#include <linux/mutex.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/s5m87xx/s5m-core.h>
+#include <linux/mfd/s5m87xx/s5m-pmic.h>
+#include <linux/mfd/s5m87xx/s5m-rtc.h>
+#include <linux/regmap.h>
+
+int s5m_reg_read(struct s5m87xx_dev *s5m87xx, u8 reg, u8 *dest)
+{
+ int ret;
+ unsigned int val;
+
+ ret = regmap_read(s5m87xx->regmap, reg, &val);
+
+ if (ret < 0)
+ return ret;
+
+ ret &= 0xff;
+ *dest = ret;
+ return 0;
+}
+EXPORT_SYMBOL(s5m_reg_read);
+
+int s5m_bulk_read(struct s5m87xx_dev *s5m87xx, u8 reg, int count, u8 *buf)
+{
+ int ret;
+
+ ret = regmap_bulk_read(s5m87xx->regmap, reg, buf, count);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+EXPORT_SYMBOL(s5m_bulk_read);
+
+int s5m_reg_write(struct s5m87xx_dev *s5m87xx, u8 reg, u8 value)
+{
+ int ret;
+
+ ret = regmap_write(s5m87xx->regmap, reg, value);
+ return ret;
+}
+EXPORT_SYMBOL(s5m_reg_write);
+
+int s5m_bulk_write(struct s5m87xx_dev *s5m87xx, u8 reg, int count, u8 *buf)
+{
+ int ret;
+
+ ret = regmap_raw_write(s5m87xx->regmap, reg, buf, count *
sizeof(u16));
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+EXPORT_SYMBOL(s5m_bulk_write);
+
+int s5m_reg_update(struct s5m87xx_dev *s5m87xx, u8 reg, u8 val, u8 mask)
+{
+ int ret;
+
+ ret = regmap_update_bits(s5m87xx->regmap, reg, mask, val);
+ if (ret < 0)
+ return ret;
+
+ return ret;
+}
+EXPORT_SYMBOL(s5m_reg_update);
+
+static struct mfd_cell s5m87xx_devs[] = {
+ {
+ .name = "s5m8763-pmic",
+ }, {
+ .name = "s5m8767-pmic",
+ }, {
+ .name = "s5m-rtc",
+ }, {
+ .name = "s5m8763-charger",
+ },
+};
+
+static struct regmap_config s5m_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+};
+
+static int s5m_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ struct s5m87xx_platform_data *pdata = i2c->dev.platform_data;
+ struct s5m87xx_dev *s5m87xx;
+ int ret = 0;
+ int error;
+
+ s5m87xx = kzalloc(sizeof(struct s5m87xx_dev), GFP_KERNEL);
+ if (s5m87xx == NULL)
+ return -ENOMEM;
+
+ i2c_set_clientdata(i2c, s5m87xx);
+ s5m87xx->dev = &i2c->dev;
+ s5m87xx->i2c = i2c;
+ s5m87xx->irq = i2c->irq;
+ s5m87xx->type = id->driver_data;
+
+ if (pdata) {
+ s5m87xx->device_type = pdata->device_type;
+ s5m87xx->ono = pdata->ono;
+ s5m87xx->irq_base = pdata->irq_base;
+ s5m87xx->wakeup = pdata->wakeup;
+ }
+
+ s5m87xx->regmap = regmap_init_i2c(i2c, &s5m_regmap_config);
+ if (IS_ERR(s5m87xx->regmap)) {
+ error = PTR_ERR(s5m87xx->regmap);
+ dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
+ error);
+ goto err;
+ }
+
+ s5m87xx->rtc = i2c_new_dummy(i2c->adapter, RTC_I2C_ADDR);
+ i2c_set_clientdata(s5m87xx->rtc, s5m87xx);
+
+ s5m_irq_init(s5m87xx);
+
+ pm_runtime_set_active(s5m87xx->dev);
+
+ ret = mfd_add_devices(s5m87xx->dev, -1,
+ s5m87xx_devs, ARRAY_SIZE(s5m87xx_devs),
+ NULL, 0);
+ if (ret < 0)
+ goto err;
+
+ dev_info(s5m87xx->dev ,"SAMSUNG S5M MFD\n");
+ return ret;
+
+err:
+ mfd_remove_devices(s5m87xx->dev);
+ s5m_irq_exit(s5m87xx);
+ i2c_unregister_device(s5m87xx->rtc);
+ regmap_exit(s5m87xx->regmap);
+ kfree(s5m87xx);
+ return ret;
+}
+
+static int s5m_i2c_remove(struct i2c_client *i2c)
+{
+ struct s5m87xx_dev *s5m87xx = i2c_get_clientdata(i2c);
+
+ mfd_remove_devices(s5m87xx->dev);
+ s5m_irq_exit(s5m87xx);
+ i2c_unregister_device(s5m87xx->rtc);
+ regmap_exit(s5m87xx->regmap);
+ kfree(s5m87xx);
+
+ return 0;
+}
+
+static const struct i2c_device_id s5m87xx_i2c_id[] = {
+ { "s5m87xx", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, s5m87xx_i2c_id);
+
+static int s5m_suspend(struct i2c_client *i2c, pm_message_t state)
+{
+ struct s5m87xx_dev *s5m87xx = i2c_get_clientdata(i2c);
+
+ if (s5m87xx->wakeup)
+ enable_irq_wake(s5m87xx->irq);
+
+ disable_irq(s5m87xx->irq);
+
+ return 0;
+}
+
+static int s5m_resume(struct i2c_client *i2c)
+{
+ struct s5m87xx_dev *s5m87xx = i2c_get_clientdata(i2c);
+
+ if (s5m87xx->wakeup)
+ disable_irq_wake(s5m87xx->irq);
+
+ enable_irq(s5m87xx->irq);
+
+ return 0;
+}
+
+static struct i2c_driver s5m87xx_i2c_driver = {
+ .driver = {
+ .name = "s5m87xx",
+ .owner = THIS_MODULE,
+ },
+ .probe = s5m_i2c_probe,
+ .remove = s5m_i2c_remove,
+ .id_table = s5m87xx_i2c_id,
+ .suspend = s5m_suspend,
+ .resume = s5m_resume,
+};
+
+static int __init s5m87xx_i2c_init(void)
+{
+ return i2c_add_driver(&s5m87xx_i2c_driver);
+}
+
+subsys_initcall(s5m87xx_i2c_init);
+
+static void __exit s5m87xx_i2c_exit(void)
+{
+ i2c_del_driver(&s5m87xx_i2c_driver);
+}
+module_exit(s5m87xx_i2c_exit);
+
+MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");
+MODULE_DESCRIPTION("Core support for the S5M87XX MFD");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/mfd/s5m87xx/s5m-core.h
b/include/linux/mfd/s5m87xx/s5m-core.h
new file mode 100644
index 0000000..ddacd5b
--- /dev/null
+++ b/include/linux/mfd/s5m87xx/s5m-core.h
@@ -0,0 +1,313 @@
+/*
+ * s5m-core.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd
+ * http://www.samsung.com
+ *
+ * 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.
+ *
+ */
+
+#ifndef __LINUX_MFD_S5M_CORE_H
+#define __LINUX_MFD_S5M_CORE_H
+
+#define NUM_IRQ_REGS 4
+
+enum s5m_device_type {
+ S5M8751X,
+ S5M8763X,
+ S5M8767X,
+};
+
+/* S5M8767 registers */
+enum s5m8767_reg {
+ S5M8767_REG_ID,
+ S5M8767_REG_INT1,
+ S5M8767_REG_INT2,
+ S5M8767_REG_INT3,
+ S5M8767_REG_INT1M,
+ S5M8767_REG_INT2M,
+ S5M8767_REG_INT3M,
+ S5M8767_REG_STATUS1,
+ S5M8767_REG_STATUS2,
+ S5M8767_REG_STATUS3,
+ S5M8767_REG_CTRL1,
+ S5M8767_REG_CTRL2,
+ S5M8767_REG_LOWBAT1,
+ S5M8767_REG_LOWBAT2,
+ S5M8767_REG_BUCHG,
+ S5M8767_REG_DVSRAMP,
+ S5M8767_REG_DVSTIMER1,
+ S5M8767_REG_DVSTIMER2,
+ S5M8767_REG_DVSTIMER3,
+ S5M8767_REG_DVSTIMER4,
+ S5M8767_REG_LDO1,
+ S5M8767_REG_LDO2,
+ S5M8767_REG_LDO3,
+ S5M8767_REG_LDO4,
+ S5M8767_REG_LDO5,
+ S5M8767_REG_LDO6,
+ S5M8767_REG_LDO7,
+ S5M8767_REG_LDO8,
+ S5M8767_REG_LDO9,
+ S5M8767_REG_LDO10,
+ S5M8767_REG_LDO11,
+ S5M8767_REG_LDO12,
+ S5M8767_REG_LDO13,
+ S5M8767_REG_LDO14,
+ S5M8767_REG_LDO15,
+ S5M8767_REG_LDO16,
+ S5M8767_REG_LDO17,
+ S5M8767_REG_LDO18,
+ S5M8767_REG_LDO19,
+ S5M8767_REG_LDO20,
+ S5M8767_REG_LDO21,
+ S5M8767_REG_LDO22,
+ S5M8767_REG_LDO23,
+ S5M8767_REG_LDO24,
+ S5M8767_REG_LDO25,
+ S5M8767_REG_LDO26,
+ S5M8767_REG_LDO27,
+ S5M8767_REG_BUCK1CTRL1 = 0x35,
+ S5M8767_REG_BUCK1CTRL2,
+ S5M8767_REG_BUCK2CTRL,
+ S5M8767_REG_BUCK2DVS1,
+ S5M8767_REG_BUCK2DVS2,
+ S5M8767_REG_BUCK2DVS3,
+ S5M8767_REG_BUCK2DVS4,
+ S5M8767_REG_BUCK2DVS5,
+ S5M8767_REG_BUCK2DVS6,
+ S5M8767_REG_BUCK2DVS7,
+ S5M8767_REG_BUCK2DVS8,
+ S5M8767_REG_BUCK3CTRL,
+ S5M8767_REG_BUCK3DVS1,
+ S5M8767_REG_BUCK3DVS2,
+ S5M8767_REG_BUCK3DVS3,
+ S5M8767_REG_BUCK3DVS4,
+ S5M8767_REG_BUCK3DVS5,
+ S5M8767_REG_BUCK3DVS6,
+ S5M8767_REG_BUCK3DVS7,
+ S5M8767_REG_BUCK3DVS8,
+ S5M8767_REG_BUCK4CTRL,
+ S5M8767_REG_BUCK4DVS1,
+ S5M8767_REG_BUCK4DVS2,
+ S5M8767_REG_BUCK4DVS3,
+ S5M8767_REG_BUCK4DVS4,
+ S5M8767_REG_BUCK4DVS5,
+ S5M8767_REG_BUCK4DVS6,
+ S5M8767_REG_BUCK4DVS7,
+ S5M8767_REG_BUCK4DVS8,
+ S5M8767_REG_BUCK5CTRL1,
+ S5M8767_REG_BUCK5CTRL2,
+ S5M8767_REG_BUCK6CTRL1,
+ S5M8767_REG_BUCK6CTRL2,
+ S5M8767_REG_BUCK7CTRL1,
+ S5M8767_REG_BUCK7CTRL2,
+ S5M8767_REG_BUCK8CTRL1,
+ S5M8767_REG_BUCK8CTRL2,
+ S5M8767_REG_LDO1CTRL,
+ S5M8767_REG_LDO2CTRL,
+ S5M8767_REG_LDO3CTRL,
+ S5M8767_REG_LDO4CTRL,
+ S5M8767_REG_LDO5CTRL,
+ S5M8767_REG_LDO6CTRL,
+ S5M8767_REG_LDO7CTRL,
+ S5M8767_REG_LDO8CTRL,
+ S5M8767_REG_LDO9CTRL,
+ S5M8767_REG_LDO10CTRL,
+ S5M8767_REG_LDO11CTRL,
+ S5M8767_REG_LDO12CTRL,
+ S5M8767_REG_LDO13CTRL,
+ S5M8767_REG_LDO14CTRL,
+ S5M8767_REG_LDO15CTRL,
+ S5M8767_REG_LDO16CTRL,
+ S5M8767_REG_LDO17CTRL,
+ S5M8767_REG_LDO18CTRL,
+ S5M8767_REG_LDO19CTRL,
+ S5M8767_REG_LDO20CTRL,
+ S5M8767_REG_LDO21CTRL,
+ S5M8767_REG_LDO22CTRL,
+ S5M8767_REG_LDO23CTRL,
+ S5M8767_REG_LDO24CTRL,
+ S5M8767_REG_LDO25CTRL,
+ S5M8767_REG_LDO26CTRL,
+ S5M8767_REG_LDO27CTRL,
+};
+
+/* S5M8763 registers */
+enum s5m8763_reg {
+ S5M8763_REG_IRQ1,
+ S5M8763_REG_IRQ2,
+ S5M8763_REG_IRQ3,
+ S5M8763_REG_IRQ4,
+ S5M8763_REG_IRQM1,
+ S5M8763_REG_IRQM2,
+ S5M8763_REG_IRQM3,
+ S5M8763_REG_IRQM4,
+ S5M8763_REG_STATUS1,
+ S5M8763_REG_STATUS2,
+ S5M8763_REG_STATUSM1,
+ S5M8763_REG_STATUSM2,
+ S5M8763_REG_CHGR1,
+ S5M8763_REG_CHGR2,
+ S5M8763_REG_LDO_ACTIVE_DISCHARGE1,
+ S5M8763_REG_LDO_ACTIVE_DISCHARGE2,
+ S5M8763_REG_BUCK_ACTIVE_DISCHARGE3,
+ S5M8763_REG_ONOFF1,
+ S5M8763_REG_ONOFF2,
+ S5M8763_REG_ONOFF3,
+ S5M8763_REG_ONOFF4,
+ S5M8763_REG_BUCK1_VOLTAGE1,
+ S5M8763_REG_BUCK1_VOLTAGE2,
+ S5M8763_REG_BUCK1_VOLTAGE3,
+ S5M8763_REG_BUCK1_VOLTAGE4,
+ S5M8763_REG_BUCK2_VOLTAGE1,
+ S5M8763_REG_BUCK2_VOLTAGE2,
+ S5M8763_REG_BUCK3,
+ S5M8763_REG_BUCK4,
+ S5M8763_REG_LDO1_LDO2,
+ S5M8763_REG_LDO3,
+ S5M8763_REG_LDO4,
+ S5M8763_REG_LDO5,
+ S5M8763_REG_LDO6,
+ S5M8763_REG_LDO7,
+ S5M8763_REG_LDO7_LDO8,
+ S5M8763_REG_LDO9_LDO10,
+ S5M8763_REG_LDO11,
+ S5M8763_REG_LDO12,
+ S5M8763_REG_LDO13,
+ S5M8763_REG_LDO14,
+ S5M8763_REG_LDO15,
+ S5M8763_REG_LDO16,
+ S5M8763_REG_BKCHR,
+ S5M8763_REG_LBCNFG1,
+ S5M8763_REG_LBCNFG2,
+};
+
+enum s5m8767_irq {
+ S5M8767_IRQ_PWRR,
+ S5M8767_IRQ_PWRF,
+ S5M8767_IRQ_PWR1S,
+ S5M8767_IRQ_JIGR,
+ S5M8767_IRQ_JIGF,
+ S5M8767_IRQ_LOWBAT2,
+ S5M8767_IRQ_LOWBAT1,
+
+ S5M8767_IRQ_MRB,
+ S5M8767_IRQ_DVSOK2,
+ S5M8767_IRQ_DVSOK3,
+ S5M8767_IRQ_DVSOK4,
+
+ S5M8767_IRQ_RTC60S,
+ S5M8767_IRQ_RTCA1,
+ S5M8767_IRQ_RTCA2,
+ S5M8767_IRQ_SMPL,
+ S5M8767_IRQ_RTC1S,
+ S5M8767_IRQ_WTSR,
+
+ S5M8767_IRQ_NR,
+};
+
+#define S5M8767_IRQ_PWRR_MASK (1 << 0)
+#define S5M8767_IRQ_PWRF_MASK (1 << 1)
+#define S5M8767_IRQ_PWR1S_MASK (1 << 3)
+#define S5M8767_IRQ_JIGR_MASK (1 << 4)
+#define S5M8767_IRQ_JIGF_MASK (1 << 5)
+#define S5M8767_IRQ_LOWBAT2_MASK (1 << 6)
+#define S5M8767_IRQ_LOWBAT1_MASK (1 << 7)
+
+#define S5M8767_IRQ_MRB_MASK (1 << 2)
+#define S5M8767_IRQ_DVSOK2_MASK (1 << 3)
+#define S5M8767_IRQ_DVSOK3_MASK (1 << 4)
+#define S5M8767_IRQ_DVSOK4_MASK (1 << 5)
+
+#define S5M8767_IRQ_RTC60S_MASK (1 << 0)
+#define S5M8767_IRQ_RTCA1_MASK (1 << 1)
+#define S5M8767_IRQ_RTCA2_MASK (1 << 2)
+#define S5M8767_IRQ_SMPL_MASK (1 << 3)
+#define S5M8767_IRQ_RTC1S_MASK (1 << 4)
+#define S5M8767_IRQ_WTSR_MASK (1 << 5)
+
+enum s5m8763_irq {
+ S5M8763_IRQ_VDCINF,
+ S5M8763_IRQ_VDCINR,
+ S5M8763_IRQ_JIGF,
+ S5M8763_IRQ_JIGR,
+ S5M8763_IRQ_PWRONF,
+ S5M8763_IRQ_PWRONR,
+
+ S5M8763_IRQ_WTSREVNT,
+ S5M8763_IRQ_SMPLEVNT,
+ S5M8763_IRQ_ALARM1,
+ S5M8763_IRQ_ALARM0,
+
+ S5M8763_IRQ_ONKEY1S,
+ S5M8763_IRQ_TOPOFFR,
+ S5M8763_IRQ_VDCINOVPR,
+ S5M8763_IRQ_CHGRSTF,
+ S5M8763_IRQ_DONER,
+ S5M8763_IRQ_CHGFAULT,
+
+ S5M8763_IRQ_LOBAT1,
+ S5M8763_IRQ_LOBAT2,
+
+ S5M8763_IRQ_NR,
+};
+
+#define S5M8763_IRQ_VDCINF_MASK (1 << 2)
+#define S5M8763_IRQ_VDCINR_MASK (1 << 3)
+#define S5M8763_IRQ_JIGF_MASK (1 << 4)
+#define S5M8763_IRQ_JIGR_MASK (1 << 5)
+#define S5M8763_IRQ_PWRONF_MASK (1 << 6)
+#define S5M8763_IRQ_PWRONR_MASK (1 << 7)
+
+#define S5M8763_IRQ_WTSREVNT_MASK (1 << 0)
+#define S5M8763_IRQ_SMPLEVNT_MASK (1 << 1)
+#define S5M8763_IRQ_ALARM1_MASK (1 << 2)
+#define S5M8763_IRQ_ALARM0_MASK (1 << 3)
+
+#define S5M8763_IRQ_ONKEY1S_MASK (1 << 0)
+#define S5M8763_IRQ_TOPOFFR_MASK (1 << 2)
+#define S5M8763_IRQ_VDCINOVPR_MASK (1 << 3)
+#define S5M8763_IRQ_CHGRSTF_MASK (1 << 4)
+#define S5M8763_IRQ_DONER_MASK (1 << 5)
+#define S5M8763_IRQ_CHGFAULT_MASK (1 << 7)
+
+#define S5M8763_IRQ_LOBAT1_MASK (1 << 0)
+#define S5M8763_IRQ_LOBAT2_MASK (1 << 1)
+
+#define S5M8763_ENRAMP (1 << 4)
+
+struct s5m87xx_dev {
+ struct device *dev;
+ struct i2c_client *i2c;
+ struct i2c_client *rtc;
+ struct mutex irqlock;
+ struct mutex iolock;
+
+ int device_type;
+ int irq_base;
+ int irq;
+ int ono;
+ u8 irq_masks_cur[NUM_IRQ_REGS];
+ u8 irq_masks_cache[NUM_IRQ_REGS];
+ int type;
+ bool wakeup;
+
+ struct regmap *regmap;
+};
+
+int s5m_irq_init(struct s5m87xx_dev *s5m87xx);
+void s5m_irq_exit(struct s5m87xx_dev *s5m87xx);
+int s5m_irq_resume(struct s5m87xx_dev *s5m87xx);
+
+extern int s5m_reg_read(struct s5m87xx_dev *s5m87xx, u8 reg, u8 *dest);
+extern int s5m_bulk_read(struct s5m87xx_dev *s5m87xx, u8 reg, int count,u8
*buf);
+extern int s5m_reg_write(struct s5m87xx_dev *s5m87xx, u8 reg, u8 value);
+extern int s5m_bulk_write(struct s5m87xx_dev *s5m87xx, u8 reg, int count,u8
*buf);
+extern int s5m_reg_update(struct s5m87xx_dev *s5m87xx, u8 reg, u8 val, u8
mask);
+
+#endif /* __LINUX_MFD_S5M_CORE_H */
diff --git a/include/linux/mfd/s5m87xx/s5m-pmic.h
b/include/linux/mfd/s5m87xx/s5m-pmic.h
new file mode 100644
index 0000000..2bb57b3
--- /dev/null
+++ b/include/linux/mfd/s5m87xx/s5m-pmic.h
@@ -0,0 +1,141 @@
+/*
+ * s5m-pmic.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd
+ * http://www.samsung.com
+ *
+ * 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.
+ *
+ */
+
+#ifndef __LINUX_MFD_S5M_PMIC_H
+#define __LINUX_MFD_S5M_PMIC_H
+
+#include <linux/regulator/machine.h>
+
+/* S5M8767 regulator ids */
+enum s5m8767_regulators {
+ S5M8767_LDO1,
+ S5M8767_LDO2,
+ S5M8767_LDO3,
+ S5M8767_LDO4,
+ S5M8767_LDO5,
+ S5M8767_LDO6,
+ S5M8767_LDO7,
+ S5M8767_LDO8,
+ S5M8767_LDO9,
+ S5M8767_LDO10,
+ S5M8767_LDO11,
+ S5M8767_LDO12,
+ S5M8767_LDO13,
+ S5M8767_LDO14,
+ S5M8767_LDO15,
+ S5M8767_LDO16,
+ S5M8767_LDO17,
+ S5M8767_LDO18,
+ S5M8767_LDO19,
+ S5M8767_LDO20,
+ S5M8767_LDO21,
+ S5M8767_LDO22,
+ S5M8767_LDO23,
+ S5M8767_LDO24,
+ S5M8767_LDO25,
+ S5M8767_LDO26,
+ S5M8767_LDO27,
+ S5M8767_BUCK1,
+ S5M8767_BUCK2,
+ S5M8767_BUCK3,
+ S5M8767_BUCK4,
+ S5M8767_BUCK5,
+ S5M8767_BUCK6,
+ S5M8767_BUCK7,
+ S5M8767_BUCK8,
+ S5M8767_32KHZAP_EN,
+ S5M8767_32KHZCP_EN,
+
+ S5M8767_REG_MAX,
+};
+
+/* S5M8763 regulator ids */
+enum s5m8763_regulators {
+ S5M8763_LDO1,
+ S5M8763_LDO2,
+ S5M8763_LDO3,
+ S5M8763_LDO4,
+ S5M8763_LDO5,
+ S5M8763_LDO6,
+ S5M8763_LDO7,
+ S5M8763_LDO8,
+ S5M8763_LDO9,
+ S5M8763_LDO10,
+ S5M8763_LDO11,
+ S5M8763_LDO12,
+ S5M8763_LDO13,
+ S5M8763_LDO14,
+ S5M8763_LDO15,
+ S5M8763_LDO16,
+ S5M8763_BUCK1,
+ S5M8763_BUCK2,
+ S5M8763_BUCK3,
+ S5M8763_BUCK4,
+ S5M8763_AP_EN32KHZ,
+ S5M8763_CP_EN32KHZ,
+ S5M8763_ENCHGVI,
+ S5M8763_ESAFEUSB1,
+ S5M8763_ESAFEUSB2,
+};
+
+/**
+ * s5m87xx_regulator_data - regulator data
+ * @id: regulator id
+ * @initdata: regulator init data (contraints, supplies, ...)
+ */
+struct s5m87xx_regulator_data {
+ int id;
+ struct regulator_init_data *initdata;
+};
+
+struct s5m87xx_platform_data {
+ struct s5m87xx_regulator_data *regulators;
+ int device_type;
+ int num_regulators;
+ int irq_base;
+ int ono;
+ bool wakeup;
+ bool buck_voltage_lock;
+
+ int buck_gpios[3];
+ int buck_default_idx;
+ int buck1_voltage[4];
+ int buck2_voltage[8];
+ bool buck2_gpiodvs;
+ int buck3_voltage[8];
+ bool buck3_gpiodvs;
+ int buck4_voltage[8];
+ bool buck4_gpiodvs;
+
+ int buck1_set1;
+ int buck1_set2;
+ int buck2_set3;
+ int buck_set1;
+ int buck_set2;
+ int buck_set3;
+ int buck2_enable;
+ int buck3_enable;
+ int buck4_enable;
+ int buck1_default_idx;
+ int buck2_default_idx;
+ int buck3_default_idx;
+ int buck4_default_idx;
+ int buck_ramp_delay;
+ bool buck2_ramp_enable;
+ bool buck3_ramp_enable;
+ bool buck4_ramp_enable;
+
+
+};
+
+#endif /* __LINUX_MFD_S5M_PMIC_H */
diff --git a/include/linux/mfd/s5m87xx/s5m-rtc.h
b/include/linux/mfd/s5m87xx/s5m-rtc.h
new file mode 100644
index 0000000..6f52e3c
--- /dev/null
+++ b/include/linux/mfd/s5m87xx/s5m-rtc.h
@@ -0,0 +1,69 @@
+/*
+ * s5m-rtc.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd
+ * http://www.samsung.com
+ *
+ * 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.
+ *
+ */
+
+#ifndef __LINUX_MFD_S5M_RTC_H
+#define __LINUX_MFD_S5M_RTC_H
+
+enum s5m_rtc_reg {
+ S5M_RTC_SEC,
+ S5M_RTC_MIN,
+ S5M_RTC_HOUR,
+ S5M_RTC_WEEKDAY,
+ S5M_RTC_DATE,
+ S5M_RTC_MONTH,
+ S5M_RTC_YEAR1,
+ S5M_RTC_YEAR2,
+ S5M_ALARM0_SEC,
+ S5M_ALARM0_MIN,
+ S5M_ALARM0_HOUR,
+ S5M_ALARM0_WEEKDAY,
+ S5M_ALARM0_DATE,
+ S5M_ALARM0_MONTH,
+ S5M_ALARM0_YEAR1,
+ S5M_ALARM0_YEAR2,
+ S5M_ALARM1_SEC,
+ S5M_ALARM1_MIN,
+ S5M_ALARM1_HOUR,
+ S5M_ALARM1_WEEKDAY,
+ S5M_ALARM1_DATE,
+ S5M_ALARM1_MONTH,
+ S5M_ALARM1_YEAR1,
+ S5M_ALARM1_YEAR2,
+ S5M_ALARM0_CONF,
+ S5M_ALARM1_CONF,
+ S5M_RTC_STATUS,
+ S5M_WTSR_SMPL_CNTL,
+ S5M_RTC_UDR_CON,
+};
+
+#define RTC_I2C_ADDR (0x0C >> 1)
+
+#define HOUR_12 (1 << 7)
+#define HOUR_AMPM (1 << 6)
+#define HOUR_PM (1 << 5)
+#define ALARM0_STATUS (1 << 1)
+#define ALARM1_STATUS (1 << 2)
+#define UPDATE_AD (1 << 0)
+
+enum {
+ RTC_SEC = 0,
+ RTC_MIN,
+ RTC_HOUR,
+ RTC_WEEKDAY,
+ RTC_DATE,
+ RTC_MONTH,
+ RTC_YEAR1,
+ RTC_YEAR2,
+};
+
+#endif /* __LINUX_MFD_S5M_RTC_H */
--
1.7.1
^ permalink raw reply related
* [PATCH 3/3] mfd: Add S5M series configuration
From: Sangbeom Kim @ 2011-10-23 8:07 UTC (permalink / raw)
To: 'Samuel Ortiz'
Cc: linux-kernel, 'Mark Brown', 'Sangbeom Kim'
This patch add Samsung S5M series configuration.
Signed-off-by: Sangbeom Kim <sbkim73@samsung.com>
---
drivers/mfd/Kconfig | 12 ++++++++++++
drivers/mfd/Makefile | 1 +
2 files changed, 13 insertions(+), 0 deletions(-)
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 21574bd..e280d2a 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -386,6 +386,18 @@ config MFD_MAX8998
additional drivers must be enabled in order to use the
functionality
of the device.
+config MFD_S5M_CORE
+ bool "SAMSUNG S5M Series Support"
+ depends on I2C=y && GENERIC_HARDIRQS
+ select MFD_CORE
+ select REGMAP_I2C
+ help
+ Say yes here to support for SAMSUNG S5M series.
+ This is a Power Management IC.
+ This driver provies common support for accessing the device,
+ additional drivers must be enabled in order to use the
functionality
+ of the device
+
config MFD_WM8400
tristate "Support Wolfson Microelectronics WM8400"
select MFD_CORE
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index c580203..dfd05a2 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -102,3 +102,4 @@ obj-$(CONFIG_MFD_PM8921_CORE) += pm8921-core.o
obj-$(CONFIG_MFD_PM8XXX_IRQ) += pm8xxx-irq.o
obj-$(CONFIG_TPS65911_COMPARATOR) += tps65911-comparator.o
obj-$(CONFIG_MFD_AAT2870_CORE) += aat2870-core.o
+obj-$(CONFIG_MFD_S5M_CORE) += s5m-core.o s5m-irq.o
--
1.7.1
^ permalink raw reply related
* Re: [RFC] subdevice PM: .s_power() deprecation?
From: Sakari Ailus @ 2011-10-23 8:07 UTC (permalink / raw)
To: Sylwester Nawrocki
Cc: Guennadi Liakhovetski, Laurent Pinchart, Linux Media Mailing List,
Tomasz Stanislawski
In-Reply-To: <4E9F399B.9080207@gmail.com>
Hi Sylwester,
Sylwester Nawrocki wrote:
...
>> I understand what you're saying, but can you give us a specific example,
>> when a subdev driver (your SoC internal subdev, that is) doesn't have a
>> way to react to an event itself and only the bridge driver gets called
>> into at that time? Something like an interrupt or an internal timer or
>> some other internal event?
>
> 1. The S5P SoC video output subsystem (http://lwn.net/Articles/449661) comprises
> of multiple logical blocks, like Video Processor, Mixer, HDMI, HDMI PHY, SD TV Out.
> For instance the master video clock is during normal operation derived from
> (synchronized to, with PLL,) the HDMI-PHY output clock. The host driver can
> switch to this clock only when the HDMI-PHY (subdev) power and clocks are enabled.
> And it should be done before .s_stream(), to do some H/W configuration earlier
> in the pipeline, before streaming is enabled. Perhaps Tomasz could give some
> further explanation of what the s_power() op does and why in the driver.
>
> 2. In some of our camera pipeline setups - "Sensor - MIPI-CSI receiver - host/DMA",
> the sensor won't boot properly if all MIPI-CSI regulators aren't enabled. So the
> MIPI-CSI receiver must always be powered on before the sensor. With the subdevs
> doing their own magic wrt to power control the situation is getting slightly
> out of control.
How about this: CSI-2 receiver implements a few new regulators which the
sensor driver then requests to be enabled. Would that work for you?
>>> I guess we all agree the power requirements of external subdevs are generally
>>> unknown to the hosts.
>>>
>>> For these it might make lot of sense to let the subdev driver handle the device
>>> power supplies on basis of requests like, s_ctrl, s_stream, etc.
>>
>> Yes, right, so, most "external" (sensor, decoder,...) subdev drivers
>> should never need to implement .s_power(), regardless of whether we decide
>> to keep it or not. Well, ok, no, put it differently - in those drivers
>> .s_power() should only really be called during system-wide suspend /
>> resume.
>
> Yes, I agree with that. But before we attempt to remove .s_power() or deprecate
> it on "external" subdevs, I'd like to get solved the issue with sensor master clock
> provided by the bridge. As these two are closely related - the sensor controller
> won't boot if the clock is disabled. And there are always advantages of not keeping
> the clock always enabled.
I guess we'll need to wait awhile before the clock framework would
support this. I don't know what's the status of this; probably worth
checking.
Regards,
--
Sakari Ailus
sakari.ailus@iki.fi
^ permalink raw reply
* [PATCH 2/3] mfd: Add s5m series irq support
From: Sangbeom Kim @ 2011-10-23 8:07 UTC (permalink / raw)
To: 'Samuel Ortiz'
Cc: linux-kernel, 'Mark Brown', 'Sangbeom Kim'
This patch support irq for s5m series.
Basically, S5M8767 and S5M8763 irq can be handled by this patch.
Signed-off-by: Sangbeom Kim <sbkim73@samsung.com>
---
drivers/mfd/s5m-irq.c | 486
+++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 486 insertions(+), 0 deletions(-)
create mode 100644 drivers/mfd/s5m-irq.c
diff --git a/drivers/mfd/s5m-irq.c b/drivers/mfd/s5m-irq.c
new file mode 100644
index 0000000..6a4a71a
--- /dev/null
+++ b/drivers/mfd/s5m-irq.c
@@ -0,0 +1,486 @@
+/*
+ * s5m-irq.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd
+ * http://www.samsung.com
+ *
+ * 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 <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/mfd/s5m87xx/s5m-core.h>
+
+struct s5m_irq_data {
+ int reg;
+ int mask;
+};
+
+static struct s5m_irq_data s5m8767_irqs[] = {
+ [S5M8767_IRQ_PWRR] = {
+ .reg = 2,
+ .mask = S5M8767_IRQ_PWRR_MASK,
+ },
+ [S5M8767_IRQ_PWRF] = {
+ .reg = 2,
+ .mask = S5M8767_IRQ_PWRF_MASK,
+ },
+ [S5M8767_IRQ_PWR1S] = {
+ .reg = 2,
+ .mask = S5M8767_IRQ_PWR1S_MASK,
+ },
+ [S5M8767_IRQ_JIGR] = {
+ .reg = 2,
+ .mask = S5M8767_IRQ_JIGR_MASK,
+ },
+ [S5M8767_IRQ_JIGF] = {
+ .reg = 2,
+ .mask = S5M8767_IRQ_JIGF_MASK,
+ },
+ [S5M8767_IRQ_LOWBAT2] = {
+ .reg = 2,
+ .mask = S5M8767_IRQ_LOWBAT2_MASK,
+ },
+ [S5M8767_IRQ_LOWBAT1] = {
+ .reg = 2,
+ .mask = S5M8767_IRQ_LOWBAT1_MASK,
+ },
+ [S5M8767_IRQ_MRB] = {
+ .reg = 3,
+ .mask = S5M8767_IRQ_MRB_MASK,
+ },
+ [S5M8767_IRQ_DVSOK2] = {
+ .reg = 3,
+ .mask = S5M8767_IRQ_DVSOK2_MASK,
+ },
+ [S5M8767_IRQ_DVSOK3] = {
+ .reg = 3,
+ .mask = S5M8767_IRQ_DVSOK3_MASK,
+ },
+ [S5M8767_IRQ_DVSOK4] = {
+ .reg = 3,
+ .mask = S5M8767_IRQ_DVSOK4_MASK,
+ },
+ [S5M8767_IRQ_RTC60S] = {
+ .reg = 4,
+ .mask = S5M8767_IRQ_RTC60S_MASK,
+ },
+ [S5M8767_IRQ_RTCA1] = {
+ .reg = 4,
+ .mask = S5M8767_IRQ_RTCA1_MASK,
+ },
+ [S5M8767_IRQ_RTCA2] = {
+ .reg = 4,
+ .mask = S5M8767_IRQ_RTCA2_MASK,
+ },
+ [S5M8767_IRQ_SMPL] = {
+ .reg = 4,
+ .mask = S5M8767_IRQ_SMPL_MASK,
+ },
+ [S5M8767_IRQ_RTC1S] = {
+ .reg = 4,
+ .mask = S5M8767_IRQ_RTC1S_MASK,
+ },
+ [S5M8767_IRQ_WTSR] = {
+ .reg = 4,
+ .mask = S5M8767_IRQ_WTSR_MASK,
+ },
+};
+
+static struct s5m_irq_data s5m8763_irqs[] = {
+ [S5M8763_IRQ_VDCINF] = {
+ .reg = 1,
+ .mask = S5M8763_IRQ_VDCINF_MASK,
+ },
+ [S5M8763_IRQ_VDCINR] = {
+ .reg = 1,
+ .mask = S5M8763_IRQ_VDCINR_MASK,
+ },
+ [S5M8763_IRQ_JIGF] = {
+ .reg = 1,
+ .mask = S5M8763_IRQ_JIGF_MASK,
+ },
+ [S5M8763_IRQ_JIGR] = {
+ .reg = 1,
+ .mask = S5M8763_IRQ_JIGR_MASK,
+ },
+ [S5M8763_IRQ_PWRONF] = {
+ .reg = 1,
+ .mask = S5M8763_IRQ_PWRONF_MASK,
+ },
+ [S5M8763_IRQ_PWRONR] = {
+ .reg = 1,
+ .mask = S5M8763_IRQ_PWRONR_MASK,
+ },
+ [S5M8763_IRQ_WTSREVNT] = {
+ .reg = 2,
+ .mask = S5M8763_IRQ_WTSREVNT_MASK,
+ },
+ [S5M8763_IRQ_SMPLEVNT] = {
+ .reg = 2,
+ .mask = S5M8763_IRQ_SMPLEVNT_MASK,
+ },
+ [S5M8763_IRQ_ALARM1] = {
+ .reg = 2,
+ .mask = S5M8763_IRQ_ALARM1_MASK,
+ },
+ [S5M8763_IRQ_ALARM0] = {
+ .reg = 2,
+ .mask = S5M8763_IRQ_ALARM0_MASK,
+ },
+ [S5M8763_IRQ_ONKEY1S] = {
+ .reg = 3,
+ .mask = S5M8763_IRQ_ONKEY1S_MASK,
+ },
+ [S5M8763_IRQ_TOPOFFR] = {
+ .reg = 3,
+ .mask = S5M8763_IRQ_TOPOFFR_MASK,
+ },
+ [S5M8763_IRQ_VDCINOVPR] = {
+ .reg = 3,
+ .mask = S5M8763_IRQ_VDCINOVPR_MASK,
+ },
+ [S5M8763_IRQ_CHGRSTF] = {
+ .reg = 3,
+ .mask = S5M8763_IRQ_CHGRSTF_MASK,
+ },
+ [S5M8763_IRQ_DONER] = {
+ .reg = 3,
+ .mask = S5M8763_IRQ_DONER_MASK,
+ },
+ [S5M8763_IRQ_CHGFAULT] = {
+ .reg = 3,
+ .mask = S5M8763_IRQ_CHGFAULT_MASK,
+ },
+ [S5M8763_IRQ_LOBAT1] = {
+ .reg = 4,
+ .mask = S5M8763_IRQ_LOBAT1_MASK,
+ },
+ [S5M8763_IRQ_LOBAT2] = {
+ .reg = 4,
+ .mask = S5M8763_IRQ_LOBAT2_MASK,
+ },
+};
+
+static inline struct s5m_irq_data *
+irq_to_s5m8767_irq(struct s5m87xx_dev *s5m87xx, int irq)
+{
+ return &s5m8767_irqs[irq - s5m87xx->irq_base];
+}
+
+static void s5m8767_irq_lock(struct irq_data *data)
+{
+ struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data);
+
+ mutex_lock(&s5m87xx->irqlock);
+}
+
+static void s5m8767_irq_sync_unlock(struct irq_data *data)
+{
+ struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data);
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(s5m87xx->irq_masks_cur); i++) {
+ if (s5m87xx->irq_masks_cur[i] !=
s5m87xx->irq_masks_cache[i]) {
+ s5m87xx->irq_masks_cache[i] =
s5m87xx->irq_masks_cur[i];
+ s5m_reg_write(s5m87xx, S5M8767_REG_INT1M + i,
+ s5m87xx->irq_masks_cur[i]);
+ }
+ }
+
+ mutex_unlock(&s5m87xx->irqlock);
+}
+
+static void s5m8767_irq_unmask(struct irq_data *data)
+{
+ struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data);
+ struct s5m_irq_data *irq_data = irq_to_s5m8767_irq(s5m87xx,
+ data->irq);
+
+ s5m87xx->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask;
+}
+
+static void s5m8767_irq_mask(struct irq_data *data)
+{
+ struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data);
+ struct s5m_irq_data *irq_data = irq_to_s5m8767_irq(s5m87xx,
+ data->irq);
+
+ s5m87xx->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask;
+}
+
+static struct irq_chip s5m8767_irq_chip = {
+ .name = "s5m8767",
+ .irq_bus_lock = s5m8767_irq_lock,
+ .irq_bus_sync_unlock = s5m8767_irq_sync_unlock,
+ .irq_mask = s5m8767_irq_mask,
+ .irq_unmask = s5m8767_irq_unmask,
+};
+
+static inline struct s5m_irq_data *
+irq_to_s5m8763_irq(struct s5m87xx_dev *s5m87xx, int irq)
+{
+ return &s5m8763_irqs[irq - s5m87xx->irq_base];
+}
+
+static void s5m8763_irq_lock(struct irq_data *data)
+{
+ struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data);
+
+ mutex_lock(&s5m87xx->irqlock);
+}
+
+static void s5m8763_irq_sync_unlock(struct irq_data *data)
+{
+ struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data);
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(s5m87xx->irq_masks_cur); i++) {
+ if (s5m87xx->irq_masks_cur[i] !=
s5m87xx->irq_masks_cache[i]) {
+ s5m87xx->irq_masks_cache[i] =
s5m87xx->irq_masks_cur[i];
+ s5m_reg_write(s5m87xx, S5M8763_REG_IRQM1 + i,
+ s5m87xx->irq_masks_cur[i]);
+ }
+ }
+
+ mutex_unlock(&s5m87xx->irqlock);
+}
+
+static void s5m8763_irq_unmask(struct irq_data *data)
+{
+ struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data);
+ struct s5m_irq_data *irq_data = irq_to_s5m8763_irq(s5m87xx,
+ data->irq);
+
+ s5m87xx->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask;
+}
+
+static void s5m8763_irq_mask(struct irq_data *data)
+{
+ struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data);
+ struct s5m_irq_data *irq_data = irq_to_s5m8763_irq(s5m87xx,
+ data->irq);
+
+ s5m87xx->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask;
+}
+
+static struct irq_chip s5m8763_irq_chip = {
+ .name = "s5m8763",
+ .irq_bus_lock = s5m8763_irq_lock,
+ .irq_bus_sync_unlock = s5m8763_irq_sync_unlock,
+ .irq_mask = s5m8763_irq_mask,
+ .irq_unmask = s5m8763_irq_unmask,
+};
+
+static irqreturn_t s5m8767_irq_thread(int irq, void *data)
+{
+ struct s5m87xx_dev *s5m87xx = data;
+ u8 irq_reg[NUM_IRQ_REGS-1];
+ int ret;
+ int i;
+
+ ret = s5m_bulk_read(s5m87xx, S5M8767_REG_INT1,
+ NUM_IRQ_REGS - 1, irq_reg);
+ if (ret < 0) {
+ dev_err(s5m87xx->dev, "Failed to read interrupt register:
%d\n",
+ ret);
+ return IRQ_NONE;
+ }
+
+ for (i = 0; i < NUM_IRQ_REGS - 1; i++)
+ irq_reg[i] &= ~s5m87xx->irq_masks_cur[i];
+
+ for (i = 0; i < S5M8767_IRQ_NR; i++) {
+ if (irq_reg[s5m8767_irqs[i].reg - 1] & s5m8767_irqs[i].mask)
+ handle_nested_irq(s5m87xx->irq_base + i);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t s5m8763_irq_thread(int irq, void *data)
+{
+ struct s5m87xx_dev *s5m87xx = data;
+ u8 irq_reg[NUM_IRQ_REGS];
+ int ret;
+ int i;
+
+ ret = s5m_bulk_read(s5m87xx, S5M8763_REG_IRQ1,
+ NUM_IRQ_REGS, irq_reg);
+ if (ret < 0) {
+ dev_err(s5m87xx->dev, "Failed to read interrupt register:
%d\n",
+ ret);
+ return IRQ_NONE;
+ }
+
+ for (i = 0; i < NUM_IRQ_REGS; i++)
+ irq_reg[i] &= ~s5m87xx->irq_masks_cur[i];
+
+ for (i = 0; i < S5M8763_IRQ_NR; i++) {
+ if (irq_reg[s5m8763_irqs[i].reg - 1] & s5m8763_irqs[i].mask)
+ handle_nested_irq(s5m87xx->irq_base + i);
+ }
+
+ return IRQ_HANDLED;
+}
+
+int s5m_irq_resume(struct s5m87xx_dev *s5m87xx)
+{
+ if (s5m87xx->irq && s5m87xx->irq_base){
+ switch (s5m87xx->device_type) {
+ case S5M8763X:
+ s5m8763_irq_thread(s5m87xx->irq_base, s5m87xx);
+ break;
+ case S5M8767X:
+ s5m8767_irq_thread(s5m87xx->irq_base, s5m87xx);
+ break;
+ default:
+ break;
+
+ }
+ }
+ return 0;
+}
+
+int s5m_irq_init(struct s5m87xx_dev *s5m87xx)
+{
+ int i;
+ int cur_irq;
+ int ret = 0;
+ int type = s5m87xx->device_type;
+
+ if (!s5m87xx->irq) {
+ dev_warn(s5m87xx->dev,
+ "No interrupt specified, no interrupts\n");
+ s5m87xx->irq_base = 0;
+ return 0;
+ }
+
+ if (!s5m87xx->irq_base) {
+ dev_err(s5m87xx->dev,
+ "No interrupt base specified, no interrupts\n");
+ return 0;
+ }
+
+ mutex_init(&s5m87xx->irqlock);
+
+ switch (type) {
+ case S5M8763X:
+ for (i = 0; i < NUM_IRQ_REGS; i++) {
+ s5m87xx->irq_masks_cur[i] = 0xff;
+ s5m87xx->irq_masks_cache[i] = 0xff;
+ s5m_reg_write(s5m87xx, S5M8763_REG_IRQM1 + i,
+ 0xff);
+ }
+
+ s5m_reg_write(s5m87xx, S5M8763_REG_STATUSM1, 0xff);
+ s5m_reg_write(s5m87xx, S5M8763_REG_STATUSM2, 0xff);
+
+ for (i = 0; i < S5M8763_IRQ_NR; i++) {
+ cur_irq = i + s5m87xx->irq_base;
+ irq_set_chip_data(cur_irq, s5m87xx);
+ irq_set_chip_and_handler(cur_irq, &s5m8763_irq_chip,
+ handle_edge_irq);
+ irq_set_nested_thread(cur_irq, 1);
+#ifdef CONFIG_ARM
+ set_irq_flags(cur_irq, IRQF_VALID);
+#else
+ irq_set_noprobe(cur_irq);
+#endif
+ }
+
+ ret = request_threaded_irq(s5m87xx->irq, NULL,
+ s5m8763_irq_thread,
+ IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+ "s5m87xx-irq", s5m87xx);
+ if (ret) {
+ dev_err(s5m87xx->dev, "Failed to request IRQ %d:
%d\n",
+ s5m87xx->irq, ret);
+ return ret;
+ }
+ break;
+ case S5M8767X:
+ for (i = 0; i < NUM_IRQ_REGS - 1; i++) {
+ s5m87xx->irq_masks_cur[i] = 0xff;
+ s5m87xx->irq_masks_cache[i] = 0xff;
+ s5m_reg_write(s5m87xx, S5M8767_REG_INT1M + i,
+ 0xff);
+ }
+
+ for (i = 0; i < S5M8767_IRQ_NR; i++) {
+ cur_irq = i + s5m87xx->irq_base;
+ irq_set_chip_data(cur_irq, s5m87xx);
+ if (ret) {
+ dev_err(s5m87xx->dev,
+ "Failed to irq_set_chip_data %d:
%d\n",
+ s5m87xx->irq, ret);
+ return ret;
+ }
+
+ irq_set_chip_and_handler(cur_irq, &s5m8767_irq_chip,
+ handle_edge_irq);
+ irq_set_nested_thread(cur_irq, 1);
+#ifdef CONFIG_ARM
+ set_irq_flags(cur_irq, IRQF_VALID);
+#else
+ irq_set_noprobe(cur_irq);
+#endif
+ }
+
+ ret = request_threaded_irq(s5m87xx->irq, NULL,
+ s5m8767_irq_thread,
+ IRQF_TRIGGER_FALLING |
IRQF_ONESHOT,
+ "s5m87xx-irq", s5m87xx);
+ if (ret) {
+ dev_err(s5m87xx->dev, "Failed to request IRQ %d:
%d\n",
+ s5m87xx->irq, ret);
+ return ret;
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (!s5m87xx->ono)
+ return 0;
+
+ switch (type) {
+ case S5M8763X:
+ ret = request_threaded_irq(s5m87xx->ono, NULL,
+ s5m8763_irq_thread,
+ IRQF_TRIGGER_FALLING |
+ IRQF_TRIGGER_RISING |
+ IRQF_ONESHOT, "s5m87xx-ono",
+ s5m87xx);
+ break;
+ case S5M8767X:
+ ret = request_threaded_irq(s5m87xx->ono, NULL,
+ s5m8767_irq_thread,
+ IRQF_TRIGGER_FALLING |
+ IRQF_TRIGGER_RISING |
+ IRQF_ONESHOT, "s5m87xx-ono",
s5m87xx);
+ break;
+ default:
+ break;
+ }
+
+ if (ret)
+ dev_err(s5m87xx->dev, "Failed to request IRQ %d: %d\n",
+ s5m87xx->ono, ret);
+
+ return 0;
+}
+
+void s5m_irq_exit(struct s5m87xx_dev *s5m87xx)
+{
+ if (s5m87xx->ono)
+ free_irq(s5m87xx->ono, s5m87xx);
+
+ if (s5m87xx->irq)
+ free_irq(s5m87xx->irq, s5m87xx);
+}
--
1.7.1
^ permalink raw reply related
* [PATCH] regulator: Add S5M8767 regulator driver
From: Sangbeom Kim @ 2011-10-23 8:12 UTC (permalink / raw)
To: 'Liam Girdwood', 'Mark Brown'
Cc: linux-kernel, 'Sangbeom Kim'
S5M8767 is a cost-effective PMIC which is designed for mobile applications.
It includes high efficient 8 Buck converters, 27 LDOs, and an RTC.
This patch implement regulator driver for S5M8767.
Signed-off-by: Sangbeom Kim <sbkim73@samsung.com>
---
drivers/regulator/Kconfig | 8 +
drivers/regulator/Makefile | 1 +
drivers/regulator/s5m8767.c | 852
+++++++++++++++++++++++++++++++++++++++++++
3 files changed, 861 insertions(+), 0 deletions(-)
create mode 100644 drivers/regulator/s5m8767.c
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index c7fd2c0..9d35b8e 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -125,6 +125,14 @@ config REGULATOR_MAX8998
via I2C bus. The provided regulator is suitable for S3C6410
and S5PC1XX chips to control VCC_CORE and VCC_USIM voltages.
+config REGULATOR_S5M8767
+ tristate "Samsung S5M8767 voltage regulator"
+ depends on MFD_S5M_CORE
+ help
+ This driver controls a Samsung S5M8767 voltage output regulator
+ via I2C bus. S5M8767 have 8 Bucks and 27 LDOs output and
+ supports 8 DVS modes ranging from 0.65V to 2.225V by 6.25mV steps.
+
config REGULATOR_TWL4030
bool "TI TWL4030/TWL5030/TWL6030/TPS659x0 PMIC"
depends on TWL4030_CORE
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 040d5aa..478fc0f 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -45,5 +45,6 @@ obj-$(CONFIG_REGULATOR_AB8500) += ab8500.o
obj-$(CONFIG_REGULATOR_DB8500_PRCMU) += db8500-prcmu.o
obj-$(CONFIG_REGULATOR_TPS65910) += tps65910-regulator.o
obj-$(CONFIG_REGULATOR_AAT2870) += aat2870-regulator.o
+obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o
ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG
diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c
new file mode 100644
index 0000000..2c4c10c
--- /dev/null
+++ b/drivers/regulator/s5m8767.c
@@ -0,0 +1,852 @@
+/*
+ * s5m8767.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd
+ * http://www.samsung.com
+ *
+ * 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 <linux/bug.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/mfd/s5m87xx/s5m-pmic.h>
+#include <linux/mfd/s5m87xx/s5m-core.h>
+
+struct s5m8767_info {
+ struct device *dev;
+ struct s5m87xx_dev *iodev;
+ int num_regulators;
+ struct regulator_dev **rdev;
+ int ramp_delay;
+ bool buck2_ramp;
+ bool buck3_ramp;
+ bool buck4_ramp;
+
+ bool buck2_gpiodvs;
+ bool buck3_gpiodvs;
+ bool buck4_gpiodvs;
+ u8 buck2_vol[8];
+ u8 buck3_vol[8];
+ u8 buck4_vol[8];
+ int buck_gpios[3];
+ int buck_gpioindex;
+};
+
+struct s5m_voltage_desc {
+ int max;
+ int min;
+ int step;
+};
+
+static const struct s5m_voltage_desc buck_voltage_val = {
+ .max = 2225000,
+ .min = 650000,
+ .step = 6250,
+};
+
+static const struct s5m_voltage_desc ldo_voltage_val = {
+ .max = 3950000,
+ .min = 800000,
+ .step = 50000,
+};
+
+static const struct s5m_voltage_desc *reg_voltage_map[] = {
+ [S5M8767_LDO1] = &ldo_voltage_val,
+ [S5M8767_LDO2] = &ldo_voltage_val,
+ [S5M8767_LDO3] = &ldo_voltage_val,
+ [S5M8767_LDO4] = &ldo_voltage_val,
+ [S5M8767_LDO5] = &ldo_voltage_val,
+ [S5M8767_LDO6] = &ldo_voltage_val,
+ [S5M8767_LDO7] = &ldo_voltage_val,
+ [S5M8767_LDO8] = &ldo_voltage_val,
+ [S5M8767_LDO9] = &ldo_voltage_val,
+ [S5M8767_LDO10] = &ldo_voltage_val,
+ [S5M8767_LDO11] = &ldo_voltage_val,
+ [S5M8767_LDO12] = &ldo_voltage_val,
+ [S5M8767_LDO13] = &ldo_voltage_val,
+ [S5M8767_LDO14] = &ldo_voltage_val,
+ [S5M8767_LDO15] = &ldo_voltage_val,
+ [S5M8767_LDO16] = &ldo_voltage_val,
+ [S5M8767_LDO17] = &ldo_voltage_val,
+ [S5M8767_LDO18] = &ldo_voltage_val,
+ [S5M8767_LDO19] = &ldo_voltage_val,
+ [S5M8767_LDO20] = &ldo_voltage_val,
+ [S5M8767_LDO21] = &ldo_voltage_val,
+ [S5M8767_LDO22] = &ldo_voltage_val,
+ [S5M8767_LDO23] = &ldo_voltage_val,
+ [S5M8767_LDO24] = &ldo_voltage_val,
+ [S5M8767_LDO25] = &ldo_voltage_val,
+ [S5M8767_LDO26] = &ldo_voltage_val,
+ [S5M8767_LDO27] = &ldo_voltage_val,
+ [S5M8767_BUCK1] = &buck_voltage_val,
+ [S5M8767_BUCK2] = &buck_voltage_val,
+ [S5M8767_BUCK3] = &buck_voltage_val,
+ [S5M8767_BUCK4] = &buck_voltage_val,
+ [S5M8767_BUCK5] = &buck_voltage_val,
+ [S5M8767_BUCK6] = &buck_voltage_val,
+ [S5M8767_BUCK7] = NULL,
+ [S5M8767_BUCK8] = NULL,
+};
+
+static inline int s5m8767_get_regid(struct regulator_dev *rdev)
+{
+ return rdev_get_id(rdev);
+}
+
+static inline int s5m8767_is_buck(struct regulator_dev *rdev)
+{
+ int reg_id = s5m8767_get_regid(rdev);
+
+ return reg_id < S5M8767_LDO27;
+}
+
+static int s5m8767_list_voltage(struct regulator_dev *rdev,
+ unsigned int selector)
+{
+ const struct s5m_voltage_desc *desc;
+ int reg_id = s5m8767_get_regid(rdev);
+ int val;
+
+ if (reg_id >= ARRAY_SIZE(reg_voltage_map) || reg_id < 0)
+ return -EINVAL;
+
+ desc = reg_voltage_map[reg_id];
+ if (desc == NULL)
+ return -EINVAL;
+
+ val = desc->min + desc->step * selector;
+ if (val > desc->max)
+ return -EINVAL;
+
+ return val;
+}
+
+static int s5m8767_get_register(struct regulator_dev *rdev, int *reg)
+{
+ int reg_id = s5m8767_get_regid(rdev);
+
+ switch (reg_id) {
+ case S5M8767_LDO1 ... S5M8767_LDO27:
+ *reg = S5M8767_REG_LDO1CTRL + (reg_id - S5M8767_LDO1);
+ break;
+ case S5M8767_BUCK1:
+ *reg = S5M8767_REG_BUCK1CTRL1;
+ break;
+ case S5M8767_BUCK2 ... S5M8767_BUCK4:
+ *reg = S5M8767_REG_BUCK2CTRL + (reg_id - S5M8767_BUCK2) * 9;
+ break;
+ case S5M8767_BUCK5 ... S5M8767_BUCK8:
+ *reg = S5M8767_REG_BUCK5CTRL1 + (reg_id - S5M8767_BUCK5) *
2;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int s5m8767_reg_is_enabled(struct regulator_dev *rdev)
+{
+ struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
+ int ret, reg;
+ int mask=0x01, pattern=0x01;
+ u8 val;
+ int reg_id = s5m8767_get_regid(rdev);
+
+ switch (reg_id) {
+ case S5M8767_LDO1 ... S5M8767_LDO27:
+ mask = 0xc0;
+ pattern = 0xc0;
+ break;
+ case S5M8767_BUCK1 ... S5M8767_BUCK8:
+ break;
+ }
+
+ ret = s5m8767_get_register(rdev, ®);
+ if (ret == -EINVAL)
+ return 1;
+ else if (ret)
+ return ret;
+
+ ret = s5m_reg_read(s5m8767->iodev, reg, &val);
+ if (ret)
+ return ret;
+
+ return (val & mask) == pattern;
+}
+
+static int s5m8767_reg_enable(struct regulator_dev *rdev)
+{
+ struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
+ int ret, reg;
+ int mask=0, pattern=0;
+ int reg_id = s5m8767_get_regid(rdev);
+
+ switch (reg_id) {
+ case S5M8767_LDO1 ... S5M8767_LDO27:
+ mask = 0xc0;
+ pattern = 0xc0;
+ break;
+ case S5M8767_BUCK1 ... S5M8767_BUCK8:
+ mask = 0x01;
+ pattern = 0x01;
+ break;
+ }
+
+ ret = s5m8767_get_register(rdev, ®);
+ if (ret)
+ return ret;
+
+ return s5m_reg_update(s5m8767->iodev, reg, pattern, mask);
+}
+
+static int s5m8767_reg_disable(struct regulator_dev *rdev)
+{
+ struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
+ int ret, reg;
+ int mask=0, pattern=0;
+ int reg_id = s5m8767_get_regid(rdev);
+
+ switch (reg_id) {
+ case S5M8767_LDO1 ... S5M8767_LDO27:
+ mask = 0xc0;
+ pattern = 0xc0;
+ break;
+ case S5M8767_BUCK1 ... S5M8767_BUCK8:
+ mask = 0x01;
+ pattern = 0x01;
+ break;
+ }
+
+ ret = s5m8767_get_register(rdev, ®);
+ if (ret)
+ return ret;
+
+ return s5m_reg_update(s5m8767->iodev, reg, ~pattern, mask);
+}
+
+static int s5m8767_get_voltage_register(struct regulator_dev *rdev, int
*_reg)
+{
+ int reg_id = s5m8767_get_regid(rdev);
+ int reg;
+
+ switch (reg_id) {
+ case S5M8767_LDO1 ... S5M8767_LDO27:
+ reg = S5M8767_REG_LDO1CTRL + (reg_id - S5M8767_LDO1);
+ break;
+ case S5M8767_BUCK1:
+ reg = S5M8767_REG_BUCK1CTRL2;
+ break;
+ case S5M8767_BUCK2:
+ reg = S5M8767_REG_BUCK2DVS1;
+ break;
+ case S5M8767_BUCK3:
+ reg = S5M8767_REG_BUCK3DVS1;
+ break;
+ case S5M8767_BUCK4:
+ reg = S5M8767_REG_BUCK4DVS1;
+ break;
+ case S5M8767_BUCK5 ... S5M8767_BUCK8:
+ reg = S5M8767_REG_BUCK5CTRL2 + (reg_id - S5M8767_BUCK5) * 2;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ *_reg = reg;
+
+ return 0;
+}
+
+static int s5m8767_get_voltage(struct regulator_dev *rdev)
+{
+ struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
+ int reg, mask=0xff, ret;
+ int reg_id = s5m8767_get_regid(rdev);
+ u8 val;
+
+ ret = s5m8767_get_voltage_register(rdev, ®);
+ if (ret)
+ return ret;
+
+ switch (reg_id) {
+ case S5M8767_LDO1 ... S5M8767_LDO27:
+ mask = 0x3f;
+ break;
+ case S5M8767_BUCK2:
+ if(s5m8767->buck2_gpiodvs)
+ reg += s5m8767->buck_gpioindex;
+ break;
+ case S5M8767_BUCK3:
+ if(s5m8767->buck3_gpiodvs)
+ reg += s5m8767->buck_gpioindex;
+ break;
+ case S5M8767_BUCK4:
+ if(s5m8767->buck4_gpiodvs)
+ reg += s5m8767->buck_gpioindex;
+ break;
+ }
+
+ ret = s5m_reg_read(s5m8767->iodev, reg, &val);
+ if (ret)
+ return ret;
+
+ val &= mask;
+
+ if (rdev->desc && rdev->desc->ops && rdev->desc->ops->list_voltage)
+ return rdev->desc->ops->list_voltage(rdev, val);
+
+ return s5m8767_list_voltage(rdev, val);
+}
+
+static inline int s5m8767_convert_voltage(
+ const struct s5m_voltage_desc *desc,
+ int min_vol, int max_vol)
+{
+ int i = 0;
+
+ if (desc == NULL)
+ return -EINVAL;
+
+ if (max_vol < desc->min || min_vol > desc->max)
+ return -EINVAL;
+
+ i = (min_vol - desc->min) / desc->step;
+
+ if (desc->min + desc->step * i > max_vol)
+ return -EINVAL;
+
+ return i;
+}
+
+static int s5m8767_set_voltage(struct regulator_dev *rdev,
+ int min_uV, int max_uV, unsigned *selector)
+{
+ struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
+ int min_vol = min_uV, max_vol = max_uV;
+ const struct s5m_voltage_desc *desc;
+ int reg_id = s5m8767_get_regid(rdev);
+ int reg, mask, ret;
+ int i;
+ u8 val;
+
+ switch (reg_id) {
+ case S5M8767_LDO1 ... S5M8767_LDO27:
+ mask = 0x3f;
+ break;
+ case S5M8767_BUCK1 ... S5M8767_BUCK6:
+ mask = 0xff;
+ break;
+ case S5M8767_BUCK7 ... S5M8767_BUCK8:
+ return -EINVAL;
+ default:
+ return -EINVAL;
+ }
+
+ desc = reg_voltage_map[reg_id];
+
+ i = s5m8767_convert_voltage(desc, min_vol, max_vol);
+ if (i < 0)
+ return i;
+
+ ret = s5m8767_get_voltage_register(rdev, ®);
+ if (ret)
+ return ret;
+
+ s5m_reg_read(s5m8767->iodev, reg, &val);
+ val = val & mask;
+
+ ret = s5m_reg_update(s5m8767->iodev, reg, i, mask);
+ *selector = i;
+
+ if (val < i)
+ udelay(DIV_ROUND_UP(desc->step * (i - val),
+ s5m8767->ramp_delay));
+
+ return ret;
+}
+
+static inline void s5m8767_set_high(struct s5m8767_info *s5m8767)
+{
+ int temp_index = s5m8767->buck_gpioindex;
+
+ gpio_set_value(s5m8767->buck_gpios[0], (temp_index >> 2) & 0x1);
+ gpio_set_value(s5m8767->buck_gpios[1], (temp_index >> 1) & 0x1);
+ gpio_set_value(s5m8767->buck_gpios[2], temp_index & 0x1);
+}
+
+static inline void s5m8767_set_low(struct s5m8767_info *s5m8767)
+{
+ int temp_index = s5m8767->buck_gpioindex;
+
+ gpio_set_value(s5m8767->buck_gpios[2], temp_index & 0x1);
+ gpio_set_value(s5m8767->buck_gpios[1], (temp_index >> 1) & 0x1);
+ gpio_set_value(s5m8767->buck_gpios[0], (temp_index >> 2) & 0x1);
+}
+
+static int s5m8767_set_voltage_buck(struct regulator_dev *rdev,
+ int min_uV, int max_uV, unsigned
*selector)
+{
+ struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
+ int reg_id = s5m8767_get_regid(rdev);
+ const struct s5m_voltage_desc *desc;
+ int new_val, old_val, i = 0;
+ int min_vol = min_uV, max_vol = max_uV;
+
+ if (reg_id < S5M8767_BUCK1 || reg_id > S5M8767_BUCK6)
+ return -EINVAL;
+
+ switch (reg_id) {
+ case S5M8767_BUCK1:
+ return s5m8767_set_voltage(rdev, min_uV, max_uV, selector);
+ case S5M8767_BUCK2 ... S5M8767_BUCK4:
+ break;
+ case S5M8767_BUCK5 ... S5M8767_BUCK6:
+ return s5m8767_set_voltage(rdev, min_uV, max_uV, selector);
+ }
+
+ desc = reg_voltage_map[reg_id];
+ new_val = s5m8767_convert_voltage(desc, min_vol, max_vol);
+ if (new_val < 0)
+ return new_val;
+
+ switch (reg_id) {
+ case S5M8767_BUCK2:
+ if(s5m8767->buck2_gpiodvs){
+ while (s5m8767->buck2_vol[i] != new_val)
+ i++;
+ }
+ else
+ return s5m8767_set_voltage(rdev, min_uV, max_uV,
selector);
+ break;
+ case S5M8767_BUCK3:
+ if(s5m8767->buck3_gpiodvs){
+ while (s5m8767->buck3_vol[i] != new_val)
+ i++;
+ } else
+ return s5m8767_set_voltage(rdev, min_uV, max_uV,
selector);
+ break;
+ case S5M8767_BUCK4:
+ if(s5m8767->buck3_gpiodvs){
+ while (s5m8767->buck4_vol[i] != new_val)
+ i++;
+ } else
+ return s5m8767_set_voltage(rdev, min_uV, max_uV,
selector);
+ break;
+ }
+
+ old_val = s5m8767->buck_gpioindex;
+ s5m8767->buck_gpioindex = i;
+
+ if ( i > old_val)
+ s5m8767_set_high(s5m8767);
+ else
+ s5m8767_set_low(s5m8767);
+
+ *selector = new_val;
+ return 0;
+}
+
+static int s5m8767_reg_enable_suspend(struct regulator_dev *rdev)
+{
+ return 0;
+}
+
+static int s5m8767_reg_disable_suspend(struct regulator_dev *rdev)
+{
+ struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
+ int ret, reg;
+ int mask=0, pattern=0;
+ int reg_id = s5m8767_get_regid(rdev);
+
+ switch (reg_id) {
+ case S5M8767_LDO1 ... S5M8767_LDO27:
+ mask = 0xc0;
+ pattern = 0xc0;
+ break;
+ case S5M8767_BUCK1 ... S5M8767_BUCK8:
+ mask = 0x01;
+ pattern = 0x01;
+ break;
+ }
+
+ ret = s5m8767_get_register(rdev, ®);
+ if (ret)
+ return ret;
+
+ return s5m_reg_update(s5m8767->iodev, reg, ~pattern, mask);
+}
+
+static struct regulator_ops s5m8767_ldo_ops = {
+ .list_voltage = s5m8767_list_voltage,
+ .is_enabled = s5m8767_reg_is_enabled,
+ .enable = s5m8767_reg_enable,
+ .disable = s5m8767_reg_disable,
+ .get_voltage = s5m8767_get_voltage,
+ .set_voltage = s5m8767_set_voltage,
+ .set_suspend_enable = s5m8767_reg_enable_suspend,
+ .set_suspend_disable = s5m8767_reg_disable_suspend,
+};
+
+static struct regulator_ops s5m8767_buck_ops = {
+ .list_voltage = s5m8767_list_voltage,
+ .is_enabled = s5m8767_reg_is_enabled,
+ .enable = s5m8767_reg_enable,
+ .disable = s5m8767_reg_disable,
+ .get_voltage = s5m8767_get_voltage,
+ .set_voltage = s5m8767_set_voltage_buck,
+ .set_suspend_enable = s5m8767_reg_enable_suspend,
+ .set_suspend_disable = s5m8767_reg_disable_suspend,
+};
+
+static struct regulator_ops s5m8767_others_ops = {
+ .is_enabled = s5m8767_reg_is_enabled,
+ .enable = s5m8767_reg_enable,
+ .disable = s5m8767_reg_disable,
+ .set_suspend_enable = s5m8767_reg_enable_suspend,
+ .set_suspend_disable = s5m8767_reg_disable_suspend,
+};
+
+#define regulator_desc_ldo(num) { \
+ .name = "LDO"#num, \
+ .id = S5M8767_LDO##num, \
+ .ops = &s5m8767_ldo_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .owner = THIS_MODULE, \
+}
+#define regulator_desc_buck(num) { \
+ .name = "BUCK"#num, \
+ .id = S5M8767_BUCK##num, \
+ .ops = &s5m8767_buck_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .owner = THIS_MODULE, \
+}
+
+static struct regulator_desc regulators[] = {
+ regulator_desc_ldo(1),
+ regulator_desc_ldo(2),
+ regulator_desc_ldo(3),
+ regulator_desc_ldo(4),
+ regulator_desc_ldo(5),
+ regulator_desc_ldo(6),
+ regulator_desc_ldo(7),
+ regulator_desc_ldo(8),
+ regulator_desc_ldo(9),
+ regulator_desc_ldo(10),
+ regulator_desc_ldo(11),
+ regulator_desc_ldo(12),
+ regulator_desc_ldo(13),
+ regulator_desc_ldo(14),
+ regulator_desc_ldo(15),
+ regulator_desc_ldo(16),
+ regulator_desc_ldo(17),
+ regulator_desc_ldo(18),
+ regulator_desc_ldo(19),
+ regulator_desc_ldo(20),
+ regulator_desc_ldo(21),
+ regulator_desc_ldo(22),
+ regulator_desc_ldo(23),
+ regulator_desc_ldo(24),
+ regulator_desc_ldo(25),
+ regulator_desc_ldo(26),
+ regulator_desc_ldo(27),
+ regulator_desc_buck(1),
+ regulator_desc_buck(2),
+ regulator_desc_buck(3),
+ regulator_desc_buck(4),
+ regulator_desc_buck(5),
+ regulator_desc_buck(6),
+ regulator_desc_buck(7),
+ regulator_desc_buck(8),
+ {
+ .name = "AP 32KHz",
+ .id = S5M8767_32KHZAP_EN,
+ .ops = &s5m8767_others_ops,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+ }, {
+ .name = "CP 32KHz",
+ .id = S5M8767_32KHZAP_EN,
+ .ops = &s5m8767_others_ops,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+ },
+};
+
+static __devinit int s5m8767_pmic_probe(struct platform_device *pdev)
+{
+ struct s5m87xx_dev *iodev = dev_get_drvdata(pdev->dev.parent);
+ struct s5m87xx_platform_data *pdata = dev_get_platdata(iodev->dev);
+ struct regulator_dev **rdev;
+ struct s5m8767_info *s5m8767;
+ struct i2c_client *i2c;
+ int i, ret, size, reg;
+ u8 val;
+
+ if (!pdata) {
+ dev_err(pdev->dev.parent, "Platform data not supplied\n");
+ return -ENODEV;
+ }
+
+ s5m8767 = kzalloc(sizeof(struct s5m8767_info), GFP_KERNEL);
+ if (!s5m8767)
+ return -ENOMEM;
+
+ size = sizeof(struct regulator_dev *) * pdata->num_regulators;
+ s5m8767->rdev = kzalloc(size, GFP_KERNEL);
+ if (!s5m8767->rdev) {
+ kfree(s5m8767);
+ return -ENOMEM;
+ }
+
+ rdev = s5m8767->rdev;
+ s5m8767->dev = &pdev->dev;
+ s5m8767->iodev = iodev;
+ s5m8767->num_regulators = pdata->num_regulators;
+ platform_set_drvdata(pdev, s5m8767);
+ i2c = s5m8767->iodev->i2c;
+
+ s5m8767->buck_gpioindex = pdata->buck_default_idx;
+ s5m8767->buck2_gpiodvs = pdata->buck2_gpiodvs;
+ s5m8767->buck3_gpiodvs = pdata->buck3_gpiodvs;
+ s5m8767->buck4_gpiodvs = pdata->buck4_gpiodvs;
+ s5m8767->buck_gpios[0] = pdata->buck_gpios[0];
+ s5m8767->buck_gpios[1] = pdata->buck_gpios[1];
+ s5m8767->buck_gpios[2] = pdata->buck_gpios[2];
+ s5m8767->ramp_delay = pdata->buck_ramp_delay;
+ s5m8767->buck2_ramp = pdata->buck2_ramp_enable;
+ s5m8767->buck3_ramp = pdata->buck3_ramp_enable;
+ s5m8767->buck4_ramp = pdata->buck4_ramp_enable;
+
+ for (i = 0; i < 8; i++) {
+ if (s5m8767->buck2_gpiodvs) {
+ s5m8767->buck2_vol[i] =
+ s5m8767_convert_voltage(
+ &buck_voltage_val,
+ pdata->buck2_voltage[i],
+ pdata->buck2_voltage[i] +
+ buck_voltage_val.step);
+ }
+
+ if (s5m8767->buck3_gpiodvs) {
+ s5m8767->buck3_vol[i] =
+ s5m8767_convert_voltage(
+ &buck_voltage_val,
+ pdata->buck3_voltage[i],
+ pdata->buck3_voltage[i] +
+ buck_voltage_val.step);
+ }
+
+ if (s5m8767->buck4_gpiodvs) {
+ s5m8767->buck4_vol[i] =
+ s5m8767_convert_voltage(
+ &buck_voltage_val,
+ pdata->buck4_voltage[i],
+ pdata->buck4_voltage[i] +
+ buck_voltage_val.step);
+ }
+
+ }
+
+ if(pdata->buck2_gpiodvs || pdata->buck3_gpiodvs ||
+ pdata->buck4_gpiodvs) {
+ if (gpio_is_valid(pdata->buck_gpios[0]) &&
+ gpio_is_valid(pdata->buck_gpios[1]) &&
+ gpio_is_valid(pdata->buck_gpios[2])) {
+ ret = gpio_request(pdata->buck_gpios[0],
+ "S5M8767 SET1");
+ if (ret == -EBUSY)
+ dev_warn(&pdev->dev, "Duplicated gpio
request"
+ " for SET1\n");
+
+ ret = gpio_request(pdata->buck_gpios[1],
+ "S5M8767 SET2");
+ if (ret == -EBUSY)
+ dev_warn(&pdev->dev, "Duplicated gpio
request"
+ " for SET2\n");
+
+ ret = gpio_request(pdata->buck_gpios[2],
+ "S5M8767 SET3");
+ if (ret == -EBUSY)
+ dev_warn(&pdev->dev, "Duplicated gpio
request"
+ " for SET3\n");
+ /* SET1 GPIO */
+ gpio_direction_output(pdata->buck_gpios[0],
+ (s5m8767->buck_gpioindex >> 2) &
0x1);
+ /* SET2 GPIO */
+ gpio_direction_output(pdata->buck_gpios[1],
+ (s5m8767->buck_gpioindex >> 1) &
0x1);
+ /* SET3 GPIO */
+ gpio_direction_output(pdata->buck_gpios[2],
+ (s5m8767->buck_gpioindex >> 0) &
0x1);
+ ret = 0;
+ } else {
+ dev_err(&pdev->dev, "GPIO ISN'T VALID\n");
+ ret = -EINVAL;
+ goto err_alloc;
+ }
+ }
+
+ s5m_reg_update(s5m8767->iodev, S5M8767_REG_BUCK2CTRL,
(pdata->buck2_gpiodvs) ?
+ (1 << 1) : (0 << 1), 1 << 1);
+ s5m_reg_update(s5m8767->iodev, S5M8767_REG_BUCK3CTRL,
(pdata->buck3_gpiodvs) ?
+ (1 << 1) : (0 << 1), 1 << 1);
+ s5m_reg_update(s5m8767->iodev, S5M8767_REG_BUCK4CTRL,
(pdata->buck4_gpiodvs) ?
+ (1 << 1) : (0 << 1), 1 << 1);
+
+ /* Initialize GPIO DVS registers */
+ for (i = 0; i < 8; i++) {
+ if (s5m8767->buck2_gpiodvs) {
+ s5m_reg_write(s5m8767->iodev, S5M8767_REG_BUCK2DVS1
+ i,
+ s5m8767->buck2_vol[i]);
+ }
+
+ if (s5m8767->buck3_gpiodvs) {
+ s5m_reg_write(s5m8767->iodev, S5M8767_REG_BUCK3DVS1
+ i,
+ s5m8767->buck3_vol[i]);
+ }
+
+ if (s5m8767->buck4_gpiodvs) {
+ s5m_reg_write(s5m8767->iodev, S5M8767_REG_BUCK4DVS1
+ i,
+ s5m8767->buck4_vol[i]);
+ }
+ }
+
+ reg = S5M8767_REG_LDO7CTRL;
+
+ do{
+ ret = s5m_reg_read(s5m8767->iodev, reg, &val);
+ if (ret)
+ return ret;
+
+ s5m_reg_update(s5m8767->iodev, reg, ((val & 0x3f) | 0x80),
0xff);
+ reg++;
+ if ((reg == S5M8767_REG_LDO9CTRL)
+ || (reg == S5M8767_REG_LDO11CTRL)
+ || (reg == S5M8767_REG_LDO13CTRL)
+ || (reg == S5M8767_REG_LDO17CTRL))
+ reg++;
+ } while (reg <= S5M8767_REG_LDO27CTRL);
+
+ if (s5m8767->buck2_ramp)
+ s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, 0x08,
0x08);
+
+ if (s5m8767->buck3_ramp)
+ s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, 0x04,
0x04);
+
+ if (s5m8767->buck4_ramp)
+ s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, 0x02,
0x02);
+
+ if (s5m8767->buck2_ramp || s5m8767->buck3_ramp
+ || s5m8767->buck4_ramp) {
+ if (s5m8767->ramp_delay < 15)
+ s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP,
+ s5m8767->ramp_delay - 1, 0xf0);
+ else if (s5m8767->ramp_delay == 15)
+ s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP,
+ 0xc0, 0xf0);
+ else if (s5m8767->ramp_delay == 25)
+ s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP,
+ 0xd0, 0xf0);
+ else if (s5m8767->ramp_delay == 50)
+ s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP,
+ 0xe0, 0xf0);
+ else if (s5m8767->ramp_delay == 100)
+ s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP,
+ 0xf0, 0xf0);
+ else
+ s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP,
+ 0x90, 0xf0);
+ }
+
+ for (i = 0; i < pdata->num_regulators; i++) {
+ const struct s5m_voltage_desc *desc;
+ int id = pdata->regulators[i].id;
+
+ desc = reg_voltage_map[id];
+ if (desc)
+ regulators[id].n_voltages =
+ (desc->max - desc->min) / desc->step + 1;
+
+ rdev[i] = regulator_register(®ulators[id], s5m8767->dev,
+ pdata->regulators[i].initdata,
+ s5m8767);
+ if (IS_ERR(rdev[i])) {
+ ret = PTR_ERR(rdev[i]);
+ dev_err(s5m8767->dev, "regulator init failed for
%d\n",
+ id);
+ rdev[i] = NULL;
+ goto err;
+ }
+ }
+
+ return 0;
+err:
+ for (i = 0; i < s5m8767->num_regulators; i++)
+ if (rdev[i])
+ regulator_unregister(rdev[i]);
+err_alloc:
+ kfree(s5m8767->rdev);
+ kfree(s5m8767);
+
+ return ret;
+}
+
+static int __devexit s5m8767_pmic_remove(struct platform_device *pdev)
+{
+ struct s5m8767_info *s5m8767 = platform_get_drvdata(pdev);
+ struct regulator_dev **rdev = s5m8767->rdev;
+ int i;
+
+ for (i = 0; i < s5m8767->num_regulators; i++)
+ if (rdev[i])
+ regulator_unregister(rdev[i]);
+
+ kfree(s5m8767->rdev);
+ kfree(s5m8767);
+
+ return 0;
+}
+
+static const struct platform_device_id s5m8767_pmic_id[] = {
+ { "s5m8767-pmic", 0},
+ { },
+};
+MODULE_DEVICE_TABLE(platform, s5m8767_pmic_id);
+
+static struct platform_driver s5m8767_pmic_driver = {
+ .driver = {
+ .name = "s5m8767-pmic",
+ .owner = THIS_MODULE,
+ },
+ .probe = s5m8767_pmic_probe,
+ .remove = __devexit_p(s5m8767_pmic_remove),
+ .id_table = s5m8767_pmic_id,
+};
+
+static int __init s5m8767_pmic_init(void)
+{
+ return platform_driver_register(&s5m8767_pmic_driver);
+}
+subsys_initcall(s5m8767_pmic_init);
+
+static void __exit s5m8767_pmic_exit(void)
+{
+ platform_driver_unregister(&s5m8767_pmic_driver);
+}
+module_exit(s5m8767_pmic_exit);
+
+/* Module information */
+MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");
+MODULE_DESCRIPTION("SAMSUNG S5M8767 Regulator Driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:s5m8767-pmic");
--
1.7.1
^ permalink raw reply related
* [U-Boot] A bit about board.c, board.c
From: Wolfgang Denk @ 2011-10-23 8:14 UTC (permalink / raw)
To: u-boot
In-Reply-To: <CAPnjgZ3ZdkF-dnLnC8=L55ZDWznWW6wqu0eJ7puTAT=3rcMcPQ@mail.gmail.com>
Dear Simon Glass,
In message <CAPnjgZ3ZdkF-dnLnC8=L55ZDWznWW6wqu0eJ7puTAT=3rcMcPQ@mail.gmail.com> you wrote:
>
> My suggestion was:
>
> CONFIG_ARCH_GENERIC_BOARD - you get lib/board.c
> not CONFIG_ARCH_GENERIC_BOARD - you get arch/xxx/lib/board.c
If we do something like this, then the other way round. There should
never be any #defines needed for the standard case - i. e. for using
lib/board.c,
Also, "ARCH_GENERIC_BOARD" is not a good name as it does not really
tell the reader that you are referencing to a specific source file
here - most people will think you are referring to some hardware
properties.
Best regards,
Wolfgang Denk
--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
"My name is Linus Torvalds, you messed with my kernel, prepare to die"
- Linus Torvalds in
<Pine.LNX.3.91.960426110644.24860I-100000@linux.cs.Helsinki.FI>
^ permalink raw reply
* Re: [PATCH 2/2] pinctrl: add a generic control interface
From: Shawn Guo @ 2011-10-23 8:25 UTC (permalink / raw)
To: Stephen Warren
Cc: Linus Walleij, linux-kernel@vger.kernel.org, Barry Song,
Linaro Dev, Sascha Hauer, David Brown, Grant Likely,
Linus Walleij
In-Reply-To: <74CDBE0F657A3D45AFBB94109FB122FF173D51C1C4@HQMAIL01.nvidia.com>
On Thu, Oct 20, 2011 at 10:26:43AM -0700, Stephen Warren wrote:
> Shawn Guo wrote at Wednesday, October 19, 2011 8:32 PM:
> > On Wed, Oct 19, 2011 at 06:21:14PM +0200, Linus Walleij wrote:
> ...
> > > +int pin_config_group(struct pinctrl_dev *pctldev, const char *pin_group,
> > > + enum pin_config_param param, unsigned long data)
> ...
> > > +enum pin_config_param {
> > > + PIN_CONFIG_BIAS_UNKNOWN,
> > > + PIN_CONFIG_BIAS_FLOAT,
> > > + PIN_CONFIG_BIAS_HIGH_IMPEDANCE,
> > > + PIN_CONFIG_BIAS_PULL_UP,
> > > + PIN_CONFIG_BIAS_PULL_DOWN,
> > > + PIN_CONFIG_BIAS_HIGH,
> > > + PIN_CONFIG_BIAS_GROUND,
> > > + PIN_CONFIG_DRIVE_UNKNOWN,
> > > + PIN_CONFIG_DRIVE_PUSH_PULL,
> > > + PIN_CONFIG_DRIVE_OPEN_DRAIN,
> > > + PIN_CONFIG_DRIVE_OPEN_SOURCE,
> > > + PIN_CONFIG_DRIVE_OFF,
> > > + PIN_CONFIG_INPUT_SCHMITT,
> > > + PIN_CONFIG_SLEW_RATE_RISING,
> > > + PIN_CONFIG_SLEW_RATE_FALLING,
> > > + PIN_CONFIG_LOAD_CAPACITANCE,
> > > + PIN_CONFIG_WAKEUP_ENABLE,
> > > + PIN_CONFIG_END,
> > > +};
> >
> > IMO, trying to enumerate all possible pin_config options is just to
> > make everyone's life harder. Firstly, this enumeration is far from
> > completion, for imx6 iomuxc example, we have 3 options for pull-up,
> > 22, 47 and 100 kOhm, and 7 options for driver-strength, 34, 40, 48,
> > 60, 80, 120, and 240 Ohm. It's just so hard to make this enumeration
> > complete. Secondly, defining this param as enum requires the API
> > user to call the function multiple times to configure one pin. For
> > example, if I want to configure pin_foo as slow-slew, open-drain,
> > 100 kOhm pull-up and 120 Ohm driver-strength, I will have to call
> > pin_config(pctldev, pin_foo, ...) 4 times to achieve that.
> >
> > I like Stephen's idea about having 'u32 param' and let pinctrl drivers
> > to encode/decode this u32 for their pinctrl controller. It makes
> > people's life much easier.
>
> That's not quite what I meant.
>
> I meant that I thought the types for param and value should be simple
> integers, with meanings of the values defined by the individual drivers,
> rather than a system-defined enum.
>
> However, I wasn't envisaging packing multiple fields into the "value"
> parameter; that would essentially be packing a struct into a u32 for
> transport. I still figured that "param" would logically be an enum,
> and represent a single modifiable parameter, and "data"/"value" would
> be the single value of that one parameter.
>
Oops, I misread your idea. Reading it correctly, I do not like it
either :) It does not resolve my concern that we need to call the API
multiple times to configure one pin.
> Still, perhaps packing stuff is an option that makes sense in some cases,
I feel strongly that this is what we want.
> depending on what API we end up with to manipulate the parameters, and
> where the source of "data"/"value" is (encoded into client driver, or
> from some hidden table passed to pinmux core by board, with the values
> being passed directly to the pinmux drivers without the client drivers
> seeing them)
I do not think client drivers care about the parameters. For the mmc
example I put earlier, all it needs from pinctrl subsystem is "Hey,
I'm going to switch bus clock to a higher frequency 100 MHz, please
configure mmc pins properly for that."
--
Regards,
Shawn
^ permalink raw reply
* [RFC][PATCH] uncompress.h cleanup and DT support
From: Zoltan Devai @ 2011-10-23 8:18 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
Originally, I just wanted to get rid of arch_decomp_* in all the uncompress.h
files, that were mostly empty. But then, I couldn't stop. Which may also mean
I have gone too far.
Plase consider all this as RFC, it's mostly not even compile-tested.
If you think it's worth to follow-up, I'm happy to do it.
What this series does:
- Remove all instances of arch_decomp_wdog
- Restructure the decompression code just a bit,
to separate the UART-printing stuff
- Introduce a low-level serial driver of the style
"check a reg if there's space for a TX char",
"output char", "wait for flush reg"
- Add init functions for the two common UARTs:
8250 and the amba.
This finally gets rid of that dozen re-implementations
that all use different register access methods and
register defines, but do the same.
- Some basic style cleanup
- Allow the uncompress UART definitions to be overridden
by a device tree description.
This would allow the removal of all the
"if machine_is_xxx, serial base is 123" lookup tables.
Remarks:
- Just to see how it works out, I converted most of the
arches/machines to use the ucuart driver.
I didn't convert any Samsung machines, because the
code is just too convoluted for me to dive into now.
- The overall patch is above 100K, so I didn't want
to post it here.
It's available here:
git://github.com/zdevai/linux.git uncompress-h
- Overall diffstat below.
Comments welcome.
Cheers,
Zoltan
arch/arm/Kconfig | 9 +
arch/arm/boot/compressed/Makefile | 9 +-
arch/arm/boot/compressed/decompress.c | 78 ++++--
arch/arm/boot/compressed/head.S | 8 +
arch/arm/boot/compressed/misc.c | 154 -----------
arch/arm/boot/compressed/print.c | 290 ++++++++++++++++++++
arch/arm/mach-at91/include/mach/uncompress.h | 62 +----
arch/arm/mach-bcmring/include/mach/uncompress.h | 47 +---
arch/arm/mach-clps711x/include/mach/uncompress.h | 49 +---
arch/arm/mach-cns3xxx/include/mach/uncompress.h | 49 +---
arch/arm/mach-davinci/include/mach/uncompress.h | 24 +--
arch/arm/mach-dove/include/mach/uncompress.h | 30 +--
arch/arm/mach-ebsa110/include/mach/uncompress.h | 40 +---
arch/arm/mach-ep93xx/include/mach/uncompress.h | 49 +---
arch/arm/mach-exynos4/include/mach/uncompress.h | 15 +-
arch/arm/mach-footbridge/include/mach/uncompress.h | 34 +--
arch/arm/mach-gemini/include/mach/uncompress.h | 41 +---
arch/arm/mach-h720x/include/mach/uncompress.h | 39 +--
arch/arm/mach-integrator/include/mach/uncompress.h | 49 +---
arch/arm/mach-iop13xx/include/mach/uncompress.h | 26 +--
arch/arm/mach-iop32x/include/mach/uncompress.h | 37 +--
arch/arm/mach-iop33x/include/mach/uncompress.h | 34 +--
arch/arm/mach-ixp2000/include/mach/uncompress.h | 48 +---
arch/arm/mach-ixp23xx/include/mach/uncompress.h | 33 +--
arch/arm/mach-ixp4xx/include/mach/uncompress.h | 44 +---
arch/arm/mach-kirkwood/include/mach/uncompress.h | 40 +---
arch/arm/mach-ks8695/include/mach/uncompress.h | 32 +--
arch/arm/mach-lpc32xx/include/mach/uncompress.h | 57 +----
arch/arm/mach-mmp/include/mach/uncompress.h | 38 +---
arch/arm/mach-msm/include/mach/uncompress.h | 45 +---
arch/arm/mach-mv78xx0/include/mach/uncompress.h | 40 +---
arch/arm/mach-mxs/include/mach/uncompress.h | 63 +----
arch/arm/mach-netx/include/mach/uncompress.h | 73 +-----
arch/arm/mach-nomadik/include/mach/uncompress.h | 58 +----
arch/arm/mach-omap1/include/mach/uncompress.h | 4 -
arch/arm/mach-omap2/include/mach/uncompress.h | 4 -
arch/arm/mach-orion5x/include/mach/uncompress.h | 48 +---
arch/arm/mach-picoxcell/include/mach/uncompress.h | 18 +-
arch/arm/mach-pnx4008/include/mach/uncompress.h | 43 +---
arch/arm/mach-prima2/include/mach/uncompress.h | 41 +---
arch/arm/mach-pxa/include/mach/uncompress.h | 77 +-----
arch/arm/mach-realview/include/mach/uncompress.h | 70 +----
arch/arm/mach-rpc/include/mach/uncompress.h | 9 +-
arch/arm/mach-s3c2410/include/mach/uncompress.h | 2 +
arch/arm/mach-s3c64xx/include/mach/uncompress.h | 18 +-
arch/arm/mach-s5p64x0/include/mach/uncompress.h | 39 +---
arch/arm/mach-s5pc100/include/mach/uncompress.h | 6 +-
arch/arm/mach-s5pv210/include/mach/uncompress.h | 17 +-
arch/arm/mach-sa1100/include/mach/uncompress.h | 62 ++---
arch/arm/mach-shark/include/mach/uncompress.h | 52 +----
arch/arm/mach-shmobile/include/mach/uncompress.h | 17 +-
arch/arm/mach-spear3xx/include/mach/uncompress.h | 18 --
arch/arm/mach-spear6xx/include/mach/uncompress.h | 18 --
arch/arm/mach-tegra/include/mach/uncompress.h | 62 +----
arch/arm/mach-u300/include/mach/uncompress.h | 45 +---
arch/arm/mach-ux500/include/mach/uncompress.h | 54 +----
arch/arm/mach-versatile/include/mach/uncompress.h | 45 +---
arch/arm/mach-vexpress/include/mach/uncompress.h | 51 +----
arch/arm/mach-vt8500/include/mach/uncompress.h | 40 +---
arch/arm/mach-w90x900/include/mach/uncompress.h | 47 +---
arch/arm/mach-zynq/include/mach/uncompress.h | 53 +---
arch/arm/plat-mxc/include/mach/uncompress.h | 37 +--
arch/arm/plat-omap/include/plat/uncompress.h | 45 +---
arch/arm/plat-samsung/Kconfig | 8 -
arch/arm/plat-samsung/include/plat/uncompress.h | 35 +---
arch/arm/plat-spear/include/plat/uncompress.h | 43 +---
arch/arm/plat-tcc/include/mach/uncompress.h | 33 +--
67 files changed, 671 insertions(+), 2234 deletions(-)
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.